src/gui/text/qtextcontrol.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    53 #include <qclipboard.h>
    53 #include <qclipboard.h>
    54 #include <qmenu.h>
    54 #include <qmenu.h>
    55 #include <qstyle.h>
    55 #include <qstyle.h>
    56 #include <qtimer.h>
    56 #include <qtimer.h>
    57 #include "private/qtextdocumentlayout_p.h"
    57 #include "private/qtextdocumentlayout_p.h"
       
    58 #include "private/qabstracttextdocumentlayout_p.h"
    58 #include "private/qtextedit_p.h"
    59 #include "private/qtextedit_p.h"
    59 #include "qtextdocument.h"
    60 #include "qtextdocument.h"
    60 #include "private/qtextdocument_p.h"
    61 #include "private/qtextdocument_p.h"
    61 #include "qtextlist.h"
    62 #include "qtextlist.h"
    62 #include "private/qtextcontrol_p.h"
    63 #include "private/qtextcontrol_p.h"
   124 #ifdef QT_KEYPAD_NAVIGATION
   125 #ifdef QT_KEYPAD_NAVIGATION
   125       hasEditFocus(false),
   126       hasEditFocus(false),
   126 #endif
   127 #endif
   127       isEnabled(true),
   128       isEnabled(true),
   128       hadSelectionOnMousePress(false),
   129       hadSelectionOnMousePress(false),
       
   130       ignoreUnusedNavigationEvents(false),
   129       openExternalLinks(false)
   131       openExternalLinks(false)
   130 {}
   132 {}
   131 
   133 
   132 bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
   134 bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
   133 {
   135 {
   262     cursor.setVisualNavigation(true);
   264     cursor.setVisualNavigation(true);
   263     const bool moved = cursor.movePosition(op, mode);
   265     const bool moved = cursor.movePosition(op, mode);
   264     cursor.setVisualNavigation(visualNavigation);
   266     cursor.setVisualNavigation(visualNavigation);
   265     q->ensureCursorVisible();
   267     q->ensureCursorVisible();
   266 
   268 
       
   269     bool ignoreNavigationEvents = ignoreUnusedNavigationEvents;
       
   270     bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
       
   271 
       
   272 #ifdef QT_KEYPAD_NAVIGATION
       
   273     ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
       
   274     isNavigationEvent = isNavigationEvent ||
       
   275                         (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
       
   276                          && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
       
   277 #else
       
   278     isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
       
   279 #endif
       
   280 
   267     if (moved) {
   281     if (moved) {
   268         if (cursor.position() != oldCursorPos)
   282         if (cursor.position() != oldCursorPos)
   269             emit q->cursorPositionChanged();
   283             emit q->cursorPositionChanged();
   270         emit q->microFocusChanged();
   284         emit q->microFocusChanged();
   271     }
   285     } else if (ignoreNavigationEvents && isNavigationEvent) {
   272 #ifdef QT_KEYPAD_NAVIGATION
       
   273     else if (QApplication::keypadNavigationEnabled()
       
   274         && ((e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)
       
   275         || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
       
   276         && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))) {
       
   277         return false;
   286         return false;
   278     }
   287     }
   279 #endif
       
   280 
   288 
   281     selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
   289     selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
   282 
   290 
   283     repaintOldAndNewSelection(oldSelection);
   291     repaintOldAndNewSelection(oldSelection);
   284 
   292 
   909         case QEvent::KeyPress:
   917         case QEvent::KeyPress:
   910             d->keyPressEvent(static_cast<QKeyEvent *>(e));
   918             d->keyPressEvent(static_cast<QKeyEvent *>(e));
   911             break;
   919             break;
   912         case QEvent::MouseButtonPress: {
   920         case QEvent::MouseButtonPress: {
   913             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
   921             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
   914             d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(),
   922             d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
   915                                ev->buttons(), ev->globalPos());
   923                                ev->buttons(), ev->globalPos());
   916             break; }
   924             break; }
   917         case QEvent::MouseMove: {
   925         case QEvent::MouseMove: {
   918             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
   926             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
   919             d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
   927             d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
   977 #endif
   985 #endif
   978 
   986 
   979 #ifndef QT_NO_GRAPHICSVIEW
   987 #ifndef QT_NO_GRAPHICSVIEW
   980         case QEvent::GraphicsSceneMousePress: {
   988         case QEvent::GraphicsSceneMousePress: {
   981             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
   989             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
   982             d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
   990             d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
   983                                ev->screenPos());
   991                                ev->screenPos());
   984             break; }
   992             break; }
   985         case QEvent::GraphicsSceneMouseMove: {
   993         case QEvent::GraphicsSceneMouseMove: {
   986             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
   994             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
   987             d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
   995             d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
  1294 }
  1302 }
  1295 
  1303 
  1296 void QTextControlPrivate::_q_updateBlock(const QTextBlock &block)
  1304 void QTextControlPrivate::_q_updateBlock(const QTextBlock &block)
  1297 {
  1305 {
  1298     Q_Q(QTextControl);
  1306     Q_Q(QTextControl);
  1299     emit q->updateRequest(q->blockBoundingRect(block));
  1307     QRectF br = q->blockBoundingRect(block);
       
  1308     br.setRight(qreal(INT_MAX)); // the block might have shrunk
       
  1309     emit q->updateRequest(br);
  1300 }
  1310 }
  1301 
  1311 
  1302 QRectF QTextControlPrivate::rectForPosition(int position) const
  1312 QRectF QTextControlPrivate::rectForPosition(int position) const
  1303 {
  1313 {
  1304     Q_Q(const QTextControl);
  1314     Q_Q(const QTextControl);
  1463 {
  1473 {
  1464     Q_D(const QTextControl);
  1474     Q_D(const QTextControl);
  1465     return selectionRect(d->cursor);
  1475     return selectionRect(d->cursor);
  1466 }
  1476 }
  1467 
  1477 
  1468 void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
  1478 void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
  1469                                           Qt::MouseButtons buttons, const QPoint &globalPos)
  1479                                           Qt::MouseButtons buttons, const QPoint &globalPos)
  1470 {
  1480 {
  1471     Q_Q(QTextControl);
  1481     Q_Q(QTextControl);
  1472 
  1482 
  1473     if (interactionFlags & Qt::LinksAccessibleByMouse) {
  1483     if (interactionFlags & Qt::LinksAccessibleByMouse) {
  1477             cursorIsFocusIndicator = false;
  1487             cursorIsFocusIndicator = false;
  1478             repaintSelection();
  1488             repaintSelection();
  1479             cursor.clearSelection();
  1489             cursor.clearSelection();
  1480         }
  1490         }
  1481     }
  1491     }
  1482     if (!(button & Qt::LeftButton))
  1492     if (!(button & Qt::LeftButton) ||
  1483         return;
  1493         !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
  1484 
  1494             e->ignore();
  1485     if (!((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable)))
  1495             return;
  1486         return;
  1496     }
  1487 
  1497 
  1488     cursorIsFocusIndicator = false;
  1498     cursorIsFocusIndicator = false;
  1489     const QTextCursor oldSelection = cursor;
  1499     const QTextCursor oldSelection = cursor;
  1490     const int oldCursorPos = cursor.position();
  1500     const int oldCursorPos = cursor.position();
  1491 
  1501 
  1505         anchorOnMousePress = QString();
  1515         anchorOnMousePress = QString();
  1506 
  1516 
  1507         trippleClickTimer.stop();
  1517         trippleClickTimer.stop();
  1508     } else {
  1518     } else {
  1509         int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
  1519         int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
  1510         if (cursorPos == -1)
  1520         if (cursorPos == -1) {
       
  1521             e->ignore();
  1511             return;
  1522             return;
       
  1523         }
  1512 
  1524 
  1513 #if !defined(QT_NO_IM)
  1525 #if !defined(QT_NO_IM)
  1514         QTextLayout *layout = cursor.block().layout();
  1526         QTextLayout *layout = cursor.block().layout();
  1515         if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
  1527         if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
  1516             QInputContext *ctx = inputContext();
  1528             QInputContext *ctx = inputContext();
  1517             if (ctx) {
  1529             if (ctx) {
  1518                 QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos,
  1530                 QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos,
  1519                                button, buttons, modifiers);
  1531                                button, buttons, modifiers);
  1520                 ctx->mouseHandler(cursorPos - cursor.position(), &ev);
  1532                 ctx->mouseHandler(cursorPos - cursor.position(), &ev);
  1521             }
  1533             }
  1522             if (!layout->preeditAreaText().isEmpty())
  1534             if (!layout->preeditAreaText().isEmpty()) {
       
  1535                 e->ignore();
  1523                 return;
  1536                 return;
       
  1537             }
  1524         }
  1538         }
  1525 #endif
  1539 #endif
  1526         if (modifiers == Qt::ShiftModifier) {
  1540         if (modifiers == Qt::ShiftModifier) {
  1527             if (selectedBlockOnTrippleClick.hasSelection())
  1541             if (selectedBlockOnTrippleClick.hasSelection())
  1528                 extendBlockwiseSelection(cursorPos);
  1542                 extendBlockwiseSelection(cursorPos);
  1617         // scrollbars. the autoscrolling ensures smooth scrolling if necessary.
  1631         // scrollbars. the autoscrolling ensures smooth scrolling if necessary.
  1618         //q->ensureCursorVisible();
  1632         //q->ensureCursorVisible();
  1619         if (cursor.position() != oldCursorPos)
  1633         if (cursor.position() != oldCursorPos)
  1620             emit q->cursorPositionChanged();
  1634             emit q->cursorPositionChanged();
  1621         _q_updateCurrentCharFormatAndSelection();
  1635         _q_updateCurrentCharFormatAndSelection();
       
  1636 #ifndef QT_NO_IM
  1622         if (QInputContext *ic = inputContext()) {
  1637         if (QInputContext *ic = inputContext()) {
  1623             ic->update();
  1638             ic->update();
  1624         }
  1639         }
       
  1640 #endif //QT_NO_IM
  1625     } else {
  1641     } else {
  1626         //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
  1642         //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
  1627         if (cursor.position() != oldCursorPos)
  1643         if (cursor.position() != oldCursorPos)
  1628             emit q->cursorPositionChanged();
  1644             emit q->cursorPositionChanged();
  1629     }
  1645     }
  1827     Q_Q(QTextControl);
  1843     Q_Q(QTextControl);
  1828     if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) {
  1844     if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) {
  1829         e->ignore();
  1845         e->ignore();
  1830         return;
  1846         return;
  1831     }
  1847     }
  1832     bool isGettingInput = !e->commitString().isEmpty() || !e->preeditString().isEmpty()
  1848     bool isGettingInput = !e->commitString().isEmpty()
       
  1849             || e->preeditString() != cursor.block().layout()->preeditAreaText()
  1833             || e->replacementLength() > 0;
  1850             || e->replacementLength() > 0;
  1834 
  1851 
       
  1852     cursor.beginEditBlock();
  1835     if (isGettingInput) {
  1853     if (isGettingInput) {
  1836         cursor.beginEditBlock();
       
  1837         cursor.removeSelectedText();
  1854         cursor.removeSelectedText();
  1838     }
  1855     }
  1839 
  1856 
  1840     // insert commit string
  1857     // insert commit string
  1841     if (!e->commitString().isEmpty() || e->replacementLength()) {
  1858     if (!e->commitString().isEmpty() || e->replacementLength()) {
  1857         }
  1874         }
  1858     }
  1875     }
  1859 
  1876 
  1860     QTextBlock block = cursor.block();
  1877     QTextBlock block = cursor.block();
  1861     QTextLayout *layout = block.layout();
  1878     QTextLayout *layout = block.layout();
  1862     layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
  1879     if (isGettingInput)
       
  1880         layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
  1863     QList<QTextLayout::FormatRange> overrides;
  1881     QList<QTextLayout::FormatRange> overrides;
  1864     preeditCursor = e->preeditString().length();
  1882     preeditCursor = e->preeditString().length();
  1865     hideCursor = false;
  1883     hideCursor = false;
  1866     for (int i = 0; i < e->attributes().size(); ++i) {
  1884     for (int i = 0; i < e->attributes().size(); ++i) {
  1867         const QInputMethodEvent::Attribute &a = e->attributes().at(i);
  1885         const QInputMethodEvent::Attribute &a = e->attributes().at(i);
  1878                 overrides.append(o);
  1896                 overrides.append(o);
  1879             }
  1897             }
  1880         }
  1898         }
  1881     }
  1899     }
  1882     layout->setAdditionalFormats(overrides);
  1900     layout->setAdditionalFormats(overrides);
  1883 
  1901     cursor.endEditBlock();
  1884     if (isGettingInput)
       
  1885         cursor.endEditBlock();
       
  1886 }
  1902 }
  1887 
  1903 
  1888 QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
  1904 QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
  1889 {
  1905 {
  1890     Q_D(const QTextControl);
  1906     Q_D(const QTextControl);
  1920 {
  1936 {
  1921     Q_Q(QTextControl);
  1937     Q_Q(QTextControl);
  1922     emit q->updateRequest(q->selectionRect());
  1938     emit q->updateRequest(q->selectionRect());
  1923     if (e->gotFocus()) {
  1939     if (e->gotFocus()) {
  1924 #ifdef QT_KEYPAD_NAVIGATION
  1940 #ifdef QT_KEYPAD_NAVIGATION
  1925         if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) {
  1941         if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
       
  1942 #ifdef Q_OS_SYMBIAN
       
  1943             || e->reason() == Qt::ActiveWindowFocusReason
       
  1944 #endif
       
  1945             ))) {
  1926 #endif
  1946 #endif
  1927         cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
  1947         cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
  1928         if (interactionFlags & Qt::TextEditable) {
  1948         if (interactionFlags & Qt::TextEditable) {
  1929             setBlinkingCursorEnabled(true);
  1949             setBlinkingCursorEnabled(true);
  1930         }
  1950         }
  2252 {
  2272 {
  2253     Q_D(const QTextControl);
  2273     Q_D(const QTextControl);
  2254     return d->openExternalLinks;
  2274     return d->openExternalLinks;
  2255 }
  2275 }
  2256 
  2276 
       
  2277 bool QTextControl::ignoreUnusedNavigationEvents() const
       
  2278 {
       
  2279     Q_D(const QTextControl);
       
  2280     return d->ignoreUnusedNavigationEvents;
       
  2281 }
       
  2282 
       
  2283 void QTextControl::setIgnoreUnusedNavigationEvents(bool ignore)
       
  2284 {
       
  2285     Q_D(QTextControl);
       
  2286     d->ignoreUnusedNavigationEvents = ignore;
       
  2287 }
       
  2288 
  2257 void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
  2289 void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
  2258 {
  2290 {
  2259     Q_D(QTextControl);
  2291     Q_D(QTextControl);
  2260     const QTextCursor oldSelection = d->cursor;
  2292     const QTextCursor oldSelection = d->cursor;
  2261     const bool moved = d->cursor.movePosition(op, mode);
  2293     const bool moved = d->cursor.movePosition(op, mode);
  2308         tempDoc->setPageSize(doc->pageSize());
  2340         tempDoc->setPageSize(doc->pageSize());
  2309         tempDoc->setDefaultFont(doc->defaultFont());
  2341         tempDoc->setDefaultFont(doc->defaultFont());
  2310         tempDoc->setUseDesignMetrics(doc->useDesignMetrics());
  2342         tempDoc->setUseDesignMetrics(doc->useDesignMetrics());
  2311         QTextCursor(tempDoc).insertFragment(d->cursor.selection());
  2343         QTextCursor(tempDoc).insertFragment(d->cursor.selection());
  2312         doc = tempDoc;
  2344         doc = tempDoc;
       
  2345 
       
  2346         // copy the custom object handlers
       
  2347         doc->documentLayout()->d_func()->handlers = d->doc->documentLayout()->d_func()->handlers;
  2313     }
  2348     }
  2314     doc->print(printer);
  2349     doc->print(printer);
  2315     delete tempDoc;
  2350     delete tempDoc;
  2316 #endif
  2351 #endif
  2317 }
  2352 }