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 "hbsmileyengine_p.h" |
39 #include "hbsmileyengine_p.h" |
40 #include "hbinputeditorinterface.h" |
40 #include "hbinputeditorinterface.h" |
41 #include "hbfeaturemanager_r.h" |
41 #ifdef HB_TEXT_MEASUREMENT_UTILITY |
42 #include "hbtextmeasurementutility_p.h" |
42 #include "hbtextmeasurementutility_r.h" |
43 #include "hbtapgesture.h" |
43 #include "hbtextmeasurementutility_r_p.h" |
44 #include "hbpangesture.h" |
44 #endif |
45 #include "hbnamespace_p.h" |
|
46 |
45 |
47 #include <QApplication> |
46 #include <QApplication> |
48 #include "hbpopup.h" |
47 #include "hbpopup.h" |
49 #include "hbformatdialog.h" |
48 #include "hbformatdialog.h" |
50 #include <QTextList> |
49 #include <QTextList> |
91 |
90 |
92 \li Editor content: Both rich text and plain text are supported in HbAbstractEdit. Depending on the actual |
91 \li Editor content: Both rich text and plain text are supported in HbAbstractEdit. Depending on the actual |
93 editor widget only one or the other type might be supported. Plain text content is set with |
92 editor widget only one or the other type might be supported. Plain text content is set with |
94 method \ref setPlainText. Method \ref toPlainText returns the content converted to plain text. |
93 method \ref setPlainText. Method \ref toPlainText returns the content converted to plain text. |
95 |
94 |
96 \li Focus control: Editor is responsble for controlling the input panel visibility. In some situations special editor may need to also handle this, but in general it is always handled by HbAbstractEdit. |
95 \li Focus control: Editor is responsble for controlling the input panel visibility. In some situations special editor may need to also handle this, |
97 Input panel is closed when editor loses focus. |
96 but in general it is always handled by HbAbstractEdit. Input panel is closed when editor loses focus. |
|
97 However when setting the editor focus programmatically with setFocus() it is the responsibility of client to control the visibility of input panel. |
98 |
98 |
99 \li Cursor control: A convenience method \ref moveCursor can also be used to move the cursor. |
99 \li Cursor control: A convenience method \ref moveCursor can also be used to move the cursor. |
100 |
100 |
101 \li Scrolling: When e.g. the size of the content exceeds the size of editor, method \ref setScrollable |
101 \li Scrolling: When e.g. the size of the content exceeds the size of editor, method \ref setScrollable |
102 can be used to make the editor scrollable. Method isScrollable tells whether the editor is scrollable or not. |
102 can be used to make the editor scrollable. Method isScrollable tells whether the editor is scrollable or not. |
105 \li Input validation: The validator for restricting the content input is set with method \ref setValidator. Only \ref HbValidator |
105 \li Input validation: The validator for restricting the content input is set with method \ref setValidator. Only \ref HbValidator |
106 based validators can be used. |
106 based validators can be used. |
107 |
107 |
108 \section composition Widget composition |
108 \section composition Widget composition |
109 |
109 |
110 Editor widget consists of these sub-items visible in the picture. |
110 The size of the canvas is always same as the size of the document, and the width of the scroll area is same as the width of the document. |
111 In this example editor shows only one visible line of the content. |
|
112 |
|
113 \image html editor_composition.jpg |
|
114 |
|
115 The size of the canvas is always same as the size of the document, and the width of the scroll area |
|
116 is same as the width of the document. The editor margins are defined in the CSS. |
|
117 |
|
118 */ |
111 */ |
119 |
112 |
120 /*! |
113 /*! |
121 \fn void HbAbstractEdit::contentsChanged() |
114 \fn void HbAbstractEdit::contentsChanged() |
122 |
115 |
223 QTextCursor matchCursor(document()); |
219 QTextCursor matchCursor(document()); |
224 matchCursor.setPosition(oldPos); |
220 matchCursor.setPosition(oldPos); |
225 d->smileyEngineInstance()->insertSmiley(matchCursor); |
221 d->smileyEngineInstance()->insertSmiley(matchCursor); |
226 |
222 |
227 d->cursorChanged(HbValidator::CursorChangeFromContentUpdate); |
223 d->cursorChanged(HbValidator::CursorChangeFromContentUpdate); |
|
224 } else if (p == "Magnifier") { |
|
225 QString param = property("Magnifier").toString(); |
|
226 |
|
227 if (param == "Enabled") { |
|
228 d->enableMagnifier = true; |
|
229 } else if (param == "Disabled") { |
|
230 d->enableMagnifier = false; |
|
231 } |
|
232 |
|
233 if (d->selectionControl) { |
|
234 d->selectionControl->setMagnifierEnabled(d->enableMagnifier); |
|
235 } |
228 } |
236 } |
229 } else { //HbEvent handler |
237 } else { //HbEvent handler |
230 if (event->type() == HbEvent::InputMethodFocusIn) { |
238 if (event->type() == HbEvent::InputMethodFocusIn) { |
231 d->setInputFocusEnabled(true); |
239 d->setInputFocusEnabled(true); |
232 |
240 |
281 || e->replacementLength() > 0; |
289 || e->replacementLength() > 0; |
282 |
290 |
283 d->cursor.beginEditBlock(); |
291 d->cursor.beginEditBlock(); |
284 |
292 |
285 if (isGettingInput) { |
293 if (isGettingInput) { |
|
294 if (d->selectionControl) { |
|
295 d->selectionControl->hideHandles(); |
|
296 d->updateCursorType(); |
|
297 } |
286 if (!d->imEditInProgress) { |
298 if (!d->imEditInProgress) { |
287 d->imEditInProgress = true; |
299 d->imEditInProgress = true; |
288 d->imPosition = d->selectionCursor.selectionStart(); |
300 d->imPosition = d->selectionCursor.selectionStart(); |
289 d->imRemoved = d->selectionCursor.selectionEnd() - d->selectionCursor.selectionStart(); |
301 d->imRemoved = d->selectionCursor.selectionEnd() - d->selectionCursor.selectionStart(); |
290 } |
302 } |
343 d->imAdded = e->commitString().length(); |
355 d->imAdded = e->commitString().length(); |
344 d->imRemoved = e->replacementLength(); |
356 d->imRemoved = e->replacementLength(); |
345 d->_q_contentsChanged(); |
357 d->_q_contentsChanged(); |
346 } |
358 } |
347 |
359 |
348 if(d->hasInputFocus()) { |
|
349 d->cursorOn = true; |
|
350 } |
|
351 d->ensureCursorVisible(); |
360 d->ensureCursorVisible(); |
|
361 d->canvas->setPreferredSize(d->calculatePreferredDocSize()); |
352 } |
362 } |
353 |
363 |
354 /*! |
364 /*! |
355 \reimp |
365 \reimp |
356 */ |
366 */ |
357 void HbAbstractEdit::keyPressEvent(QKeyEvent *event) |
367 void HbAbstractEdit::keyPressEvent(QKeyEvent *event) |
358 { |
368 { |
359 Q_D(HbAbstractEdit); |
369 Q_D(HbAbstractEdit); |
360 |
370 |
361 if (d->interactionFlags & Qt::NoTextInteraction) |
371 if (d->selectionControl) { |
362 return; |
372 d->selectionControl->hideHandles(); |
|
373 d->updateCursorType(); |
|
374 } |
363 |
375 |
364 #ifndef QT_NO_SHORTCUT |
376 #ifndef QT_NO_SHORTCUT |
365 #ifndef QT_NO_CLIPBOARD |
377 #ifndef QT_NO_CLIPBOARD |
366 if (event == QKeySequence::Copy) { |
378 if (event == QKeySequence::Copy) { |
367 event->accept(); |
379 event->accept(); |
487 Q_D(HbAbstractEdit); |
499 Q_D(HbAbstractEdit); |
488 |
500 |
489 HbWidget::focusInEvent(event); |
501 HbWidget::focusInEvent(event); |
490 |
502 |
491 d->selectionControl = HbSelectionControl::attachEditor(this); |
503 d->selectionControl = HbSelectionControl::attachEditor(this); |
492 |
504 d->selectionControl->setMagnifierEnabled(isSelectionControlEnabled()&&d->enableMagnifier); |
493 if (d->interactionFlags & Qt::NoTextInteraction) |
|
494 return; |
|
495 |
505 |
496 // It sets the cursor the focus item's depending on if |
506 // It sets the cursor the focus item's depending on if |
497 // the input panel is connceted or not |
507 // the input panel is connceted or not |
498 d->setInputFocusEnabled(d->hasInputFocus()); |
508 d->setInputFocusEnabled(d->hasInputFocus()); |
499 |
509 |
678 \deprecated HbAbstractEdit::primitive(HbStyle::Primitive) |
685 \deprecated HbAbstractEdit::primitive(HbStyle::Primitive) |
679 is deprecated. |
686 is deprecated. |
680 |
687 |
681 Returns pointer to a \a primitive of HbAbstractEdit. |
688 Returns pointer to a \a primitive of HbAbstractEdit. |
682 |
689 |
683 Available primitive is HbStyle::P_Edit_text. |
690 Available primitive is HbStylePrivate::P_Edit_text. |
684 |
691 |
685 \reimp |
692 \reimp |
686 \sa HbStyle::Primitive, HbWidget::primitive() |
693 \sa HbStyle::Primitive, HbWidget::primitive() |
687 */ |
694 */ |
688 QGraphicsItem *HbAbstractEdit::primitive (HbStyle::Primitive primitive) const |
695 QGraphicsItem *HbAbstractEdit::primitive (HbStyle::Primitive primitive) const |
689 { |
696 { |
690 Q_D(const HbAbstractEdit); |
697 Q_D(const HbAbstractEdit); |
691 |
698 const HbStylePrivate::Primitive p = (HbStylePrivate::Primitive)primitive; |
692 if (primitive == HbStyle::P_Edit_text) { |
699 if (p == HbStylePrivate::P_Edit_text) { |
693 return d->scrollArea; |
700 return d->scrollArea; |
694 } else { |
701 } else { |
695 return HbWidget::primitive(primitive); |
702 return HbWidget::primitive(primitive); |
696 } |
703 } |
697 } |
704 } |
721 if(d->scrollArea) { |
728 if(d->scrollArea) { |
722 canvasGeom.setHeight(qMax(d->scrollArea->size().height(), d->doc->size().height())); |
729 canvasGeom.setHeight(qMax(d->scrollArea->size().height(), d->doc->size().height())); |
723 } |
730 } |
724 |
731 |
725 d->canvas->setGeometry(canvasGeom); |
732 d->canvas->setGeometry(canvasGeom); |
|
733 d->canvas->setPreferredSize(d->calculatePreferredDocSize()); |
726 |
734 |
727 d->ensureCursorVisible(); |
735 d->ensureCursorVisible(); |
728 if (d->selectionControl) { |
736 if (d->selectionControl) { |
729 d->selectionControl->updatePrimitives(); |
737 d->selectionControl->updatePrimitives(); |
730 } |
738 } |
775 void HbAbstractEdit::timerEvent(QTimerEvent *e) |
783 void HbAbstractEdit::timerEvent(QTimerEvent *e) |
776 { |
784 { |
777 Q_D(HbAbstractEdit); |
785 Q_D(HbAbstractEdit); |
778 |
786 |
779 if (e->timerId() == d->cursorBlinkTimer.timerId()) { |
787 if (e->timerId() == d->cursorBlinkTimer.timerId()) { |
780 d->cursorOn = !d->cursorOn; |
788 d->cursorOn = !d->cursorOn; |
781 |
|
782 if (d->cursor.hasSelection()) |
|
783 d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected) != 0); |
|
784 |
|
785 d->repaintCursor(); |
789 d->repaintCursor(); |
|
790 } else if (e->timerId() == d->doubleTapTimer.timerId()) { |
|
791 d->doubleTapTimer.stop(); |
|
792 |
|
793 if (d->tapCounter == 1 && d->showContextMenu && contextMenuFlags().testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) { |
|
794 showContextMenu(mapToScene(d->tapPosition)); |
|
795 } |
|
796 d->tapCounter = 0; |
786 } |
797 } |
787 } |
798 } |
788 |
799 |
789 /*! |
800 /*! |
790 This is a slot for listening a signal with a same name from QTextDocument. |
801 This is a slot for listening a signal with a same name from QTextDocument. |
1062 QRectF rect = d->rectForPositionInCanvasCoords(position, edge); |
1074 QRectF rect = d->rectForPositionInCanvasCoords(position, edge); |
1063 rect = mapRectFromItem(d->canvas,rect); |
1075 rect = mapRectFromItem(d->canvas,rect); |
1064 return rect; |
1076 return rect; |
1065 } |
1077 } |
1066 |
1078 |
|
1079 |
1067 /*! |
1080 /*! |
1068 Returns the contents as plain text. If smiley recognition is enabled |
1081 Returns the contents as plain text. If smiley recognition is enabled |
1069 all the smiley images will be replaced by their textual representations. |
1082 all the smiley images will be replaced by their textual representations. |
1070 |
1083 |
1071 \sa QTextDocument::toPlainText() setSmileysEnabled() |
1084 \sa QTextDocument::toPlainText() setSmileysEnabled() |
1200 void HbAbstractEdit::drawContents(QPainter *painter, const QStyleOptionGraphicsItem &option) |
1215 void HbAbstractEdit::drawContents(QPainter *painter, const QStyleOptionGraphicsItem &option) |
1201 { |
1216 { |
1202 Q_D(HbAbstractEdit); |
1217 Q_D(HbAbstractEdit); |
1203 #ifdef HB_DEBUG_EDITOR_DRAW_RECTS |
1218 #ifdef HB_DEBUG_EDITOR_DRAW_RECTS |
1204 painter->setPen(Qt::green); |
1219 painter->setPen(Qt::green); |
1205 /*for(QTextBlock tb = d->doc->begin(); tb.isValid(); tb=tb.next()) { |
1220 /* |
1206 painter->drawRect(blockBoundingRect(tb)); |
1221 for(QTextBlock tb = d->doc->begin(); tb.isValid(); tb=tb.next()) { |
|
1222 painter->drawRect(blockBoundingRect(tb)); |
|
1223 |
|
1224 // Draw lines |
|
1225 const QPointF layoutPos = blockBoundingRect(tb).topLeft(); |
|
1226 |
|
1227 painter->setPen(Qt::red); |
|
1228 const QTextLayout *layout = tb.layout(); |
|
1229 for(int i = 0;i < layout->lineCount();i++) { |
|
1230 QTextLine line = layout->lineAt(i); |
|
1231 |
|
1232 // Draw descent rect |
|
1233 QRectF rect = QRectF(layoutPos.x() + line.x(), |
|
1234 layoutPos.y() + line.y() + line.ascent(), |
|
1235 line.width(),line.descent()+1); |
|
1236 painter->drawRect(rect); |
|
1237 } |
1207 }*/ |
1238 }*/ |
1208 painter->drawRect(d->doc->documentLayout()->frameBoundingRect( |
1239 painter->drawRect(d->doc->documentLayout()->frameBoundingRect( |
1209 d->doc->rootFrame()).adjusted(2,2,-2,-2)); |
1240 d->doc->rootFrame()).adjusted(2,2,-2,-2)); |
1210 painter->setOpacity(0.3); |
1241 painter->setOpacity(0.3); |
1211 painter->setPen(Qt::blue); |
1242 painter->setPen(Qt::blue); |
1216 QRectF viewRect = d->viewPortRect(); |
1247 QRectF viewRect = d->viewPortRect(); |
1217 QRectF intersected = option.exposedRect.intersected(mapRectToItem(d->canvas, viewRect)); |
1248 QRectF intersected = option.exposedRect.intersected(mapRectToItem(d->canvas, viewRect)); |
1218 |
1249 |
1219 |
1250 |
1220 QAbstractTextDocumentLayout::PaintContext ctx = d->getPaintContext(); |
1251 QAbstractTextDocumentLayout::PaintContext ctx = d->getPaintContext(); |
1221 // Save painter state that will be modified |
|
1222 QRegion clipRegion = painter->clipRegion(); |
|
1223 |
1252 |
1224 if (option.exposedRect.isValid()){ |
1253 if (option.exposedRect.isValid()){ |
1225 painter->setClipRect(intersected, Qt::IntersectClip); |
1254 painter->setClipRect(intersected, Qt::IntersectClip); |
1226 } |
1255 } |
1227 ctx.clip = intersected; |
1256 ctx.clip = intersected; |
|
1257 // Disable drawing of Qt cursor and save old cursor position |
|
1258 int oldCursorPosition = ctx.cursorPosition; |
|
1259 ctx.cursorPosition = -1; |
1228 |
1260 |
1229 d->drawContentBackground(painter, option); |
1261 d->drawContentBackground(painter, option); |
1230 |
1262 |
1231 if(document()->isEmpty() && d->placeholderDoc && !d->placeholderDoc->isEmpty()) { |
1263 if(document()->isEmpty() && d->placeholderDoc && !d->placeholderDoc->isEmpty()) { |
1232 QTextBlock block = d->cursor.block(); |
1264 QTextBlock block = d->cursor.block(); |
1233 QTextLayout *layout = block.layout(); |
1265 QTextLayout *layout = block.layout(); |
1234 |
1266 |
1235 if(!layout->preeditAreaText().length()) { |
1267 if(!layout->preeditAreaText().length()) { |
1236 QColor textColor(ctx.palette.color(QPalette::Text)); |
1268 QColor textColor(ctx.palette.color(QPalette::Text)); |
1237 QColor hintText(ctx.palette.color(QPalette::NoRole)); |
1269 QColor hintText(ctx.palette.color(QPalette::NoRole)); |
1238 int cursorPos = ctx.cursorPosition; |
|
1239 ctx.cursorPosition = -1; |
|
1240 ctx.palette.setColor(QPalette::Text, hintText); |
1270 ctx.palette.setColor(QPalette::Text, hintText); |
1241 |
1271 |
1242 d->placeholderDoc->documentLayout()->draw(painter, ctx); |
1272 d->placeholderDoc->documentLayout()->draw(painter, ctx); |
1243 |
1273 |
1244 ctx.palette.setColor(QPalette::Text, textColor); |
1274 ctx.palette.setColor(QPalette::Text, textColor); |
1245 ctx.cursorPosition = cursorPos; |
|
1246 } |
1275 } |
1247 } |
1276 } |
1248 document()->documentLayout()->draw(painter, ctx); |
1277 document()->documentLayout()->draw(painter, ctx); |
1249 // Draw the pins for the selection handle |
1278 ctx.cursorPosition = oldCursorPosition; |
1250 d->drawSelectionEdges(painter, ctx); |
1279 d->drawCursor(painter, ctx); |
1251 |
1280 |
1252 #ifdef HB_DEBUG_EDITOR_HANDLES |
1281 #ifdef HB_DEBUG_EDITOR_HANDLES |
1253 QRectF a = rectForPosition(d->cursor.anchor()); |
1282 QRectF a = rectForPosition(d->cursor.anchor()); |
1254 QRectF c = rectForPosition(d->cursor.position()); |
1283 QRectF c = rectForPosition(d->cursor.position()); |
1255 |
1284 |
1258 painter->setPen(Qt::green); |
1287 painter->setPen(Qt::green); |
1259 painter->drawRect(c); |
1288 painter->drawRect(c); |
1260 painter->setPen(Qt::red); |
1289 painter->setPen(Qt::red); |
1261 painter->drawRect(d->cursorRect()); |
1290 painter->drawRect(d->cursorRect()); |
1262 #endif |
1291 #endif |
1263 // Restore state |
|
1264 painter->setClipRegion(clipRegion); |
|
1265 } |
1292 } |
1266 |
1293 |
1267 /*! |
1294 /*! |
1268 Returns the used scroll area if edit is set as scrollable; |
1295 Returns the used scroll area if edit is set as scrollable; |
1269 otherwise returns null pointer. |
1296 otherwise returns null pointer. |
1308 menu = new HbMenu(); |
1335 menu = new HbMenu(); |
1309 } |
1336 } |
1310 |
1337 |
1311 if (d->cursor.hasSelection() && d->canCut()) { |
1338 if (d->cursor.hasSelection() && d->canCut()) { |
1312 connect( |
1339 connect( |
1313 menu->addAction(hbTrId("txt_common_menu_cut")), SIGNAL(triggered()), |
1340 menu->addAction(hbTrId("txt_common_menu_cut")), SIGNAL(triggered()), this, SLOT(cut())); |
1314 this, SLOT(cut())); |
|
1315 } |
1341 } |
1316 if (d->cursor.hasSelection() && d->canCopy()) { |
1342 if (d->cursor.hasSelection() && d->canCopy()) { |
1317 connect( |
1343 connect( |
1318 menu->addAction(hbTrId("txt_common_menu_copy")), SIGNAL(triggered()), |
1344 menu->addAction(hbTrId("txt_common_menu_copy")), SIGNAL(triggered()), this, SLOT(copy())); |
1319 this, SLOT(copy())); |
|
1320 } |
1345 } |
1321 if (!d->cursor.hasSelection() && !d->doc->isEmpty() && d->canCopy()){ |
1346 if (!d->cursor.hasSelection() && !d->doc->isEmpty() && d->canCopy()){ |
1322 connect( |
1347 connect( |
1323 menu->addAction(hbTrId("txt_common_menu_select")), SIGNAL(triggered()), |
1348 menu->addAction(hbTrId("txt_common_menu_select_all_contents")), SIGNAL(triggered()), this, SLOT(selectAll())); |
1324 this, SLOT(selectClickedWord())); |
|
1325 connect( |
|
1326 menu->addAction(hbTrId("txt_common_menu_select_all_contents")), SIGNAL(triggered()), |
|
1327 this, SLOT(selectAll())); |
|
1328 } |
1349 } |
1329 if (d->canPaste()) { |
1350 if (d->canPaste()) { |
1330 connect( |
1351 connect( |
1331 menu->addAction(hbTrId("txt_common_menu_paste")), SIGNAL(triggered()), |
1352 menu->addAction(hbTrId("txt_common_menu_paste")), SIGNAL(triggered()), this, SLOT(paste())); |
1332 this, SLOT(paste())); |
|
1333 } |
1353 } |
1334 if (d->cursor.hasSelection()) { |
1354 if (d->cursor.hasSelection()) { |
1335 connect( |
1355 connect( |
1336 menu->addAction(hbTrId("txt_common_menu_deselect")), SIGNAL(triggered()), |
1356 menu->addAction(hbTrId("txt_common_menu_deselect")), SIGNAL(triggered()), this, SLOT(deselect())); |
1337 this, SLOT(deselect())); |
|
1338 } |
1357 } |
1339 if (d->canFormat()) { |
1358 if (d->canFormat()) { |
1340 connect( |
1359 connect( |
1341 menu->addAction(hbTrId("txt_common_menu_format")), SIGNAL(triggered()), |
1360 menu->addAction(hbTrId("txt_common_menu_format")), SIGNAL(triggered()), this, SLOT(format())); |
1342 this, SLOT(format())); |
|
1343 } |
1361 } |
1344 |
1362 |
1345 emit aboutToShowContextMenu(menu, d->tapPosition); |
1363 emit aboutToShowContextMenu(menu, d->tapPosition); |
1346 |
1364 |
1347 if(menu->actions().count() > 0){ |
1365 if(menu->actions().count() > 0){ |
1348 // d->minimizeInputPanel(); |
|
1349 menu->setPreferredPos(position); |
1366 menu->setPreferredPos(position); |
1350 menu->show(); |
1367 menu->show(); |
1351 } |
1368 } |
|
1369 d->showContextMenu = false; |
1352 } |
1370 } |
1353 |
1371 |
1354 /*! |
1372 /*! |
1355 Returns the validator currently in use. |
1373 Returns the validator currently in use. |
1356 |
1374 |
1414 { |
1432 { |
1415 return document()->defaultTextOption().alignment(); |
1433 return document()->defaultTextOption().alignment(); |
1416 } |
1434 } |
1417 |
1435 |
1418 /*! |
1436 /*! |
1419 Returns current flags describing on which events context menu is shown |
1437 Returns current flags describing on which events context menu is shown. |
1420 |
1438 The default value is both Hb::ShowTextContextMenuOnSelectionClicked and Hb::ShowTextContextMenuOnLongPress are set. |
1421 \sa Hb::TextContextMenuFlag |
1439 \sa Hb::TextContextMenuFlag |
1422 */ |
1440 */ |
1423 Hb::TextContextMenuFlags HbAbstractEdit::contextMenuFlags() const |
1441 Hb::TextContextMenuFlags HbAbstractEdit::contextMenuFlags() const |
1424 { |
1442 { |
1425 Q_D(const HbAbstractEdit); |
1443 Q_D(const HbAbstractEdit); |
1426 |
1444 |
1427 return d->contextMenuShownOn; |
1445 return d->contextMenuShownOn; |
1428 } |
1446 } |
1429 |
1447 |
1430 /*! |
1448 /*! |
1431 Sets \a flags describing on which events context menu is shown |
1449 Sets \a flags describing on which events context menu is shown. |
|
1450 To disable context menu completely set \a flags to 0. |
1432 \sa Hb::TextContextMenuFlag |
1451 \sa Hb::TextContextMenuFlag |
1433 */ |
1452 */ |
1434 void HbAbstractEdit::setContextMenuFlags(Hb::TextContextMenuFlags flags) |
1453 void HbAbstractEdit::setContextMenuFlags(Hb::TextContextMenuFlags flags) |
1435 { |
1454 { |
1436 Q_D(HbAbstractEdit); |
1455 Q_D(HbAbstractEdit); |
1490 d->updatePlaceholderDocProperties(); |
1509 d->updatePlaceholderDocProperties(); |
1491 } |
1510 } |
1492 |
1511 |
1493 QString txt( placeholderText ); |
1512 QString txt( placeholderText ); |
1494 #ifdef HB_TEXT_MEASUREMENT_UTILITY |
1513 #ifdef HB_TEXT_MEASUREMENT_UTILITY |
1495 if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) { |
1514 if (HbTextMeasurementUtility::instance()->locTestMode()) { |
1496 if (placeholderText.endsWith(QChar(LOC_TEST_END))) { |
1515 if (placeholderText.endsWith(QChar(LOC_TEST_END))) { |
1497 int index = placeholderText.indexOf(QChar(LOC_TEST_START)); |
1516 int index = placeholderText.indexOf(QChar(LOC_TEST_START)); |
1498 setProperty( HbTextMeasurementUtilityNameSpace::textIdPropertyName, placeholderText.mid(index + 1, placeholderText.indexOf(QChar(LOC_TEST_END)) - index - 1) ); |
1517 setProperty( HbTextMeasurementUtilityNameSpace::textIdPropertyName, placeholderText.mid(index + 1, placeholderText.indexOf(QChar(LOC_TEST_END)) - index - 1) ); |
1499 setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, -1 ); |
1518 setProperty( HbTextMeasurementUtilityNameSpace::textMaxLines, -1 ); |
1500 txt = placeholderText.left(index); |
1519 txt = placeholderText.left(index); |
1518 or an empty string if no anchor exists at that point. |
1537 or an empty string if no anchor exists at that point. |
1519 */ |
1538 */ |
1520 QString HbAbstractEdit::anchorAt(const QPointF &pos) const |
1539 QString HbAbstractEdit::anchorAt(const QPointF &pos) const |
1521 { |
1540 { |
1522 Q_D(const HbAbstractEdit); |
1541 Q_D(const HbAbstractEdit); |
1523 return d->doc->documentLayout()->anchorAt(pos); |
1542 return d->doc->documentLayout()->anchorAt(mapToItem(d->canvas,pos)); |
1524 } |
1543 } |
1525 |
1544 |
1526 /*! |
1545 /*! |
1527 Returns the reference of the anchor the given cursor position, |
1546 Returns the reference of the anchor the given cursor position, |
1528 or an empty string if no anchor exists at that position. |
1547 or an empty string if no anchor exists at that position. |
1668 /*! |
1687 /*! |
1669 \reimp |
1688 \reimp |
1670 */ |
1689 */ |
1671 QVariant HbAbstractEdit::itemChange(GraphicsItemChange change, const QVariant &value) |
1690 QVariant HbAbstractEdit::itemChange(GraphicsItemChange change, const QVariant &value) |
1672 { |
1691 { |
1673 Q_D(const HbAbstractEdit); |
1692 Q_D(HbAbstractEdit); |
1674 if (change == QGraphicsItem::ItemScenePositionHasChanged) { |
1693 if (change == QGraphicsItem::ItemScenePositionHasChanged) { |
1675 if (d->selectionControl) { |
1694 if (d->selectionControl) { |
1676 d->selectionControl->updatePrimitives(); |
1695 d->selectionControl->updatePrimitives(); |
1677 } |
1696 } |
|
1697 } else if (change == QGraphicsItem::ItemEnabledHasChanged) { |
|
1698 if(!value.toBool()) { |
|
1699 if (d->hasInputFocus()) { |
|
1700 d->closeInputPanel(); |
|
1701 } |
|
1702 deselect(); |
|
1703 } |
|
1704 updatePrimitives(); |
1678 } |
1705 } |
1679 return HbWidget::itemChange(change, value); |
1706 return HbWidget::itemChange(change, value); |
1680 } |
1707 } |
1681 |
1708 |
1682 /*! |
1709 /*! |
1685 QChar HbAbstractEdit::characterAt(int pos) const |
1712 QChar HbAbstractEdit::characterAt(int pos) const |
1686 { |
1713 { |
1687 return document()->characterAt(pos); |
1714 return document()->characterAt(pos); |
1688 } |
1715 } |
1689 |
1716 |
|
1717 /*! |
|
1718 Activates or deactivates the selection control in the editor. |
|
1719 The selection control can be used to resize the selection or fine tune the cursor position. |
|
1720 Note: if the selection control is disabled the word selection is still possible by double-tap on word of text. |
|
1721 */ |
|
1722 void HbAbstractEdit::setSelectionControlEnabled(bool enabled) |
|
1723 { |
|
1724 Q_D(HbAbstractEdit); |
|
1725 if(d->enableSelectionControl != enabled) { |
|
1726 d->enableSelectionControl = enabled; |
|
1727 if(enabled && (d->hasInputFocus() || d->cursor.hasSelection())) { |
|
1728 d->selectionControl = HbSelectionControl::attachEditor(this); |
|
1729 d->selectionControl->setMagnifierEnabled(d->enableMagnifier); |
|
1730 d->selectionControl->showHandles(); |
|
1731 } else if (d->selectionControl) { |
|
1732 d->selectionControl->hideHandles(); |
|
1733 } |
|
1734 d->updateCursorType(); |
|
1735 } |
|
1736 } |
|
1737 |
|
1738 /*! |
|
1739 Return true if selection control is enabled in the editor otherwise returns false. |
|
1740 */ |
|
1741 bool HbAbstractEdit::isSelectionControlEnabled() const |
|
1742 { |
|
1743 Q_D(const HbAbstractEdit); |
|
1744 return d->enableSelectionControl; |
|
1745 } |
|
1746 |
|
1747 |
1690 void HbAbstractEdit::gestureEvent(QGestureEvent* event) { |
1748 void HbAbstractEdit::gestureEvent(QGestureEvent* event) { |
1691 Q_D(HbAbstractEdit); |
1749 Q_D(HbAbstractEdit); |
1692 |
1750 |
1693 if(HbTapGesture *tap = qobject_cast<HbTapGesture*>(event->gesture(Qt::TapGesture))) { |
1751 d->gestureEvent(event); |
1694 // QTapGesture::position() is in screen coordinates and thus |
|
1695 // needs to be transformed into items own coordinate system. |
|
1696 // The QGestureEvent knows the viewport through which the gesture |
|
1697 // was triggered. |
|
1698 QPointF pos = mapFromScene(event->mapToGraphicsScene(tap->position())); |
|
1699 switch(tap->state()) { |
|
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 |
|
1706 d->tapPosition = pos; |
|
1707 HbWidgetFeedback::triggered(this, Hb::InstantPressed); |
|
1708 break; |
|
1709 case Qt::GestureUpdated: |
|
1710 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
|
1711 d->openInputPanel(); |
|
1712 d->longTapGesture(pos); |
|
1713 } |
|
1714 break; |
|
1715 case Qt::GestureFinished: |
|
1716 scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant()); |
|
1717 |
|
1718 if(tap->tapStyleHint() == HbTapGesture::TapAndHold) { |
|
1719 } else { |
|
1720 d->tapGesture(pos); |
|
1721 } |
|
1722 |
|
1723 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
|
1724 |
|
1725 d->openInputPanel(); |
|
1726 |
|
1727 break; |
|
1728 case Qt::GestureCanceled: |
|
1729 scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant()); |
|
1730 |
|
1731 break; |
|
1732 default: |
|
1733 break; |
|
1734 } |
|
1735 event->accept(); |
|
1736 } else { |
|
1737 event->ignore(); |
|
1738 } |
|
1739 } |
1752 } |
1740 |
1753 |
1741 /*! |
1754 /*! |
1742 Returns the filtered text, or \a text if no input filter attached to editor. |
1755 Returns the filtered text, or \a text if no input filter attached to editor. |
1743 */ |
1756 */ |