diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2011-05-07 00:02:01 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2011-05-07 00:02:01 +0200 |
commit | f67b8df3ebdba2d398b9cce686b7c644adffff08 (patch) | |
tree | 062dd469f7cf8daa01a32d3e7b767b8fbdb7573a /src/gui/to_be_moved | |
parent | 32ce4fe9e6a94e77828e976776cf08da85254ff2 (diff) |
library split
Diffstat (limited to 'src/gui/to_be_moved')
-rw-r--r-- | src/gui/to_be_moved/qdnd.cpp | 491 | ||||
-rw-r--r-- | src/gui/to_be_moved/qdnd_p.h | 336 | ||||
-rw-r--r-- | src/gui/to_be_moved/qdnd_qpa.cpp | 426 | ||||
-rw-r--r-- | src/gui/to_be_moved/qdrag.cpp | 359 | ||||
-rw-r--r-- | src/gui/to_be_moved/qdrag.h | 105 | ||||
-rw-r--r-- | src/gui/to_be_moved/qlinecontrol.cpp | 1833 | ||||
-rw-r--r-- | src/gui/to_be_moved/qlinecontrol_p.h | 456 | ||||
-rw-r--r-- | src/gui/to_be_moved/qshortcut.cpp | 407 | ||||
-rw-r--r-- | src/gui/to_be_moved/qshortcut.h | 107 | ||||
-rw-r--r-- | src/gui/to_be_moved/qshortcutmap.cpp | 897 | ||||
-rw-r--r-- | src/gui/to_be_moved/qshortcutmap_p.h | 123 | ||||
-rw-r--r-- | src/gui/to_be_moved/qtextcontrol.cpp | 3148 | ||||
-rw-r--r-- | src/gui/to_be_moved/qtextcontrol_p.h | 307 | ||||
-rw-r--r-- | src/gui/to_be_moved/qtextcontrol_p_p.h | 238 | ||||
-rw-r--r-- | src/gui/to_be_moved/to_be_moved.pri | 17 |
15 files changed, 0 insertions, 9250 deletions
diff --git a/src/gui/to_be_moved/qdnd.cpp b/src/gui/to_be_moved/qdnd.cpp deleted file mode 100644 index db79b9042d..0000000000 --- a/src/gui/to_be_moved/qdnd.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" - -#include "qbitmap.h" -#include "qdrag.h" -#include "qpixmap.h" -#include "qevent.h" -#include "qfile.h" -#include "qtextcodec.h" -#include "qguiapplication.h" -#include "qpoint.h" -#include "qwidget.h" -#include "qbuffer.h" -#include "qimage.h" -#include "qregexp.h" -#include "qdir.h" -#include "qdnd_p.h" -#include "qimagereader.h" -#include "qimagewriter.h" -#include "qdebug.h" -#include <ctype.h> - -#include <private/qguiapplication_p.h> - -#ifndef QT_NO_DRAGANDDROP - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_DRAGANDDROP - -//#define QDND_DEBUG - -#ifdef QDND_DEBUG -QString dragActionsToString(Qt::DropActions actions) -{ - QString str; - if (actions == Qt::IgnoreAction) { - if (!str.isEmpty()) - str += " | "; - str += "IgnoreAction"; - } - if (actions & Qt::LinkAction) { - if (!str.isEmpty()) - str += " | "; - str += "LinkAction"; - } - if (actions & Qt::CopyAction) { - if (!str.isEmpty()) - str += " | "; - str += "CopyAction"; - } - if (actions & Qt::MoveAction) { - if (!str.isEmpty()) - str += " | "; - str += "MoveAction"; - } - if ((actions & Qt::TargetMoveAction) == Qt::TargetMoveAction ) { - if (!str.isEmpty()) - str += " | "; - str += "TargetMoveAction"; - } - return str; -} - -QString KeyboardModifiersToString(Qt::KeyboardModifiers moderfies) -{ - QString str; - if (moderfies & Qt::ControlModifier) { - if (!str.isEmpty()) - str += " | "; - str += Qt::ControlModifier; - } - if (moderfies & Qt::AltModifier) { - if (!str.isEmpty()) - str += " | "; - str += Qt::AltModifier; - } - if (moderfies & Qt::ShiftModifier) { - if (!str.isEmpty()) - str += " | "; - str += Qt::ShiftModifier; - } - return str; -} -#endif - - -// the universe's only drag manager -QDragManager *QDragManager::instance = 0; - - -QDragManager::QDragManager() - : QObject(qApp) -{ - Q_ASSERT(!instance); - -#ifdef Q_WS_QWS - currentActionForOverrideCursor = Qt::IgnoreAction; -#endif - object = 0; - beingCancelled = false; - restoreCursor = false; - willDrop = false; - eventLoop = 0; - dropData = new QDropData(); - currentDropTarget = 0; -#ifdef Q_WS_X11 - xdndMimeTransferedPixmapIndex = 0; -#endif -} - - -QDragManager::~QDragManager() -{ -#ifndef QT_NO_CURSOR - if (restoreCursor) - QGuiApplication::restoreOverrideCursor(); -#endif - instance = 0; - delete dropData; -} - -QDragManager *QDragManager::self() -{ - if (!instance && !QApplication::closingDown()) - instance = new QDragManager; - return instance; -} - -QPixmap QDragManager::dragCursor(Qt::DropAction action) const -{ - QDragPrivate * d = dragPrivate(); - if (d && d->customCursors.contains(action)) - return d->customCursors[action]; - else if (action == Qt::MoveAction) - return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragMoveCursor); - else if (action == Qt::CopyAction) - return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragCopyCursor); - else if (action == Qt::LinkAction) - return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragLinkCursor); -#ifdef Q_WS_WIN - else if (action == Qt::IgnoreAction) - return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::ForbiddenCursor); -#endif - return QPixmap(); -} - -bool QDragManager::hasCustomDragCursors() const -{ - QDragPrivate * d = dragPrivate(); - return d && !d->customCursors.isEmpty(); -} - -Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions, - Qt::KeyboardModifiers modifiers) const -{ -#ifdef QDND_DEBUG - qDebug("QDragManager::defaultAction(Qt::DropActions possibleActions)"); - qDebug("keyboard modifiers : %s", KeyboardModifiersToString(modifiers).latin1()); -#endif - - QDragPrivate *d = dragPrivate(); - Qt::DropAction defaultAction = d ? d->defaultDropAction : Qt::IgnoreAction; - - if (defaultAction == Qt::IgnoreAction) { - //This means that the drag was initiated by QDrag::start and we need to - //preserve the old behavior -#ifdef Q_WS_MAC - defaultAction = Qt::MoveAction; -#else - defaultAction = Qt::CopyAction; -#endif - } - -#ifdef Q_WS_MAC - if (modifiers & Qt::ControlModifier && modifiers & Qt::AltModifier) - defaultAction = Qt::LinkAction; - else if (modifiers & Qt::AltModifier) - defaultAction = Qt::CopyAction; - else if (modifiers & Qt::ControlModifier) - defaultAction = Qt::MoveAction; -#else - if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier) - defaultAction = Qt::LinkAction; - else if (modifiers & Qt::ControlModifier) - defaultAction = Qt::CopyAction; - else if (modifiers & Qt::ShiftModifier) - defaultAction = Qt::MoveAction; - else if (modifiers & Qt::AltModifier) - defaultAction = Qt::LinkAction; -#endif - - // if the object is set take the list of possibles from it - if (object) - possibleActions = object->d_func()->possible_actions; - -#ifdef QDND_DEBUG - qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1()); -#endif - - // Check if the action determined is allowed - if (!(possibleActions & defaultAction)) { - if (possibleActions & Qt::CopyAction) - defaultAction = Qt::CopyAction; - else if (possibleActions & Qt::MoveAction) - defaultAction = Qt::MoveAction; - else if (possibleActions & Qt::LinkAction) - defaultAction = Qt::LinkAction; - else - defaultAction = Qt::IgnoreAction; - } - -#ifdef QDND_DEBUG - qDebug("default action : %s", dragActionsToString(defaultAction).latin1()); -#endif - - return defaultAction; -} - -void QDragManager::setCurrentTarget(QWidget *target, bool dropped) -{ - if (currentDropTarget == target) - return; - - currentDropTarget = target; - if (!dropped && object) { - object->d_func()->target = target; - emit object->targetChanged(target); - } - -} - -QWidget *QDragManager::currentTarget() -{ - return currentDropTarget; -} - -#endif - -QDropData::QDropData() - : QInternalMimeData() -{ -} - -QDropData::~QDropData() -{ -} -#endif // QT_NO_DRAGANDDROP - -#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) - -static QStringList imageReadMimeFormats() -{ - QStringList formats; - QList<QByteArray> imageFormats = QImageReader::supportedImageFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - QString format = QLatin1String("image/"); - format += QString::fromLatin1(imageFormats.at(i).toLower()); - formats.append(format); - } - - //put png at the front because it is best - int pngIndex = formats.indexOf(QLatin1String("image/png")); - if (pngIndex != -1 && pngIndex != 0) - formats.move(pngIndex, 0); - - return formats; -} - - -static QStringList imageWriteMimeFormats() -{ - QStringList formats; - QList<QByteArray> imageFormats = QImageWriter::supportedImageFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - QString format = QLatin1String("image/"); - format += QString::fromLatin1(imageFormats.at(i).toLower()); - formats.append(format); - } - - //put png at the front because it is best - int pngIndex = formats.indexOf(QLatin1String("image/png")); - if (pngIndex != -1 && pngIndex != 0) - formats.move(pngIndex, 0); - - return formats; -} - -QInternalMimeData::QInternalMimeData() - : QMimeData() -{ -} - -QInternalMimeData::~QInternalMimeData() -{ -} - -bool QInternalMimeData::hasFormat(const QString &mimeType) const -{ - bool foundFormat = hasFormat_sys(mimeType); - if (!foundFormat && mimeType == QLatin1String("application/x-qt-image")) { - QStringList imageFormats = imageReadMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - if ((foundFormat = hasFormat_sys(imageFormats.at(i)))) - break; - } - } - return foundFormat; -} - -QStringList QInternalMimeData::formats() const -{ - QStringList realFormats = formats_sys(); - if (!realFormats.contains(QLatin1String("application/x-qt-image"))) { - QStringList imageFormats = imageReadMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - if (realFormats.contains(imageFormats.at(i))) { - realFormats += QLatin1String("application/x-qt-image"); - break; - } - } - } - return realFormats; -} - -QVariant QInternalMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const -{ - QVariant data = retrieveData_sys(mimeType, type); - if (mimeType == QLatin1String("application/x-qt-image")) { - if (data.isNull() || (data.type() == QVariant::ByteArray && data.toByteArray().isEmpty())) { - // try to find an image - QStringList imageFormats = imageReadMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - data = retrieveData_sys(imageFormats.at(i), type); - if (data.isNull() || (data.type() == QVariant::ByteArray && data.toByteArray().isEmpty())) - continue; - break; - } - } - // we wanted some image type, but all we got was a byte array. Convert it to an image. - if (data.type() == QVariant::ByteArray - && (type == QVariant::Image || type == QVariant::Pixmap || type == QVariant::Bitmap)) - data = QImage::fromData(data.toByteArray()); - - } else if (mimeType == QLatin1String("application/x-color") && data.type() == QVariant::ByteArray) { - QColor c; - QByteArray ba = data.toByteArray(); - if (ba.size() == 8) { - ushort * colBuf = (ushort *)ba.data(); - c.setRgbF(qreal(colBuf[0]) / qreal(0xFFFF), - qreal(colBuf[1]) / qreal(0xFFFF), - qreal(colBuf[2]) / qreal(0xFFFF), - qreal(colBuf[3]) / qreal(0xFFFF)); - data = c; - } else { - qWarning("Qt: Invalid color format"); - } - } else if (data.type() != type && data.type() == QVariant::ByteArray) { - // try to use mime data's internal conversion stuf. - QInternalMimeData *that = const_cast<QInternalMimeData *>(this); - that->setData(mimeType, data.toByteArray()); - data = QMimeData::retrieveData(mimeType, type); - that->clear(); - } - return data; -} - -bool QInternalMimeData::canReadData(const QString &mimeType) -{ - return imageReadMimeFormats().contains(mimeType); -} - -// helper functions for rendering mimedata to the system, this is needed because QMimeData is in core. -QStringList QInternalMimeData::formatsHelper(const QMimeData *data) -{ - QStringList realFormats = data->formats(); - if (realFormats.contains(QLatin1String("application/x-qt-image"))) { - // add all supported image formats - QStringList imageFormats = imageWriteMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - if (!realFormats.contains(imageFormats.at(i))) - realFormats.append(imageFormats.at(i)); - } - } - return realFormats; -} - -bool QInternalMimeData::hasFormatHelper(const QString &mimeType, const QMimeData *data) -{ - - bool foundFormat = data->hasFormat(mimeType); - if (!foundFormat) { - if (mimeType == QLatin1String("application/x-qt-image")) { - // check all supported image formats - QStringList imageFormats = imageWriteMimeFormats(); - for (int i = 0; i < imageFormats.size(); ++i) { - if ((foundFormat = data->hasFormat(imageFormats.at(i)))) - break; - } - } else if (mimeType.startsWith(QLatin1String("image/"))) { - return data->hasImage() && imageWriteMimeFormats().contains(mimeType); - } - } - return foundFormat; -} - -QByteArray QInternalMimeData::renderDataHelper(const QString &mimeType, const QMimeData *data) -{ - QByteArray ba; - if (mimeType == QLatin1String("application/x-color")) { - /* QMimeData can only provide colors as QColor or the name - of a color as a QByteArray or a QString. So we need to do - the conversion to application/x-color here. - The application/x-color format is : - type: application/x-color - format: 16 - data[0]: red - data[1]: green - data[2]: blue - data[3]: opacity - */ - ba.resize(8); - ushort * colBuf = (ushort *)ba.data(); - QColor c = qvariant_cast<QColor>(data->colorData()); - colBuf[0] = ushort(c.redF() * 0xFFFF); - colBuf[1] = ushort(c.greenF() * 0xFFFF); - colBuf[2] = ushort(c.blueF() * 0xFFFF); - colBuf[3] = ushort(c.alphaF() * 0xFFFF); - } else { - ba = data->data(mimeType); - if (ba.isEmpty()) { - if (mimeType == QLatin1String("application/x-qt-image") && data->hasImage()) { - QImage image = qvariant_cast<QImage>(data->imageData()); - QBuffer buf(&ba); - buf.open(QBuffer::WriteOnly); - // would there not be PNG ?? - image.save(&buf, "PNG"); - } else if (mimeType.startsWith(QLatin1String("image/")) && data->hasImage()) { - QImage image = qvariant_cast<QImage>(data->imageData()); - QBuffer buf(&ba); - buf.open(QBuffer::WriteOnly); - image.save(&buf, mimeType.mid(mimeType.indexOf(QLatin1Char('/')) + 1).toLatin1().toUpper()); - } - } - } - return ba; -} - -#endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD - -QT_END_NAMESPACE diff --git a/src/gui/to_be_moved/qdnd_p.h b/src/gui/to_be_moved/qdnd_p.h deleted file mode 100644 index 754366637c..0000000000 --- a/src/gui/to_be_moved/qdnd_p.h +++ /dev/null @@ -1,336 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDND_P_H -#define QDND_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtCore/qobject.h" -#include "QtCore/qmap.h" -#include "QtGui/qmime.h" -#include "QtGui/qdrag.h" -#include "QtGui/qpixmap.h" -#include "QtGui/qcursor.h" -#include "QtCore/qpoint.h" -#include "private/qobject_p.h" -#ifdef Q_WS_MAC -# include "private/qt_mac_p.h" -#endif - -#if defined(Q_WS_WIN) -# include <qt_windows.h> -# include <objidl.h> -#endif - -QT_BEGIN_NAMESPACE - -class QEventLoop; - -#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) - -class Q_GUI_EXPORT QInternalMimeData : public QMimeData -{ - Q_OBJECT -public: - QInternalMimeData(); - ~QInternalMimeData(); - - bool hasFormat(const QString &mimeType) const; - QStringList formats() const; - static bool canReadData(const QString &mimeType); - - - static QStringList formatsHelper(const QMimeData *data); - static bool hasFormatHelper(const QString &mimeType, const QMimeData *data); - static QByteArray renderDataHelper(const QString &mimeType, const QMimeData *data); - -protected: - QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; - - virtual bool hasFormat_sys(const QString &mimeType) const = 0; - virtual QStringList formats_sys() const = 0; - virtual QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const = 0; -}; - -#ifdef Q_WS_WIN -class QOleDataObject : public IDataObject -{ -public: - explicit QOleDataObject(QMimeData *mimeData); - virtual ~QOleDataObject(); - - void releaseQt(); - const QMimeData *mimeData() const; - DWORD reportedPerformedEffect() const; - - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - - // IDataObject methods - STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium); - STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium); - STDMETHOD(QueryGetData)(LPFORMATETC pformatetc); - STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut); - STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium, - BOOL fRelease); - STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc); - STDMETHOD(DAdvise)(FORMATETC FAR* pFormatetc, DWORD advf, - LPADVISESINK pAdvSink, DWORD FAR* pdwConnection); - STDMETHOD(DUnadvise)(DWORD dwConnection); - STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise); - -private: - ULONG m_refs; - QPointer<QMimeData> data; - int CF_PERFORMEDDROPEFFECT; - DWORD performedEffect; -}; - -class QOleEnumFmtEtc : public IEnumFORMATETC -{ -public: - explicit QOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs); - explicit QOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs); - virtual ~QOleEnumFmtEtc(); - - bool isNull() const; - - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - - // IEnumFORMATETC methods - STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched); - STDMETHOD(Skip)(ULONG celt); - STDMETHOD(Reset)(void); - STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum); - -private: - bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const; - - ULONG m_dwRefs; - ULONG m_nIndex; - QVector<LPFORMATETC> m_lpfmtetcs; - bool m_isNull; -}; - -#endif - -#endif //QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD - -#ifndef QT_NO_DRAGANDDROP - -class QDragPrivate : public QObjectPrivate -{ -public: - QWidget *source; - QWidget *target; - QMimeData *data; - QPixmap pixmap; - QPoint hotspot; - Qt::DropActions possible_actions; - Qt::DropAction executed_action; - QMap<Qt::DropAction, QPixmap> customCursors; - Qt::DropAction defaultDropAction; -}; - -class QDropData : public QInternalMimeData -{ - Q_OBJECT -public: - QDropData(); - ~QDropData(); - -protected: - bool hasFormat_sys(const QString &mimeType) const; - QStringList formats_sys() const; - QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; - -#if defined(Q_WS_WIN) -public: - LPDATAOBJECT currentDataObject; -#endif -}; - -class QDragManager: public QObject { - Q_OBJECT - - QDragManager(); - ~QDragManager(); - // only friend classes can use QDragManager. - friend class QDrag; - friend class QDragMoveEvent; - friend class QDropEvent; - friend class QApplication; -#ifdef Q_WS_MAC - friend class QWidgetPrivate; //dnd is implemented here -#endif - - bool eventFilter(QObject *, QEvent *); - void timerEvent(QTimerEvent*); - -public: - Qt::DropAction drag(QDrag *); - - void cancel(bool deleteSource = true); - void move(const QPoint &); - void drop(); - void updatePixmap(); - QWidget *source() const { return object ? object->d_func()->source : 0; } - QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; } - static QDragPrivate *dragPrivate(QDrag *drag) { return drag ? drag->d_func() : 0; } - - static QDragManager *self(); - Qt::DropAction defaultAction(Qt::DropActions possibleActions, - Qt::KeyboardModifiers modifiers) const; - - QDrag *object; - - void updateCursor(); - - bool beingCancelled; - bool restoreCursor; - bool willDrop; - QEventLoop *eventLoop; - - QPixmap dragCursor(Qt::DropAction action) const; - - bool hasCustomDragCursors() const; - - QDropData *dropData; - - void emitActionChanged(Qt::DropAction newAction) { if (object) emit object->actionChanged(newAction); } - - void setCurrentTarget(QWidget *target, bool dropped = false); - QWidget *currentTarget(); - -#ifdef Q_WS_X11 - QPixmap xdndMimeTransferedPixmap[2]; - int xdndMimeTransferedPixmapIndex; -#endif - -private: -#if defined(Q_WS_QWS) || defined(Q_WS_QPA) - Qt::DropAction currentActionForOverrideCursor; -#endif -#ifdef Q_OS_SYMBIAN -#ifndef QT_NO_CURSOR - QCursor overrideCursor; -#endif -#endif - QWidget *currentDropTarget; - - static QDragManager *instance; - Q_DISABLE_COPY(QDragManager) -}; - - -#if defined(Q_WS_WIN) - -class QOleDropTarget : public IDropTarget -{ -public: - QOleDropTarget(QWidget* w); - virtual ~QOleDropTarget() {} - - void releaseQt(); - - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG, AddRef)(void); - STDMETHOD_(ULONG, Release)(void); - - // IDropTarget methods - STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); - STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); - STDMETHOD(DragLeave)(); - STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); - -private: - ULONG m_refs; - QWidget* widget; - QPointer<QWidget> currentWidget; - QRect answerRect; - QPoint lastPoint; - DWORD chosenEffect; - DWORD lastKeyState; - - void sendDragEnterEvent(QWidget *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); -}; - -#endif - -#if defined (Q_WS_MAC) -class QCocoaDropData : public QInternalMimeData -{ - Q_OBJECT -public: - QCocoaDropData(CFStringRef pasteboard); - ~QCocoaDropData(); - -protected: - bool hasFormat_sys(const QString &mimeType) const; - QStringList formats_sys() const; - QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; -public: - CFStringRef dropPasteboard; -}; -#endif - -#endif // !QT_NO_DRAGANDDROP - - -QT_END_NAMESPACE - -#endif // QDND_P_H diff --git a/src/gui/to_be_moved/qdnd_qpa.cpp b/src/gui/to_be_moved/qdnd_qpa.cpp deleted file mode 100644 index 82e8d580ae..0000000000 --- a/src/gui/to_be_moved/qdnd_qpa.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qguiapplication.h" - -#ifndef QT_NO_DRAGANDDROP - -#include "qwidget.h" -#include "qdatetime.h" -#include "qbitmap.h" -#include "qcursor.h" -#include "qevent.h" -#include "qpainter.h" -#include "qdnd_p.h" - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -static QPixmap *defaultPm = 0; -static const int default_pm_hotx = -2; -static const int default_pm_hoty = -16; -static const char *const default_pm[] = { -"13 9 3 1", -". c None", -" c #000000", -"X c #FFFFFF", -"X X X X X X X", -" X X X X X X ", -"X ......... X", -" X.........X ", -"X ......... X", -" X.........X ", -"X ......... X", -" X X X X X X ", -"X X X X X X X", -}; - -// Shift/Ctrl handling, and final drop status -static Qt::DropAction global_accepted_action = Qt::CopyAction; -static Qt::DropActions possible_actions = Qt::IgnoreAction; - - -// static variables in place of a proper cross-process solution -static QDrag *drag_object; -static bool qt_qws_dnd_dragging = false; - - -static Qt::KeyboardModifiers oldstate; - -class QShapedPixmapWidget : public QWidget { - QPixmap pixmap; -public: - QShapedPixmapWidget() : - QWidget(0, Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint) - { - // ### Temporary workaround for 4.2-rc1!!! To prevent flickering when - // using drag'n drop in a client application. (task 126956) - // setAttribute() should be done unconditionally! - // if (QApplication::type() == QApplication::GuiServer) - setAttribute(Qt::WA_TransparentForMouseEvents); - } - - void setPixmap(QPixmap pm) - { - pixmap = pm; - if (!pixmap.mask().isNull()) { - setMask(pixmap.mask()); - } else { - clearMask(); - } - resize(pm.width(),pm.height()); - } - - void paintEvent(QPaintEvent*) - { - QPainter p(this); - p.drawPixmap(0,0,pixmap); - } -}; - - -static QShapedPixmapWidget *qt_qws_dnd_deco = 0; - - -void QDragManager::updatePixmap() -{ - if (qt_qws_dnd_deco) { - QPixmap pm; - QPoint pm_hot(default_pm_hotx,default_pm_hoty); - if (drag_object) { - pm = drag_object->pixmap(); - if (!pm.isNull()) - pm_hot = drag_object->hotSpot(); - } - if (pm.isNull()) { - if (!defaultPm) - defaultPm = new QPixmap(default_pm); - pm = *defaultPm; - } - qt_qws_dnd_deco->setPixmap(pm); - qt_qws_dnd_deco->move(QCursor::pos()-pm_hot); - if (willDrop) { - qt_qws_dnd_deco->show(); - } else { - qt_qws_dnd_deco->hide(); - } - } -} - -void QDragManager::timerEvent(QTimerEvent *) { } - -void QDragManager::move(const QPoint &) { } - -void QDragManager::updateCursor() -{ -#ifndef QT_NO_CURSOR - if (willDrop) { - if (qt_qws_dnd_deco) - qt_qws_dnd_deco->show(); - if (currentActionForOverrideCursor != global_accepted_action) { - QGuiApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0)); - currentActionForOverrideCursor = global_accepted_action; - } - } else { - QCursor *overrideCursor = QGuiApplication::overrideCursor(); - if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) { - QGuiApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor)); - currentActionForOverrideCursor = Qt::IgnoreAction; - } - if (qt_qws_dnd_deco) - qt_qws_dnd_deco->hide(); - } -#endif -} - - -bool QDragManager::eventFilter(QObject *o, QEvent *e) -{ - if (beingCancelled) { - if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) { - qApp->removeEventFilter(this); - Q_ASSERT(object == 0); - beingCancelled = false; - eventLoop->exit(); - return true; // block the key release - } - return false; - } - - - - if (!o->isWidgetType()) - return false; - - switch(e->type()) { - case QEvent::ShortcutOverride: - // prevent accelerators from firing while dragging - e->accept(); - return true; - - case QEvent::KeyPress: - case QEvent::KeyRelease: - { - QKeyEvent *ke = ((QKeyEvent*)e); - if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) { - cancel(); - qApp->removeEventFilter(this); - beingCancelled = false; - eventLoop->exit(); - } else { - updateCursor(); - } - return true; // Eat all key events - } - - case QEvent::MouseButtonPress: - case QEvent::MouseMove: - { - if (!object) { //#### this should not happen - qWarning("QDragManager::eventFilter: No object"); - return true; - } - - QDragManager *manager = QDragManager::self(); - QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData; - if (manager->object) - possible_actions = manager->dragPrivate()->possible_actions; - else - possible_actions = Qt::IgnoreAction; - - QMouseEvent *me = (QMouseEvent *)e; - if (me->buttons()) { - Qt::DropAction prevAction = global_accepted_action; - QWidget *cw = QApplication::widgetAt(me->globalPos()); - - // Fix for when we move mouse on to the deco widget - if (qt_qws_dnd_deco && cw == qt_qws_dnd_deco) - cw = object->target(); - - while (cw && !cw->acceptDrops() && !cw->isWindow()) - cw = cw->parentWidget(); - - if (object->target() != cw) { - if (object->target()) { - QDragLeaveEvent dle; - QCoreApplication::sendEvent(object->target(), &dle); - willDrop = false; - global_accepted_action = Qt::IgnoreAction; - updateCursor(); - restoreCursor = true; - object->d_func()->target = 0; - } - if (cw && cw->acceptDrops()) { - object->d_func()->target = cw; - QDragEnterEvent dee(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData, - me->buttons(), me->modifiers()); - QCoreApplication::sendEvent(object->target(), &dee); - willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction; - global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction; - updateCursor(); - restoreCursor = true; - } - } else if (cw) { - QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData, - me->buttons(), me->modifiers()); - if (global_accepted_action != Qt::IgnoreAction) { - dme.setDropAction(global_accepted_action); - dme.accept(); - } - QCoreApplication::sendEvent(cw, &dme); - willDrop = dme.isAccepted(); - global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction; - updatePixmap(); - updateCursor(); - } - if (global_accepted_action != prevAction) - emitActionChanged(global_accepted_action); - } - return true; // Eat all mouse events - } - - case QEvent::MouseButtonRelease: - { - qApp->removeEventFilter(this); - if (restoreCursor) { - willDrop = false; -#ifndef QT_NO_CURSOR - QGuiApplication::restoreOverrideCursor(); -#endif - restoreCursor = false; - } - if (object && object->target()) { - QMouseEvent *me = (QMouseEvent *)e; - - QDragManager *manager = QDragManager::self(); - QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData; - - QDropEvent de(object->target()->mapFromGlobal(me->globalPos()), possible_actions, dropData, - me->buttons(), me->modifiers()); - QCoreApplication::sendEvent(object->target(), &de); - if (de.isAccepted()) - global_accepted_action = de.dropAction(); - else - global_accepted_action = Qt::IgnoreAction; - - if (object) - object->deleteLater(); - drag_object = object = 0; - } - eventLoop->exit(); - return true; // Eat all mouse events - } - - default: - break; - } - - return false; -} - -Qt::DropAction QDragManager::drag(QDrag *o) -{ - if (object == o || !o || !o->source()) - return Qt::IgnoreAction; - - if (object) { - cancel(); - qApp->removeEventFilter(this); - beingCancelled = false; - } - - object = drag_object = o; - qt_qws_dnd_deco = new QShapedPixmapWidget(); - oldstate = Qt::NoModifier; // #### Should use state that caused the drag -// drag_mode = mode; - - willDrop = false; - updatePixmap(); - updateCursor(); - restoreCursor = true; - object->d_func()->target = 0; - qApp->installEventFilter(this); - - global_accepted_action = Qt::CopyAction; -#ifndef QT_NO_CURSOR - qApp->setOverrideCursor(Qt::ArrowCursor); - restoreCursor = true; - updateCursor(); -#endif - - qt_qws_dnd_dragging = true; - - eventLoop = new QEventLoop; - (void) eventLoop->exec(); - delete eventLoop; - eventLoop = 0; - - delete qt_qws_dnd_deco; - qt_qws_dnd_deco = 0; - qt_qws_dnd_dragging = false; - - - return global_accepted_action; -} - - -void QDragManager::cancel(bool deleteSource) -{ -// qDebug("QDragManager::cancel"); - beingCancelled = true; - - if (object->target()) { - QDragLeaveEvent dle; - QCoreApplication::sendEvent(object->target(), &dle); - } - -#ifndef QT_NO_CURSOR - if (restoreCursor) { - QGuiApplication::restoreOverrideCursor(); - restoreCursor = false; - } -#endif - - if (drag_object) { - if (deleteSource) - object->deleteLater(); - drag_object = object = 0; - } - - delete qt_qws_dnd_deco; - qt_qws_dnd_deco = 0; - - global_accepted_action = Qt::IgnoreAction; -} - - -void QDragManager::drop() -{ -} - -QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const -{ - if (!drag_object) - return QVariant(); - QByteArray data = drag_object->mimeData()->data(mimetype); - if (type == QVariant::String) - return QString::fromUtf8(data); - return data; -} - -bool QDropData::hasFormat_sys(const QString &format) const -{ - return formats().contains(format); -} - -QStringList QDropData::formats_sys() const -{ - if (drag_object) - return drag_object->mimeData()->formats(); - return QStringList(); -} - - -#endif // QT_NO_DRAGANDDROP - - -QT_END_NAMESPACE diff --git a/src/gui/to_be_moved/qdrag.cpp b/src/gui/to_be_moved/qdrag.cpp deleted file mode 100644 index d8d14cb45c..0000000000 --- a/src/gui/to_be_moved/qdrag.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qwidget.h> -#include <qdrag.h> -#include <qpixmap.h> -#include <qpoint.h> -#include "qdnd_p.h" - -#ifndef QT_NO_DRAGANDDROP - -QT_BEGIN_NAMESPACE - -/*! - \class QDrag - \brief The QDrag class provides support for MIME-based drag and drop data - transfer. - - Drag and drop is an intuitive way for users to copy or move data around in an - application, and is used in many desktop environments as a mechanism for copying - data between applications. Drag and drop support in Qt is centered around the - QDrag class that handles most of the details of a drag and drop operation. - - The data to be transferred by the drag and drop operation is contained in a - QMimeData object. This is specified with the setMimeData() function in the - following way: - - \snippet doc/src/snippets/dragging/mainwindow.cpp 1 - - Note that setMimeData() assigns ownership of the QMimeData object to the - QDrag object. The QDrag must be constructed on the heap with a parent QWidget - to ensure that Qt can clean up after the drag and drop operation has been - completed. - - A pixmap can be used to represent the data while the drag is in - progress, and will move with the cursor to the drop target. This - pixmap typically shows an icon that represents the MIME type of - the data being transferred, but any pixmap can be set with - setPixmap(). The cursor's hot spot can be given a position - relative to the top-left corner of the pixmap with the - setHotSpot() function. The following code positions the pixmap so - that the cursor's hot spot points to the center of its bottom - edge: - - \snippet doc/src/snippets/separations/finalwidget.cpp 2 - - \note On X11, the pixmap may not be able to keep up with the mouse - movements if the hot spot causes the pixmap to be displayed - directly under the cursor. - - The source and target widgets can be found with source() and target(). - These functions are often used to determine whether drag and drop operations - started and finished at the same widget, so that special behavior can be - implemented. - - QDrag only deals with the drag and drop operation itself. It is up to the - developer to decide when a drag operation begins, and how a QDrag object should - be constructed and used. For a given widget, it is often necessary to - reimplement \l{QWidget::mousePressEvent()}{mousePressEvent()} to determine - whether the user has pressed a mouse button, and reimplement - \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is - required. - - \sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime, - {Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example}, - {Fridge Magnets Example} -*/ - -/*! - Constructs a new drag object for the widget specified by \a dragSource. -*/ -QDrag::QDrag(QWidget *dragSource) - : QObject(*new QDragPrivate, dragSource) -{ - Q_D(QDrag); - d->source = dragSource; - d->target = 0; - d->data = 0; - d->hotspot = QPoint(-10, -10); - d->possible_actions = Qt::CopyAction; - d->executed_action = Qt::IgnoreAction; - d->defaultDropAction = Qt::IgnoreAction; -} - -/*! - Destroys the drag object. -*/ -QDrag::~QDrag() -{ - Q_D(QDrag); - delete d->data; - QDragManager *manager = QDragManager::self(); - if (manager && manager->object == this) - manager->cancel(false); -} - -/*! - Sets the data to be sent to the given MIME \a data. Ownership of the data is - transferred to the QDrag object. -*/ -void QDrag::setMimeData(QMimeData *data) -{ - Q_D(QDrag); - if (d->data == data) - return; - if (d->data != 0) - delete d->data; - d->data = data; -} - -/*! - Returns the MIME data that is encapsulated by the drag object. -*/ -QMimeData *QDrag::mimeData() const -{ - Q_D(const QDrag); - return d->data; -} - -/*! - Sets \a pixmap as the pixmap used to represent the data in a drag - and drop operation. You can only set a pixmap before the drag is - started. -*/ -void QDrag::setPixmap(const QPixmap &pixmap) -{ - Q_D(QDrag); - d->pixmap = pixmap; -} - -/*! - Returns the pixmap used to represent the data in a drag and drop operation. -*/ -QPixmap QDrag::pixmap() const -{ - Q_D(const QDrag); - return d->pixmap; -} - -/*! - Sets the position of the hot spot relative to the top-left corner of the - pixmap used to the point specified by \a hotspot. - - \bold{Note:} on X11, the pixmap may not be able to keep up with the mouse - movements if the hot spot causes the pixmap to be displayed - directly under the cursor. -*/ -void QDrag::setHotSpot(const QPoint& hotspot) -{ - Q_D(QDrag); - d->hotspot = hotspot; -} - -/*! - Returns the position of the hot spot relative to the top-left corner of the - cursor. -*/ -QPoint QDrag::hotSpot() const -{ - Q_D(const QDrag); - return d->hotspot; -} - -/*! - Returns the source of the drag object. This is the widget where the drag - and drop operation originated. -*/ -QWidget *QDrag::source() const -{ - Q_D(const QDrag); - return d->source; -} - -/*! - Returns the target of the drag and drop operation. This is the widget where - the drag object was dropped. -*/ -QWidget *QDrag::target() const -{ - Q_D(const QDrag); - return d->target; -} - -/*! - \since 4.3 - - Starts the drag and drop operation and returns a value indicating the requested - drop action when it is completed. The drop actions that the user can choose - from are specified in \a supportedActions. The default proposed action will be selected - among the allowed actions in the following order: Move, Copy and Link. - - \bold{Note:} On Linux and Mac OS X, the drag and drop operation - can take some time, but this function does not block the event - loop. Other events are still delivered to the application while - the operation is performed. On Windows, the Qt event loop is - blocked while during the operation. -*/ - -Qt::DropAction QDrag::exec(Qt::DropActions supportedActions) -{ - return exec(supportedActions, Qt::IgnoreAction); -} - -/*! - \since 4.3 - - Starts the drag and drop operation and returns a value indicating the requested - drop action when it is completed. The drop actions that the user can choose - from are specified in \a supportedActions. - - The \a defaultDropAction determines which action will be proposed when the user performs a - drag without using modifier keys. - - \bold{Note:} On Linux and Mac OS X, the drag and drop operation - can take some time, but this function does not block the event - loop. Other events are still delivered to the application while - the operation is performed. On Windows, the Qt event loop is - blocked during the operation. However, QDrag::exec() on - Windows causes processEvents() to be called frequently to keep the GUI responsive. - If any loops or operations are called while a drag operation is active, it will block the drag operation. -*/ - -Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defaultDropAction) -{ - Q_D(QDrag); - if (!d->data) { - qWarning("QDrag: No mimedata set before starting the drag"); - return d->executed_action; - } - QDragManager *manager = QDragManager::self(); - d->defaultDropAction = Qt::IgnoreAction; - d->possible_actions = supportedActions; - - if (manager) { - if (defaultDropAction == Qt::IgnoreAction) { - if (supportedActions & Qt::MoveAction) { - d->defaultDropAction = Qt::MoveAction; - } else if (supportedActions & Qt::CopyAction) { - d->defaultDropAction = Qt::CopyAction; - } else if (supportedActions & Qt::LinkAction) { - d->defaultDropAction = Qt::LinkAction; - } - } else { - d->defaultDropAction = defaultDropAction; - } - d->executed_action = manager->drag(this); - } - - return d->executed_action; -} - -/*! - \obsolete - - \bold{Note:} It is recommended to use exec() instead of this function. - - Starts the drag and drop operation and returns a value indicating the requested - drop action when it is completed. The drop actions that the user can choose - from are specified in \a request. Qt::CopyAction is always allowed. - - \bold{Note:} Although the drag and drop operation can take some time, this function - does not block the event loop. Other events are still delivered to the application - while the operation is performed. - - \sa exec() -*/ -Qt::DropAction QDrag::start(Qt::DropActions request) -{ - Q_D(QDrag); - if (!d->data) { - qWarning("QDrag: No mimedata set before starting the drag"); - return d->executed_action; - } - QDragManager *manager = QDragManager::self(); - d->defaultDropAction = Qt::IgnoreAction; - d->possible_actions = request | Qt::CopyAction; - if (manager) - d->executed_action = manager->drag(this); - return d->executed_action; -} - -/*! - Sets the drag \a cursor for the \a action. This allows you - to override the default native cursors. To revert to using the - native cursor for \a action pass in a null QPixmap as \a cursor. - - The \a action can only be CopyAction, MoveAction or LinkAction. - All other values of DropAction are ignored. -*/ -void QDrag::setDragCursor(const QPixmap &cursor, Qt::DropAction action) -{ - Q_D(QDrag); - if (action != Qt::CopyAction && action != Qt::MoveAction && action != Qt::LinkAction) - return; - if (cursor.isNull()) - d->customCursors.remove(action); - else - d->customCursors[action] = cursor; -} - -/*! - \fn void QDrag::actionChanged(Qt::DropAction action) - - This signal is emitted when the \a action associated with the - drag changes. - - \sa targetChanged() -*/ - -/*! - \fn void QDrag::targetChanged(QWidget *newTarget) - - This signal is emitted when the target of the drag and drop - operation changes, with \a newTarget the new target. - - \sa target(), actionChanged() -*/ - -QT_END_NAMESPACE - -#endif // QT_NO_DRAGANDDROP diff --git a/src/gui/to_be_moved/qdrag.h b/src/gui/to_be_moved/qdrag.h deleted file mode 100644 index da847898b2..0000000000 --- a/src/gui/to_be_moved/qdrag.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDRAG_H -#define QDRAG_H - -#include <QtCore/qobject.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_DRAGANDDROP -class QMimeData; -class QDragPrivate; -class QWidget; -class QPixmap; -class QPoint; -class QDragManager; - -class Q_GUI_EXPORT QDrag : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QDrag) -public: - explicit QDrag(QWidget *dragSource); - ~QDrag(); - - void setMimeData(QMimeData *data); - QMimeData *mimeData() const; - - void setPixmap(const QPixmap &); - QPixmap pixmap() const; - - void setHotSpot(const QPoint &hotspot); - QPoint hotSpot() const; - - QWidget *source() const; - QWidget *target() const; - - Qt::DropAction start(Qt::DropActions supportedActions = Qt::CopyAction); - Qt::DropAction exec(Qt::DropActions supportedActions = Qt::MoveAction); - Qt::DropAction exec(Qt::DropActions supportedActions, Qt::DropAction defaultAction); - - void setDragCursor(const QPixmap &cursor, Qt::DropAction action); - -Q_SIGNALS: - void actionChanged(Qt::DropAction action); - void targetChanged(QWidget *newTarget); - -private: -#ifdef Q_WS_MAC - friend class QWidgetPrivate; -#endif - friend class QDragManager; - Q_DISABLE_COPY(QDrag) -}; - -#endif // QT_NO_DRAGANDDROP - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QDRAG_H diff --git a/src/gui/to_be_moved/qlinecontrol.cpp b/src/gui/to_be_moved/qlinecontrol.cpp deleted file mode 100644 index eb4e142328..0000000000 --- a/src/gui/to_be_moved/qlinecontrol.cpp +++ /dev/null @@ -1,1833 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qlinecontrol_p.h" - -#ifndef QT_NO_LINEEDIT - -#include "qabstractitemview.h" -#include "qclipboard.h" -#ifndef QT_NO_ACCESSIBILITY -#include "qaccessible.h" -#endif -#ifndef QT_NO_IM -#include "qinputcontext.h" -#include "qlist.h" -#endif -#include "qapplication.h" -#ifndef QT_NO_GRAPHICSVIEW -#include "qgraphicssceneevent.h" -#endif - -QT_BEGIN_NAMESPACE - -/*! - \internal - - Updates the display text based of the current edit text - If the text has changed will emit displayTextChanged() -*/ -void QLineControl::updateDisplayText(bool forceUpdate) -{ - QString orig = m_textLayout.text(); - QString str; - if (m_echoMode == QLineEdit::NoEcho) - str = QString::fromLatin1(""); - else - str = m_text; - - if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit - && !m_passwordEchoEditing)) - str.fill(m_passwordCharacter); - - // replace certain non-printable characters with spaces (to avoid - // drawing boxes when using fonts that don't have glyphs for such - // characters) - QChar* uc = str.data(); - for (int i = 0; i < (int)str.length(); ++i) { - if ((uc[i] < 0x20 && uc[i] != 0x09) - || uc[i] == QChar::LineSeparator - || uc[i] == QChar::ParagraphSeparator - || uc[i] == QChar::ObjectReplacementCharacter) - uc[i] = QChar(0x0020); - } - - m_textLayout.setText(str); - - QTextOption option; - option.setTextDirection(m_layoutDirection); - option.setFlags(QTextOption::IncludeTrailingSpaces); - m_textLayout.setTextOption(option); - - m_textLayout.beginLayout(); - QTextLine l = m_textLayout.createLine(); - m_textLayout.endLayout(); - m_ascent = qRound(l.ascent()); - - if (str != orig || forceUpdate) - emit displayTextChanged(str); -} - -#ifndef QT_NO_CLIPBOARD -/*! - \internal - - Copies the currently selected text into the clipboard using the given - \a mode. - - \note If the echo mode is set to a mode other than Normal then copy - will not work. This is to prevent using copy as a method of bypassing - password features of the line control. -*/ -void QLineControl::copy(QClipboard::Mode mode) const -{ - QString t = selectedText(); - if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) { - disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0); - QApplication::clipboard()->setText(t, mode); - connect(QApplication::clipboard(), SIGNAL(selectionChanged()), - this, SLOT(_q_clipboardChanged())); - } -} - -/*! - \internal - - Inserts the text stored in the application clipboard into the line - control. - - \sa insert() -*/ -void QLineControl::paste(QClipboard::Mode clipboardMode) -{ - QString clip = QApplication::clipboard()->text(clipboardMode); - if (!clip.isEmpty() || hasSelectedText()) { - separate(); //make it a separate undo/redo command - insert(clip); - separate(); - } -} - -#endif // !QT_NO_CLIPBOARD - -/*! - \internal - - Handles the behavior for the backspace key or function. - Removes the current selection if there is a selection, otherwise - removes the character prior to the cursor position. - - \sa del() -*/ -void QLineControl::backspace() -{ - int priorState = m_undoState; - if (hasSelectedText()) { - removeSelectedText(); - } else if (m_cursor) { - --m_cursor; - if (m_maskData) - m_cursor = prevMaskBlank(m_cursor); - QChar uc = m_text.at(m_cursor); - if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { - // second half of a surrogate, check if we have the first half as well, - // if yes delete both at once - uc = m_text.at(m_cursor - 1); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) { - internalDelete(true); - --m_cursor; - } - } - internalDelete(true); - } - finishChange(priorState); -} - -/*! - \internal - - Handles the behavior for the delete key or function. - Removes the current selection if there is a selection, otherwise - removes the character after the cursor position. - - \sa del() -*/ -void QLineControl::del() -{ - int priorState = m_undoState; - if (hasSelectedText()) { - removeSelectedText(); - } else { - int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor; - while (n--) - internalDelete(); - } - finishChange(priorState); -} - -/*! - \internal - - Inserts the given \a newText at the current cursor position. - If there is any selected text it is removed prior to insertion of - the new text. -*/ -void QLineControl::insert(const QString &newText) -{ - int priorState = m_undoState; - removeSelectedText(); - internalInsert(newText); - finishChange(priorState); -} - -/*! - \internal - - Clears the line control text. -*/ -void QLineControl::clear() -{ - int priorState = m_undoState; - m_selstart = 0; - m_selend = m_text.length(); - removeSelectedText(); - separate(); - finishChange(priorState, /*update*/false, /*edited*/false); -} - -/*! - \internal - - Sets \a length characters from the given \a start position as selected. - The given \a start position must be within the current text for - the line control. If \a length characters cannot be selected, then - the selection will extend to the end of the current text. -*/ -void QLineControl::setSelection(int start, int length) -{ - if(start < 0 || start > (int)m_text.length()){ - qWarning("QLineControl::setSelection: Invalid start position"); - return; - } - - if (length > 0) { - if (start == m_selstart && start + length == m_selend) - return; - m_selstart = start; - m_selend = qMin(start + length, (int)m_text.length()); - m_cursor = m_selend; - } else if (length < 0){ - if (start == m_selend && start + length == m_selstart) - return; - m_selstart = qMax(start + length, 0); - m_selend = start; - m_cursor = m_selstart; - } else if (m_selstart != m_selend) { - m_selstart = 0; - m_selend = 0; - m_cursor = start; - } else { - m_cursor = start; - emitCursorPositionChanged(); - return; - } - emit selectionChanged(); - emitCursorPositionChanged(); -} - -void QLineControl::_q_clipboardChanged() -{ -} - -void QLineControl::_q_deleteSelected() -{ - if (!hasSelectedText()) - return; - - int priorState = m_undoState; - emit resetInputContext(); - removeSelectedText(); - separate(); - finishChange(priorState); -} - -/*! - \internal - - Initializes the line control with a starting text value of \a txt. -*/ -void QLineControl::init(const QString &txt) -{ - m_text = txt; - updateDisplayText(); - m_cursor = m_text.length(); -} - -/*! - \internal - - Sets the password echo editing to \a editing. If password echo editing - is true, then the text of the password is displayed even if the echo - mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing - does not affect other echo modes. -*/ -void QLineControl::updatePasswordEchoEditing(bool editing) -{ - m_passwordEchoEditing = editing; - updateDisplayText(); -} - -/*! - \internal - - Returns the cursor position of the given \a x pixel value in relation - to the displayed text. The given \a betweenOrOn specified what kind - of cursor position is requested. -*/ -int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const -{ - return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn); -} - -/*! - \internal - - Returns the bounds of the current cursor, as defined as a - between characters cursor. -*/ -QRect QLineControl::cursorRect() const -{ - QTextLine l = m_textLayout.lineAt(0); - int c = m_cursor; - if (m_preeditCursor != -1) - c += m_preeditCursor; - int cix = qRound(l.cursorToX(c)); - int w = m_cursorWidth; - int ch = l.height() + 1; - - return QRect(cix-5, 0, w+9, ch); -} - -/*! - \internal - - Fixes the current text so that it is valid given any set validators. - - Returns true if the text was changed. Otherwise returns false. -*/ -bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable -{ -#ifndef QT_NO_VALIDATOR - if (m_validator) { - QString textCopy = m_text; - int cursorCopy = m_cursor; - m_validator->fixup(textCopy); - if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) { - if (textCopy != m_text || cursorCopy != m_cursor) - internalSetText(textCopy, cursorCopy); - return true; - } - } -#endif - return false; -} - -/*! - \internal - - Moves the cursor to the given position \a pos. If \a mark is true will - adjust the currently selected text. -*/ -void QLineControl::moveCursor(int pos, bool mark) -{ - if (pos != m_cursor) { - separate(); - if (m_maskData) - pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos); - } - if (mark) { - int anchor; - if (m_selend > m_selstart && m_cursor == m_selstart) - anchor = m_selend; - else if (m_selend > m_selstart && m_cursor == m_selend) - anchor = m_selstart; - else - anchor = m_cursor; - m_selstart = qMin(anchor, pos); - m_selend = qMax(anchor, pos); - updateDisplayText(); - } else { - internalDeselect(); - } - m_cursor = pos; - if (mark || m_selDirty) { - m_selDirty = false; - emit selectionChanged(); - } - emitCursorPositionChanged(); -} - -/*! - \internal - - Applies the given input method event \a event to the text of the line - control -*/ -void QLineControl::processInputMethodEvent(QInputMethodEvent *event) -{ - int priorState = 0; - bool isGettingInput = !event->commitString().isEmpty() - || event->preeditString() != preeditAreaText() - || event->replacementLength() > 0; - bool cursorPositionChanged = false; - - if (isGettingInput) { - // If any text is being input, remove selected text. - priorState = m_undoState; - if (echoMode() == QLineEdit::PasswordEchoOnEdit && !passwordEchoEditing()) { - updatePasswordEchoEditing(true); - m_selstart = 0; - m_selend = m_text.length(); - } - removeSelectedText(); - } - - int c = m_cursor; // cursor position after insertion of commit string - if (event->replacementStart() <= 0) - c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength()); - - m_cursor += event->replacementStart(); - - // insert commit string - if (event->replacementLength()) { - m_selstart = m_cursor; - m_selend = m_selstart + event->replacementLength(); - removeSelectedText(); - } - if (!event->commitString().isEmpty()) { - internalInsert(event->commitString()); - cursorPositionChanged = true; - } - - m_cursor = qMin(c, m_text.length()); - - for (int i = 0; i < event->attributes().size(); ++i) { - const QInputMethodEvent::Attribute &a = event->attributes().at(i); - if (a.type == QInputMethodEvent::Selection) { - m_cursor = qBound(0, a.start + a.length, m_text.length()); - if (a.length) { - m_selstart = qMax(0, qMin(a.start, m_text.length())); - m_selend = m_cursor; - if (m_selend < m_selstart) { - qSwap(m_selstart, m_selend); - } - } else { - m_selstart = m_selend = 0; - } - cursorPositionChanged = true; - } - } -#ifndef QT_NO_IM - setPreeditArea(m_cursor, event->preeditString()); -#endif //QT_NO_IM - const int oldPreeditCursor = m_preeditCursor; - m_preeditCursor = event->preeditString().length(); - m_hideCursor = false; - QList<QTextLayout::FormatRange> formats; - for (int i = 0; i < event->attributes().size(); ++i) { - const QInputMethodEvent::Attribute &a = event->attributes().at(i); - if (a.type == QInputMethodEvent::Cursor) { - m_preeditCursor = a.start; - m_hideCursor = !a.length; - } else if (a.type == QInputMethodEvent::TextFormat) { - QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat(); - if (f.isValid()) { - QTextLayout::FormatRange o; - o.start = a.start + m_cursor; - o.length = a.length; - o.format = f; - formats.append(o); - } - } - } - m_textLayout.setAdditionalFormats(formats); - updateDisplayText(/*force*/ true); - if (cursorPositionChanged) - emitCursorPositionChanged(); - else if (m_preeditCursor != oldPreeditCursor) - emit updateMicroFocus(); - if (isGettingInput) - finishChange(priorState); -} - -/*! - \internal - - Draws the display text for the line control using the given - \a painter, \a clip, and \a offset. Which aspects of the display text - are drawn is specified by the given \a flags. - - If the flags contain DrawSelections, then the selection or input mask - backgrounds and foregrounds will be applied before drawing the text. - - If the flags contain DrawCursor a cursor of the current cursorWidth() - will be drawn after drawing the text. - - The display text will only be drawn if the flags contain DrawText -*/ -void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags) -{ - QVector<QTextLayout::FormatRange> selections; - if (flags & DrawSelections) { - QTextLayout::FormatRange o; - if (m_selstart < m_selend) { - o.start = m_selstart; - o.length = m_selend - m_selstart; - o.format.setBackground(m_palette.brush(QPalette::Highlight)); - o.format.setForeground(m_palette.brush(QPalette::HighlightedText)); - } else { - // mask selection - if(!m_blinkPeriod || m_blinkStatus){ - o.start = m_cursor; - o.length = 1; - o.format.setBackground(m_palette.brush(QPalette::Text)); - o.format.setForeground(m_palette.brush(QPalette::Window)); - } - } - selections.append(o); - } - - if (flags & DrawText) - m_textLayout.draw(painter, offset, selections, clip); - - if (flags & DrawCursor){ - int cursor = m_cursor; - if (m_preeditCursor != -1) - cursor += m_preeditCursor; - if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus)) - m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth); - } -} - -/*! - \internal - - Sets the selection to cover the word at the given cursor position. - The word boundaries are defined by the behavior of QTextLayout::SkipWords - cursor mode. -*/ -void QLineControl::selectWordAtPos(int cursor) -{ - int next = cursor + 1; - if(next > end()) - --next; - int c = m_textLayout.previousCursorPosition(next, QTextLayout::SkipWords); - moveCursor(c, false); - // ## text layout should support end of words. - int end = m_textLayout.nextCursorPosition(c, QTextLayout::SkipWords); - while (end > cursor && m_text[end-1].isSpace()) - --end; - moveCursor(end, true); -} - -/*! - \internal - - Completes a change to the line control text. If the change is not valid - will undo the line control state back to the given \a validateFromState. - - If \a edited is true and the change is valid, will emit textEdited() in - addition to textChanged(). Otherwise only emits textChanged() on a valid - change. - - The \a update value is currently unused. -*/ -bool QLineControl::finishChange(int validateFromState, bool update, bool edited) -{ - Q_UNUSED(update) - bool lineDirty = m_selDirty; - if (m_textDirty) { - // do validation - bool wasValidInput = m_validInput; - m_validInput = true; -#ifndef QT_NO_VALIDATOR - if (m_validator) { - m_validInput = false; - QString textCopy = m_text; - int cursorCopy = m_cursor; - m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid); - if (m_validInput) { - if (m_text != textCopy) { - internalSetText(textCopy, cursorCopy); - return true; - } - m_cursor = cursorCopy; - } - } -#endif - if (validateFromState >= 0 && wasValidInput && !m_validInput) { - if (m_transactions.count()) - return false; - internalUndo(validateFromState); - m_history.resize(m_undoState); - if (m_modifiedState > m_undoState) - m_modifiedState = -1; - m_validInput = true; - m_textDirty = false; - } - updateDisplayText(); - lineDirty |= m_textDirty; - if (m_textDirty) { - m_textDirty = false; - QString actualText = text(); - if (edited) - emit textEdited(actualText); - emit textChanged(actualText); - } - } - if (m_selDirty) { - m_selDirty = false; - emit selectionChanged(); - } - emitCursorPositionChanged(); - return true; -} - -/*! - \internal - - An internal function for setting the text of the line control. -*/ -void QLineControl::internalSetText(const QString &txt, int pos, bool edited) -{ - internalDeselect(); - emit resetInputContext(); - QString oldText = m_text; - if (m_maskData) { - m_text = maskString(0, txt, true); - m_text += clearString(m_text.length(), m_maxLength - m_text.length()); - } else { - m_text = txt.isEmpty() ? txt : txt.left(m_maxLength); - } - m_history.clear(); - m_modifiedState = m_undoState = 0; - m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; - m_textDirty = (oldText != m_text); - finishChange(-1, true, edited); -} - - -/*! - \internal - - Adds the given \a command to the undo history - of the line control. Does not apply the command. -*/ -void QLineControl::addCommand(const Command &cmd) -{ - if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) { - m_history.resize(m_undoState + 2); - m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend); - } else { - m_history.resize(m_undoState + 1); - } - m_separator = false; - m_history[m_undoState++] = cmd; -} - -/*! - \internal - - Inserts the given string \a s into the line - control. - - Also adds the appropriate commands into the undo history. - This function does not call finishChange(), and may leave the text - in an invalid state. -*/ -void QLineControl::internalInsert(const QString &s) -{ - if (hasSelectedText()) - addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); - if (m_maskData) { - QString ms = maskString(m_cursor, s); - for (int i = 0; i < (int) ms.length(); ++i) { - addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1)); - addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1)); - } - m_text.replace(m_cursor, ms.length(), ms); - m_cursor += ms.length(); - m_cursor = nextMaskBlank(m_cursor); - m_textDirty = true; - } else { - int remaining = m_maxLength - m_text.length(); - if (remaining != 0) { - m_text.insert(m_cursor, s.left(remaining)); - for (int i = 0; i < (int) s.left(remaining).length(); ++i) - addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1)); - m_textDirty = true; - } - } -} - -/*! - \internal - - deletes a single character from the current text. If \a wasBackspace, - the character prior to the cursor is removed. Otherwise the character - after the cursor is removed. - - Also adds the appropriate commands into the undo history. - This function does not call finishChange(), and may leave the text - in an invalid state. -*/ -void QLineControl::internalDelete(bool wasBackspace) -{ - if (m_cursor < (int) m_text.length()) { - if (hasSelectedText()) - addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); - addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)), - m_cursor, m_text.at(m_cursor), -1, -1)); - if (m_maskData) { - m_text.replace(m_cursor, 1, clearString(m_cursor, 1)); - addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1)); - } else { - m_text.remove(m_cursor, 1); - } - m_textDirty = true; - } -} - -/*! - \internal - - removes the currently selected text from the line control. - - Also adds the appropriate commands into the undo history. - This function does not call finishChange(), and may leave the text - in an invalid state. -*/ -void QLineControl::removeSelectedText() -{ - if (m_selstart < m_selend && m_selend <= (int) m_text.length()) { - separate(); - int i ; - addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); - if (m_selstart <= m_cursor && m_cursor < m_selend) { - // cursor is within the selection. Split up the commands - // to be able to restore the correct cursor position - for (i = m_cursor; i >= m_selstart; --i) - addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1)); - for (i = m_selend - 1; i > m_cursor; --i) - addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1)); - } else { - for (i = m_selend-1; i >= m_selstart; --i) - addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1)); - } - if (m_maskData) { - m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart)); - for (int i = 0; i < m_selend - m_selstart; ++i) - addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1)); - } else { - m_text.remove(m_selstart, m_selend - m_selstart); - } - if (m_cursor > m_selstart) - m_cursor -= qMin(m_cursor, m_selend) - m_selstart; - internalDeselect(); - m_textDirty = true; - } -} - -/*! - \internal - - Parses the input mask specified by \a maskFields to generate - the mask data used to handle input masks. -*/ -void QLineControl::parseInputMask(const QString &maskFields) -{ - int delimiter = maskFields.indexOf(QLatin1Char(';')); - if (maskFields.isEmpty() || delimiter == 0) { - if (m_maskData) { - delete [] m_maskData; - m_maskData = 0; - m_maxLength = 32767; - internalSetText(QString()); - } - return; - } - - if (delimiter == -1) { - m_blank = QLatin1Char(' '); - m_inputMask = maskFields; - } else { - m_inputMask = maskFields.left(delimiter); - m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' '); - } - - // calculate m_maxLength / m_maskData length - m_maxLength = 0; - QChar c = 0; - for (int i=0; i<m_inputMask.length(); i++) { - c = m_inputMask.at(i); - if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) { - m_maxLength++; - continue; - } - if (c != QLatin1Char('\\') && c != QLatin1Char('!') && - c != QLatin1Char('<') && c != QLatin1Char('>') && - c != QLatin1Char('{') && c != QLatin1Char('}') && - c != QLatin1Char('[') && c != QLatin1Char(']')) - m_maxLength++; - } - - delete [] m_maskData; - m_maskData = new MaskInputData[m_maxLength]; - - MaskInputData::Casemode m = MaskInputData::NoCaseMode; - c = 0; - bool s; - bool escape = false; - int index = 0; - for (int i = 0; i < m_inputMask.length(); i++) { - c = m_inputMask.at(i); - if (escape) { - s = true; - m_maskData[index].maskChar = c; - m_maskData[index].separator = s; - m_maskData[index].caseMode = m; - index++; - escape = false; - } else if (c == QLatin1Char('<')) { - m = MaskInputData::Lower; - } else if (c == QLatin1Char('>')) { - m = MaskInputData::Upper; - } else if (c == QLatin1Char('!')) { - m = MaskInputData::NoCaseMode; - } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) { - switch (c.unicode()) { - case 'A': - case 'a': - case 'N': - case 'n': - case 'X': - case 'x': - case '9': - case '0': - case 'D': - case 'd': - case '#': - case 'H': - case 'h': - case 'B': - case 'b': - s = false; - break; - case '\\': - escape = true; - default: - s = true; - break; - } - - if (!escape) { - m_maskData[index].maskChar = c; - m_maskData[index].separator = s; - m_maskData[index].caseMode = m; - index++; - } - } - } - internalSetText(m_text); -} - - -/*! - \internal - - checks if the key is valid compared to the inputMask -*/ -bool QLineControl::isValidInput(QChar key, QChar mask) const -{ - switch (mask.unicode()) { - case 'A': - if (key.isLetter()) - return true; - break; - case 'a': - if (key.isLetter() || key == m_blank) - return true; - break; - case 'N': - if (key.isLetterOrNumber()) - return true; - break; - case 'n': - if (key.isLetterOrNumber() || key == m_blank) - return true; - break; - case 'X': - if (key.isPrint()) - return true; - break; - case 'x': - if (key.isPrint() || key == m_blank) - return true; - break; - case '9': - if (key.isNumber()) - return true; - break; - case '0': - if (key.isNumber() || key == m_blank) - return true; - break; - case 'D': - if (key.isNumber() && key.digitValue() > 0) - return true; - break; - case 'd': - if ((key.isNumber() && key.digitValue() > 0) || key == m_blank) - return true; - break; - case '#': - if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank) - return true; - break; - case 'B': - if (key == QLatin1Char('0') || key == QLatin1Char('1')) - return true; - break; - case 'b': - if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank) - return true; - break; - case 'H': - if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F'))) - return true; - break; - case 'h': - if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank) - return true; - break; - default: - break; - } - return false; -} - -/*! - \internal - - Returns true if the given text \a str is valid for any - validator or input mask set for the line control. - - Otherwise returns false -*/ -bool QLineControl::hasAcceptableInput(const QString &str) const -{ -#ifndef QT_NO_VALIDATOR - QString textCopy = str; - int cursorCopy = m_cursor; - if (m_validator && m_validator->validate(textCopy, cursorCopy) - != QValidator::Acceptable) - return false; -#endif - - if (!m_maskData) - return true; - - if (str.length() != m_maxLength) - return false; - - for (int i=0; i < m_maxLength; ++i) { - if (m_maskData[i].separator) { - if (str.at(i) != m_maskData[i].maskChar) - return false; - } else { - if (!isValidInput(str.at(i), m_maskData[i].maskChar)) - return false; - } - } - return true; -} - -/*! - \internal - - Applies the inputMask on \a str starting from position \a pos in the mask. \a clear - specifies from where characters should be gotten when a separator is met in \a str - true means - that blanks will be used, false that previous input is used. - Calling this when no inputMask is set is undefined. -*/ -QString QLineControl::maskString(uint pos, const QString &str, bool clear) const -{ - if (pos >= (uint)m_maxLength) - return QString::fromLatin1(""); - - QString fill; - fill = clear ? clearString(0, m_maxLength) : m_text; - - int strIndex = 0; - QString s = QString::fromLatin1(""); - int i = pos; - while (i < m_maxLength) { - if (strIndex < str.length()) { - if (m_maskData[i].separator) { - s += m_maskData[i].maskChar; - if (str[(int)strIndex] == m_maskData[i].maskChar) - strIndex++; - ++i; - } else { - if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) { - switch (m_maskData[i].caseMode) { - case MaskInputData::Upper: - s += str[(int)strIndex].toUpper(); - break; - case MaskInputData::Lower: - s += str[(int)strIndex].toLower(); - break; - default: - s += str[(int)strIndex]; - } - ++i; - } else { - // search for separator first - int n = findInMask(i, true, true, str[(int)strIndex]); - if (n != -1) { - if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) { - s += fill.mid(i, n-i+1); - i = n + 1; // update i to find + 1 - } - } else { - // search for valid m_blank if not - n = findInMask(i, true, false, str[(int)strIndex]); - if (n != -1) { - s += fill.mid(i, n-i); - switch (m_maskData[n].caseMode) { - case MaskInputData::Upper: - s += str[(int)strIndex].toUpper(); - break; - case MaskInputData::Lower: - s += str[(int)strIndex].toLower(); - break; - default: - s += str[(int)strIndex]; - } - i = n + 1; // updates i to find + 1 - } - } - } - ++strIndex; - } - } else - break; - } - - return s; -} - - - -/*! - \internal - - Returns a "cleared" string with only separators and blank chars. - Calling this when no inputMask is set is undefined. -*/ -QString QLineControl::clearString(uint pos, uint len) const -{ - if (pos >= (uint)m_maxLength) - return QString(); - - QString s; - int end = qMin((uint)m_maxLength, pos + len); - for (int i = pos; i < end; ++i) - if (m_maskData[i].separator) - s += m_maskData[i].maskChar; - else - s += m_blank; - - return s; -} - -/*! - \internal - - Strips blank parts of the input in a QLineControl when an inputMask is set, - separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1". -*/ -QString QLineControl::stripString(const QString &str) const -{ - if (!m_maskData) - return str; - - QString s; - int end = qMin(m_maxLength, (int)str.length()); - for (int i = 0; i < end; ++i) - if (m_maskData[i].separator) - s += m_maskData[i].maskChar; - else - if (str[i] != m_blank) - s += str[i]; - - return s; -} - -/*! - \internal - searches forward/backward in m_maskData for either a separator or a m_blank -*/ -int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const -{ - if (pos >= m_maxLength || pos < 0) - return -1; - - int end = forward ? m_maxLength : -1; - int step = forward ? 1 : -1; - int i = pos; - - while (i != end) { - if (findSeparator) { - if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar) - return i; - } else { - if (!m_maskData[i].separator) { - if (searchChar.isNull()) - return i; - else if (isValidInput(searchChar, m_maskData[i].maskChar)) - return i; - } - } - i += step; - } - return -1; -} - -void QLineControl::internalUndo(int until) -{ - if (!isUndoAvailable()) - return; - internalDeselect(); - while (m_undoState && m_undoState > until) { - Command& cmd = m_history[--m_undoState]; - switch (cmd.type) { - case Insert: - m_text.remove(cmd.pos, 1); - m_cursor = cmd.pos; - break; - case SetSelection: - m_selstart = cmd.selStart; - m_selend = cmd.selEnd; - m_cursor = cmd.pos; - break; - case Remove: - case RemoveSelection: - m_text.insert(cmd.pos, cmd.uc); - m_cursor = cmd.pos + 1; - break; - case Delete: - case DeleteSelection: - m_text.insert(cmd.pos, cmd.uc); - m_cursor = cmd.pos; - break; - case Separator: - continue; - } - if (until < 0 && m_undoState) { - Command& next = m_history[m_undoState-1]; - if (next.type != cmd.type && next.type < RemoveSelection - && (cmd.type < RemoveSelection || next.type == Separator)) - break; - } - } - m_textDirty = true; - emitCursorPositionChanged(); -} - -void QLineControl::internalRedo() -{ - if (!isRedoAvailable()) - return; - internalDeselect(); - while (m_undoState < (int)m_history.size()) { - Command& cmd = m_history[m_undoState++]; - switch (cmd.type) { - case Insert: - m_text.insert(cmd.pos, cmd.uc); - m_cursor = cmd.pos + 1; - break; - case SetSelection: - m_selstart = cmd.selStart; - m_selend = cmd.selEnd; - m_cursor = cmd.pos; - break; - case Remove: - case Delete: - case RemoveSelection: - case DeleteSelection: - m_text.remove(cmd.pos, 1); - m_selstart = cmd.selStart; - m_selend = cmd.selEnd; - m_cursor = cmd.pos; - break; - case Separator: - m_selstart = cmd.selStart; - m_selend = cmd.selEnd; - m_cursor = cmd.pos; - break; - } - if (m_undoState < (int)m_history.size()) { - Command& next = m_history[m_undoState]; - if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator - && (next.type < RemoveSelection || cmd.type == Separator)) - break; - } - } - m_textDirty = true; - emitCursorPositionChanged(); -} - -/*! - \internal - - If the current cursor position differs from the last emitted cursor - position, emits cursorPositionChanged(). -*/ -void QLineControl::emitCursorPositionChanged() -{ - if (m_cursor != m_lastCursorPos) { - const int oldLast = m_lastCursorPos; - m_lastCursorPos = m_cursor; - cursorPositionChanged(oldLast, m_cursor); - } -} - -#ifndef QT_NO_COMPLETER -// iterating forward(dir=1)/backward(dir=-1) from the -// current row based. dir=0 indicates a new completion prefix was set. -bool QLineControl::advanceToEnabledItem(int dir) -{ - int start = m_completer->currentRow(); - if (start == -1) - return false; - int i = start + dir; - if (dir == 0) dir = 1; - do { - if (!m_completer->setCurrentRow(i)) { - if (!m_completer->wrapAround()) - break; - i = i > 0 ? 0 : m_completer->completionCount() - 1; - } else { - QModelIndex currentIndex = m_completer->currentIndex(); - if (m_completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled) - return true; - i += dir; - } - } while (i != start); - - m_completer->setCurrentRow(start); // restore - return false; -} - -void QLineControl::complete(int key) -{ - if (!m_completer || isReadOnly() || echoMode() != QLineEdit::Normal) - return; - - QString text = this->text(); - if (m_completer->completionMode() == QCompleter::InlineCompletion) { - if (key == Qt::Key_Backspace) - return; - int n = 0; - if (key == Qt::Key_Up || key == Qt::Key_Down) { - if (textAfterSelection().length()) - return; - QString prefix = hasSelectedText() ? textBeforeSelection() - : text; - if (text.compare(m_completer->currentCompletion(), m_completer->caseSensitivity()) != 0 - || prefix.compare(m_completer->completionPrefix(), m_completer->caseSensitivity()) != 0) { - m_completer->setCompletionPrefix(prefix); - } else { - n = (key == Qt::Key_Up) ? -1 : +1; - } - } else { - m_completer->setCompletionPrefix(text); - } - if (!advanceToEnabledItem(n)) - return; - } else { -#ifndef QT_KEYPAD_NAVIGATION - if (text.isEmpty()) { - m_completer->popup()->hide(); - return; - } -#endif - m_completer->setCompletionPrefix(text); - } - - m_completer->complete(); -} -#endif - -void QLineControl::setCursorBlinkPeriod(int msec) -{ - if (msec == m_blinkPeriod) - return; - if (m_blinkTimer) { - killTimer(m_blinkTimer); - } - if (msec) { - m_blinkTimer = startTimer(msec / 2); - m_blinkStatus = 1; - } else { - m_blinkTimer = 0; - if (m_blinkStatus == 1) - emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); - } - m_blinkPeriod = msec; -} - -void QLineControl::resetCursorBlinkTimer() -{ - if (m_blinkPeriod == 0 || m_blinkTimer == 0) - return; - killTimer(m_blinkTimer); - m_blinkTimer = startTimer(m_blinkPeriod / 2); - m_blinkStatus = 1; -} - -void QLineControl::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_blinkTimer) { - m_blinkStatus = !m_blinkStatus; - emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); - } else if (event->timerId() == m_deleteAllTimer) { - killTimer(m_deleteAllTimer); - m_deleteAllTimer = 0; - clear(); - } else if (event->timerId() == m_tripleClickTimer) { - killTimer(m_tripleClickTimer); - m_tripleClickTimer = 0; - } -} - -bool QLineControl::processEvent(QEvent* ev) -{ -#ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { - if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) { - QKeyEvent *ke = (QKeyEvent *)ev; - if (ke->key() == Qt::Key_Back) { - if (ke->isAutoRepeat()) { - // Swallow it. We don't want back keys running amok. - ke->accept(); - return true; - } - if ((ev->type() == QEvent::KeyRelease) - && !isReadOnly() - && m_deleteAllTimer) { - killTimer(m_deleteAllTimer); - m_deleteAllTimer = 0; - backspace(); - ke->accept(); - return true; - } - } - } - } -#endif - switch(ev->type()){ -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseDoubleClick: - case QEvent::GraphicsSceneMouseMove: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMousePress:{ - QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev); - QMouseEvent* mouse = new QMouseEvent(ev->type(), - gvEv->pos().toPoint(), gvEv->button(), gvEv->buttons(), gvEv->modifiers()); - processMouseEvent(mouse); break; - } -#endif - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - processMouseEvent(static_cast<QMouseEvent*>(ev)); break; - case QEvent::KeyPress: - case QEvent::KeyRelease: - processKeyEvent(static_cast<QKeyEvent*>(ev)); break; - case QEvent::InputMethod: - processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break; -#ifndef QT_NO_SHORTCUT - case QEvent::ShortcutOverride:{ - if (isReadOnly()) - return false; - QKeyEvent* ke = static_cast<QKeyEvent*>(ev); - if (ke == QKeySequence::Copy - || ke == QKeySequence::Paste - || ke == QKeySequence::Cut - || ke == QKeySequence::Redo - || ke == QKeySequence::Undo - || ke == QKeySequence::MoveToNextWord - || ke == QKeySequence::MoveToPreviousWord - || ke == QKeySequence::MoveToStartOfDocument - || ke == QKeySequence::MoveToEndOfDocument - || ke == QKeySequence::SelectNextWord - || ke == QKeySequence::SelectPreviousWord - || ke == QKeySequence::SelectStartOfLine - || ke == QKeySequence::SelectEndOfLine - || ke == QKeySequence::SelectStartOfBlock - || ke == QKeySequence::SelectEndOfBlock - || ke == QKeySequence::SelectStartOfDocument - || ke == QKeySequence::SelectAll - || ke == QKeySequence::SelectEndOfDocument) { - ke->accept(); - } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier - || ke->modifiers() == Qt::KeypadModifier) { - if (ke->key() < Qt::Key_Escape) { - ke->accept(); - } else { - switch (ke->key()) { - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - ke->accept(); - default: - break; - } - } - } - } -#endif - default: - return false; - } - return true; -} - -void QLineControl::processMouseEvent(QMouseEvent* ev) -{ - - switch (ev->type()) { - case QEvent::GraphicsSceneMousePress: - case QEvent::MouseButtonPress:{ - if (m_tripleClickTimer - && (ev->pos() - m_tripleClick).manhattanLength() - < QApplication::startDragDistance()) { - selectAll(); - return; - } - if (ev->button() == Qt::RightButton) - return; - - bool mark = ev->modifiers() & Qt::ShiftModifier; - int cursor = xToPos(ev->pos().x()); - moveCursor(cursor, mark); - break; - } - case QEvent::GraphicsSceneMouseDoubleClick: - case QEvent::MouseButtonDblClick: - if (ev->button() == Qt::LeftButton) { - selectWordAtPos(xToPos(ev->pos().x())); - if (m_tripleClickTimer) - killTimer(m_tripleClickTimer); - m_tripleClickTimer = startTimer(QApplication::doubleClickInterval()); - m_tripleClick = ev->pos(); - } - break; - case QEvent::GraphicsSceneMouseRelease: - case QEvent::MouseButtonRelease: -#ifndef QT_NO_CLIPBOARD - if (QApplication::clipboard()->supportsSelection()) { - if (ev->button() == Qt::LeftButton) { - copy(QClipboard::Selection); - } else if (!isReadOnly() && ev->button() == Qt::MidButton) { - deselect(); - insert(QApplication::clipboard()->text(QClipboard::Selection)); - } - } -#endif - break; - case QEvent::GraphicsSceneMouseMove: - case QEvent::MouseMove: - if (ev->buttons() & Qt::LeftButton) { - moveCursor(xToPos(ev->pos().x()), true); - } - break; - default: - break; - } -} - -void QLineControl::processKeyEvent(QKeyEvent* event) -{ - bool inlineCompletionAccepted = false; - -#ifndef QT_NO_COMPLETER - if (m_completer) { - QCompleter::CompletionMode completionMode = m_completer->completionMode(); - if ((completionMode == QCompleter::PopupCompletion - || completionMode == QCompleter::UnfilteredPopupCompletion) - && m_completer->popup() - && m_completer->popup()->isVisible()) { - // The following keys are forwarded by the completer to the widget - // Ignoring the events lets the completer provide suitable default behavior - switch (event->key()) { - case Qt::Key_Escape: - event->ignore(); - return; - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_F4: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) - break; -#endif - m_completer->popup()->hide(); // just hide. will end up propagating to parent - default: - break; // normal key processing - } - } else if (completionMode == QCompleter::InlineCompletion) { - switch (event->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_F4: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) - break; -#endif - if (!m_completer->currentCompletion().isEmpty() && hasSelectedText() - && textAfterSelection().isEmpty()) { - setText(m_completer->currentCompletion()); - inlineCompletionAccepted = true; - } - default: - break; // normal key processing - } - } - } -#endif // QT_NO_COMPLETER - - if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { - if (hasAcceptableInput() || fixup()) { - emit accepted(); - emit editingFinished(); - } - if (inlineCompletionAccepted) - event->accept(); - else - event->ignore(); - return; - } - - if (echoMode() == QLineEdit::PasswordEchoOnEdit - && !passwordEchoEditing() - && !isReadOnly() - && !event->text().isEmpty() -#ifdef QT_KEYPAD_NAVIGATION - && event->key() != Qt::Key_Select - && event->key() != Qt::Key_Up - && event->key() != Qt::Key_Down - && event->key() != Qt::Key_Back -#endif - && !(event->modifiers() & Qt::ControlModifier)) { - // Clear the edit and reset to normal echo mode while editing; the - // echo mode switches back when the edit loses focus - // ### resets current content. dubious code; you can - // navigate with keys up, down, back, and select(?), but if you press - // "left" or "right" it clears? - updatePasswordEchoEditing(true); - clear(); - } - - bool unknown = false; - bool visual = cursorMoveStyle() == QTextCursor::Visual; - - if (false) { - } -#ifndef QT_NO_SHORTCUT - else if (event == QKeySequence::Undo) { - if (!isReadOnly()) - undo(); - } - else if (event == QKeySequence::Redo) { - if (!isReadOnly()) - redo(); - } - else if (event == QKeySequence::SelectAll) { - selectAll(); - } -#ifndef QT_NO_CLIPBOARD - else if (event == QKeySequence::Copy) { - copy(); - } - else if (event == QKeySequence::Paste) { - if (!isReadOnly()) { - QClipboard::Mode mode = QClipboard::Clipboard; -#ifdef Q_WS_X11 - if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert) - mode = QClipboard::Selection; -#endif - paste(mode); - } - } - else if (event == QKeySequence::Cut) { - if (!isReadOnly()) { - copy(); - del(); - } - } - else if (event == QKeySequence::DeleteEndOfLine) { - if (!isReadOnly()) { - setSelection(cursor(), end()); - copy(); - del(); - } - } -#endif //QT_NO_CLIPBOARD - else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) { - home(0); - } - else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) { - end(0); - } - else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) { - home(1); - } - else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) { - end(1); - } - else if (event == QKeySequence::MoveToNextChar) { -#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) - if (hasSelectedText()) { -#else - if (hasSelectedText() && m_completer - && m_completer->completionMode() == QCompleter::InlineCompletion) { -#endif - moveCursor(selectionEnd(), false); - } else { - cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); - } - } - else if (event == QKeySequence::SelectNextChar) { - cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); - } - else if (event == QKeySequence::MoveToPreviousChar) { -#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) - if (hasSelectedText()) { -#else - if (hasSelectedText() && m_completer - && m_completer->completionMode() == QCompleter::InlineCompletion) { -#endif - moveCursor(selectionStart(), false); - } else { - cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); - } - } - else if (event == QKeySequence::SelectPreviousChar) { - cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); - } - else if (event == QKeySequence::MoveToNextWord) { - if (echoMode() == QLineEdit::Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0); - else - layoutDirection() == Qt::LeftToRight ? end(0) : home(0); - } - else if (event == QKeySequence::MoveToPreviousWord) { - if (echoMode() == QLineEdit::Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0); - else if (!isReadOnly()) { - layoutDirection() == Qt::LeftToRight ? home(0) : end(0); - } - } - else if (event == QKeySequence::SelectNextWord) { - if (echoMode() == QLineEdit::Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1); - else - layoutDirection() == Qt::LeftToRight ? end(1) : home(1); - } - else if (event == QKeySequence::SelectPreviousWord) { - if (echoMode() == QLineEdit::Normal) - layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1); - else - layoutDirection() == Qt::LeftToRight ? home(1) : end(1); - } - else if (event == QKeySequence::Delete) { - if (!isReadOnly()) - del(); - } - else if (event == QKeySequence::DeleteEndOfWord) { - if (!isReadOnly()) { - cursorWordForward(true); - del(); - } - } - else if (event == QKeySequence::DeleteStartOfWord) { - if (!isReadOnly()) { - cursorWordBackward(true); - del(); - } - } -#endif // QT_NO_SHORTCUT - else { - bool handled = false; -#ifdef Q_WS_MAC - if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { - Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier); - if (myModifiers & Qt::ShiftModifier) { - if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier) - || myModifiers == (Qt::AltModifier|Qt::ShiftModifier) - || myModifiers == Qt::ShiftModifier) { - - event->key() == Qt::Key_Up ? home(1) : end(1); - } - } else { - if ((myModifiers == Qt::ControlModifier - || myModifiers == Qt::AltModifier - || myModifiers == Qt::NoModifier)) { - event->key() == Qt::Key_Up ? home(0) : end(0); - } - } - handled = true; - } -#endif - if (event->modifiers() & Qt::ControlModifier) { - switch (event->key()) { - case Qt::Key_Backspace: - if (!isReadOnly()) { - cursorWordBackward(true); - del(); - } - break; -#ifndef QT_NO_COMPLETER - case Qt::Key_Up: - case Qt::Key_Down: - complete(event->key()); - break; -#endif -#if defined(Q_WS_X11) - case Qt::Key_E: - end(0); - break; - - case Qt::Key_U: - if (!isReadOnly()) { - setSelection(0, text().size()); -#ifndef QT_NO_CLIPBOARD - copy(); -#endif - del(); - } - break; -#endif - default: - if (!handled) - unknown = true; - } - } else { // ### check for *no* modifier - switch (event->key()) { - case Qt::Key_Backspace: - if (!isReadOnly()) { - backspace(); -#ifndef QT_NO_COMPLETER - complete(Qt::Key_Backspace); -#endif - } - break; -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat() - && !isReadOnly()) { - if (text().length() == 0) { - setText(m_cancelText); - - if (passwordEchoEditing()) - updatePasswordEchoEditing(false); - - emit editFocusChange(false); - } else if (!m_deleteAllTimer) { - m_deleteAllTimer = startTimer(750); - } - } else { - unknown = true; - } - break; -#endif - default: - if (!handled) - unknown = true; - } - } - } - - if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) { - setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft); - unknown = false; - } - - if (unknown && !isReadOnly()) { - QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint()) { - insert(t); -#ifndef QT_NO_COMPLETER - complete(event->key()); -#endif - event->accept(); - return; - } - } - - if (unknown) - event->ignore(); - else - event->accept(); -} - - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/to_be_moved/qlinecontrol_p.h b/src/gui/to_be_moved/qlinecontrol_p.h deleted file mode 100644 index 0042f17261..0000000000 --- a/src/gui/to_be_moved/qlinecontrol_p.h +++ /dev/null @@ -1,456 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QLINECONTROL_P_H -#define QLINECONTROL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtCore/qglobal.h" - -#ifndef QT_NO_LINEEDIT -#include "private/qwidget_p.h" -#include "QtGui/qlineedit.h" -#include "QtGui/qtextlayout.h" -#include "QtGui/qstyleoption.h" -#include "QtCore/qpointer.h" -#include "QtGui/qlineedit.h" -#include "QtGui/qclipboard.h" -#include "QtCore/qpoint.h" -#include "QtGui/qcompleter.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class Q_GUI_EXPORT QLineControl : public QObject -{ - Q_OBJECT - -public: - QLineControl(const QString &txt = QString()) - : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto), - m_hideCursor(false), m_separator(0), m_readOnly(0), - m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0), - m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0), - m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1), - m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0), - m_selstart(0), m_selend(0), m_passwordEchoEditing(false) - { - init(txt); - } - - ~QLineControl() - { - delete [] m_maskData; - } - - int nextMaskBlank(int pos) - { - int c = findInMask(pos, true, false); - m_separator |= (c != pos); - return (c != -1 ? c : m_maxLength); - } - - int prevMaskBlank(int pos) - { - int c = findInMask(pos, false, false); - m_separator |= (c != pos); - return (c != -1 ? c : 0); - } - - bool isUndoAvailable() const { return !m_readOnly && m_undoState; } - bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); } - void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; } - - bool isModified() const { return m_modifiedState != m_undoState; } - void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; } - - bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); } - bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; } - - int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; } - int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; } - int ascent() const { return m_ascent; } - qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); } - - void setSelection(int start, int length); - - inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); } - QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); } - QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); } - - int selectionStart() const { return hasSelectedText() ? m_selstart : -1; } - int selectionEnd() const { return hasSelectedText() ? m_selend : -1; } - bool inSelection(int x) const - { - if (m_selstart >= m_selend) - return false; - int pos = xToPos(x, QTextLine::CursorOnCharacter); - return pos >= m_selstart && pos < m_selend; - } - - void removeSelection() - { - int priorState = m_undoState; - removeSelectedText(); - finishChange(priorState); - } - - int start() const { return 0; } - int end() const { return m_text.length(); } - -#ifndef QT_NO_CLIPBOARD - void copy(QClipboard::Mode mode = QClipboard::Clipboard) const; - void paste(QClipboard::Mode mode = QClipboard::Clipboard); -#endif - - int cursor() const{ return m_cursor; } - int preeditCursor() const { return m_preeditCursor; } - - int cursorWidth() const { return m_cursorWidth; } - void setCursorWidth(int value) { m_cursorWidth = value; } - - QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } - void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); } - - void moveCursor(int pos, bool mark = false); - void cursorForward(bool mark, int steps) - { - int c = m_cursor; - if (steps > 0) { - while (steps--) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c) - : m_textLayout.nextCursorPosition(c); - } else if (steps < 0) { - while (steps++) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c) - : m_textLayout.previousCursorPosition(c); - } - moveCursor(c, mark); - } - - void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); } - void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); } - - void home(bool mark) { moveCursor(0, mark); } - void end(bool mark) { moveCursor(text().length(), mark); } - - int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; - QRect cursorRect() const; - - qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); } - qreal cursorToX() const - { - int cursor = m_cursor; - if (m_preeditCursor != -1) - cursor += m_preeditCursor; - return cursorToX(cursor); - } - - bool isReadOnly() const { return m_readOnly; } - void setReadOnly(bool enable) { m_readOnly = enable; } - - QString text() const - { - QString res = m_maskData ? stripString(m_text) : m_text; - return (res.isNull() ? QString::fromLatin1("") : res); - } - void setText(const QString &txt) { internalSetText(txt, -1, false); } - QString displayText() const { return m_textLayout.text(); } - - void backspace(); - void del(); - void deselect() { internalDeselect(); finishChange(); } - void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); } - - void insert(const QString &); - void clear(); - void undo() { internalUndo(); finishChange(-1, true); } - void redo() { internalRedo(); finishChange(); } - void selectWordAtPos(int); - - uint echoMode() const { return m_echoMode; } - void setEchoMode(uint mode) - { - m_echoMode = mode; - m_passwordEchoEditing = false; - updateDisplayText(); - } - - int maxLength() const { return m_maxLength; } - void setMaxLength(int maxLength) - { - if (m_maskData) - return; - m_maxLength = maxLength; - setText(m_text); - } - -#ifndef QT_NO_VALIDATOR - const QValidator *validator() const { return m_validator; } - void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); } -#endif - -#ifndef QT_NO_COMPLETER - QCompleter *completer() const { return m_completer; } - /* Note that you must set the widget for the completer separately */ - void setCompleter(const QCompleter *c) { m_completer = const_cast<QCompleter*>(c); } - void complete(int key); -#endif - - int cursorPosition() const { return m_cursor; } - void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); } - - bool hasAcceptableInput() const { return hasAcceptableInput(m_text); } - bool fixup(); - - QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); } - void setInputMask(const QString &mask) - { - parseInputMask(mask); - if (m_maskData) - moveCursor(nextMaskBlank(0)); - } - - // input methods -#ifndef QT_NO_IM - bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); } - void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); } -#endif - - QString preeditAreaText() const { return m_textLayout.preeditAreaText(); } - - void updatePasswordEchoEditing(bool editing); - bool passwordEchoEditing() const { return m_passwordEchoEditing; } - - QChar passwordCharacter() const { return m_passwordCharacter; } - void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } - - Qt::LayoutDirection layoutDirection() const { - if (m_layoutDirection == Qt::LayoutDirectionAuto) { - if (m_text.isEmpty()) - return QApplication::keyboardInputDirection(); - return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; - } - return m_layoutDirection; - } - void setLayoutDirection(Qt::LayoutDirection direction) - { - if (direction != m_layoutDirection) { - m_layoutDirection = direction; - updateDisplayText(); - } - } - - void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); } - - void processInputMethodEvent(QInputMethodEvent *event); - void processMouseEvent(QMouseEvent* ev); - void processKeyEvent(QKeyEvent* ev); - - int cursorBlinkPeriod() const { return m_blinkPeriod; } - void setCursorBlinkPeriod(int msec); - void resetCursorBlinkTimer(); - - QString cancelText() const { return m_cancelText; } - void setCancelText(const QString &text) { m_cancelText = text; } - - const QPalette &palette() const { return m_palette; } - void setPalette(const QPalette &p) { m_palette = p; } - - enum DrawFlags { - DrawText = 0x01, - DrawSelections = 0x02, - DrawCursor = 0x04, - DrawAll = DrawText | DrawSelections | DrawCursor - }; - void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll); - - bool processEvent(QEvent *ev); - -private: - void init(const QString &txt); - void removeSelectedText(); - void internalSetText(const QString &txt, int pos = -1, bool edited = true); - void updateDisplayText(bool forceUpdate = false); - - void internalInsert(const QString &s); - void internalDelete(bool wasBackspace = false); - void internalRemove(int pos); - - inline void internalDeselect() - { - m_selDirty |= (m_selend > m_selstart); - m_selstart = m_selend = 0; - } - - void internalUndo(int until = -1); - void internalRedo(); - - QString m_text; - QPalette m_palette; - int m_cursor; - int m_preeditCursor; - int m_cursorWidth; - Qt::LayoutDirection m_layoutDirection; - uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas - uint m_separator : 1; - uint m_readOnly : 1; - uint m_dragEnabled : 1; - uint m_echoMode : 2; - uint m_textDirty : 1; - uint m_selDirty : 1; - uint m_validInput : 1; - uint m_blinkStatus : 1; - int m_blinkPeriod; // 0 for non-blinking cursor - int m_blinkTimer; - int m_deleteAllTimer; - int m_ascent; - int m_maxLength; - int m_lastCursorPos; - QList<int> m_transactions; - QPoint m_tripleClick; - int m_tripleClickTimer; - QString m_cancelText; - - void emitCursorPositionChanged(); - - bool finishChange(int validateFromState = -1, bool update = false, bool edited = true); - -#ifndef QT_NO_VALIDATOR - QPointer<QValidator> m_validator; -#endif - QPointer<QCompleter> m_completer; -#ifndef QT_NO_COMPLETER - bool advanceToEnabledItem(int dir); -#endif - - struct MaskInputData { - enum Casemode { NoCaseMode, Upper, Lower }; - QChar maskChar; // either the separator char or the inputmask - bool separator; - Casemode caseMode; - }; - QString m_inputMask; - QChar m_blank; - MaskInputData *m_maskData; - - // undo/redo handling - enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection }; - struct Command { - inline Command() {} - inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {} - uint type : 4; - QChar uc; - int pos, selStart, selEnd; - }; - int m_modifiedState; - int m_undoState; - QVector<Command> m_history; - void addCommand(const Command& cmd); - - inline void separate() { m_separator = true; } - - // selection - int m_selstart; - int m_selend; - - // masking - void parseInputMask(const QString &maskFields); - bool isValidInput(QChar key, QChar mask) const; - bool hasAcceptableInput(const QString &text) const; - QString maskString(uint pos, const QString &str, bool clear = false) const; - QString clearString(uint pos, uint len) const; - QString stripString(const QString &str) const; - int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const; - - // complex text layout - QTextLayout m_textLayout; - - bool m_passwordEchoEditing; - QChar m_passwordCharacter; - -Q_SIGNALS: - void cursorPositionChanged(int, int); - void selectionChanged(); - - void displayTextChanged(const QString &); - void textChanged(const QString &); - void textEdited(const QString &); - - void resetInputContext(); - void updateMicroFocus(); - - void accepted(); - void editingFinished(); - void updateNeeded(const QRect &); - -#ifdef QT_KEYPAD_NAVIGATION - void editFocusChange(bool); -#endif -protected: - virtual void timerEvent(QTimerEvent *event); - -private Q_SLOTS: - void _q_clipboardChanged(); - void _q_deleteSelected(); - -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QT_NO_LINEEDIT - -#endif // QLINECONTROL_P_H diff --git a/src/gui/to_be_moved/qshortcut.cpp b/src/gui/to_be_moved/qshortcut.cpp deleted file mode 100644 index 978ef0c240..0000000000 --- a/src/gui/to_be_moved/qshortcut.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qshortcut.h" -#include "private/qwidget_p.h" - -#ifndef QT_NO_SHORTCUT -#include <qevent.h> -#include <qwhatsthis.h> -#include <qmenu.h> -#include <qapplication.h> -#include <private/qapplication_p.h> -#include <private/qshortcutmap_p.h> - -QT_BEGIN_NAMESPACE - -#define QAPP_CHECK(functionName) \ - if (!qApp) { \ - qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \ - return; \ - } - -/*! - \class QShortcut - \brief The QShortcut class is used to create keyboard shortcuts. - - \ingroup events - - - The QShortcut class provides a way of connecting keyboard - shortcuts to Qt's \l{signals and slots} mechanism, so that - objects can be informed when a shortcut is executed. The shortcut - can be set up to contain all the key presses necessary to - describe a keyboard shortcut, including the states of modifier - keys such as \gui Shift, \gui Ctrl, and \gui Alt. - - \target mnemonic - - On certain widgets, using '&' in front of a character will - automatically create a mnemonic (a shortcut) for that character, - e.g. "E&xit" will create the shortcut \gui Alt+X (use '&&' to - display an actual ampersand). The widget might consume and perform - an action on a given shortcut. On X11 the ampersand will not be - shown and the character will be underlined. On Windows, shortcuts - are normally not displayed until the user presses the \gui Alt - key, but this is a setting the user can change. On Mac, shortcuts - are disabled by default. Call qt_set_sequence_auto_mnemonic() to - enable them. However, because mnemonic shortcuts do not fit in - with Aqua's guidelines, Qt will not show the shortcut character - underlined. - - For applications that use menus, it may be more convenient to - use the convenience functions provided in the QMenu class to - assign keyboard shortcuts to menu items as they are created. - Alternatively, shortcuts may be associated with other types of - actions in the QAction class. - - The simplest way to create a shortcut for a particular widget is - to construct the shortcut with a key sequence. For example: - - \snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 0 - - When the user types the \l{QKeySequence}{key sequence} - for a given shortcut, the shortcut's activated() signal is - emitted. (In the case of ambiguity, the activatedAmbiguously() - signal is emitted.) A shortcut is "listened for" by Qt's event - loop when the shortcut's parent widget is receiving events. - - A shortcut's key sequence can be set with setKey() and retrieved - with key(). A shortcut can be enabled or disabled with - setEnabled(), and can have "What's This?" help text set with - setWhatsThis(). - - \sa QShortcutEvent, QKeySequence, QAction -*/ - -/*! - \fn QWidget *QShortcut::parentWidget() const - - Returns the shortcut's parent widget. -*/ - -/*! - \fn void QShortcut::activated() - - This signal is emitted when the user types the shortcut's key - sequence. - - \sa activatedAmbiguously() -*/ - -/*! - \fn void QShortcut::activatedAmbiguously() - - When a key sequence is being typed at the keyboard, it is said to - be ambiguous as long as it matches the start of more than one - shortcut. - - When a shortcut's key sequence is completed, - activatedAmbiguously() is emitted if the key sequence is still - ambiguous (i.e., it is the start of one or more other shortcuts). - The activated() signal is not emitted in this case. - - \sa activated() -*/ - -/* - \internal - Private data accessed through d-pointer. -*/ -class QShortcutPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QShortcut) -public: - QShortcutPrivate() : sc_context(Qt::WindowShortcut), sc_enabled(true), sc_autorepeat(true), sc_id(0) {} - QKeySequence sc_sequence; - Qt::ShortcutContext sc_context; - bool sc_enabled; - bool sc_autorepeat; - int sc_id; - QString sc_whatsthis; - void redoGrab(QShortcutMap &map); -}; - -void QShortcutPrivate::redoGrab(QShortcutMap &map) -{ - Q_Q(QShortcut); - if (!parent) { - qWarning("QShortcut: No widget parent defined"); - return; - } - - if (sc_id) - map.removeShortcut(sc_id, q); - if (sc_sequence.isEmpty()) - return; - sc_id = map.addShortcut(q, sc_sequence, sc_context); - if (!sc_enabled) - map.setShortcutEnabled(false, sc_id, q); - if (!sc_autorepeat) - map.setShortcutAutoRepeat(false, sc_id, q); -} - -/*! - Constructs a QShortcut object for the \a parent widget. Since no - shortcut key sequence is specified, the shortcut will not emit any - signals. - - \sa setKey() -*/ -QShortcut::QShortcut(QWidget *parent) - : QObject(*new QShortcutPrivate, parent) -{ - Q_ASSERT(parent != 0); -} - -/*! - Constructs a QShortcut object for the \a parent widget. The shortcut - operates on its parent, listening for \l{QShortcutEvent}s that - match the \a key sequence. Depending on the ambiguity of the - event, the shortcut will call the \a member function, or the \a - ambiguousMember function, if the key press was in the shortcut's - \a context. -*/ -QShortcut::QShortcut(const QKeySequence &key, QWidget *parent, - const char *member, const char *ambiguousMember, - Qt::ShortcutContext context) - : QObject(*new QShortcutPrivate, parent) -{ - QAPP_CHECK("QShortcut"); - - Q_D(QShortcut); - Q_ASSERT(parent != 0); - d->sc_context = context; - d->sc_sequence = key; - d->redoGrab(qApp->d_func()->shortcutMap); - if (member) - connect(this, SIGNAL(activated()), parent, member); - if (ambiguousMember) - connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember); -} - -/*! - Destroys the shortcut. -*/ -QShortcut::~QShortcut() -{ - Q_D(QShortcut); - if (qApp) - qApp->d_func()->shortcutMap.removeShortcut(d->sc_id, this); -} - -/*! - \property QShortcut::key - \brief the shortcut's key sequence - - This is a key sequence with an optional combination of Shift, Ctrl, - and Alt. The key sequence may be supplied in a number of ways: - - \snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 1 - - By default, this property contains an empty key sequence. -*/ -void QShortcut::setKey(const QKeySequence &key) -{ - Q_D(QShortcut); - if (d->sc_sequence == key) - return; - QAPP_CHECK("setKey"); - d->sc_sequence = key; - d->redoGrab(qApp->d_func()->shortcutMap); -} - -QKeySequence QShortcut::key() const -{ - Q_D(const QShortcut); - return d->sc_sequence; -} - -/*! - \property QShortcut::enabled - \brief whether the shortcut is enabled - - An enabled shortcut emits the activated() or activatedAmbiguously() - signal when a QShortcutEvent occurs that matches the shortcut's - key() sequence. - - If the application is in \c WhatsThis mode the shortcut will not emit - the signals, but will show the "What's This?" text instead. - - By default, this property is true. - - \sa whatsThis -*/ -void QShortcut::setEnabled(bool enable) -{ - Q_D(QShortcut); - if (d->sc_enabled == enable) - return; - QAPP_CHECK("setEnabled"); - d->sc_enabled = enable; - qApp->d_func()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this); -} - -bool QShortcut::isEnabled() const -{ - Q_D(const QShortcut); - return d->sc_enabled; -} - -/*! - \property QShortcut::context - \brief the context in which the shortcut is valid - - A shortcut's context decides in which circumstances a shortcut is - allowed to be triggered. The normal context is Qt::WindowShortcut, - which allows the shortcut to trigger if the parent (the widget - containing the shortcut) is a subwidget of the active top-level - window. - - By default, this property is set to Qt::WindowShortcut. -*/ -void QShortcut::setContext(Qt::ShortcutContext context) -{ - Q_D(QShortcut); - if(d->sc_context == context) - return; - QAPP_CHECK("setContext"); - d->sc_context = context; - d->redoGrab(qApp->d_func()->shortcutMap); -} - -Qt::ShortcutContext QShortcut::context() -{ - Q_D(QShortcut); - return d->sc_context; -} - -/*! - \property QShortcut::whatsThis - \brief the shortcut's "What's This?" help text - - The text will be shown when the application is in "What's - This?" mode and the user types the shortcut key() sequence. - - To set "What's This?" help on a menu item (with or without a - shortcut key), set the help on the item's action. - - By default, this property contains an empty string. - - \sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis() -*/ -void QShortcut::setWhatsThis(const QString &text) -{ - Q_D(QShortcut); - d->sc_whatsthis = text; -} - -QString QShortcut::whatsThis() const -{ - Q_D(const QShortcut); - return d->sc_whatsthis; -} - -/*! - \property QShortcut::autoRepeat - \brief whether the shortcut can auto repeat - \since 4.2 - - If true, the shortcut will auto repeat when the keyboard shortcut - combination is held down, provided that keyboard auto repeat is - enabled on the system. - The default value is true. -*/ -void QShortcut::setAutoRepeat(bool on) -{ - Q_D(QShortcut); - if (d->sc_autorepeat == on) - return; - QAPP_CHECK("setAutoRepeat"); - d->sc_autorepeat = on; - qApp->d_func()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this); -} - -bool QShortcut::autoRepeat() const -{ - Q_D(const QShortcut); - return d->sc_autorepeat; -} - -/*! - Returns the shortcut's ID. - - \sa QShortcutEvent::shortcutId() -*/ -int QShortcut::id() const -{ - Q_D(const QShortcut); - return d->sc_id; -} - -/*! - \internal -*/ -bool QShortcut::event(QEvent *e) -{ - Q_D(QShortcut); - bool handled = false; - if (d->sc_enabled && e->type() == QEvent::Shortcut) { - QShortcutEvent *se = static_cast<QShortcutEvent *>(e); - if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){ -#ifndef QT_NO_WHATSTHIS - if (QWhatsThis::inWhatsThisMode()) { - QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis); - handled = true; - } else -#endif - if (se->isAmbiguous()) - emit activatedAmbiguously(); - else - emit activated(); - handled = true; - } - } - return handled; -} -#endif // QT_NO_SHORTCUT - -QT_END_NAMESPACE diff --git a/src/gui/to_be_moved/qshortcut.h b/src/gui/to_be_moved/qshortcut.h deleted file mode 100644 index f432d9ad97..0000000000 --- a/src/gui/to_be_moved/qshortcut.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSHORTCUT_H -#define QSHORTCUT_H - -#include <QtGui/qwidget.h> -#include <QtGui/qkeysequence.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_SHORTCUT - -class QShortcutPrivate; -class Q_GUI_EXPORT QShortcut : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QShortcut) - Q_PROPERTY(QKeySequence key READ key WRITE setKey) - Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) - Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat) - Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) -public: - explicit QShortcut(QWidget *parent); - QShortcut(const QKeySequence& key, QWidget *parent, - const char *member = 0, const char *ambiguousMember = 0, - Qt::ShortcutContext context = Qt::WindowShortcut); - ~QShortcut(); - - void setKey(const QKeySequence& key); - QKeySequence key() const; - - void setEnabled(bool enable); - bool isEnabled() const; - - void setContext(Qt::ShortcutContext context); - Qt::ShortcutContext context(); - - void setWhatsThis(const QString &text); - QString whatsThis() const; - - void setAutoRepeat(bool on); - bool autoRepeat() const; - - int id() const; - - inline QWidget *parentWidget() const - { return static_cast<QWidget *>(QObject::parent()); } - -Q_SIGNALS: - void activated(); - void activatedAmbiguously(); - -protected: - bool event(QEvent *e); -}; - -#endif // QT_NO_SHORTCUT - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSHORTCUT_H diff --git a/src/gui/to_be_moved/qshortcutmap.cpp b/src/gui/to_be_moved/qshortcutmap.cpp deleted file mode 100644 index d6baa1331e..0000000000 --- a/src/gui/to_be_moved/qshortcutmap.cpp +++ /dev/null @@ -1,897 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qshortcutmap_p.h" -#include "private/qobject_p.h" -#include "qkeysequence.h" -#include "qgraphicsscene.h" -#include "qgraphicsview.h" -#include "qdebug.h" -#include "qevent.h" -#include "qwidget.h" -#include "qapplication.h" -#include "qvector.h" -#include "qmenu.h" -#include "qmenubar.h" -#include "qshortcut.h" -#include "private/qapplication_p.h" -#include <private/qaction_p.h> -#include <private/qkeymapper_p.h> -#include <private/qwidget_p.h> - -#ifndef QT_NO_SHORTCUT - -QT_BEGIN_NAMESPACE - -// To enable verbose output uncomment below -//#define DEBUG_QSHORTCUTMAP - -/* \internal - Entry data for QShortcutMap - Contains: - Keysequence for entry - Pointer to parent owning the sequence -*/ -struct QShortcutEntry -{ - QShortcutEntry() - : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0) - {} - - QShortcutEntry(const QKeySequence &k) - : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0) - {} - - QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i) - : keyseq(k), context(c), enabled(true), autorepeat(1), id(i), owner(o) - {} - - QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a) - : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o) - {} - - bool operator<(const QShortcutEntry &f) const - { return keyseq < f.keyseq; } - - QKeySequence keyseq; - Qt::ShortcutContext context; - bool enabled : 1; - bool autorepeat : 1; - signed int id; - QObject *owner; -}; - -#if 0 //ndef QT_NO_DEBUG_STREAM -/*! \internal - QDebug operator<< for easy debug output of the shortcut entries. -*/ -static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) { - if (!se) - return dbg << "QShortcutEntry(0x0)"; - dbg.nospace() - << "QShortcutEntry(" << se->keyseq - << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat - << "), owner(" << se->owner << ')'; - return dbg.space(); -} -#endif // QT_NO_DEBUGSTREAM - -/* \internal - Private data for QShortcutMap -*/ -class QShortcutMapPrivate -{ - Q_DECLARE_PUBLIC(QShortcutMap) - -public: - QShortcutMapPrivate(QShortcutMap* parent) - : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch) - { - identicals.reserve(10); - currentSequences.reserve(10); - } - QShortcutMap *q_ptr; // Private's parent - - QList<QShortcutEntry> sequences; // All sequences! - - int currentId; // Global shortcut ID number - int ambigCount; // Index of last enabled ambiguous dispatch - QKeySequence::SequenceMatch currentState; - QVector<QKeySequence> currentSequences; // Sequence for the current state - QVector<QKeySequence> newEntries; - QKeySequence prevSequence; // Sequence for the previous identical match - QVector<const QShortcutEntry*> identicals; // Last identical matches -}; - - -/*! \internal - QShortcutMap constructor. -*/ -QShortcutMap::QShortcutMap() - : d_ptr(new QShortcutMapPrivate(this)) -{ - resetState(); -} - -/*! \internal - QShortcutMap destructor. -*/ -QShortcutMap::~QShortcutMap() -{ -} - -/*! \internal - Adds a shortcut to the global map. - Returns the id of the newly added shortcut. -*/ -int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context) -{ - Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner"); - Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map"); - Q_D(QShortcutMap); - - QShortcutEntry newEntry(owner, key, context, --(d->currentId), true); - QList<QShortcutEntry>::iterator it = qUpperBound(d->sequences.begin(), d->sequences.end(), newEntry); - d->sequences.insert(it, newEntry); // Insert sorted -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::addShortcut(" << owner << ", " - << key << ", " << context << ") = " << d->currentId; -#endif - return d->currentId; -} - -/*! \internal - Removes a shortcut from the global map. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are removed. - Returns the number of sequences removed from the map. -*/ - -int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsRemoved = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - // Special case, remove everything - if (allOwners && allKeys && id == 0) { - itemsRemoved = d->sequences.size(); - d->sequences.clear(); - return itemsRemoved; - } - - int i = d->sequences.size()-1; - while (i>=0) - { - const QShortcutEntry &entry = d->sequences.at(i); - int entryId = entry.id; - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences.removeAt(i); - ++itemsRemoved; - } - if (id == entryId) - return itemsRemoved; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", " - << key << ") = " << itemsRemoved; -#endif - return itemsRemoved; -} - -/*! \internal - Changes the enable state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are changed. - Returns the number of sequences which are matched in the map. -*/ -int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsChanged = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - int i = d->sequences.size()-1; - while (i>=0) - { - QShortcutEntry entry = d->sequences.at(i); - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences[i].enabled = enable; - ++itemsChanged; - } - if (id == entry.id) - return itemsChanged; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", " - << owner << ", " << key << ") = " << itemsChanged; -#endif - return itemsChanged; -} - -/*! \internal - Changes the auto repeat state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are changed. - Returns the number of sequences which are matched in the map. -*/ -int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsChanged = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - int i = d->sequences.size()-1; - while (i>=0) - { - QShortcutEntry entry = d->sequences.at(i); - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences[i].autorepeat = on; - ++itemsChanged; - } - if (id == entry.id) - return itemsChanged; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", " - << owner << ", " << key << ") = " << itemsChanged; -#endif - return itemsChanged; -} - -/*! \internal - Resets the state of the statemachine to NoMatch -*/ -void QShortcutMap::resetState() -{ - Q_D(QShortcutMap); - d->currentState = QKeySequence::NoMatch; - clearSequence(d->currentSequences); -} - -/*! \internal - Returns the current state of the statemachine -*/ -QKeySequence::SequenceMatch QShortcutMap::state() -{ - Q_D(QShortcutMap); - return d->currentState; -} - -/*! \internal - Uses ShortcutOverride event to see if any widgets want to override - the event. If not, uses nextState(QKeyEvent) to check for a grabbed - Shortcut, and dispatchEvent() is found an identical. - \sa nextState dispatchEvent -*/ -bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e) -{ - Q_D(QShortcutMap); - - bool wasAccepted = e->isAccepted(); - bool wasSpontaneous = e->spont; - if (d->currentState == QKeySequence::NoMatch) { - ushort orgType = e->t; - e->t = QEvent::ShortcutOverride; - e->ignore(); - QCoreApplication::sendEvent(o, e); - e->t = orgType; - e->spont = wasSpontaneous; - if (e->isAccepted()) { - if (!wasAccepted) - e->ignore(); - return false; - } - } - - QKeySequence::SequenceMatch result = nextState(e); - bool stateWasAccepted = e->isAccepted(); - if (wasAccepted) - e->accept(); - else - e->ignore(); - - int identicalMatches = d->identicals.count(); - - switch(result) { - case QKeySequence::NoMatch: - return stateWasAccepted; - case QKeySequence::ExactMatch: - resetState(); - dispatchEvent(e); - default: - break; - } - // If nextState is QKeySequence::ExactMatch && identicals.count == 0 - // we've only found disabled shortcuts - return identicalMatches > 0 || result == QKeySequence::PartialMatch; -} - -/*! \internal - Returns the next state of the statemachine - If return value is SequenceMatch::ExactMatch, then a call to matches() - will return a QObjects* list of all matching objects for the last matching - sequence. -*/ -QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) -{ - Q_D(QShortcutMap); - // Modifiers can NOT be shortcuts... - if (e->key() >= Qt::Key_Shift && - e->key() <= Qt::Key_Alt) - return d->currentState; - - QKeySequence::SequenceMatch result = QKeySequence::NoMatch; - - // We start fresh each time.. - d->identicals.resize(0); - - result = find(e); - if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) { - // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab - if (e->key() == Qt::Key_Backtab) { - QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text()); - result = find(&pe); - } - } - - // Should we eat this key press? - if (d->currentState == QKeySequence::PartialMatch - || (d->currentState == QKeySequence::ExactMatch && d->identicals.count())) - e->accept(); - // Does the new state require us to clean up? - if (result == QKeySequence::NoMatch) - clearSequence(d->currentSequences); - d->currentState = result; - -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result; -#endif - return result; -} - - -/*! \internal - Determines if an enabled shortcut has a matcing key sequence. -*/ -bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const -{ - Q_D(const QShortcutMap); - QShortcutEntry entry(seq); // needed for searching - QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd(); - QList<QShortcutEntry>::ConstIterator it = qLowerBound(d->sequences.constBegin(), itEnd, entry); - - for (;it != itEnd; ++it) { - if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && correctContext(*it) && (*it).enabled) { - return true; - } - } - - //end of the loop: we didn't find anything - return false; -} - -/*! \internal - Returns the next state of the statemachine, based - on the new key event \a e. - Matches are appended to the vector of identicals, - which can be access through matches(). - \sa matches -*/ -QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e) -{ - Q_D(QShortcutMap); - if (!d->sequences.count()) - return QKeySequence::NoMatch; - - createNewSequences(e, d->newEntries); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Possible shortcut key sequences:" << d->newEntries; -#endif - - // Should never happen - if (d->newEntries == d->currentSequences) { - Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(), - "QShortcutMap::find", "New sequence to find identical to previous"); - return QKeySequence::NoMatch; - } - - // Looking for new identicals, scrap old - d->identicals.resize(0); - - bool partialFound = false; - bool identicalDisabledFound = false; - QVector<QKeySequence> okEntries; - int result = QKeySequence::NoMatch; - for (int i = d->newEntries.count()-1; i >= 0 ; --i) { - QShortcutEntry entry(d->newEntries.at(i)); // needed for searching - QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd(); - QList<QShortcutEntry>::ConstIterator it = - qLowerBound(d->sequences.constBegin(), itEnd, entry); - - int oneKSResult = QKeySequence::NoMatch; - int tempRes = QKeySequence::NoMatch; - do { - if (it == itEnd) - break; - tempRes = matches(entry.keyseq, (*it).keyseq); - oneKSResult = qMax(oneKSResult, tempRes); - if (tempRes != QKeySequence::NoMatch && correctContext(*it)) { - if (tempRes == QKeySequence::ExactMatch) { - if ((*it).enabled) - d->identicals.append(&*it); - else - identicalDisabledFound = true; - } else if (tempRes == QKeySequence::PartialMatch) { - // We don't need partials, if we have identicals - if (d->identicals.size()) - break; - // We only care about enabled partials, so we don't consume - // key events when all partials are disabled! - partialFound |= (*it).enabled; - } - } - ++it; - // If we got a valid match on this run, there might still be more keys to check against, - // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible - // matches in the shortcutmap. - } while (tempRes != QKeySequence::NoMatch); - - // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the - // previous list. If this match is equal or better than the last match, append to the list - if (oneKSResult > result) { - okEntries.clear(); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list"; -#endif - } - if (oneKSResult && oneKSResult >= result) { - okEntries << d->newEntries.at(i); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Added ok key sequence" << d->newEntries; -#endif - } - } - - if (d->identicals.size()) { - result = QKeySequence::ExactMatch; - } else if (partialFound) { - result = QKeySequence::PartialMatch; - } else if (identicalDisabledFound) { - result = QKeySequence::ExactMatch; - } else { - clearSequence(d->currentSequences); - result = QKeySequence::NoMatch; - } - if (result != QKeySequence::NoMatch) - d->currentSequences = okEntries; -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Returning shortcut match == " << result; -#endif - return QKeySequence::SequenceMatch(result); -} - -/*! \internal - Clears \a seq to an empty QKeySequence. - Same as doing (the slower) - \snippet doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp 0 -*/ -void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl) -{ - ksl.clear(); - d_func()->newEntries.clear(); -} - -/*! \internal - Alters \a seq to the new sequence state, based on the - current sequence state, and the new key event \a e. -*/ -void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl) -{ - Q_D(QShortcutMap); - QList<int> possibleKeys = QKeyMapper::possibleKeys(e); - int pkTotal = possibleKeys.count(); - if (!pkTotal) - return; - - int ssActual = d->currentSequences.count(); - int ssTotal = qMax(1, ssActual); - // Resize to possible permutations of the current sequence(s). - ksl.resize(pkTotal * ssTotal); - - int index = ssActual ? d->currentSequences.at(0).count() : 0; - for (int pkNum = 0; pkNum < pkTotal; ++pkNum) { - for (int ssNum = 0; ssNum < ssTotal; ++ssNum) { - int i = (pkNum * ssTotal) + ssNum; - QKeySequence &curKsl = ksl[i]; - if (ssActual) { - const QKeySequence &curSeq = d->currentSequences.at(ssNum); - curKsl.setKey(curSeq[0], 0); - curKsl.setKey(curSeq[1], 1); - curKsl.setKey(curSeq[2], 2); - curKsl.setKey(curSeq[3], 3); - } else { - curKsl.setKey(0, 0); - curKsl.setKey(0, 1); - curKsl.setKey(0, 2); - curKsl.setKey(0, 3); - } - // Filtering keycode here with 0xdfffffff to ignore the Keypad modifier - curKsl.setKey(possibleKeys.at(pkNum) & 0xdfffffff, index); - } - } -} - -/*! \internal - Basically the same function as QKeySequence::matches(const QKeySequence &seq) const - only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and - they conceptually the same. -*/ -QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1, - const QKeySequence &seq2) const -{ - uint userN = seq1.count(), - seqN = seq2.count(); - - if (userN > seqN) - return QKeySequence::NoMatch; - - // If equal in length, we have a potential ExactMatch sequence, - // else we already know it can only be partial. - QKeySequence::SequenceMatch match = (userN == seqN - ? QKeySequence::ExactMatch - : QKeySequence::PartialMatch); - - for (uint i = 0; i < userN; ++i) { - int userKey = seq1[i], - sequenceKey = seq2[i]; - if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen) - userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; - if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen) - sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; - if (userKey != sequenceKey) - return QKeySequence::NoMatch; - } - return match; -} - -/*! \internal - Returns true if the widget \a w is a logical sub window of the current - top-level widget. -*/ -bool QShortcutMap::correctContext(const QShortcutEntry &item) const { - Q_ASSERT_X(item.owner, "QShortcutMap", "Shortcut has no owner. Illegal map state!"); - - QWidget *active_window = QApplication::activeWindow(); - - // popups do not become the active window, - // so we fake it here to get the correct context - // for the shortcut system. - if (QApplication::activePopupWidget()) - active_window = QApplication::activePopupWidget(); - - if (!active_window) - return false; -#ifndef QT_NO_ACTION - if (QAction *a = qobject_cast<QAction *>(item.owner)) - return correctContext(item.context, a, active_window); -#endif -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsWidget *gw = qobject_cast<QGraphicsWidget *>(item.owner)) - return correctGraphicsWidgetContext(item.context, gw, active_window); -#endif - QWidget *w = qobject_cast<QWidget *>(item.owner); - if (!w) { - QShortcut *s = qobject_cast<QShortcut *>(item.owner); - w = s->parentWidget(); - } - return correctWidgetContext(item.context, w, active_window); -} - -bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) const -{ - bool visible = w->isVisible(); -#ifdef Q_WS_MAC - if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) - visible = true; -#endif - - if (!visible || !w->isEnabled()) - return false; - - if (context == Qt::ApplicationShortcut) - return QApplicationPrivate::tryModalHelper(w, 0); // true, unless w is shadowed by a modal dialog - - if (context == Qt::WidgetShortcut) - return w == QApplication::focusWidget(); - - if (context == Qt::WidgetWithChildrenShortcut) { - const QWidget *tw = QApplication::focusWidget(); - while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) - tw = tw->parentWidget(); - return tw == w; - } - - // Below is Qt::WindowShortcut context - QWidget *tlw = w->window(); -#ifndef QT_NO_GRAPHICSVIEW - if (QWExtra *topData = tlw->d_func()->extra) { - if (topData->proxyWidget) { - bool res = correctGraphicsWidgetContext(context, (QGraphicsWidget *)topData->proxyWidget, active_window); - return res; - } - } -#endif - - /* if a floating tool window is active, keep shortcuts on the - * parent working */ - if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) { - active_window = active_window->parentWidget()->window(); - } - - if (active_window != tlw) - return false; - - /* if we live in a MDI subwindow, ignore the event if we are - not the active document window */ - const QWidget* sw = w; - while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow()) - sw = sw->parentWidget(); - if (sw && (sw->windowType() == Qt::SubWindow)) { - QWidget *focus_widget = QApplication::focusWidget(); - while (focus_widget && focus_widget != sw) - focus_widget = focus_widget->parentWidget(); - return sw == focus_widget; - } - -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() << "..true [Pass-through]"; -#endif - return true; -} - -#ifndef QT_NO_GRAPHICSVIEW -bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) const -{ - bool visible = w->isVisible(); -#ifdef Q_WS_MAC - if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) - visible = true; -#endif - - if (!visible || !w->isEnabled() || !w->scene()) - return false; - - if (context == Qt::ApplicationShortcut) { - // Applicationwide shortcuts are always reachable unless their owner - // is shadowed by modality. In QGV there's no modality concept, but we - // must still check if all views are shadowed. - QList<QGraphicsView *> views = w->scene()->views(); - for (int i = 0; i < views.size(); ++i) { - if (QApplicationPrivate::tryModalHelper(views.at(i), 0)) - return true; - } - return false; - } - - if (context == Qt::WidgetShortcut) - return static_cast<QGraphicsItem *>(w) == w->scene()->focusItem(); - - if (context == Qt::WidgetWithChildrenShortcut) { - const QGraphicsItem *ti = w->scene()->focusItem(); - if (ti && ti->isWidget()) { - const QGraphicsWidget *tw = static_cast<const QGraphicsWidget *>(ti); - while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) - tw = tw->parentWidget(); - return tw == w; - } - return false; - } - - // Below is Qt::WindowShortcut context - - // Find the active view (if any). - QList<QGraphicsView *> views = w->scene()->views(); - QGraphicsView *activeView = 0; - for (int i = 0; i < views.size(); ++i) { - QGraphicsView *view = views.at(i); - if (view->window() == active_window) { - activeView = view; - break; - } - } - if (!activeView) - return false; - - // The shortcut is reachable if owned by a windowless widget, or if the - // widget's window is the same as the focus item's window. - QGraphicsWidget *a = w->scene()->activeWindow(); - return !w->window() || a == w->window(); -} -#endif - -#ifndef QT_NO_ACTION -bool QShortcutMap::correctContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window) const -{ - const QList<QWidget *> &widgets = a->d_func()->widgets; -#if defined(DEBUG_QSHORTCUTMAP) - if (widgets.isEmpty()) - qDebug() << a << "not connected to any widgets; won't trigger"; -#endif - for (int i = 0; i < widgets.size(); ++i) { - QWidget *w = widgets.at(i); -#ifndef QT_NO_MENU - if (QMenu *menu = qobject_cast<QMenu *>(w)) { - QAction *a = menu->menuAction(); - if (correctContext(context, a, active_window)) - return true; - } else -#endif - if (correctWidgetContext(context, w, active_window)) - return true; - } - -#ifndef QT_NO_GRAPHICSVIEW - const QList<QGraphicsWidget *> &graphicsWidgets = a->d_func()->graphicsWidgets; -#if defined(DEBUG_QSHORTCUTMAP) - if (graphicsWidgets.isEmpty()) - qDebug() << a << "not connected to any widgets; won't trigger"; -#endif - for (int i = 0; i < graphicsWidgets.size(); ++i) { - QGraphicsWidget *w = graphicsWidgets.at(i); - if (correctGraphicsWidgetContext(context, w, active_window)) - return true; - } -#endif - return false; -} -#endif // QT_NO_ACTION - -/*! \internal - Converts keyboard button states into modifier states -*/ -int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers) -{ - int result = 0; - if (modifiers & Qt::ShiftModifier) - result |= Qt::SHIFT; - if (modifiers & Qt::ControlModifier) - result |= Qt::CTRL; - if (modifiers & Qt::MetaModifier) - result |= Qt::META; - if (modifiers & Qt::AltModifier) - result |= Qt::ALT; - return result; -} - -/*! \internal - Returns the vector of QShortcutEntry's matching the last Identical state. -*/ -QVector<const QShortcutEntry*> QShortcutMap::matches() const -{ - Q_D(const QShortcutMap); - return d->identicals; -} - -/*! \internal - Dispatches QShortcutEvents to widgets who grabbed the matched key sequence. -*/ -void QShortcutMap::dispatchEvent(QKeyEvent *e) -{ - Q_D(QShortcutMap); - if (!d->identicals.size()) - return; - - const QKeySequence &curKey = d->identicals.at(0)->keyseq; - if (d->prevSequence != curKey) { - d->ambigCount = 0; - d->prevSequence = curKey; - } - // Find next - const QShortcutEntry *current = 0, *next = 0; - int i = 0, enabledShortcuts = 0; - while(i < d->identicals.size()) { - current = d->identicals.at(i); - if (current->enabled || !next){ - ++enabledShortcuts; - if (enabledShortcuts > d->ambigCount + 1) - break; - next = current; - } - ++i; - } - d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1); - // Don't trigger shortcut if we're autorepeating and the shortcut is - // grabbed with not accepting autorepeats. - if (!next || (e->isAutoRepeat() && !next->autorepeat)) - return; - // Dispatch next enabled -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" - << (QString)next->keyseq << "\", " << next->id << ", " - << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; -#endif - QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); - QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se); -} - -/* \internal - QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is - defined. -*/ -#if defined(Dump_QShortcutMap) -void QShortcutMap::dumpMap() const -{ - Q_D(const QShortcutMap); - for (int i = 0; i < d->sequences.size(); ++i) - qDebug().nospace() << &(d->sequences.at(i)); -} -#endif - -QT_END_NAMESPACE - -#endif // QT_NO_SHORTCUT diff --git a/src/gui/to_be_moved/qshortcutmap_p.h b/src/gui/to_be_moved/qshortcutmap_p.h deleted file mode 100644 index bc530b00b4..0000000000 --- a/src/gui/to_be_moved/qshortcutmap_p.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSHORTCUTMAP_P_H -#define QSHORTCUTMAP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qkeysequence.h" -#include "QtCore/qvector.h" -#include "QtCore/qscopedpointer.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SHORTCUT - -// To enable dump output uncomment below -//#define Dump_QShortcutMap - -class QKeyEvent; -struct QShortcutEntry; -class QShortcutMapPrivate; -class QGraphicsWidget; -class QWidget; -class QAction; -class QObject; - -class QShortcutMap -{ - Q_DECLARE_PRIVATE(QShortcutMap) -public: - QShortcutMap(); - ~QShortcutMap(); - - int addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context); - int removeShortcut(int id, QObject *owner, const QKeySequence &key = QKeySequence()); - int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key = QKeySequence()); - int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key = QKeySequence()); - - void resetState(); - QKeySequence::SequenceMatch nextState(QKeyEvent *e); - QKeySequence::SequenceMatch state(); - void dispatchEvent(QKeyEvent *e); - bool tryShortcutEvent(QObject *o, QKeyEvent *e); - -#ifdef Dump_QShortcutMap - void dumpMap() const; -#endif - - bool hasShortcutForKeySequence(const QKeySequence &seq) const; - - -private: - bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) const; -#ifndef QT_NO_GRAPHICSVIEW - bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) const; -#endif -#ifndef QT_NO_ACTION - bool correctContext(Qt::ShortcutContext context,QAction *a, QWidget *active_window) const; -#endif - QScopedPointer<QShortcutMapPrivate> d_ptr; - - QKeySequence::SequenceMatch find(QKeyEvent *e); - QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const; - QVector<const QShortcutEntry *> matches() const; - void createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl); - void clearSequence(QVector<QKeySequence> &ksl); - bool correctContext(const QShortcutEntry &item) const; - int translateModifiers(Qt::KeyboardModifiers modifiers); -}; - -#endif // QT_NO_SHORTCUT - -QT_END_NAMESPACE - -#endif // QSHORTCUTMAP_P_H diff --git a/src/gui/to_be_moved/qtextcontrol.cpp b/src/gui/to_be_moved/qtextcontrol.cpp deleted file mode 100644 index 43967307bc..0000000000 --- a/src/gui/to_be_moved/qtextcontrol.cpp +++ /dev/null @@ -1,3148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtextcontrol_p.h" -#include "qtextcontrol_p_p.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/qabstracttextdocumentlayout_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 "qtextdocumentwriter.h" -#include "private/qtextcursor_p.h" - -#include <qtextformat.h> -#include <qdatetime.h> -#include <qbuffer.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> -#include <QtGui/qlineedit.h> - -#ifndef QT_NO_SHORTCUT -#include "private/qapplication_p.h" -#include "private/qshortcutmap_p.h" -#include <qkeysequence.h> -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString()) -#else -#define ACCEL_KEY(k) QString() -#endif - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_CONTEXTMENU -#if defined(Q_WS_WIN) || defined(Q_WS_X11) -extern bool qt_use_rtl_extensions; -#endif -#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), - dragEnabled(true), -#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 - isEnabled(true), - hadSelectionOnMousePress(false), - ignoreUnusedNavigationEvents(false), - openExternalLinks(false), - wordSelectionEnabled(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::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) - - bool visualNavigation = cursor.visualNavigation(); - cursor.setVisualNavigation(true); - const bool moved = cursor.movePosition(op, mode); - cursor.setVisualNavigation(visualNavigation); - q->ensureCursorVisible(); - - bool ignoreNavigationEvents = ignoreUnusedNavigationEvents; - bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down; - -#ifdef QT_KEYPAD_NAVIGATION - ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled(); - isNavigationEvent = isNavigationEvent || - (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional - && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)); -#else - isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right; -#endif - - if (moved) { - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - emit q->microFocusChanged(); - } else if (ignoreNavigationEvents && isNavigationEvent && oldSelection.anchor() == cursor.anchor()) { - return false; - } - - 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) -{ - Q_Q(QTextControl); - setContent(format, text, document); - - doc->setUndoRedoEnabled(interactionFlags & Qt::TextEditable); - q->setCursorWidth(-1); -} - -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) { - if (document) { - doc = document; - clearDocument = false; - } else { - palette = QApplication::palette("QTextControl"); - doc = new QTextDocument(q); - } - _q_documentLayoutChanged(); - cursor = QTextCursor(doc); - -// #### doc->documentLayout()->setPaintDevice(viewport); - - QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection())); - QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor))); - QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged())); - - // convenience signal forwards - QObject::connect(doc, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool))); - QObject::connect(doc, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool))); - QObject::connect(doc, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool))); - QObject::connect(doc, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int))); - } - - bool previousUndoRedoState = doc->isUndoRedoEnabled(); - if (!document) - doc->setUndoRedoEnabled(false); - - //Saving the index save some time. - static int contentsChangedIndex = QTextDocument::staticMetaObject.indexOfSignal("contentsChanged()"); - static int textChangedIndex = QTextControl::staticMetaObject.indexOfSignal("textChanged()"); - // avoid multiple textChanged() signals being emitted - QMetaObject::disconnect(doc, contentsChangedIndex, q, textChangedIndex); - - if (!text.isEmpty()) { - // clear 'our' cursor for insertion to prevent - // the emission of the cursorPositionChanged() signal. - // instead we emit it only once at the end instead of - // at the end of the document after loading and when - // positioning the cursor again to the start of the - // document. - cursor = QTextCursor(); - if (format == Qt::PlainText) { - QTextCursor formatCursor(doc); - // put the setPlainText and the setCharFormat into one edit block, - // so that the syntax highlight triggers only /once/ for the entire - // document, not twice. - formatCursor.beginEditBlock(); - doc->setPlainText(text); - doc->setUndoRedoEnabled(false); - formatCursor.select(QTextCursor::Document); - formatCursor.setCharFormat(charFormatForInsertion); - formatCursor.endEditBlock(); - } else { -#ifndef QT_NO_TEXTHTMLPARSER - doc->setHtml(text); -#else - doc->setPlainText(text); -#endif - doc->setUndoRedoEnabled(false); - } - cursor = QTextCursor(doc); - } else if (clearDocument) { - doc->clear(); - } - cursor.setCharFormat(charFormatForInsertion); - - QMetaObject::connect(doc, contentsChangedIndex, q, textChangedIndex); - emit q->textChanged(); - if (!document) - doc->setUndoRedoEnabled(previousUndoRedoState); - _q_updateCurrentCharFormatAndSelection(); - if (!document) - doc->setModified(false); - - q->ensureCursorVisible(); - emit q->cursorPositionChanged(); -} - -void QTextControlPrivate::startDrag() -{ -#ifndef QT_NO_DRAGANDDROP - Q_Q(QTextControl); - mousePressed = false; - if (!contextWidget) - return; - QMimeData *data = q->createMimeDataFromSelection(); - - QDrag *drag = new QDrag(contextWidget); - drag->setMimeData(data); - - Qt::DropActions actions = Qt::CopyAction; - Qt::DropAction action; - if (interactionFlags & Qt::TextEditable) { - actions |= Qt::MoveAction; - action = drag->exec(actions, Qt::MoveAction); - } else { - action = drag->exec(actions, Qt::CopyAction); - } - - if (action == Qt::MoveAction && drag->target() != contextWidget) - cursor.removeSelectedText(); -#endif -} - -void QTextControlPrivate::setCursorPosition(const QPointF &pos) -{ - Q_Q(QTextControl); - const int cursorPos = q->hitTest(pos, Qt::FuzzyHit); - if (cursorPos == -1) - return; - cursor.setPosition(cursorPos); -} - -void QTextControlPrivate::setCursorPosition(int pos, QTextCursor::MoveMode mode) -{ - cursor.setPosition(pos, mode); - - if (mode != QTextCursor::KeepAnchor) { - selectedWordOnDoubleClick = QTextCursor(); - selectedBlockOnTrippleClick = QTextCursor(); - } -} - -void QTextControlPrivate::repaintCursor() -{ - Q_Q(QTextControl); - emit q->updateRequest(cursorRectPlusUnicodeDirectionMarkers(cursor)); -} - -void QTextControlPrivate::repaintOldAndNewSelection(const QTextCursor &oldSelection) -{ - Q_Q(QTextControl); - if (cursor.hasSelection() - && oldSelection.hasSelection() - && cursor.currentFrame() == oldSelection.currentFrame() - && !cursor.hasComplexSelection() - && !oldSelection.hasComplexSelection() - && cursor.anchor() == oldSelection.anchor() - ) { - QTextCursor differenceSelection(doc); - differenceSelection.setPosition(oldSelection.position()); - differenceSelection.setPosition(cursor.position(), QTextCursor::KeepAnchor); - emit q->updateRequest(q->selectionRect(differenceSelection)); - } else { - if (!oldSelection.isNull()) - emit q->updateRequest(q->selectionRect(oldSelection) | cursorRectPlusUnicodeDirectionMarkers(oldSelection)); - emit q->updateRequest(q->selectionRect() | cursorRectPlusUnicodeDirectionMarkers(cursor)); - } -} - -void QTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /*=false*/) -{ - Q_Q(QTextControl); - if (forceEmitSelectionChanged) - emit q->selectionChanged(); - - bool current = cursor.hasSelection(); - if (current == lastSelectionState) - return; - - lastSelectionState = current; - emit q->copyAvailable(current); - if (!forceEmitSelectionChanged) - emit q->selectionChanged(); - emit q->microFocusChanged(); -} - -void QTextControlPrivate::_q_updateCurrentCharFormatAndSelection() -{ - updateCurrentCharFormat(); - selectionChanged(); -} - -#ifndef QT_NO_CLIPBOARD -void QTextControlPrivate::setClipboardSelection() -{ - QClipboard *clipboard = QApplication::clipboard(); - if (!cursor.hasSelection() || !clipboard->supportsSelection()) - return; - Q_Q(QTextControl); - QMimeData *data = q->createMimeDataFromSelection(); - clipboard->setMimeData(data, QClipboard::Selection); -} -#endif - -void QTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someCursor) -{ - Q_Q(QTextControl); - if (someCursor.isCopyOf(cursor)) { - emit q->cursorPositionChanged(); - emit q->microFocusChanged(); - } -} - -void QTextControlPrivate::_q_documentLayoutChanged() -{ - Q_Q(QTextControl); - QAbstractTextDocumentLayout *layout = doc->documentLayout(); - QObject::connect(layout, SIGNAL(update(QRectF)), q, SIGNAL(updateRequest(QRectF))); - QObject::connect(layout, SIGNAL(updateBlock(QTextBlock)), q, SLOT(_q_updateBlock(QTextBlock))); - QObject::connect(layout, SIGNAL(documentSizeChanged(QSizeF)), q, SIGNAL(documentSizeChanged(QSizeF))); - -} - -void QTextControlPrivate::setBlinkingCursorEnabled(bool enable) -{ - Q_Q(QTextControl); - - if (enable && QApplication::cursorFlashTime() > 0) - cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, q); - else - cursorBlinkTimer.stop(); - - cursorOn = enable; - - repaintCursor(); -} - -void QTextControlPrivate::extendWordwiseSelection(int suggestedNewPosition, qreal mouseXPosition) -{ - Q_Q(QTextControl); - - // if inside the initial selected word keep that - if (suggestedNewPosition >= selectedWordOnDoubleClick.selectionStart() - && suggestedNewPosition <= selectedWordOnDoubleClick.selectionEnd()) { - q->setTextCursor(selectedWordOnDoubleClick); - return; - } - - QTextCursor curs = selectedWordOnDoubleClick; - curs.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor); - - if (!curs.movePosition(QTextCursor::StartOfWord)) - return; - const int wordStartPos = curs.position(); - - const int blockPos = curs.block().position(); - const QPointF blockCoordinates = q->blockBoundingRect(curs.block()).topLeft(); - - QTextLine line = currentTextLine(curs); - if (!line.isValid()) - return; - - const qreal wordStartX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x(); - - if (!curs.movePosition(QTextCursor::EndOfWord)) - return; - const int wordEndPos = curs.position(); - - const QTextLine otherLine = currentTextLine(curs); - if (otherLine.textStart() != line.textStart() - || wordEndPos == wordStartPos) - return; - - const qreal wordEndX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x(); - - if (mouseXPosition < wordStartX || mouseXPosition > wordEndX) - return; - - // keep the already selected word even when moving to the left - // (#39164) - if (suggestedNewPosition < selectedWordOnDoubleClick.position()) - cursor.setPosition(selectedWordOnDoubleClick.selectionEnd()); - else - cursor.setPosition(selectedWordOnDoubleClick.selectionStart()); - - const qreal differenceToStart = mouseXPosition - wordStartX; - const qreal differenceToEnd = wordEndX - mouseXPosition; - - if (differenceToStart < differenceToEnd) - setCursorPosition(wordStartPos, QTextCursor::KeepAnchor); - else - setCursorPosition(wordEndPos, QTextCursor::KeepAnchor); - - if (interactionFlags & Qt::TextSelectableByMouse) { -#ifndef QT_NO_CLIPBOARD - setClipboardSelection(); -#endif - selectionChanged(true); - } -} - -void QTextControlPrivate::extendBlockwiseSelection(int suggestedNewPosition) -{ - Q_Q(QTextControl); - - // if inside the initial selected line keep that - if (suggestedNewPosition >= selectedBlockOnTrippleClick.selectionStart() - && suggestedNewPosition <= selectedBlockOnTrippleClick.selectionEnd()) { - q->setTextCursor(selectedBlockOnTrippleClick); - return; - } - - if (suggestedNewPosition < selectedBlockOnTrippleClick.position()) { - cursor.setPosition(selectedBlockOnTrippleClick.selectionEnd()); - cursor.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); - } else { - cursor.setPosition(selectedBlockOnTrippleClick.selectionStart()); - cursor.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); - } - - if (interactionFlags & Qt::TextSelectableByMouse) { -#ifndef QT_NO_CLIPBOARD - setClipboardSelection(); -#endif - selectionChanged(true); - } -} - -void QTextControlPrivate::_q_deleteSelected() -{ - if (!(interactionFlags & Qt::TextEditable) || !cursor.hasSelection()) - return; - cursor.removeSelectedText(); -} - -void QTextControl::undo() -{ - Q_D(QTextControl); - d->repaintSelection(); - const int oldCursorPos = d->cursor.position(); - d->doc->undo(&d->cursor); - if (d->cursor.position() != oldCursorPos) - emit cursorPositionChanged(); - emit microFocusChanged(); - ensureCursorVisible(); -} - -void QTextControl::redo() -{ - Q_D(QTextControl); - d->repaintSelection(); - const int oldCursorPos = d->cursor.position(); - d->doc->redo(&d->cursor); - if (d->cursor.position() != oldCursorPos) - emit cursorPositionChanged(); - emit microFocusChanged(); - ensureCursorVisible(); -} - -QTextControl::QTextControl(QObject *parent) - : QObject(*new QTextControlPrivate, parent) -{ - Q_D(QTextControl); - d->init(); -} - -QTextControl::QTextControl(const QString &text, QObject *parent) - : QObject(*new QTextControlPrivate, parent) -{ - Q_D(QTextControl); - d->init(Qt::RichText, text); -} - -QTextControl::QTextControl(QTextDocument *doc, QObject *parent) - : QObject(*new QTextControlPrivate, parent) -{ - Q_D(QTextControl); - d->init(Qt::RichText, QString(), doc); -} - -QTextControl::~QTextControl() -{ -} - -void QTextControl::setDocument(QTextDocument *document) -{ - Q_D(QTextControl); - if (d->doc == document) - return; - - d->doc->disconnect(this); - d->doc->documentLayout()->disconnect(this); - d->doc->documentLayout()->setPaintDevice(0); - - if (d->doc->parent() == this) - delete d->doc; - - d->doc = 0; - d->setContent(Qt::RichText, QString(), document); -} - -QTextDocument *QTextControl::document() const -{ - Q_D(const QTextControl); - return d->doc; -} - -void QTextControl::setTextCursor(const QTextCursor &cursor) -{ - Q_D(QTextControl); - d->cursorIsFocusIndicator = false; - const bool posChanged = cursor.position() != d->cursor.position(); - const QTextCursor oldSelection = d->cursor; - d->cursor = cursor; - d->cursorOn = d->hasFocus && (d->interactionFlags & Qt::TextEditable); - d->_q_updateCurrentCharFormatAndSelection(); - ensureCursorVisible(); - d->repaintOldAndNewSelection(oldSelection); - if (posChanged) - emit cursorPositionChanged(); -} - -QTextCursor QTextControl::textCursor() const -{ - Q_D(const QTextControl); - return d->cursor; -} - -#ifndef QT_NO_CLIPBOARD - -void QTextControl::cut() -{ - Q_D(QTextControl); - if (!(d->interactionFlags & Qt::TextEditable) || !d->cursor.hasSelection()) - return; - copy(); - d->cursor.removeSelectedText(); -} - -void QTextControl::copy() -{ - Q_D(QTextControl); - if (!d->cursor.hasSelection()) - return; - QMimeData *data = createMimeDataFromSelection(); - QApplication::clipboard()->setMimeData(data); -} - -void QTextControl::paste(QClipboard::Mode mode) -{ - const QMimeData *md = QApplication::clipboard()->mimeData(mode); - if (md) - insertFromMimeData(md); -} -#endif - -void QTextControl::clear() -{ - Q_D(QTextControl); - // clears and sets empty content - d->extraSelections.clear(); - d->setContent(); -} - - -void QTextControl::selectAll() -{ - Q_D(QTextControl); - const int selectionLength = qAbs(d->cursor.position() - d->cursor.anchor()); - d->cursor.select(QTextCursor::Document); - d->selectionChanged(selectionLength != qAbs(d->cursor.position() - d->cursor.anchor())); - d->cursorIsFocusIndicator = false; - emit updateRequest(); -} - -void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWidget *contextWidget) -{ - QMatrix m; - m.translate(coordinateOffset.x(), coordinateOffset.y()); - processEvent(e, m, contextWidget); -} - -void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget) -{ - Q_D(QTextControl); - if (d->interactionFlags == Qt::NoTextInteraction) { - e->ignore(); - return; - } - - d->contextWidget = contextWidget; - - if (!d->contextWidget) { - switch (e->type()) { -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseMove: - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseDoubleClick: - case QEvent::GraphicsSceneContextMenu: - case QEvent::GraphicsSceneHoverEnter: - case QEvent::GraphicsSceneHoverMove: - case QEvent::GraphicsSceneHoverLeave: - case QEvent::GraphicsSceneHelp: - case QEvent::GraphicsSceneDragEnter: - case QEvent::GraphicsSceneDragMove: - case QEvent::GraphicsSceneDragLeave: - case QEvent::GraphicsSceneDrop: { - QGraphicsSceneEvent *ev = static_cast<QGraphicsSceneEvent *>(e); - d->contextWidget = ev->widget(); - break; - } -#endif // QT_NO_GRAPHICSVIEW - default: break; - }; - } - - switch (e->type()) { - case QEvent::KeyPress: - d->keyPressEvent(static_cast<QKeyEvent *>(e)); - break; - case QEvent::MouseButtonPress: { - QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), - ev->buttons(), ev->globalPos()); - break; } - case QEvent::MouseMove: { - QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), - ev->buttons(), ev->globalPos()); - break; } - case QEvent::MouseButtonRelease: { - QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), - ev->buttons(), ev->globalPos()); - break; } - case QEvent::MouseButtonDblClick: { - QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), - ev->buttons(), ev->globalPos()); - break; } - case QEvent::InputMethod: - d->inputMethodEvent(static_cast<QInputMethodEvent *>(e)); - break; -#ifndef QT_NO_CONTEXTMENU - case QEvent::ContextMenu: { - QContextMenuEvent *ev = static_cast<QContextMenuEvent *>(e); - d->contextMenuEvent(ev->globalPos(), matrix.map(ev->pos()), contextWidget); - break; } -#endif // QT_NO_CONTEXTMENU - case QEvent::FocusIn: - case QEvent::FocusOut: - d->focusEvent(static_cast<QFocusEvent *>(e)); - break; - - case QEvent::EnabledChange: - d->isEnabled = e->isAccepted(); - break; - -#ifndef QT_NO_TOOLTIP - case QEvent::ToolTip: { - QHelpEvent *ev = static_cast<QHelpEvent *>(e); - d->showToolTip(ev->globalPos(), matrix.map(ev->pos()), contextWidget); - break; - } -#endif // QT_NO_TOOLTIP - -#ifndef QT_NO_DRAGANDDROP - case QEvent::DragEnter: { - QDragEnterEvent *ev = static_cast<QDragEnterEvent *>(e); - if (d->dragEnterEvent(e, ev->mimeData())) - ev->acceptProposedAction(); - break; - } - case QEvent::DragLeave: - d->dragLeaveEvent(); - break; - case QEvent::DragMove: { - QDragMoveEvent *ev = static_cast<QDragMoveEvent *>(e); - if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos()))) - ev->acceptProposedAction(); - break; - } - case QEvent::Drop: { - QDropEvent *ev = static_cast<QDropEvent *>(e); - if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source())) - ev->acceptProposedAction(); - break; - } -#endif - -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: { - QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), - ev->screenPos()); - break; } - case QEvent::GraphicsSceneMouseMove: { - QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), - ev->screenPos()); - break; } - case QEvent::GraphicsSceneMouseRelease: { - QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), - ev->screenPos()); - break; } - case QEvent::GraphicsSceneMouseDoubleClick: { - QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), - ev->screenPos()); - break; } - case QEvent::GraphicsSceneContextMenu: { - QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e); - d->contextMenuEvent(ev->screenPos(), matrix.map(ev->pos()), contextWidget); - break; } - - case QEvent::GraphicsSceneHoverMove: { - QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e); - d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton, - ev->screenPos()); - break; } - - case QEvent::GraphicsSceneDragEnter: { - QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e); - if (d->dragEnterEvent(e, ev->mimeData())) - ev->acceptProposedAction(); - break; } - case QEvent::GraphicsSceneDragLeave: - d->dragLeaveEvent(); - break; - case QEvent::GraphicsSceneDragMove: { - QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e); - if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos()))) - ev->acceptProposedAction(); - break; } - case QEvent::GraphicsSceneDrop: { - QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e); - if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source())) - ev->accept(); - break; } -#endif // QT_NO_GRAPHICSVIEW -#ifdef QT_KEYPAD_NAVIGATION - case QEvent::EnterEditFocus: - case QEvent::LeaveEditFocus: - if (QApplication::keypadNavigationEnabled()) - d->editFocusEvent(e); - break; -#endif - case QEvent::ShortcutOverride: - if (d->interactionFlags & Qt::TextEditable) { - QKeyEvent* ke = static_cast<QKeyEvent *>(e); - if (ke->modifiers() == Qt::NoModifier - || ke->modifiers() == Qt::ShiftModifier - || ke->modifiers() == Qt::KeypadModifier) { - if (ke->key() < Qt::Key_Escape) { - ke->accept(); - } else { - switch (ke->key()) { - case Qt::Key_Return: - case Qt::Key_Enter: - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Tab: - ke->accept(); - default: - break; - } - } -#ifndef QT_NO_SHORTCUT - } else if (ke == QKeySequence::Copy - || ke == QKeySequence::Paste - || ke == QKeySequence::Cut - || ke == QKeySequence::Redo - || ke == QKeySequence::Undo - || ke == QKeySequence::MoveToNextWord - || ke == QKeySequence::MoveToPreviousWord - || ke == QKeySequence::MoveToStartOfDocument - || ke == QKeySequence::MoveToEndOfDocument - || ke == QKeySequence::SelectNextWord - || ke == QKeySequence::SelectPreviousWord - || ke == QKeySequence::SelectStartOfLine - || ke == QKeySequence::SelectEndOfLine - || ke == QKeySequence::SelectStartOfBlock - || ke == QKeySequence::SelectEndOfBlock - || ke == QKeySequence::SelectStartOfDocument - || ke == QKeySequence::SelectEndOfDocument - || ke == QKeySequence::SelectAll - ) { - ke->accept(); -#endif - } - } - break; - default: - break; - } -} - -bool QTextControl::event(QEvent *e) -{ - return QObject::event(e); -} - -void QTextControl::timerEvent(QTimerEvent *e) -{ - Q_D(QTextControl); - if (e->timerId() == d->cursorBlinkTimer.timerId()) { - d->cursorOn = !d->cursorOn; - - if (d->cursor.hasSelection()) - d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected) - != 0); - - d->repaintCursor(); - } else if (e->timerId() == d->trippleClickTimer.timerId()) { - d->trippleClickTimer.stop(); - } -} - -void QTextControl::setPlainText(const QString &text) -{ - Q_D(QTextControl); - d->setContent(Qt::PlainText, text); -} - -void QTextControl::setHtml(const QString &text) -{ - Q_D(QTextControl); - d->setContent(Qt::RichText, text); -} - -void QTextControlPrivate::keyPressEvent(QKeyEvent *e) -{ - Q_Q(QTextControl); -#ifndef QT_NO_SHORTCUT - if (e == QKeySequence::SelectAll) { - e->accept(); - q->selectAll(); - return; - } -#ifndef QT_NO_CLIPBOARD - else if (e == QKeySequence::Copy) { - e->accept(); - q->copy(); - return; - } -#endif -#endif // QT_NO_SHORTCUT - - if (interactionFlags & Qt::TextSelectableByKeyboard - && cursorMoveKeyEvent(e)) - goto accept; - - if (interactionFlags & Qt::LinksAccessibleByKeyboard) { - if ((e->key() == Qt::Key_Return - || e->key() == Qt::Key_Enter -#ifdef QT_KEYPAD_NAVIGATION - || e->key() == Qt::Key_Select -#endif - ) - && cursor.hasSelection()) { - - e->accept(); - activateLinkUnderCursor(); - return; - } - } - - if (!(interactionFlags & Qt::TextEditable)) { - e->ignore(); - return; - } - - 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); - cursor.mergeBlockFormat(fmt); - goto accept; - } - - // schedule a repaint of the region of the cursor, as when we move it we - // want to make sure the old cursor disappears (not noticeable when moving - // only a few pixels but noticeable when jumping between cells in tables for - // example) - repaintSelection(); - - if (e->key() == Qt::Key_Backspace && !(e->modifiers() & ~Qt::ShiftModifier)) { - QTextBlockFormat blockFmt = cursor.blockFormat(); - QTextList *list = cursor.currentList(); - if (list && cursor.atBlockStart() && !cursor.hasSelection()) { - list->remove(cursor.block()); - } else if (cursor.atBlockStart() && blockFmt.indent() > 0) { - blockFmt.setIndent(blockFmt.indent() - 1); - cursor.setBlockFormat(blockFmt); - } else { - QTextCursor localCursor = cursor; - localCursor.deletePreviousChar(); - } - goto accept; - } -#ifndef QT_NO_SHORTCUT - else if (e == QKeySequence::InsertParagraphSeparator) { - cursor.insertBlock(); - e->accept(); - goto accept; - } else if (e == QKeySequence::InsertLineSeparator) { - cursor.insertText(QString(QChar::LineSeparator)); - e->accept(); - goto accept; - } -#endif - if (false) { - } -#ifndef QT_NO_SHORTCUT - else if (e == QKeySequence::Undo) { - q->undo(); - } - else if (e == QKeySequence::Redo) { - q->redo(); - } -#ifndef QT_NO_CLIPBOARD - else if (e == QKeySequence::Cut) { - q->cut(); - } - else if (e == QKeySequence::Paste) { - QClipboard::Mode mode = QClipboard::Clipboard; -#ifdef Q_WS_X11 - if (e->modifiers() == (Qt::CTRL | Qt::SHIFT) && e->key() == Qt::Key_Insert) - mode = QClipboard::Selection; -#endif - q->paste(mode); - } -#endif - else if (e == QKeySequence::Delete) { - QTextCursor localCursor = cursor; - localCursor.deleteChar(); - } - else if (e == QKeySequence::DeleteEndOfWord) { - if (!cursor.hasSelection()) - cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } - else if (e == QKeySequence::DeleteStartOfWord) { - if (!cursor.hasSelection()) - cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } - else if (e == QKeySequence::DeleteEndOfLine) { - QTextBlock block = cursor.block(); - if (cursor.position() == block.position() + block.length() - 2) - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); - else - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } -#endif // QT_NO_SHORTCUT - else { - goto process; - } - goto accept; - -process: - { - QString text = e->text(); - if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { - if (overwriteMode - // no need to call deleteChar() if we have a selection, insertText - // does it already - && !cursor.hasSelection() - && !cursor.atBlockEnd()) - cursor.deleteChar(); - - cursor.insertText(text); - selectionChanged(); - } else { - e->ignore(); - return; - } - } - - accept: - - e->accept(); - cursorOn = true; - - q->ensureCursorVisible(); - - updateCurrentCharFormat(); -} - -QVariant QTextControl::loadResource(int type, const QUrl &name) -{ -#ifdef QT_NO_TEXTEDIT - Q_UNUSED(type); - Q_UNUSED(name); -#else - if (QTextEdit *textEdit = qobject_cast<QTextEdit *>(parent())) { - QUrl resolvedName = textEdit->d_func()->resolveUrl(name); - return textEdit->loadResource(type, resolvedName); - } -#endif - return QVariant(); -} - -void QTextControlPrivate::_q_updateBlock(const QTextBlock &block) -{ - Q_Q(QTextControl); - QRectF br = q->blockBoundingRect(block); - br.setRight(qreal(INT_MAX)); // the block might have shrunk - emit q->updateRequest(br); -} - -QRectF QTextControlPrivate::rectForPosition(int position) const -{ - Q_Q(const QTextControl); - const QTextBlock block = doc->findBlock(position); - if (!block.isValid()) - return QRectF(); - const QAbstractTextDocumentLayout *docLayout = doc->documentLayout(); - const QTextLayout *layout = block.layout(); - const QPointF layoutPos = q->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); - - int cursorWidth; - { - bool ok = false; -#ifndef QT_NO_PROPERTIES - cursorWidth = docLayout->property("cursorWidth").toInt(&ok); -#endif - if (!ok) - cursorWidth = 1; - } - - QRectF r; - - if (line.isValid()) { - qreal x = line.cursorToX(relativePos); - qreal w = 0; - if (overwriteMode) { - if (relativePos < line.textLength() - line.textStart()) - w = line.cursorToX(relativePos + 1) - x; - else - w = QFontMetrics(block.layout()->font()).width(QLatin1Char(' ')); // in sync with QTextLine::draw() - } - r = QRectF(layoutPos.x() + x, layoutPos.y() + line.y(), - cursorWidth + w, line.height()); - } else { - r = QRectF(layoutPos.x(), layoutPos.y(), cursorWidth, 10); // #### correct height - } - - return r; -} - -static inline bool firstFramePosLessThanCursorPos(QTextFrame *frame, int position) -{ - return frame->firstPosition() < position; -} - -static inline bool cursorPosLessThanLastFramePos(int position, QTextFrame *frame) -{ - return position < frame->lastPosition(); -} - -static QRectF boundingRectOfFloatsInSelection(const QTextCursor &cursor) -{ - QRectF r; - QTextFrame *frame = cursor.currentFrame(); - const QList<QTextFrame *> children = frame->childFrames(); - - const QList<QTextFrame *>::ConstIterator firstFrame = qLowerBound(children.constBegin(), children.constEnd(), - cursor.selectionStart(), firstFramePosLessThanCursorPos); - const QList<QTextFrame *>::ConstIterator lastFrame = qUpperBound(children.constBegin(), children.constEnd(), - cursor.selectionEnd(), cursorPosLessThanLastFramePos); - for (QList<QTextFrame *>::ConstIterator it = firstFrame; it != lastFrame; ++it) { - if ((*it)->frameFormat().position() != QTextFrameFormat::InFlow) - r |= frame->document()->documentLayout()->frameBoundingRect(*it); - } - return r; -} - -QRectF QTextControl::selectionRect(const QTextCursor &cursor) const -{ - Q_D(const QTextControl); - - QRectF r = d->rectForPosition(cursor.selectionStart()); - - if (cursor.hasComplexSelection() && cursor.currentTable()) { - QTextTable *table = cursor.currentTable(); - - r = d->doc->documentLayout()->frameBoundingRect(table); - /* - 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(firstCell.firstCursorPosition().block()); - - for (int col = firstColumn; col < firstColumn + numColumns; ++col) { - const QTextTableCell cell = table->cellAt(firstRow, col); - const qreal y = layout->blockBoundingRect(cell.firstCursorPosition().block()).top(); - - tableSelRect.setTop(qMin(tableSelRect.top(), y)); - } - - for (int row = firstRow; row < firstRow + numRows; ++row) { - const QTextTableCell cell = table->cellAt(row, firstColumn); - const qreal x = layout->blockBoundingRect(cell.firstCursorPosition().block()).left(); - - tableSelRect.setLeft(qMin(tableSelRect.left(), x)); - } - - for (int col = firstColumn; col < firstColumn + numColumns; ++col) { - const QTextTableCell cell = table->cellAt(firstRow + numRows - 1, col); - const qreal y = layout->blockBoundingRect(cell.lastCursorPosition().block()).bottom(); - - tableSelRect.setBottom(qMax(tableSelRect.bottom(), y)); - } - - for (int row = firstRow; row < firstRow + numRows; ++row) { - const QTextTableCell cell = table->cellAt(row, firstColumn + numColumns - 1); - const qreal x = layout->blockBoundingRect(cell.lastCursorPosition().block()).right(); - - tableSelRect.setRight(qMax(tableSelRect.right(), x)); - } - - r = tableSelRect.toRect(); - */ - } else if (cursor.hasSelection()) { - const int position = cursor.selectionStart(); - const int anchor = cursor.selectionEnd(); - const QTextBlock posBlock = d->doc->findBlock(position); - const QTextBlock anchorBlock = d->doc->findBlock(anchor); - if (posBlock == anchorBlock && posBlock.isValid() && posBlock.layout()->lineCount()) { - const QTextLine posLine = posBlock.layout()->lineForTextPosition(position - posBlock.position()); - const QTextLine anchorLine = anchorBlock.layout()->lineForTextPosition(anchor - anchorBlock.position()); - - const int firstLine = qMin(posLine.lineNumber(), anchorLine.lineNumber()); - const int lastLine = qMax(posLine.lineNumber(), anchorLine.lineNumber()); - const QTextLayout *layout = posBlock.layout(); - r = QRectF(); - for (int i = firstLine; i <= lastLine; ++i) { - r |= layout->lineAt(i).rect(); - r |= layout->lineAt(i).naturalTextRect(); // might be bigger in the case of wrap not enabled - } - r.translate(blockBoundingRect(posBlock).topLeft()); - } else { - QRectF anchorRect = d->rectForPosition(cursor.selectionEnd()); - r |= anchorRect; - r |= boundingRectOfFloatsInSelection(cursor); - QRectF frameRect(d->doc->documentLayout()->frameBoundingRect(cursor.currentFrame())); - r.setLeft(frameRect.left()); - r.setRight(frameRect.right()); - } - if (r.isValid()) - r.adjust(-1, -1, 1, 1); - } - - return r; -} - -QRectF QTextControl::selectionRect() const -{ - Q_D(const QTextControl); - return selectionRect(d->cursor); -} - -void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, const QPoint &globalPos) -{ - Q_Q(QTextControl); - - if (sendMouseEventToInputContext( - e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) { - return; - } - - if (interactionFlags & Qt::LinksAccessibleByMouse) { - anchorOnMousePress = q->anchorAt(pos); - - if (cursorIsFocusIndicator) { - cursorIsFocusIndicator = false; - repaintSelection(); - cursor.clearSelection(); - } - } - if (!(button & Qt::LeftButton) || - !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) { - e->ignore(); - return; - } - - cursorIsFocusIndicator = false; - const QTextCursor oldSelection = cursor; - const int oldCursorPos = cursor.position(); - - mousePressed = (interactionFlags & Qt::TextSelectableByMouse); -#ifndef QT_NO_DRAGANDDROP - mightStartDrag = false; -#endif - - if (trippleClickTimer.isActive() - && ((pos - trippleClickPoint).toPoint().manhattanLength() < QApplication::startDragDistance())) { - - cursor.movePosition(QTextCursor::StartOfBlock); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); - selectedBlockOnTrippleClick = cursor; - - anchorOnMousePress = QString(); - - trippleClickTimer.stop(); - } else { - int cursorPos = q->hitTest(pos, Qt::FuzzyHit); - if (cursorPos == -1) { - e->ignore(); - return; - } - - if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) { - if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { - selectedWordOnDoubleClick = cursor; - selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); - } - - if (selectedBlockOnTrippleClick.hasSelection()) - extendBlockwiseSelection(cursorPos); - else if (selectedWordOnDoubleClick.hasSelection()) - extendWordwiseSelection(cursorPos, pos.x()); - else if (!wordSelectionEnabled) - setCursorPosition(cursorPos, QTextCursor::KeepAnchor); - } else { - - if (dragEnabled - && cursor.hasSelection() - && !cursorIsFocusIndicator - && cursorPos >= cursor.selectionStart() - && cursorPos <= cursor.selectionEnd() - && q->hitTest(pos, Qt::ExactHit) != -1) { -#ifndef QT_NO_DRAGANDDROP - mightStartDrag = true; - dragStartPos = pos.toPoint(); -#endif - return; - } - - setCursorPosition(cursorPos); - } - } - - if (interactionFlags & Qt::TextEditable) { - q->ensureCursorVisible(); - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - _q_updateCurrentCharFormatAndSelection(); - } else { - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - selectionChanged(); - } - repaintOldAndNewSelection(oldSelection); - hadSelectionOnMousePress = cursor.hasSelection(); -} - -void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, const QPoint &globalPos) -{ - Q_Q(QTextControl); - - if (sendMouseEventToInputContext( - e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) { - return; - } - - if (interactionFlags & Qt::LinksAccessibleByMouse) { - QString anchor = q->anchorAt(mousePos); - if (anchor != highlightedAnchor) { - highlightedAnchor = anchor; - emit q->linkHovered(anchor); - } - } - - if (!(buttons & Qt::LeftButton)) - return; - - const bool editable = interactionFlags & Qt::TextEditable; - - if (!(mousePressed - || editable - || mightStartDrag - || selectedWordOnDoubleClick.hasSelection() - || selectedBlockOnTrippleClick.hasSelection())) - return; - - const QTextCursor oldSelection = cursor; - const int oldCursorPos = cursor.position(); - - if (mightStartDrag) { - if ((mousePos.toPoint() - dragStartPos).manhattanLength() > QApplication::startDragDistance()) - startDrag(); - return; - } - - if (!mousePressed) - return; - - const qreal mouseX = qreal(mousePos.x()); - - int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); - if (newCursorPos == -1) - return; - - if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { - selectedWordOnDoubleClick = cursor; - selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); - } - - if (selectedBlockOnTrippleClick.hasSelection()) - extendBlockwiseSelection(newCursorPos); - else if (selectedWordOnDoubleClick.hasSelection()) - extendWordwiseSelection(newCursorPos, mouseX); - else - setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); - - if (interactionFlags & Qt::TextEditable) { - // don't call ensureVisible for the visible cursor to avoid jumping - // scrollbars. the autoscrolling ensures smooth scrolling if necessary. - //q->ensureCursorVisible(); - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - _q_updateCurrentCharFormatAndSelection(); -#ifndef QT_NO_IM - if (contextWidget) { - if (QInputContext *ic = inputContext()) { - ic->update(); - } - } -#endif //QT_NO_IM - } else { - //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1))); - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - } - selectionChanged(true); - repaintOldAndNewSelection(oldSelection); -} - -void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, const QPoint &globalPos) -{ - Q_Q(QTextControl); - - if (sendMouseEventToInputContext( - e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) { - return; - } - - const QTextCursor oldSelection = cursor; - const int oldCursorPos = cursor.position(); - -#ifndef QT_NO_DRAGANDDROP - if (mightStartDrag && (button & Qt::LeftButton)) { - mousePressed = false; - setCursorPosition(pos); - cursor.clearSelection(); - selectionChanged(); - } -#endif - if (mousePressed) { - mousePressed = false; -#ifndef QT_NO_CLIPBOARD - setClipboardSelection(); - selectionChanged(true); - } else if (button == Qt::MidButton - && (interactionFlags & Qt::TextEditable) - && QApplication::clipboard()->supportsSelection()) { - setCursorPosition(pos); - const QMimeData *md = QApplication::clipboard()->mimeData(QClipboard::Selection); - if (md) - q->insertFromMimeData(md); -#endif - } - - repaintOldAndNewSelection(oldSelection); - - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - - if (interactionFlags & Qt::LinksAccessibleByMouse) { - if (!(button & Qt::LeftButton)) - return; - - const QString anchor = q->anchorAt(pos); - - if (anchor.isEmpty()) - return; - - if (!cursor.hasSelection() - || (anchor == anchorOnMousePress && hadSelectionOnMousePress)) { - - const int anchorPos = q->hitTest(pos, Qt::ExactHit); - if (anchorPos != -1) { - cursor.setPosition(anchorPos); - - QString anchor = anchorOnMousePress; - anchorOnMousePress = QString(); - activateLinkUnderCursor(anchor); - } - } - } -} - -void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, const QPoint &globalPos) -{ - Q_Q(QTextControl); - - if (sendMouseEventToInputContext( - e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) { - return; - } - - if (button != Qt::LeftButton - || !(interactionFlags & Qt::TextSelectableByMouse)) { - e->ignore(); - return; - } - -#ifndef QT_NO_DRAGANDDROP - mightStartDrag = false; -#endif - const QTextCursor oldSelection = cursor; - setCursorPosition(pos); - QTextLine line = currentTextLine(cursor); - bool doEmit = false; - if (line.isValid() && line.textLength()) { - cursor.select(QTextCursor::WordUnderCursor); - doEmit = true; - } - repaintOldAndNewSelection(oldSelection); - - cursorIsFocusIndicator = false; - selectedWordOnDoubleClick = cursor; - - trippleClickPoint = pos; - trippleClickTimer.start(QApplication::doubleClickInterval(), q); - if (doEmit) { - selectionChanged(); -#ifndef QT_NO_CLIPBOARD - setClipboardSelection(); -#endif - emit q->cursorPositionChanged(); - } -} - -bool QTextControlPrivate::sendMouseEventToInputContext( - QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos, - Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos) -{ -#if !defined(QT_NO_IM) - Q_Q(QTextControl); - - QTextLayout *layout = cursor.block().layout(); - if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { - QInputContext *ctx = inputContext(); - int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position(); - - if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) { - cursorPos = -1; - // don't send move events outside the preedit area - if (eventType == QEvent::MouseMove) - return true; - } - if (ctx) { - QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos, - button, buttons, modifiers); - ctx->mouseHandler(cursorPos, &ev); - e->setAccepted(ev.isAccepted()); - } - if (!layout->preeditAreaText().isEmpty()) - return true; - } -#else - Q_UNUSED(e); - Q_UNUSED(eventType); - Q_UNUSED(button); - Q_UNUSED(pos); - Q_UNUSED(modifiers); - Q_UNUSED(buttons); - Q_UNUSED(globalPos); -#endif - return false; -} - -void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget) -{ -#ifdef QT_NO_CONTEXTMENU - Q_UNUSED(screenPos); - Q_UNUSED(docPos); - Q_UNUSED(contextWidget); -#else - Q_Q(QTextControl); - if (!hasFocus) - return; - QMenu *menu = q->createStandardContextMenu(docPos, contextWidget); - if (!menu) - return; - menu->setAttribute(Qt::WA_DeleteOnClose); - menu->popup(screenPos); -#endif -} - -bool QTextControlPrivate::dragEnterEvent(QEvent *e, const QMimeData *mimeData) -{ - Q_Q(QTextControl); - if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData)) { - e->ignore(); - return false; - } - - dndFeedbackCursor = QTextCursor(); - - return true; // accept proposed action -} - -void QTextControlPrivate::dragLeaveEvent() -{ - Q_Q(QTextControl); - - const QRectF crect = q->cursorRect(dndFeedbackCursor); - dndFeedbackCursor = QTextCursor(); - - if (crect.isValid()) - emit q->updateRequest(crect); -} - -bool QTextControlPrivate::dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos) -{ - Q_Q(QTextControl); - if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData)) { - e->ignore(); - return false; - } - - const int cursorPos = q->hitTest(pos, Qt::FuzzyHit); - if (cursorPos != -1) { - QRectF crect = q->cursorRect(dndFeedbackCursor); - if (crect.isValid()) - emit q->updateRequest(crect); - - dndFeedbackCursor = cursor; - dndFeedbackCursor.setPosition(cursorPos); - - crect = q->cursorRect(dndFeedbackCursor); - emit q->updateRequest(crect); - } - - return true; // accept proposed action -} - -bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source) -{ - Q_Q(QTextControl); - dndFeedbackCursor = QTextCursor(); - - if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData)) - return false; - - repaintSelection(); - - QTextCursor insertionCursor = q->cursorForPosition(pos); - insertionCursor.beginEditBlock(); - - if (dropAction == Qt::MoveAction && source == contextWidget) - cursor.removeSelectedText(); - - cursor = insertionCursor; - q->insertFromMimeData(mimeData); - insertionCursor.endEditBlock(); - q->ensureCursorVisible(); - return true; // accept proposed action -} - -void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) -{ - Q_Q(QTextControl); - if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) { - e->ignore(); - return; - } - bool isGettingInput = !e->commitString().isEmpty() - || e->preeditString() != cursor.block().layout()->preeditAreaText() - || e->replacementLength() > 0; - - cursor.beginEditBlock(); - if (isGettingInput) { - cursor.removeSelectedText(); - } - - // insert commit string - if (!e->commitString().isEmpty() || e->replacementLength()) { - QTextCursor c = cursor; - c.setPosition(c.position() + e->replacementStart()); - c.setPosition(c.position() + e->replacementLength(), QTextCursor::KeepAnchor); - c.insertText(e->commitString()); - } - - for (int i = 0; i < e->attributes().size(); ++i) { - const QInputMethodEvent::Attribute &a = e->attributes().at(i); - if (a.type == QInputMethodEvent::Selection) { - QTextCursor oldCursor = cursor; - int blockStart = a.start + cursor.block().position(); - cursor.setPosition(blockStart, QTextCursor::MoveAnchor); - cursor.setPosition(blockStart + a.length, QTextCursor::KeepAnchor); - q->ensureCursorVisible(); - repaintOldAndNewSelection(oldCursor); - } - } - - QTextBlock block = cursor.block(); - QTextLayout *layout = block.layout(); - if (isGettingInput) - layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); - QList<QTextLayout::FormatRange> overrides; - const int oldPreeditCursor = preeditCursor; - preeditCursor = e->preeditString().length(); - hideCursor = false; - for (int i = 0; i < e->attributes().size(); ++i) { - const QInputMethodEvent::Attribute &a = e->attributes().at(i); - if (a.type == QInputMethodEvent::Cursor) { - preeditCursor = a.start; - hideCursor = !a.length; - } else if (a.type == QInputMethodEvent::TextFormat) { - QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat(); - if (f.isValid()) { - QTextLayout::FormatRange o; - o.start = a.start + cursor.position() - block.position(); - o.length = a.length; - o.format = f; - overrides.append(o); - } - } - } - layout->setAdditionalFormats(overrides); - cursor.endEditBlock(); - if (cursor.d) - cursor.d->setX(); - if (oldPreeditCursor != preeditCursor) - emit q->microFocusChanged(); -} - -QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const -{ - Q_D(const QTextControl); - QTextBlock block = d->cursor.block(); - switch(property) { - case Qt::ImMicroFocus: - return cursorRect(); - case Qt::ImFont: - return QVariant(d->cursor.charFormat().font()); - case Qt::ImCursorPosition: - return QVariant(d->cursor.position() - block.position()); - case Qt::ImSurroundingText: - return QVariant(block.text()); - case Qt::ImCurrentSelection: - return QVariant(d->cursor.selectedText()); - case Qt::ImMaximumTextLength: - return QVariant(); // No limit. - case Qt::ImAnchorPosition: - return QVariant(qBound(0, d->cursor.anchor() - block.position(), block.length())); - default: - return QVariant(); - } -} - -void QTextControl::setFocus(bool focus, Qt::FocusReason reason) -{ - QFocusEvent ev(focus ? QEvent::FocusIn : QEvent::FocusOut, - reason); - processEvent(&ev); -} - -void QTextControlPrivate::focusEvent(QFocusEvent *e) -{ - Q_Q(QTextControl); - emit q->updateRequest(q->selectionRect()); - if (e->gotFocus()) { -#ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason -#ifdef Q_OS_SYMBIAN - || e->reason() == Qt::ActiveWindowFocusReason -#endif - ))) { -#endif - cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard); - if (interactionFlags & Qt::TextEditable) { - setBlinkingCursorEnabled(true); - } -#ifdef QT_KEYPAD_NAVIGATION - } -#endif - } else { - setBlinkingCursorEnabled(false); - - if (cursorIsFocusIndicator - && e->reason() != Qt::ActiveWindowFocusReason - && e->reason() != Qt::PopupFocusReason - && cursor.hasSelection()) { - cursor.clearSelection(); - } - } - hasFocus = e->gotFocus(); -} - -QString QTextControlPrivate::anchorForCursor(const QTextCursor &anchorCursor) const -{ - if (anchorCursor.hasSelection()) { - QTextCursor cursor = anchorCursor; - if (cursor.selectionStart() != cursor.position()) - cursor.setPosition(cursor.selectionStart()); - cursor.movePosition(QTextCursor::NextCharacter); - QTextCharFormat fmt = cursor.charFormat(); - if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref)) - return fmt.stringProperty(QTextFormat::AnchorHref); - } - return QString(); -} - -#ifdef QT_KEYPAD_NAVIGATION -void QTextControlPrivate::editFocusEvent(QEvent *e) -{ - Q_Q(QTextControl); - - if (QApplication::keypadNavigationEnabled()) { - if (e->type() == QEvent::EnterEditFocus && interactionFlags & Qt::TextEditable) { - const QTextCursor oldSelection = cursor; - const int oldCursorPos = cursor.position(); - const bool moved = cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - q->ensureCursorVisible(); - if (moved) { - if (cursor.position() != oldCursorPos) - emit q->cursorPositionChanged(); - emit q->microFocusChanged(); - } - selectionChanged(); - repaintOldAndNewSelection(oldSelection); - - setBlinkingCursorEnabled(true); - } else - setBlinkingCursorEnabled(false); - } - - hasEditFocus = e->type() == QEvent::EnterEditFocus ? true : false; -} -#endif - -#ifndef QT_NO_CONTEXTMENU -QMenu *QTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent) -{ - Q_D(QTextControl); - - const bool showTextSelectionActions = d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); - - d->linkToCopy = QString(); - if (!pos.isNull()) - d->linkToCopy = anchorAt(pos); - - if (d->linkToCopy.isEmpty() && !showTextSelectionActions) - return 0; - - QMenu *menu = new QMenu(parent); - QAction *a; - - if (d->interactionFlags & Qt::TextEditable) { - a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo())); - a->setEnabled(d->doc->isUndoAvailable()); - a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo())); - a->setEnabled(d->doc->isRedoAvailable()); - menu->addSeparator(); - - a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut())); - a->setEnabled(d->cursor.hasSelection()); - } - - if (showTextSelectionActions) { - a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy())); - a->setEnabled(d->cursor.hasSelection()); - } - - if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard) - || (d->interactionFlags & Qt::LinksAccessibleByMouse)) { - - a = menu->addAction(tr("Copy &Link Location"), this, SLOT(_q_copyLink())); - a->setEnabled(!d->linkToCopy.isEmpty()); - } - - if (d->interactionFlags & Qt::TextEditable) { -#if !defined(QT_NO_CLIPBOARD) - a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste())); - a->setEnabled(canPaste()); -#endif - a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected())); - a->setEnabled(d->cursor.hasSelection()); - } - - - if (showTextSelectionActions) { - menu->addSeparator(); - a = menu->addAction(tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll), this, SLOT(selectAll())); - a->setEnabled(!d->doc->isEmpty()); - } - -#if !defined(QT_NO_IM) - if (d->contextWidget) { - QInputContext *qic = d->inputContext(); - if (qic) { - QList<QAction *> imActions = qic->actions(); - for (int i = 0; i < imActions.size(); ++i) - menu->addAction(imActions.at(i)); - } - } -#endif - -#if defined(Q_WS_WIN) || defined(Q_WS_X11) - if ((d->interactionFlags & Qt::TextEditable) && qt_use_rtl_extensions) { -#else - if (d->interactionFlags & Qt::TextEditable) { -#endif - menu->addSeparator(); - QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, menu); - menu->addMenu(ctrlCharacterMenu); - } - - return menu; -} -#endif // QT_NO_CONTEXTMENU - -QTextCursor QTextControl::cursorForPosition(const QPointF &pos) const -{ - Q_D(const QTextControl); - int cursorPos = hitTest(pos, Qt::FuzzyHit); - if (cursorPos == -1) - cursorPos = 0; - QTextCursor c(d->doc); - c.setPosition(cursorPos); - return c; -} - -QRectF QTextControl::cursorRect(const QTextCursor &cursor) const -{ - Q_D(const QTextControl); - if (cursor.isNull()) - return QRectF(); - - return d->rectForPosition(cursor.position()); -} - -QRectF QTextControl::cursorRect() const -{ - Q_D(const QTextControl); - return cursorRect(d->cursor); -} - -QRectF QTextControlPrivate::cursorRectPlusUnicodeDirectionMarkers(const QTextCursor &cursor) const -{ - if (cursor.isNull()) - return QRectF(); - - return rectForPosition(cursor.position()).adjusted(-4, 0, 4, 0); -} - -QString QTextControl::anchorAt(const QPointF &pos) const -{ - Q_D(const QTextControl); - return d->doc->documentLayout()->anchorAt(pos); -} - -QString QTextControl::anchorAtCursor() const -{ - Q_D(const QTextControl); - - return d->anchorForCursor(d->cursor); -} - -bool QTextControl::overwriteMode() const -{ - Q_D(const QTextControl); - return d->overwriteMode; -} - -void QTextControl::setOverwriteMode(bool overwrite) -{ - Q_D(QTextControl); - d->overwriteMode = overwrite; -} - -int QTextControl::cursorWidth() const -{ -#ifndef QT_NO_PROPERTIES - Q_D(const QTextControl); - return d->doc->documentLayout()->property("cursorWidth").toInt(); -#else - return 1; -#endif -} - -void QTextControl::setCursorWidth(int width) -{ - Q_D(QTextControl); -#ifdef QT_NO_PROPERTIES - Q_UNUSED(width); -#else - if (width == -1) - width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth); - d->doc->documentLayout()->setProperty("cursorWidth", width); -#endif - d->repaintCursor(); -} - -bool QTextControl::acceptRichText() const -{ - Q_D(const QTextControl); - return d->acceptRichText; -} - -void QTextControl::setAcceptRichText(bool accept) -{ - Q_D(QTextControl); - d->acceptRichText = accept; -} - -#ifndef QT_NO_TEXTEDIT - -void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections) -{ - Q_D(QTextControl); - - QHash<int, int> hash; - for (int i = 0; i < d->extraSelections.count(); ++i) { - const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i); - hash.insertMulti(esel.cursor.anchor(), i); - } - - for (int i = 0; i < selections.count(); ++i) { - const QTextEdit::ExtraSelection &sel = selections.at(i); - QHash<int, int>::iterator it = hash.find(sel.cursor.anchor()); - if (it != hash.end()) { - const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value()); - if (esel.cursor.position() == sel.cursor.position() - && esel.format == sel.format) { - hash.erase(it); - continue; - } - } - QRectF r = selectionRect(sel.cursor); - if (sel.format.boolProperty(QTextFormat::FullWidthSelection)) { - r.setLeft(0); - r.setWidth(qreal(INT_MAX)); - } - emit updateRequest(r); - } - - for (QHash<int, int>::iterator it = hash.begin(); it != hash.end(); ++it) { - const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value()); - QRectF r = selectionRect(esel.cursor); - if (esel.format.boolProperty(QTextFormat::FullWidthSelection)) { - r.setLeft(0); - r.setWidth(qreal(INT_MAX)); - } - emit updateRequest(r); - } - - d->extraSelections.resize(selections.count()); - for (int i = 0; i < selections.count(); ++i) { - d->extraSelections[i].cursor = selections.at(i).cursor; - d->extraSelections[i].format = selections.at(i).format; - } -} - -QList<QTextEdit::ExtraSelection> QTextControl::extraSelections() const -{ - Q_D(const QTextControl); - QList<QTextEdit::ExtraSelection> selections; - for (int i = 0; i < d->extraSelections.count(); ++i) { - QTextEdit::ExtraSelection sel; - sel.cursor = d->extraSelections.at(i).cursor; - sel.format = d->extraSelections.at(i).format; - selections.append(sel); - } - return selections; -} - -#endif // QT_NO_TEXTEDIT - -void QTextControl::setTextWidth(qreal width) -{ - Q_D(QTextControl); - d->doc->setTextWidth(width); -} - -qreal QTextControl::textWidth() const -{ - Q_D(const QTextControl); - return d->doc->textWidth(); -} - -QSizeF QTextControl::size() const -{ - Q_D(const QTextControl); - return d->doc->size(); -} - -void QTextControl::setOpenExternalLinks(bool open) -{ - Q_D(QTextControl); - d->openExternalLinks = open; -} - -bool QTextControl::openExternalLinks() const -{ - Q_D(const QTextControl); - return d->openExternalLinks; -} - -bool QTextControl::ignoreUnusedNavigationEvents() const -{ - Q_D(const QTextControl); - return d->ignoreUnusedNavigationEvents; -} - -void QTextControl::setIgnoreUnusedNavigationEvents(bool ignore) -{ - Q_D(QTextControl); - d->ignoreUnusedNavigationEvents = ignore; -} - -void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode) -{ - Q_D(QTextControl); - const QTextCursor oldSelection = d->cursor; - const bool moved = d->cursor.movePosition(op, mode); - d->_q_updateCurrentCharFormatAndSelection(); - ensureCursorVisible(); - d->repaintOldAndNewSelection(oldSelection); - if (moved) - emit cursorPositionChanged(); -} - -bool QTextControl::canPaste() const -{ -#ifndef QT_NO_CLIPBOARD - Q_D(const QTextControl); - if (d->interactionFlags & Qt::TextEditable) { - const QMimeData *md = QApplication::clipboard()->mimeData(); - return md && canInsertFromMimeData(md); - } -#endif - return false; -} - -void QTextControl::setCursorIsFocusIndicator(bool b) -{ - Q_D(QTextControl); - d->cursorIsFocusIndicator = b; - d->repaintCursor(); -} - -bool QTextControl::cursorIsFocusIndicator() const -{ - Q_D(const QTextControl); - return d->cursorIsFocusIndicator; -} - - -void QTextControl::setDragEnabled(bool enabled) -{ - Q_D(QTextControl); - d->dragEnabled = enabled; -} - -bool QTextControl::isDragEnabled() const -{ - Q_D(const QTextControl); - return d->dragEnabled; -} - -void QTextControl::setWordSelectionEnabled(bool enabled) -{ - Q_D(QTextControl); - d->wordSelectionEnabled = enabled; -} - -bool QTextControl::isWordSelectionEnabled() const -{ - Q_D(const QTextControl); - return d->wordSelectionEnabled; -} - -#ifndef QT_NO_PRINTER -void QTextControl::print(QPrinter *printer) const -{ -#ifndef QT_NO_PRINTER - Q_D(const QTextControl); - if (!printer || !printer->isValid()) - return; - QTextDocument *tempDoc = 0; - const QTextDocument *doc = d->doc; - if (printer->printRange() == QPrinter::Selection) { - if (!d->cursor.hasSelection()) - return; - tempDoc = new QTextDocument(const_cast<QTextDocument *>(doc)); - tempDoc->setMetaInformation(QTextDocument::DocumentTitle, doc->metaInformation(QTextDocument::DocumentTitle)); - tempDoc->setPageSize(doc->pageSize()); - tempDoc->setDefaultFont(doc->defaultFont()); - tempDoc->setUseDesignMetrics(doc->useDesignMetrics()); - QTextCursor(tempDoc).insertFragment(d->cursor.selection()); - doc = tempDoc; - - // copy the custom object handlers - doc->documentLayout()->d_func()->handlers = d->doc->documentLayout()->d_func()->handlers; - } - doc->print(printer); - delete tempDoc; -#endif -} -#endif // QT_NO_PRINTER - -QMimeData *QTextControl::createMimeDataFromSelection() const -{ - Q_D(const QTextControl); - const QTextDocumentFragment fragment(d->cursor); - return new QTextEditMimeData(fragment); -} - -bool QTextControl::canInsertFromMimeData(const QMimeData *source) const -{ - Q_D(const QTextControl); - if (d->acceptRichText) - return (source->hasText() && !source->text().isEmpty()) - || source->hasHtml() - || source->hasFormat(QLatin1String("application/x-qrichtext")) - || source->hasFormat(QLatin1String("application/x-qt-richtext")); - else - return source->hasText() && !source->text().isEmpty(); -} - -void QTextControl::insertFromMimeData(const QMimeData *source) -{ - Q_D(QTextControl); - if (!(d->interactionFlags & Qt::TextEditable) || !source) - return; - - bool hasData = false; - QTextDocumentFragment fragment; -#ifndef QT_NO_TEXTHTMLPARSER - if (source->hasFormat(QLatin1String("application/x-qrichtext")) && d->acceptRichText) { - // x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore). - QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext"))); - richtext.prepend(QLatin1String("<meta name=\"qrichtext\" content=\"1\" />")); - fragment = QTextDocumentFragment::fromHtml(richtext, d->doc); - hasData = true; - } else if (source->hasHtml() && d->acceptRichText) { - fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc); - hasData = true; - } else { - QString text = source->text(); - if (!text.isNull()) { - fragment = QTextDocumentFragment::fromPlainText(text); - hasData = true; - } - } -#else - fragment = QTextDocumentFragment::fromPlainText(source->text()); -#endif // QT_NO_TEXTHTMLPARSER - - if (hasData) - d->cursor.insertFragment(fragment); - ensureCursorVisible(); -} - -bool QTextControl::findNextPrevAnchor(const QTextCursor &startCursor, bool next, QTextCursor &newAnchor) -{ - Q_D(QTextControl); - - int anchorStart = -1; - QString anchorHref; - int anchorEnd = -1; - - if (next) { - const int startPos = startCursor.selectionEnd(); - - QTextBlock block = d->doc->findBlock(startPos); - QTextBlock::Iterator it = block.begin(); - - while (!it.atEnd() && it.fragment().position() < startPos) - ++it; - - while (block.isValid()) { - anchorStart = -1; - - // find next anchor - for (; !it.atEnd(); ++it) { - const QTextFragment fragment = it.fragment(); - const QTextCharFormat fmt = fragment.charFormat(); - - if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref)) { - anchorStart = fragment.position(); - anchorHref = fmt.anchorHref(); - break; - } - } - - if (anchorStart != -1) { - anchorEnd = -1; - - // find next non-anchor fragment - for (; !it.atEnd(); ++it) { - const QTextFragment fragment = it.fragment(); - const QTextCharFormat fmt = fragment.charFormat(); - - if (!fmt.isAnchor() || fmt.anchorHref() != anchorHref) { - anchorEnd = fragment.position(); - break; - } - } - - if (anchorEnd == -1) - anchorEnd = block.position() + block.length() - 1; - - // make found selection - break; - } - - block = block.next(); - it = block.begin(); - } - } else { - int startPos = startCursor.selectionStart(); - if (startPos > 0) - --startPos; - - QTextBlock block = d->doc->findBlock(startPos); - QTextBlock::Iterator blockStart = block.begin(); - QTextBlock::Iterator it = block.end(); - - if (startPos == block.position()) { - it = block.begin(); - } else { - do { - if (it == blockStart) { - it = QTextBlock::Iterator(); - block = QTextBlock(); - } else { - --it; - } - } while (!it.atEnd() && it.fragment().position() + it.fragment().length() - 1 > startPos); - } - - while (block.isValid()) { - anchorStart = -1; - - if (!it.atEnd()) { - do { - const QTextFragment fragment = it.fragment(); - const QTextCharFormat fmt = fragment.charFormat(); - - if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref)) { - anchorStart = fragment.position() + fragment.length(); - anchorHref = fmt.anchorHref(); - break; - } - - if (it == blockStart) - it = QTextBlock::Iterator(); - else - --it; - } while (!it.atEnd()); - } - - if (anchorStart != -1 && !it.atEnd()) { - anchorEnd = -1; - - do { - const QTextFragment fragment = it.fragment(); - const QTextCharFormat fmt = fragment.charFormat(); - - if (!fmt.isAnchor() || fmt.anchorHref() != anchorHref) { - anchorEnd = fragment.position() + fragment.length(); - break; - } - - if (it == blockStart) - it = QTextBlock::Iterator(); - else - --it; - } while (!it.atEnd()); - - if (anchorEnd == -1) - anchorEnd = qMax(0, block.position()); - - break; - } - - block = block.previous(); - it = block.end(); - if (it != block.begin()) - --it; - blockStart = block.begin(); - } - - } - - if (anchorStart != -1 && anchorEnd != -1) { - newAnchor = d->cursor; - newAnchor.setPosition(anchorStart); - newAnchor.setPosition(anchorEnd, QTextCursor::KeepAnchor); - return true; - } - - return false; -} - -void QTextControlPrivate::activateLinkUnderCursor(QString href) -{ - QTextCursor oldCursor = cursor; - - if (href.isEmpty()) { - QTextCursor tmp = cursor; - if (tmp.selectionStart() != tmp.position()) - tmp.setPosition(tmp.selectionStart()); - tmp.movePosition(QTextCursor::NextCharacter); - href = tmp.charFormat().anchorHref(); - } - if (href.isEmpty()) - return; - - if (!cursor.hasSelection()) { - QTextBlock block = cursor.block(); - const int cursorPos = cursor.position(); - - QTextBlock::Iterator it = block.begin(); - QTextBlock::Iterator linkFragment; - - for (; !it.atEnd(); ++it) { - QTextFragment fragment = it.fragment(); - const int fragmentPos = fragment.position(); - if (fragmentPos <= cursorPos && - fragmentPos + fragment.length() > cursorPos) { - linkFragment = it; - break; - } - } - - if (!linkFragment.atEnd()) { - it = linkFragment; - cursor.setPosition(it.fragment().position()); - if (it != block.begin()) { - do { - --it; - QTextFragment fragment = it.fragment(); - if (fragment.charFormat().anchorHref() != href) - break; - cursor.setPosition(fragment.position()); - } while (it != block.begin()); - } - - for (it = linkFragment; !it.atEnd(); ++it) { - QTextFragment fragment = it.fragment(); - if (fragment.charFormat().anchorHref() != href) - break; - cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); - } - } - } - - if (hasFocus) { - cursorIsFocusIndicator = true; - } else { - cursorIsFocusIndicator = false; - cursor.clearSelection(); - } - repaintOldAndNewSelection(oldCursor); - -#ifndef QT_NO_DESKTOPSERVICES - if (openExternalLinks) - QDesktopServices::openUrl(href); - else -#endif - emit q_func()->linkActivated(href); -} - -#ifndef QT_NO_TOOLTIP -void QTextControlPrivate::showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget) -{ - const QString toolTip = q_func()->cursorForPosition(pos).charFormat().toolTip(); - if (toolTip.isEmpty()) - return; - QToolTip::showText(globalPos, toolTip, contextWidget); -} -#endif // QT_NO_TOOLTIP - -bool QTextControl::setFocusToNextOrPreviousAnchor(bool next) -{ - Q_D(QTextControl); - - if (!(d->interactionFlags & Qt::LinksAccessibleByKeyboard)) - return false; - - QRectF crect = selectionRect(); - emit updateRequest(crect); - - // If we don't have a current anchor, we start from the start/end - if (!d->cursor.hasSelection()) { - d->cursor = QTextCursor(d->doc); - if (next) - d->cursor.movePosition(QTextCursor::Start); - else - d->cursor.movePosition(QTextCursor::End); - } - - QTextCursor newAnchor; - if (findNextPrevAnchor(d->cursor, next, newAnchor)) { - d->cursor = newAnchor; - d->cursorIsFocusIndicator = true; - } else { - d->cursor.clearSelection(); - } - - if (d->cursor.hasSelection()) { - crect = selectionRect(); - emit updateRequest(crect); - emit visibilityRequest(crect); - return true; - } else { - return false; - } -} - -bool QTextControl::setFocusToAnchor(const QTextCursor &newCursor) -{ - Q_D(QTextControl); - - if (!(d->interactionFlags & Qt::LinksAccessibleByKeyboard)) - return false; - - // Verify that this is an anchor. - const QString anchorHref = d->anchorForCursor(newCursor); - if (anchorHref.isEmpty()) - return false; - - // and process it - QRectF crect = selectionRect(); - emit updateRequest(crect); - - d->cursor.setPosition(newCursor.selectionStart()); - d->cursor.setPosition(newCursor.selectionEnd(), QTextCursor::KeepAnchor); - d->cursorIsFocusIndicator = true; - - crect = selectionRect(); - emit updateRequest(crect); - emit visibilityRequest(crect); - return true; -} - -void QTextControl::setTextInteractionFlags(Qt::TextInteractionFlags flags) -{ - Q_D(QTextControl); - if (flags == d->interactionFlags) - return; - d->interactionFlags = flags; - - if (d->hasFocus) - d->setBlinkingCursorEnabled(flags & Qt::TextEditable); -} - -Qt::TextInteractionFlags QTextControl::textInteractionFlags() const -{ - Q_D(const QTextControl); - return d->interactionFlags; -} - -void QTextControl::mergeCurrentCharFormat(const QTextCharFormat &modifier) -{ - Q_D(QTextControl); - d->cursor.mergeCharFormat(modifier); - d->updateCurrentCharFormat(); -} - -void QTextControl::setCurrentCharFormat(const QTextCharFormat &format) -{ - Q_D(QTextControl); - d->cursor.setCharFormat(format); - d->updateCurrentCharFormat(); -} - -QTextCharFormat QTextControl::currentCharFormat() const -{ - Q_D(const QTextControl); - return d->cursor.charFormat(); -} - -void QTextControl::insertPlainText(const QString &text) -{ - Q_D(QTextControl); - d->cursor.insertText(text); -} - -#ifndef QT_NO_TEXTHTMLPARSER -void QTextControl::insertHtml(const QString &text) -{ - Q_D(QTextControl); - d->cursor.insertHtml(text); -} -#endif // QT_NO_TEXTHTMLPARSER - -QPointF QTextControl::anchorPosition(const QString &name) const -{ - Q_D(const QTextControl); - if (name.isEmpty()) - return QPointF(); - - QRectF r; - for (QTextBlock block = d->doc->begin(); block.isValid(); block = block.next()) { - QTextCharFormat format = block.charFormat(); - if (format.isAnchor() && format.anchorNames().contains(name)) { - r = d->rectForPosition(block.position()); - break; - } - - for (QTextBlock::Iterator it = block.begin(); !it.atEnd(); ++it) { - QTextFragment fragment = it.fragment(); - format = fragment.charFormat(); - if (format.isAnchor() && format.anchorNames().contains(name)) { - r = d->rectForPosition(fragment.position()); - block = QTextBlock(); - break; - } - } - } - if (!r.isValid()) - return QPointF(); - return QPointF(0, r.top()); -} - -void QTextControl::adjustSize() -{ - Q_D(QTextControl); - d->doc->adjustSize(); -} - -bool QTextControl::find(const QString &exp, QTextDocument::FindFlags options) -{ - Q_D(QTextControl); - QTextCursor search = d->doc->find(exp, d->cursor, options); - if (search.isNull()) - return false; - - setTextCursor(search); - return true; -} - - - -void QTextControlPrivate::append(const QString &text, Qt::TextFormat format) -{ - QTextCursor tmp(doc); - tmp.beginEditBlock(); - tmp.movePosition(QTextCursor::End); - - if (!doc->isEmpty()) - tmp.insertBlock(cursor.blockFormat(), cursor.charFormat()); - else - tmp.setCharFormat(cursor.charFormat()); - - // preserve the char format - QTextCharFormat oldCharFormat = cursor.charFormat(); - -#ifndef QT_NO_TEXTHTMLPARSER - if (format == Qt::RichText || (format == Qt::AutoText && Qt::mightBeRichText(text))) { - tmp.insertHtml(text); - } else { - tmp.insertText(text); - } -#else - tmp.insertText(text); -#endif // QT_NO_TEXTHTMLPARSER - if (!cursor.hasSelection()) - cursor.setCharFormat(oldCharFormat); - - tmp.endEditBlock(); -} - -void QTextControl::append(const QString &text) -{ - Q_D(QTextControl); - d->append(text, Qt::AutoText); -} - -void QTextControl::appendHtml(const QString &html) -{ - Q_D(QTextControl); - d->append(html, Qt::RichText); -} - -void QTextControl::appendPlainText(const QString &text) -{ - Q_D(QTextControl); - d->append(text, Qt::PlainText); -} - - -void QTextControl::ensureCursorVisible() -{ - Q_D(QTextControl); - QRectF crect = d->rectForPosition(d->cursor.position()).adjusted(-5, 0, 5, 0); - emit visibilityRequest(crect); - emit microFocusChanged(); -} - -QPalette QTextControl::palette() const -{ - Q_D(const QTextControl); - return d->palette; -} - -void QTextControl::setPalette(const QPalette &pal) -{ - Q_D(QTextControl); - d->palette = pal; -} - -QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget *widget) const -{ - Q_D(const QTextControl); - - QAbstractTextDocumentLayout::PaintContext ctx; - - ctx.selections = d->extraSelections; - ctx.palette = d->palette; - if (d->cursorOn && d->isEnabled) { - if (d->hideCursor) - ctx.cursorPosition = -1; - else if (d->preeditCursor != 0) - ctx.cursorPosition = - (d->preeditCursor + 2); - else - ctx.cursorPosition = d->cursor.position(); - } - - if (!d->dndFeedbackCursor.isNull()) - ctx.cursorPosition = d->dndFeedbackCursor.position(); -#ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || d->hasEditFocus) -#endif - if (d->cursor.hasSelection()) { - QAbstractTextDocumentLayout::Selection selection; - selection.cursor = d->cursor; - if (d->cursorIsFocusIndicator) { - QStyleOption opt; - opt.palette = ctx.palette; - QStyleHintReturnVariant ret; - QStyle *style = QApplication::style(); - if (widget) - style = widget->style(); - style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret); - selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat(); - } else { - QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive; - selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight)); - selection.format.setForeground(ctx.palette.brush(cg, QPalette::HighlightedText)); - QStyleOption opt; - QStyle *style = QApplication::style(); - if (widget) { - opt.initFrom(widget); - style = widget->style(); - } - if (style->styleHint(QStyle::SH_RichText_FullWidthSelection, &opt, widget)) - selection.format.setProperty(QTextFormat::FullWidthSelection, true); - } - ctx.selections.append(selection); - } - - return ctx; -} - -void QTextControl::drawContents(QPainter *p, const QRectF &rect, QWidget *widget) -{ - Q_D(QTextControl); - p->save(); - QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext(widget); - if (rect.isValid()) - p->setClipRect(rect, Qt::IntersectClip); - ctx.clip = rect; - - d->doc->documentLayout()->draw(p, ctx); - p->restore(); -} - -void QTextControlPrivate::_q_copyLink() -{ -#ifndef QT_NO_CLIPBOARD - QMimeData *md = new QMimeData; - md->setText(linkToCopy); - QApplication::clipboard()->setMimeData(md); -#endif -} - -QInputContext *QTextControlPrivate::inputContext() -{ - QInputContext *ctx = contextWidget->inputContext(); - if (!ctx && contextWidget->parentWidget()) - ctx = contextWidget->parentWidget()->inputContext(); - return ctx; -} - -int QTextControl::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const -{ - Q_D(const QTextControl); - return d->doc->documentLayout()->hitTest(point, accuracy); -} - -QRectF QTextControl::blockBoundingRect(const QTextBlock &block) const -{ - Q_D(const QTextControl); - return d->doc->documentLayout()->blockBoundingRect(block); -} - -#ifndef QT_NO_CONTEXTMENU -#define NUM_CONTROL_CHARACTERS 10 -const struct QUnicodeControlCharacter { - const char *text; - ushort character; -} qt_controlCharacters[NUM_CONTROL_CHARACTERS] = { - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRM Left-to-right mark"), 0x200e }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLM Right-to-left mark"), 0x200f }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWJ Zero width joiner"), 0x200d }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWNJ Zero width non-joiner"), 0x200c }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWSP Zero width space"), 0x200b }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRE Start of left-to-right embedding"), 0x202a }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLE Start of right-to-left embedding"), 0x202b }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e }, - { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c }, -}; - -QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent) - : QMenu(parent), editWidget(_editWidget) -{ - setTitle(tr("Insert Unicode control character")); - for (int i = 0; i < NUM_CONTROL_CHARACTERS; ++i) { - addAction(tr(qt_controlCharacters[i].text), this, SLOT(menuActionTriggered())); - } -} - -void QUnicodeControlCharacterMenu::menuActionTriggered() -{ - QAction *a = qobject_cast<QAction *>(sender()); - int idx = actions().indexOf(a); - if (idx < 0 || idx >= NUM_CONTROL_CHARACTERS) - return; - QChar c(qt_controlCharacters[idx].character); - QString str(c); - -#ifndef QT_NO_TEXTEDIT - if (QTextEdit *edit = qobject_cast<QTextEdit *>(editWidget)) { - edit->insertPlainText(str); - return; - } -#endif - if (QTextControl *control = qobject_cast<QTextControl *>(editWidget)) { - control->insertPlainText(str); - } -#ifndef QT_NO_LINEEDIT - if (QLineEdit *edit = qobject_cast<QLineEdit *>(editWidget)) { - edit->insert(str); - return; - } -#endif -} -#endif // QT_NO_CONTEXTMENU - -QStringList QTextEditMimeData::formats() const -{ - if (!fragment.isEmpty()) - return QStringList() << QString::fromLatin1("text/plain") << QString::fromLatin1("text/html") -#ifndef QT_NO_TEXTODFWRITER - << QString::fromLatin1("application/vnd.oasis.opendocument.text") -#endif - ; - else - return QMimeData::formats(); -} - -QVariant QTextEditMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const -{ - if (!fragment.isEmpty()) - setup(); - return QMimeData::retrieveData(mimeType, type); -} - -void QTextEditMimeData::setup() const -{ - QTextEditMimeData *that = const_cast<QTextEditMimeData *>(this); -#ifndef QT_NO_TEXTHTMLPARSER - that->setData(QLatin1String("text/html"), fragment.toHtml("utf-8").toUtf8()); -#endif -#ifndef QT_NO_TEXTODFWRITER - { - QBuffer buffer; - QTextDocumentWriter writer(&buffer, "ODF"); - writer.write(fragment); - buffer.close(); - that->setData(QLatin1String("application/vnd.oasis.opendocument.text"), buffer.data()); - } -#endif - that->setText(fragment.toPlainText()); - fragment = QTextDocumentFragment(); -} - -QT_END_NAMESPACE - -#include "moc_qtextcontrol_p.cpp" - -#endif // QT_NO_TEXTCONTROL diff --git a/src/gui/to_be_moved/qtextcontrol_p.h b/src/gui/to_be_moved/qtextcontrol_p.h deleted file mode 100644 index dce0ca90a5..0000000000 --- a/src/gui/to_be_moved/qtextcontrol_p.h +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTEXTCONTROL_P_H -#define QTEXTCONTROL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/qtextdocument.h> -#include <QtGui/qtextoption.h> -#include <QtGui/qtextcursor.h> -#include <QtGui/qtextformat.h> -#include <QtGui/qtextedit.h> -#include <QtGui/qmenu.h> -#include <QtCore/qrect.h> -#include <QtGui/qabstracttextdocumentlayout.h> -#include <QtGui/qtextdocumentfragment.h> -#include <QtGui/qclipboard.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QStyleSheet; -class QTextDocument; -class QMenu; -class QTextControlPrivate; -class QMimeData; -class QAbstractScrollArea; -class QEvent; -class QTimerEvent; - -class Q_GUI_EXPORT QTextControl : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QTextControl) -#ifndef QT_NO_TEXTHTMLPARSER - Q_PROPERTY(QString html READ toHtml WRITE setHtml NOTIFY textChanged USER true) -#endif - Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) - Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText) - Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth) - Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) - Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks) - Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents WRITE setIgnoreUnusedNavigationEvents) -public: - explicit QTextControl(QObject *parent = 0); - explicit QTextControl(const QString &text, QObject *parent = 0); - explicit QTextControl(QTextDocument *doc, QObject *parent = 0); - virtual ~QTextControl(); - - void setDocument(QTextDocument *document); - QTextDocument *document() const; - - void setTextCursor(const QTextCursor &cursor); - QTextCursor textCursor() const; - - void setTextInteractionFlags(Qt::TextInteractionFlags flags); - Qt::TextInteractionFlags textInteractionFlags() const; - - void mergeCurrentCharFormat(const QTextCharFormat &modifier); - - void setCurrentCharFormat(const QTextCharFormat &format); - QTextCharFormat currentCharFormat() const; - - bool find(const QString &exp, QTextDocument::FindFlags options = 0); - - inline QString toPlainText() const - { return document()->toPlainText(); } -#ifndef QT_NO_TEXTHTMLPARSER - inline QString toHtml() const - { return document()->toHtml(); } -#endif - - virtual void ensureCursorVisible(); - - virtual QVariant loadResource(int type, const QUrl &name); -#ifndef QT_NO_CONTEXTMENU - QMenu *createStandardContextMenu(const QPointF &pos, QWidget *parent); -#endif - - QTextCursor cursorForPosition(const QPointF &pos) const; - QRectF cursorRect(const QTextCursor &cursor) const; - QRectF cursorRect() const; - QRectF selectionRect(const QTextCursor &cursor) const; - QRectF selectionRect() const; - - QString anchorAt(const QPointF &pos) const; - QPointF anchorPosition(const QString &name) const; - - QString anchorAtCursor() const; - - bool overwriteMode() const; - void setOverwriteMode(bool overwrite); - - int cursorWidth() const; - void setCursorWidth(int width); - - bool acceptRichText() const; - void setAcceptRichText(bool accept); - -#ifndef QT_NO_TEXTEDIT - void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections); - QList<QTextEdit::ExtraSelection> extraSelections() const; -#endif - - void setTextWidth(qreal width); - qreal textWidth() const; - QSizeF size() const; - - void setOpenExternalLinks(bool open); - bool openExternalLinks() const; - - void setIgnoreUnusedNavigationEvents(bool ignore); - bool ignoreUnusedNavigationEvents() const; - - void moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor); - - bool canPaste() const; - - void setCursorIsFocusIndicator(bool b); - bool cursorIsFocusIndicator() const; - - void setDragEnabled(bool enabled); - bool isDragEnabled() const; - - bool isWordSelectionEnabled() const; - void setWordSelectionEnabled(bool enabled); - -#ifndef QT_NO_PRINTER - void print(QPrinter *printer) const; -#endif - - virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const; - virtual QRectF blockBoundingRect(const QTextBlock &block) const; - QAbstractTextDocumentLayout::PaintContext getPaintContext(QWidget *widget) const; - -public Q_SLOTS: - void setPlainText(const QString &text); - void setHtml(const QString &text); - -#ifndef QT_NO_CLIPBOARD - void cut(); - void copy(); - void paste(QClipboard::Mode mode = QClipboard::Clipboard); -#endif - - void undo(); - void redo(); - - void clear(); - void selectAll(); - - void insertPlainText(const QString &text); -#ifndef QT_NO_TEXTHTMLPARSER - void insertHtml(const QString &text); -#endif - - void append(const QString &text); - void appendHtml(const QString &html); - void appendPlainText(const QString &text); - - void adjustSize(); - -Q_SIGNALS: - void textChanged(); - void undoAvailable(bool b); - void redoAvailable(bool b); - void currentCharFormatChanged(const QTextCharFormat &format); - void copyAvailable(bool b); - void selectionChanged(); - void cursorPositionChanged(); - - // control signals - void updateRequest(const QRectF &rect = QRectF()); - void documentSizeChanged(const QSizeF &); - void blockCountChanged(int newBlockCount); - void visibilityRequest(const QRectF &rect); - void microFocusChanged(); - void linkActivated(const QString &link); - void linkHovered(const QString &); - void modificationChanged(bool m); - -public: - // control properties - QPalette palette() const; - void setPalette(const QPalette &pal); - - virtual void processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget = 0); - void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF(), QWidget *contextWidget = 0); - - // control methods - void drawContents(QPainter *painter, const QRectF &rect = QRectF(), QWidget *widget = 0); - - void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason); - - virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; - - virtual QMimeData *createMimeDataFromSelection() const; - virtual bool canInsertFromMimeData(const QMimeData *source) const; - virtual void insertFromMimeData(const QMimeData *source); - - bool setFocusToAnchor(const QTextCursor &newCursor); - bool setFocusToNextOrPreviousAnchor(bool next); - bool findNextPrevAnchor(const QTextCursor& from, bool next, QTextCursor& newAnchor); - -protected: - virtual void timerEvent(QTimerEvent *e); - - virtual bool event(QEvent *e); - -private: - Q_DISABLE_COPY(QTextControl) - Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection()) - Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &)) - Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected()) - Q_PRIVATE_SLOT(d_func(), void _q_copyLink()) - Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &)) - Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged()) -}; - - -#ifndef QT_NO_CONTEXTMENU -class QUnicodeControlCharacterMenu : public QMenu -{ - Q_OBJECT -public: - QUnicodeControlCharacterMenu(QObject *editWidget, QWidget *parent); - -private Q_SLOTS: - void menuActionTriggered(); - -private: - QObject *editWidget; -}; -#endif // QT_NO_CONTEXTMENU - - -// also used by QLabel -class QTextEditMimeData : public QMimeData -{ -public: - inline QTextEditMimeData(const QTextDocumentFragment &aFragment) : fragment(aFragment) {} - - virtual QStringList formats() const; -protected: - virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; -private: - void setup() const; - - mutable QTextDocumentFragment fragment; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QTEXTCONTROL_H diff --git a/src/gui/to_be_moved/qtextcontrol_p_p.h b/src/gui/to_be_moved/qtextcontrol_p_p.h deleted file mode 100644 index 94670e225e..0000000000 --- a/src/gui/to_be_moved/qtextcontrol_p_p.h +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTEXTCONTROL_P_P_H -#define QTEXTCONTROL_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qtextdocumentfragment.h" -#include "QtGui/qscrollbar.h" -#include "QtGui/qtextcursor.h" -#include "QtGui/qtextformat.h" -#include "QtGui/qmenu.h" -#include "QtGui/qabstracttextdocumentlayout.h" -#include "QtCore/qbasictimer.h" -#include "QtCore/qpointer.h" -#include "private/qobject_p.h" - -QT_BEGIN_NAMESPACE - -class QMimeData; -class QAbstractScrollArea; -class QInputContext; - -class QTextControlPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QTextControl) -public: - QTextControlPrivate(); - - bool cursorMoveKeyEvent(QKeyEvent *e); - - void updateCurrentCharFormat(); - - void indent(); - void outdent(); - - void gotoNextTableCell(); - void gotoPreviousTableCell(); - - void createAutoBulletList(); - - void init(Qt::TextFormat format = Qt::RichText, const QString &text = QString(), - QTextDocument *document = 0); - void setContent(Qt::TextFormat format = Qt::RichText, const QString &text = QString(), - QTextDocument *document = 0); - void startDrag(); - - void paste(const QMimeData *source); - - void setCursorPosition(const QPointF &pos); - void setCursorPosition(int pos, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor); - - void repaintCursor(); - inline void repaintSelection() - { repaintOldAndNewSelection(QTextCursor()); } - void repaintOldAndNewSelection(const QTextCursor &oldSelection); - - void selectionChanged(bool forceEmitSelectionChanged = false); - - void _q_updateCurrentCharFormatAndSelection(); - -#ifndef QT_NO_CLIPBOARD - void setClipboardSelection(); -#endif - - void _q_emitCursorPosChanged(const QTextCursor &someCursor); - - void setBlinkingCursorEnabled(bool enable); - - void extendWordwiseSelection(int suggestedNewPosition, qreal mouseXPosition); - void extendBlockwiseSelection(int suggestedNewPosition); - - void _q_deleteSelected(); - - void _q_setCursorAfterUndoRedo(int undoPosition, int charsAdded, int charsRemoved); - - QRectF cursorRectPlusUnicodeDirectionMarkers(const QTextCursor &cursor) const; - QRectF rectForPosition(int position) const; - QRectF selectionRect(const QTextCursor &cursor) const; - inline QRectF selectionRect() const - { return selectionRect(this->cursor); } - - QString anchorForCursor(const QTextCursor &anchor) const; - - void keyPressEvent(QKeyEvent *e); - void mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, - Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, - const QPoint &globalPos); - void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, - Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, - const QPoint &globalPos); - void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, - Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, - const QPoint &globalPos); - void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, - Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, - const QPoint &globalPos); - bool sendMouseEventToInputContext(QEvent *e, QEvent::Type eventType, Qt::MouseButton button, - const QPointF &pos, - Qt::KeyboardModifiers modifiers, - Qt::MouseButtons buttons, - const QPoint &globalPos); - void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget); - void focusEvent(QFocusEvent *e); -#ifdef QT_KEYPAD_NAVIGATION - void editFocusEvent(QEvent *e); -#endif - bool dragEnterEvent(QEvent *e, const QMimeData *mimeData); - void dragLeaveEvent(); - bool dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos); - bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source); - - void inputMethodEvent(QInputMethodEvent *); - - void activateLinkUnderCursor(QString href = QString()); - -#ifndef QT_NO_TOOLTIP - void showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget); -#endif - - void append(const QString &text, Qt::TextFormat format = Qt::AutoText); - - QInputContext *inputContext(); - - QTextDocument *doc; - bool cursorOn; - QTextCursor cursor; - bool cursorIsFocusIndicator; - QTextCharFormat lastCharFormat; - - QTextCursor dndFeedbackCursor; - - Qt::TextInteractionFlags interactionFlags; - - QBasicTimer cursorBlinkTimer; - QBasicTimer trippleClickTimer; - QPointF trippleClickPoint; - - bool dragEnabled; - - bool mousePressed; - - bool mightStartDrag; - QPoint dragStartPos; - QPointer<QWidget> contextWidget; - - bool lastSelectionState; - - bool ignoreAutomaticScrollbarAdjustement; - - QTextCursor selectedWordOnDoubleClick; - QTextCursor selectedBlockOnTrippleClick; - - bool overwriteMode; - bool acceptRichText; - - int preeditCursor; - bool hideCursor; // used to hide the cursor in the preedit area - - QVector<QAbstractTextDocumentLayout::Selection> extraSelections; - - QPalette palette; - bool hasFocus; -#ifdef QT_KEYPAD_NAVIGATION - bool hasEditFocus; -#endif - bool isEnabled; - - QString highlightedAnchor; // Anchor below cursor - QString anchorOnMousePress; - bool hadSelectionOnMousePress; - - bool ignoreUnusedNavigationEvents; - bool openExternalLinks; - - bool wordSelectionEnabled; - - QString linkToCopy; - void _q_copyLink(); - void _q_updateBlock(const QTextBlock &); - void _q_documentLayoutChanged(); -}; - -QT_END_NAMESPACE - -#endif // QTEXTCONTROL_P_H diff --git a/src/gui/to_be_moved/to_be_moved.pri b/src/gui/to_be_moved/to_be_moved.pri deleted file mode 100644 index d09c568c69..0000000000 --- a/src/gui/to_be_moved/to_be_moved.pri +++ /dev/null @@ -1,17 +0,0 @@ -HEADERS += \ - to_be_moved/qlinecontrol_p.h \ - to_be_moved/qtextcontrol_p.h \ - to_be_moved/qtextcontrol_p_p.h \ - to_be_moved/qshortcut.h \ - to_be_moved/qshortcutmap_p.h \ - to_be_moved/qdrag.h \ - to_be_moved/qdnd_p.h \ - -SOURCES += \ - to_be_moved/qlinecontrol.cpp \ - to_be_moved/qtextcontrol.cpp \ - to_be_moved/qshortcut.cpp \ - to_be_moved/qshortcutmap.cpp \ - to_be_moved/qdrag.cpp \ - to_be_moved/qdnd.cpp \ - to_be_moved/qdnd_qpa.cpp \ |