📄 qtextedit.cpp
字号:
} return; }#ifdef QT_KEYPAD_NAVIGATION switch (e->key()) { case Qt::Key_Select: if (QApplication::keypadNavigationEnabled()) setEditFocus(!hasEditFocus()); break; case Qt::Key_Back: case Qt::Key_No: if (!QApplication::keypadNavigationEnabled() || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) { e->ignore(); return; } break; default: if (QApplication::keypadNavigationEnabled()) { if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) { if (e->text()[0].isPrint()) { setEditFocus(true); clear(); } else { e->ignore(); return; } } } }#endif // schedule a repaint of the region of the cursor, as when we move it we // want to make sure the old cursor disappears (not noticable when moving // only a few pixels but noticable when jumping between cells in tables for // example) d->repaintSelection(); if (e->key() == Qt::Key_Direction_L || e->key() == Qt::Key_Direction_R) { QTextBlockFormat fmt; fmt.setLayoutDirection((e->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft); d->cursor.mergeBlockFormat(fmt); goto accept; } if (d->cursorMoveKeyEvent(e)) goto accept; if (e->modifiers() & Qt::ControlModifier) { switch( e->key() ) { case Qt::Key_Z: if (e->modifiers() & Qt::ShiftModifier) d->redo(); else d->undo(); break; case Qt::Key_Y: d->doc->redo(); break;#ifndef QT_NO_CLIPBOARD case Qt::Key_X: case Qt::Key_F20: // Cut key on Sun keyboards cut(); break; case Qt::Key_V: case Qt::Key_F18: // Paste key on Sun keyboards paste(); break;#endif // QT_NO_CLIPBOARD case Qt::Key_Backspace: d->cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); goto process; case Qt::Key_Delete: d->cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); goto process; case Qt::Key_K: { QTextBlock block = d->cursor.block(); if (d->cursor.position() == block.position() + block.length() - 2) d->cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); else d->cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); d->cursor.deleteChar(); break; } default: goto process; } goto accept; }process: switch( e->key() ) { case Qt::Key_Backspace: {#if defined(Q_WS_WIN) if (e->modifiers() & Qt::AltModifier) { if (e->modifiers() & Qt::ShiftModifier) d->redo(); else d->undo(); } else#endif { QTextBlockFormat blockFmt = d->cursor.blockFormat(); QTextList *list = d->cursor.currentList(); if (list && d->cursor.atBlockStart()) { list->remove(d->cursor.block()); } else if (d->cursor.atBlockStart() && blockFmt.indent() > 0) { blockFmt.setIndent(blockFmt.indent() - 1); d->cursor.setBlockFormat(blockFmt); } else { d->cursor.deletePreviousChar(); } } break; } case Qt::Key_Delete:#ifndef QT_NO_CLIPBOARD if (e->modifiers() & Qt::ShiftModifier) cut(); else#endif d->cursor.deleteChar(); break;#ifndef QT_NO_CLIPBOARD case Qt::Key_Insert: if (e->modifiers() & Qt::ShiftModifier) paste(); break;#endif case Qt::Key_Return: case Qt::Key_Enter: if (e->modifiers() & Qt::ControlModifier) d->cursor.insertText(QString(QChar::LineSeparator)); else d->cursor.insertBlock(); break;#ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Up: case Qt::Key_Down: if (QApplication::keypadNavigationEnabled()) { // Cursor position didn't change, so we want to leave // these keys to change focus. e->ignore(); return; } break; case Qt::Key_Back: if (!e->isAutoRepeat()) { if (QApplication::keypadNavigationEnabled()) { if (document()->isEmpty()) { setEditFocus(false); } else if (!d->deleteAllTimer.isActive()) { d->deleteAllTimer.start(750, this); } } else { e->ignore(); return; } } break;#endif default: { QString text = e->text(); if (e->key() == Qt::Key_Tab) { if (d->tabChangesFocus) { e->ignore(); return; } /* if (d->cursor.currentTable()) { d->gotoNextTableCell(); break; } else if (d->cursor.atBlockStart()) { d->indent(); break; } */ } if (e->key() == Qt::Key_Backtab) { if (d->tabChangesFocus) { e->ignore(); return; } /* if (d->cursor.currentTable()) { d->gotoPreviousTableCell(); break; } else if (d->cursor.atBlockStart()) { d->outdent(); break; } */ } if (d->cursor.atBlockStart() && (d->autoFormatting & AutoBulletList) && (!text.isEmpty()) && (text[0] == '-' || text[0] == '*') && (!d->cursor.currentList())) { text.remove(0, 1); d->createAutoBulletList(); } if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { if (d->overwriteMode // no need to call deleteChar() if we have a selection, insertText // does it already && !d->cursor.hasSelection() && !d->cursor.atBlockEnd()) d->cursor.deleteChar(); d->cursor.insertText(text); d->selectionChanged(); } else { QAbstractScrollArea::keyPressEvent(e); return; } break; } } accept: e->accept(); d->cursorOn = true; ensureCursorVisible(); d->updateCurrentCharFormat();}#ifdef QT_KEYPAD_NAVIGATION/*! \reimp*/void QTextEdit::keyReleaseEvent(QKeyEvent *e){ Q_D(QTextEdit); if (QApplication::keypadNavigationEnabled()) { if (!e->isAutoRepeat() && e->key() == Qt::Key_Back && d->deleteAllTimer.isActive()) { d->deleteAllTimer.stop(); QTextBlockFormat blockFmt = d->cursor.blockFormat(); QTextList *list = d->cursor.currentList(); if (list && d->cursor.atBlockStart()) { list->remove(d->cursor.block()); } else if (d->cursor.atBlockStart() && blockFmt.indent() > 0) { blockFmt.setIndent(blockFmt.indent() - 1); d->cursor.setBlockFormat(blockFmt); } else { d->cursor.deletePreviousChar(); } } }}#endif/*! Loads the resource specified by the given \a type and \a name. This function is an extension of QTextDocument::loadResource(). \sa QTextDocument::loadResource()*/QVariant QTextEdit::loadResource(int type, const QUrl &name){ Q_UNUSED(type); Q_UNUSED(name); return QVariant();}/*! \reimp*/void QTextEdit::resizeEvent(QResizeEvent *e){ Q_D(QTextEdit); if (d->lineWrap == WidgetWidth) { if (e->oldSize().width() == e->size().width() && e->oldSize().height() != e->size().height()) d->_q_adjustScrollbars(); else d->relayoutDocument(); } else { d->_q_adjustScrollbars(); }}void QTextEditPrivate::relayoutDocument(){ QAbstractTextDocumentLayout *layout = doc->documentLayout(); if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) { if (lineWrap == QTextEdit::NoWrap) tlayout->setBlockTextFlags(tlayout->blockTextFlags() | Qt::TextSingleLine); else tlayout->setBlockTextFlags(tlayout->blockTextFlags() & ~Qt::TextSingleLine); if (lineWrap == QTextEdit::FixedColumnWidth) tlayout->setFixedColumnWidth(lineWrapColumnOrWidth); else tlayout->setFixedColumnWidth(-1); } QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout); QSize lastUsedSize; if (tlayout) lastUsedSize = tlayout->dynamicDocumentSize().toSize(); else lastUsedSize = layout->documentSize().toSize(); // ignore calls to _q_adjustScrollbars caused by an emission of the // usedSizeChanged() signal in the layout, as we're calling it // later on our own anyway (or deliberately not) . ignoreAutomaticScrollbarAdjustement = true; int width = 0; switch (lineWrap) { case QTextEdit::NoWrap: width = 0; break; case QTextEdit::WidgetWidth: width = viewport->width(); break; case QTextEdit::FixedPixelWidth: width = lineWrapColumnOrWidth; break; case QTextEdit::FixedColumnWidth: width = 0; break; } doc->setPageSize(QSize(width, INT_MAX)); if (tlayout) tlayout->ensureLayouted(verticalOffset() + viewport->height()); ignoreAutomaticScrollbarAdjustement = false; QSize usedSize; if (tlayout) usedSize = tlayout->dynamicDocumentSize().toSize(); else usedSize = layout->documentSize().toSize(); // this is an obscure situation in the layout that can happen: // if a character at the end of a line is the tallest one and therefore // influencing the total height of the line and the line right below it // is always taller though, then it can happen that if due to line breaking // that tall character wraps into the lower line the document not only shrinks // horizontally (causing the character to wrap in the first place) but also // vertically, because the original line is now smaller and the one below kept // its size. So a layout with less width _can_ take up less vertical space, too. // If the wider case causes a vertical scrollbar to appear and the narrower one // (narrower because the vertical scrollbar takes up horizontal space)) to disappear // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the // scrollbars, the QAbstractScrollArea will find out about it and try to show/hide the scrollbars // again. That's why we try to detect this case here and break out. // // (if you change this please also check the layoutingLoop() testcase in // QTextEdit's autotests) if (lastUsedSize.isValid() && !vbar->isHidden() && viewport->width() < lastUsedSize.width() && usedSize.height() < lastUsedSize.height() && usedSize.height() <= viewport->height()) return; _q_adjustScrollbars();}QRect QTextEditPrivate::rectForPosition(int position) const{ const QTextBlock block = doc->findBlock(position); if (!block.isValid()) return QRect(); const QAbstractTextDocumentLayout *docLayout = doc->documentLayout(); const QTextLayout *layout = block.layout(); const QPointF layoutPos = docLayout->blockBoundingRect(block).topLeft(); int relativePos = position - block.position(); if (preeditCursor != 0) { int preeditPos = layout->preeditAreaPosition(); if (relativePos == preeditPos) relativePos += preeditCursor; else if (relativePos > preeditPos) relativePos += layout->preeditAreaText().length(); } QTextLine line = layout->lineForTextPosition(relativePos); QRect r; if (line.isValid()) r = QRect(qRound(layoutPos.x() + line.cursorToX(relativePos))-5, qRound(layoutPos.y() + line.y()), 10, qRound(line.ascent() + line.descent()+1.)); else r = QRect(qRound(layoutPos.x()-5), qRound(layoutPos.y()), 10, 10); // #### correct height return r;}QRect QTextEditPrivate::selectionRect() const{ QRect r = rectForPosition(cursor.selectionStart()); if (cursor.hasComplexSelection() && cursor.currentTable()) { QTextTable *table = cursor.currentTable(); r = doc->documentLayout()->frameBoundingRect(table).toRect(); /* int firstRow, numRows, firstColumn, numColumns; cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns); const QTextTableCell firstCell = table->cellAt(firstRow, firstColumn); const QTextTableCell lastCell = table->cellAt(firstRow + numRows - 1, firstColumn + numColumns - 1); const QAbstractTextDocumentLayout * const layout = doc->documentLayout(); QRectF tableSelRect = layout->blockBoundingRect(firs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -