--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbinput/inputwidgets/hbinputcandidatelist.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbInput module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include <QLabel>
+#include <QGraphicsLayout>
+
+#if QT_VERSION >= 0x040600
+#include <QGraphicsDropShadowEffect>
+#endif
+
+#include <hblistwidget.h>
+#include <hblistwidgetitem.h>
+#include <hbview.h>
+#include <hbframeitem.h>
+#include <hbframedrawer.h>
+
+#include <hbdeviceprofile.h>
+
+#include <hbinputmethod.h>
+#include <hbinputsettingproxy.h>
+#include <hbinputvkbhost.h>
+
+#include "hbinputcandidatelist.h"
+
+#include "hbdialog_p.h"
+
+const int HbCandListDefaultNumRows = 5;
+const qreal HbCandListMaxWidthMultiplier = 0.8;
+const qreal HbCandListMinWidth = 30.0;
+const qreal HbAutoComplPopupSideMargin = 15.0;
+const qreal HbAutoComplPopupVerticalMargin = 15.0;
+const qreal HbAutoComplPopupMinAllowedHeight = 25.0;
+
+/// @cond
+
+class HbCandidateListPrivate : public HbDialogPrivate
+{
+ Q_DECLARE_PUBLIC(HbCandidateList)
+
+public:
+ HbCandidateListPrivate(HbInputMethod* input);
+ ~HbCandidateListPrivate();
+ void calculateAndSetSize(qreal maxWidth);
+ void initFrameIcon();
+
+public:
+ HbListWidget* mList;
+ HbInputMethod* mInput;
+ int numRows;
+ int numCandidates;
+ int longestStringWidth;
+ HbFrameItem *mFrameBackground;
+};
+
+HbCandidateListPrivate::HbCandidateListPrivate(HbInputMethod* input)
+ : mInput(input),
+ numRows(HbCandListDefaultNumRows),
+ numCandidates(0),
+ longestStringWidth(0),
+ mFrameBackground( 0 )
+{
+ Q_Q(HbCandidateList);
+
+ mList = new HbListWidget(q);
+}
+
+HbCandidateListPrivate::~HbCandidateListPrivate()
+{
+// delete mBackground;
+}
+
+void HbCandidateListPrivate::initFrameIcon()
+{
+ Q_Q(HbCandidateList);
+
+ mFrameBackground = static_cast<HbFrameItem*>( q->primitive( HbStyle::P_Popup_background ));
+
+ if( mFrameBackground == 0 ) {
+ mFrameBackground = static_cast<HbFrameItem*>( q->style()->createPrimitive(( HbStyle::Primitive )( HbStyle::P_Popup_background ), q ));
+ }
+}
+
+
+void HbCandidateListPrivate::calculateAndSetSize(qreal maxWidth)
+{
+ Q_Q(HbCandidateList);
+
+ const qreal oneLineHeight = 40.0; // temporarily as a constant, eventually we'll need to calculate this.
+
+ QRectF geom = q->geometry();
+ qreal finalWidth = 30 + longestStringWidth * 2; // Use magic numbers for now until we can calculate this from font.
+
+ // Font has not been set yet at this point...
+ /*QList<HbAbstractViewItem *> items = mList->itemPrototypes();
+ mList->adjustSize();
+ HbAbstractViewItem * firstItem = items.at(0);
+
+ if(firstItem){
+ QFontMetrics fontMetrics(firstItem->fontSpec().font());
+ finalWidth = fontMetrics.boundingRect(longestString).width();
+ }*/
+
+ if (finalWidth > maxWidth) {
+ finalWidth = maxWidth;
+ }
+
+ qreal finalHeight = geom.height();
+ const int numLines = (numCandidates < numRows ? numCandidates : numRows);
+ qreal l = 0, r = 0, t = 0, b = 0;
+ if (q->layout()) {
+ q->layout()->getContentsMargins(&l, &t, &r, &b);
+ }
+
+ finalWidth = finalWidth + l + r ;
+ finalHeight = (qreal)numLines * oneLineHeight + 5.0 + t + b;
+
+ if(finalHeight > HbDeviceProfile::current().logicalSize().height() - 30)
+ finalHeight = HbDeviceProfile::current().logicalSize().height() - 30;
+
+ geom.setHeight(finalHeight);
+ geom.setWidth(finalWidth);
+
+ q->setGeometry(geom);
+}
+
+/// @endcond
+
+/*!
+@proto
+@hbinput
+\class HbCandidateList
+\brief Hb based candidate list popup.
+
+Shows a list of word prediction candidates. Informs the owning
+input method when a word is selected
+
+\sa HbInputVkbWidget
+*/
+
+
+/*!
+Constructor.
+@param input The input method that uses this widget.
+@param parent parent of the widget.
+*/
+HbCandidateList::HbCandidateList(HbInputMethod* input, QGraphicsItem* parent)
+ : HbDialog(*new HbCandidateListPrivate(input), parent)
+{
+ Q_D(HbCandidateList);
+
+ d->setPriority(HbPopupPrivate::VirtualKeyboard + 1); // Should be shown on top of virtual keyboard.
+ d->initFrameIcon();
+
+#if QT_VERSION >= 0x040600
+ // Make sure the preview pane never steals focus.
+ setFlag(QGraphicsItem::ItemIsPanel, true);
+ setActive(false);
+
+ // enable drop shadow for the preview pane
+ QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
+ effect->setBlurRadius(8);
+ setGraphicsEffect(effect);
+#endif
+
+ setTimeout(NoTimeout);
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+ connect(d->mList, SIGNAL(activated(HbListWidgetItem*)), this, SLOT(itemActivated(HbListWidgetItem*)));
+
+ setBackgroundFaded(false);
+}
+
+/*!
+Destroys the object.
+*/
+HbCandidateList::~HbCandidateList()
+{
+}
+
+/*!
+Populates the candidate list with text strings given as parameter.
+
+@param
+*/
+void HbCandidateList::populateList(const QStringList& candidates)
+{
+ Q_D(HbCandidateList);
+
+ setContentWidget(d->mList);
+
+ d->setPriority(HbPopupPrivate::VirtualKeyboard + 1); // Should be shown on top of virtual keyboard.
+ d->mList->clear();
+
+ int longestwidth = 0;
+ int finalWidth = 250;
+ for (int i = 0; i < candidates.count(); i++) {
+ HbListWidgetItem* item = new HbListWidgetItem();
+ item->setText(candidates[i]);
+ d->mList->addItem(item);
+
+ // TODO: Font has not been set corretly yet...
+ QFontMetrics fontMetrics(d->mList->fontSpec().font());
+ finalWidth = fontMetrics.width(candidates[i]);
+ if (finalWidth > longestwidth) {
+ longestwidth = finalWidth;
+ }
+ }
+
+ d->mList->setMinimumWidth(HbCandListMinWidth);
+ d->numCandidates = candidates.count();
+ d->longestStringWidth = longestwidth;
+
+ //always scroll to first item
+ d->mList->setCurrentRow(0);
+ d->mList->scrollTo(d->mList->currentIndex());
+
+ d->calculateAndSetSize((qreal)HbDeviceProfile::current().logicalSize().width() * HbCandListMaxWidthMultiplier);
+}
+
+/*!
+Inherited from HbDialog.
+*/
+void HbCandidateList::keyPressEvent(QKeyEvent* event)
+{
+ Q_D(HbCandidateList);
+
+ if (event->key() == Qt::Key_Space
+ || event->key() == Qt::Key_Enter
+ || event->key() == Qt::Key_Return
+ || event->key() == Qt::Key_Right
+ || event->key() == Qt::Key_Left) {
+ d->mInput->candidatePopupClosed(event->key());
+ hide();
+ }
+}
+
+/*!
+Inherited from HbDialog.
+*/
+void HbCandidateList::closeEvent(QCloseEvent* /*event*/)
+{
+ hide();
+ emit candidatePopupCancelled();
+}
+
+/*!
+Called when an item on the list is activated. Hides the list and informs the input.
+*/
+void HbCandidateList::itemActivated(HbListWidgetItem *item)
+{
+ Q_UNUSED(item);
+ Q_D(HbCandidateList);
+
+ d->mInput->candidatePopupClosed();
+ hide();
+}
+
+/*!
+Returns the currently selected candidate on the list.
+*/
+QString HbCandidateList::currentCandidate()
+{
+ Q_D(HbCandidateList);
+ return d->mList->currentItem()->text();
+}
+
+/*!
+Sets the maximum number of visible candidates.
+*/
+void HbCandidateList::setNumberOfVisibleLines(int numLines)
+{
+ Q_D(HbCandidateList);
+
+ d->numRows = numLines;
+ update();
+}
+/*!
+this event handler is called, for Hide events, is delivered after the widget has been hidden.
+*/
+void HbCandidateList::hideEvent(QHideEvent * event)
+{
+ HbDialog::hideEvent(event);
+}
+
+void HbCandidateList::updatePrimitives()
+{
+ Q_D(HbCandidateList);
+
+ d->mFrameBackground->frameDrawer().setFrameType(HbFrameDrawer::NinePieces);
+ d->mFrameBackground->frameDrawer().setFrameGraphicsName("qtg_fr_popup_secondary");
+ d->mFrameBackground->setGeometry(boundingRect());
+}
+
+/*!
+Finds correct size and position for auto-completion popup. It checks if there is enough space to display candidate popup,
+finds out whether it is display above or below the editor and sets correct width.
+Returns true if suitable position was found and set.
+*/
+bool HbCandidateList::setSizeAndPositionForAutoCompletion(HbVkbHost *vkbHost)
+{
+ Q_D(HbCandidateList);
+
+ if (vkbHost && d->mInput && d->mInput->focusObject()) {
+ QRectF freeViewRect = vkbHost->applicationArea();
+ QRectF microFocus = d->mInput->focusObject()->microFocus();
+
+ if (freeViewRect.isValid() &&
+ microFocus.isValid() &&
+ freeViewRect.contains(microFocus)) {
+ QRectF topRect = freeViewRect;
+ topRect.setBottom(microFocus.top());
+ topRect.adjust(HbAutoComplPopupSideMargin, HbAutoComplPopupVerticalMargin, -HbAutoComplPopupSideMargin, -HbAutoComplPopupVerticalMargin);
+
+ QRectF bottomRect = freeViewRect;
+ bottomRect.setTop(microFocus.bottom());
+ bottomRect.adjust(HbAutoComplPopupSideMargin, HbAutoComplPopupVerticalMargin, -HbAutoComplPopupSideMargin, -HbAutoComplPopupVerticalMargin);
+
+ if (topRect.height() > bottomRect.height()) {
+ if (topRect.height() > HbAutoComplPopupMinAllowedHeight) {
+ qreal finalHeight = (size().height() < topRect.height() ? size().height() : topRect.height());
+ topRect.setTop(topRect.bottom() - finalHeight);
+ resize(topRect.width(), topRect.height());
+ setPos(topRect.topLeft());
+ return true;
+ }
+ } else {
+ if (bottomRect.height() > HbAutoComplPopupMinAllowedHeight) {
+ qreal finalHeight = (size().height() < bottomRect.height() ? size().height() : bottomRect.height());
+ bottomRect.setHeight(finalHeight);
+ resize(bottomRect.width(), bottomRect.height());
+ setPos(bottomRect.topLeft());
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+// End of file