Qt 4.8
qdeclarativetextedit.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativetextedit_p.h"
43 #include "private/qdeclarativetextedit_p_p.h"
44 
45 #include "private/qdeclarativeevents_p_p.h"
46 #include <private/qdeclarativeglobal_p.h>
47 #include <qdeclarativeinfo.h>
48 
49 #include <QtCore/qmath.h>
50 
51 #include <private/qtextengine_p.h>
52 #include <QTextLayout>
53 #include <QTextLine>
54 #include <QTextDocument>
55 #include <QTextObject>
56 #include <QGraphicsSceneMouseEvent>
57 #include <QDebug>
58 #include <QPainter>
59 
60 #include <private/qtextcontrol_p.h>
61 
63 
124 {
126  d->init();
127 }
128 
130 {
131  Q_D(const QDeclarativeTextEdit);
132 
133 #ifndef QT_NO_TEXTHTMLPARSER
134  if (d->richText)
135  return d->document->toHtml();
136  else
137 #endif
138  return d->document->toPlainText();
139 }
140 
291 {
293  if (QDeclarativeTextEdit::text() == text)
294  return;
295 
296  d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text));
297  if (d->richText) {
298 #ifndef QT_NO_TEXTHTMLPARSER
299  d->control->setHtml(text);
300 #else
301  d->control->setPlainText(text);
302 #endif
303  } else {
304  d->control->setPlainText(text);
305  }
306  q_textChanged();
307 }
308 
351 {
352  Q_D(const QDeclarativeTextEdit);
353  return d->format;
354 }
355 
357 {
359  if (format == d->format)
360  return;
361  bool wasRich = d->richText;
362  d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
363 
364  if (wasRich && !d->richText) {
365  d->control->setPlainText(d->text);
366  updateSize();
367  } else if (!wasRich && d->richText) {
368 #ifndef QT_NO_TEXTHTMLPARSER
369  d->control->setHtml(d->text);
370 #else
371  d->control->setPlainText(d->text);
372 #endif
373  updateSize();
374  }
375  d->format = format;
376  d->control->setAcceptRichText(d->format != PlainText);
377  emit textFormatChanged(d->format);
378 }
379 
381 {
382  Q_D(const QDeclarativeTextEdit);
383  return d->sourceFont;
384 }
385 
387 {
389  if (d->sourceFont == font)
390  return;
391 
392  d->sourceFont = font;
393  QFont oldFont = d->font;
394  d->font = font;
395  if (d->font.pointSizeF() != -1) {
396  // 0.5pt resolution
397  qreal size = qRound(d->font.pointSizeF()*2.0);
398  d->font.setPointSizeF(size/2.0);
399  }
400 
401  if (oldFont != d->font) {
402  clearCache();
403  d->document->setDefaultFont(d->font);
404  if(d->cursor){
405  d->cursor->setHeight(QFontMetrics(d->font).height());
407  }
408  updateSize();
409  update();
410  }
411  emit fontChanged(d->sourceFont);
412 }
413 
433 {
434  Q_D(const QDeclarativeTextEdit);
435  return d->color;
436 }
437 
439 {
441  if (d->color == color)
442  return;
443 
444  clearCache();
445  d->color = color;
446  QPalette pal = d->control->palette();
447  pal.setColor(QPalette::Text, color);
448  d->control->setPalette(pal);
449  update();
450  emit colorChanged(d->color);
451 }
452 
462 {
463  Q_D(const QDeclarativeTextEdit);
464  return d->selectionColor;
465 }
466 
468 {
470  if (d->selectionColor == color)
471  return;
472 
473  clearCache();
474  d->selectionColor = color;
475  QPalette pal = d->control->palette();
476  pal.setColor(QPalette::Highlight, color);
477  d->control->setPalette(pal);
478  update();
479  emit selectionColorChanged(d->selectionColor);
480 }
481 
491 {
492  Q_D(const QDeclarativeTextEdit);
493  return d->selectedTextColor;
494 }
495 
497 {
499  if (d->selectedTextColor == color)
500  return;
501 
502  clearCache();
503  d->selectedTextColor = color;
504  QPalette pal = d->control->palette();
506  d->control->setPalette(pal);
507  update();
508  emit selectedTextColorChanged(d->selectedTextColor);
509 }
510 
544 {
545  Q_D(const QDeclarativeTextEdit);
546  return d->hAlign;
547 }
548 
550 {
552  bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
553  d->hAlignImplicit = false;
554  if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
555  d->updateDefaultTextOption();
556  updateSize();
557  }
558 }
559 
561 {
563  d->hAlignImplicit = true;
564  if (d->determineHorizontalAlignment() && isComponentComplete()) {
565  d->updateDefaultTextOption();
566  updateSize();
567  }
568 }
569 
571 {
572  Q_D(const QDeclarativeTextEdit);
573  QDeclarativeTextEdit::HAlignment effectiveAlignment = d->hAlign;
574  if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
575  switch (d->hAlign) {
577  effectiveAlignment = QDeclarativeTextEdit::AlignRight;
578  break;
580  effectiveAlignment = QDeclarativeTextEdit::AlignLeft;
581  break;
582  default:
583  break;
584  }
585  }
586  return effectiveAlignment;
587 }
588 
590 {
592  if (hAlign != alignment || forceAlign) {
593  hAlign = alignment;
594  emit q->horizontalAlignmentChanged(alignment);
595  return true;
596  }
597  return false;
598 }
599 
601 {
603  if (hAlignImplicit && q->isComponentComplete()) {
604  bool alignToRight;
605  if (text.isEmpty() && !control->textCursor().isNull()) {
606  const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
607  alignToRight = preeditText.isEmpty()
609  : preeditText.isRightToLeft();
610  } else {
611  alignToRight = rightToLeftText;
612  }
614  }
615  return false;
616 }
617 
619 {
621  if (q->isComponentComplete()) {
623  updateDefaultTextOption();
624  q->updateSize();
625  }
626  }
627 }
628 
630 {
631  Q_D(const QDeclarativeTextEdit);
632  return d->vAlign;
633 }
634 
636 {
638  if (alignment == d->vAlign)
639  return;
640  d->vAlign = alignment;
641  d->updateDefaultTextOption();
642  updateSize();
645 }
646 
666 {
667  Q_D(const QDeclarativeTextEdit);
668  return d->wrapMode;
669 }
670 
672 {
674  if (mode == d->wrapMode)
675  return;
676  d->wrapMode = mode;
677  d->updateDefaultTextOption();
678  updateSize();
680 }
681 
692 {
693  Q_D(const QDeclarativeTextEdit);
694  return d->lineCount;
695 }
696 
707 {
708  Q_D(const QDeclarativeTextEdit);
709  return d->paintedSize.width();
710 }
711 
722 {
723  Q_D(const QDeclarativeTextEdit);
724  return d->paintedSize.height();
725 }
726 
738 {
739  Q_D(const QDeclarativeTextEdit);
740  QTextCursor c(d->document);
741  c.setPosition(pos);
742  return d->control->cursorRect(c);
743 
744 }
745 
758 {
759  Q_D(const QDeclarativeTextEdit);
760  int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
761  QTextCursor cursor = d->control->textCursor();
762  if (r > cursor.position()) {
763  // The cursor position includes positions within the preedit text, but only positions in the
764  // same text block are offset so it is possible to get a position that is either part of the
765  // preedit or the next text block.
766  QTextLayout *layout = cursor.block().layout();
767  const int preeditLength = layout
768  ? layout->preeditAreaText().length()
769  : 0;
770  if (preeditLength > 0
771  && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
772  r = r > cursor.position() + preeditLength
773  ? r - preeditLength
774  : cursor.position();
775  }
776  }
777  return r;
778 }
779 
781 {
782  //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
784  QTextCursor cursor = d->control->textCursor();
785  if (cursor.position() == pos)
786  return;
788  d->control->setTextCursor(cursor);
789 }
790 
833 {
835  QTextCursor cursor = d->control->textCursor();
836  if (cursor.position() == pos)
837  return;
838  if (mode == SelectCharacters) {
840  } else if (cursor.anchor() < pos || (cursor.anchor() == pos && cursor.position() < pos)) {
841  if (cursor.anchor() > cursor.position()) {
842  cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
844  if (cursor.position() == cursor.anchor())
846  else
847  cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
848  } else {
849  cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
851  }
852 
855  if (cursor.position() != pos)
857  } else if (cursor.anchor() > pos || (cursor.anchor() == pos && cursor.position() > pos)) {
858  if (cursor.anchor() < cursor.position()) {
859  cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
861  } else {
862  cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
865  if (cursor.position() != cursor.anchor()) {
866  cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
868  }
869  }
870 
873  if (cursor.position() != pos) {
876  }
877  }
878  d->control->setTextCursor(cursor);
879 }
880 
892 {
893  Q_D(const QDeclarativeTextEdit);
894  return d->cursorVisible;
895 }
896 
898 {
900  if (d->cursorVisible == on)
901  return;
902  d->cursorVisible = on;
903  QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut);
904  if (!on && !d->persistentSelection)
905  d->control->setCursorIsFocusIndicator(true);
906  d->control->processEvent(&focusEvent, QPointF(0, -d->yoff));
907  emit cursorVisibleChanged(d->cursorVisible);
908 }
909 
918 {
919  Q_D(const QDeclarativeTextEdit);
920  return d->control->textCursor().position();
921 }
922 
924 {
926  if (pos < 0 || pos > d->text.length())
927  return;
928  QTextCursor cursor = d->control->textCursor();
929  if (cursor.position() == pos && cursor.anchor() == pos)
930  return;
931  cursor.setPosition(pos);
932  d->control->setTextCursor(cursor);
933 }
934 
952 {
953  Q_D(const QDeclarativeTextEdit);
954  return d->cursorComponent;
955 }
956 
958 {
960  if(d->cursorComponent){
961  if(d->cursor){
962  d->control->setCursorWidth(-1);
964  delete d->cursor;
965  d->cursor = 0;
966  }
967  }
968  d->cursorComponent = c;
969  if(c && c->isReady()){
971  }else{
972  if(c)
973  connect(c, SIGNAL(statusChanged()),
974  this, SLOT(loadCursorDelegate()));
975  }
976 
978 }
979 
981 {
983  if(d->cursorComponent->isLoading())
984  return;
985  d->cursor = qobject_cast<QDeclarativeItem*>(d->cursorComponent->create(qmlContext(this)));
986  if(d->cursor){
987  d->control->setCursorWidth(0);
989  QDeclarative_setParent_noEvent(d->cursor, this);
990  d->cursor->setParentItem(this);
991  d->cursor->setHeight(QFontMetrics(d->font).height());
993  }else{
994  qmlInfo(this) << "Error loading cursor delegate.";
995  }
996 }
997 
1012 {
1013  Q_D(const QDeclarativeTextEdit);
1014  return d->control->textCursor().selectionStart();
1015 }
1016 
1031 {
1032  Q_D(const QDeclarativeTextEdit);
1033  return d->control->textCursor().selectionEnd();
1034 }
1035 
1054 {
1055  Q_D(const QDeclarativeTextEdit);
1056  return d->control->textCursor().selectedText();
1057 }
1058 
1069 {
1070  Q_D(const QDeclarativeTextEdit);
1071  return d->focusOnPress;
1072 }
1073 
1075 {
1077  if (d->focusOnPress == on)
1078  return;
1079  d->focusOnPress = on;
1080  emit activeFocusOnPressChanged(d->focusOnPress);
1081 }
1082 
1093 {
1094  Q_D(const QDeclarativeTextEdit);
1095  return d->persistentSelection;
1096 }
1097 
1099 {
1101  if (d->persistentSelection == on)
1102  return;
1103  d->persistentSelection = on;
1104  emit persistentSelectionChanged(d->persistentSelection);
1105 }
1106 
1107 /*
1108  \qmlproperty real TextEdit::textMargin
1109 
1110  The margin, in pixels, around the text in the TextEdit.
1111 */
1113 {
1114  Q_D(const QDeclarativeTextEdit);
1115  return d->textMargin;
1116 }
1117 
1119 {
1121  if (d->textMargin == margin)
1122  return;
1123  d->textMargin = margin;
1124  d->document->setDocumentMargin(d->textMargin);
1125  emit textMarginChanged(d->textMargin);
1126 }
1127 
1129  const QRectF &oldGeometry)
1130 {
1131  if (newGeometry.width() != oldGeometry.width())
1132  updateSize();
1133  QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry);
1134 }
1135 
1141 {
1144  if (d->dirty) {
1145  d->determineHorizontalAlignment();
1146  d->updateDefaultTextOption();
1147  updateSize();
1148  d->dirty = false;
1149  }
1150 }
1151 
1166 {
1167  Q_D(const QDeclarativeTextEdit);
1168  return d->selectByMouse;
1169 }
1170 
1172 {
1174  if (d->selectByMouse != on) {
1175  d->selectByMouse = on;
1176  setKeepMouseGrab(on);
1177  if (on)
1178  setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse);
1179  else
1180  setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
1182  }
1183 }
1184 
1185 
1204 {
1205  Q_D(const QDeclarativeTextEdit);
1206  return d->mouseSelectionMode;
1207 }
1208 
1210 {
1212  if (d->mouseSelectionMode != mode) {
1213  d->mouseSelectionMode = mode;
1214  d->control->setWordSelectionEnabled(mode == SelectWords);
1216  }
1217 }
1218 
1231 {
1233  if (r == isReadOnly())
1234  return;
1235 
1237 
1238  Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse;
1239  if (d->selectByMouse)
1240  flags = flags | Qt::TextSelectableByMouse;
1241  if (!r)
1243  d->control->setTextInteractionFlags(flags);
1244  if (!r)
1245  d->control->moveCursor(QTextCursor::End);
1246 
1247  emit readOnlyChanged(r);
1248 }
1249 
1251 {
1252  Q_D(const QDeclarativeTextEdit);
1253  return !(d->control->textInteractionFlags() & Qt::TextEditable);
1254 }
1255 
1261 {
1263  d->control->setTextInteractionFlags(flags);
1264 }
1265 
1270 Qt::TextInteractionFlags QDeclarativeTextEdit::textInteractionFlags() const
1271 {
1272  Q_D(const QDeclarativeTextEdit);
1273  return d->control->textInteractionFlags();
1274 }
1275 
1286 {
1287  Q_D(const QDeclarativeTextEdit);
1288  return d->control->cursorRect().toRect().translated(0,d->yoff);
1289 }
1290 
1291 
1297 {
1299  if (event->type() == QEvent::ShortcutOverride) {
1300  d->control->processEvent(event, QPointF(0, -d->yoff));
1301  return event->isAccepted();
1302  }
1303  return QDeclarativePaintedItem::event(event);
1304 }
1305 
1311 {
1313  keyPressPreHandler(event);
1314  if (!event->isAccepted())
1315  d->control->processEvent(event, QPointF(0, -d->yoff));
1316  if (!event->isAccepted())
1318 }
1319 
1325 {
1327  keyReleasePreHandler(event);
1328  if (!event->isAccepted())
1329  d->control->processEvent(event, QPointF(0, -d->yoff));
1330  if (!event->isAccepted())
1332 }
1333 
1335 {
1337  q->setCursorVisible(hasFocus && scene && scene->hasFocus());
1339 }
1340 
1351 {
1353  QTextCursor c = d->control->textCursor();
1354  c.clearSelection();
1355  d->control->setTextCursor(c);
1356 }
1357 
1367 {
1369  d->control->selectAll();
1370 }
1371 
1381 {
1383  QTextCursor c = d->control->textCursor();
1385  d->control->setTextCursor(c);
1386 }
1387 
1404 void QDeclarativeTextEdit::select(int start, int end)
1405 {
1407  if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length())
1408  return;
1409  QTextCursor cursor = d->control->textCursor();
1410  cursor.beginEditBlock();
1411  cursor.setPosition(start, QTextCursor::MoveAnchor);
1412  cursor.setPosition(end, QTextCursor::KeepAnchor);
1413  cursor.endEditBlock();
1414  d->control->setTextCursor(cursor);
1415 
1416  // QTBUG-11100
1418 }
1419 
1430 {
1432  if (start > end) {
1433  qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
1434  return false;
1435  } else {
1436  return d->text.mid(start, end - start).isRightToLeft();
1437  }
1438 }
1439 
1440 #ifndef QT_NO_CLIPBOARD
1441 
1450 {
1452  d->control->cut();
1453 }
1454 
1464 {
1466  d->control->copy();
1467 }
1468 
1478 {
1480  d->control->paste();
1481 }
1482 #endif // QT_NO_CLIPBOARD
1483 
1489 {
1491  if (d->focusOnPress){
1492  bool hadActiveFocus = hasActiveFocus();
1493  forceActiveFocus();
1494  if (d->showInputPanelOnFocus) {
1495  if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) {
1496  // re-open input panel on press if already focused
1498  }
1499  } else { // show input panel on click
1500  if (hasActiveFocus() && !hadActiveFocus) {
1501  d->clickCausedFocus = true;
1502  }
1503  }
1504  }
1505 
1506  d->control->processEvent(event, QPointF(0, -d->yoff));
1507  if (!event->isAccepted())
1509 }
1510 
1516 {
1518  d->control->processEvent(event, QPointF(0, -d->yoff));
1519  if (!d->showInputPanelOnFocus) { // input panel on click
1520  if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) {
1521  if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
1522  if (view->scene() && view->scene() == scene()) {
1523  qt_widget_private(view)->handleSoftwareInputPanel(event->button(), d->clickCausedFocus);
1524  }
1525  }
1526  }
1527  }
1528  d->clickCausedFocus = false;
1529 
1530  if (!event->isAccepted())
1532 }
1533 
1539 {
1541 
1542  d->control->processEvent(event, QPointF(0, -d->yoff));
1543  if (!event->isAccepted())
1545 
1546 }
1547 
1553 {
1555  d->control->processEvent(event, QPointF(0, -d->yoff));
1556  if (!event->isAccepted())
1558 }
1559 
1565 {
1567  const bool wasComposing = isInputMethodComposing();
1568  d->control->processEvent(event, QPointF(0, -d->yoff));
1569  if (wasComposing != isInputMethodComposing())
1571 }
1572 
1578 {
1579  Q_D(const QDeclarativeTextEdit);
1580  return d->control->inputMethodQuery(property);
1581 }
1582 
1588 {
1590 
1591  painter->setRenderHint(QPainter::TextAntialiasing, true);
1592  painter->translate(0,d->yoff);
1593 
1594  d->control->drawContents(painter, bounds.translated(0,-d->yoff));
1595 
1596  painter->translate(0,-d->yoff);
1597 }
1598 
1600 {
1601  Q_D(const QDeclarativeTextEdit);
1602  QRect r;
1603  if (!rf.isValid()) {
1604  r = QRect(0,0,INT_MAX,INT_MAX);
1605  } else {
1606  r = rf.toRect();
1607  if (r.height() > INT_MAX/2) {
1608  // Take care of overflow when translating "everything"
1609  r.setTop(r.y() + d->yoff);
1610  r.setBottom(INT_MAX/2);
1611  } else {
1612  r = r.translated(0,d->yoff);
1613  }
1614  }
1615  dirtyCache(r);
1616  emit update();
1617 }
1618 
1646 bool QDeclarativeTextEdit::canPaste() const
1647 {
1648  Q_D(const QDeclarativeTextEdit);
1649  return d->canPaste;
1650 }
1651 
1669 {
1670  Q_D(const QDeclarativeTextEdit);
1671  if (QTextLayout *layout = d->control->textCursor().block().layout())
1672  return layout->preeditAreaText().length() > 0;
1673  return false;
1674 }
1675 
1677 {
1679 
1680  q->setSmooth(smooth);
1681  q->setAcceptedMouseButtons(Qt::LeftButton);
1682  q->setFlag(QGraphicsItem::ItemHasNoContents, false);
1684 
1685  control = new QTextControl(q);
1686  control->setIgnoreUnusedNavigationEvents(true);
1687  control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
1688  control->setDragEnabled(false);
1689 
1690  // QTextControl follows the default text color
1691  // defined by the platform, declarative text
1692  // should be black by default
1693  QPalette pal = control->palette();
1694  if (pal.color(QPalette::Text) != color) {
1696  control->setPalette(pal);
1697  }
1698 
1699  QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateImgCache(QRectF)));
1700 
1706  QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate()));
1708 #ifndef QT_NO_CLIPBOARD
1711  canPaste = control->canPaste();
1712 #endif
1713 
1714  document = control->document();
1715  document->setDefaultFont(font);
1716  document->setDocumentMargin(textMargin);
1717  document->setUndoRedoEnabled(false); // flush undo buffer.
1718  document->setUndoRedoEnabled(true);
1719  updateDefaultTextOption();
1720 }
1721 
1723 {
1725  d->text = text();
1726  d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
1727  d->determineHorizontalAlignment();
1728  d->updateDefaultTextOption();
1729  updateSize();
1730  updateTotalLines();
1731  emit textChanged(d->text);
1732 }
1733 
1735 {
1737  d->determineHorizontalAlignment();
1738  updateMicroFocus();
1740  if(!d->cursor)
1741  return;
1742  QRectF cursorRect = cursorRectangle();
1743  d->cursor->setX(cursorRect.x());
1744  d->cursor->setY(cursorRect.y());
1745 }
1746 
1748 {
1750  QTextCursor cursor = control->textCursor();
1751  bool startChange = (lastSelectionStart != cursor.selectionStart());
1752  bool endChange = (lastSelectionEnd != cursor.selectionEnd());
1753  cursor.beginEditBlock();
1754  cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor);
1755  cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
1756  cursor.endEditBlock();
1757  control->setTextCursor(cursor);
1758  if(startChange)
1759  q->selectionStartChanged();
1760  if(endChange)
1761  q->selectionEndChanged();
1762 }
1763 
1765 {
1767  if(d->lastSelectionStart != d->control->textCursor().selectionStart()){
1768  d->lastSelectionStart = d->control->textCursor().selectionStart();
1770  }
1771  if(d->lastSelectionEnd != d->control->textCursor().selectionEnd()){
1772  d->lastSelectionEnd = d->control->textCursor().selectionEnd();
1774  }
1775 }
1776 
1778 {
1779  Q_D(const QDeclarativeTextEdit);
1781  int cursorWidth = 1;
1782  if(d->cursor)
1783  cursorWidth = d->cursor->width();
1784  if(!d->document->isEmpty())
1785  cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor
1786 
1787  // Could include font max left/right bearings to either side of rectangle.
1788 
1789  r.setRight(r.right() + cursorWidth);
1790  return r.translated(0,d->yoff);
1791 }
1792 
1794 {
1795  Q_Q(const QDeclarativeTextEdit);
1796  if (!requireImplicitWidth) {
1797  // We don't calculate implicitWidth unless it is required.
1798  // We need to force a size update now to ensure implicitWidth is calculated
1799  const_cast<QDeclarativeTextEditPrivate*>(this)->requireImplicitWidth = true;
1800  const_cast<QDeclarativeTextEdit*>(q)->updateSize();
1801  }
1802  return mImplicitWidth;
1803 }
1804 
1805 //### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
1806 // need to do all the calculations each time
1808 {
1810  if (isComponentComplete()) {
1811  qreal naturalWidth = d->mImplicitWidth;
1812  // ### assumes that if the width is set, the text will fill to edges
1813  // ### (unless wrap is false, then clipping will occur)
1814  if (widthValid()) {
1815  if (!d->requireImplicitWidth) {
1817  // if the implicitWidth is used, then updateSize() has already been called (recursively)
1818  if (d->requireImplicitWidth)
1819  return;
1820  }
1821  if (d->requireImplicitWidth) {
1822  d->document->setTextWidth(-1);
1823  naturalWidth = d->document->idealWidth();
1824  }
1825  if (d->document->textWidth() != width())
1826  d->document->setTextWidth(width());
1827  } else {
1828  d->document->setTextWidth(-1);
1829  }
1830  QFontMetrics fm = QFontMetrics(d->font);
1831  int dy = height();
1832  dy -= (int)d->document->size().height();
1833 
1834  int nyoff;
1835  if (heightValid()) {
1836  if (d->vAlign == AlignBottom)
1837  nyoff = dy;
1838  else if (d->vAlign == AlignVCenter)
1839  nyoff = dy/2;
1840  else
1841  nyoff = 0;
1842  } else {
1843  nyoff = 0;
1844  }
1845  if (nyoff != d->yoff) {
1847  d->yoff = nyoff;
1848  }
1849  setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
1850 
1851  //### need to comfirm cost of always setting these
1852  int newWidth = qCeil(d->document->idealWidth());
1853  if (!widthValid() && d->document->textWidth() != newWidth)
1854  d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
1855  // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
1856  if (!widthValid())
1857  setImplicitWidth(newWidth);
1858  else if (d->requireImplicitWidth)
1859  setImplicitWidth(naturalWidth);
1860  qreal newHeight = d->document->size().height();
1861  if (newHeight == 0)
1862  newHeight = fm.height();
1863  setImplicitHeight(newHeight);
1864 
1865  d->paintedSize = QSize(newWidth, newHeight);
1866  setContentsSize(d->paintedSize);
1868  } else {
1869  d->dirty = true;
1870  }
1871  emit update();
1872 }
1873 
1875 {
1877 
1878  int subLines = 0;
1879 
1880  for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) {
1881  QTextLayout *layout = it.layout();
1882  if (!layout)
1883  continue;
1884  subLines += layout->lineCount()-1;
1885  }
1886 
1887  int newTotalLines = d->document->lineCount() + subLines;
1888  if (d->lineCount != newTotalLines) {
1889  d->lineCount = newTotalLines;
1891  }
1892 }
1893 
1895 {
1897  QTextOption opt = document->defaultTextOption();
1898  int oldAlignment = opt.alignment();
1899 
1901  if (rightToLeftText) {
1902  if (horizontalAlignment == QDeclarativeTextEdit::AlignLeft)
1903  horizontalAlignment = QDeclarativeTextEdit::AlignRight;
1904  else if (horizontalAlignment == QDeclarativeTextEdit::AlignRight)
1905  horizontalAlignment = QDeclarativeTextEdit::AlignLeft;
1906  }
1907  opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));
1908 
1909  QTextOption::WrapMode oldWrapMode = opt.wrapMode();
1911 
1912  if (oldWrapMode == opt.wrapMode() && oldAlignment == opt.alignment())
1913  return;
1914  document->setDefaultTextOption(opt);
1915 }
1916 
1917 
1961 {
1963  if (qApp) {
1964  if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
1965  if (view->scene() && view->scene() == scene()) {
1966  QApplication::sendEvent(view, &event);
1967  }
1968  }
1969  }
1970 }
1971 
2015 {
2017  if (qApp) {
2018  if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
2019  if (view->scene() && view->scene() == scene()) {
2020  QApplication::sendEvent(view, &event);
2021  }
2022  }
2023  }
2024 }
2025 
2027 {
2028  Q_D(const QDeclarativeTextEdit);
2029  if (d->showInputPanelOnFocus) {
2030  if (d->focusOnPress && !isReadOnly()) {
2032  }
2033  }
2035 }
2036 
2038 {
2040  bool old = d->canPaste;
2041  d->canPaste = d->control->canPaste();
2042  if(old!=d->canPaste)
2044 }
2045 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void focusInEvent(QFocusEvent *event)
This event handler, for event event, can be reimplemented to receive focus in events for this item...
void mouseSelectionModeChanged(SelectionMode mode)
int anchor() const
Returns the anchor position; this is the same as position() unless there is a selection in which case...
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
qreal right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:527
void endEditBlock()
Indicates the end of a block of editing operations on the document that should appear as a single ope...
The QKeyEvent class describes a key event.
Definition: qevent.h:224
QDeclarativeComponent * cursorDelegate() const
void drawContents(QPainter *, const QRect &)
Draws the contents of the text edit using the given painter within the given bounds.
double qreal
Definition: qglobal.h:1193
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
unsigned char c[8]
Definition: qnumeric_p.h:62
void setText(const QString &)
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:65
Q_INVOKABLE QRectF positionToRectangle(int) const
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QDeclarativeParserStatus ** d
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:661
QFont font() const
void textFormatChanged(TextFormat textFormat)
int qCeil(qreal v)
Definition: qmath.h:63
void setMouseSelectionMode(SelectionMode mode)
#define it(className, varName)
bool widthValid() const
Returns whether the width property has been set explicitly.
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
qreal textMargin() const
WrapMode wrapMode() const
void keyReleaseEvent(QKeyEvent *)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void fontChanged(const QFont &font)
int selectionEnd() const
Returns the end of the selection or position() if the cursor doesn&#39;t have a selection.
virtual bool event(QEvent *)
void setContentsSize(const QSize &)
Sets the size of the contents to the given size.
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
void linkActivated(const QString &link)
void setBaselineOffset(qreal)
#define SLOT(a)
Definition: qobjectdefs.h:226
qreal paintedWidth() const
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
The QGraphicsSceneMouseEvent class provides mouse events in the graphics view framework.
WrapMode
This enum describes how text is wrapped in a document.
Definition: qtextoption.h:102
Q_GUI_EXPORT bool mightBeRichText(const QString &)
Returns true if the string text is likely to be rich text; otherwise returns false.
Qt::MouseButton button() const
Returns the mouse button (if any) that caused the event.
bool heightValid() const
Returns whether the height property has been set explicitly.
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
bool isReady() const
Returns true if status() == QDeclarativeComponent::Ready.
virtual void keyPressEvent(QKeyEvent *event)
QString text() const
QVariant inputMethodQuery(Qt::InputMethodQuery property) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void keyPressEvent(QKeyEvent *)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void selectionColorChanged(const QColor &color)
QPointF pos() const
Returns the position of the item in parent coordinates.
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
This function is called to handle this item&#39;s changes in geometry from oldGeometry to newGeometry...
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event event, can be reimplemented to receive mouse doubleclick events for thi...
void updateMicroFocus()
Updates the item&#39;s micro focus.
Q_INVOKABLE void openSoftwareInputPanel()
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
void readOnlyChanged(bool isReadOnly)
void setTextMargin(qreal margin)
T * qobject_cast(QObject *object)
Definition: qobject.h:375
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event event, can be reimplemented to receive mouse press events for this item...
void update(const QRectF &rect=QRectF())
Schedules a redraw of the area covered by rect in this item.
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void selectByMouseChanged(bool selectByMouse)
Q_DECLARATIVE_EXPORT QDeclarativeContext * qmlContext(const QObject *)
#define Q_D(Class)
Definition: qglobal.h:2482
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition: qpalette.h:107
void setSelectionColor(const QColor &c)
Qt::TextInteractionFlags textInteractionFlags() const
Returns the flags specifying how the text edit should interact with user input.
void setRight(qreal pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:672
void inputMethodEvent(QInputMethodEvent *e)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void select(int start, int end)
QDeclarativeTextEdit(QDeclarativeItem *parent=0)
This handler is called when the user clicks on a link embedded in the text.
bool isRightToLeft(int start, int end)
#define Q_Q(Class)
Definition: qglobal.h:2483
virtual void focusInEvent(QFocusEvent *event)
This event handler, for event event, can be reimplemented to receive focus in events for this item...
QString selectedText() const
QColor selectedTextColor() const
int ascent() const
Returns the ascent of the font.
QCursor cursor() const
Returns the current cursor shape for the item.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void updateImgCache(const QRectF &rect)
void textChanged(const QString &)
QColor selectionColor() const
void setAlignment(Qt::Alignment alignment)
Sets the option&#39;s text alignment to the specified alignment.
Definition: qtextoption.h:148
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint...
Definition: qpainter.cpp:7620
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void inputMethodComposingChanged()
bool isAccepted() const
Definition: qcoreevent.h:307
The QDeclarativeComponent class encapsulates a QML component definition.
int selectionEnd() const
The QDeclarativeItem class provides the most basic of all visual items in QML.
static QClipboard * clipboard()
Returns a pointer to the application global clipboard.
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event event, can be reimplemented to receive mouse move events for this item...
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
int lineCount() const
The QTextCursor class offers an API to access and modify QTextDocuments.
Definition: qtextcursor.h:70
#define qApp
void verticalAlignmentChanged(VAlignment alignment)
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
bool isRightToLeft() const
Returns true if the string is read right to left.
Definition: qstring.cpp:7528
#define emit
Definition: qobjectdefs.h:76
const char * layout
bool setHAlign(QDeclarativeTextEdit::HAlignment, bool forceAlign=false)
bool hasActiveFocus() const
The QTextBlock class provides a container for text fragments in a QTextDocument.
Definition: qtextobject.h:199
void textMarginChanged(qreal textMargin)
void colorChanged(const QColor &color)
QRect cursorRectangle() const
void activeFocusOnPressChanged(bool activeFocusOnPressed)
void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
Definition: qwidget_p.h:669
void setFont(const QFont &font)
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
bool persistentSelection() const
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
void select(SelectionType selection)
Selects text in the document according to the given selection.
void cursorVisibleChanged(bool isCursorVisible)
void dirtyCache(const QRect &)
Marks areas of the cache that intersect with the given rect as dirty and in need of being refreshed...
int position() const
Returns the absolute position of the cursor within the document.
bool selectByMouse() const
GraphicsItemFlags flags() const
Returns this item&#39;s flags.
TextFormat textFormat() const
void keyReleasePreHandler(QKeyEvent *)
void setImplicitWidth(qreal)
Sets the implied width of the item to w.
QRect toRect() const
Returns a QRect based on the values of this rectangle.
Definition: qrect.h:845
void setHAlign(HAlignment align)
QTextBlock block() const
Returns the block that contains the cursor.
void clearSelection()
Clears the current selection by setting the anchor to the cursor position.
virtual void focusChanged(bool)
InputMethodQuery
Definition: qnamespace.h:1541
virtual void keyReleaseEvent(QKeyEvent *event)
The QInputMethodEvent class provides parameters for input method events.
Definition: qevent.h:431
QString preeditAreaText() const
Returns the text that is inserted in the layout before editing occurs.
The QTextLayout class is used to lay out and render text.
Definition: qtextlayout.h:105
virtual void componentComplete()
Ensures any delayed caching or data loading the class needs to performed is complete.
void beginEditBlock()
Indicates the start of a block of editing operations on the document that should appear as a single o...
qreal y() const
This convenience function is equivalent to calling pos().
bool smooth() const
void prepareGeometryChange()
Prepares the item for a geometry change.
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
bool hasFocus() const
Returns true if the scene has focus; otherwise returns false.
void QDeclarative_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
qreal x() const
This convenience function is equivalent to calling pos().
virtual void componentComplete()
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition: qpalette.h:201
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
Sets how the text edit should interact with user input to the given flags.
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
Definition: qnamespace.h:54
WrapMode wrapMode() const
Returns the text wrap mode defined by the option.
Definition: qtextoption.h:110
void setCursorDelegate(QDeclarativeComponent *)
virtual bool contains(const QPointF &point) const
Returns true if this item contains point, which is in local coordinates; otherwise, false is returned.
void persistentSelectionChanged(bool isPersistentSelection)
The QTextOption class provides a description of general rich text properties.
Definition: qtextoption.h:59
bool event(QEvent *)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool movePosition(MoveOperation op, MoveMode=MoveAnchor, int n=1)
Moves the cursor by performing the given operation n times, using the specified mode, and returns true if all operations were completed successfully; otherwise returns false.
int cursorPosition() const
void mousePressEvent(QGraphicsSceneMouseEvent *event)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QVariant property(const char *name) const
Returns the value of the object&#39;s name property.
Definition: qobject.cpp:3807
void setPosition(int pos, MoveMode mode=MoveAnchor)
Moves the cursor to the absolute position in the document specified by pos using a MoveMode specified...
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:64
void clearCache()
Marks the entirety of the contents cache as dirty.
QPointF pos() const
Returns the mouse cursor position in item coordinates.
int selectionStart() const
Qt::Alignment alignment() const
Returns the text alignment defined by the option.
Definition: qtextoption.h:97
void setWrapMode(WrapMode wrap)
Sets the option&#39;s text wrap mode to the given mode.
Definition: qtextoption.h:109
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QGraphicsScene * scene() const
Returns the current scene for the item, or 0 if the item is not stored in a scene.
Q_GUI_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
Definition: qwidget.cpp:12920
QColor color() const
QRectF translated(qreal dx, qreal dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:740
QDeclarativeInfo qmlInfo(const QObject *me)
static Qt::LayoutDirection keyboardInputDirection()
Returns the current keyboard input direction.
int height() const
Returns the height of the font.
void setImplicitHeight(qreal)
Sets the implied height of the item to h.
static const KeyPair *const end
qreal paintedHeight() const
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setColor(const QColor &c)
void setSelectedTextColor(const QColor &c)
void setFlag(GraphicsItemFlag flag, bool enabled=true)
If enabled is true, the item flag flag is enabled; otherwise, it is disabled.
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
SelectionMode mouseSelectionMode() const
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
This function is called to handle this item&#39;s changes in geometry from oldGeometry to newGeometry...
HAlignment effectiveHAlign() const
Q_INVOKABLE int positionAt(int x, int y) const
Q_INVOKABLE void forceActiveFocus()
Forces active focus on the item.
Q_INVOKABLE void moveCursorSelection(int pos)
#define INT_MAX
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
This event handler, for event event, can be reimplemented to receive mouse release events for this it...
void setTextFormat(TextFormat format)
bool canPaste() const
The QFocusEvent class contains event parameters for widget focus events.
Definition: qevent.h:275
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
int selectionStart() const
Returns the start of the selection or position() if the cursor doesn&#39;t have a selection.
Q_INVOKABLE void closeSoftwareInputPanel()
int lineCount() const
Returns the number of lines in this text layout.
void setKeepMouseGrab(bool)
The flag indicating whether the mouse should remain with this item is set to keep.
void keyPressPreHandler(QKeyEvent *)
void setVAlign(VAlignment align)
void selectedTextColorChanged(const QColor &color)
void translate(const QPointF &offset)
Translates the coordinate system by the given offset; i.e.
Definition: qpainter.cpp:3311
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61
QTextLayout * layout() const
Returns the QTextLayout that is used to lay out and display the block&#39;s contents. ...