📄 qtextcontrol.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qtextcontrol_p.h"#include "qtextcontrol_p_p.h"#include "qlineedit.h"#ifndef QT_NO_TEXTCONTROL#include <qfont.h>#include <qpainter.h>#include <qevent.h>#include <qdebug.h>#include <qmime.h>#include <qdrag.h>#include <qclipboard.h>#include <qmenu.h>#include <qstyle.h>#include <qtimer.h>#include "private/qtextdocumentlayout_p.h"#include "private/qtextedit_p.h"#include "qtextdocument.h"#include "private/qtextdocument_p.h"#include "qtextlist.h"#include "private/qtextcontrol_p.h"#include "qgraphicssceneevent.h"#include "qprinter.h"#include <qtextformat.h>#include <qdatetime.h>#include <qapplication.h>#include <limits.h>#include <qtexttable.h>#include <qvariant.h>#include <qurl.h>#include <qdesktopservices.h>#include <qinputcontext.h>#include <qtooltip.h>#include <qstyleoption.h>#ifndef QT_NO_SHORTCUT#include <qkeysequence.h>#define ACCEL_KEY(k) QString::fromLatin1("\t") + QString(QKeySequence(k))#else#define ACCEL_KEY(k) QString()#endif// could go into QTextCursor...static QTextLine currentTextLine(const QTextCursor &cursor){ const QTextBlock block = cursor.block(); if (!block.isValid()) return QTextLine(); const QTextLayout *layout = block.layout(); if (!layout) return QTextLine(); const int relativePos = cursor.position() - block.position(); return layout->lineForTextPosition(relativePos);}QTextControlPrivate::QTextControlPrivate() : doc(0), cursorOn(false), cursorIsFocusIndicator(false), interactionFlags(Qt::TextEditorInteraction),#ifndef QT_NO_DRAGANDDROP mousePressed(false), mightStartDrag(false),#endif lastSelectionState(false), ignoreAutomaticScrollbarAdjustement(false), overwriteMode(false), acceptRichText(true), preeditCursor(0), hideCursor(false), hasFocus(false),#ifdef QT_KEYPAD_NAVIGATION hasEditFocus(false),#endif layoutDirection(QApplication::layoutDirection()), isEnabled(true), hadSelectionOnMousePress(false), openExternalLinks(false){}bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e){#ifdef QT_NO_SHORTCUT Q_UNUSED(e);#endif Q_Q(QTextControl); if (cursor.isNull()) return false; const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); QTextCursor::MoveMode mode = QTextCursor::MoveAnchor; QTextCursor::MoveOperation op = QTextCursor::NoMove; if (false) { }#ifndef QT_NO_SHORTCUT if (e == QKeySequence::MoveToNextChar) { op = QTextCursor::Right; } else if (e == QKeySequence::MoveToPreviousChar) { op = QTextCursor::Left; } else if (e == QKeySequence::SelectNextChar) { op = QTextCursor::Right; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectPreviousChar) { op = QTextCursor::Left; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectNextWord) { op = QTextCursor::WordRight; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectPreviousWord) { op = QTextCursor::WordLeft; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectStartOfLine) { op = QTextCursor::StartOfLine; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectEndOfLine) { op = QTextCursor::EndOfLine; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectStartOfBlock) { op = QTextCursor::StartOfBlock; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectEndOfBlock) { op = QTextCursor::EndOfBlock; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectStartOfDocument) { op = QTextCursor::Start; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectEndOfDocument) { op = QTextCursor::End; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectPreviousLine) { op = QTextCursor::Up; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectNextLine) { op = QTextCursor::Down; mode = QTextCursor::KeepAnchor; { QTextBlock block = cursor.block(); QTextLine line = currentTextLine(cursor); if (!block.next().isValid() && line.isValid() && line.lineNumber() == block.layout()->lineCount() - 1) op = QTextCursor::End; } } else if (e == QKeySequence::SelectNextLine) { op = QTextCursor::Down; mode = QTextCursor::KeepAnchor; { QTextBlock block = cursor.block(); QTextLine line = currentTextLine(cursor); if (!block.next().isValid() && line.isValid() && line.lineNumber() == block.layout()->lineCount() - 1) op = QTextCursor::End; } } else if (e == QKeySequence::MoveToNextWord) { op = QTextCursor::WordRight; } else if (e == QKeySequence::MoveToPreviousWord) { op = QTextCursor::WordLeft; } else if (e == QKeySequence::MoveToEndOfBlock) { op = QTextCursor::EndOfBlock; } else if (e == QKeySequence::MoveToStartOfBlock) { op = QTextCursor::StartOfBlock; } else if (e == QKeySequence::MoveToNextLine) { op = QTextCursor::Down; } else if (e == QKeySequence::MoveToPreviousLine) { op = QTextCursor::Up; } else if (e == QKeySequence::MoveToPreviousLine) { op = QTextCursor::Up; } else if (e == QKeySequence::MoveToStartOfLine) { op = QTextCursor::StartOfLine; } else if (e == QKeySequence::MoveToEndOfLine) { op = QTextCursor::EndOfLine; } else if (e == QKeySequence::MoveToStartOfDocument) { op = QTextCursor::Start; } else if (e == QKeySequence::MoveToEndOfDocument) { op = QTextCursor::End; }#endif // QT_NO_SHORTCUT else { return false; }// Except for pageup and pagedown, Mac OS X has very different behavior, we don't do it all, but// here's the breakdown:// Shift still works as an anchor, but only one of the other keys can be down Ctrl (Command),// Alt (Option), or Meta (Control).// Command/Control + Left/Right -- Move to left or right of the line// + Up/Down -- Move to top bottom of the file. (Control doesn't move the cursor)// Option + Left/Right -- Move one word Left/right.// + Up/Down -- Begin/End of Paragraph.// Home/End Top/Bottom of file. (usually don't move the cursor, but will select) const bool moved = cursor.movePosition(op, mode); q->ensureCursorVisible(); if (moved) { if (cursor.position() != oldCursorPos) emit q->cursorPositionChanged(); emit q->microFocusChanged(); }#ifdef QT_KEYPAD_NAVIGATION else if (QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) { return false; }#endif selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor)); repaintOldAndNewSelection(oldSelection); return true;}void QTextControlPrivate::updateCurrentCharFormat(){ Q_Q(QTextControl); QTextCharFormat fmt = cursor.charFormat(); if (fmt == lastCharFormat) return; lastCharFormat = fmt; emit q->currentCharFormatChanged(fmt); emit q->microFocusChanged();}void QTextControlPrivate::indent(){ QTextBlockFormat blockFmt = cursor.blockFormat(); QTextList *list = cursor.currentList(); if (!list) { QTextBlockFormat modifier; modifier.setIndent(blockFmt.indent() + 1); cursor.mergeBlockFormat(modifier); } else { QTextListFormat format = list->format(); format.setIndent(format.indent() + 1); if (list->itemNumber(cursor.block()) == 1) list->setFormat(format); else cursor.createList(format); }}void QTextControlPrivate::outdent(){ QTextBlockFormat blockFmt = cursor.blockFormat(); QTextList *list = cursor.currentList(); if (!list) { QTextBlockFormat modifier; modifier.setIndent(blockFmt.indent() - 1); cursor.mergeBlockFormat(modifier); } else { QTextListFormat listFmt = list->format(); listFmt.setIndent(listFmt.indent() - 1); list->setFormat(listFmt); }}void QTextControlPrivate::gotoNextTableCell(){ QTextTable *table = cursor.currentTable(); QTextTableCell cell = table->cellAt(cursor); int newColumn = cell.column() + cell.columnSpan(); int newRow = cell.row(); if (newColumn >= table->columns()) { newColumn = 0; ++newRow; if (newRow >= table->rows()) table->insertRows(table->rows(), 1); } cell = table->cellAt(newRow, newColumn); cursor = cell.firstCursorPosition();}void QTextControlPrivate::gotoPreviousTableCell(){ QTextTable *table = cursor.currentTable(); QTextTableCell cell = table->cellAt(cursor); int newColumn = cell.column() - 1; int newRow = cell.row(); if (newColumn < 0) { newColumn = table->columns() - 1; --newRow; if (newRow < 0) return; } cell = table->cellAt(newRow, newColumn); cursor = cell.firstCursorPosition();}void QTextControlPrivate::createAutoBulletList(){ cursor.beginEditBlock(); QTextBlockFormat blockFmt = cursor.blockFormat(); QTextListFormat listFmt; listFmt.setStyle(QTextListFormat::ListDisc); listFmt.setIndent(blockFmt.indent() + 1); blockFmt.setIndent(0); cursor.setBlockFormat(blockFmt); cursor.createList(listFmt); cursor.endEditBlock();}void QTextControlPrivate::init(Qt::TextFormat format, const QString &text, QTextDocument *document){ setContent(format, text, document); doc->setUndoRedoEnabled(interactionFlags & Qt::TextEditable);}void QTextControlPrivate::setContent(Qt::TextFormat format, const QString &text, QTextDocument *document){ Q_Q(QTextControl); // for use when called from setPlainText. we may want to re-use the currently // set char format then. const QTextCharFormat charFormatForInsertion = cursor.charFormat(); bool clearDocument = true; if (!doc) { palette = QApplication::palette("QTextControl"); if (document) { doc = document; clearDocument = false; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -