src/hbwidgets/editors/hbabstractedit.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    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 
   150 
   143 
   151     \sa QTextDocument::toPlainText()
   144     \sa QTextDocument::toPlainText()
   152 */
   145 */
   153 
   146 
   154 #define Hb_Invalid_Position QPointF(-1.0, -1.0)
   147 #define Hb_Invalid_Position QPointF(-1.0, -1.0)
       
   148 
       
   149 
       
   150 
   155 
   151 
   156 /*!
   152 /*!
   157     Constructs a HbAbstractEdit with parent \a parent.
   153     Constructs a HbAbstractEdit with parent \a parent.
   158  */
   154  */
   159 HbAbstractEdit::HbAbstractEdit(QGraphicsItem *parent) :
   155 HbAbstractEdit::HbAbstractEdit(QGraphicsItem *parent) :
   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 
   506 void HbAbstractEdit::focusOutEvent(QFocusEvent *event)
   516 void HbAbstractEdit::focusOutEvent(QFocusEvent *event)
   507 {
   517 {
   508     HbWidget::focusOutEvent(event);
   518     HbWidget::focusOutEvent(event);
   509 
   519 
   510     Q_D(HbAbstractEdit);
   520     Q_D(HbAbstractEdit);
   511 
       
   512     if (d->interactionFlags & Qt::NoTextInteraction)
       
   513         return;
       
   514 
   521 
   515     // It sets the cursor the focus item's depending on if
   522     // It sets the cursor the focus item's depending on if
   516     // the input panel is connceted or not
   523     // the input panel is connceted or not
   517     d->setInputFocusEnabled(d->hasInputFocus());
   524     d->setInputFocusEnabled(d->hasInputFocus());
   518 
   525 
   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.
   883 {
   894 {
   884 #ifndef QT_NO_CLIPBOARD
   895 #ifndef QT_NO_CLIPBOARD
   885     Q_D(HbAbstractEdit);
   896     Q_D(HbAbstractEdit);
   886     if (!(d->interactionFlags & Qt::TextEditable) || !d->cursor.hasSelection())
   897     if (!(d->interactionFlags & Qt::TextEditable) || !d->cursor.hasSelection())
   887         return;
   898         return;
   888     copy();
   899     copy();    
   889     d->cursor.removeSelectedText();
   900     d->cursor.removeSelectedText();
       
   901     d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
   890 #endif//QT_NO_CLIPBOARD
   902 #endif//QT_NO_CLIPBOARD
   891 }
   903 }
   892 
   904 
   893 /*!
   905 /*!
   894     Adds content which is currently selected in editor to clipboard.
   906     Adds content which is currently selected in editor to clipboard.
   924         d->prepDocForPaste();
   936         d->prepDocForPaste();
   925         const QMimeData *md = QApplication::clipboard()->mimeData();
   937         const QMimeData *md = QApplication::clipboard()->mimeData();
   926         if (md) {
   938         if (md) {
   927             insertFromMimeData(md);
   939             insertFromMimeData(md);
   928         }
   940         }
   929     }
   941         d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
   930 
   942     }
   931 #endif//QT_NO_CLIPBOARD
   943 #endif//QT_NO_CLIPBOARD
   932 }
   944 }
   933 
   945 
   934 /*!
   946 /*!
   935     Selects the word under the cursor in the editor.
   947     Selects the word under the cursor in the editor.
   943     int cursorPos = d->hitTest(d->tapPosition, Qt::FuzzyHit);
   955     int cursorPos = d->hitTest(d->tapPosition, Qt::FuzzyHit);
   944 
   956 
   945     if (cursorPos == -1)
   957     if (cursorPos == -1)
   946         return;
   958         return;
   947 
   959 
   948     setCursorPosition(cursorPos);
   960     d->cursor.setPosition(cursorPos);
   949     d->cursor.select(QTextCursor::WordUnderCursor);
   961     d->cursor.select(QTextCursor::WordUnderCursor);
   950     d->cursorChanged(HbValidator::CursorChangeFromMouse);
   962     d->cursorChanged(HbValidator::CursorChangeFromMouse);
   951 }
   963 }
   952 
   964 
   953 /*!
   965 /*!
  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()
  1109 void HbAbstractEdit::setValidator(HbValidator* validator)
  1122 void HbAbstractEdit::setValidator(HbValidator* validator)
  1110 {
  1123 {
  1111     Q_D(HbAbstractEdit);
  1124     Q_D(HbAbstractEdit);
  1112 
  1125 
  1113     d->validator = validator;
  1126     d->validator = validator;
  1114     d->initValidator();
  1127     if (d->validator) {
       
  1128         d->initValidator();
       
  1129     }
  1115 }
  1130 }
  1116 
  1131 
  1117 /*!
  1132 /*!
  1118     \property QLineEdit::acceptableInput
  1133     \property QLineEdit::acceptableInput
  1119     This property holds whether the input satisfies the validator.
  1134     This property holds whether the input satisfies the validator.
  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 */