34 #include "hbevent.h" |
34 #include "hbevent.h" |
35 #include "hbwidgetfeedback.h" |
35 #include "hbwidgetfeedback.h" |
36 #include "hbmenu.h" |
36 #include "hbmenu.h" |
37 #include "hbaction.h" |
37 #include "hbaction.h" |
38 #include "hbselectioncontrol_p.h" |
38 #include "hbselectioncontrol_p.h" |
39 #include "hbmeshlayout_p.h" |
|
40 #include "hbsmileyengine_p.h" |
39 #include "hbsmileyengine_p.h" |
41 #include "hbinputeditorinterface.h" |
40 #include "hbinputeditorinterface.h" |
42 #include "hbfeaturemanager_p.h" |
41 #include "hbfeaturemanager_r.h" |
43 #include "hbtextmeasurementutility_p.h" |
42 #include "hbtextmeasurementutility_p.h" |
44 #include "hbtapgesture.h" |
43 #include "hbtapgesture.h" |
45 #include "hbpangesture.h" |
44 #include "hbpangesture.h" |
|
45 #include "hbnamespace_p.h" |
46 |
46 |
47 #include <QApplication> |
47 #include <QApplication> |
48 #include "hbpopup.h" |
48 #include "hbpopup.h" |
49 #include "hbformatdialog.h" |
49 #include "hbformatdialog.h" |
50 #include <QTextList> |
50 #include <QTextList> |
214 matchCursor.setPosition(oldPos); |
224 matchCursor.setPosition(oldPos); |
215 d->smileyEngineInstance()->insertSmiley(matchCursor); |
225 d->smileyEngineInstance()->insertSmiley(matchCursor); |
216 |
226 |
217 d->cursorChanged(HbValidator::CursorChangeFromContentUpdate); |
227 d->cursorChanged(HbValidator::CursorChangeFromContentUpdate); |
218 } |
228 } |
219 } |
229 } else { //HbEvent handler |
|
230 if (event->type() == HbEvent::InputMethodFocusIn) { |
|
231 d->setInputFocusEnabled(true); |
|
232 |
|
233 } else if (event->type() == HbEvent::InputMethodFocusOut) { |
|
234 d->setInputFocusEnabled(false); |
|
235 } |
|
236 } |
|
237 |
220 return HbWidget::event(event); |
238 return HbWidget::event(event); |
221 } |
239 } |
222 |
240 |
223 QVariant HbAbstractEdit::inputMethodQuery (Qt::InputMethodQuery query) const |
241 QVariant HbAbstractEdit::inputMethodQuery (Qt::InputMethodQuery query) const |
224 { |
242 { |
681 \reimp |
700 \reimp |
682 */ |
701 */ |
683 void HbAbstractEdit::updatePrimitives() |
702 void HbAbstractEdit::updatePrimitives() |
684 { |
703 { |
685 Q_D(HbAbstractEdit); |
704 Q_D(HbAbstractEdit); |
686 HbWidget::updatePrimitives(); |
705 |
687 |
706 if (d->polished && !d->updatePrimitivesInProgress) { |
688 if (d->scrollArea) { |
707 |
689 d->doc->setTextWidth(d->scrollArea->size().width()); |
708 d->updatePrimitivesInProgress = true; |
690 if(d->placeholderDoc) { |
709 |
691 d->placeholderDoc->setTextWidth(d->scrollArea->size().width()); |
710 HbWidget::updatePrimitives(); |
692 } |
711 |
693 } |
712 if (d->scrollArea) { |
694 QRectF canvasGeom(QRectF(QPointF(0,0),d->doc->size())); |
713 if(!qFuzzyCompare(d->doc->textWidth(), d->scrollArea->size().width())){ |
695 if(d->scrollArea) { |
714 d->doc->setTextWidth(d->scrollArea->size().width()); |
696 canvasGeom.setHeight(qMax(d->scrollArea->size().height(), d->doc->size().height())); |
715 if(d->placeholderDoc) { |
697 } |
716 d->placeholderDoc->setTextWidth(d->scrollArea->size().width()); |
698 //Changed from setGeometry() to setPreferredSize() because it causes |
717 } |
699 //weird input behavior otherwise. |
718 } |
700 d->canvas->setPreferredSize(canvasGeom.size()); |
719 } |
701 d->ensureCursorVisible(); |
720 QRectF canvasGeom(QRectF(QPointF(0,0),d->doc->size())); |
702 if (d->selectionControl) { |
721 if(d->scrollArea) { |
703 d->selectionControl->updatePrimitives(); |
722 canvasGeom.setHeight(qMax(d->scrollArea->size().height(), d->doc->size().height())); |
704 } |
723 } |
705 |
724 |
|
725 d->canvas->setGeometry(canvasGeom); |
|
726 |
|
727 d->ensureCursorVisible(); |
|
728 if (d->selectionControl) { |
|
729 d->selectionControl->updatePrimitives(); |
|
730 } |
|
731 |
|
732 d->updatePrimitivesInProgress=false; |
|
733 } |
706 } |
734 } |
707 |
735 |
708 /*! |
736 /*! |
709 Replaces editor content with \a text. |
737 Replaces editor content with \a text. |
710 |
738 |
917 |
944 |
918 if (cursorPos == -1) |
945 if (cursorPos == -1) |
919 return; |
946 return; |
920 |
947 |
921 setCursorPosition(cursorPos); |
948 setCursorPosition(cursorPos); |
922 const QTextCursor oldSelection = d->cursor; |
|
923 d->cursor.select(QTextCursor::WordUnderCursor); |
949 d->cursor.select(QTextCursor::WordUnderCursor); |
924 emit selectionChanged(oldSelection, d->cursor); |
|
925 d->repaintOldAndNewSelection(oldSelection); |
|
926 d->cursorChanged(HbValidator::CursorChangeFromMouse); |
950 d->cursorChanged(HbValidator::CursorChangeFromMouse); |
927 //TODO: focus is in VKB so needs to re-focus to editor |
|
928 // setFocus(); |
|
929 } |
951 } |
930 |
952 |
931 /*! |
953 /*! |
932 Selects all the text in the editor. |
954 Selects all the text in the editor. |
933 \sa selectClickedWord deselect |
955 \sa selectClickedWord deselect |
934 */ |
956 */ |
935 void HbAbstractEdit::selectAll() |
957 void HbAbstractEdit::selectAll() |
936 { |
958 { |
937 Q_D(HbAbstractEdit); |
959 Q_D(HbAbstractEdit); |
938 const QTextCursor oldSelection = d->cursor; |
|
939 d->cursor.select(QTextCursor::Document); |
960 d->cursor.select(QTextCursor::Document); |
940 emit selectionChanged(oldSelection, d->cursor); |
|
941 d->repaintOldAndNewSelection(oldSelection); |
|
942 d->cursorChanged(HbValidator::CursorChangeFromMouse); |
961 d->cursorChanged(HbValidator::CursorChangeFromMouse); |
943 } |
962 } |
944 |
963 |
945 /*! |
964 /*! |
946 Deselects the text in the editor if there is text selected. |
965 Deselects the text in the editor if there is text selected. |
947 \sa selectClickedWord selectAll |
966 \sa selectClickedWord selectAll |
948 */ |
967 */ |
949 void HbAbstractEdit::deselect() |
968 void HbAbstractEdit::deselect() |
950 { |
969 { |
951 Q_D(HbAbstractEdit); |
970 Q_D(HbAbstractEdit); |
952 const QTextCursor oldSelection = d->cursor; |
|
953 d->cursor.clearSelection(); |
971 d->cursor.clearSelection(); |
954 emit selectionChanged(oldSelection, d->cursor); |
972 d->cursorChanged(HbValidator::CursorChangeFromMouse); |
955 } |
973 } |
956 |
974 |
957 /*! |
975 /*! |
958 Launches the format user interface. |
976 Launches the format user interface. |
959 */ |
977 */ |
1011 QTextDocumentFragment fragment; |
1029 QTextDocumentFragment fragment; |
1012 #ifndef QT_NO_TEXTHTMLPARSER |
1030 #ifndef QT_NO_TEXTHTMLPARSER |
1013 if (source->hasFormat(QLatin1String("application/x-qrichtext"))) { |
1031 if (source->hasFormat(QLatin1String("application/x-qrichtext"))) { |
1014 QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext"))); |
1032 QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext"))); |
1015 richtext.prepend(QLatin1String("<meta name=\"qrichtext\" content=\"1\" />")); |
1033 richtext.prepend(QLatin1String("<meta name=\"qrichtext\" content=\"1\" />")); |
1016 fragment = QTextDocumentFragment::fromHtml(filterInputText(richtext), d->doc); |
1034 fragment = QTextDocumentFragment::fromHtml(richtext, d->doc); |
1017 hasData = true; |
1035 hasData = true; |
1018 } else if (source->hasHtml()) { |
1036 } else if (source->hasHtml()) { |
1019 fragment = QTextDocumentFragment::fromHtml(filterInputText(source->html()), d->doc); |
1037 fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc); |
1020 hasData = true; |
1038 hasData = true; |
1021 } else |
1039 } else |
1022 #endif //QT_NO_TEXTHTMLPARSER |
1040 #endif //QT_NO_TEXTHTMLPARSER |
1023 { |
1041 { |
1024 QString text = source->text(); |
1042 QString text = source->text(); |
1122 \sa QTextCursor::movePosition() |
1133 \sa QTextCursor::movePosition() |
1123 */ |
1134 */ |
1124 void HbAbstractEdit::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode) |
1135 void HbAbstractEdit::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode) |
1125 { |
1136 { |
1126 Q_D(HbAbstractEdit); |
1137 Q_D(HbAbstractEdit); |
1127 //const QTextCursor oldCursor = d->cursor; |
|
1128 d->cursor.movePosition(op, mode); |
1138 d->cursor.movePosition(op, mode); |
1129 |
1139 |
1130 d->updateCurrentCharFormat(); |
1140 d->updateCurrentCharFormat(); |
1131 |
1141 |
1132 d->ensureCursorVisible(); |
1142 d->ensureCursorVisible(); |
1133 QTextCursor previousCursor(d->cursor); |
1143 QTextCursor previousCursor(d->cursor); |
1134 previousCursor.setPosition(d->previousCursorAnchor); |
1144 previousCursor.setPosition(d->previousCursorAnchor); |
1135 previousCursor.setPosition(d->previousCursorPosition, QTextCursor::KeepAnchor); |
1145 previousCursor.setPosition(d->previousCursorPosition, QTextCursor::KeepAnchor); |
1136 d->repaintOldAndNewSelection(previousCursor); |
|
1137 d->cursorChanged(HbValidator::CursorChangeFromOperation); |
1146 d->cursorChanged(HbValidator::CursorChangeFromOperation); |
1138 } |
1147 } |
1139 |
1148 |
1140 /*! |
1149 /*! |
1141 Returns the bounding rect for given text block. |
1150 Returns the bounding rect for given text block. |
1283 void HbAbstractEdit::showContextMenu(QPointF position) |
1292 void HbAbstractEdit::showContextMenu(QPointF position) |
1284 { |
1293 { |
1285 Q_D(HbAbstractEdit); |
1294 Q_D(HbAbstractEdit); |
1286 HbMenu *menu = createContextMenu(); |
1295 HbMenu *menu = createContextMenu(); |
1287 |
1296 |
|
1297 QTextBlock block = d->cursor.block(); |
|
1298 QTextLayout *layout = block.layout(); |
|
1299 if(layout && !layout->preeditAreaText().isEmpty()) |
|
1300 { |
|
1301 // there's pre-edit text present, it needs to be commited 1st |
|
1302 if(qApp->inputContext()) { |
|
1303 qApp->inputContext()->reset(); |
|
1304 } |
|
1305 } |
|
1306 |
1288 if (!menu) { |
1307 if (!menu) { |
1289 menu = new HbMenu(); |
1308 menu = new HbMenu(); |
1290 } |
1309 } |
1291 |
1310 |
1292 menu->setAttribute(Hb::InputMethodNeutral); |
|
1293 |
|
1294 if (d->cursor.hasSelection() && d->canCut()) { |
1311 if (d->cursor.hasSelection() && d->canCut()) { |
1295 connect( |
1312 connect( |
1296 menu->addAction("Cut"), SIGNAL(triggered()), |
1313 menu->addAction(hbTrId("txt_common_menu_cut")), SIGNAL(triggered()), |
1297 this, SLOT(cut())); |
1314 this, SLOT(cut())); |
1298 } |
1315 } |
1299 if (d->cursor.hasSelection() && d->canCopy()) { |
1316 if (d->cursor.hasSelection() && d->canCopy()) { |
1300 connect( |
1317 connect( |
1301 menu->addAction("Copy"), SIGNAL(triggered()), |
1318 menu->addAction(hbTrId("txt_common_menu_copy")), SIGNAL(triggered()), |
1302 this, SLOT(copy())); |
1319 this, SLOT(copy())); |
1303 } |
1320 } |
1304 if (!d->cursor.hasSelection() && !d->doc->isEmpty() && d->canCopy()){ |
1321 if (!d->cursor.hasSelection() && !d->doc->isEmpty() && d->canCopy()){ |
1305 connect( |
1322 connect( |
1306 menu->addAction("Select"), SIGNAL(triggered()), |
1323 menu->addAction(hbTrId("txt_common_menu_select")), SIGNAL(triggered()), |
1307 this, SLOT(selectClickedWord())); |
1324 this, SLOT(selectClickedWord())); |
1308 connect( |
1325 connect( |
1309 menu->addAction("Select all"), SIGNAL(triggered()), |
1326 menu->addAction(hbTrId("txt_common_menu_select_all_contents")), SIGNAL(triggered()), |
1310 this, SLOT(selectAll())); |
1327 this, SLOT(selectAll())); |
1311 } |
1328 } |
1312 if (d->canPaste()) { |
1329 if (d->canPaste()) { |
1313 connect( |
1330 connect( |
1314 menu->addAction("Paste"), SIGNAL(triggered()), |
1331 menu->addAction(hbTrId("txt_common_menu_paste")), SIGNAL(triggered()), |
1315 this, SLOT(paste())); |
1332 this, SLOT(paste())); |
1316 } |
1333 } |
1317 if (d->cursor.hasSelection()) { |
1334 if (d->cursor.hasSelection()) { |
1318 connect( |
1335 connect( |
1319 menu->addAction("Deselect"), SIGNAL(triggered()), |
1336 menu->addAction(hbTrId("txt_common_menu_deselect")), SIGNAL(triggered()), |
1320 this, SLOT(deselect())); |
1337 this, SLOT(deselect())); |
1321 } |
1338 } |
1322 if (d->canFormat()) { |
1339 if (d->canFormat()) { |
1323 connect( |
1340 connect( |
1324 menu->addAction("Format"), SIGNAL(triggered()), |
1341 menu->addAction(hbTrId("txt_common_menu_format")), SIGNAL(triggered()), |
1325 this, SLOT(format())); |
1342 this, SLOT(format())); |
1326 } |
1343 } |
1327 |
1344 |
1328 emit aboutToShowContextMenu(menu, d->tapPosition); |
1345 emit aboutToShowContextMenu(menu, d->tapPosition); |
1329 |
1346 |
1330 if(menu->actions().count() > 0){ |
1347 if(menu->actions().count() > 0){ |
1331 d->minimizeInputPanel(); |
1348 // d->minimizeInputPanel(); |
1332 menu->setPreferredPos(position); |
1349 menu->setPreferredPos(position); |
1333 menu->show(); |
1350 menu->show(); |
1334 } |
1351 } |
1335 } |
1352 } |
1336 |
1353 |
1679 // The QGestureEvent knows the viewport through which the gesture |
1696 // The QGestureEvent knows the viewport through which the gesture |
1680 // was triggered. |
1697 // was triggered. |
1681 QPointF pos = mapFromScene(event->mapToGraphicsScene(tap->position())); |
1698 QPointF pos = mapFromScene(event->mapToGraphicsScene(tap->position())); |
1682 switch(tap->state()) { |
1699 switch(tap->state()) { |
1683 case Qt::GestureStarted: |
1700 case Qt::GestureStarted: |
|
1701 scene()->setProperty(HbPrivate::OverridingGesture.latin1(),Qt::TapGesture); |
|
1702 if (!tap->property(HbPrivate::ThresholdRect.latin1()).toRect().isValid()) { |
|
1703 tap->setProperty(HbPrivate::ThresholdRect.latin1(), mapRectToScene(boundingRect()).toRect()); |
|
1704 } |
|
1705 |
1684 d->tapPosition = pos; |
1706 d->tapPosition = pos; |
1685 HbWidgetFeedback::triggered(this, Hb::InstantPressed); |
1707 HbWidgetFeedback::triggered(this, Hb::InstantPressed); |
1686 break; |
1708 break; |
1687 case Qt::GestureUpdated: |
1709 case Qt::GestureUpdated: |
1688 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
1710 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
1689 d->longTapGesture(pos); |
1711 d->openInputPanel(); |
|
1712 d->longTapGesture(pos); |
1690 } |
1713 } |
1691 break; |
1714 break; |
1692 case Qt::GestureFinished: |
1715 case Qt::GestureFinished: |
|
1716 scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant()); |
|
1717 |
1693 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
1718 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
1694 } else { |
1719 } else { |
1695 d->tapGesture(pos); |
1720 d->tapGesture(pos); |
1696 } |
1721 } |
1697 |
1722 |
1714 /*! |
1741 /*! |
1715 Returns the filtered text, or \a text if no input filter attached to editor. |
1742 Returns the filtered text, or \a text if no input filter attached to editor. |
1716 */ |
1743 */ |
1717 QString HbAbstractEdit::filterInputText(const QString &text) |
1744 QString HbAbstractEdit::filterInputText(const QString &text) |
1718 { |
1745 { |
1719 HbEditorInterface editorInterface(this); |
1746 Q_D(HbAbstractEdit); |
1720 HbInputFilter *inputFilter = editorInterface.filter(); |
1747 QString filteredText(text); |
1721 if (!text.isEmpty() && inputFilter) { |
1748 d->filterInputText(filteredText); |
1722 QString filteredText; |
1749 return filteredText; |
1723 foreach(QChar c, text) { |
1750 } |
1724 if (inputFilter->filter(c)) { |
|
1725 filteredText.append(c); |
|
1726 } |
|
1727 } |
|
1728 return filteredText; |
|
1729 } |
|
1730 return text; |
|
1731 } |
|