summaryrefslogtreecommitdiffstats
path: root/src/gui/util
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2011-05-07 00:02:01 +0200
committerLars Knoll <lars.knoll@nokia.com>2011-05-07 00:02:01 +0200
commitf67b8df3ebdba2d398b9cce686b7c644adffff08 (patch)
tree062dd469f7cf8daa01a32d3e7b767b8fbdb7573a /src/gui/util
parent32ce4fe9e6a94e77828e976776cf08da85254ff2 (diff)
library split
Diffstat (limited to 'src/gui/util')
-rw-r--r--src/gui/util/qcompleter.cpp1833
-rw-r--r--src/gui/util/qcompleter.h171
-rw-r--r--src/gui/util/qcompleter_p.h264
-rw-r--r--src/gui/util/qflickgesture.cpp715
-rw-r--r--src/gui/util/qflickgesture_p.h113
-rw-r--r--src/gui/util/qscroller.cpp2059
-rw-r--r--src/gui/util/qscroller.h155
-rw-r--r--src/gui/util/qscroller_mac.mm71
-rw-r--r--src/gui/util/qscroller_p.h209
-rw-r--r--src/gui/util/qscrollerproperties.cpp393
-rw-r--r--src/gui/util/qscrollerproperties.h140
-rw-r--r--src/gui/util/qscrollerproperties_p.h94
-rw-r--r--src/gui/util/qsystemtrayicon.cpp674
-rw-r--r--src/gui/util/qsystemtrayicon.h132
-rw-r--r--src/gui/util/qsystemtrayicon_mac.mm578
-rw-r--r--src/gui/util/qsystemtrayicon_p.h186
-rw-r--r--src/gui/util/qsystemtrayicon_qpa.cpp96
-rw-r--r--src/gui/util/qsystemtrayicon_win.cpp524
-rw-r--r--src/gui/util/qsystemtrayicon_wince.cpp293
-rw-r--r--src/gui/util/qsystemtrayicon_x11.cpp401
-rw-r--r--src/gui/util/qundogroup.cpp499
-rw-r--r--src/gui/util/qundogroup.h110
-rw-r--r--src/gui/util/qundostack.cpp1127
-rw-r--r--src/gui/util/qundostack.h158
-rw-r--r--src/gui/util/qundostack_p.h111
-rw-r--r--src/gui/util/qundoview.cpp476
-rw-r--r--src/gui/util/qundoview.h102
-rw-r--r--src/gui/util/util.pri69
28 files changed, 0 insertions, 11753 deletions
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
deleted file mode 100644
index 0cb3bbdf8c..0000000000
--- a/src/gui/util/qcompleter.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$
-**
-****************************************************************************/
-
-/*!
- \class QCompleter
- \brief The QCompleter class provides completions based on an item model.
- \since 4.2
-
- You can use QCompleter to provide auto completions in any Qt
- widget, such as QLineEdit and QComboBox.
- When the user starts typing a word, QCompleter suggests possible ways of
- completing the word, based on a word list. The word list is
- provided as a QAbstractItemModel. (For simple applications, where
- the word list is static, you can pass a QStringList to
- QCompleter's constructor.)
-
- \tableofcontents
-
- \section1 Basic Usage
-
- A QCompleter is used typically with a QLineEdit or QComboBox.
- For example, here's how to provide auto completions from a simple
- word list in a QLineEdit:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 0
-
- A QFileSystemModel can be used to provide auto completion of file names.
- For example:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 1
-
- To set the model on which QCompleter should operate, call
- setModel(). By default, QCompleter will attempt to match the \l
- {completionPrefix}{completion prefix} (i.e., the word that the
- user has started typing) against the Qt::EditRole data stored in
- column 0 in the model case sensitively. This can be changed
- using setCompletionRole(), setCompletionColumn(), and
- setCaseSensitivity().
-
- If the model is sorted on the column and role that are used for completion,
- you can call setModelSorting() with either
- QCompleter::CaseSensitivelySortedModel or
- QCompleter::CaseInsensitivelySortedModel as the argument. On large models,
- this can lead to significant performance improvements, because QCompleter
- can then use binary search instead of linear search.
-
- The model can be a \l{QAbstractListModel}{list model},
- a \l{QAbstractTableModel}{table model}, or a
- \l{QAbstractItemModel}{tree model}. Completion on tree models
- is slightly more involved and is covered in the \l{Handling
- Tree Models} section below.
-
- The completionMode() determines the mode used to provide completions to
- the user.
-
- \section1 Iterating Through Completions
-
- To retrieve a single candidate string, call setCompletionPrefix()
- with the text that needs to be completed and call
- currentCompletion(). You can iterate through the list of
- completions as below:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 2
-
- completionCount() returns the total number of completions for the
- current prefix. completionCount() should be avoided when possible,
- since it requires a scan of the entire model.
-
- \section1 The Completion Model
-
- completionModel() return a list model that contains all possible
- completions for the current completion prefix, in the order in which
- they appear in the model. This model can be used to display the current
- completions in a custom view. Calling setCompletionPrefix() automatically
- refreshes the completion model.
-
- \section1 Handling Tree Models
-
- QCompleter can look for completions in tree models, assuming
- that any item (or sub-item or sub-sub-item) can be unambiguously
- represented as a string by specifying the path to the item. The
- completion is then performed one level at a time.
-
- Let's take the example of a user typing in a file system path.
- The model is a (hierarchical) QFileSystemModel. The completion
- occurs for every element in the path. For example, if the current
- text is \c C:\Wind, QCompleter might suggest \c Windows to
- complete the current path element. Similarly, if the current text
- is \c C:\Windows\Sy, QCompleter might suggest \c System.
-
- For this kind of completion to work, QCompleter needs to be able to
- split the path into a list of strings that are matched at each level.
- For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy".
- The default implementation of splitPath(), splits the completionPrefix
- using QDir::separator() if the model is a QFileSystemModel.
-
- To provide completions, QCompleter needs to know the path from an index.
- This is provided by pathFromIndex(). The default implementation of
- pathFromIndex(), returns the data for the \l{Qt::EditRole}{edit role}
- for list models and the absolute file path if the mode is a QFileSystemModel.
-
- \sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example}
-*/
-
-#include "qcompleter_p.h"
-
-#ifndef QT_NO_COMPLETER
-
-#include "QtGui/qscrollbar.h"
-#include "QtGui/qstringlistmodel.h"
-#include "QtGui/qdirmodel.h"
-#include "QtGui/qfilesystemmodel.h"
-#include "QtGui/qheaderview.h"
-#include "QtGui/qlistview.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/qevent.h"
-#include "QtGui/qheaderview.h"
-#include "QtGui/qdesktopwidget.h"
-#include "QtGui/qlineedit.h"
-
-QT_BEGIN_NAMESPACE
-
-QCompletionModel::QCompletionModel(QCompleterPrivate *c, QObject *parent)
- : QAbstractProxyModel(*new QCompletionModelPrivate, parent),
- c(c), showAll(false)
-{
- createEngine();
-}
-
-int QCompletionModel::columnCount(const QModelIndex &) const
-{
- Q_D(const QCompletionModel);
- return d->model->columnCount();
-}
-
-void QCompletionModel::setSourceModel(QAbstractItemModel *source)
-{
- bool hadModel = (sourceModel() != 0);
-
- if (hadModel)
- QObject::disconnect(sourceModel(), 0, this, 0);
-
- QAbstractProxyModel::setSourceModel(source);
-
- if (source) {
- // TODO: Optimize updates in the source model
- connect(source, SIGNAL(modelReset()), this, SLOT(invalidate()));
- connect(source, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));
- connect(source, SIGNAL(layoutChanged()), this, SLOT(invalidate()));
- connect(source, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted()));
- connect(source, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate()));
- }
-
- invalidate();
-}
-
-void QCompletionModel::createEngine()
-{
- bool sortedEngine = false;
- switch (c->sorting) {
- case QCompleter::UnsortedModel:
- sortedEngine = false;
- break;
- case QCompleter::CaseSensitivelySortedModel:
- sortedEngine = c->cs == Qt::CaseSensitive;
- break;
- case QCompleter::CaseInsensitivelySortedModel:
- sortedEngine = c->cs == Qt::CaseInsensitive;
- break;
- }
-
- if (sortedEngine)
- engine.reset(new QSortedModelEngine(c));
- else
- engine.reset(new QUnsortedModelEngine(c));
-}
-
-QModelIndex QCompletionModel::mapToSource(const QModelIndex& index) const
-{
- Q_D(const QCompletionModel);
- if (!index.isValid())
- return engine->curParent;
-
- int row;
- QModelIndex parent = engine->curParent;
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
- Q_ASSERT(index.row() < engine->matchCount());
- QIndexMapper& rootIndices = engine->historyMatch.indices;
- if (index.row() < rootIndices.count()) {
- row = rootIndices[index.row()];
- parent = QModelIndex();
- } else {
- row = engine->curMatch.indices[index.row() - rootIndices.count()];
- }
- } else {
- row = index.row();
- }
-
- return d->model->index(row, index.column(), parent);
-}
-
-QModelIndex QCompletionModel::mapFromSource(const QModelIndex& idx) const
-{
- if (!idx.isValid())
- return QModelIndex();
-
- int row = -1;
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
-
- QIndexMapper& rootIndices = engine->historyMatch.indices;
- if (idx.parent().isValid()) {
- if (idx.parent() != engine->curParent)
- return QModelIndex();
- } else {
- row = rootIndices.indexOf(idx.row());
- if (row == -1 && engine->curParent.isValid())
- return QModelIndex(); // source parent and our parent don't match
- }
-
- if (row == -1) {
- QIndexMapper& indices = engine->curMatch.indices;
- engine->filterOnDemand(idx.row() - indices.last());
- row = indices.indexOf(idx.row()) + rootIndices.count();
- }
-
- if (row == -1)
- return QModelIndex();
- } else {
- if (idx.parent() != engine->curParent)
- return QModelIndex();
- row = idx.row();
- }
-
- return createIndex(row, idx.column());
-}
-
-bool QCompletionModel::setCurrentRow(int row)
-{
- if (row < 0 || !engine->matchCount())
- return false;
-
- if (row >= engine->matchCount())
- engine->filterOnDemand(row + 1 - engine->matchCount());
-
- if (row >= engine->matchCount()) // invalid row
- return false;
-
- engine->curRow = row;
- return true;
-}
-
-QModelIndex QCompletionModel::currentIndex(bool sourceIndex) const
-{
- if (!engine->matchCount())
- return QModelIndex();
-
- int row = engine->curRow;
- if (showAll)
- row = engine->curMatch.indices[engine->curRow];
-
- QModelIndex idx = createIndex(row, c->column);
- if (!sourceIndex)
- return idx;
- return mapToSource(idx);
-}
-
-QModelIndex QCompletionModel::index(int row, int column, const QModelIndex& parent) const
-{
- Q_D(const QCompletionModel);
- if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid())
- return QModelIndex();
-
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
- if (row >= engine->historyMatch.indices.count()) {
- int want = row + 1 - engine->matchCount();
- if (want > 0)
- engine->filterOnDemand(want);
- if (row >= engine->matchCount())
- return QModelIndex();
- }
- } else {
- if (row >= d->model->rowCount(engine->curParent))
- return QModelIndex();
- }
-
- return createIndex(row, column);
-}
-
-int QCompletionModel::completionCount() const
-{
- if (!engine->matchCount())
- return 0;
-
- engine->filterOnDemand(INT_MAX);
- return engine->matchCount();
-}
-
-int QCompletionModel::rowCount(const QModelIndex &parent) const
-{
- Q_D(const QCompletionModel);
- if (parent.isValid())
- return 0;
-
- if (showAll) {
- // Show all items below current parent, even if we have no valid matches
- if (engine->curParts.count() != 1 && !engine->matchCount()
- && !engine->curParent.isValid())
- return 0;
- return d->model->rowCount(engine->curParent);
- }
-
- return completionCount();
-}
-
-void QCompletionModel::setFiltered(bool filtered)
-{
- if (showAll == !filtered)
- return;
- showAll = !filtered;
- resetModel();
-}
-
-bool QCompletionModel::hasChildren(const QModelIndex &parent) const
-{
- Q_D(const QCompletionModel);
- if (parent.isValid())
- return false;
-
- if (showAll)
- return d->model->hasChildren(mapToSource(parent));
-
- if (!engine->matchCount())
- return false;
-
- return true;
-}
-
-QVariant QCompletionModel::data(const QModelIndex& index, int role) const
-{
- Q_D(const QCompletionModel);
- return d->model->data(mapToSource(index), role);
-}
-
-void QCompletionModel::modelDestroyed()
-{
- QAbstractProxyModel::setSourceModel(0); // switch to static empty model
- invalidate();
-}
-
-void QCompletionModel::rowsInserted()
-{
- invalidate();
- emit rowsAdded();
-}
-
-void QCompletionModel::invalidate()
-{
- engine->cache.clear();
- filter(engine->curParts);
-}
-
-void QCompletionModel::filter(const QStringList& parts)
-{
- Q_D(QCompletionModel);
- engine->filter(parts);
- resetModel();
-
- if (d->model->canFetchMore(engine->curParent))
- d->model->fetchMore(engine->curParent);
-}
-
-void QCompletionModel::resetModel()
-{
- if (rowCount() == 0) {
- reset();
- return;
- }
-
- emit layoutAboutToBeChanged();
- QModelIndexList piList = persistentIndexList();
- QModelIndexList empty;
- for (int i = 0; i < piList.size(); i++)
- empty.append(QModelIndex());
- changePersistentIndexList(piList, empty);
- emit layoutChanged();
-}
-
-//////////////////////////////////////////////////////////////////////////////
-void QCompletionEngine::filter(const QStringList& parts)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
- curParts = parts;
- if (curParts.isEmpty())
- curParts.append(QString());
-
- curRow = -1;
- curParent = QModelIndex();
- curMatch = QMatchData();
- historyMatch = filterHistory();
-
- if (!model)
- return;
-
- QModelIndex parent;
- for (int i = 0; i < curParts.count() - 1; i++) {
- QString part = curParts[i];
- int emi = filter(part, parent, -1).exactMatchIndex;
- if (emi == -1)
- return;
- parent = model->index(emi, c->column, parent);
- }
-
- // Note that we set the curParent to a valid parent, even if we have no matches
- // When filtering is disabled, we show all the items under this parent
- curParent = parent;
- if (curParts.last().isEmpty())
- curMatch = QMatchData(QIndexMapper(0, model->rowCount(curParent) - 1), -1, false);
- else
- curMatch = filter(curParts.last(), curParent, 1); // build at least one
- curRow = curMatch.isValid() ? 0 : -1;
-}
-
-QMatchData QCompletionEngine::filterHistory()
-{
- QAbstractItemModel *source = c->proxy->sourceModel();
- if (curParts.count() <= 1 || c->proxy->showAll || !source)
- return QMatchData();
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- isDirModel = (qobject_cast<QDirModel *>(source) != 0);
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- isFsModel = (qobject_cast<QFileSystemModel *>(source) != 0);
-#endif
- QVector<int> v;
- QIndexMapper im(v);
- QMatchData m(im, -1, true);
-
- for (int i = 0; i < source->rowCount(); i++) {
- QString str = source->index(i, c->column).data().toString();
- if (str.startsWith(c->prefix, c->cs)
-#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
- && ((!isFsModel && !isDirModel) || QDir::toNativeSeparators(str) != QDir::separator())
-#endif
- )
- m.indices.append(i);
- }
- return m;
-}
-
-// Returns a match hint from the cache by chopping the search string
-bool QCompletionEngine::matchHint(QString part, const QModelIndex& parent, QMatchData *hint)
-{
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
-
- const CacheItem& map = cache[parent];
-
- QString key = part;
- while (!key.isEmpty()) {
- key.chop(1);
- if (map.contains(key)) {
- *hint = map[key];
- return true;
- }
- }
-
- return false;
-}
-
-bool QCompletionEngine::lookupCache(QString part, const QModelIndex& parent, QMatchData *m)
-{
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
- const CacheItem& map = cache[parent];
- if (!map.contains(part))
- return false;
- *m = map[part];
- return true;
-}
-
-// When the cache size exceeds 1MB, it clears out about 1/2 of the cache.
-void QCompletionEngine::saveInCache(QString part, const QModelIndex& parent, const QMatchData& m)
-{
- QMatchData old = cache[parent].take(part);
- cost = cost + m.indices.cost() - old.indices.cost();
- if (cost * sizeof(int) > 1024 * 1024) {
- QMap<QModelIndex, CacheItem>::iterator it1 = cache.begin();
- while (it1 != cache.end()) {
- CacheItem& ci = it1.value();
- int sz = ci.count()/2;
- QMap<QString, QMatchData>::iterator it2 = ci.begin();
- int i = 0;
- while (it2 != ci.end() && i < sz) {
- cost -= it2.value().indices.cost();
- it2 = ci.erase(it2);
- i++;
- }
- if (ci.count() == 0) {
- it1 = cache.erase(it1);
- } else {
- ++it1;
- }
- }
- }
-
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
- cache[parent][part] = m;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-QIndexMapper QSortedModelEngine::indexHint(QString part, const QModelIndex& parent, Qt::SortOrder order)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
-
- const CacheItem& map = cache[parent];
-
- // Try to find a lower and upper bound for the search from previous results
- int to = model->rowCount(parent) - 1;
- int from = 0;
- const CacheItem::const_iterator it = map.lowerBound(part);
-
- // look backward for first valid hint
- for(CacheItem::const_iterator it1 = it; it1-- != map.constBegin();) {
- const QMatchData& value = it1.value();
- if (value.isValid()) {
- if (order == Qt::AscendingOrder) {
- from = value.indices.last() + 1;
- } else {
- to = value.indices.first() - 1;
- }
- break;
- }
- }
-
- // look forward for first valid hint
- for(CacheItem::const_iterator it2 = it; it2 != map.constEnd(); ++it2) {
- const QMatchData& value = it2.value();
- if (value.isValid() && !it2.key().startsWith(part)) {
- if (order == Qt::AscendingOrder) {
- to = value.indices.first() - 1;
- } else {
- from = value.indices.first() + 1;
- }
- break;
- }
- }
-
- return QIndexMapper(from, to);
-}
-
-Qt::SortOrder QSortedModelEngine::sortOrder(const QModelIndex &parent) const
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- int rowCount = model->rowCount(parent);
- if (rowCount < 2)
- return Qt::AscendingOrder;
- QString first = model->data(model->index(0, c->column, parent), c->role).toString();
- QString last = model->data(model->index(rowCount - 1, c->column, parent), c->role).toString();
- return QString::compare(first, last, c->cs) <= 0 ? Qt::AscendingOrder : Qt::DescendingOrder;
-}
-
-QMatchData QSortedModelEngine::filter(const QString& part, const QModelIndex& parent, int)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- QMatchData hint;
- if (lookupCache(part, parent, &hint))
- return hint;
-
- QIndexMapper indices;
- Qt::SortOrder order = sortOrder(parent);
-
- if (matchHint(part, parent, &hint)) {
- if (!hint.isValid())
- return QMatchData();
- indices = hint.indices;
- } else {
- indices = indexHint(part, parent, order);
- }
-
- // binary search the model within 'indices' for 'part' under 'parent'
- int high = indices.to() + 1;
- int low = indices.from() - 1;
- int probe;
- QModelIndex probeIndex;
- QString probeData;
-
- while (high - low > 1)
- {
- probe = (high + low) / 2;
- probeIndex = model->index(probe, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- const int cmp = QString::compare(probeData, part, c->cs);
- if ((order == Qt::AscendingOrder && cmp >= 0)
- || (order == Qt::DescendingOrder && cmp < 0)) {
- high = probe;
- } else {
- low = probe;
- }
- }
-
- if ((order == Qt::AscendingOrder && low == indices.to())
- || (order == Qt::DescendingOrder && high == indices.from())) { // not found
- saveInCache(part, parent, QMatchData());
- return QMatchData();
- }
-
- probeIndex = model->index(order == Qt::AscendingOrder ? low+1 : high-1, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- if (!probeData.startsWith(part, c->cs)) {
- saveInCache(part, parent, QMatchData());
- return QMatchData();
- }
-
- const bool exactMatch = QString::compare(probeData, part, c->cs) == 0;
- int emi = exactMatch ? (order == Qt::AscendingOrder ? low+1 : high-1) : -1;
-
- int from = 0;
- int to = 0;
- if (order == Qt::AscendingOrder) {
- from = low + 1;
- high = indices.to() + 1;
- low = from;
- } else {
- to = high - 1;
- low = indices.from() - 1;
- high = to;
- }
-
- while (high - low > 1)
- {
- probe = (high + low) / 2;
- probeIndex = model->index(probe, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- const bool startsWith = probeData.startsWith(part, c->cs);
- if ((order == Qt::AscendingOrder && startsWith)
- || (order == Qt::DescendingOrder && !startsWith)) {
- low = probe;
- } else {
- high = probe;
- }
- }
-
- QMatchData m(order == Qt::AscendingOrder ? QIndexMapper(from, high - 1) : QIndexMapper(low+1, to), emi, false);
- saveInCache(part, parent, m);
- return m;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& parent, int n,
- const QIndexMapper& indices, QMatchData* m)
-{
- Q_ASSERT(m->partial);
- Q_ASSERT(n != -1 || m->exactMatchIndex == -1);
- const QAbstractItemModel *model = c->proxy->sourceModel();
- int i, count = 0;
-
- for (i = 0; i < indices.count() && count != n; ++i) {
- QModelIndex idx = model->index(indices[i], c->column, parent);
- QString data = model->data(idx, c->role).toString();
- if (!data.startsWith(str, c->cs) || !(model->flags(idx) & Qt::ItemIsSelectable))
- continue;
- m->indices.append(indices[i]);
- ++count;
- if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) {
- m->exactMatchIndex = indices[i];
- if (n == -1)
- return indices[i];
- }
- }
- return indices[i-1];
-}
-
-void QUnsortedModelEngine::filterOnDemand(int n)
-{
- Q_ASSERT(matchCount());
- if (!curMatch.partial)
- return;
- Q_ASSERT(n >= -1);
- const QAbstractItemModel *model = c->proxy->sourceModel();
- int lastRow = model->rowCount(curParent) - 1;
- QIndexMapper im(curMatch.indices.last() + 1, lastRow);
- int lastIndex = buildIndices(curParts.last(), curParent, n, im, &curMatch);
- curMatch.partial = (lastRow != lastIndex);
- saveInCache(curParts.last(), curParent, curMatch);
-}
-
-QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& parent, int n)
-{
- QMatchData hint;
-
- QVector<int> v;
- QIndexMapper im(v);
- QMatchData m(im, -1, true);
-
- const QAbstractItemModel *model = c->proxy->sourceModel();
- bool foundInCache = lookupCache(part, parent, &m);
-
- if (!foundInCache) {
- if (matchHint(part, parent, &hint) && !hint.isValid())
- return QMatchData();
- }
-
- if (!foundInCache && !hint.isValid()) {
- const int lastRow = model->rowCount(parent) - 1;
- QIndexMapper all(0, lastRow);
- int lastIndex = buildIndices(part, parent, n, all, &m);
- m.partial = (lastIndex != lastRow);
- } else {
- if (!foundInCache) { // build from hint as much as we can
- buildIndices(part, parent, INT_MAX, hint.indices, &m);
- m.partial = hint.partial;
- }
- if (m.partial && ((n == -1 && m.exactMatchIndex == -1) || (m.indices.count() < n))) {
- // need more and have more
- const int lastRow = model->rowCount(parent) - 1;
- QIndexMapper rest(hint.indices.last() + 1, lastRow);
- int want = n == -1 ? -1 : n - m.indices.count();
- int lastIndex = buildIndices(part, parent, want, rest, &m);
- m.partial = (lastRow != lastIndex);
- }
- }
-
- saveInCache(part, parent, m);
- return m;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-QCompleterPrivate::QCompleterPrivate()
-: widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0),
- maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true),
- hiddenBecauseNoMatch(false)
-{
-}
-
-void QCompleterPrivate::init(QAbstractItemModel *m)
-{
- Q_Q(QCompleter);
- proxy = new QCompletionModel(this, q);
- QObject::connect(proxy, SIGNAL(rowsAdded()), q, SLOT(_q_autoResizePopup()));
- q->setModel(m);
-#ifdef QT_NO_LISTVIEW
- q->setCompletionMode(QCompleter::InlineCompletion);
-#else
- q->setCompletionMode(QCompleter::PopupCompletion);
-#endif // QT_NO_LISTVIEW
-}
-
-void QCompleterPrivate::setCurrentIndex(QModelIndex index, bool select)
-{
- Q_Q(QCompleter);
- if (!q->popup())
- return;
- if (!select) {
- popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- } else {
- if (!index.isValid())
- popup->selectionModel()->clear();
- else
- popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select
- | QItemSelectionModel::Rows);
- }
- index = popup->selectionModel()->currentIndex();
- if (!index.isValid())
- popup->scrollToTop();
- else
- popup->scrollTo(index, QAbstractItemView::PositionAtTop);
-}
-
-void QCompleterPrivate::_q_completionSelected(const QItemSelection& selection)
-{
- QModelIndex index;
- if (!selection.indexes().isEmpty())
- index = selection.indexes().first();
-
- _q_complete(index, true);
-}
-
-void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted)
-{
- Q_Q(QCompleter);
- QString completion;
-
- if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) {
- completion = prefix;
- } else {
- if (!(index.flags() & Qt::ItemIsEnabled))
- return;
- QModelIndex si = proxy->mapToSource(index);
- si = si.sibling(si.row(), column); // for clicked()
- completion = q->pathFromIndex(si);
-#ifndef QT_NO_DIRMODEL
- // add a trailing separator in inline
- if (mode == QCompleter::InlineCompletion) {
- if (qobject_cast<QDirModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
- completion += QDir::separator();
- }
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- // add a trailing separator in inline
- if (mode == QCompleter::InlineCompletion) {
- if (qobject_cast<QFileSystemModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
- completion += QDir::separator();
- }
-#endif
- }
-
- if (highlighted) {
- emit q->highlighted(index);
- emit q->highlighted(completion);
- } else {
- emit q->activated(index);
- emit q->activated(completion);
- }
-}
-
-void QCompleterPrivate::_q_autoResizePopup()
-{
- if (!popup || !popup->isVisible())
- return;
- showPopup(popupRect);
-}
-
-void QCompleterPrivate::showPopup(const QRect& rect)
-{
- const QRect screen = QApplication::desktop()->availableGeometry(widget);
- Qt::LayoutDirection dir = widget->layoutDirection();
- QPoint pos;
- int rh, w;
- int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3;
- QScrollBar *hsb = popup->horizontalScrollBar();
- if (hsb && hsb->isVisible())
- h += popup->horizontalScrollBar()->sizeHint().height();
-
- if (rect.isValid()) {
- rh = rect.height();
- w = rect.width();
- pos = widget->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft());
- } else {
- rh = widget->height();
- pos = widget->mapToGlobal(QPoint(0, widget->height() - 2));
- w = widget->width();
- }
-
- if (w > screen.width())
- w = screen.width();
- if ((pos.x() + w) > (screen.x() + screen.width()))
- pos.setX(screen.x() + screen.width() - w);
- if (pos.x() < screen.x())
- pos.setX(screen.x());
-
- int top = pos.y() - rh - screen.top() + 2;
- int bottom = screen.bottom() - pos.y();
- h = qMax(h, popup->minimumHeight());
- if (h > bottom) {
- h = qMin(qMax(top, bottom), h);
-
- if (top > bottom)
- pos.setY(pos.y() - h - rh + 2);
- }
-
- popup->setGeometry(pos.x(), pos.y(), w, h);
-
- if (!popup->isVisible())
- popup->show();
-}
-
-void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
-{
- Q_Q(QCompleter);
- // Slot called when QFileSystemModel has finished loading.
- // If we hide the popup because there was no match because the model was not loaded yet,
- // we re-start the completion when we get the results
- if (hiddenBecauseNoMatch
- && prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
- && widget) {
- q->complete();
- }
-}
-
-/*!
- Constructs a completer object with the given \a parent.
-*/
-QCompleter::QCompleter(QObject *parent)
-: QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init();
-}
-
-/*!
- Constructs a completer object with the given \a parent that provides completions
- from the specified \a model.
-*/
-QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent)
- : QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init(model);
-}
-
-#ifndef QT_NO_STRINGLISTMODEL
-/*!
- Constructs a QCompleter object with the given \a parent that uses the specified
- \a list as a source of possible completions.
-*/
-QCompleter::QCompleter(const QStringList& list, QObject *parent)
-: QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init(new QStringListModel(list, this));
-}
-#endif // QT_NO_STRINGLISTMODEL
-
-/*!
- Destroys the completer object.
-*/
-QCompleter::~QCompleter()
-{
-}
-
-/*!
- Sets the widget for which completion are provided for to \a widget. This
- function is automatically called when a QCompleter is set on a QLineEdit
- using QLineEdit::setCompleter() or on a QComboBox using
- QComboBox::setCompleter(). The widget needs to be set explicitly when
- providing completions for custom widgets.
-
- \sa widget(), setModel(), setPopup()
- */
-void QCompleter::setWidget(QWidget *widget)
-{
- Q_D(QCompleter);
- if (d->widget)
- d->widget->removeEventFilter(this);
- d->widget = widget;
- if (d->widget)
- d->widget->installEventFilter(this);
- if (d->popup) {
- d->popup->hide();
- d->popup->setFocusProxy(d->widget);
- }
-}
-
-/*!
- Returns the widget for which the completer object is providing completions.
-
- \sa setWidget()
- */
-QWidget *QCompleter::widget() const
-{
- Q_D(const QCompleter);
- return d->widget;
-}
-
-/*!
- Sets the model which provides completions to \a model. The \a model can
- be list model or a tree model. If a model has been already previously set
- and it has the QCompleter as its parent, it is deleted.
-
- For convenience, if \a model is a QFileSystemModel, QCompleter switches its
- caseSensitivity to Qt::CaseInsensitive on Windows and Qt::CaseSensitive
- on other platforms.
-
- \sa completionModel(), modelSorting, {Handling Tree Models}
-*/
-void QCompleter::setModel(QAbstractItemModel *model)
-{
- Q_D(QCompleter);
- QAbstractItemModel *oldModel = d->proxy->sourceModel();
- d->proxy->setSourceModel(model);
- if (d->popup)
- setPopup(d->popup); // set the model and make new connections
- if (oldModel && oldModel->QObject::parent() == this)
- delete oldModel;
-#ifndef QT_NO_DIRMODEL
- if (qobject_cast<QDirModel *>(model)) {
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
- setCaseSensitivity(Qt::CaseInsensitive);
-#else
- setCaseSensitivity(Qt::CaseSensitive);
-#endif
- }
-#endif // QT_NO_DIRMODEL
-#ifndef QT_NO_FILESYSTEMMODEL
- QFileSystemModel *fsModel = qobject_cast<QFileSystemModel *>(model);
- if (fsModel) {
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
- setCaseSensitivity(Qt::CaseInsensitive);
-#else
- setCaseSensitivity(Qt::CaseSensitive);
-#endif
- setCompletionRole(QFileSystemModel::FileNameRole);
- connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString)));
- }
-#endif // QT_NO_FILESYSTEMMODEL
-}
-
-/*!
- Returns the model that provides completion strings.
-
- \sa completionModel()
-*/
-QAbstractItemModel *QCompleter::model() const
-{
- Q_D(const QCompleter);
- return d->proxy->sourceModel();
-}
-
-/*!
- \enum QCompleter::CompletionMode
-
- This enum specifies how completions are provided to the user.
-
- \value PopupCompletion Current completions are displayed in a popup window.
- \value InlineCompletion Completions appear inline (as selected text).
- \value UnfilteredPopupCompletion All possible completions are displayed in a popup window with the most likely suggestion indicated as current.
-
- \sa setCompletionMode()
-*/
-
-/*!
- \property QCompleter::completionMode
- \brief how the completions are provided to the user
-
- The default value is QCompleter::PopupCompletion.
-*/
-void QCompleter::setCompletionMode(QCompleter::CompletionMode mode)
-{
- Q_D(QCompleter);
- d->mode = mode;
- d->proxy->setFiltered(mode != QCompleter::UnfilteredPopupCompletion);
-
- if (mode == QCompleter::InlineCompletion) {
- if (d->widget)
- d->widget->removeEventFilter(this);
- if (d->popup) {
- d->popup->deleteLater();
- d->popup = 0;
- }
- } else {
- if (d->widget)
- d->widget->installEventFilter(this);
- }
-}
-
-QCompleter::CompletionMode QCompleter::completionMode() const
-{
- Q_D(const QCompleter);
- return d->mode;
-}
-
-/*!
- Sets the popup used to display completions to \a popup. QCompleter takes
- ownership of the view.
-
- A QListView is automatically created when the completionMode() is set to
- QCompleter::PopupCompletion or QCompleter::UnfilteredPopupCompletion. The
- default popup displays the completionColumn().
-
- Ensure that this function is called before the view settings are modified.
- This is required since view's properties may require that a model has been
- set on the view (for example, hiding columns in the view requires a model
- to be set on the view).
-
- \sa popup()
-*/
-void QCompleter::setPopup(QAbstractItemView *popup)
-{
- Q_D(QCompleter);
- Q_ASSERT(popup != 0);
- if (d->popup) {
- QObject::disconnect(d->popup->selectionModel(), 0, this, 0);
- QObject::disconnect(d->popup, 0, this, 0);
- }
- if (d->popup != popup)
- delete d->popup;
- if (popup->model() != d->proxy)
- popup->setModel(d->proxy);
-#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
- popup->show();
-#else
- popup->hide();
-#endif
-
- Qt::FocusPolicy origPolicy = Qt::NoFocus;
- if (d->widget)
- origPolicy = d->widget->focusPolicy();
- popup->setParent(0, Qt::Popup);
- popup->setFocusPolicy(Qt::NoFocus);
- if (d->widget)
- d->widget->setFocusPolicy(origPolicy);
-
- popup->setFocusProxy(d->widget);
- popup->installEventFilter(this);
- popup->setItemDelegate(new QCompleterItemDelegate(popup));
-#ifndef QT_NO_LISTVIEW
- if (QListView *listView = qobject_cast<QListView *>(popup)) {
- listView->setModelColumn(d->column);
- }
-#endif
-
- QObject::connect(popup, SIGNAL(clicked(QModelIndex)),
- this, SLOT(_q_complete(QModelIndex)));
- QObject::connect(this, SIGNAL(activated(QModelIndex)),
- popup, SLOT(hide()));
-
- QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(_q_completionSelected(QItemSelection)));
- d->popup = popup;
-}
-
-/*!
- Returns the popup used to display completions.
-
- \sa setPopup()
-*/
-QAbstractItemView *QCompleter::popup() const
-{
- Q_D(const QCompleter);
-#ifndef QT_NO_LISTVIEW
- if (!d->popup && completionMode() != QCompleter::InlineCompletion) {
- QListView *listView = new QListView;
- listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
- listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- listView->setSelectionBehavior(QAbstractItemView::SelectRows);
- listView->setSelectionMode(QAbstractItemView::SingleSelection);
- listView->setModelColumn(d->column);
- QCompleter *that = const_cast<QCompleter*>(this);
- that->setPopup(listView);
- }
-#endif // QT_NO_LISTVIEW
- return d->popup;
-}
-
-/*!
- \reimp
-*/
-bool QCompleter::event(QEvent *ev)
-{
- return QObject::event(ev);
-}
-
-/*!
- \reimp
-*/
-bool QCompleter::eventFilter(QObject *o, QEvent *e)
-{
- Q_D(QCompleter);
-
- if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) {
- d->hiddenBecauseNoMatch = false;
- if (d->popup && d->popup->isVisible())
- return true;
- }
-
- if (o != d->popup)
- return QObject::eventFilter(o, e);
-
- switch (e->type()) {
- case QEvent::KeyPress: {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
-
- QModelIndex curIndex = d->popup->currentIndex();
- QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
-
- const int key = ke->key();
- // In UnFilteredPopup mode, select the current item
- if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
- && d->mode == QCompleter::UnfilteredPopupCompletion) {
- d->setCurrentIndex(curIndex);
- return true;
- }
-
- // Handle popup navigation keys. These are hardcoded because up/down might make the
- // widget do something else (lineedit cursor moves to home/end on mac, for instance)
- switch (key) {
- case Qt::Key_End:
- case Qt::Key_Home:
- if (ke->modifiers() & Qt::ControlModifier)
- return false;
- break;
-
- case Qt::Key_Up:
- if (!curIndex.isValid()) {
- int rowCount = d->proxy->rowCount();
- QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
- d->setCurrentIndex(lastIndex);
- return true;
- } else if (curIndex.row() == 0) {
- if (d->wrap)
- d->setCurrentIndex(QModelIndex());
- return true;
- }
- return false;
-
- case Qt::Key_Down:
- if (!curIndex.isValid()) {
- QModelIndex firstIndex = d->proxy->index(0, d->column);
- d->setCurrentIndex(firstIndex);
- return true;
- } else if (curIndex.row() == d->proxy->rowCount() - 1) {
- if (d->wrap)
- d->setCurrentIndex(QModelIndex());
- return true;
- }
- return false;
-
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- return false;
- }
-
- // Send the event to the widget. If the widget accepted the event, do nothing
- // If the widget did not accept the event, provide a default implementation
- d->eatFocusOut = false;
- (static_cast<QObject *>(d->widget))->event(ke);
- d->eatFocusOut = true;
- if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
- // widget lost focus, hide the popup
- if (d->widget && (!d->widget->hasFocus()
-#ifdef QT_KEYPAD_NAVIGATION
- || (QApplication::keypadNavigationEnabled() && !d->widget->hasEditFocus())
-#endif
- ))
- d->popup->hide();
- if (e->isAccepted())
- return true;
- }
-
- // default implementation for keys not handled by the widget when popup is open
- switch (key) {
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- case Qt::Key_Return:
- case Qt::Key_Enter:
- case Qt::Key_Tab:
- d->popup->hide();
- if (curIndex.isValid())
- d->_q_complete(curIndex);
- break;
-
- case Qt::Key_F4:
- if (ke->modifiers() & Qt::AltModifier)
- d->popup->hide();
- break;
-
- case Qt::Key_Backtab:
- case Qt::Key_Escape:
- d->popup->hide();
- break;
-
- default:
- break;
- }
-
- return true;
- }
-
-#ifdef QT_KEYPAD_NAVIGATION
- case QEvent::KeyRelease: {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
- if (QApplication::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
- // Send the event to the 'widget'. This is what we did for KeyPress, so we need
- // to do the same for KeyRelease, in case the widget's KeyPress event set
- // up something (such as a timer) that is relying on also receiving the
- // key release. I see this as a bug in Qt, and should really set it up for all
- // the affected keys. However, it is difficult to tell how this will affect
- // existing code, and I can't test for every combination!
- d->eatFocusOut = false;
- static_cast<QObject *>(d->widget)->event(ke);
- d->eatFocusOut = true;
- }
- break;
- }
-#endif
-
- case QEvent::MouseButtonPress: {
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- // if we've clicked in the widget (or its descendant), let it handle the click
- QWidget *source = qobject_cast<QWidget *>(o);
- if (source) {
- QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
- QWidget *target = QApplication::widgetAt(pos);
- if (target && (d->widget->isAncestorOf(target) ||
- target == d->widget)) {
- d->eatFocusOut = false;
- static_cast<QObject *>(target)->event(e);
- d->eatFocusOut = true;
- return true;
- }
- }
- }
-#endif
- if (!d->popup->underMouse()) {
- d->popup->hide();
- return true;
- }
- }
- return false;
-
- case QEvent::InputMethod:
- case QEvent::ShortcutOverride:
- QApplication::sendEvent(d->widget, e);
- break;
-
- default:
- return false;
- }
- return false;
-}
-
-/*!
- For QCompleter::PopupCompletion and QCompletion::UnfilteredPopupCompletion
- modes, calling this function displays the popup displaying the current
- completions. By default, if \a rect is not specified, the popup is displayed
- on the bottom of the widget(). If \a rect is specified the popup is
- displayed on the left edge of the rectangle.
-
- For QCompleter::InlineCompletion mode, the highlighted() signal is fired
- with the current completion.
-*/
-void QCompleter::complete(const QRect& rect)
-{
- Q_D(QCompleter);
- QModelIndex idx = d->proxy->currentIndex(false);
- d->hiddenBecauseNoMatch = false;
- if (d->mode == QCompleter::InlineCompletion) {
- if (idx.isValid())
- d->_q_complete(idx, true);
- return;
- }
-
- Q_ASSERT(d->widget != 0);
- if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
- || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
- if (d->popup)
- d->popup->hide(); // no suggestion, hide
- d->hiddenBecauseNoMatch = true;
- return;
- }
-
- popup();
- if (d->mode == QCompleter::UnfilteredPopupCompletion)
- d->setCurrentIndex(idx, false);
-
- d->showPopup(rect);
- d->popupRect = rect;
-}
-
-/*!
- Sets the current row to the \a row specified. Returns true if successful;
- otherwise returns false.
-
- This function may be used along with currentCompletion() to iterate
- through all the possible completions.
-
- \sa currentCompletion(), completionCount()
-*/
-bool QCompleter::setCurrentRow(int row)
-{
- Q_D(QCompleter);
- return d->proxy->setCurrentRow(row);
-}
-
-/*!
- Returns the current row.
-
- \sa setCurrentRow()
-*/
-int QCompleter::currentRow() const
-{
- Q_D(const QCompleter);
- return d->proxy->currentRow();
-}
-
-/*!
- Returns the number of completions for the current prefix. For an unsorted
- model with a large number of items this can be expensive. Use setCurrentRow()
- and currentCompletion() to iterate through all the completions.
-*/
-int QCompleter::completionCount() const
-{
- Q_D(const QCompleter);
- return d->proxy->completionCount();
-}
-
-/*!
- \enum QCompleter::ModelSorting
-
- This enum specifies how the items in the model are sorted.
-
- \value UnsortedModel The model is unsorted.
- \value CaseSensitivelySortedModel The model is sorted case sensitively.
- \value CaseInsensitivelySortedModel The model is sorted case insensitively.
-
- \sa setModelSorting()
-*/
-
-/*!
- \property QCompleter::modelSorting
- \brief the way the model is sorted
-
- By default, no assumptions are made about the order of the items
- in the model that provides the completions.
-
- If the model's data for the completionColumn() and completionRole() is sorted in
- ascending order, you can set this property to \l CaseSensitivelySortedModel
- or \l CaseInsensitivelySortedModel. On large models, this can lead to
- significant performance improvements because the completer object can
- then use a binary search algorithm instead of linear search algorithm.
-
- The sort order (i.e ascending or descending order) of the model is determined
- dynamically by inspecting the contents of the model.
-
- \bold{Note:} The performance improvements described above cannot take place
- when the completer's \l caseSensitivity is different to the case sensitivity
- used by the model's when sorting.
-
- \sa setCaseSensitivity(), QCompleter::ModelSorting
-*/
-void QCompleter::setModelSorting(QCompleter::ModelSorting sorting)
-{
- Q_D(QCompleter);
- if (d->sorting == sorting)
- return;
- d->sorting = sorting;
- d->proxy->createEngine();
- d->proxy->invalidate();
-}
-
-QCompleter::ModelSorting QCompleter::modelSorting() const
-{
- Q_D(const QCompleter);
- return d->sorting;
-}
-
-/*!
- \property QCompleter::completionColumn
- \brief the column in the model in which completions are searched for.
-
- If the popup() is a QListView, it is automatically setup to display
- this column.
-
- By default, the match column is 0.
-
- \sa completionRole, caseSensitivity
-*/
-void QCompleter::setCompletionColumn(int column)
-{
- Q_D(QCompleter);
- if (d->column == column)
- return;
-#ifndef QT_NO_LISTVIEW
- if (QListView *listView = qobject_cast<QListView *>(d->popup))
- listView->setModelColumn(column);
-#endif
- d->column = column;
- d->proxy->invalidate();
-}
-
-int QCompleter::completionColumn() const
-{
- Q_D(const QCompleter);
- return d->column;
-}
-
-/*!
- \property QCompleter::completionRole
- \brief the item role to be used to query the contents of items for matching.
-
- The default role is Qt::EditRole.
-
- \sa completionColumn, caseSensitivity
-*/
-void QCompleter::setCompletionRole(int role)
-{
- Q_D(QCompleter);
- if (d->role == role)
- return;
- d->role = role;
- d->proxy->invalidate();
-}
-
-int QCompleter::completionRole() const
-{
- Q_D(const QCompleter);
- return d->role;
-}
-
-/*!
- \property QCompleter::wrapAround
- \brief the completions wrap around when navigating through items
- \since 4.3
-
- The default is true.
-*/
-void QCompleter::setWrapAround(bool wrap)
-{
- Q_D(QCompleter);
- if (d->wrap == wrap)
- return;
- d->wrap = wrap;
-}
-
-bool QCompleter::wrapAround() const
-{
- Q_D(const QCompleter);
- return d->wrap;
-}
-
-/*!
- \property QCompleter::maxVisibleItems
- \brief the maximum allowed size on screen of the completer, measured in items
- \since 4.6
-
- By default, this property has a value of 7.
-*/
-int QCompleter::maxVisibleItems() const
-{
- Q_D(const QCompleter);
- return d->maxVisibleItems;
-}
-
-void QCompleter::setMaxVisibleItems(int maxItems)
-{
- Q_D(QCompleter);
- if (maxItems < 0) {
- qWarning("QCompleter::setMaxVisibleItems: "
- "Invalid max visible items (%d) must be >= 0", maxItems);
- return;
- }
- d->maxVisibleItems = maxItems;
-}
-
-/*!
- \property QCompleter::caseSensitivity
- \brief the case sensitivity of the matching
-
- The default is Qt::CaseSensitive.
-
- \sa completionColumn, completionRole, modelSorting
-*/
-void QCompleter::setCaseSensitivity(Qt::CaseSensitivity cs)
-{
- Q_D(QCompleter);
- if (d->cs == cs)
- return;
- d->cs = cs;
- d->proxy->createEngine();
- d->proxy->invalidate();
-}
-
-Qt::CaseSensitivity QCompleter::caseSensitivity() const
-{
- Q_D(const QCompleter);
- return d->cs;
-}
-
-/*!
- \property QCompleter::completionPrefix
- \brief the completion prefix used to provide completions.
-
- The completionModel() is updated to reflect the list of possible
- matches for \a prefix.
-*/
-void QCompleter::setCompletionPrefix(const QString &prefix)
-{
- Q_D(QCompleter);
- d->prefix = prefix;
- d->proxy->filter(splitPath(prefix));
-}
-
-QString QCompleter::completionPrefix() const
-{
- Q_D(const QCompleter);
- return d->prefix;
-}
-
-/*!
- Returns the model index of the current completion in the completionModel().
-
- \sa setCurrentRow(), currentCompletion(), model()
-*/
-QModelIndex QCompleter::currentIndex() const
-{
- Q_D(const QCompleter);
- return d->proxy->currentIndex(false);
-}
-
-/*!
- Returns the current completion string. This includes the \l completionPrefix.
- When used alongside setCurrentRow(), it can be used to iterate through
- all the matches.
-
- \sa setCurrentRow(), currentIndex()
-*/
-QString QCompleter::currentCompletion() const
-{
- Q_D(const QCompleter);
- return pathFromIndex(d->proxy->currentIndex(true));
-}
-
-/*!
- Returns the completion model. The completion model is a read-only list model
- that contains all the possible matches for the current completion prefix.
- The completion model is auto-updated to reflect the current completions.
-
- \note The return value of this function is defined to be an QAbstractItemModel
- purely for generality. This actual kind of model returned is an instance of an
- QAbstractProxyModel subclass.
-
- \sa completionPrefix, model()
-*/
-QAbstractItemModel *QCompleter::completionModel() const
-{
- Q_D(const QCompleter);
- return d->proxy;
-}
-
-/*!
- Returns the path for the given \a index. The completer object uses this to
- obtain the completion text from the underlying model.
-
- The default implementation returns the \l{Qt::EditRole}{edit role} of the
- item for list models. It returns the absolute file path if the model is a
- QFileSystemModel.
-
- \sa splitPath()
-*/
-
-QString QCompleter::pathFromIndex(const QModelIndex& index) const
-{
- Q_D(const QCompleter);
- if (!index.isValid())
- return QString();
-
- QAbstractItemModel *sourceModel = d->proxy->sourceModel();
- if (!sourceModel)
- return QString();
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
-#endif
- if (!isDirModel && !isFsModel)
- return sourceModel->data(index, d->role).toString();
-
- QModelIndex idx = index;
- QStringList list;
- do {
- QString t;
- if (isDirModel)
- t = sourceModel->data(idx, Qt::EditRole).toString();
-#ifndef QT_NO_FILESYSTEMMODEL
- else
- t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
-#endif
- list.prepend(t);
- QModelIndex parent = idx.parent();
- idx = parent.sibling(parent.row(), index.column());
- } while (idx.isValid());
-
-#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
- if (list.count() == 1) // only the separator or some other text
- return list[0];
- list[0].clear() ; // the join below will provide the separator
-#endif
-
- return list.join(QDir::separator());
-}
-
-/*!
- Splits the given \a path into strings that are used to match at each level
- in the model().
-
- The default implementation of splitPath() splits a file system path based on
- QDir::separator() when the sourceModel() is a QFileSystemModel.
-
- When used with list models, the first item in the returned list is used for
- matching.
-
- \sa pathFromIndex(), {Handling Tree Models}
-*/
-QStringList QCompleter::splitPath(const QString& path) const
-{
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- Q_D(const QCompleter);
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
-#ifdef QT_NO_DIRMODEL
- Q_D(const QCompleter);
-#endif
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
-#endif
-
- if ((!isDirModel && !isFsModel) || path.isEmpty())
- return QStringList(completionPrefix());
-
- QString pathCopy = QDir::toNativeSeparators(path);
- QString sep = QDir::separator();
-#if defined(Q_OS_SYMBIAN)
- if (pathCopy == QLatin1String("\\"))
- return QStringList(pathCopy);
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\"))
- return QStringList(pathCopy);
- QString doubleSlash(QLatin1String("\\\\"));
- if (pathCopy.startsWith(doubleSlash))
- pathCopy = pathCopy.mid(2);
- else
- doubleSlash.clear();
-#endif
-
- QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
- QStringList parts = pathCopy.split(re);
-
-#if defined(Q_OS_SYMBIAN)
- // Do nothing
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (!doubleSlash.isEmpty())
- parts[0].prepend(doubleSlash);
-#else
- if (pathCopy[0] == sep[0]) // readd the "/" at the beginning as the split removed it
- parts[0] = QDir::fromNativeSeparators(QString(sep[0]));
-#endif
-
- return parts;
-}
-
-/*!
- \fn void QCompleter::activated(const QModelIndex& index)
-
- This signal is sent when an item in the popup() is activated by the user.
- (by clicking or pressing return). The item's \a index in the completionModel()
- is given.
-
-*/
-
-/*!
- \fn void QCompleter::activated(const QString &text)
-
- This signal is sent when an item in the popup() is activated by the user (by
- clicking or pressing return). The item's \a text is given.
-
-*/
-
-/*!
- \fn void QCompleter::highlighted(const QModelIndex& index)
-
- This signal is sent when an item in the popup() is highlighted by
- the user. It is also sent if complete() is called with the completionMode()
- set to QCompleter::InlineCompletion. The item's \a index in the completionModel()
- is given.
-*/
-
-/*!
- \fn void QCompleter::highlighted(const QString &text)
-
- This signal is sent when an item in the popup() is highlighted by
- the user. It is also sent if complete() is called with the completionMode()
- set to QCompleter::InlineCompletion. The item's \a text is given.
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qcompleter.cpp"
-
-#endif // QT_NO_COMPLETER
diff --git a/src/gui/util/qcompleter.h b/src/gui/util/qcompleter.h
deleted file mode 100644
index ace2f0afb6..0000000000
--- a/src/gui/util/qcompleter.h
+++ /dev/null
@@ -1,171 +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 QCOMPLETER_H
-#define QCOMPLETER_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qrect.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_COMPLETER
-
-class QCompleterPrivate;
-class QAbstractItemView;
-class QAbstractProxyModel;
-class QWidget;
-
-class Q_GUI_EXPORT QCompleter : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString completionPrefix READ completionPrefix WRITE setCompletionPrefix)
- Q_PROPERTY(ModelSorting modelSorting READ modelSorting WRITE setModelSorting)
- Q_PROPERTY(CompletionMode completionMode READ completionMode WRITE setCompletionMode)
- Q_PROPERTY(int completionColumn READ completionColumn WRITE setCompletionColumn)
- Q_PROPERTY(int completionRole READ completionRole WRITE setCompletionRole)
- Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
- Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity)
- Q_PROPERTY(bool wrapAround READ wrapAround WRITE setWrapAround)
-
-public:
- enum CompletionMode {
- PopupCompletion,
- UnfilteredPopupCompletion,
- InlineCompletion
- };
-
- enum ModelSorting {
- UnsortedModel = 0,
- CaseSensitivelySortedModel,
- CaseInsensitivelySortedModel
- };
-
- QCompleter(QObject *parent = 0);
- QCompleter(QAbstractItemModel *model, QObject *parent = 0);
-#ifndef QT_NO_STRINGLISTMODEL
- QCompleter(const QStringList& completions, QObject *parent = 0);
-#endif
- ~QCompleter();
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
- void setModel(QAbstractItemModel *c);
- QAbstractItemModel *model() const;
-
- void setCompletionMode(CompletionMode mode);
- CompletionMode completionMode() const;
-
- QAbstractItemView *popup() const;
- void setPopup(QAbstractItemView *popup);
-
- void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
- Qt::CaseSensitivity caseSensitivity() const;
-
- void setModelSorting(ModelSorting sorting);
- ModelSorting modelSorting() const;
-
- void setCompletionColumn(int column);
- int completionColumn() const;
-
- void setCompletionRole(int role);
- int completionRole() const;
-
- bool wrapAround() const;
-
- int maxVisibleItems() const;
- void setMaxVisibleItems(int maxItems);
-
- int completionCount() const;
- bool setCurrentRow(int row);
- int currentRow() const;
-
- QModelIndex currentIndex() const;
- QString currentCompletion() const;
-
- QAbstractItemModel *completionModel() const;
-
- QString completionPrefix() const;
-
-public Q_SLOTS:
- void setCompletionPrefix(const QString &prefix);
- void complete(const QRect& rect = QRect());
- void setWrapAround(bool wrap);
-
-public:
- virtual QString pathFromIndex(const QModelIndex &index) const;
- virtual QStringList splitPath(const QString &path) const;
-
-protected:
- bool eventFilter(QObject *o, QEvent *e);
- bool event(QEvent *);
-
-Q_SIGNALS:
- void activated(const QString &text);
- void activated(const QModelIndex &index);
- void highlighted(const QString &text);
- void highlighted(const QModelIndex &index);
-
-private:
- Q_DISABLE_COPY(QCompleter)
- Q_DECLARE_PRIVATE(QCompleter)
-
- Q_PRIVATE_SLOT(d_func(), void _q_complete(QModelIndex))
- Q_PRIVATE_SLOT(d_func(), void _q_completionSelected(const QItemSelection&))
- Q_PRIVATE_SLOT(d_func(), void _q_autoResizePopup())
- Q_PRIVATE_SLOT(d_func(), void _q_fileSystemModelDirectoryLoaded(const QString&))
-};
-
-#endif // QT_NO_COMPLETER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOMPLETER_H
diff --git a/src/gui/util/qcompleter_p.h b/src/gui/util/qcompleter_p.h
deleted file mode 100644
index 83e7a27636..0000000000
--- a/src/gui/util/qcompleter_p.h
+++ /dev/null
@@ -1,264 +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 QCOMPLETER_P_H
-#define QCOMPLETER_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 "private/qobject_p.h"
-
-#ifndef QT_NO_COMPLETER
-
-#include "QtGui/qtreeview.h"
-#include "QtGui/qabstractproxymodel.h"
-#include "qcompleter.h"
-#include "QtGui/qitemdelegate.h"
-#include "QtGui/qpainter.h"
-#include "private/qabstractproxymodel_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QCompletionModel;
-
-class QCompleterPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QCompleter)
-
-public:
- QCompleterPrivate();
- ~QCompleterPrivate() { delete popup; }
- void init(QAbstractItemModel *model = 0);
-
- QPointer<QWidget> widget;
- QCompletionModel *proxy;
- QAbstractItemView *popup;
- QCompleter::CompletionMode mode;
-
- QString prefix;
- Qt::CaseSensitivity cs;
- int role;
- int column;
- int maxVisibleItems;
- QCompleter::ModelSorting sorting;
- bool wrap;
-
- bool eatFocusOut;
- QRect popupRect;
- bool hiddenBecauseNoMatch;
-
- void showPopup(const QRect&);
- void _q_complete(QModelIndex, bool = false);
- void _q_completionSelected(const QItemSelection&);
- void _q_autoResizePopup();
- void _q_fileSystemModelDirectoryLoaded(const QString &path);
- void setCurrentIndex(QModelIndex, bool = true);
-};
-
-class QIndexMapper
-{
-public:
- QIndexMapper() : v(false), f(0), t(-1) { }
- QIndexMapper(int f, int t) : v(false), f(f), t(t) { }
- QIndexMapper(QVector<int> vec) : v(true), vector(vec), f(-1), t(-1) { }
-
- inline int count() const { return v ? vector.count() : t - f + 1; }
- inline int operator[] (int index) const { return v ? vector[index] : f + index; }
- inline int indexOf(int x) const { return v ? vector.indexOf(x) : ((t < f) ? -1 : x - f); }
- inline bool isValid() const { return !isEmpty(); }
- inline bool isEmpty() const { return v ? vector.isEmpty() : (t < f); }
- inline void append(int x) { Q_ASSERT(v); vector.append(x); }
- inline int first() const { return v ? vector.first() : f; }
- inline int last() const { return v ? vector.last() : t; }
- inline int from() const { Q_ASSERT(!v); return f; }
- inline int to() const { Q_ASSERT(!v); return t; }
- inline int cost() const { return vector.count()+2; }
-
-private:
- bool v;
- QVector<int> vector;
- int f, t;
-};
-
-struct QMatchData {
- QMatchData() : exactMatchIndex(-1) { }
- QMatchData(const QIndexMapper& indices, int em, bool p) :
- indices(indices), exactMatchIndex(em), partial(p) { }
- QIndexMapper indices;
- inline bool isValid() const { return indices.isValid(); }
- int exactMatchIndex;
- bool partial;
-};
-
-class QCompletionEngine
-{
-public:
- typedef QMap<QString, QMatchData> CacheItem;
- typedef QMap<QModelIndex, CacheItem> Cache;
-
- QCompletionEngine(QCompleterPrivate *c) : c(c), curRow(-1), cost(0) { }
- virtual ~QCompletionEngine() { }
-
- void filter(const QStringList &parts);
-
- QMatchData filterHistory();
- bool matchHint(QString, const QModelIndex&, QMatchData*);
-
- void saveInCache(QString, const QModelIndex&, const QMatchData&);
- bool lookupCache(QString part, const QModelIndex& parent, QMatchData *m);
-
- virtual void filterOnDemand(int) { }
- virtual QMatchData filter(const QString&, const QModelIndex&, int) = 0;
-
- int matchCount() const { return curMatch.indices.count() + historyMatch.indices.count(); }
-
- QMatchData curMatch, historyMatch;
- QCompleterPrivate *c;
- QStringList curParts;
- QModelIndex curParent;
- int curRow;
-
- Cache cache;
- int cost;
-};
-
-class QSortedModelEngine : public QCompletionEngine
-{
-public:
- QSortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
- QMatchData filter(const QString&, const QModelIndex&, int);
- QIndexMapper indexHint(QString, const QModelIndex&, Qt::SortOrder);
- Qt::SortOrder sortOrder(const QModelIndex&) const;
-};
-
-class QUnsortedModelEngine : public QCompletionEngine
-{
-public:
- QUnsortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
-
- void filterOnDemand(int);
- QMatchData filter(const QString&, const QModelIndex&, int);
-private:
- int buildIndices(const QString& str, const QModelIndex& parent, int n,
- const QIndexMapper& iv, QMatchData* m);
-};
-
-class QCompleterItemDelegate : public QItemDelegate
-{
-public:
- QCompleterItemDelegate(QAbstractItemView *view)
- : QItemDelegate(view), view(view) { }
- void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const {
- QStyleOptionViewItem optCopy = opt;
- optCopy.showDecorationSelected = true;
- if (view->currentIndex() == idx)
- optCopy.state |= QStyle::State_HasFocus;
- QItemDelegate::paint(p, optCopy, idx);
- }
-
-private:
- QAbstractItemView *view;
-};
-
-class QCompletionModelPrivate;
-
-class QCompletionModel : public QAbstractProxyModel
-{
- Q_OBJECT
-
-public:
- QCompletionModel(QCompleterPrivate *c, QObject *parent);
-
- void createEngine();
- void setFiltered(bool);
- void filter(const QStringList& parts);
- int completionCount() const;
- int currentRow() const { return engine->curRow; }
- bool setCurrentRow(int row);
- QModelIndex currentIndex(bool) const;
- void resetModel();
-
- QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const;
- int rowCount(const QModelIndex &index = QModelIndex()) const;
- int columnCount(const QModelIndex &index = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex & = QModelIndex()) const { return QModelIndex(); }
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-
- void setSourceModel(QAbstractItemModel *sourceModel);
- QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
- QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
-
- QCompleterPrivate *c;
- QScopedPointer<QCompletionEngine> engine;
- bool showAll;
-
- Q_DECLARE_PRIVATE(QCompletionModel)
-
-signals:
- void rowsAdded();
-
-public Q_SLOTS:
- void invalidate();
- void rowsInserted();
- void modelDestroyed();
-};
-
-class QCompletionModelPrivate : public QAbstractProxyModelPrivate
-{
- Q_DECLARE_PUBLIC(QCompletionModel)
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_COMPLETER
-
-#endif // QCOMPLETER_P_H
diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp
deleted file mode 100644
index fdd2a95333..0000000000
--- a/src/gui/util/qflickgesture.cpp
+++ /dev/null
@@ -1,715 +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 "qgesture.h"
-#include "qapplication.h"
-#include "qevent.h"
-#include "qwidget.h"
-#include "qgraphicsitem.h"
-#include "qgraphicsscene.h"
-#include "qgraphicssceneevent.h"
-#include "qgraphicsview.h"
-#include "qscroller.h"
-#include "private/qevent_p.h"
-#include "private/qflickgesture_p.h"
-#include "qdebug.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-//#define QFLICKGESTURE_DEBUG
-
-#ifdef QFLICKGESTURE_DEBUG
-# define qFGDebug qDebug
-#else
-# define qFGDebug while (false) qDebug
-#endif
-
-extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
-static QMouseEvent *copyMouseEvent(QEvent *e)
-{
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove: {
- QMouseEvent *me = static_cast<QMouseEvent *>(e);
- return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers());
- }
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseMove: {
- QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e);
-#if 1
- QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress :
- (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove);
- return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers());
-#else
- QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type());
- copy->setPos(me->pos());
- copy->setScenePos(me->scenePos());
- copy->setScreenPos(me->screenPos());
- for (int i = 0x1; i <= 0x10; i <<= 1) {
- Qt::MouseButton button = Qt::MouseButton(i);
- copy->setButtonDownPos(button, me->buttonDownPos(button));
- copy->setButtonDownScenePos(button, me->buttonDownScenePos(button));
- copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button));
- }
- copy->setLastPos(me->lastPos());
- copy->setLastScenePos(me->lastScenePos());
- copy->setLastScreenPos(me->lastScreenPos());
- copy->setButtons(me->buttons());
- copy->setButton(me->button());
- copy->setModifiers(me->modifiers());
- return copy;
-#endif
- }
-#endif // QT_NO_GRAPHICSVIEW
- default:
- return 0;
- }
-}
-
-class PressDelayHandler : public QObject
-{
-private:
- PressDelayHandler(QObject *parent = 0)
- : QObject(parent)
- , pressDelayTimer(0)
- , sendingEvent(false)
- , mouseButton(Qt::NoButton)
- , mouseTarget(0)
- { }
-
- static PressDelayHandler *inst;
-
-public:
- enum {
- UngrabMouseBefore = 1,
- RegrabMouseAfterwards = 2
- };
-
- static PressDelayHandler *instance()
- {
- static PressDelayHandler *inst = 0;
- if (!inst)
- inst = new PressDelayHandler(QCoreApplication::instance());
- return inst;
- }
-
- bool shouldEventBeIgnored(QEvent *) const
- {
- return sendingEvent;
- }
-
- bool isDelaying() const
- {
- return !pressDelayEvent.isNull();
- }
-
- void pressed(QEvent *e, int delay)
- {
- if (!pressDelayEvent) {
- pressDelayEvent.reset(copyMouseEvent(e));
- pressDelayTimer = startTimer(delay);
- mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos());
- mouseButton = pressDelayEvent->button();
- qFGDebug() << "QFG: consuming/delaying mouse press";
- } else {
- qFGDebug() << "QFG: NOT consuming/delaying mouse press";
- }
- e->setAccepted(true);
- }
-
- bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive)
- {
- // consume this event if the scroller was or is active
- bool result = scrollerWasActive || scrollerIsActive;
-
- // stop the timer
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- // we still haven't even sent the press, so do it now
- if (pressDelayEvent && mouseTarget && !scrollerIsActive) {
- QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e));
-
- qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget;
- sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
-
- qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget;
- sendMouseEvent(releaseEvent.data());
-
- result = true; // consume this event
- } else if (mouseTarget && scrollerIsActive) {
- // we grabbed the mouse expicitly when the scroller became active, so undo that now
- sendMouseEvent(0, UngrabMouseBefore);
- }
- pressDelayEvent.reset(0);
- mouseTarget = 0;
- return result;
- }
-
- void scrollerWasIntercepted()
- {
- qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted";
- if (pressDelayEvent) {
- // we still haven't even sent the press, so just throw it away now
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- pressDelayEvent.reset(0);
- }
- mouseTarget = 0;
- }
-
- void scrollerBecameActive()
- {
- if (pressDelayEvent) {
- // we still haven't even sent the press, so just throw it away now
- qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now";
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- pressDelayEvent.reset(0);
- mouseTarget = 0;
- } else if (mouseTarget) {
- // we did send a press, so we need to fake a release now
- Qt::MouseButtons mouseButtons = QApplication::mouseButtons();
-
- // release all pressed mouse buttons
- /*for (int i = 0; i < 32; ++i) {
- if (mouseButtons & (1 << i)) {
- Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
- mouseButtons &= ~b;
- QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
-
- qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
- QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
- b, mouseButtons, QApplication::keyboardModifiers());
- sendMouseEvent(&re);
- }
- }*/
-
- QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
-
- qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
- QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
- mouseButton, QApplication::mouseButtons() & ~mouseButton,
- QApplication::keyboardModifiers());
- sendMouseEvent(&re, RegrabMouseAfterwards);
- // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release!
- }
- }
-
-protected:
- void timerEvent(QTimerEvent *e)
- {
- if (e->timerId() == pressDelayTimer) {
- if (pressDelayEvent && mouseTarget) {
- qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget;
- sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
- }
- pressDelayEvent.reset(0);
-
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- }
- }
-
- void sendMouseEvent(QMouseEvent *me, int flags = 0)
- {
- if (mouseTarget) {
- sendingEvent = true;
-
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsItem *grabber = 0;
- if (mouseTarget->parentWidget()) {
- if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
- if (gv->scene())
- grabber = gv->scene()->mouseGrabberItem();
- }
- }
-
- if (grabber && (flags & UngrabMouseBefore)) {
- // GraphicsView Mouse Handling Workaround #1:
- // we need to ungrab the mouse before re-sending the press,
- // since the scene had already set the mouse grabber to the
- // original (and consumed) event's receiver
- qFGDebug() << "QFG: ungrabbing" << grabber;
- grabber->ungrabMouse();
- }
-#endif // QT_NO_GRAPHICSVIEW
-
- if (me) {
- QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers());
- qt_sendSpontaneousEvent(mouseTarget, &copy);
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (grabber && (flags & RegrabMouseAfterwards)) {
- // GraphicsView Mouse Handling Workaround #2:
- // we need to re-grab the mouse after sending a faked mouse
- // release, since we still need the mouse moves for the gesture
- // (the scene will clear the item's mouse grabber status on
- // release).
- qFGDebug() << "QFG: re-grabbing" << grabber;
- grabber->grabMouse();
- }
-#endif
- sendingEvent = false;
- }
- }
-
-
-private:
- int pressDelayTimer;
- QScopedPointer<QMouseEvent> pressDelayEvent;
- bool sendingEvent;
- Qt::MouseButton mouseButton;
- QPointer<QWidget> mouseTarget;
-};
-
-
-/*!
- \internal
- \class QFlickGesture
- \since 4.8
- \brief The QFlickGesture class describes a flicking gesture made by the user.
- \ingroup gestures
- The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties
- to decide if it is triggered.
- This gesture is reacting on touch event as compared to the QMouseFlickGesture.
-
- \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture
-*/
-
-/*!
- \internal
-*/
-QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent)
- : QGesture(*new QFlickGesturePrivate, parent)
-{
- d_func()->q_ptr = this;
- d_func()->receiver = receiver;
- d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0;
- d_func()->button = button;
-}
-
-QFlickGesture::~QFlickGesture()
-{ }
-
-QFlickGesturePrivate::QFlickGesturePrivate()
- : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false)
-{ }
-
-
-//
-// QFlickGestureRecognizer
-//
-
-
-QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button)
-{
- this->button = button;
-}
-
-/*! \reimp
- */
-QGesture *QFlickGestureRecognizer::create(QObject *target)
-{
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
- if (go && button == Qt::NoButton) {
- go->setAcceptTouchEvents(true);
- }
-#endif
- return new QFlickGesture(target, button);
-}
-
-/*! \internal
- The recognize function detects a touch event suitable to start the attached QScroller.
- The QFlickGesture will be triggered as soon as the scroller is no longer in the state
- QScroller::Inactive or QScroller::Pressed. It will be finished or canceled
- at the next QEvent::TouchEnd.
- Note that the QScroller might continue scrolling (kinetically) at this point.
- */
-QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
- QObject *watched,
- QEvent *event)
-{
- Q_UNUSED(watched);
-
- static QElapsedTimer monotonicTimer;
- if (!monotonicTimer.isValid())
- monotonicTimer.start();
-
- QFlickGesture *q = static_cast<QFlickGesture *>(state);
- QFlickGesturePrivate *d = q->d_func();
-
- QScroller *scroller = d->receiverScroller;
- if (!scroller)
- return Ignore; // nothing to do without a scroller?
-
- QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
-#endif
-
- // this is only set for events that we inject into the event loop via sendEvent()
- if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
- //qFGDebug() << state << "QFG: ignored event: " << event->type();
- return Ignore;
- }
-
- const QMouseEvent *me = 0;
-#ifndef QT_NO_GRAPHICSVIEW
- const QGraphicsSceneMouseEvent *gsme = 0;
-#endif
- const QTouchEvent *te = 0;
- QPoint globalPos;
-
- // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button;
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- if (!receiverWidget)
- return Ignore;
- if (button != Qt::NoButton) {
- me = static_cast<const QMouseEvent *>(event);
- globalPos = me->globalPos();
- }
- break;
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseMove:
- if (!receiverGraphicsObject)
- return Ignore;
- if (button != Qt::NoButton) {
- gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
- globalPos = gsme->screenPos();
- }
- break;
-#endif
- case QEvent::TouchBegin:
- case QEvent::TouchEnd:
- case QEvent::TouchUpdate:
- if (button == Qt::NoButton) {
- te = static_cast<const QTouchEvent *>(event);
- if (!te->touchPoints().isEmpty())
- globalPos = te->touchPoints().at(0).screenPos().toPoint();
- }
- break;
-
-#if defined(Q_WS_MAC)
- // the only way to distinguish between real mouse wheels and wheel
- // events generated by the native 2 finger swipe gesture is to listen
- // for these events (according to Apple's Cocoa Event-Handling Guide)
-
- case QEvent::NativeGesture: {
- QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event);
- if (nge->gestureType == QNativeGestureEvent::GestureBegin)
- d->macIgnoreWheel = true;
- else if (nge->gestureType == QNativeGestureEvent::GestureEnd)
- d->macIgnoreWheel = false;
- break;
- }
-#endif
-
- // consume all wheel events if the scroller is active
- case QEvent::Wheel:
- if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive))
- return Ignore | ConsumeEventHint;
- break;
-
- // consume all dbl click events if the scroller is active
- case QEvent::MouseButtonDblClick:
- if (scroller->state() != QScroller::Inactive)
- return Ignore | ConsumeEventHint;
- break;
-
- default:
- break;
- }
-
- if (!me
-#ifndef QT_NO_GRAPHICSVIEW
- && !gsme
-#endif
- && !te) // Neither mouse nor touch
- return Ignore;
-
- // get the current pointer position in local coordinates.
- QPointF point;
- QScroller::Input inputType = (QScroller::Input) 0;
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- if (me && me->button() == button && me->buttons() == button) {
- point = me->globalPos();
- inputType = QScroller::InputPress;
- } else if (me) {
- scroller->stop();
- return CancelGesture;
- }
- break;
- case QEvent::MouseButtonRelease:
- if (me && me->button() == button) {
- point = me->globalPos();
- inputType = QScroller::InputRelease;
- }
- break;
- case QEvent::MouseMove:
-#ifdef Q_OS_SYMBIAN
- // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
- // relies on the windowing system to report the current buttons state.
- if (me && (me->buttons() == button || !me->buttons())) {
-#else
- if (me && me->buttons() == button) {
-#endif
- point = me->globalPos();
- inputType = QScroller::InputMove;
- }
- break;
-
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- if (gsme && gsme->button() == button && gsme->buttons() == button) {
- point = gsme->scenePos();
- inputType = QScroller::InputPress;
- } else if (gsme) {
- scroller->stop();
- return CancelGesture;
- }
- break;
- case QEvent::GraphicsSceneMouseRelease:
- if (gsme && gsme->button() == button) {
- point = gsme->scenePos();
- inputType = QScroller::InputRelease;
- }
- break;
- case QEvent::GraphicsSceneMouseMove:
-#ifdef Q_OS_SYMBIAN
- // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
- // relies on the windowing system to report the current buttons state.
- if (gsme && (gsme->buttons() == button || !me->buttons())) {
-#else
- if (gsme && gsme->buttons() == button) {
-#endif
- point = gsme->scenePos();
- inputType = QScroller::InputMove;
- }
- break;
-#endif
-
- case QEvent::TouchBegin:
- inputType = QScroller::InputPress;
- // fall through
- case QEvent::TouchEnd:
- if (!inputType)
- inputType = QScroller::InputRelease;
- // fallthrough
- case QEvent::TouchUpdate:
- if (!inputType)
- inputType = QScroller::InputMove;
-
- if (te->deviceType() == QTouchEvent::TouchPad) {
- if (te->touchPoints().count() != 2) // 2 fingers on pad
- return Ignore;
-
- point = te->touchPoints().at(0).startScenePos() +
- ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) +
- (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2;
- } else { // TouchScreen
- if (te->touchPoints().count() != 1) // 1 finger on screen
- return Ignore;
-
- point = te->touchPoints().at(0).scenePos();
- }
- break;
-
- default:
- break;
- }
-
- // Check for an active scroller at globalPos
- if (inputType == QScroller::InputPress) {
- foreach (QScroller *as, QScroller::activeScrollers()) {
- if (as != scroller) {
- QRegion scrollerRegion;
-
- if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
- scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
-#ifndef QT_NO_GRAPHICSVIEW
- } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
- if (go->scene() && !go->scene()->views().isEmpty()) {
- foreach (QGraphicsView *gv, go->scene()->views())
- scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
- .translated(gv->mapToGlobal(QPoint(0, 0)));
- }
-#endif
- }
- // active scrollers always have priority
- if (scrollerRegion.contains(globalPos))
- return Ignore;
- }
- }
- }
-
- bool scrollerWasDragging = (scroller->state() == QScroller::Dragging);
- bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling);
-
- if (inputType) {
- if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
- point = w->mapFromGlobal(point.toPoint());
-#ifndef QT_NO_GRAPHICSVIEW
- else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
- point = go->mapFromScene(point);
-#endif
-
- // inform the scroller about the new event
- scroller->handleInput(inputType, point, monotonicTimer.elapsed());
- }
-
- // depending on the scroller state return the gesture state
- Result result(0);
- bool scrollerIsActive = (scroller->state() == QScroller::Dragging ||
- scroller->state() == QScroller::Scrolling);
-
- // Consume all mouse events while dragging or scrolling to avoid nasty
- // side effects with Qt's standard widgets.
- if ((me
-#ifndef QT_NO_GRAPHICSVIEW
- || gsme
-#endif
- ) && scrollerIsActive)
- result |= ConsumeEventHint;
-
- // The only problem with this approach is that we consume the
- // MouseRelease when we start the scrolling with a flick gesture, so we
- // have to fake a MouseRelease "somewhere" to not mess with the internal
- // states of Qt's widgets (a QPushButton would stay in 'pressed' state
- // forever, if it doesn't receive a MouseRelease).
- if (me
-#ifndef QT_NO_GRAPHICSVIEW
- || gsme
-#endif
- ) {
- if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
- PressDelayHandler::instance()->scrollerBecameActive();
- else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
- PressDelayHandler::instance()->scrollerWasIntercepted();
- }
-
- if (!inputType) {
- result |= Ignore;
- } else {
- switch (event->type()) {
- case QEvent::MouseButtonPress:
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
-#endif
- if (scroller->state() == QScroller::Pressed) {
- int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
- if (pressDelay > 0) {
- result |= ConsumeEventHint;
-
- PressDelayHandler::instance()->pressed(event, pressDelay);
- event->accept();
- }
- }
- // fall through
- case QEvent::TouchBegin:
- q->setHotSpot(globalPos);
- result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
- break;
-
- case QEvent::MouseMove:
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseMove:
-#endif
- if (PressDelayHandler::instance()->isDelaying())
- result |= ConsumeEventHint;
- // fall through
- case QEvent::TouchUpdate:
- result |= scrollerIsActive ? TriggerGesture : Ignore;
- break;
-
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseRelease:
-#endif
- case QEvent::MouseButtonRelease:
- if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
- result |= ConsumeEventHint;
- // fall through
- case QEvent::TouchEnd:
- result |= scrollerIsActive ? FinishGesture : CancelGesture;
- break;
-
- default:
- result |= Ignore;
- break;
- }
- }
- return result;
-}
-
-
-/*! \reimp
- */
-void QFlickGestureRecognizer::reset(QGesture *state)
-{
- QGestureRecognizer::reset(state);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
diff --git a/src/gui/util/qflickgesture_p.h b/src/gui/util/qflickgesture_p.h
deleted file mode 100644
index 451b579edd..0000000000
--- a/src/gui/util/qflickgesture_p.h
+++ /dev/null
@@ -1,113 +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 QFLICKGESTURE_P_H
-#define QFLICKGESTURE_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 "qevent.h"
-#include "qgesturerecognizer.h"
-#include "private/qgesture_p.h"
-#include "qscroller.h"
-#include "qscopedpointer.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-class QFlickGesturePrivate;
-class QGraphicsItem;
-
-class Q_GUI_EXPORT QFlickGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QFlickGesture)
-
-public:
- QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent = 0);
- ~QFlickGesture();
-
- friend class QFlickGestureRecognizer;
-};
-
-class PressDelayHandler;
-
-class QFlickGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QFlickGesture)
-public:
- QFlickGesturePrivate();
-
- QPointer<QObject> receiver;
- QScroller *receiverScroller;
- Qt::MouseButton button; // NoButton == Touch
- bool macIgnoreWheel;
- static PressDelayHandler *pressDelayHandler;
-};
-
-class QFlickGestureRecognizer : public QGestureRecognizer
-{
-public:
- QFlickGestureRecognizer(Qt::MouseButton button);
-
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
- void reset(QGesture *state);
-
-private:
- Qt::MouseButton button; // NoButton == Touch
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
-
-#endif // QFLICKGESTURE_P_H
diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp
deleted file mode 100644
index db128c136a..0000000000
--- a/src/gui/util/qscroller.cpp
+++ /dev/null
@@ -1,2059 +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 "qevent.h"
-#include "qwidget.h"
-#include "qscroller.h"
-#include "private/qflickgesture_p.h"
-#include "private/qscroller_p.h"
-#include "qscrollerproperties.h"
-#include "private/qscrollerproperties_p.h"
-#include "qnumeric.h"
-#include "math.h"
-
-#include <QTime>
-#include <QElapsedTimer>
-#include <QMap>
-#include <QApplication>
-#include <QAbstractScrollArea>
-#include <QGraphicsObject>
-#include <QGraphicsScene>
-#include <QGraphicsView>
-#include <QDesktopWidget>
-#include <QtCore/qmath.h>
-#include <QtGui/qevent.h>
-#include <qnumeric.h>
-
-#include <QtDebug>
-
-#if defined(Q_WS_X11)
-# include "private/qt_x11_p.h"
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
-//#define QSCROLLER_DEBUG
-
-#ifdef QSCROLLER_DEBUG
-# define qScrollerDebug qDebug
-#else
-# define qScrollerDebug while (false) qDebug
-#endif
-
-QDebug &operator<<(QDebug &dbg, const QScrollerPrivate::ScrollSegment &s)
-{
- dbg << "\n Time: start:" << s.startTime << " duration:" << s.deltaTime << " stop progress:" << s.stopProgress;
- dbg << "\n Pos: start:" << s.startPos << " delta:" << s.deltaPos << " stop:" << s.stopPos;
- dbg << "\n Curve: type:" << s.curve.type() << "\n";
- return dbg;
-}
-
-
-// a few helper operators to make the code below a lot more readable:
-// otherwise a lot of ifs would have to be multi-line to check both the x
-// and y coordinate separately.
-
-// returns true only if the abs. value of BOTH x and y are <= f
-inline bool operator<=(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f);
-}
-
-// returns true only if the abs. value of BOTH x and y are < f
-inline bool operator<(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) < f) && (qAbs(p.y()) < f);
-}
-
-// returns true if the abs. value of EITHER x or y are >= f
-inline bool operator>=(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f);
-}
-
-// returns true if the abs. value of EITHER x or y are > f
-inline bool operator>(const QPointF &p, qreal f)
-{
- return (qAbs(p.x()) > f) || (qAbs(p.y()) > f);
-}
-
-// returns a new point with both coordinates having the abs. value of the original one
-inline QPointF qAbs(const QPointF &p)
-{
- return QPointF(qAbs(p.x()), qAbs(p.y()));
-}
-
-// returns a new point with all components of p1 multiplied by the corresponding components of p2
-inline QPointF operator*(const QPointF &p1, const QPointF &p2)
-{
- return QPointF(p1.x() * p2.x(), p1.y() * p2.y());
-}
-
-// returns a new point with all components of p1 divided by the corresponding components of p2
-inline QPointF operator/(const QPointF &p1, const QPointF &p2)
-{
- return QPointF(p1.x() / p2.x(), p1.y() / p2.y());
-}
-
-inline QPointF clampToRect(const QPointF &p, const QRectF &rect)
-{
- qreal x = qBound(rect.left(), p.x(), rect.right());
- qreal y = qBound(rect.top(), p.y(), rect.bottom());
- return QPointF(x, y);
-}
-
-// returns -1, 0 or +1 according to r being <0, ==0 or >0
-inline int qSign(qreal r)
-{
- return (r < 0) ? -1 : ((r > 0) ? 1 : 0);
-}
-
-// this version is not mathematically exact, but it just works for every
-// easing curve type (even custom ones)
-
-static qreal differentialForProgress(const QEasingCurve &curve, qreal pos)
-{
- const qreal dx = 0.01;
- qreal left = (pos < qreal(0.5)) ? pos : pos - qreal(dx);
- qreal right = (pos >= qreal(0.5)) ? pos : pos + qreal(dx);
- qreal d = (curve.valueForProgress(right) - curve.valueForProgress(left)) / qreal(dx);
-
- //qScrollerDebug() << "differentialForProgress(type: " << curve.type() << ", pos: " << pos << ") = " << d;
-
- return d;
-}
-
-// this version is not mathematically exact, but it just works for every
-// easing curve type (even custom ones)
-
-static qreal progressForValue(const QEasingCurve &curve, qreal value)
-{
- if (curve.type() >= QEasingCurve::InElastic &&
- curve.type() < QEasingCurve::Custom) {
- qWarning("progressForValue(): QEasingCurves of type %d do not have an inverse, since they are not injective.", curve.type());
- return value;
- }
- if (value < qreal(0) || value > qreal(1))
- return value;
-
- qreal progress = value, left(0), right(1);
- for (int iterations = 6; iterations; --iterations) {
- qreal v = curve.valueForProgress(progress);
- if (v < value)
- left = progress;
- else if (v > value)
- right = progress;
- else
- break;
- progress = (left + right) / qreal(2);
- }
- return progress;
-}
-
-
-#ifndef QT_NO_ANIMATION
-class QScrollTimer : public QAbstractAnimation
-{
-public:
- QScrollTimer(QScrollerPrivate *_d)
- : d(_d), ignoreUpdate(false), skip(0)
- { }
-
- int duration() const
- {
- return -1;
- }
-
- void start()
- {
- // QAbstractAnimation::start() will immediately call
- // updateCurrentTime(), but our state is not set correctly yet
- ignoreUpdate = true;
- QAbstractAnimation::start();
- ignoreUpdate = false;
- skip = 0;
- }
-
-protected:
- void updateCurrentTime(int /*currentTime*/)
- {
- if (!ignoreUpdate) {
- if (++skip >= d->frameRateSkip()) {
- skip = 0;
- d->timerTick();
- }
- }
- }
-
-private:
- QScrollerPrivate *d;
- bool ignoreUpdate;
- int skip;
-};
-#endif // QT_NO_ANIMATION
-
-/*!
- \class QScroller
- \brief The QScroller class enables kinetic scrolling for any scrolling widget or graphics item.
- \since 4.8
-
- With kinetic scrolling, the user can push the widget in a given
- direction and it will continue to scroll in this direction until it is
- stopped either by the user or by friction. Aspects of inertia, friction
- and other physical concepts can be changed in order to fine-tune an
- intuitive user experience.
-
- The QScroller object is the object that stores the current position and
- scrolling speed and takes care of updates.
- QScroller can be triggered by a flick gesture
-
- \code
- QWidget *w = ...;
- QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture);
- \endcode
-
- or directly like this:
-
- \code
- QWidget *w = ...;
- QScroller *scroller = QScroller::scroller(w);
- scroller->scrollTo(QPointF(100, 100));
- \endcode
-
- The scrolled QObjects receive a QScrollPrepareEvent whenever the scroller needs to
- update its geometry information and a QScrollEvent whenever the content of the object should
- actually be scrolled.
-
- The scroller uses the global QAbstractAnimation timer to generate its QScrollEvents. This
- can be changed with QScrollerProperties::FrameRate on a per-QScroller basis.
-
- Several examples in the \c scroller examples directory show how QScroller,
- QScrollEvent and the scroller gesture can be used.
-
- Even though this kinetic scroller has a large number of settings available via
- QScrollerProperties, we recommend that you leave them all at their default, platform optimized
- values. Before changing them you can experiment with the \c plot example in
- the \c scroller examples directory.
-
- \sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties
-*/
-
-typedef QMap<QObject *, QScroller *> ScrollerHash;
-typedef QSet<QScroller *> ScrollerSet;
-
-Q_GLOBAL_STATIC(ScrollerHash, qt_allScrollers)
-Q_GLOBAL_STATIC(ScrollerSet, qt_activeScrollers)
-
-/*!
- Returns \c true if a QScroller object was already created for \a target; \c false otherwise.
-
- \sa scroller()
-*/
-bool QScroller::hasScroller(QObject *target)
-{
- return (qt_allScrollers()->value(target));
-}
-
-/*!
- Returns the scroller for the given \a target.
- As long as the object exists this function will always return the same QScroller instance.
- If no QScroller exists for the \a target, one will implicitly be created.
- At no point more than one QScroller will be active on an object.
-
- \sa hasScroller(), target()
-*/
-QScroller *QScroller::scroller(QObject *target)
-{
- if (!target) {
- qWarning("QScroller::scroller() was called with a null target.");
- return 0;
- }
-
- if (qt_allScrollers()->contains(target))
- return qt_allScrollers()->value(target);
-
- QScroller *s = new QScroller(target);
- qt_allScrollers()->insert(target, s);
- return s;
-}
-
-/*!
- \overload
- This is the const version of scroller().
-*/
-const QScroller *QScroller::scroller(const QObject *target)
-{
- return scroller(const_cast<QObject*>(target));
-}
-
-/*!
- Returns an application wide list of currently active QScroller objects.
- Active QScroller objects are in a state() that is not QScroller::Inactive.
- This function is useful when writing your own gesture recognizer.
-*/
-QList<QScroller *> QScroller::activeScrollers()
-{
- return qt_activeScrollers()->toList();
-}
-
-/*!
- Returns the target object of this scroller.
- \sa hasScroller(), scroller()
- */
-QObject *QScroller::target() const
-{
- Q_D(const QScroller);
- return d->target;
-}
-
-/*!
- \fn QScroller::scrollerPropertiesChanged(const QScrollerProperties &newProperties);
-
- QScroller emits this signal whenever its scroller properties change.
- \a newProperties are the new scroller properties.
-
- \sa scrollerProperties
-*/
-
-
-/*! \property QScroller::scrollerProperties
- \brief The scroller properties of this scroller.
- The properties are used by the QScroller to determine its scrolling behavior.
-*/
-QScrollerProperties QScroller::scrollerProperties() const
-{
- Q_D(const QScroller);
- return d->properties;
-}
-
-void QScroller::setScrollerProperties(const QScrollerProperties &sp)
-{
- Q_D(QScroller);
- if (d->properties != sp) {
- d->properties = sp;
- emit scrollerPropertiesChanged(sp);
-
- // we need to force the recalculation here, since the overshootPolicy may have changed and
- // existing segments may include an overshoot animation.
- d->recalcScrollingSegments(true);
- }
-}
-
-#ifndef QT_NO_GESTURES
-
-/*!
- Registers a custom scroll gesture recognizer, grabs it for the \a
- target and returns the resulting gesture type. If \a scrollGestureType is
- set to TouchGesture the gesture triggers on touch events. If it is set to
- one of LeftMouseButtonGesture, RightMouseButtonGesture or
- MiddleMouseButtonGesture it triggers on mouse events of the
- corresponding button.
-
- Only one scroll gesture can be active on a single object at the same
- time. If you call this function twice on the same object, it will
- ungrab the existing gesture before grabbing the new one.
-
- \note To avoid unwanted side-effects, mouse events are consumed while
- the gesture is triggered. Since the initial mouse press event is
- not consumed, the gesture sends a fake mouse release event
- at the global position \c{(INT_MIN, INT_MIN)}. This ensures that
- internal states of the widget that received the original mouse press
- are consistent.
-
- \sa ungrabGesture, grabbedGesture
-*/
-Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scrollGestureType)
-{
- // ensure that a scroller for target is created
- QScroller *s = scroller(target);
- if (!s)
- return Qt::GestureType(0);
-
- QScrollerPrivate *sp = s->d_ptr;
- if (sp->recognizer)
- ungrabGesture(target); // ungrab the old gesture
-
- Qt::MouseButton button;
- switch (scrollGestureType) {
- case LeftMouseButtonGesture : button = Qt::LeftButton; break;
- case RightMouseButtonGesture : button = Qt::RightButton; break;
- case MiddleMouseButtonGesture: button = Qt::MiddleButton; break;
- default :
- case TouchGesture : button = Qt::NoButton; break; // NoButton == Touch
- }
-
- sp->recognizer = new QFlickGestureRecognizer(button);
- sp->recognizerType = QGestureRecognizer::registerRecognizer(sp->recognizer);
-
- if (target->isWidgetType()) {
- QWidget *widget = static_cast<QWidget *>(target);
- widget->grabGesture(sp->recognizerType);
- if (scrollGestureType == TouchGesture)
- widget->setAttribute(Qt::WA_AcceptTouchEvents);
-#ifndef QT_NO_GRAPHICSVIEW
- } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) {
- if (scrollGestureType == TouchGesture)
- go->setAcceptTouchEvents(true);
- go->grabGesture(sp->recognizerType);
-#endif // QT_NO_GRAPHICSVIEW
- }
- return sp->recognizerType;
-}
-
-/*!
- Returns the gesture type currently grabbed for the \a target or 0 if no
- gesture is grabbed.
-
- \sa grabGesture, ungrabGesture
-*/
-Qt::GestureType QScroller::grabbedGesture(QObject *target)
-{
- QScroller *s = scroller(target);
- if (s && s->d_ptr)
- return s->d_ptr->recognizerType;
- else
- return Qt::GestureType(0);
-}
-
-/*!
- Ungrabs the gesture for the \a target.
- Does nothing if no gesture is grabbed.
-
- \sa grabGesture, grabbedGesture
-*/
-void QScroller::ungrabGesture(QObject *target)
-{
- QScroller *s = scroller(target);
- if (!s)
- return;
-
- QScrollerPrivate *sp = s->d_ptr;
- if (!sp->recognizer)
- return; // nothing to do
-
- if (target->isWidgetType()) {
- QWidget *widget = static_cast<QWidget *>(target);
- widget->ungrabGesture(sp->recognizerType);
-#ifndef QT_NO_GRAPHICSVIEW
- } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) {
- go->ungrabGesture(sp->recognizerType);
-#endif
- }
-
- QGestureRecognizer::unregisterRecognizer(sp->recognizerType);
- // do not delete the recognizer. The QGestureManager is doing this.
- sp->recognizer = 0;
-}
-
-#endif // QT_NO_GESTURES
-
-/*!
- \internal
-*/
-QScroller::QScroller(QObject *target)
- : d_ptr(new QScrollerPrivate(this, target))
-{
- Q_ASSERT(target); // you can't create a scroller without a target in any normal way
- Q_D(QScroller);
- d->init();
-}
-
-/*!
- \internal
-*/
-QScroller::~QScroller()
-{
- Q_D(QScroller);
-#ifndef QT_NO_GESTURES
- QGestureRecognizer::unregisterRecognizer(d->recognizerType);
- // do not delete the recognizer. The QGestureManager is doing this.
- d->recognizer = 0;
-#endif
- qt_allScrollers()->remove(d->target);
- qt_activeScrollers()->remove(this);
-
- delete d_ptr;
-}
-
-
-/*!
- \fn QScroller::stateChanged(QScroller::State newState);
-
- QScroller emits this signal whenever the state changes. \a newState is the new State.
-
- \sa state
-*/
-
-/*!
- \property QScroller::state
- \brief the state of the scroller
-
- \sa QScroller::State
-*/
-QScroller::State QScroller::state() const
-{
- Q_D(const QScroller);
- return d->state;
-}
-
-/*!
- Stops the scroller and resets its state back to Inactive.
-*/
-void QScroller::stop()
-{
- Q_D(QScroller);
- if (d->state != Inactive) {
- QPointF here = clampToRect(d->contentPosition, d->contentPosRange);
- qreal snapX = d->nextSnapPos(here.x(), 0, Qt::Horizontal);
- qreal snapY = d->nextSnapPos(here.y(), 0, Qt::Vertical);
- QPointF snap = here;
- if (!qIsNaN(snapX))
- snap.setX(snapX);
- if (!qIsNaN(snapY))
- snap.setY(snapY);
- d->contentPosition = snap;
- d->overshootPosition = QPointF(0, 0);
-
- d->setState(Inactive);
- }
-}
-
-/*!
- Returns the pixel per meter metric for the scrolled widget.
-
- The value is reported for both the x and y axis separately by using a QPointF.
-
- \note Please note that this value should be physically correct. The actual DPI settings
- that Qt returns for the display may be reported wrongly on purpose by the underlying
- windowing system, for example on Mac OS X or Maemo 5.
-*/
-QPointF QScroller::pixelPerMeter() const
-{
- Q_D(const QScroller);
- QPointF ppm = d->pixelPerMeter;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->target)) {
- QTransform viewtr;
- //TODO: the first view isn't really correct - maybe use an additional field in the prepare event?
- if (go->scene() && !go->scene()->views().isEmpty())
- viewtr = go->scene()->views().first()->viewportTransform();
- QTransform tr = go->deviceTransform(viewtr);
- if (tr.isScaling()) {
- QPointF p0 = tr.map(QPointF(0, 0));
- QPointF px = tr.map(QPointF(1, 0));
- QPointF py = tr.map(QPointF(0, 1));
- ppm.rx() /= QLineF(p0, px).length();
- ppm.ry() /= QLineF(p0, py).length();
- }
- }
-#endif // QT_NO_GRAPHICSVIEW
- return ppm;
-}
-
-/*!
- Returns the current scrolling velocity in meter per second when the state is Scrolling or Dragging.
- Returns a zero velocity otherwise.
-
- The velocity is reported for both the x and y axis separately by using a QPointF.
-
- \sa pixelPerMeter()
-*/
-QPointF QScroller::velocity() const
-{
- Q_D(const QScroller);
- const QScrollerPropertiesPrivate *sp = d->properties.d.data();
-
- switch (state()) {
- case Dragging:
- return d->releaseVelocity;
- case Scrolling: {
- QPointF vel;
- qint64 now = d->monotonicTimer.elapsed();
-
- if (!d->xSegments.isEmpty()) {
- const QScrollerPrivate::ScrollSegment &s = d->xSegments.head();
- qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime);
- qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress);
- vel.setX(v);
- }
-
- if (!d->ySegments.isEmpty()) {
- const QScrollerPrivate::ScrollSegment &s = d->ySegments.head();
- qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime);
- qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress);
- vel.setY(v);
- }
- return vel;
- }
- default:
- return QPointF(0, 0);
- }
-}
-
-/*!
- Returns the estimated final position for the current scroll movement.
- Returns the current position if the scroller state is not Scrolling.
- The result is undefined when the scroller state is Inactive.
-
- The target position is in pixel.
-
- \sa pixelPerMeter(), scrollTo()
-*/
-QPointF QScroller::finalPosition() const
-{
- Q_D(const QScroller);
- return QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal),
- d->scrollingSegmentsEndPos(Qt::Vertical));
-}
-
-/*!
- Starts scrolling the widget so that point \a pos is at the top-left position in
- the viewport.
-
- The behaviour when scrolling outside the valid scroll area is undefined.
- In this case the scroller might or might not overshoot.
-
- The scrolling speed will be calculated so that the given position will
- be reached after a platform-defined time span.
-
- \a pos is given in viewport coordinates.
-
- \sa ensureVisible()
-*/
-void QScroller::scrollTo(const QPointF &pos)
-{
- // we could make this adjustable via QScrollerProperties
- scrollTo(pos, 300);
-}
-
-/*! \overload
-
- This version will reach its destination position in \a scrollTime milliseconds.
-*/
-void QScroller::scrollTo(const QPointF &pos, int scrollTime)
-{
- Q_D(QScroller);
-
- if (d->state == Pressed || d->state == Dragging )
- return;
-
- // no need to resend a prepare event if we are already scrolling
- if (d->state == Inactive && !d->prepareScrolling(QPointF()))
- return;
-
- QPointF newpos = clampToRect(pos, d->contentPosRange);
- qreal snapX = d->nextSnapPos(newpos.x(), 0, Qt::Horizontal);
- qreal snapY = d->nextSnapPos(newpos.y(), 0, Qt::Vertical);
- if (!qIsNaN(snapX))
- newpos.setX(snapX);
- if (!qIsNaN(snapY))
- newpos.setY(snapY);
-
- qScrollerDebug() << "QScroller::scrollTo(req:" << pos << " [pix] / snap:" << newpos << ", " << scrollTime << " [ms])";
-
- if (newpos == d->contentPosition + d->overshootPosition)
- return;
-
- QPointF vel = velocity();
-
- if (scrollTime < 0)
- scrollTime = 0;
- qreal time = qreal(scrollTime) / 1000;
-
- d->createScrollToSegments(vel.x(), time, newpos.x(), Qt::Horizontal, QScrollerPrivate::ScrollTypeScrollTo);
- d->createScrollToSegments(vel.y(), time, newpos.y(), Qt::Vertical, QScrollerPrivate::ScrollTypeScrollTo);
-
- if (!scrollTime)
- d->setContentPositionHelperScrolling();
- d->setState(scrollTime ? Scrolling : Inactive);
-}
-
-/*!
- Starts scrolling so that the rectangle \a rect is visible inside the
- viewport with additional margins specified in pixels by \a xmargin and \a ymargin around
- the rect.
-
- In cases where it is not possible to fit the rect plus margins inside the viewport the contents
- are scrolled so that as much as possible is visible from \a rect.
-
- The scrolling speed is calculated so that the given position is reached after a platform-defined
- time span.
-
- This function performs the actual scrolling by calling scrollTo().
-
- \sa scrollTo
-*/
-void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin)
-{
- // we could make this adjustable via QScrollerProperties
- ensureVisible(rect, xmargin, ymargin, 1000);
-}
-
-/*! \overload
-
- This version will reach its destination position in \a scrollTime milliseconds.
-*/
-void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime)
-{
- Q_D(QScroller);
-
- if (d->state == Pressed || d->state == Dragging )
- return;
-
- if (d->state == Inactive && !d->prepareScrolling(QPointF()))
- return;
-
- // -- calculate the current pos (or the position after the current scroll)
- QPointF startPos = d->contentPosition + d->overshootPosition;
- startPos = QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal),
- d->scrollingSegmentsEndPos(Qt::Vertical));
-
- QRectF marginRect(rect.x() - xmargin, rect.y() - ymargin,
- rect.width() + 2 * xmargin, rect.height() + 2 * ymargin);
-
- QSizeF visible = d->viewportSize;
- QRectF visibleRect(startPos, visible);
-
- qScrollerDebug() << "QScroller::ensureVisible(" << rect << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])";
- qScrollerDebug() << " --> content position:" << d->contentPosition;
-
- if (visibleRect.contains(marginRect))
- return;
-
- QPointF newPos = startPos;
-
- if (visibleRect.width() < rect.width()) {
- // at least try to move the rect into view
- if (rect.left() > visibleRect.left())
- newPos.setX(rect.left());
- else if (rect.right() < visibleRect.right())
- newPos.setX(rect.right() - visible.width());
-
- } else if (visibleRect.width() < marginRect.width()) {
- newPos.setX(rect.center().x() - visibleRect.width() / 2);
- } else if (marginRect.left() > visibleRect.left()) {
- newPos.setX(marginRect.left());
- } else if (marginRect.right() < visibleRect.right()) {
- newPos.setX(marginRect.right() - visible.width());
- }
-
- if (visibleRect.height() < rect.height()) {
- // at least try to move the rect into view
- if (rect.top() > visibleRect.top())
- newPos.setX(rect.top());
- else if (rect.bottom() < visibleRect.bottom())
- newPos.setX(rect.bottom() - visible.height());
-
- } else if (visibleRect.height() < marginRect.height()) {
- newPos.setY(rect.center().y() - visibleRect.height() / 2);
- } else if (marginRect.top() > visibleRect.top()) {
- newPos.setY(marginRect.top());
- } else if (marginRect.bottom() < visibleRect.bottom()) {
- newPos.setY(marginRect.bottom() - visible.height());
- }
-
- // clamp to maximum content position
- newPos = clampToRect(newPos, d->contentPosRange);
- if (newPos == startPos)
- return;
-
- scrollTo(newPos, scrollTime);
-}
-
-/*! This function resends the QScrollPrepareEvent.
- Calling resendPrepareEvent triggers a QScrollPrepareEvent from the scroller.
- This allows the receiver to re-set content position and content size while
- scrolling.
- Calling this function while in the Inactive state is useless as the prepare event
- is sent again before scrolling starts.
- */
-void QScroller::resendPrepareEvent()
-{
- Q_D(QScroller);
- d->prepareScrolling(d->pressPosition);
-}
-
-/*! Set the snap positions for the horizontal axis to a list of \a positions.
- This overwrites all previously set snap positions and also a previously
- set snapping interval.
- Snapping can be deactivated by setting an empty list of positions.
- */
-void QScroller::setSnapPositionsX(const QList<qreal> &positions)
-{
- Q_D(QScroller);
- d->snapPositionsX = positions;
- d->snapIntervalX = 0.0;
-
- d->recalcScrollingSegments();
-}
-
-/*! Set the snap positions for the horizontal axis to regular spaced intervals.
- The first snap position is at \a first. The next at \a first + \a interval.
- This can be used to implement a list header.
- This overwrites all previously set snap positions and also a previously
- set snapping interval.
- Snapping can be deactivated by setting an interval of 0.0
- */
-void QScroller::setSnapPositionsX(qreal first, qreal interval)
-{
- Q_D(QScroller);
- d->snapFirstX = first;
- d->snapIntervalX = interval;
- d->snapPositionsX.clear();
-
- d->recalcScrollingSegments();
-}
-
-/*! Set the snap positions for the vertical axis to a list of \a positions.
- This overwrites all previously set snap positions and also a previously
- set snapping interval.
- Snapping can be deactivated by setting an empty list of positions.
- */
-void QScroller::setSnapPositionsY(const QList<qreal> &positions)
-{
- Q_D(QScroller);
- d->snapPositionsY = positions;
- d->snapIntervalY = 0.0;
-
- d->recalcScrollingSegments();
-}
-
-/*! Set the snap positions for the vertical axis to regular spaced intervals.
- The first snap position is at \a first. The next at \a first + \a interval.
- This overwrites all previously set snap positions and also a previously
- set snapping interval.
- Snapping can be deactivated by setting an interval of 0.0
- */
-void QScroller::setSnapPositionsY(qreal first, qreal interval)
-{
- Q_D(QScroller);
- d->snapFirstY = first;
- d->snapIntervalY = interval;
- d->snapPositionsY.clear();
-
- d->recalcScrollingSegments();
-}
-
-
-
-// -------------- private ------------
-
-QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target)
- : target(_target)
-#ifndef QT_NO_GESTURES
- , recognizer(0)
- , recognizerType(Qt::CustomGesture)
-#endif
- , state(QScroller::Inactive)
- , firstScroll(true)
- , pressTimestamp(0)
- , lastTimestamp(0)
- , snapFirstX(-1.0)
- , snapIntervalX(0.0)
- , snapFirstY(-1.0)
- , snapIntervalY(0.0)
-#ifndef QT_NO_ANIMATION
- , scrollTimer(new QScrollTimer(this))
-#endif
- , q_ptr(q)
-{
- connect(target, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed()));
-}
-
-void QScrollerPrivate::init()
-{
- setDpiFromWidget(0);
- monotonicTimer.start();
-}
-
-void QScrollerPrivate::sendEvent(QObject *o, QEvent *e)
-{
- qt_sendSpontaneousEvent(o, e);
-}
-
-const char *QScrollerPrivate::stateName(QScroller::State state)
-{
- switch (state) {
- case QScroller::Inactive: return "inactive";
- case QScroller::Pressed: return "pressed";
- case QScroller::Dragging: return "dragging";
- case QScroller::Scrolling: return "scrolling";
- default: return "(invalid)";
- }
-}
-
-const char *QScrollerPrivate::inputName(QScroller::Input input)
-{
- switch (input) {
- case QScroller::InputPress: return "press";
- case QScroller::InputMove: return "move";
- case QScroller::InputRelease: return "release";
- default: return "(invalid)";
- }
-}
-
-void QScrollerPrivate::targetDestroyed()
-{
-#ifndef QT_NO_ANIMATION
- scrollTimer->stop();
-#endif
- delete q_ptr;
-}
-
-void QScrollerPrivate::timerTick()
-{
- struct timerevent {
- QScroller::State state;
- typedef void (QScrollerPrivate::*timerhandler_t)();
- timerhandler_t handler;
- };
-
- timerevent timerevents[] = {
- { QScroller::Dragging, &QScrollerPrivate::timerEventWhileDragging },
- { QScroller::Scrolling, &QScrollerPrivate::timerEventWhileScrolling },
- };
-
- for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) {
- timerevent *te = timerevents + i;
-
- if (state == te->state) {
- (this->*te->handler)();
- return;
- }
- }
-
-#ifndef QT_NO_ANIMATION
- scrollTimer->stop();
-#endif
-}
-
-/*!
- This function is used by gesture recognizers to inform the scroller about a new input event.
- The scroller changes its internal state() according to the input event and its attached
- scroller properties. The scroller doesn't distinguish between the kind of input device the
- event came from. Therefore the event needs to be split into the \a input type, a \a position and a
- milli-second \a timestamp. The \a position needs to be in the target's coordinate system.
-
- The return value is \c true if the event should be consumed by the calling filter or \c false
- if the event should be forwarded to the control.
-
- \note Using grabGesture() should be sufficient for most use cases.
-*/
-bool QScroller::handleInput(Input input, const QPointF &position, qint64 timestamp)
-{
- Q_D(QScroller);
-
- qScrollerDebug() << "QScroller::handleInput(" << input << ", " << d->stateName(d->state) << ", " << position << ", " << timestamp << ")";
- struct statechange {
- State state;
- Input input;
- typedef bool (QScrollerPrivate::*inputhandler_t)(const QPointF &position, qint64 timestamp);
- inputhandler_t handler;
- };
-
- statechange statechanges[] = {
- { QScroller::Inactive, InputPress, &QScrollerPrivate::pressWhileInactive },
- { QScroller::Pressed, InputMove, &QScrollerPrivate::moveWhilePressed },
- { QScroller::Pressed, InputRelease, &QScrollerPrivate::releaseWhilePressed },
- { QScroller::Dragging, InputMove, &QScrollerPrivate::moveWhileDragging },
- { QScroller::Dragging, InputRelease, &QScrollerPrivate::releaseWhileDragging },
- { QScroller::Scrolling, InputPress, &QScrollerPrivate::pressWhileScrolling }
- };
-
- for (int i = 0; i < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) {
- statechange *sc = statechanges + i;
-
- if (d->state == sc->state && input == sc->input)
- return (d->*sc->handler)(position - d->overshootPosition, timestamp);
- }
- return false;
-}
-
-#if !defined(Q_WS_MAC)
-// the Mac version is implemented in qscroller_mac.mm
-
-QPointF QScrollerPrivate::realDpi(int screen)
-{
-# ifdef Q_WS_MAEMO_5
- Q_UNUSED(screen);
-
- // The DPI value is hardcoded to 96 on Maemo5:
- // https://projects.maemo.org/bugzilla/show_bug.cgi?id=152525
- // This value (260) is only correct for the N900 though, but
- // there's no way to get the real DPI at run time.
- return QPointF(260, 260);
-
-# elif defined(Q_WS_X11) && !defined(QT_NO_XRANDR)
- if (X11 && X11->use_xrandr && X11->ptrXRRSizes && X11->ptrXRRRootToScreen) {
- int nsizes = 0;
- // QDesktopWidget is based on Xinerama screens, which do not always
- // correspond to RandR screens: NVidia's TwinView e.g. will show up
- // as 2 screens in QDesktopWidget, but libXRandR will only see 1 screen.
- // (although with the combined size of the Xinerama screens).
- // Additionally, libXrandr will simply crash when calling XRRSizes
- // for (the non-existent) screen 1 in this scenario.
- Window root = RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen);
- int randrscreen = (root != XNone) ? X11->ptrXRRRootToScreen(X11->display, root) : -1;
-
- XRRScreenSize *sizes = X11->ptrXRRSizes(X11->display, randrscreen == -1 ? 0 : randrscreen, &nsizes);
- if (nsizes > 0 && sizes && sizes->width && sizes->height && sizes->mwidth && sizes->mheight) {
- qScrollerDebug() << "XRandR DPI:" << QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth),
- qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight));
- return QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth),
- qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight));
- }
- }
-# endif
-
- QWidget *w = QApplication::desktop()->screen(screen);
- return QPointF(w->physicalDpiX(), w->physicalDpiY());
-}
-
-#endif // !Q_WS_MAC
-
-
-/*! \internal
- Returns the resolution of the used screen.
-*/
-QPointF QScrollerPrivate::dpi() const
-{
- return pixelPerMeter * qreal(0.0254);
-}
-
-/*! \internal
- Sets the resolution used for scrolling.
- This resolution is only used by the kinetic scroller. If you change this
- then the scroller will behave quite different as a lot of the values are
- given in physical distances (millimeter).
-*/
-void QScrollerPrivate::setDpi(const QPointF &dpi)
-{
- pixelPerMeter = dpi / qreal(0.0254);
-}
-
-/*! \internal
- Sets the dpi used for scrolling to the value of the widget.
-*/
-void QScrollerPrivate::setDpiFromWidget(QWidget *widget)
-{
- QDesktopWidget *dw = QApplication::desktop();
- setDpi(realDpi(widget ? dw->screenNumber(widget) : dw->primaryScreen()));
-}
-
-/*! \internal
- Updates the velocity during dragging.
- Sets releaseVelocity.
-*/
-void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime)
-{
- if (deltaTime <= 0)
- return;
-
- Q_Q(QScroller);
- QPointF ppm = q->pixelPerMeter();
- const QScrollerPropertiesPrivate *sp = properties.d.data();
- QPointF deltaPixel = deltaPixelRaw;
-
- qScrollerDebug() << "QScroller::updateVelocity(" << deltaPixelRaw << " [delta pix], " << deltaTime << " [delta ms])";
-
- // faster than 2.5mm/ms seems bogus (that would be a screen height in ~20 ms)
- if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / ((ppm.x() + ppm.y()) / 2) * 1000) > qreal(2.5))
- deltaPixel = deltaPixelRaw * qreal(2.5) * ppm / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength();
-
- QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / ppm;
- // around 95% of all updates are in the [1..50] ms range, so make sure
- // to scale the smoothing factor over that range: this way a 50ms update
- // will have full impact, while 5ms update will only have a 10% impact.
- qreal smoothing = sp->dragVelocitySmoothingFactor * qMin(qreal(deltaTime), qreal(50)) / qreal(50);
-
- // only smooth if we already have a release velocity and only if the
- // user hasn't stopped to move his finger for more than 100ms
- if ((releaseVelocity != QPointF(0, 0)) && (deltaTime < 100)) {
- qScrollerDebug() << "SMOOTHED from " << newv << " to " << newv * smoothing + releaseVelocity * (qreal(1) - smoothing);
- // smooth x or y only if the new velocity is either 0 or at least in
- // the same direction of the release velocity
- if (!newv.x() || (qSign(releaseVelocity.x()) == qSign(newv.x())))
- newv.setX(newv.x() * smoothing + releaseVelocity.x() * (qreal(1) - smoothing));
- if (!newv.y() || (qSign(releaseVelocity.y()) == qSign(newv.y())))
- newv.setY(newv.y() * smoothing + releaseVelocity.y() * (qreal(1) - smoothing));
- } else
- qScrollerDebug() << "NO SMOOTHING to " << newv;
-
- releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity));
- releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity));
-
- qScrollerDebug() << " --> new velocity:" << releaseVelocity;
-}
-
-void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation)
-{
- if (startPos == stopPos || deltaPos == 0)
- return;
-
- ScrollSegment s;
- if (orientation == Qt::Horizontal && !xSegments.isEmpty())
- s.startTime = xSegments.last().startTime + xSegments.last().deltaTime * xSegments.last().stopProgress;
- else if (orientation == Qt::Vertical && !ySegments.isEmpty())
- s.startTime = ySegments.last().startTime + ySegments.last().deltaTime * ySegments.last().stopProgress;
- else
- s.startTime = monotonicTimer.elapsed();
-
- s.startPos = startPos;
- s.deltaPos = deltaPos;
- s.stopPos = stopPos;
- s.deltaTime = deltaTime * 1000;
- s.stopProgress = stopProgress;
- s.curve.setType(curve);
- s.type = type;
-
- if (orientation == Qt::Horizontal)
- xSegments.enqueue(s);
- else
- ySegments.enqueue(s);
-
- qScrollerDebug() << "+++ Added a new ScrollSegment: " << s;
-}
-
-
-/*! \internal
- Clears the old segments and recalculates them if the current segments are not longer valid
-*/
-void QScrollerPrivate::recalcScrollingSegments(bool forceRecalc)
-{
- Q_Q(QScroller);
- QPointF ppm = q->pixelPerMeter();
-
- releaseVelocity = q->velocity();
-
- if (forceRecalc || !scrollingSegmentsValid(Qt::Horizontal))
- createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal);
-
- if (forceRecalc || !scrollingSegmentsValid(Qt::Vertical))
- createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical);
-}
-
-/*! \internal
- Returns the end position after the current scroll has finished.
-*/
-qreal QScrollerPrivate::scrollingSegmentsEndPos(Qt::Orientation orientation) const
-{
- if (orientation == Qt::Horizontal) {
- if (xSegments.isEmpty())
- return contentPosition.x() + overshootPosition.x();
- else
- return xSegments.last().stopPos;
- } else {
- if (ySegments.isEmpty())
- return contentPosition.y() + overshootPosition.y();
- else
- return ySegments.last().stopPos;
- }
-}
-
-/*! \internal
- Checks if the scroller segment end in a valid position.
-*/
-bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation)
-{
- QQueue<ScrollSegment> *segments;
- qreal minPos;
- qreal maxPos;
-
- if (orientation == Qt::Horizontal) {
- segments = &xSegments;
- minPos = contentPosRange.left();
- maxPos = contentPosRange.right();
- } else {
- segments = &ySegments;
- minPos = contentPosRange.top();
- maxPos = contentPosRange.bottom();
- }
-
- if (segments->isEmpty())
- return true;
-
- const ScrollSegment &last = segments->last();
- qreal stopPos = last.stopPos;
-
- if (last.type == ScrollTypeScrollTo)
- return true; // scrollTo is always valid
-
- if (last.type == ScrollTypeOvershoot &&
- (stopPos != minPos && stopPos != maxPos))
- return false;
-
- if (stopPos < minPos || stopPos > maxPos)
- return false;
-
- if (stopPos == minPos || stopPos == maxPos) // the begin and the end of the list are always ok
- return true;
-
- qreal nextSnap = nextSnapPos(stopPos, 0, orientation);
- if (!qIsNaN(nextSnap) && stopPos != nextSnap)
- return false;
-
- return true;
-}
-
-/*! \internal
- Creates the sections needed to scroll to the specific \a endPos to the segments queue.
-*/
-void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type)
-{
- Q_UNUSED(v);
-
- if (orientation == Qt::Horizontal)
- xSegments.clear();
- else
- ySegments.clear();
-
- qScrollerDebug() << "+++ createScrollToSegments: t:" << deltaTime << "ep:" << endPos << "o:" << int(orientation);
-
- const QScrollerPropertiesPrivate *sp = properties.d.data();
-
- qreal startPos = (orientation == Qt::Horizontal) ? contentPosition.x() + overshootPosition.x()
- : contentPosition.y() + overshootPosition.y();
- qreal deltaPos = (endPos - startPos) / 2;
-
- pushSegment(type, deltaTime * qreal(0.3), qreal(1.0), startPos, deltaPos, startPos + deltaPos, QEasingCurve::InQuad, orientation);
- pushSegment(type, deltaTime * qreal(0.7), qreal(1.0), startPos + deltaPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation);
-}
-
-/*! \internal
-*/
-void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation)
-{
- const QScrollerPropertiesPrivate *sp = properties.d.data();
-
- QScrollerProperties::OvershootPolicy policy;
- qreal minPos;
- qreal maxPos;
- qreal viewSize;
-
- if (orientation == Qt::Horizontal) {
- xSegments.clear();
- policy = sp->hOvershootPolicy;
- minPos = contentPosRange.left();
- maxPos = contentPosRange.right();
- viewSize = viewportSize.width();
- } else {
- ySegments.clear();
- policy = sp->vOvershootPolicy;
- minPos = contentPosRange.top();
- maxPos = contentPosRange.bottom();
- viewSize = viewportSize.height();
- }
-
- bool alwaysOvershoot = (policy == QScrollerProperties::OvershootAlwaysOn);
- bool noOvershoot = (policy == QScrollerProperties::OvershootAlwaysOff) || !sp->overshootScrollDistanceFactor;
- bool canOvershoot = !noOvershoot && (alwaysOvershoot || maxPos);
-
- qScrollerDebug() << "+++ createScrollingSegments: s:" << startPos << "maxPos:" << maxPos << "o:" << int(orientation);
-
- qScrollerDebug() << "v = " << v << ", decelerationFactor = " << sp->decelerationFactor << ", curveType = " << sp->scrollingCurve.type();
-
- // This is only correct for QEasingCurve::OutQuad (linear velocity,
- // constant deceleration), but the results look and feel ok for OutExpo
- // and OutSine as well
-
- // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime)
- // v(0) = vrelease
- // v(deltaTime) = 0
- // deltaTime = (2 * vrelease) / (a * differntial(0))
-
- // pos(t) = integrate(v(t)dt)
- // pos(t) = vrelease * t - 0.5 * a * t * t
- // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime
- // deltaPos = pos(deltaTime)
-
- qreal deltaTime = (qreal(2) * qAbs(v)) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0));
- qreal deltaPos = qSign(v) * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor * ppm;
- qreal endPos = startPos + deltaPos;
-
- qScrollerDebug() << " Real Delta:" << deltaPos;
-
- // -- determine snap points
- qreal nextSnap = nextSnapPos(endPos, 0, orientation);
- qreal lowerSnapPos = nextSnapPos(startPos, -1, orientation);
- qreal higherSnapPos = nextSnapPos(startPos, 1, orientation);
-
- qScrollerDebug() << " Real Delta:" << lowerSnapPos <<"-"<<nextSnap <<"-"<<higherSnapPos;
-
- // - check if we can reach another snap point
- if (nextSnap > higherSnapPos || qIsNaN(higherSnapPos))
- higherSnapPos = nextSnap;
- if (nextSnap < lowerSnapPos || qIsNaN(lowerSnapPos))
- lowerSnapPos = nextSnap;
-
- // -- check if are in overshoot and end in overshoot
- if ((startPos < minPos && endPos < minPos) ||
- (startPos > maxPos && endPos > maxPos)) {
- qreal stopPos = endPos < minPos ? minPos : maxPos;
- qreal oDeltaTime = sp->overshootScrollTime;
-
- pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), startPos, stopPos - startPos, stopPos, sp->scrollingCurve.type(), orientation);
- return;
- }
-
- if (qAbs(v) < sp->minimumVelocity) {
-
- qScrollerDebug() << "### below minimum Vel" << orientation;
-
- // - no snap points or already at one
- if (qIsNaN(nextSnap) || nextSnap == startPos)
- return; // nothing to do, no scrolling needed.
-
- // - decide which point to use
-
- qreal snapDistance = higherSnapPos - lowerSnapPos;
-
- qreal pressDistance = (orientation == Qt::Horizontal) ?
- lastPosition.x() - pressPosition.x() :
- lastPosition.y() - pressPosition.y();
-
- // if not dragged far enough, pick the next snap point.
- if (sp->snapPositionRatio == 0.0 || qAbs(pressDistance / sp->snapPositionRatio) > snapDistance)
- endPos = nextSnap;
- else if (pressDistance < 0.0)
- endPos = lowerSnapPos;
- else
- endPos = higherSnapPos;
-
- deltaPos = endPos - startPos;
- qreal midPos = startPos + deltaPos * qreal(0.3);
- pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.3), qreal(1.0), startPos, midPos - startPos, midPos, QEasingCurve::InQuad, orientation);
- pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.7), qreal(1.0), midPos, endPos - midPos, endPos, sp->scrollingCurve.type(), orientation);
- return;
- }
-
- // - go to the next snappoint if there is one
- if (v > 0 && !qIsNaN(higherSnapPos)) {
- // change the time in relation to the changed end position
- if (endPos - startPos)
- deltaTime *= qAbs((higherSnapPos - startPos) / (endPos - startPos));
- if (deltaTime > sp->snapTime)
- deltaTime = sp->snapTime;
- endPos = higherSnapPos;
-
- } else if (v < 0 && !qIsNaN(lowerSnapPos)) {
- // change the time in relation to the changed end position
- if (endPos - startPos)
- deltaTime *= qAbs((lowerSnapPos - startPos) / (endPos - startPos));
- if (deltaTime > sp->snapTime)
- deltaTime = sp->snapTime;
- endPos = lowerSnapPos;
-
- // -- check if we are overshooting
- } else if (endPos < minPos || endPos > maxPos) {
- qreal stopPos = endPos < minPos ? minPos : maxPos;
-
- qScrollerDebug() << "Overshoot: delta:" << (stopPos - startPos);
-
- qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos));
-
- if (!canOvershoot) {
- qScrollerDebug() << "Overshoot stopp:" << stopProgress;
-
- pushSegment(ScrollTypeFlick, deltaTime, stopProgress, startPos, endPos, stopPos, sp->scrollingCurve.type(), orientation);
- } else {
- qreal oDeltaTime = sp->overshootScrollTime;
- qreal oStopProgress = qMin(stopProgress + oDeltaTime * qreal(0.3) / deltaTime, qreal(1));
- qreal oDistance = startPos + deltaPos * sp->scrollingCurve.valueForProgress(oStopProgress) - stopPos;
- qreal oMaxDistance = qSign(oDistance) * (viewSize * sp->overshootScrollDistanceFactor);
-
- qScrollerDebug() << "1 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress;
-
- if (qAbs(oDistance) > qAbs(oMaxDistance)) {
- oStopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos + oMaxDistance - startPos) / deltaPos));
- oDistance = oMaxDistance;
- qScrollerDebug() << "2 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress;
- }
-
- pushSegment(ScrollTypeFlick, deltaTime, oStopProgress, startPos, deltaPos, stopPos + oDistance, sp->scrollingCurve.type(), orientation);
- pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), stopPos + oDistance, -oDistance, stopPos, sp->scrollingCurve.type(), orientation);
- }
- return;
- }
-
- pushSegment(ScrollTypeFlick, deltaTime, qreal(1.0), startPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation);
-}
-
-
-/*! \internal
- Prepares scrolling by sending a QScrollPrepareEvent to the receiver widget.
- Returns true if the scrolling was accepted and a target was returned.
-*/
-bool QScrollerPrivate::prepareScrolling(const QPointF &position)
-{
- QScrollPrepareEvent spe(position);
- spe.ignore();
- sendEvent(target, &spe);
-
- qScrollerDebug() << "QScrollPrepareEvent returned from" << target << "with" << spe.isAccepted() << "mcp:" << spe.contentPosRange() << "cp:" << spe.contentPos();
- if (spe.isAccepted()) {
- QPointF oldContentPos = contentPosition + overshootPosition;
- QPointF contentDelta = spe.contentPos() - oldContentPos;
-
- viewportSize = spe.viewportSize();
- contentPosRange = spe.contentPosRange();
- if (contentPosRange.width() < 0)
- contentPosRange.setWidth(0);
- if (contentPosRange.height() < 0)
- contentPosRange.setHeight(0);
- contentPosition = clampToRect(spe.contentPos(), contentPosRange);
- overshootPosition = spe.contentPos() - contentPosition;
-
- // - check if the content position was moved
- if (contentDelta != QPointF(0, 0)) {
- // need to correct all segments
- for (int i = 0; i < xSegments.count(); i++)
- xSegments[i].startPos -= contentDelta.x();
-
- for (int i = 0; i < ySegments.count(); i++)
- ySegments[i].startPos -= contentDelta.y();
- }
-
- if (QWidget *w = qobject_cast<QWidget *>(target))
- setDpiFromWidget(w);
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(target)) {
- //TODO: the first view isn't really correct - maybe use an additional field in the prepare event?
- if (go->scene() && !go->scene()->views().isEmpty())
- setDpiFromWidget(go->scene()->views().first());
- }
-#endif
-
- if (state == QScroller::Scrolling) {
- recalcScrollingSegments();
- }
- return true;
- }
-
- return false;
-}
-
-void QScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp)
-{
- const QScrollerPropertiesPrivate *sp = properties.d.data();
-
- QPointF deltaPixel = position - lastPosition;
- qint64 deltaTime = timestamp - lastTimestamp;
-
- if (sp->axisLockThreshold) {
- int dx = qAbs(deltaPixel.x());
- int dy = qAbs(deltaPixel.y());
- if (dx || dy) {
- bool vertical = (dy > dx);
- qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx);
- //qScrollerDebug() << "QScroller::handleDrag() -- axis lock:" << alpha << " / " << axisLockThreshold << "- isvertical:" << vertical << "- dx:" << dx << "- dy:" << dy;
- if (alpha <= sp->axisLockThreshold) {
- if (vertical)
- deltaPixel.setX(0);
- else
- deltaPixel.setY(0);
- }
- }
- }
-
- // calculate velocity (if the user would release the mouse NOW)
- updateVelocity(deltaPixel, deltaTime);
-
- // restrict velocity, if content is not scrollable
- QRectF max = contentPosRange;
- bool canScrollX = (max.width() > 0) || (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
- bool canScrollY = (max.height() > 0) || (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
-
- if (!canScrollX) {
- deltaPixel.setX(0);
- releaseVelocity.setX(0);
- }
- if (!canScrollY) {
- deltaPixel.setY(0);
- releaseVelocity.setY(0);
- }
-
-// if (firstDrag) {
-// // Do not delay the first drag
-// setContentPositionHelper(q->contentPosition() - overshootDistance - deltaPixel);
-// dragDistance = QPointF(0, 0);
-// } else {
- dragDistance += deltaPixel;
-// }
-//qScrollerDebug() << "######################" << deltaPixel << position.y() << lastPosition.y();
- if (canScrollX)
- lastPosition.setX(position.x());
- if (canScrollY)
- lastPosition.setY(position.y());
- lastTimestamp = timestamp;
-}
-
-bool QScrollerPrivate::pressWhileInactive(const QPointF &position, qint64 timestamp)
-{
- if (prepareScrolling(position)) {
- const QScrollerPropertiesPrivate *sp = properties.d.data();
-
- if (!contentPosRange.isNull() ||
- (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) ||
- (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)) {
-
- lastPosition = pressPosition = position;
- lastTimestamp = pressTimestamp = timestamp;
- setState(QScroller::Pressed);
- }
- }
- return false;
-}
-
-bool QScrollerPrivate::releaseWhilePressed(const QPointF &, qint64)
-{
- if (overshootPosition != QPointF(0.0, 0.0)) {
- setState(QScroller::Scrolling);
- return true;
- } else {
- setState(QScroller::Inactive);
- return false;
- }
-}
-
-bool QScrollerPrivate::moveWhilePressed(const QPointF &position, qint64 timestamp)
-{
- Q_Q(QScroller);
- const QScrollerPropertiesPrivate *sp = properties.d.data();
- QPointF ppm = q->pixelPerMeter();
-
- QPointF deltaPixel = position - pressPosition;
-
- bool moveAborted = false;
- bool moveStarted = (((deltaPixel / ppm).manhattanLength()) > sp->dragStartDistance);
-
- // check the direction of the mouse drag and abort if it's too much in the wrong direction.
- if (moveStarted) {
- QRectF max = contentPosRange;
- bool canScrollX = (max.width() > 0);
- bool canScrollY = (max.height() > 0);
-
- if (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)
- canScrollX = true;
- if (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)
- canScrollY = true;
-
- if (qAbs(deltaPixel.x() / ppm.x()) < qAbs(deltaPixel.y() / ppm.y())) {
- if (!canScrollY)
- moveAborted = true;
- } else {
- if (!canScrollX)
- moveAborted = true;
- }
- }
-
- if (moveAborted) {
- setState(QScroller::Inactive);
- moveStarted = false;
-
- } else if (moveStarted) {
- setState(QScroller::Dragging);
-
- // subtract the dragStartDistance
- deltaPixel = deltaPixel - deltaPixel * (sp->dragStartDistance / deltaPixel.manhattanLength());
-
- if (deltaPixel != QPointF(0, 0)) {
- // handleDrag updates lastPosition, lastTimestamp and velocity
- handleDrag(pressPosition + deltaPixel, timestamp);
- }
- }
- return moveStarted;
-}
-
-bool QScrollerPrivate::moveWhileDragging(const QPointF &position, qint64 timestamp)
-{
- // handleDrag updates lastPosition, lastTimestamp and velocity
- handleDrag(position, timestamp);
- return true;
-}
-
-void QScrollerPrivate::timerEventWhileDragging()
-{
- if (dragDistance != QPointF(0, 0)) {
- qScrollerDebug() << "QScroller::timerEventWhileDragging() -- dragDistance:" << dragDistance;
-
- setContentPositionHelperDragging(-dragDistance);
- dragDistance = QPointF(0, 0);
- }
-}
-
-bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 timestamp)
-{
- Q_Q(QScroller);
- const QScrollerPropertiesPrivate *sp = properties.d.data();
-
- // handleDrag updates lastPosition, lastTimestamp and velocity
- handleDrag(position, timestamp);
-
- // check if we moved at all - this can happen if you stop a running
- // scroller with a press and release shortly afterwards
- QPointF deltaPixel = position - pressPosition;
- if (((deltaPixel / q->pixelPerMeter()).manhattanLength()) > sp->dragStartDistance) {
-
- // handle accelerating flicks
- if ((oldVelocity != QPointF(0, 0)) && sp->acceleratingFlickMaximumTime &&
- ((timestamp - pressTimestamp) < qint64(sp->acceleratingFlickMaximumTime * 1000))) {
-
- // - determine if the direction was changed
- int signX = 0, signY = 0;
- if (releaseVelocity.x())
- signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1;
- if (releaseVelocity.y())
- signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1;
-
- if (signX > 0)
- releaseVelocity.setX(qBound(-sp->maximumVelocity,
- oldVelocity.x() * sp->acceleratingFlickSpeedupFactor,
- sp->maximumVelocity));
- if (signY > 0)
- releaseVelocity.setY(qBound(-sp->maximumVelocity,
- oldVelocity.y() * sp->acceleratingFlickSpeedupFactor,
- sp->maximumVelocity));
- }
- }
-
- QPointF ppm = q->pixelPerMeter();
- createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal);
- createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical);
-
- qScrollerDebug() << "QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << sp->minimumVelocity << "overshoot" << overshootPosition;
-
- if (xSegments.isEmpty() && ySegments.isEmpty())
- setState(QScroller::Inactive);
- else
- setState(QScroller::Scrolling);
-
- return true;
-}
-
-void QScrollerPrivate::timerEventWhileScrolling()
-{
- qScrollerDebug() << "QScroller::timerEventWhileScrolling()";
-
- setContentPositionHelperScrolling();
- if (xSegments.isEmpty() && ySegments.isEmpty())
- setState(QScroller::Inactive);
-}
-
-bool QScrollerPrivate::pressWhileScrolling(const QPointF &position, qint64 timestamp)
-{
- Q_Q(QScroller);
-
- if ((q->velocity() <= properties.d->maximumClickThroughVelocity) &&
- (overshootPosition == QPointF(0.0, 0.0))) {
- setState(QScroller::Inactive);
- return false;
- } else {
- lastPosition = pressPosition = position;
- lastTimestamp = pressTimestamp = timestamp;
- setState(QScroller::Pressed);
- setState(QScroller::Dragging);
- return true;
- }
-}
-
-/*! \internal
- This function handles all state changes of the scroller.
-*/
-void QScrollerPrivate::setState(QScroller::State newstate)
-{
- Q_Q(QScroller);
- bool sendLastScroll = false;
-
- if (state == newstate)
- return;
-
- qScrollerDebug() << q << "QScroller::setState(" << stateName(newstate) << ")";
-
- switch (newstate) {
- case QScroller::Inactive:
-#ifndef QT_NO_ANIMATION
- scrollTimer->stop();
-#endif
-
- // send the last scroll event (but only after the current state change was finished)
- if (!firstScroll)
- sendLastScroll = true;
-
- releaseVelocity = QPointF(0, 0);
- break;
-
- case QScroller::Pressed:
-#ifndef QT_NO_ANIMATION
- scrollTimer->stop();
-#endif
-
- oldVelocity = releaseVelocity;
- releaseVelocity = QPointF(0, 0);
- break;
-
- case QScroller::Dragging:
- dragDistance = QPointF(0, 0);
-#ifndef QT_NO_ANIMATION
- if (state == QScroller::Pressed)
- scrollTimer->start();
-#endif
- break;
-
- case QScroller::Scrolling:
-#ifndef QT_NO_ANIMATION
- scrollTimer->start();
-#endif
- break;
- }
-
- qSwap(state, newstate);
-
- if (sendLastScroll) {
- QScrollEvent se(contentPosition, overshootPosition, QScrollEvent::ScrollFinished);
- sendEvent(target, &se);
- firstScroll = true;
- }
- if (state == QScroller::Dragging || state == QScroller::Scrolling)
- qt_activeScrollers()->insert(q);
- else
- qt_activeScrollers()->remove(q);
- emit q->stateChanged(state);
-}
-
-
-/*! \internal
- Helps when setting the content position.
- It will try to move the content by the requested delta but stop in case
- when we are coming back from an overshoot or a scrollTo.
- It will also indicate a new overshooting condition by the overshootX and oversthootY flags.
-
- In this cases it will reset the velocity variables and other flags.
-
- Also keeps track of the current over-shooting value in overshootPosition.
-
- \a deltaPos is the amount of pixels the current content position should be moved
-*/
-void QScrollerPrivate::setContentPositionHelperDragging(const QPointF &deltaPos)
-{
- Q_Q(QScroller);
- QPointF ppm = q->pixelPerMeter();
- const QScrollerPropertiesPrivate *sp = properties.d.data();
- QPointF v = q->velocity();
-
- if (sp->overshootDragResistanceFactor)
- overshootPosition /= sp->overshootDragResistanceFactor;
-
- QPointF oldPos = contentPosition + overshootPosition;
- QPointF newPos = oldPos + deltaPos;
-
- qScrollerDebug() << "QScroller::setContentPositionHelperDragging(" << deltaPos << " [pix])";
- qScrollerDebug() << " --> overshoot:" << overshootPosition << "- old pos:" << oldPos << "- new pos:" << newPos;
-
- QPointF oldClampedPos = clampToRect(oldPos, contentPosRange);
- QPointF newClampedPos = clampToRect(newPos, contentPosRange);
-
- // --- handle overshooting and stop if the coordinate is going back inside the normal area
- bool alwaysOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
- bool alwaysOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn);
- bool noOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) ||
- ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) ||
- !sp->overshootDragDistanceFactor;
- bool noOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) ||
- ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) ||
- !sp->overshootDragDistanceFactor;
- bool canOvershootX = !noOvershootX && (alwaysOvershootX || contentPosRange.width());
- bool canOvershootY = !noOvershootY && (alwaysOvershootY || contentPosRange.height());
-
- qreal oldOvershootX = (canOvershootX) ? oldPos.x() - oldClampedPos.x() : 0;
- qreal oldOvershootY = (canOvershootY) ? oldPos.y() - oldClampedPos.y() : 0;
-
- qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0;
- qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0;
-
- qreal maxOvershootX = viewportSize.width() * sp->overshootDragDistanceFactor;
- qreal maxOvershootY = viewportSize.height() * sp->overshootDragDistanceFactor;
-
- qScrollerDebug() << " --> noOs:" << noOvershootX << "drf:" << sp->overshootDragResistanceFactor << "mdf:" << sp->overshootScrollDistanceFactor << "ossP:"<<sp->hOvershootPolicy;
- qScrollerDebug() << " --> canOS:" << canOvershootX << "newOS:" << newOvershootX << "maxOS:" << maxOvershootX;
-
- if (sp->overshootDragResistanceFactor) {
- oldOvershootX *= sp->overshootDragResistanceFactor;
- oldOvershootY *= sp->overshootDragResistanceFactor;
- newOvershootX *= sp->overshootDragResistanceFactor;
- newOvershootY *= sp->overshootDragResistanceFactor;
- }
-
- // -- stop at the maximum overshoot distance
-
- newOvershootX = qBound(-maxOvershootX, newOvershootX, maxOvershootX);
- newOvershootY = qBound(-maxOvershootY, newOvershootY, maxOvershootY);
-
- overshootPosition.setX(newOvershootX);
- overshootPosition.setY(newOvershootY);
- contentPosition = newClampedPos;
-
- QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated);
- sendEvent(target, &se);
- firstScroll = false;
-
- qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition <<
- "- overshoot x/y?:" << overshootPosition;
-}
-
-
-qreal QScrollerPrivate::nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos)
-{
- qreal pos = oldPos;
-
- // check the X segments for new positions
- while (!segments.isEmpty()) {
- const ScrollSegment s = segments.head();
-
- if ((s.startTime + s.deltaTime * s.stopProgress) <= now) {
- segments.dequeue();
- pos = s.stopPos;
- } else if (s.startTime <= now) {
- qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime);
- pos = s.startPos + s.deltaPos * s.curve.valueForProgress(progress);
- if (s.deltaPos > 0 ? pos > s.stopPos : pos < s.stopPos) {
- segments.dequeue();
- pos = s.stopPos;
- } else {
- break;
- }
- } else {
- break;
- }
- }
- return pos;
-}
-
-void QScrollerPrivate::setContentPositionHelperScrolling()
-{
- qint64 now = monotonicTimer.elapsed();
- QPointF newPos = contentPosition + overshootPosition;
-
- newPos.setX(nextSegmentPosition(xSegments, now, newPos.x()));
- newPos.setY(nextSegmentPosition(ySegments, now, newPos.y()));
-
- // -- set the position and handle overshoot
- qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()";
- qScrollerDebug() << " --> overshoot:" << overshootPosition << "- new pos:" << newPos;
-
- QPointF newClampedPos = clampToRect(newPos, contentPosRange);
-
- overshootPosition = newPos - newClampedPos;
- contentPosition = newClampedPos;
-
- QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated);
- sendEvent(target, &se);
- firstScroll = false;
-
- qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition;
-}
-
-/*! \internal
- Returns the next snap point in direction.
- If \a direction >0 it will return the next snap point that is larger than the current position.
- If \a direction <0 it will return the next snap point that is smaller than the current position.
- If \a direction ==0 it will return the nearest snap point (or the current position if we are already
- on a snap point.
- Returns the nearest snap position or NaN if no such point could be found.
- */
-qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation)
-{
- qreal bestSnapPos = Q_QNAN;
- qreal bestSnapPosDist = Q_INFINITY;
-
- qreal minPos;
- qreal maxPos;
-
- if (orientation == Qt::Horizontal) {
- minPos = contentPosRange.left();
- maxPos = contentPosRange.right();
- } else {
- minPos = contentPosRange.top();
- maxPos = contentPosRange.bottom();
- }
-
- if (orientation == Qt::Horizontal) {
- // the snap points in the list
- foreach (qreal snapPos, snapPositionsX) {
- qreal snapPosDist = snapPos - p;
- if ((dir > 0 && snapPosDist < 0) ||
- (dir < 0 && snapPosDist > 0))
- continue; // wrong direction
- if (snapPos < minPos || snapPos > maxPos )
- continue; // invalid
-
- if (qIsNaN(bestSnapPos) ||
- qAbs(snapPosDist) < bestSnapPosDist ) {
- bestSnapPos = snapPos;
- bestSnapPosDist = qAbs(snapPosDist);
- }
- }
-
- // the snap point interval
- if (snapIntervalX > 0.0) {
- qreal first = minPos + snapFirstX;
- qreal snapPos;
- if (dir > 0)
- snapPos = qCeil((p - first) / snapIntervalX) * snapIntervalX + first;
- else if (dir < 0)
- snapPos = qFloor((p - first) / snapIntervalX) * snapIntervalX + first;
- else if (p <= first)
- snapPos = first;
- else
- {
- qreal last = qFloor((maxPos - first) / snapIntervalX) * snapIntervalX + first;
- if (p >= last)
- snapPos = last;
- else
- snapPos = qRound((p - first) / snapIntervalX) * snapIntervalX + first;
- }
-
- if (snapPos >= first && snapPos <= maxPos ) {
- qreal snapPosDist = snapPos - p;
-
- if (qIsNaN(bestSnapPos) ||
- qAbs(snapPosDist) < bestSnapPosDist ) {
- bestSnapPos = snapPos;
- bestSnapPosDist = qAbs(snapPosDist);
- }
- }
- }
-
- } else { // (orientation == Qt::Vertical)
- // the snap points in the list
- foreach (qreal snapPos, snapPositionsY) {
- qreal snapPosDist = snapPos - p;
- if ((dir > 0 && snapPosDist < 0) ||
- (dir < 0 && snapPosDist > 0))
- continue; // wrong direction
- if (snapPos < minPos || snapPos > maxPos )
- continue; // invalid
-
- if (qIsNaN(bestSnapPos) ||
- qAbs(snapPosDist) < bestSnapPosDist) {
- bestSnapPos = snapPos;
- bestSnapPosDist = qAbs(snapPosDist);
- }
- }
-
- // the snap point interval
- if (snapIntervalY > 0.0) {
- qreal first = minPos + snapFirstY;
- qreal snapPos;
- if (dir > 0)
- snapPos = qCeil((p - first) / snapIntervalY) * snapIntervalY + first;
- else if (dir < 0)
- snapPos = qFloor((p - first) / snapIntervalY) * snapIntervalY + first;
- else if (p <= first)
- snapPos = first;
- else
- {
- qreal last = qFloor((maxPos - first) / snapIntervalY) * snapIntervalY + first;
- if (p >= last)
- snapPos = last;
- else
- snapPos = qRound((p - first) / snapIntervalY) * snapIntervalY + first;
- }
-
- if (snapPos >= first && snapPos <= maxPos ) {
- qreal snapPosDist = snapPos - p;
-
- if (qIsNaN(bestSnapPos) ||
- qAbs(snapPosDist) < bestSnapPosDist) {
- bestSnapPos = snapPos;
- bestSnapPosDist = qAbs(snapPosDist);
- }
- }
- }
- }
-
- return bestSnapPos;
-}
-
-/*!
- \enum QScroller::State
-
- This enum contains the different QScroller states.
-
- \value Inactive The scroller is not scrolling and nothing is pressed.
- \value Pressed A touch event was received or the mouse button was pressed but the scroll area is currently not dragged.
- \value Dragging The scroll area is currently following the touch point or mouse.
- \value Scrolling The scroll area is moving on it's own.
-*/
-
-/*!
- \enum QScroller::ScrollerGestureType
-
- This enum contains the different gesture types that are supported by the QScroller gesture recognizer.
-
- \value TouchGesture The gesture recognizer will only trigger on touch
- events. Specifically it will react on single touch points when using a
- touch screen and dual touch points when using a touchpad.
- \value LeftMouseButtonGesture The gesture recognizer will only trigger on left mouse button events.
- \value MiddleMouseButtonGesture The gesture recognizer will only trigger on middle mouse button events.
- \value RightMouseButtonGesture The gesture recognizer will only trigger on right mouse button events.
-*/
-
-/*!
- \enum QScroller::Input
-
- This enum contains an input device agnostic view of input events that are relevant for QScroller.
-
- \value InputPress The user pressed the input device (e.g. QEvent::MouseButtonPress,
- QEvent::GraphicsSceneMousePress, QEvent::TouchBegin)
-
- \value InputMove The user moved the input device (e.g. QEvent::MouseMove,
- QEvent::GraphicsSceneMouseMove, QEvent::TouchUpdate)
-
- \value InputRelease The user released the input device (e.g. QEvent::MouseButtonRelease,
- QEvent::GraphicsSceneMouseRelease, QEvent::TouchEnd)
-
-*/
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h
deleted file mode 100644
index 1599c7dcdf..0000000000
--- a/src/gui/util/qscroller.h
+++ /dev/null
@@ -1,155 +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 QSCROLLER_H
-#define QSCROLLER_H
-
-#include <QtCore/QObject>
-#include <QtCore/QPointF>
-#include <QtGui/QScrollerProperties>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWidget;
-class QScrollerPrivate;
-class QScrollerProperties;
-#ifndef QT_NO_GESTURES
-class QFlickGestureRecognizer;
-class QMouseFlickGestureRecognizer;
-#endif
-
-class Q_GUI_EXPORT QScroller : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(State state READ state NOTIFY stateChanged)
- Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged)
- Q_ENUMS(State)
-
-public:
- enum State
- {
- Inactive,
- Pressed,
- Dragging,
- Scrolling
- };
-
- enum ScrollerGestureType
- {
- TouchGesture,
- LeftMouseButtonGesture,
- RightMouseButtonGesture,
- MiddleMouseButtonGesture
- };
-
- enum Input
- {
- InputPress = 1,
- InputMove,
- InputRelease
- };
-
- static bool hasScroller(QObject *target);
-
- static QScroller *scroller(QObject *target);
- static const QScroller *scroller(const QObject *target);
-
-#ifndef QT_NO_GESTURES
- static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture);
- static Qt::GestureType grabbedGesture(QObject *target);
- static void ungrabGesture(QObject *target);
-#endif
-
- static QList<QScroller *> activeScrollers();
-
- QObject *target() const;
-
- State state() const;
-
- bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0);
-
- void stop();
- QPointF velocity() const;
- QPointF finalPosition() const;
- QPointF pixelPerMeter() const;
-
- QScrollerProperties scrollerProperties() const;
-
- void setSnapPositionsX( const QList<qreal> &positions );
- void setSnapPositionsX( qreal first, qreal interval );
- void setSnapPositionsY( const QList<qreal> &positions );
- void setSnapPositionsY( qreal first, qreal interval );
-
-public Q_SLOTS:
- void setScrollerProperties(const QScrollerProperties &prop);
- void scrollTo(const QPointF &pos);
- void scrollTo(const QPointF &pos, int scrollTime);
- void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin);
- void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime);
- void resendPrepareEvent();
-
-Q_SIGNALS:
- void stateChanged(QScroller::State newstate);
- void scrollerPropertiesChanged(const QScrollerProperties &);
-
-private:
- QScrollerPrivate *d_ptr;
-
- QScroller(QObject *target);
- virtual ~QScroller();
-
- Q_DISABLE_COPY(QScroller)
- Q_DECLARE_PRIVATE(QScroller)
-
-#ifndef QT_NO_GESTURES
- friend class QFlickGestureRecognizer;
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCROLLER_H
diff --git a/src/gui/util/qscroller_mac.mm b/src/gui/util/qscroller_mac.mm
deleted file mode 100644
index 4bf69c17c0..0000000000
--- a/src/gui/util/qscroller_mac.mm
+++ /dev/null
@@ -1,71 +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 <QtCore/qglobal.h>
-
-#ifdef Q_WS_MAC
-
-#import <Cocoa/Cocoa.h>
-
-#include "qscroller_p.h"
-
-QPointF QScrollerPrivate::realDpi(int screen)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSArray *nsscreens = [NSScreen screens];
-
- if (screen < 0 || screen >= int([nsscreens count]))
- screen = 0;
-
- NSScreen *nsscreen = [nsscreens objectAtIndex:screen];
- CGDirectDisplayID display = [[[nsscreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue];
-
- CGSize mmsize = CGDisplayScreenSize(display);
- if (mmsize.width > 0 && mmsize.height > 0) {
- return QPointF(CGDisplayPixelsWide(display) / mmsize.width,
- CGDisplayPixelsHigh(display) / mmsize.height) * qreal(25.4);
- } else {
- return QPointF();
- }
- [pool release];
-}
-
-#endif
diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h
deleted file mode 100644
index c1196152df..0000000000
--- a/src/gui/util/qscroller_p.h
+++ /dev/null
@@ -1,209 +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 QSCROLLER_P_H
-#define QSCROLLER_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 <QObject>
-#include <QPointer>
-#include <QQueue>
-#include <QSet>
-#include <QEasingCurve>
-#include <QElapsedTimer>
-#include <QSizeF>
-#include <QPointF>
-#include <QRectF>
-#include <qscroller.h>
-#include <qscrollerproperties.h>
-#include <private/qscrollerproperties_p.h>
-#include <QAbstractAnimation>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_GESTURES
-class QFlickGestureRecognizer;
-#endif
-
-#ifndef QT_NO_ANIMATION
-class QScrollTimer;
-#endif
-class QScrollerPrivate : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PUBLIC(QScroller)
-
-public:
- QScrollerPrivate(QScroller *q, QObject *target);
- void init();
-
- void sendEvent(QObject *o, QEvent *e);
-
- void setState(QScroller::State s);
-
- enum ScrollType {
- ScrollTypeFlick = 0,
- ScrollTypeScrollTo,
- ScrollTypeOvershoot
- };
-
- struct ScrollSegment {
- qint64 startTime;
- qint64 deltaTime;
- qreal startPos;
- qreal deltaPos;
- QEasingCurve curve;
- qreal stopProgress; // whatever is..
- qreal stopPos; // ..reached first
- ScrollType type;
- };
-
- bool pressWhileInactive(const QPointF &position, qint64 timestamp);
- bool moveWhilePressed(const QPointF &position, qint64 timestamp);
- bool releaseWhilePressed(const QPointF &position, qint64 timestamp);
- bool moveWhileDragging(const QPointF &position, qint64 timestamp);
- bool releaseWhileDragging(const QPointF &position, qint64 timestamp);
- bool pressWhileScrolling(const QPointF &position, qint64 timestamp);
-
- void timerTick();
- void timerEventWhileDragging();
- void timerEventWhileScrolling();
-
- bool prepareScrolling(const QPointF &position);
- void handleDrag(const QPointF &position, qint64 timestamp);
-
- QPointF realDpi(int screen);
- QPointF dpi() const;
- void setDpi(const QPointF &dpi);
- void setDpiFromWidget(QWidget *widget);
-
- void updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime);
- void pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation);
- void recalcScrollingSegments(bool forceRecalc = false);
- qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const;
- bool scrollingSegmentsValid(Qt::Orientation orientation);
- void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type);
- void createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation);
-
- void setContentPositionHelperDragging(const QPointF &deltaPos);
- void setContentPositionHelperScrolling();
-
- qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation);
- static qreal nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos);
-
- inline int frameRateSkip() const { return properties.d.data()->frameRate; }
-
- static const char *stateName(QScroller::State state);
- static const char *inputName(QScroller::Input input);
-
-public slots:
- void targetDestroyed();
-
-public:
- // non static
- QObject *target;
- QScrollerProperties properties;
-#ifndef QT_NO_GESTURES
- QFlickGestureRecognizer *recognizer;
- Qt::GestureType recognizerType;
-#endif
-
- // scroller state:
-
- // QPointer<QObject> scrollTarget;
- QSizeF viewportSize;
- QRectF contentPosRange;
- QPointF contentPosition;
- QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor)
-
- // state
-
- bool enabled;
- QScroller::State state;
- bool firstScroll; // true if we haven't already send a scroll event
-
- QPointF oldVelocity; // the release velocity of the last drag
-
- QPointF pressPosition;
- QPointF lastPosition;
- qint64 pressTimestamp;
- qint64 lastTimestamp;
-
- QPointF dragDistance; // the distance we should move during the next drag timer event
-
- QQueue<ScrollSegment> xSegments;
- QQueue<ScrollSegment> ySegments;
-
- // snap positions
- QList<qreal> snapPositionsX;
- qreal snapFirstX;
- qreal snapIntervalX;
- QList<qreal> snapPositionsY;
- qreal snapFirstY;
- qreal snapIntervalY;
-
- QPointF pixelPerMeter;
-
- QElapsedTimer monotonicTimer;
-
- QPointF releaseVelocity; // the starting velocity of the scrolling state
-#ifndef QT_NO_ANIMATION
- QScrollTimer *scrollTimer;
-#endif
-
- QScroller *q_ptr;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QSCROLLER_P_H
-
diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp
deleted file mode 100644
index 85e2e82af1..0000000000
--- a/src/gui/util/qscrollerproperties.cpp
+++ /dev/null
@@ -1,393 +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 <QPointer>
-#include <QObject>
-#include <QtCore/qmath.h>
-#ifdef Q_WS_WIN
-# include <QLibrary>
-#endif
-
-#include "qscrollerproperties.h"
-#include "private/qscrollerproperties_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static QScrollerPropertiesPrivate *userDefaults = 0;
-static QScrollerPropertiesPrivate *systemDefaults = 0;
-
-QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults()
-{
- if (!systemDefaults) {
- QScrollerPropertiesPrivate spp;
- spp.mousePressEventDelay = qreal(0.25);
- spp.dragStartDistance = qreal(5.0 / 1000);
- spp.dragVelocitySmoothingFactor = qreal(0.8);
- spp.axisLockThreshold = qreal(0);
- spp.scrollingCurve.setType(QEasingCurve::OutQuad);
- spp.decelerationFactor = qreal(0.125);
- spp.minimumVelocity = qreal(50.0 / 1000);
- spp.maximumVelocity = qreal(500.0 / 1000);
- spp.maximumClickThroughVelocity = qreal(66.5 / 1000);
- spp.acceleratingFlickMaximumTime = qreal(1.25);
- spp.acceleratingFlickSpeedupFactor = qreal(3.0);
- spp.snapPositionRatio = qreal(0.5);
- spp.snapTime = qreal(0.3);
- spp.overshootDragResistanceFactor = qreal(0.5);
- spp.overshootDragDistanceFactor = qreal(1);
- spp.overshootScrollDistanceFactor = qreal(0.5);
- spp.overshootScrollTime = qreal(0.7);
-# ifdef Q_WS_WIN
- if (QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback"))
- spp.overshootScrollTime = qreal(0.35);
-# endif
- spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
- spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
- spp.frameRate = QScrollerProperties::Standard;
-
- systemDefaults = new QScrollerPropertiesPrivate(spp);
- }
- return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults);
-}
-
-/*!
- \class QScrollerProperties
- \brief The QScrollerProperties class stores the settings for a QScroller.
- \since 4.8
-
- The QScrollerProperties class stores the parameters used by QScroller.
-
- The default settings are platform dependent so that Qt emulates the
- platform behaviour for kinetic scrolling.
-
- As a convention the QScrollerProperties are in physical units (meter,
- seconds) and are converted by QScroller using the current DPI.
-
- \sa QScroller
-*/
-
-/*!
- Constructs new scroller properties.
-*/
-QScrollerProperties::QScrollerProperties()
- : d(QScrollerPropertiesPrivate::defaults())
-{
-}
-
-/*!
- Constructs a copy of \a sp.
-*/
-QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp)
- : d(new QScrollerPropertiesPrivate(*sp.d))
-{
-}
-
-/*!
- Assigns \a sp to these scroller properties and returns a reference to these scroller properties.
-*/
-QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp)
-{
- *d.data() = *sp.d.data();
- return *this;
-}
-
-/*!
- Destroys the scroller properties.
-*/
-QScrollerProperties::~QScrollerProperties()
-{
-}
-
-/*!
- Returns true if these scroller properties are equal to \a sp; otherwise returns false.
-*/
-bool QScrollerProperties::operator==(const QScrollerProperties &sp) const
-{
- return *d.data() == *sp.d.data();
-}
-
-/*!
- Returns true if these scroller properties are different from \a sp; otherwise returns false.
-*/
-bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const
-{
- return !(*d.data() == *sp.d.data());
-}
-
-bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const
-{
- bool same = true;
- same &= (mousePressEventDelay == p.mousePressEventDelay);
- same &= (dragStartDistance == p.dragStartDistance);
- same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor);
- same &= (axisLockThreshold == p.axisLockThreshold);
- same &= (scrollingCurve == p.scrollingCurve);
- same &= (decelerationFactor == p.decelerationFactor);
- same &= (minimumVelocity == p.minimumVelocity);
- same &= (maximumVelocity == p.maximumVelocity);
- same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity);
- same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime);
- same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor);
- same &= (snapPositionRatio == p.snapPositionRatio);
- same &= (snapTime == p.snapTime);
- same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor);
- same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor);
- same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor);
- same &= (overshootScrollTime == p.overshootScrollTime);
- same &= (hOvershootPolicy == p.hOvershootPolicy);
- same &= (vOvershootPolicy == p.vOvershootPolicy);
- same &= (frameRate == p.frameRate);
- return same;
-}
-
-/*!
- Sets the scroller properties for all new QScrollerProperties objects to \a sp.
-
- Use this function to override the platform default properties returned by the default
- constructor. If you only want to change the scroller properties of a single scroller, use
- QScroller::setScrollerProperties()
-
- \note Calling this function will not change the content of already existing
- QScrollerProperties objects.
-
- \sa unsetDefaultScrollerProperties()
-*/
-void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp)
-{
- if (!userDefaults)
- userDefaults = new QScrollerPropertiesPrivate(*sp.d);
- else
- *userDefaults = *sp.d;
-}
-
-/*!
- Sets the scroller properties returned by the default constructor back to the platform default
- properties.
-
- \sa setDefaultScrollerProperties()
-*/
-void QScrollerProperties::unsetDefaultScrollerProperties()
-{
- delete userDefaults;
- userDefaults = 0;
-}
-
-/*!
- Query the \a metric value of the scroller properties.
-
- \sa setScrollMetric(), ScrollMetric
-*/
-QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const
-{
- switch (metric) {
- case MousePressEventDelay: return d->mousePressEventDelay;
- case DragStartDistance: return d->dragStartDistance;
- case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor;
- case AxisLockThreshold: return d->axisLockThreshold;
- case ScrollingCurve: return d->scrollingCurve;
- case DecelerationFactor: return d->decelerationFactor;
- case MinimumVelocity: return d->minimumVelocity;
- case MaximumVelocity: return d->maximumVelocity;
- case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity;
- case AcceleratingFlickMaximumTime: return d->acceleratingFlickMaximumTime;
- case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor;
- case SnapPositionRatio: return d->snapPositionRatio;
- case SnapTime: return d->snapTime;
- case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor;
- case OvershootDragDistanceFactor: return d->overshootDragDistanceFactor;
- case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor;
- case OvershootScrollTime: return d->overshootScrollTime;
- case HorizontalOvershootPolicy: return QVariant::fromValue(d->hOvershootPolicy);
- case VerticalOvershootPolicy: return QVariant::fromValue(d->vOvershootPolicy);
- case FrameRate: return QVariant::fromValue(d->frameRate);
- case ScrollMetricCount: break;
- }
- return QVariant();
-}
-
-/*!
- Set a specific value of the \a metric ScrollerMetric to \a value.
-
- \sa scrollMetric(), ScrollMetric
-*/
-void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value)
-{
- switch (metric) {
- case MousePressEventDelay: d->mousePressEventDelay = value.toReal(); break;
- case DragStartDistance: d->dragStartDistance = value.toReal(); break;
- case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case AxisLockThreshold: d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case ScrollingCurve: d->scrollingCurve = value.toEasingCurve(); break;
- case DecelerationFactor: d->decelerationFactor = value.toReal(); break;
- case MinimumVelocity: d->minimumVelocity = value.toReal(); break;
- case MaximumVelocity: d->maximumVelocity = value.toReal(); break;
- case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break;
- case AcceleratingFlickMaximumTime: d->acceleratingFlickMaximumTime = value.toReal(); break;
- case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break;
- case SnapPositionRatio: d->snapPositionRatio = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case SnapTime: d->snapTime = value.toReal(); break;
- case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break;
- case OvershootDragDistanceFactor: d->overshootDragDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
- case OvershootScrollTime: d->overshootScrollTime = value.toReal(); break;
- case HorizontalOvershootPolicy: d->hOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break;
- case VerticalOvershootPolicy: d->vOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break;
- case FrameRate: d->frameRate = value.value<QScrollerProperties::FrameRates>(); break;
- case ScrollMetricCount: break;
- }
-}
-
-/*!
- \enum QScrollerProperties::FrameRates
-
- This enum describes the available frame rates used while dragging or scrolling.
-
- \value Fps60 60 frames per second
- \value Fps30 30 frames per second
- \value Fps20 20 frames per second
- \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation).
-*/
-
-/*!
- \enum QScrollerProperties::OvershootPolicy
-
- This enum describes the various modes of overshooting.
-
- \value OvershootWhenScrollable Overshooting is possible when the content is scrollable. This is the
- default.
-
- \value OvershootAlwaysOff Overshooting is never enabled, even when the content is scrollable.
-
- \value OvershootAlwaysOn Overshooting is always enabled, even when the content is not
- scrollable.
-*/
-
-/*!
- \enum QScrollerProperties::ScrollMetric
-
- This enum contains the different scroll metric types. When not indicated otherwise the
- setScrollMetric function expects a QVariant of type qreal.
-
- See the QScroller documentation for further details of the concepts behind the different
- values.
-
- \value MousePressEventDelay This is the time a mouse press event is delayed when starting
- a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or
- release is sent to the scrolled object. If it triggers after that delay the delayed
- mouse press plus a faked release event at global postion \c{QPoint(-QWIDGETSIZE_MAX,
- -QWIDGETSIZE_MAX)} is sent. If the gesture is canceled, then both the delayed mouse
- press plus the real release event are delivered.
-
- \value DragStartDistance This is the minimum distance the touch or mouse point needs to be
- moved before the flick gesture is triggered in \c m.
-
- \value DragVelocitySmoothingFactor A value that describes to which extent new drag velocities are
- included in the final scrolling velocity. This value should be in the range between \c 0 and
- \c 1. The lower the value, the more smoothing is applied to the dragging velocity.
-
- \value AxisLockThreshold Restricts the movement to one axis if the movement is inside an angle
- around the axis. The threshold must be in the range \c 0 to \c 1.
-
- \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an
- user initiated flick. Please note that this is the easing curve for the positions, \bold{not}
- the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in
- velocity (1st derivative) and a constant deceleration (2nd derivative).
-
- \value DecelerationFactor This factor influences how long it takes the scroller to decelerate
- to 0 velocity. The actual value depends on the chosen ScrollingCurve. For most
- types the value should be in the range from \c 0.1 to \c 2.0
-
- \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing
- the mouse to start scrolling in \c{m/s}.
-
- \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}.
-
- \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through
- in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop
- the scrolling but the click event will also be delivered to the UI control. This is
- useful when using exponential-type scrolling curves.
-
- \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture
- can take to be recognized as an accelerating flick. If set to zero no such gesture is
- detected. An "accelerating flick" is a flick gesture executed on an already scrolling object.
- In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to
- accelerate it.
-
- \value AcceleratingFlickSpeedupFactor The current speed is multiplied by this number if an
- accelerating flick is detected. Should be \c{>= 1}.
-
- \value SnapPositionRatio This is the distance that the user must drag the area beween two snap
- points in order to snap it to the next position. \c{0.33} means that the scroll must only
- reach one third of the distance between two snap points to snap to the next one. The ratio must
- be between \c 0 and \c 1.
-
- \value SnapTime This is the time factor for the scrolling curve. A lower value means that the
- scrolling will take longer. The scrolling distance is independet of this value.
-
- \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and
- the actual scroll area movement (during overshoot). The factor must be between \c 0 and \c 1.
-
- \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while
- dragging. The actual overshoot distance is calculated by multiplying this value with the
- viewport size of the scrolled object. The factor must be between \c 0 and \c 1.
-
- \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while
- scrolling. The actual overshoot distance is calculated by multiplying this value with the
- viewport size of the scrolled object. The factor must be between \c 0 and \c 1.
-
- \value OvershootScrollTime This is the time in \c seconds that is used to play the
- complete overshoot animation.
-
- \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).
-
- \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).
-
- \value FrameRate This is the frame rate which should be used while dragging or scrolling.
- QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other
- animations that might be active at the same time. If the standard value of 60 frames per
- second is too fast, it can be lowered with this setting,
- while still being in-sync with QAbstractAnimation. Please note that only the values of the
- FrameRates enum are allowed here.
-
- \value ScrollMetricCount This is always the last entry.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h
deleted file mode 100644
index 75d8932f81..0000000000
--- a/src/gui/util/qscrollerproperties.h
+++ /dev/null
@@ -1,140 +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 QSCROLLERPROPERTIES_H
-#define QSCROLLERPROPERTIES_H
-
-#include <QtCore/QScopedPointer>
-#include <QtCore/QMetaType>
-#include <QtCore/QVariant>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QScroller;
-class QScrollerPrivate;
-class QScrollerPropertiesPrivate;
-
-class Q_GUI_EXPORT QScrollerProperties
-{
-public:
- QScrollerProperties();
- QScrollerProperties(const QScrollerProperties &sp);
- QScrollerProperties &operator=(const QScrollerProperties &sp);
- virtual ~QScrollerProperties();
-
- bool operator==(const QScrollerProperties &sp) const;
- bool operator!=(const QScrollerProperties &sp) const;
-
- static void setDefaultScrollerProperties(const QScrollerProperties &sp);
- static void unsetDefaultScrollerProperties();
-
- enum OvershootPolicy
- {
- OvershootWhenScrollable,
- OvershootAlwaysOff,
- OvershootAlwaysOn
- };
-
- enum FrameRates {
- Standard,
- Fps60,
- Fps30,
- Fps20
- };
-
- enum ScrollMetric
- {
- MousePressEventDelay, // qreal [s]
- DragStartDistance, // qreal [m]
- DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
- AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)
-
- ScrollingCurve, // QEasingCurve
- DecelerationFactor, // slope of the curve
-
- MinimumVelocity, // qreal [m/s]
- MaximumVelocity, // qreal [m/s]
- MaximumClickThroughVelocity, // qreal [m/s]
-
- AcceleratingFlickMaximumTime, // qreal [s]
- AcceleratingFlickSpeedupFactor, // qreal [1..]
-
- SnapPositionRatio, // qreal [0..1]
- SnapTime, // qreal [s]
-
- OvershootDragResistanceFactor, // qreal [0..1]
- OvershootDragDistanceFactor, // qreal [0..1]
- OvershootScrollDistanceFactor, // qreal [0..1]
- OvershootScrollTime, // qreal [s]
-
- HorizontalOvershootPolicy, // enum OvershootPolicy
- VerticalOvershootPolicy, // enum OvershootPolicy
- FrameRate, // enum FrameRates
-
- ScrollMetricCount
- };
-
- QVariant scrollMetric(ScrollMetric metric) const;
- void setScrollMetric(ScrollMetric metric, const QVariant &value);
-
-protected:
- QScopedPointer<QScrollerPropertiesPrivate> d;
-
-private:
- QScrollerProperties(QScrollerPropertiesPrivate &dd);
-
- friend class QScrollerPropertiesPrivate;
- friend class QScroller;
- friend class QScrollerPrivate;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy)
-Q_DECLARE_METATYPE(QScrollerProperties::FrameRates)
-
-QT_END_HEADER
-
-#endif // QSCROLLERPROPERTIES_H
diff --git a/src/gui/util/qscrollerproperties_p.h b/src/gui/util/qscrollerproperties_p.h
deleted file mode 100644
index 76d8b0a79b..0000000000
--- a/src/gui/util/qscrollerproperties_p.h
+++ /dev/null
@@ -1,94 +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 QSCROLLERPROPERTIES_P_H
-#define QSCROLLERPROPERTIES_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 <QPointF>
-#include <QEasingCurve>
-#include <qscrollerproperties.h>
-
-QT_BEGIN_NAMESPACE
-
-class QScrollerPropertiesPrivate
-{
-public:
- static QScrollerPropertiesPrivate *defaults();
-
- bool operator==(const QScrollerPropertiesPrivate &) const;
-
- qreal mousePressEventDelay;
- qreal dragStartDistance;
- qreal dragVelocitySmoothingFactor;
- qreal axisLockThreshold;
- QEasingCurve scrollingCurve;
- qreal decelerationFactor;
- qreal minimumVelocity;
- qreal maximumVelocity;
- qreal maximumClickThroughVelocity;
- qreal acceleratingFlickMaximumTime;
- qreal acceleratingFlickSpeedupFactor;
- qreal snapPositionRatio;
- qreal snapTime;
- qreal overshootDragResistanceFactor;
- qreal overshootDragDistanceFactor;
- qreal overshootScrollDistanceFactor;
- qreal overshootScrollTime;
- QScrollerProperties::OvershootPolicy hOvershootPolicy;
- QScrollerProperties::OvershootPolicy vOvershootPolicy;
- QScrollerProperties::FrameRates frameRate;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSCROLLERPROPERTIES_P_H
-
diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp
deleted file mode 100644
index 33cc61ee97..0000000000
--- a/src/gui/util/qsystemtrayicon.cpp
+++ /dev/null
@@ -1,674 +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 "qsystemtrayicon.h"
-#include "qsystemtrayicon_p.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include "qmenu.h"
-#include "qevent.h"
-#include "qpoint.h"
-#include "qlabel.h"
-#include "qpushbutton.h"
-#include "qpainterpath.h"
-#include "qpainter.h"
-#include "qstyle.h"
-#include "qgridlayout.h"
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qbitmap.h"
-#include "private/qlabel_p.h"
-#include "qapplication.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QSystemTrayIcon
- \brief The QSystemTrayIcon class provides an icon for an application in the system tray.
- \since 4.2
- \ingroup desktop
-
- Modern operating systems usually provide a special area on the desktop,
- called the \e{system tray} or \e{notification area}, where long-running
- applications can display icons and short messages.
-
- \image system-tray.png The system tray on Windows XP.
-
- The QSystemTrayIcon class can be used on the following platforms:
-
- \list
- \o All supported versions of Windows.
- \o All window managers for X11 that implement the \l{freedesktop.org} system
- tray specification, including recent versions of KDE and GNOME.
- \o All supported versions of Mac OS X. Note that the Growl
- notification system must be installed for
- QSystemTrayIcon::showMessage() to display messages.
- \endlist
-
- To check whether a system tray is present on the user's desktop,
- call the QSystemTrayIcon::isSystemTrayAvailable() static function.
-
- To add a system tray entry, create a QSystemTrayIcon object, call setContextMenu()
- to provide a context menu for the icon, and call show() to make it visible in the
- system tray. Status notification messages ("balloon messages") can be displayed at
- any time using showMessage().
-
- If the system tray is unavailable when a system tray icon is constructed, but
- becomes available later, QSystemTrayIcon will automatically add an entry for the
- application in the system tray if the icon is \l visible.
-
- The activated() signal is emitted when the user activates the icon.
-
- Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent
- of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of
- type QEvent::Wheel. These are not supported on any other platform.
-
- \sa QDesktopServices, QDesktopWidget, {Desktop Integration}, {System Tray Icon Example}
-*/
-
-/*!
- \enum QSystemTrayIcon::MessageIcon
-
- This enum describes the icon that is shown when a balloon message is displayed.
-
- \value NoIcon No icon is shown.
- \value Information An information icon is shown.
- \value Warning A standard warning icon is shown.
- \value Critical A critical warning icon is shown.
-
- \sa QMessageBox
-*/
-
-/*!
- Constructs a QSystemTrayIcon object with the given \a parent.
-
- The icon is initially invisible.
-
- \sa visible
-*/
-QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
-: QObject(*new QSystemTrayIconPrivate(), parent)
-{
-}
-
-/*!
- Constructs a QSystemTrayIcon object with the given \a icon and \a parent.
-
- The icon is initially invisible.
-
- \sa visible
-*/
-QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
-: QObject(*new QSystemTrayIconPrivate(), parent)
-{
- setIcon(icon);
-}
-
-/*!
- Removes the icon from the system tray and frees all allocated resources.
-*/
-QSystemTrayIcon::~QSystemTrayIcon()
-{
- Q_D(QSystemTrayIcon);
- d->remove_sys();
-}
-
-#ifndef QT_NO_MENU
-
-/*!
- Sets the specified \a menu to be the context menu for the system tray icon.
-
- The menu will pop up when the user requests the context menu for the system
- tray icon by clicking the mouse button.
-
- On Mac OS X, this is currenly converted to a NSMenu, so the
- aboutToHide() signal is not emitted.
-
- \note The system tray icon does not take ownership of the menu. You must
- ensure that it is deleted at the appropriate time by, for example, creating
- the menu with a suitable parent object.
-*/
-void QSystemTrayIcon::setContextMenu(QMenu *menu)
-{
- Q_D(QSystemTrayIcon);
- d->menu = menu;
- d->updateMenu_sys();
-}
-
-/*!
- Returns the current context menu for the system tray entry.
-*/
-QMenu* QSystemTrayIcon::contextMenu() const
-{
- Q_D(const QSystemTrayIcon);
- return d->menu;
-}
-
-#endif // QT_NO_MENU
-
-/*!
- \property QSystemTrayIcon::icon
- \brief the system tray icon
-
- On Windows, the system tray icon size is 16x16; on X11, the preferred size is
- 22x22. The icon will be scaled to the appropriate size as necessary.
-*/
-void QSystemTrayIcon::setIcon(const QIcon &icon)
-{
- Q_D(QSystemTrayIcon);
- d->icon = icon;
- d->updateIcon_sys();
-}
-
-QIcon QSystemTrayIcon::icon() const
-{
- Q_D(const QSystemTrayIcon);
- return d->icon;
-}
-
-/*!
- \property QSystemTrayIcon::toolTip
- \brief the tooltip for the system tray entry
-
- On some systems, the tooltip's length is limited. The tooltip will be truncated
- if necessary.
-*/
-void QSystemTrayIcon::setToolTip(const QString &tooltip)
-{
- Q_D(QSystemTrayIcon);
- d->toolTip = tooltip;
- d->updateToolTip_sys();
-}
-
-QString QSystemTrayIcon::toolTip() const
-{
- Q_D(const QSystemTrayIcon);
- return d->toolTip;
-}
-
-/*!
- \fn void QSystemTrayIcon::show()
-
- Shows the icon in the system tray.
-
- \sa hide(), visible
-*/
-
-/*!
- \fn void QSystemTrayIcon::hide()
-
- Hides the system tray entry.
-
- \sa show(), visible
-*/
-
-/*!
- \since 4.3
- Returns the geometry of the system tray icon in screen coordinates.
-
- \sa visible
-*/
-QRect QSystemTrayIcon::geometry() const
-{
- Q_D(const QSystemTrayIcon);
- if (!d->visible)
- return QRect();
- return d->geometry_sys();
-}
-
-/*!
- \property QSystemTrayIcon::visible
- \brief whether the system tray entry is visible
-
- Setting this property to true or calling show() makes the system tray icon
- visible; setting this property to false or calling hide() hides it.
-*/
-void QSystemTrayIcon::setVisible(bool visible)
-{
- Q_D(QSystemTrayIcon);
- if (visible == d->visible)
- return;
- if (d->icon.isNull() && visible)
- qWarning("QSystemTrayIcon::setVisible: No Icon set");
- d->visible = visible;
- if (d->visible)
- d->install_sys();
- else
- d->remove_sys();
-}
-
-bool QSystemTrayIcon::isVisible() const
-{
- Q_D(const QSystemTrayIcon);
- return d->visible;
-}
-
-/*!
- \reimp
-*/
-bool QSystemTrayIcon::event(QEvent *e)
-{
-#if defined(Q_WS_X11)
- if (e->type() == QEvent::ToolTip) {
- Q_D(QSystemTrayIcon);
- return d->sys->deliverToolTipEvent(e);
- }
-#endif
- return QObject::event(e);
-}
-
-/*!
- \enum QSystemTrayIcon::ActivationReason
-
- This enum describes the reason the system tray was activated.
-
- \value Unknown Unknown reason
- \value Context The context menu for the system tray entry was requested
- \value DoubleClick The system tray entry was double clicked
- \value Trigger The system tray entry was clicked
- \value MiddleClick The system tray entry was clicked with the middle mouse button
-
- \sa activated()
-*/
-
-/*!
- \fn void QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)
-
- This signal is emitted when the user activates the system tray icon. \a reason
- specifies the reason for activation. QSystemTrayIcon::ActivationReason enumerates
- the various reasons.
-
- \sa QSystemTrayIcon::ActivationReason
-*/
-
-/*!
- \fn void QSystemTrayIcon::messageClicked()
-
- This signal is emitted when the message displayed using showMessage()
- was clicked by the user.
-
- Currently this signal is not sent on Mac OS X.
-
- \note We follow Microsoft Windows XP/Vista behavior, so the
- signal is also emitted when the user clicks on a tray icon with
- a balloon message displayed.
-
- \sa activated()
-*/
-
-
-/*!
- Returns true if the system tray is available; otherwise returns false.
-
- If the system tray is currently unavailable but becomes available later,
- QSystemTrayIcon will automatically add an entry in the system tray if it
- is \l visible.
-*/
-
-bool QSystemTrayIcon::isSystemTrayAvailable()
-{
- return QSystemTrayIconPrivate::isSystemTrayAvailable_sys();
-}
-
-/*!
- Returns true if the system tray supports balloon messages; otherwise returns false.
-
- \sa showMessage()
-*/
-bool QSystemTrayIcon::supportsMessages()
-{
- return QSystemTrayIconPrivate::supportsMessages_sys();
-}
-
-/*!
- \fn void QSystemTrayIcon::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint)
- \since 4.3
-
- Shows a balloon message for the entry with the given \a title, \a message and
- \a icon for the time specified in \a millisecondsTimeoutHint. \a title and \a message
- must be plain text strings.
-
- Message can be clicked by the user; the messageClicked() signal will emitted when
- this occurs.
-
- Note that display of messages are dependent on the system configuration and user
- preferences, and that messages may not appear at all. Hence, it should not be
- relied upon as the sole means for providing critical information.
-
- On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
- when the application has focus.
-
- On Mac OS X, the Growl notification system must be installed for this function to
- display messages.
-
- \sa show() supportsMessages()
- */
-void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
- QSystemTrayIcon::MessageIcon icon, int msecs)
-{
- Q_D(QSystemTrayIcon);
- if (d->visible)
- d->showMessage_sys(title, msg, icon, msecs);
-}
-
-//////////////////////////////////////////////////////////////////////
-static QBalloonTip *theSolitaryBalloonTip = 0;
-
-void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& message, QSystemTrayIcon *trayIcon,
- const QPoint& pos, int timeout, bool showArrow)
-{
- hideBalloon();
- if (message.isEmpty() && title.isEmpty())
- return;
-
- theSolitaryBalloonTip = new QBalloonTip(icon, title, message, trayIcon);
- if (timeout < 0)
- timeout = 10000; //10 s default
- theSolitaryBalloonTip->balloon(pos, timeout, showArrow);
-}
-
-void QBalloonTip::hideBalloon()
-{
- if (!theSolitaryBalloonTip)
- return;
- theSolitaryBalloonTip->hide();
- delete theSolitaryBalloonTip;
- theSolitaryBalloonTip = 0;
-}
-
-bool QBalloonTip::isBalloonVisible()
-{
- return theSolitaryBalloonTip;
-}
-
-QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& message, QSystemTrayIcon *ti)
- : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1)
-{
- setAttribute(Qt::WA_DeleteOnClose);
- QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close()));
-
- QLabel *titleLabel = new QLabel;
- titleLabel->installEventFilter(this);
- titleLabel->setText(title);
- QFont f = titleLabel->font();
- f.setBold(true);
-#ifdef Q_WS_WINCE
- f.setPointSize(f.pointSize() - 2);
-#endif
- titleLabel->setFont(f);
- titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows
-
-#ifdef Q_WS_WINCE
- const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
- const int closeButtonSize = style()->pixelMetric(QStyle::PM_SmallIconSize) - 2;
-#else
- const int iconSize = 18;
- const int closeButtonSize = 15;
-#endif
-
- QPushButton *closeButton = new QPushButton;
- closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
- closeButton->setIconSize(QSize(closeButtonSize, closeButtonSize));
- closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- closeButton->setFixedSize(closeButtonSize, closeButtonSize);
- QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
-
- QLabel *msgLabel = new QLabel;
-#ifdef Q_WS_WINCE
- f.setBold(false);
- msgLabel->setFont(f);
-#endif
- msgLabel->installEventFilter(this);
- msgLabel->setText(message);
- msgLabel->setTextFormat(Qt::PlainText);
- msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
-
- // smart size for the message label
-#ifdef Q_WS_WINCE
- int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 2;
-#else
- int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3;
-#endif
- if (msgLabel->sizeHint().width() > limit) {
- msgLabel->setWordWrap(true);
- if (msgLabel->sizeHint().width() > limit) {
- msgLabel->d_func()->ensureTextControl();
- if (QTextControl *control = msgLabel->d_func()->control) {
- QTextOption opt = control->document()->defaultTextOption();
- opt.setWrapMode(QTextOption::WrapAnywhere);
- control->document()->setDefaultTextOption(opt);
- }
- }
-#ifdef Q_WS_WINCE
- // Make sure that the text isn't wrapped "somewhere" in the balloon widget
- // in the case that we have a long title label.
- setMaximumWidth(limit);
-#else
- // Here we allow the text being much smaller than the balloon widget
- // to emulate the weird standard windows behavior.
- msgLabel->setFixedSize(limit, msgLabel->heightForWidth(limit));
-#endif
- }
-
- QIcon si;
- switch (icon) {
- case QSystemTrayIcon::Warning:
- si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
- break;
- case QSystemTrayIcon::Critical:
- si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
- break;
- case QSystemTrayIcon::Information:
- si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
- break;
- case QSystemTrayIcon::NoIcon:
- default:
- break;
- }
-
- QGridLayout *layout = new QGridLayout;
- if (!si.isNull()) {
- QLabel *iconLabel = new QLabel;
- iconLabel->setPixmap(si.pixmap(iconSize, iconSize));
- iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- iconLabel->setMargin(2);
- layout->addWidget(iconLabel, 0, 0);
- layout->addWidget(titleLabel, 0, 1);
- } else {
- layout->addWidget(titleLabel, 0, 0, 1, 2);
- }
-
- layout->addWidget(closeButton, 0, 2);
- layout->addWidget(msgLabel, 1, 0, 1, 3);
- layout->setSizeConstraint(QLayout::SetFixedSize);
- layout->setMargin(3);
- setLayout(layout);
-
- QPalette pal = palette();
- pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
- pal.setColor(QPalette::WindowText, Qt::black);
- setPalette(pal);
-}
-
-QBalloonTip::~QBalloonTip()
-{
- theSolitaryBalloonTip = 0;
-}
-
-void QBalloonTip::paintEvent(QPaintEvent *)
-{
- QPainter painter(this);
- painter.drawPixmap(rect(), pixmap);
-}
-
-void QBalloonTip::resizeEvent(QResizeEvent *ev)
-{
- QWidget::resizeEvent(ev);
-}
-
-void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
-{
- QRect scr = QApplication::desktop()->screenGeometry(pos);
- QSize sh = sizeHint();
- const int border = 1;
- const int ah = 18, ao = 18, aw = 18, rc = 7;
- bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height());
- bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width());
- setContentsMargins(border + 3, border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2);
- updateGeometry();
- sh = sizeHint();
-
- int ml, mr, mt, mb;
- QSize sz = sizeHint();
- if (!arrowAtTop) {
- ml = mt = 0;
- mr = sz.width() - 1;
- mb = sz.height() - ah - 1;
- } else {
- ml = 0;
- mt = ah;
- mr = sz.width() - 1;
- mb = sz.height() - 1;
- }
-
- QPainterPath path;
-#if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
- // XShape is required for setting the mask, so we just
- // draw an ugly square when its not available
- path.moveTo(0, 0);
- path.lineTo(sz.width() - 1, 0);
- path.lineTo(sz.width() - 1, sz.height() - 1);
- path.lineTo(0, sz.height() - 1);
- path.lineTo(0, 0);
- move(qMax(pos.x() - sz.width(), scr.left()), pos.y());
-#else
- path.moveTo(ml + rc, mt);
- if (arrowAtTop && arrowAtLeft) {
- if (showArrow) {
- path.lineTo(ml + ao, mt);
- path.lineTo(ml + ao, mt - ah);
- path.lineTo(ml + ao + aw, mt);
- }
- move(qMax(pos.x() - ao, scr.left() + 2), pos.y());
- } else if (arrowAtTop && !arrowAtLeft) {
- if (showArrow) {
- path.lineTo(mr - ao - aw, mt);
- path.lineTo(mr - ao, mt - ah);
- path.lineTo(mr - ao, mt);
- }
- move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y());
- }
- path.lineTo(mr - rc, mt);
- path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90);
- path.lineTo(mr, mb - rc);
- path.arcTo(QRect(mr - rc*2, mb - rc*2, rc*2, rc*2), 0, -90);
- if (!arrowAtTop && !arrowAtLeft) {
- if (showArrow) {
- path.lineTo(mr - ao, mb);
- path.lineTo(mr - ao, mb + ah);
- path.lineTo(mr - ao - aw, mb);
- }
- move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2),
- pos.y() - sh.height());
- } else if (!arrowAtTop && arrowAtLeft) {
- if (showArrow) {
- path.lineTo(ao + aw, mb);
- path.lineTo(ao, mb + ah);
- path.lineTo(ao, mb);
- }
- move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height());
- }
- path.lineTo(ml + rc, mb);
- path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90);
- path.lineTo(ml, mt + rc);
- path.arcTo(QRect(ml, mt, rc*2, rc*2), 180, -90);
-
- // Set the mask
- QBitmap bitmap = QBitmap(sizeHint());
- bitmap.fill(Qt::color0);
- QPainter painter1(&bitmap);
- painter1.setPen(QPen(Qt::color1, border));
- painter1.setBrush(QBrush(Qt::color1));
- painter1.drawPath(path);
- setMask(bitmap);
-#endif
-
- // Draw the border
- pixmap = QPixmap(sz);
- QPainter painter2(&pixmap);
- painter2.setPen(QPen(palette().color(QPalette::Window).darker(160), border));
- painter2.setBrush(palette().color(QPalette::Window));
- painter2.drawPath(path);
-
- if (msecs > 0)
- timerId = startTimer(msecs);
- show();
-}
-
-void QBalloonTip::mousePressEvent(QMouseEvent *e)
-{
- close();
- if(e->button() == Qt::LeftButton)
- emit trayIcon->messageClicked();
-}
-
-void QBalloonTip::timerEvent(QTimerEvent *e)
-{
- if (e->timerId() == timerId) {
- killTimer(timerId);
- if (!underMouse())
- close();
- return;
- }
- QWidget::timerEvent(e);
-}
-
-void qtsystray_sendActivated(QSystemTrayIcon *i, int r)
-{
- emit i->activated((QSystemTrayIcon::ActivationReason)r);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/gui/util/qsystemtrayicon.h b/src/gui/util/qsystemtrayicon.h
deleted file mode 100644
index 1f0dab5393..0000000000
--- a/src/gui/util/qsystemtrayicon.h
+++ /dev/null
@@ -1,132 +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 QSYSTEMTRAYICON_H
-#define QSYSTEMTRAYICON_H
-
-#include <QtCore/qobject.h>
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QSystemTrayIconPrivate;
-
-class QMenu;
-class QEvent;
-class QWheelEvent;
-class QMouseEvent;
-class QPoint;
-
-class Q_GUI_EXPORT QSystemTrayIcon : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
-
-public:
- QSystemTrayIcon(QObject *parent = 0);
- QSystemTrayIcon(const QIcon &icon, QObject *parent = 0);
- ~QSystemTrayIcon();
-
- enum ActivationReason {
- Unknown,
- Context,
- DoubleClick,
- Trigger,
- MiddleClick
- };
-
-#ifndef QT_NO_MENU
- void setContextMenu(QMenu *menu);
- QMenu *contextMenu() const;
-#endif
-
- QIcon icon() const;
- void setIcon(const QIcon &icon);
-
- QString toolTip() const;
- void setToolTip(const QString &tip);
-
- static bool isSystemTrayAvailable();
- static bool supportsMessages();
-
- enum MessageIcon { NoIcon, Information, Warning, Critical };
- void showMessage(const QString &title, const QString &msg,
- MessageIcon icon = Information, int msecs = 10000);
-
- QRect geometry() const;
- bool isVisible() const;
-
-public Q_SLOTS:
- void setVisible(bool visible);
- inline void show() { setVisible(true); }
- inline void hide() { setVisible(false); }
-
-Q_SIGNALS:
- void activated(QSystemTrayIcon::ActivationReason reason);
- void messageClicked();
-
-protected:
- bool event(QEvent *event);
-
-private:
- Q_DISABLE_COPY(QSystemTrayIcon)
- Q_DECLARE_PRIVATE(QSystemTrayIcon)
-
- friend class QSystemTrayIconSys;
- friend class QBalloonTip;
- friend void qtsystray_sendActivated(QSystemTrayIcon *, int);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_SYSTEMTRAYICON
-#endif // QSYSTEMTRAYICON_H
diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm
deleted file mode 100644
index 0ec0b07040..0000000000
--- a/src/gui/util/qsystemtrayicon_mac.mm
+++ /dev/null
@@ -1,578 +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$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#define QT_MAC_SYSTEMTRAY_USE_GROWL
-
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qsystemtrayicon_p.h>
-#include <qtemporaryfile.h>
-#include <qimagewriter.h>
-#include <qapplication.h>
-#include <qdebug.h>
-#include <qstyle.h>
-
-#include <private/qt_mac_p.h>
-#import <AppKit/AppKit.h>
-
-QT_BEGIN_NAMESPACE
-extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret); //qapplication_mac.cpp
-extern void qtsystray_sendActivated(QSystemTrayIcon *i, int r); //qsystemtrayicon.cpp
-extern NSString *keySequenceToKeyEqivalent(const QKeySequence &accel); // qmenu_mac.mm
-extern NSUInteger keySequenceModifierMask(const QKeySequence &accel); // qmenu_mac.mm
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-@class QT_MANGLE_NAMESPACE(QNSMenu);
-@class QT_MANGLE_NAMESPACE(QNSImageView);
-
-@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject {
- NSStatusItem *item;
- QSystemTrayIcon *icon;
- QSystemTrayIconPrivate *iconPrivate;
- QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
-}
--(id)initWithIcon:(QSystemTrayIcon*)icon iconPrivate:(QSystemTrayIconPrivate *)iprivate;
--(void)dealloc;
--(QSystemTrayIcon*)icon;
--(NSStatusItem*)item;
--(QRectF)geometry;
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton;
-- (void)doubleClickSelector:(id)sender;
-@end
-
-@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView {
- BOOL down;
- QT_MANGLE_NAMESPACE(QNSStatusItem) *parent;
-}
--(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent;
--(QSystemTrayIcon*)icon;
--(void)menuTrackingDone:(NSNotification*)notification;
--(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton;
-@end
-
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-
-@protocol NSMenuDelegate <NSObject>
--(void)menuNeedsUpdate:(NSMenu*)menu;
-@end
-#endif
-
-
-@interface QT_MANGLE_NAMESPACE(QNSMenu) : NSMenu <NSMenuDelegate> {
- QMenu *qmenu;
-}
--(QMenu*)menu;
--(id)initWithQMenu:(QMenu*)qmenu;
--(void)selectedAction:(id)item;
-@end
-
-QT_BEGIN_NAMESPACE
-class QSystemTrayIconSys
-{
-public:
- QSystemTrayIconSys(QSystemTrayIcon *icon, QSystemTrayIconPrivate *d) {
- QMacCocoaAutoReleasePool pool;
- item = [[QT_MANGLE_NAMESPACE(QNSStatusItem) alloc] initWithIcon:icon iconPrivate:d];
- }
- ~QSystemTrayIconSys() {
- QMacCocoaAutoReleasePool pool;
- [[[item item] view] setHidden: YES];
- [item release];
- }
- QT_MANGLE_NAMESPACE(QNSStatusItem) *item;
-};
-
-void QSystemTrayIconPrivate::install_sys()
-{
- Q_Q(QSystemTrayIcon);
- if (!sys) {
- sys = new QSystemTrayIconSys(q, this);
- updateIcon_sys();
- updateMenu_sys();
- updateToolTip_sys();
- }
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- if(sys) {
- const QRectF geom = [sys->item geometry];
- if(!geom.isNull())
- return geom.toRect();
- }
- return QRect();
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
- delete sys;
- sys = 0;
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
- if(sys && !icon.isNull()) {
- QMacCocoaAutoReleasePool pool;
-#ifndef QT_MAC_USE_COCOA
- const short scale = GetMBarHeight()-4;
-#else
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-#endif
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(icon.pixmap(QSize(scale, scale))));
- [(NSImageView*)[[sys->item item] view] setImage: nsimage];
- [nsimage release];
- }
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
- if(sys) {
- QMacCocoaAutoReleasePool pool;
- if(menu && !menu->isEmpty()) {
- [[sys->item item] setHighlightMode:YES];
- } else {
- [[sys->item item] setHighlightMode:NO];
- }
- }
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
- if(sys) {
- QMacCocoaAutoReleasePool pool;
- QCFString string(toolTip);
- [[[sys->item item] view] setToolTip:(NSString*)static_cast<CFStringRef>(string)];
- }
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return true;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return true;
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon icon, int)
-{
-
- if(sys) {
-#ifdef QT_MAC_SYSTEMTRAY_USE_GROWL
- // Make sure that we have Growl installed on the machine we are running on.
- QCFType<CFURLRef> cfurl;
- OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator,
- CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl);
- if (status == kLSApplicationNotFoundErr)
- return;
- QCFType<CFBundleRef> bundle = CFBundleCreate(0, cfurl);
-
- if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"),
- kCFCompareCaseInsensitive | kCFCompareBackwards) != kCFCompareEqualTo)
- return;
- QPixmap notificationIconPixmap;
- if(icon == QSystemTrayIcon::Information)
- notificationIconPixmap = QApplication::style()->standardPixmap(QStyle::SP_MessageBoxInformation);
- else if(icon == QSystemTrayIcon::Warning)
- notificationIconPixmap = QApplication::style()->standardPixmap(QStyle::SP_MessageBoxWarning);
- else if(icon == QSystemTrayIcon::Critical)
- notificationIconPixmap = QApplication::style()->standardPixmap(QStyle::SP_MessageBoxCritical);
- QTemporaryFile notificationIconFile;
- QString notificationType(QLatin1String("Notification")), notificationIcon, notificationApp(QApplication::applicationName());
- if(notificationApp.isEmpty())
- notificationApp = QLatin1String("Application");
- if(!notificationIconPixmap.isNull() && notificationIconFile.open()) {
- QImageWriter writer(&notificationIconFile, "PNG");
- if(writer.write(notificationIconPixmap.toImage()))
- notificationIcon = QLatin1String("image from location \"file://") + notificationIconFile.fileName() + QLatin1String("\"");
- }
- const QString script(QLatin1String(
- "tell application \"GrowlHelperApp\"\n"
- "-- Make a list of all the notification types (all)\n"
- "set the allNotificationsList to {\"") + notificationType + QLatin1String("\"}\n"
-
- "-- Make a list of the notifications (enabled)\n"
- "set the enabledNotificationsList to {\"") + notificationType + QLatin1String("\"}\n"
-
- "-- Register our script with growl.\n"
- "register as application \"") + notificationApp + QLatin1String("\" all notifications allNotificationsList default notifications enabledNotificationsList\n"
-
- "-- Send a Notification...\n") +
- QLatin1String("notify with name \"") + notificationType +
- QLatin1String("\" title \"") + title +
- QLatin1String("\" description \"") + message +
- QLatin1String("\" application name \"") + notificationApp +
- QLatin1String("\" ") + notificationIcon +
- QLatin1String("\nend tell"));
- qt_mac_execute_apple_script(script, 0);
-#elif 0
- Q_Q(QSystemTrayIcon);
- NSView *v = [[sys->item item] view];
- NSWindow *w = [v window];
- w = [[sys->item item] window];
- qDebug() << w << v;
- QPoint p(qRound([w frame].origin.x), qRound([w frame].origin.y));
- qDebug() << p;
- QBalloonTip::showBalloon(icon, message, title, q, QPoint(0, 0), msecs);
-#else
- Q_UNUSED(icon);
- Q_UNUSED(title);
- Q_UNUSED(message);
-#endif
- }
-}
-QT_END_NAMESPACE
-
-@implementation NSStatusItem (Qt)
-@end
-
-@implementation QT_MANGLE_NAMESPACE(QNSImageView)
--(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent {
- self = [super init];
- parent = myParent;
- down = NO;
- return self;
-}
-
--(QSystemTrayIcon*)icon {
- return [parent icon];
-}
-
--(void)menuTrackingDone:(NSNotification*)notification
-{
- Q_UNUSED(notification);
- down = NO;
-
- if( ![self icon]->icon().isNull() ) {
-#ifndef QT_MAC_USE_COCOA
- const short scale = GetMBarHeight()-4;
-#else
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-#endif
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale))));
- [self setImage: nsimage];
- [nsimage release];
- }
-
- if([self icon]->contextMenu())
- [self icon]->contextMenu()->hide();
-
- [self setNeedsDisplay:YES];
-}
-
--(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton
-{
- down = YES;
- int clickCount = [mouseEvent clickCount];
- [self setNeedsDisplay:YES];
-
-#ifndef QT_MAC_USE_COCOA
- const short scale = GetMBarHeight()-4;
-#else
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-#endif
-
- if (![self icon]->icon().isNull() ) {
- NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale), QIcon::Selected)));
- [self setImage: nsaltimage];
- [nsaltimage release];
- }
-
- if ((clickCount == 2)) {
- [self menuTrackingDone:nil];
- [parent doubleClickSelector:self];
- } else {
- [parent triggerSelector:self button:mouseButton];
- }
-}
-
--(void)mouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent button:Qt::LeftButton];
-}
-
--(void)mouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
-
-- (void)rightMouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent button:Qt::RightButton];
-}
-
--(void)rightMouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
-
-- (void)otherMouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent button:cocoaButton2QtButton([mouseEvent buttonNumber])];
-}
-
--(void)otherMouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
-
--(void)drawRect:(NSRect)rect {
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
- [super drawRect:rect];
-}
-@end
-
-@implementation QT_MANGLE_NAMESPACE(QNSStatusItem)
-
--(id)initWithIcon:(QSystemTrayIcon*)i iconPrivate:(QSystemTrayIconPrivate *)iPrivate
-{
- self = [super init];
- if(self) {
- icon = i;
- iconPrivate = iPrivate;
- item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
- imageCell = [[QT_MANGLE_NAMESPACE(QNSImageView) alloc] initWithParent:self];
- [item setView: imageCell];
- }
- return self;
-}
--(void)dealloc {
- [[NSStatusBar systemStatusBar] removeStatusItem:item];
- [imageCell release];
- [item release];
- [super dealloc];
-
-}
-
--(QSystemTrayIcon*)icon {
- return icon;
-}
-
--(NSStatusItem*)item {
- return item;
-}
--(QRectF)geometry {
- if(NSWindow *window = [[item view] window]) {
- NSRect screenRect = [[window screen] frame];
- NSRect windowRect = [window frame];
- return QRectF(windowRect.origin.x, screenRect.size.height-windowRect.origin.y-windowRect.size.height, windowRect.size.width, windowRect.size.height);
- }
- return QRectF();
-}
-
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton {
- Q_UNUSED(sender);
- if (!icon)
- return;
-
- if (mouseButton == Qt::MidButton)
- qtsystray_sendActivated(icon, QSystemTrayIcon::MiddleClick);
- else
- qtsystray_sendActivated(icon, QSystemTrayIcon::Trigger);
-
- if (icon->contextMenu()) {
-#ifndef QT_MAC_USE_COCOA
- [[[self item] view] removeAllToolTips];
- iconPrivate->updateToolTip_sys();
-#endif
- NSMenu *m = [[QT_MANGLE_NAMESPACE(QNSMenu) alloc] initWithQMenu:icon->contextMenu()];
- [m setAutoenablesItems: NO];
- [[NSNotificationCenter defaultCenter] addObserver:imageCell
- selector:@selector(menuTrackingDone:)
- name:NSMenuDidEndTrackingNotification
- object:m];
- [item popUpStatusItemMenu: m];
- [m release];
- }
-}
-
-- (void)doubleClickSelector:(id)sender {
- Q_UNUSED(sender);
- if(!icon)
- return;
- qtsystray_sendActivated(icon, QSystemTrayIcon::DoubleClick);
-}
-
-@end
-
-class QSystemTrayIconQMenu : public QMenu
-{
-public:
- void doAboutToShow() { emit aboutToShow(); }
-private:
- QSystemTrayIconQMenu();
-};
-
-@implementation QT_MANGLE_NAMESPACE(QNSMenu)
--(id)initWithQMenu:(QMenu*)qm {
- self = [super init];
- if(self) {
- self->qmenu = qm;
- [self setDelegate:self];
- }
- return self;
-}
--(QMenu*)menu {
- return qmenu;
-}
--(void)menuNeedsUpdate:(NSMenu*)nsmenu {
- QT_MANGLE_NAMESPACE(QNSMenu) *menu = static_cast<QT_MANGLE_NAMESPACE(QNSMenu) *>(nsmenu);
- emit static_cast<QSystemTrayIconQMenu*>(menu->qmenu)->doAboutToShow();
- for(int i = [menu numberOfItems]-1; i >= 0; --i)
- [menu removeItemAtIndex:i];
- QList<QAction*> actions = menu->qmenu->actions();;
- for(int i = 0; i < actions.size(); ++i) {
- const QAction *action = actions[i];
- if(!action->isVisible())
- continue;
-
- NSMenuItem *item = 0;
- bool needRelease = false;
- if(action->isSeparator()) {
- item = [NSMenuItem separatorItem];
- } else {
- item = [[NSMenuItem alloc] init];
- needRelease = true;
- QString text = action->text();
- QKeySequence accel = action->shortcut();
- {
- int st = text.lastIndexOf(QLatin1Char('\t'));
- if(st != -1) {
- accel = QKeySequence(text.right(text.length()-(st+1)));
- text.remove(st, text.length()-st);
- }
- }
- if(accel.count() > 1)
- text += QLatin1String(" (****)"); //just to denote a multi stroke shortcut
-
- [item setTitle:(NSString*)QCFString::toCFStringRef(qt_mac_removeMnemonics(text))];
- [item setEnabled:menu->qmenu->isEnabled() && action->isEnabled()];
- [item setState:action->isChecked() ? NSOnState : NSOffState];
- [item setToolTip:(NSString*)QCFString::toCFStringRef(action->toolTip())];
- const QIcon icon = action->icon();
- if(!icon.isNull()) {
-#ifndef QT_MAC_USE_COCOA
- const short scale = GetMBarHeight();
-#else
- const short scale = [[NSApp mainMenu] menuBarHeight];
-#endif
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(icon.pixmap(QSize(scale, scale))));
- [item setImage: nsimage];
- [nsimage release];
- }
- if(action->menu()) {
- QT_MANGLE_NAMESPACE(QNSMenu) *sub = [[QT_MANGLE_NAMESPACE(QNSMenu) alloc] initWithQMenu:action->menu()];
- [item setSubmenu:sub];
- } else {
- [item setAction:@selector(selectedAction:)];
- [item setTarget:self];
- }
- if(!accel.isEmpty()) {
- [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
- [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
- }
- }
- if(item)
- [menu addItem:item];
- if (needRelease)
- [item release];
- }
-}
--(void)selectedAction:(id)a {
- const int activated = [self indexOfItem:a];
- QAction *action = 0;
- QList<QAction*> actions = qmenu->actions();
- for(int i = 0, cnt = 0; i < actions.size(); ++i) {
- if(actions.at(i)->isVisible() && (cnt++) == activated) {
- action = actions.at(i);
- break;
- }
- }
- if(action) {
- action->activate(QAction::Trigger);
- }
-}
-@end
-
diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
deleted file mode 100644
index cc7bd47092..0000000000
--- a/src/gui/util/qsystemtrayicon_p.h
+++ /dev/null
@@ -1,186 +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 QSYSTEMTRAYICON_P_H
-#define QSYSTEMTRAYICON_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qsystemtrayicon.h"
-#include "private/qobject_p.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include "QtGui/qmenu.h"
-#include "QtGui/qpixmap.h"
-#include "QtCore/qstring.h"
-#include "QtCore/qpointer.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSystemTrayIconSys;
-class QToolButton;
-class QLabel;
-
-class QSystemTrayIconPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QSystemTrayIcon)
-
-public:
- QSystemTrayIconPrivate() : sys(0), visible(false) { }
-
- void install_sys();
- void remove_sys();
- void updateIcon_sys();
- void updateToolTip_sys();
- void updateMenu_sys();
- QRect geometry_sys() const;
- void showMessage_sys(const QString &msg, const QString &title, QSystemTrayIcon::MessageIcon icon, int secs);
-
- static bool isSystemTrayAvailable_sys();
- static bool supportsMessages_sys();
-
- QPointer<QMenu> menu;
- QIcon icon;
- QString toolTip;
- QSystemTrayIconSys *sys;
- bool visible;
-};
-
-class QBalloonTip : public QWidget
-{
- Q_OBJECT
-public:
- static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& msg, QSystemTrayIcon *trayIcon,
- const QPoint& pos, int timeout, bool showArrow = true);
- static void hideBalloon();
- static bool isBalloonVisible();
-
-private:
- QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& msg, QSystemTrayIcon *trayIcon);
- ~QBalloonTip();
- void balloon(const QPoint&, int, bool);
-
-protected:
- void paintEvent(QPaintEvent *);
- void resizeEvent(QResizeEvent *);
- void mousePressEvent(QMouseEvent *e);
- void timerEvent(QTimerEvent *e);
-
-private:
- QSystemTrayIcon *trayIcon;
- QPixmap pixmap;
- int timerId;
-};
-
-#if defined(Q_WS_X11)
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtCore/qcoreapplication.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-QT_END_INCLUDE_NAMESPACE
-
-class QSystemTrayIconSys : public QWidget
-{
- friend class QSystemTrayIconPrivate;
-
-public:
- QSystemTrayIconSys(QSystemTrayIcon *q);
- ~QSystemTrayIconSys();
- enum {
- SYSTEM_TRAY_REQUEST_DOCK = 0,
- SYSTEM_TRAY_BEGIN_MESSAGE = 1,
- SYSTEM_TRAY_CANCEL_MESSAGE =2
- };
-
- void addToTray();
- void updateIcon();
- XVisualInfo* getSysTrayVisualInfo();
-
- // QObject::event is public but QWidget's ::event() re-implementation
- // is protected ;(
- inline bool deliverToolTipEvent(QEvent *e)
- { return QWidget::event(e); }
-
- static Window sysTrayWindow;
- static QList<QSystemTrayIconSys *> trayIcons;
- static QCoreApplication::EventFilter oldEventFilter;
- static bool sysTrayTracker(void *message, long *result);
- static Window locateSystemTray();
- static Atom sysTraySelection;
- static XVisualInfo sysTrayVisual;
-
-protected:
- void paintEvent(QPaintEvent *pe);
- void resizeEvent(QResizeEvent *re);
- bool x11Event(XEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *event);
-#endif
- bool event(QEvent *e);
-
-private:
- QPixmap background;
- QSystemTrayIcon *q;
- Colormap colormap;
-};
-#endif // Q_WS_X11
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SYSTEMTRAYICON
-
-#endif // QSYSTEMTRAYICON_P_H
-
diff --git a/src/gui/util/qsystemtrayicon_qpa.cpp b/src/gui/util/qsystemtrayicon_qpa.cpp
deleted file mode 100644
index 48f8fe8922..0000000000
--- a/src/gui/util/qsystemtrayicon_qpa.cpp
+++ /dev/null
@@ -1,96 +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 "qsystemtrayicon_p.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-QT_BEGIN_NAMESPACE
-
-void QSystemTrayIconPrivate::install_sys()
-{
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- return QRect();
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return false;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return false;
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &message,
- const QString &title,
- QSystemTrayIcon::MessageIcon icon,
- int msecs)
-{
- Q_UNUSED(message);
- Q_UNUSED(title);
- Q_UNUSED(icon);
- Q_UNUSED(msecs);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp
deleted file mode 100644
index 5a0e179e6d..0000000000
--- a/src/gui/util/qsystemtrayicon_win.cpp
+++ /dev/null
@@ -1,524 +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 "qsystemtrayicon_p.h"
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#endif
-
-#ifndef _WIN32_IE
-#define _WIN32_IE 0x600
-#endif
-
-#include <qt_windows.h>
-#include <windowsx.h>
-#include <commctrl.h>
-
-#include <private/qsystemlibrary_p.h>
-#include <QApplication>
-#include <QSettings>
-
-QT_BEGIN_NAMESPACE
-
-static const UINT q_uNOTIFYICONID = 0;
-
-static uint MYWM_TASKBARCREATED = 0;
-#define MYWM_NOTIFYICON (WM_APP+101)
-
-struct Q_NOTIFYICONIDENTIFIER {
- DWORD cbSize;
- HWND hWnd;
- UINT uID;
- GUID guidItem;
-};
-
-#ifndef NOTIFYICON_VERSION_4
-#define NOTIFYICON_VERSION_4 4
-#endif
-
-#ifndef NIN_SELECT
-#define NIN_SELECT (WM_USER + 0)
-#endif
-
-#ifndef NIN_KEYSELECT
-#define NIN_KEYSELECT (WM_USER + 1)
-#endif
-
-#ifndef NIN_BALLOONTIMEOUT
-#define NIN_BALLOONTIMEOUT (WM_USER + 4)
-#endif
-
-#ifndef NIN_BALLOONUSERCLICK
-#define NIN_BALLOONUSERCLICK (WM_USER + 5)
-#endif
-
-#ifndef NIF_SHOWTIP
-#define NIF_SHOWTIP 0x00000080
-#endif
-
-#define Q_MSGFLT_ALLOW 1
-
-typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation);
-typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag);
-typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct);
-
-class QSystemTrayIconSys : QWidget
-{
-public:
- QSystemTrayIconSys(QSystemTrayIcon *object);
- ~QSystemTrayIconSys();
- bool winEvent( MSG *m, long *result );
- bool trayMessage(DWORD msg);
- void setIconContents(NOTIFYICONDATA &data);
- bool showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs);
- QRect findIconGeometry(const int a_iButtonID);
- void createIcon();
- HICON hIcon;
- QPoint globalPos;
- QSystemTrayIcon *q;
-private:
- uint notifyIconSize;
- int maxTipLength;
- int version;
- bool ignoreNextMouseRelease;
-};
-
-static bool allowsMessages()
-{
-#ifndef QT_NO_SETTINGS
- QSettings settings(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft"
- "\\Windows\\CurrentVersion\\Explorer\\Advanced"), QSettings::NativeFormat);
- return settings.value(QLatin1String("EnableBalloonTips"), true).toBool();
-#else
- return false;
-#endif
-}
-
-QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
- : hIcon(0), q(object), ignoreNextMouseRelease(false)
-
-{
- if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) {
- notifyIconSize = sizeof(NOTIFYICONDATA);
- version = NOTIFYICON_VERSION_4;
- } else {
- notifyIconSize = NOTIFYICONDATA_V2_SIZE;
- version = NOTIFYICON_VERSION;
- }
-
- maxTipLength = 128;
-
- // For restoring the tray icon after explorer crashes
- if (!MYWM_TASKBARCREATED) {
- MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
- }
-
- // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows Vista and higher
- static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx =
- (PtrChangeWindowMessageFilterEx)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx");
-
- if (pChangeWindowMessageFilterEx) {
- // Call the safer ChangeWindowMessageFilterEx API if available
- pChangeWindowMessageFilterEx(winId(), MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0);
- } else {
- static PtrChangeWindowMessageFilter pChangeWindowMessageFilter =
- (PtrChangeWindowMessageFilter)QSystemLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter");
-
- if (pChangeWindowMessageFilter) {
- // Call the deprecated ChangeWindowMessageFilter API otherwise
- pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW);
- }
- }
-}
-
-QSystemTrayIconSys::~QSystemTrayIconSys()
-{
- if (hIcon)
- DestroyIcon(hIcon);
-}
-
-void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd)
-{
- tnd.uFlags |= NIF_MESSAGE | NIF_ICON | NIF_TIP;
- tnd.uCallbackMessage = MYWM_NOTIFYICON;
- tnd.hIcon = hIcon;
- QString tip = q->toolTip();
-
- if (!tip.isNull()) {
- tip = tip.left(maxTipLength - 1) + QChar();
- memcpy(tnd.szTip, tip.utf16(), qMin(tip.length() + 1, maxTipLength) * sizeof(wchar_t));
- }
-}
-
-static int iconFlag( QSystemTrayIcon::MessageIcon icon )
-{
- switch (icon) {
- case QSystemTrayIcon::Information:
- return NIIF_INFO;
- case QSystemTrayIcon::Warning:
- return NIIF_WARNING;
- case QSystemTrayIcon::Critical:
- return NIIF_ERROR;
- case QSystemTrayIcon::NoIcon:
- return NIIF_NONE;
- default:
- Q_ASSERT_X(false, "QSystemTrayIconSys::showMessage", "Invalid QSystemTrayIcon::MessageIcon value");
- return NIIF_NONE;
- }
-}
-
-bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs)
-{
- NOTIFYICONDATA tnd;
- memset(&tnd, 0, notifyIconSize);
-
- memcpy(tnd.szInfo, message.utf16(), qMin(message.length() + 1, 256) * sizeof(wchar_t));
- memcpy(tnd.szInfoTitle, title.utf16(), qMin(title.length() + 1, 64) * sizeof(wchar_t));
-
- tnd.uID = q_uNOTIFYICONID;
- tnd.dwInfoFlags = iconFlag(type);
- tnd.cbSize = notifyIconSize;
- tnd.hWnd = winId();
- tnd.uTimeout = uSecs;
- tnd.uFlags = NIF_INFO | NIF_SHOWTIP;
-
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-
- return Shell_NotifyIcon(NIM_MODIFY, &tnd);
-}
-
-bool QSystemTrayIconSys::trayMessage(DWORD msg)
-{
- NOTIFYICONDATA tnd;
- memset(&tnd, 0, notifyIconSize);
-
- tnd.uID = q_uNOTIFYICONID;
- tnd.cbSize = notifyIconSize;
- tnd.hWnd = winId();
- tnd.uFlags = NIF_SHOWTIP;
- tnd.uVersion = version;
-
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-
- if (msg == NIM_ADD || msg == NIM_MODIFY) {
- setIconContents(tnd);
- }
-
- bool success = Shell_NotifyIcon(msg, &tnd);
-
- if (msg == NIM_ADD)
- return success && Shell_NotifyIcon(NIM_SETVERSION, &tnd);
- else
- return success;
-}
-
-void QSystemTrayIconSys::createIcon()
-{
- hIcon = 0;
- QIcon icon = q->icon();
- if (icon.isNull())
- return;
-
- const int iconSizeX = GetSystemMetrics(SM_CXSMICON);
- const int iconSizeY = GetSystemMetrics(SM_CYSMICON);
- QSize size = icon.actualSize(QSize(iconSizeX, iconSizeY));
- QPixmap pm = icon.pixmap(size);
- if (pm.isNull())
- return;
-
- hIcon = pm.toWinHICON();
-}
-
-bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
-{
- switch(m->message) {
- case MYWM_NOTIFYICON:
- {
- int message = 0;
- QPoint gpos;
-
- if (version == NOTIFYICON_VERSION_4) {
- Q_ASSERT(q_uNOTIFYICONID == HIWORD(m->lParam));
- message = LOWORD(m->lParam);
- gpos = QPoint(GET_X_LPARAM(m->wParam), GET_Y_LPARAM(m->wParam));
- } else {
- Q_ASSERT(q_uNOTIFYICONID == m->wParam);
- message = m->lParam;
- gpos = QCursor::pos();
- }
-
- switch (message) {
- case NIN_SELECT:
- case NIN_KEYSELECT:
- if (ignoreNextMouseRelease)
- ignoreNextMouseRelease = false;
- else
- emit q->activated(QSystemTrayIcon::Trigger);
- break;
-
- case WM_LBUTTONDBLCLK:
- ignoreNextMouseRelease = true; // Since DBLCLICK Generates a second mouse
- // release we must ignore it
- emit q->activated(QSystemTrayIcon::DoubleClick);
- break;
-
- case WM_CONTEXTMENU:
- if (q->contextMenu()) {
- q->contextMenu()->popup(gpos);
- q->contextMenu()->activateWindow();
- }
- emit q->activated(QSystemTrayIcon::Context);
- break;
-
- case NIN_BALLOONUSERCLICK:
- emit q->messageClicked();
- break;
-
- case WM_MBUTTONUP:
- emit q->activated(QSystemTrayIcon::MiddleClick);
- break;
-
- default:
- break;
- }
- break;
- }
- default:
- if (m->message == MYWM_TASKBARCREATED)
- trayMessage(NIM_ADD);
- else
- return QWidget::winEvent(m, result);
- break;
- }
- return 0;
-}
-
-void QSystemTrayIconPrivate::install_sys()
-{
- Q_Q(QSystemTrayIcon);
- if (!sys) {
- sys = new QSystemTrayIconSys(q);
- sys->createIcon();
- sys->trayMessage(NIM_ADD);
- }
-}
-
-/*
-* This function tries to determine the icon geometry from the tray
-*
-* If it fails an invalid rect is returned.
-*/
-QRect QSystemTrayIconSys::findIconGeometry(const int iconId)
-{
- static PtrShell_NotifyIconGetRect Shell_NotifyIconGetRect =
- (PtrShell_NotifyIconGetRect)QSystemLibrary::resolve(QLatin1String("shell32"), "Shell_NotifyIconGetRect");
-
- if (Shell_NotifyIconGetRect) {
- Q_NOTIFYICONIDENTIFIER nid;
- memset(&nid, 0, sizeof(nid));
- nid.cbSize = sizeof(nid);
- nid.hWnd = winId();
- nid.uID = iconId;
-
- RECT rect;
- HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect);
- if (SUCCEEDED(hr)) {
- return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
- }
- }
-
- QRect ret;
-
- TBBUTTON buttonData;
- DWORD processID = 0;
- HWND trayHandle = FindWindow(L"Shell_TrayWnd", NULL);
-
- //find the toolbar used in the notification area
- if (trayHandle) {
- trayHandle = FindWindowEx(trayHandle, NULL, L"TrayNotifyWnd", NULL);
- if (trayHandle) {
- HWND hwnd = FindWindowEx(trayHandle, NULL, L"SysPager", NULL);
- if (hwnd) {
- hwnd = FindWindowEx(hwnd, NULL, L"ToolbarWindow32", NULL);
- if (hwnd)
- trayHandle = hwnd;
- }
- }
- }
-
- if (!trayHandle)
- return ret;
-
- GetWindowThreadProcessId(trayHandle, &processID);
- if (processID <= 0)
- return ret;
-
- HANDLE trayProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, 0, processID);
- if (!trayProcess)
- return ret;
-
- int buttonCount = SendMessage(trayHandle, TB_BUTTONCOUNT, 0, 0);
- LPVOID data = VirtualAllocEx(trayProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
-
- if ( buttonCount < 1 || !data ) {
- CloseHandle(trayProcess);
- return ret;
- }
-
- //search for our icon among all toolbar buttons
- for (int toolbarButton = 0; toolbarButton < buttonCount; ++toolbarButton ) {
- SIZE_T numBytes = 0;
- DWORD appData[2] = { 0, 0 };
- SendMessage(trayHandle, TB_GETBUTTON, toolbarButton , (LPARAM)data);
-
- if (!ReadProcessMemory(trayProcess, data, &buttonData, sizeof(TBBUTTON), &numBytes))
- continue;
-
- if (!ReadProcessMemory(trayProcess, (LPVOID) buttonData.dwData, appData, sizeof(appData), &numBytes))
- continue;
-
- int currentIconId = appData[1];
- HWND currentIconHandle = (HWND) appData[0];
- bool isHidden = buttonData.fsState & TBSTATE_HIDDEN;
-
- if (currentIconHandle == winId() &&
- currentIconId == iconId && !isHidden) {
- SendMessage(trayHandle, TB_GETITEMRECT, toolbarButton , (LPARAM)data);
- RECT iconRect = {0, 0};
- if(ReadProcessMemory(trayProcess, data, &iconRect, sizeof(RECT), &numBytes)) {
- MapWindowPoints(trayHandle, NULL, (LPPOINT)&iconRect, 2);
- QRect geometry(iconRect.left + 1, iconRect.top + 1,
- iconRect.right - iconRect.left - 2,
- iconRect.bottom - iconRect.top - 2);
- if (geometry.isValid())
- ret = geometry;
- break;
- }
- }
- }
- VirtualFreeEx(trayProcess, data, 0, MEM_RELEASE);
- CloseHandle(trayProcess);
- return ret;
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, int timeOut)
-{
- if (!sys || !allowsMessages())
- return;
-
- uint uSecs = 0;
- if ( timeOut < 0)
- uSecs = 10000; //10 sec default
- else uSecs = (int)timeOut;
-
- //message is limited to 255 chars + NULL
- QString messageString;
- if (message.isEmpty() && !title.isEmpty())
- messageString = QLatin1Char(' '); //ensures that the message shows when only title is set
- else
- messageString = message.left(255) + QChar();
-
- //title is limited to 63 chars + NULL
- QString titleString = title.left(63) + QChar();
-
- sys->showMessage(titleString, messageString, type, uSecs);
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- if (!sys)
- return QRect();
-
- return sys->findIconGeometry(q_uNOTIFYICONID);
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
- if (!sys)
- return;
-
- sys->trayMessage(NIM_DELETE);
- delete sys;
- sys = 0;
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
- if (!sys)
- return;
-
- HICON hIconToDestroy = sys->hIcon;
-
- sys->createIcon();
- sys->trayMessage(NIM_MODIFY);
-
- if (hIconToDestroy)
- DestroyIcon(hIconToDestroy);
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
-
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
- if (!sys)
- return;
-
- sys->trayMessage(NIM_MODIFY);
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return true;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return allowsMessages();
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/util/qsystemtrayicon_wince.cpp b/src/gui/util/qsystemtrayicon_wince.cpp
deleted file mode 100644
index 85a34bbe25..0000000000
--- a/src/gui/util/qsystemtrayicon_wince.cpp
+++ /dev/null
@@ -1,293 +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 "qsystemtrayicon_p.h"
-#ifndef QT_NO_SYSTEMTRAYICON
-#define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE
-
-#include <qt_windows.h>
-#include <shlwapi.h>
-#include <QApplication>
-
-QT_BEGIN_NAMESPACE
-
-static const UINT q_uNOTIFYICONID = 13; // IDs from 0 to 12 are reserved on WinCE.
-#define MYWM_NOTIFYICON (WM_APP+101)
-
-struct Q_NOTIFYICONIDENTIFIER {
- DWORD cbSize;
- HWND hWnd;
- UINT uID;
- GUID guidItem;
-};
-
-class QSystemTrayIconSys : QWidget
-{
-public:
- QSystemTrayIconSys(QSystemTrayIcon *object);
- ~QSystemTrayIconSys();
- bool winEvent( MSG *m, long *result );
- bool trayMessage(DWORD msg);
- void setIconContents(NOTIFYICONDATA &data);
- void createIcon();
- QRect findTrayGeometry();
- HICON hIcon;
- QPoint globalPos;
- QSystemTrayIcon *q;
-private:
- uint notifyIconSize;
- int maxTipLength;
- bool ignoreNextMouseRelease;
-};
-
-QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
- : hIcon(0), q(object), ignoreNextMouseRelease(false)
-
-{
- notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, szTip[64]); // NOTIFYICONDATAW_V1_SIZE;
- maxTipLength = 64;
-}
-
-QSystemTrayIconSys::~QSystemTrayIconSys()
-{
- if (hIcon)
- DestroyIcon(hIcon);
-}
-
-QRect QSystemTrayIconSys::findTrayGeometry()
-{
- // Use lower right corner as fallback
- QPoint brCorner = qApp->desktop()->screenGeometry().bottomRight();
- QRect ret(brCorner.x() - 10, brCorner.y() - 10, 10, 10);
- return ret;
-}
-
-void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd)
-{
- tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
- tnd.uCallbackMessage = MYWM_NOTIFYICON;
- tnd.hIcon = hIcon;
- QString tip = q->toolTip();
-
- if (!tip.isNull()) {
- tip = tip.left(maxTipLength - 1) + QChar();
- memcpy(tnd.szTip, tip.utf16(), qMin(tip.length() + 1, maxTipLength) * sizeof(wchar_t));
- }
-}
-
-bool QSystemTrayIconSys::trayMessage(DWORD msg)
-{
- NOTIFYICONDATA tnd;
- memset(&tnd, 0, notifyIconSize);
- tnd.uID = q_uNOTIFYICONID;
- tnd.cbSize = notifyIconSize;
- tnd.hWnd = winId();
-
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-
- if (msg != NIM_DELETE) {
- setIconContents(tnd);
- }
-
- return Shell_NotifyIcon(msg, &tnd);
-}
-
-void QSystemTrayIconSys::createIcon()
-{
- hIcon = 0;
- QIcon icon = q->icon();
- if (icon.isNull())
- return;
-
- //const QSize preferredSize(GetSystemMetrics(SM_CXSMICON) * 2, GetSystemMetrics(SM_CYSMICON) * 2);
- const QSize preferredSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
- QPixmap pm = icon.pixmap(preferredSize);
- if (pm.isNull())
- return;
-
- hIcon = pm.toWinHICON();
-}
-
-bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
-{
- switch(m->message) {
- case WM_CREATE:
- SetWindowLong(winId(), GWL_USERDATA, (LONG)((CREATESTRUCTW*)m->lParam)->lpCreateParams);
- break;
-
- case MYWM_NOTIFYICON:
- {
- QPoint gpos = QCursor::pos();
-
- switch (m->lParam) {
- case WM_LBUTTONUP:
- if (ignoreNextMouseRelease)
- ignoreNextMouseRelease = false;
- else
- emit q->activated(QSystemTrayIcon::Trigger);
- break;
-
- case WM_LBUTTONDBLCLK:
- ignoreNextMouseRelease = true; // Since DBLCLICK Generates a second mouse
- // release we must ignore it
- emit q->activated(QSystemTrayIcon::DoubleClick);
- break;
-
- case WM_RBUTTONUP:
- if (q->contextMenu()) {
- q->contextMenu()->popup(gpos);
-
- // We must ensure that the popup menu doesn't show up behind the task bar.
- QRect desktopRect = qApp->desktop()->availableGeometry();
- int maxY = desktopRect.y() + desktopRect.height() - q->contextMenu()->height();
- if (gpos.y() > maxY) {
- gpos.ry() = maxY;
- q->contextMenu()->move(gpos);
- }
- }
- emit q->activated(QSystemTrayIcon::Context);
- break;
-
- case WM_MBUTTONUP:
- emit q->activated(QSystemTrayIcon::MiddleClick);
- break;
-
- default:
- break;
- }
- break;
- }
- default:
- return QWidget::winEvent(m, result);
- }
- return 0;
-}
-
-void QSystemTrayIconPrivate::install_sys()
-{
- Q_Q(QSystemTrayIcon);
- if (!sys) {
- sys = new QSystemTrayIconSys(q);
- sys->createIcon();
- sys->trayMessage(NIM_ADD);
- }
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, int timeOut)
-{
- if (!sys)
- return;
-
- uint uSecs = 0;
- if ( timeOut < 0)
- uSecs = 10000; //10 sec default
- else uSecs = (int)timeOut;
-
- //message is limited to 255 chars + NULL
- QString messageString;
- if (message.isEmpty() && !title.isEmpty())
- messageString = QLatin1Char(' '); //ensures that the message shows when only title is set
- else
- messageString = message.left(255) + QChar();
-
- //title is limited to 63 chars + NULL
- QString titleString = title.left(63) + QChar();
-
- //show QBalloonTip
- QRect trayRect = sys->findTrayGeometry();
- QBalloonTip::showBalloon(type, title, message, sys->q, QPoint(trayRect.left(),
- trayRect.center().y()), uSecs, false);
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- return QRect();
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
- if (!sys)
- return;
-
- sys->trayMessage(NIM_DELETE);
- delete sys;
- sys = 0;
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
- if (!sys)
- return;
-
- HICON hIconToDestroy = sys->hIcon;
-
- sys->createIcon();
- sys->trayMessage(NIM_MODIFY);
-
- if (hIconToDestroy)
- DestroyIcon(hIconToDestroy);
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
-
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
- // Calling sys->trayMessage(NIM_MODIFY) on an existing icon is broken on Windows CE.
- // So we need to call updateIcon_sys() which creates a new icon handle.
- updateIcon_sys();
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return true;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return true;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp
deleted file mode 100644
index 694746c834..0000000000
--- a/src/gui/util/qsystemtrayicon_x11.cpp
+++ /dev/null
@@ -1,401 +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 "private/qt_x11_p.h"
-#include "qlabel.h"
-#include "qx11info_x11.h"
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qbitmap.h"
-#include "qevent.h"
-#include "qapplication.h"
-#include "qlist.h"
-#include "qmenu.h"
-#include "qtimer.h"
-#include "qsystemtrayicon_p.h"
-#include "qpaintengine.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-QT_BEGIN_NAMESPACE
-
-Window QSystemTrayIconSys::sysTrayWindow = XNone;
-QList<QSystemTrayIconSys *> QSystemTrayIconSys::trayIcons;
-QCoreApplication::EventFilter QSystemTrayIconSys::oldEventFilter = 0;
-Atom QSystemTrayIconSys::sysTraySelection = XNone;
-XVisualInfo QSystemTrayIconSys::sysTrayVisual = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-// Locate the system tray
-Window QSystemTrayIconSys::locateSystemTray()
-{
- Display *display = QX11Info::display();
- if (sysTraySelection == XNone) {
- int screen = QX11Info::appScreen();
- QString net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen);
- sysTraySelection = XInternAtom(display, net_sys_tray.toLatin1(), False);
- }
-
- return XGetSelectionOwner(QX11Info::display(), sysTraySelection);
-}
-
-XVisualInfo* QSystemTrayIconSys::getSysTrayVisualInfo()
-{
- Display *display = QX11Info::display();
-
- if (!sysTrayVisual.visual) {
- Window win = locateSystemTray();
- if (win != XNone) {
- Atom actual_type;
- int actual_format;
- ulong nitems, bytes_remaining;
- uchar *data = 0;
- int result = XGetWindowProperty(display, win, ATOM(_NET_SYSTEM_TRAY_VISUAL), 0, 1,
- False, XA_VISUALID, &actual_type,
- &actual_format, &nitems, &bytes_remaining, &data);
- VisualID vid = 0;
- if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 &&
- nitems == 1 && bytes_remaining == 0)
- vid = *(VisualID*)data;
- if (data)
- XFree(data);
- if (vid == 0)
- return 0;
-
- uint mask = VisualIDMask;
- XVisualInfo *vi, rvi;
- int count;
- rvi.visualid = vid;
- vi = XGetVisualInfo(display, mask, &rvi, &count);
- if (vi) {
- sysTrayVisual = vi[0];
- XFree((char*)vi);
- }
- if (sysTrayVisual.depth != 32)
- memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
- }
- }
-
- return sysTrayVisual.visual ? &sysTrayVisual : 0;
-}
-
-bool QSystemTrayIconSys::sysTrayTracker(void *message, long *result)
-{
- bool retval = false;
- if (QSystemTrayIconSys::oldEventFilter)
- retval = QSystemTrayIconSys::oldEventFilter(message, result);
-
- if (trayIcons.isEmpty())
- return retval;
-
- Display *display = QX11Info::display();
- XEvent *ev = (XEvent *)message;
- if (ev->type == DestroyNotify && ev->xany.window == sysTrayWindow) {
- sysTrayWindow = locateSystemTray();
- memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
- for (int i = 0; i < trayIcons.count(); i++) {
- if (sysTrayWindow == XNone) {
- QBalloonTip::hideBalloon();
- trayIcons[i]->hide(); // still no luck
- trayIcons[i]->destroy();
- trayIcons[i]->create();
- } else
- trayIcons[i]->addToTray(); // add it to the new tray
- }
- retval = true;
- } else if (ev->type == ClientMessage && sysTrayWindow == XNone) {
- static Atom manager_atom = XInternAtom(display, "MANAGER", False);
- XClientMessageEvent *cm = (XClientMessageEvent *)message;
- if ((cm->message_type == manager_atom) && ((Atom)cm->data.l[1] == sysTraySelection)) {
- sysTrayWindow = cm->data.l[2];
- memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
- XSelectInput(display, sysTrayWindow, StructureNotifyMask);
- for (int i = 0; i < trayIcons.count(); i++) {
- trayIcons[i]->addToTray();
- }
- retval = true;
- }
- } else if (ev->type == PropertyNotify && ev->xproperty.atom == ATOM(_NET_SYSTEM_TRAY_VISUAL) &&
- ev->xproperty.window == sysTrayWindow) {
- memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
- for (int i = 0; i < trayIcons.count(); i++) {
- trayIcons[i]->addToTray();
- }
- }
-
- return retval;
-}
-
-QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *q)
- : QWidget(0, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint),
- q(q), colormap(0)
-{
- setAttribute(Qt::WA_AlwaysShowToolTips);
- setAttribute(Qt::WA_QuitOnClose, false);
- setAttribute(Qt::WA_NoSystemBackground, true);
- setAttribute(Qt::WA_PaintOnScreen);
-
- static bool eventFilterAdded = false;
- Display *display = QX11Info::display();
- if (!eventFilterAdded) {
- oldEventFilter = qApp->setEventFilter(sysTrayTracker);
- eventFilterAdded = true;
- Window root = QX11Info::appRootWindow();
- XWindowAttributes attr;
- XGetWindowAttributes(display, root, &attr);
- if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) {
- (void) QApplication::desktop(); // lame trick to ensure our event mask is not overridden
- XSelectInput(display, root, attr.your_event_mask | StructureNotifyMask); // for MANAGER selection
- }
- }
- if (trayIcons.isEmpty()) {
- sysTrayWindow = locateSystemTray();
- if (sysTrayWindow != XNone)
- XSelectInput(display, sysTrayWindow, StructureNotifyMask); // track tray events
- }
- trayIcons.append(this);
- setMouseTracking(true);
-#ifndef QT_NO_TOOLTIP
- setToolTip(q->toolTip());
-#endif
- if (sysTrayWindow != XNone)
- addToTray();
-}
-
-QSystemTrayIconSys::~QSystemTrayIconSys()
-{
- trayIcons.removeAt(trayIcons.indexOf(this));
- Display *display = QX11Info::display();
- if (trayIcons.isEmpty()) {
- if (sysTrayWindow == XNone)
- return;
- if (display)
- XSelectInput(display, sysTrayWindow, 0); // stop tracking the tray
- sysTrayWindow = XNone;
- }
- if (colormap)
- XFreeColormap(display, colormap);
-}
-
-void QSystemTrayIconSys::addToTray()
-{
- Q_ASSERT(sysTrayWindow != XNone);
- Display *display = QX11Info::display();
-
- XVisualInfo *vi = getSysTrayVisualInfo();
- if (vi && vi->visual) {
- Window root = RootWindow(display, vi->screen);
- Window p = root;
- if (QWidget *pw = parentWidget())
- p = pw->effectiveWinId();
- colormap = XCreateColormap(display, root, vi->visual, AllocNone);
- XSetWindowAttributes wsa;
- wsa.background_pixmap = 0;
- wsa.colormap = colormap;
- wsa.background_pixel = 0;
- wsa.border_pixel = 0;
- Window wid = XCreateWindow(display, p, -1, -1, 1, 1,
- 0, vi->depth, InputOutput, vi->visual,
- CWBackPixmap|CWBackPixel|CWBorderPixel|CWColormap, &wsa);
- create(wid);
- } else {
- XSetWindowBackgroundPixmap(display, winId(), ParentRelative);
- }
-
- // GNOME, NET WM Specification
- static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False);
- long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0 };
- XEvent ev;
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = sysTrayWindow;
- ev.xclient.message_type = netwm_tray_atom;
- ev.xclient.format = 32;
- memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
- XSendEvent(display, sysTrayWindow, False, 0, &ev);
- setMinimumSize(22, 22); // required at least on GNOME
-}
-
-void QSystemTrayIconSys::updateIcon()
-{
- update();
-}
-
-void QSystemTrayIconSys::resizeEvent(QResizeEvent *re)
-{
- QWidget::resizeEvent(re);
- updateIcon();
-}
-
-void QSystemTrayIconSys::paintEvent(QPaintEvent*)
-{
- QPainter p(this);
- if (!getSysTrayVisualInfo()) {
- const QRegion oldSystemClip = p.paintEngine()->systemClip();
- const QRect clearedRect = oldSystemClip.boundingRect();
- XClearArea(QX11Info::display(), winId(), clearedRect.x(), clearedRect.y(),
- clearedRect.width(), clearedRect.height(), False);
- QPaintEngine *pe = p.paintEngine();
- pe->setSystemClip(clearedRect);
- q->icon().paint(&p, rect());
- pe->setSystemClip(oldSystemClip);
- } else {
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(rect(), Qt::transparent);
- p.setCompositionMode(QPainter::CompositionMode_SourceOver);
- q->icon().paint(&p, rect());
- }
-}
-
-void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
-{
- QPoint globalPos = ev->globalPos();
- if (ev->button() == Qt::RightButton && q->contextMenu())
- q->contextMenu()->popup(globalPos);
-
- if (QBalloonTip::isBalloonVisible()) {
- emit q->messageClicked();
- QBalloonTip::hideBalloon();
- }
-
- if (ev->button() == Qt::LeftButton)
- emit q->activated(QSystemTrayIcon::Trigger);
- else if (ev->button() == Qt::RightButton)
- emit q->activated(QSystemTrayIcon::Context);
- else if (ev->button() == Qt::MidButton)
- emit q->activated(QSystemTrayIcon::MiddleClick);
-}
-
-void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)
-{
- if (ev->button() == Qt::LeftButton)
- emit q->activated(QSystemTrayIcon::DoubleClick);
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QSystemTrayIconSys::wheelEvent(QWheelEvent *e)
-{
- QApplication::sendEvent(q, e);
-}
-#endif
-
-bool QSystemTrayIconSys::event(QEvent *e)
-{
- if (e->type() == QEvent::ToolTip) {
- return QApplication::sendEvent(q, e);
- }
- return QWidget::event(e);
-}
-
-bool QSystemTrayIconSys::x11Event(XEvent *event)
-{
- if (event->type == ReparentNotify)
- show();
- return QWidget::x11Event(event);
-}
-
-////////////////////////////////////////////////////////////////////////////
-void QSystemTrayIconPrivate::install_sys()
-{
- Q_Q(QSystemTrayIcon);
- if (!sys)
- sys = new QSystemTrayIconSys(q);
-}
-
-QRect QSystemTrayIconPrivate::geometry_sys() const
-{
- if (!sys)
- return QRect();
- return QRect(sys->mapToGlobal(QPoint(0, 0)), sys->size());
-}
-
-void QSystemTrayIconPrivate::remove_sys()
-{
- if (!sys)
- return;
- QBalloonTip::hideBalloon();
- sys->hide(); // this should do the trick, but...
- delete sys; // wm may resize system tray only for DestroyEvents
- sys = 0;
-}
-
-void QSystemTrayIconPrivate::updateIcon_sys()
-{
- if (!sys)
- return;
- sys->updateIcon();
-}
-
-void QSystemTrayIconPrivate::updateMenu_sys()
-{
-
-}
-
-void QSystemTrayIconPrivate::updateToolTip_sys()
-{
- if (!sys)
- return;
-#ifndef QT_NO_TOOLTIP
- sys->setToolTip(toolTip);
-#endif
-}
-
-bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
-{
- return QSystemTrayIconSys::locateSystemTray() != XNone;
-}
-
-bool QSystemTrayIconPrivate::supportsMessages_sys()
-{
- return true;
-}
-
-void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QString &title,
- QSystemTrayIcon::MessageIcon icon, int msecs)
-{
- if (!sys)
- return;
- QPoint g = sys->mapToGlobal(QPoint(0, 0));
- QBalloonTip::showBalloon(icon, message, title, sys->q,
- QPoint(g.x() + sys->width()/2, g.y() + sys->height()/2),
- msecs);
-}
-
-QT_END_NAMESPACE
-#endif //QT_NO_SYSTEMTRAYICON
diff --git a/src/gui/util/qundogroup.cpp b/src/gui/util/qundogroup.cpp
deleted file mode 100644
index 42cda7462a..0000000000
--- a/src/gui/util/qundogroup.cpp
+++ /dev/null
@@ -1,499 +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 "qundogroup.h"
-#include "qundostack.h"
-#include "qundostack_p.h"
-
-#ifndef QT_NO_UNDOGROUP
-
-QT_BEGIN_NAMESPACE
-
-class QUndoGroupPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QUndoGroup)
-public:
- QUndoGroupPrivate() : active(0) {}
-
- QUndoStack *active;
- QList<QUndoStack*> stack_list;
-};
-
-/*!
- \class QUndoGroup
- \brief The QUndoGroup class is a group of QUndoStack objects.
- \since 4.2
-
- For an overview of the Qt's undo framework, see the
- \link qundo.html overview\endlink.
-
- An application often has multiple undo stacks, one for each opened document. At the
- same time, an application usually has one undo action and one redo action, which
- triggers undo or redo in the active document.
-
- QUndoGroup is a group of QUndoStack objects, one of which may be active. It has
- an undo() and redo() slot, which calls QUndoStack::undo() and QUndoStack::redo()
- for the active stack. It also has the functions createUndoAction() and createRedoAction().
- The actions returned by these functions behave in the same way as those returned by
- QUndoStack::createUndoAction() and QUndoStack::createRedoAction() of the active
- stack.
-
- Stacks are added to a group with addStack() and removed with removeStack(). A stack
- is implicitly added to a group when it is created with the group as its parent
- QObject.
-
- It is the programmer's responsibility to specify which stack is active by
- calling QUndoStack::setActive(), usually when the associated document window receives focus.
- The active stack may also be set with setActiveStack(), and is returned by activeStack().
-
- When a stack is added to a group using addStack(), the group does not take ownership
- of the stack. This means the stack has to be deleted separately from the group. When
- a stack is deleted, it is automatically removed from a group. A stack may belong to
- only one group. Adding it to another group will cause it to be removed from the previous
- group.
-
- A QUndoGroup is also useful in conjunction with QUndoView. If a QUndoView is
- set to watch a group using QUndoView::setGroup(), it will update itself to display
- the active stack.
-*/
-
-/*!
- Creates an empty QUndoGroup object with parent \a parent.
-
- \sa addStack()
-*/
-
-QUndoGroup::QUndoGroup(QObject *parent)
- : QObject(*new QUndoGroupPrivate(), parent)
-{
-}
-
-/*!
- Destroys the QUndoGroup.
-*/
-QUndoGroup::~QUndoGroup()
-{
- // Ensure all QUndoStacks no longer refer to this group.
- Q_D(QUndoGroup);
- QList<QUndoStack *>::iterator it = d->stack_list.begin();
- QList<QUndoStack *>::iterator end = d->stack_list.end();
- while (it != end) {
- (*it)->d_func()->group = 0;
- ++it;
- }
-}
-
-/*!
- Adds \a stack to this group. The group does not take ownership of the stack. Another
- way of adding a stack to a group is by specifying the group as the stack's parent
- QObject in QUndoStack::QUndoStack(). In this case, the stack is deleted when the
- group is deleted, in the usual manner of QObjects.
-
- \sa removeStack() stacks() QUndoStack::QUndoStack()
-*/
-
-void QUndoGroup::addStack(QUndoStack *stack)
-{
- Q_D(QUndoGroup);
-
- if (d->stack_list.contains(stack))
- return;
- d->stack_list.append(stack);
-
- if (QUndoGroup *other = stack->d_func()->group)
- other->removeStack(stack);
- stack->d_func()->group = this;
-}
-
-/*!
- Removes \a stack from this group. If the stack was the active stack in the group,
- the active stack becomes 0.
-
- \sa addStack() stacks() QUndoStack::~QUndoStack()
-*/
-
-void QUndoGroup::removeStack(QUndoStack *stack)
-{
- Q_D(QUndoGroup);
-
- if (d->stack_list.removeAll(stack) == 0)
- return;
- if (stack == d->active)
- setActiveStack(0);
- stack->d_func()->group = 0;
-}
-
-/*!
- Returns a list of stacks in this group.
-
- \sa addStack() removeStack()
-*/
-
-QList<QUndoStack*> QUndoGroup::stacks() const
-{
- Q_D(const QUndoGroup);
- return d->stack_list;
-}
-
-/*!
- Sets the active stack of this group to \a stack.
-
- If the stack is not a member of this group, this function does nothing.
-
- Synonymous with calling QUndoStack::setActive() on \a stack.
-
- The actions returned by createUndoAction() and createRedoAction() will now behave
- in the same way as those returned by \a stack's QUndoStack::createUndoAction()
- and QUndoStack::createRedoAction().
-
- \sa QUndoStack::setActive() activeStack()
-*/
-
-void QUndoGroup::setActiveStack(QUndoStack *stack)
-{
- Q_D(QUndoGroup);
- if (d->active == stack)
- return;
-
- if (d->active != 0) {
- disconnect(d->active, SIGNAL(canUndoChanged(bool)),
- this, SIGNAL(canUndoChanged(bool)));
- disconnect(d->active, SIGNAL(undoTextChanged(QString)),
- this, SIGNAL(undoTextChanged(QString)));
- disconnect(d->active, SIGNAL(canRedoChanged(bool)),
- this, SIGNAL(canRedoChanged(bool)));
- disconnect(d->active, SIGNAL(redoTextChanged(QString)),
- this, SIGNAL(redoTextChanged(QString)));
- disconnect(d->active, SIGNAL(indexChanged(int)),
- this, SIGNAL(indexChanged(int)));
- disconnect(d->active, SIGNAL(cleanChanged(bool)),
- this, SIGNAL(cleanChanged(bool)));
- }
-
- d->active = stack;
-
- if (d->active == 0) {
- emit canUndoChanged(false);
- emit undoTextChanged(QString());
- emit canRedoChanged(false);
- emit redoTextChanged(QString());
- emit cleanChanged(true);
- emit indexChanged(0);
- } else {
- connect(d->active, SIGNAL(canUndoChanged(bool)),
- this, SIGNAL(canUndoChanged(bool)));
- connect(d->active, SIGNAL(undoTextChanged(QString)),
- this, SIGNAL(undoTextChanged(QString)));
- connect(d->active, SIGNAL(canRedoChanged(bool)),
- this, SIGNAL(canRedoChanged(bool)));
- connect(d->active, SIGNAL(redoTextChanged(QString)),
- this, SIGNAL(redoTextChanged(QString)));
- connect(d->active, SIGNAL(indexChanged(int)),
- this, SIGNAL(indexChanged(int)));
- connect(d->active, SIGNAL(cleanChanged(bool)),
- this, SIGNAL(cleanChanged(bool)));
- emit canUndoChanged(d->active->canUndo());
- emit undoTextChanged(d->active->undoText());
- emit canRedoChanged(d->active->canRedo());
- emit redoTextChanged(d->active->redoText());
- emit cleanChanged(d->active->isClean());
- emit indexChanged(d->active->index());
- }
-
- emit activeStackChanged(d->active);
-}
-
-/*!
- Returns the active stack of this group.
-
- If none of the stacks are active, or if the group is empty, this function
- returns 0.
-
- \sa setActiveStack() QUndoStack::setActive()
-*/
-
-QUndoStack *QUndoGroup::activeStack() const
-{
- Q_D(const QUndoGroup);
- return d->active;
-}
-
-/*!
- Calls QUndoStack::undo() on the active stack.
-
- If none of the stacks are active, or if the group is empty, this function
- does nothing.
-
- \sa redo() canUndo() setActiveStack()
-*/
-
-void QUndoGroup::undo()
-{
- Q_D(QUndoGroup);
- if (d->active != 0)
- d->active->undo();
-}
-
-/*!
- Calls QUndoStack::redo() on the active stack.
-
- If none of the stacks are active, or if the group is empty, this function
- does nothing.
-
- \sa undo() canRedo() setActiveStack()
-*/
-
-
-void QUndoGroup::redo()
-{
- Q_D(QUndoGroup);
- if (d->active != 0)
- d->active->redo();
-}
-
-/*!
- Returns the value of the active stack's QUndoStack::canUndo().
-
- If none of the stacks are active, or if the group is empty, this function
- returns false.
-
- \sa canRedo() setActiveStack()
-*/
-
-bool QUndoGroup::canUndo() const
-{
- Q_D(const QUndoGroup);
- return d->active != 0 && d->active->canUndo();
-}
-
-/*!
- Returns the value of the active stack's QUndoStack::canRedo().
-
- If none of the stacks are active, or if the group is empty, this function
- returns false.
-
- \sa canUndo() setActiveStack()
-*/
-
-bool QUndoGroup::canRedo() const
-{
- Q_D(const QUndoGroup);
- return d->active != 0 && d->active->canRedo();
-}
-
-/*!
- Returns the value of the active stack's QUndoStack::undoText().
-
- If none of the stacks are active, or if the group is empty, this function
- returns an empty string.
-
- \sa redoText() setActiveStack()
-*/
-
-QString QUndoGroup::undoText() const
-{
- Q_D(const QUndoGroup);
- return d->active == 0 ? QString() : d->active->undoText();
-}
-
-/*!
- Returns the value of the active stack's QUndoStack::redoText().
-
- If none of the stacks are active, or if the group is empty, this function
- returns an empty string.
-
- \sa undoText() setActiveStack()
-*/
-
-QString QUndoGroup::redoText() const
-{
- Q_D(const QUndoGroup);
- return d->active == 0 ? QString() : d->active->redoText();
-}
-
-/*!
- Returns the value of the active stack's QUndoStack::isClean().
-
- If none of the stacks are active, or if the group is empty, this function
- returns true.
-
- \sa setActiveStack()
-*/
-
-bool QUndoGroup::isClean() const
-{
- Q_D(const QUndoGroup);
- return d->active == 0 || d->active->isClean();
-}
-
-#ifndef QT_NO_ACTION
-
-/*!
- Creates an undo QAction object with parent \a parent.
-
- Triggering this action will cause a call to QUndoStack::undo() on the active stack.
- The text of this action will always be the text of the command which will be undone
- in the next call to undo(), prefixed by \a prefix. If there is no command available
- for undo, if the group is empty or if none of the stacks are active, this action will
- be disabled.
-
- If \a prefix is empty, the default prefix "Undo" is used.
-
- \sa createRedoAction() canUndo() QUndoCommand::text()
-*/
-
-QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const
-{
- QString pref = prefix.isEmpty() ? tr("Undo") : prefix;
- QUndoAction *result = new QUndoAction(pref, parent);
- result->setEnabled(canUndo());
- result->setPrefixedText(undoText());
- connect(this, SIGNAL(canUndoChanged(bool)),
- result, SLOT(setEnabled(bool)));
- connect(this, SIGNAL(undoTextChanged(QString)),
- result, SLOT(setPrefixedText(QString)));
- connect(result, SIGNAL(triggered()), this, SLOT(undo()));
- return result;
-}
-
-/*!
- Creates an redo QAction object with parent \a parent.
-
- Triggering this action will cause a call to QUndoStack::redo() on the active stack.
- The text of this action will always be the text of the command which will be redone
- in the next call to redo(), prefixed by \a prefix. If there is no command available
- for redo, if the group is empty or if none of the stacks are active, this action will
- be disabled.
-
- If \a prefix is empty, the default prefix "Undo" is used.
-
- \sa createUndoAction() canRedo() QUndoCommand::text()
-*/
-
-QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const
-{
- QString pref = prefix.isEmpty() ? tr("Redo") : prefix;
- QUndoAction *result = new QUndoAction(pref, parent);
- result->setEnabled(canRedo());
- result->setPrefixedText(redoText());
- connect(this, SIGNAL(canRedoChanged(bool)),
- result, SLOT(setEnabled(bool)));
- connect(this, SIGNAL(redoTextChanged(QString)),
- result, SLOT(setPrefixedText(QString)));
- connect(result, SIGNAL(triggered()), this, SLOT(redo()));
- return result;
-}
-
-#endif // QT_NO_ACTION
-
-/*! \fn void QUndoGroup::activeStackChanged(QUndoStack *stack)
-
- This signal is emitted whenever the active stack of the group changes. This can happen
- when setActiveStack() or QUndoStack::setActive() is called, or when the active stack
- is removed form the group. \a stack is the new active stack. If no stack is active,
- \a stack is 0.
-
- \sa setActiveStack() QUndoStack::setActive()
-*/
-
-/*! \fn void QUndoGroup::indexChanged(int idx)
-
- This signal is emitted whenever the active stack emits QUndoStack::indexChanged()
- or the active stack changes.
-
- \a idx is the new current index, or 0 if the active stack is 0.
-
- \sa QUndoStack::indexChanged() setActiveStack()
-*/
-
-/*! \fn void QUndoGroup::cleanChanged(bool clean)
-
- This signal is emitted whenever the active stack emits QUndoStack::cleanChanged()
- or the active stack changes.
-
- \a clean is the new state, or true if the active stack is 0.
-
- \sa QUndoStack::cleanChanged() setActiveStack()
-*/
-
-/*! \fn void QUndoGroup::canUndoChanged(bool canUndo)
-
- This signal is emitted whenever the active stack emits QUndoStack::canUndoChanged()
- or the active stack changes.
-
- \a canUndo is the new state, or false if the active stack is 0.
-
- \sa QUndoStack::canUndoChanged() setActiveStack()
-*/
-
-/*! \fn void QUndoGroup::canRedoChanged(bool canRedo)
-
- This signal is emitted whenever the active stack emits QUndoStack::canRedoChanged()
- or the active stack changes.
-
- \a canRedo is the new state, or false if the active stack is 0.
-
- \sa QUndoStack::canRedoChanged() setActiveStack()
-*/
-
-/*! \fn void QUndoGroup::undoTextChanged(const QString &undoText)
-
- This signal is emitted whenever the active stack emits QUndoStack::undoTextChanged()
- or the active stack changes.
-
- \a undoText is the new state, or an empty string if the active stack is 0.
-
- \sa QUndoStack::undoTextChanged() setActiveStack()
-*/
-
-/*! \fn void QUndoGroup::redoTextChanged(const QString &redoText)
-
- This signal is emitted whenever the active stack emits QUndoStack::redoTextChanged()
- or the active stack changes.
-
- \a redoText is the new state, or an empty string if the active stack is 0.
-
- \sa QUndoStack::redoTextChanged() setActiveStack()
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_UNDOGROUP
diff --git a/src/gui/util/qundogroup.h b/src/gui/util/qundogroup.h
deleted file mode 100644
index 4ed79a9c81..0000000000
--- a/src/gui/util/qundogroup.h
+++ /dev/null
@@ -1,110 +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 QUNDOGROUP_H
-#define QUNDOGROUP_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QUndoGroupPrivate;
-class QUndoStack;
-class QAction;
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_UNDOGROUP
-
-class Q_GUI_EXPORT QUndoGroup : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoGroup)
-
-public:
- explicit QUndoGroup(QObject *parent = 0);
- ~QUndoGroup();
-
- void addStack(QUndoStack *stack);
- void removeStack(QUndoStack *stack);
- QList<QUndoStack*> stacks() const;
- QUndoStack *activeStack() const;
-
-#ifndef QT_NO_ACTION
- QAction *createUndoAction(QObject *parent,
- const QString &prefix = QString()) const;
- QAction *createRedoAction(QObject *parent,
- const QString &prefix = QString()) const;
-#endif // QT_NO_ACTION
- bool canUndo() const;
- bool canRedo() const;
- QString undoText() const;
- QString redoText() const;
- bool isClean() const;
-
-public Q_SLOTS:
- void undo();
- void redo();
- void setActiveStack(QUndoStack *stack);
-
-Q_SIGNALS:
- void activeStackChanged(QUndoStack *stack);
- void indexChanged(int idx);
- void cleanChanged(bool clean);
- void canUndoChanged(bool canUndo);
- void canRedoChanged(bool canRedo);
- void undoTextChanged(const QString &undoText);
- void redoTextChanged(const QString &redoText);
-
-private:
- Q_DISABLE_COPY(QUndoGroup)
-};
-
-#endif // QT_NO_UNDOGROUP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QUNDOGROUP_H
diff --git a/src/gui/util/qundostack.cpp b/src/gui/util/qundostack.cpp
deleted file mode 100644
index 6b038ee52e..0000000000
--- a/src/gui/util/qundostack.cpp
+++ /dev/null
@@ -1,1127 +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 <QtCore/qdebug.h>
-#include "qundostack.h"
-#include "qundogroup.h"
-#include "qundostack_p.h"
-
-#ifndef QT_NO_UNDOCOMMAND
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QUndoCommand
- \brief The QUndoCommand class is the base class of all commands stored on a QUndoStack.
- \since 4.2
-
- For an overview of Qt's Undo Framework, see the
- \l{Overview of Qt's Undo Framework}{overview document}.
-
- A QUndoCommand represents a single editing action on a document; for example,
- inserting or deleting a block of text in a text editor. QUndoCommand can apply
- a change to the document with redo() and undo the change with undo(). The
- implementations for these functions must be provided in a derived class.
-
- \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 0
-
- A QUndoCommand has an associated text(). This is a short string
- describing what the command does. It is used to update the text
- properties of the stack's undo and redo actions; see
- QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
-
- QUndoCommand objects are owned by the stack they were pushed on.
- QUndoStack deletes a command if it has been undone and a new command is pushed. For example:
-
-\snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 1
-
- In effect, when a command is pushed, it becomes the top-most command
- on the stack.
-
- To support command compression, QUndoCommand has an id() and the virtual function
- mergeWith(). These functions are used by QUndoStack::push().
-
- To support command macros, a QUndoCommand object can have any number of child
- commands. Undoing or redoing the parent command will cause the child
- commands to be undone or redone. A command can be assigned
- to a parent explicitly in the constructor. In this case, the command
- will be owned by the parent.
-
- The parent in this case is usually an empty command, in that it doesn't
- provide its own implementation of undo() and redo(). Instead, it uses
- the base implementations of these functions, which simply call undo() or
- redo() on all its children. The parent should, however, have a meaningful
- text().
-
- \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 2
-
- Another way to create macros is to use the convenience functions
- QUndoStack::beginMacro() and QUndoStack::endMacro().
-
- \sa QUndoStack
-*/
-
-/*!
- Constructs a QUndoCommand object with the given \a parent and \a text.
-
- If \a parent is not 0, this command is appended to parent's child list.
- The parent command then owns this command and will delete it in its
- destructor.
-
- \sa ~QUndoCommand()
-*/
-
-QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent)
-{
- d = new QUndoCommandPrivate;
- if (parent != 0)
- parent->d->child_list.append(this);
- d->text = text;
-}
-
-/*!
- Constructs a QUndoCommand object with parent \a parent.
-
- If \a parent is not 0, this command is appended to parent's child list.
- The parent command then owns this command and will delete it in its
- destructor.
-
- \sa ~QUndoCommand()
-*/
-
-QUndoCommand::QUndoCommand(QUndoCommand *parent)
-{
- d = new QUndoCommandPrivate;
- if (parent != 0)
- parent->d->child_list.append(this);
-}
-
-/*!
- Destroys the QUndoCommand object and all child commands.
-
- \sa QUndoCommand()
-*/
-
-QUndoCommand::~QUndoCommand()
-{
- qDeleteAll(d->child_list);
- delete d;
-}
-
-/*!
- Returns the ID of this command.
-
- A command ID is used in command compression. It must be an integer unique to
- this command's class, or -1 if the command doesn't support compression.
-
- If the command supports compression this function must be overridden in the
- derived class to return the correct ID. The base implementation returns -1.
-
- QUndoStack::push() will only try to merge two commands if they have the
- same ID, and the ID is not -1.
-
- \sa mergeWith(), QUndoStack::push()
-*/
-
-int QUndoCommand::id() const
-{
- return -1;
-}
-
-/*!
- Attempts to merge this command with \a command. Returns true on
- success; otherwise returns false.
-
- If this function returns true, calling this command's redo() must have the same
- effect as redoing both this command and \a command.
- Similarly, calling this command's undo() must have the same effect as undoing
- \a command and this command.
-
- QUndoStack will only try to merge two commands if they have the same id, and
- the id is not -1.
-
- The default implementation returns false.
-
- \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 3
-
- \sa id() QUndoStack::push()
-*/
-
-bool QUndoCommand::mergeWith(const QUndoCommand *command)
-{
- Q_UNUSED(command);
- return false;
-}
-
-/*!
- Applies a change to the document. This function must be implemented in
- the derived class. Calling QUndoStack::push(),
- QUndoStack::undo() or QUndoStack::redo() from this function leads to
- undefined beahavior.
-
- The default implementation calls redo() on all child commands.
-
- \sa undo()
-*/
-
-void QUndoCommand::redo()
-{
- for (int i = 0; i < d->child_list.size(); ++i)
- d->child_list.at(i)->redo();
-}
-
-/*!
- Reverts a change to the document. After undo() is called, the state of
- the document should be the same as before redo() was called. This function must
- be implemented in the derived class. Calling QUndoStack::push(),
- QUndoStack::undo() or QUndoStack::redo() from this function leads to
- undefined beahavior.
-
- The default implementation calls undo() on all child commands in reverse order.
-
- \sa redo()
-*/
-
-void QUndoCommand::undo()
-{
- for (int i = d->child_list.size() - 1; i >= 0; --i)
- d->child_list.at(i)->undo();
-}
-
-/*!
- Returns a short text string describing what this command does; for example,
- "insert text".
-
- The text is used when the text properties of the stack's undo and redo
- actions are updated.
-
- \sa setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
-*/
-
-QString QUndoCommand::text() const
-{
- return d->text;
-}
-
-/*!
- Sets the command's text to be the \a text specified.
-
- The specified text should be a short user-readable string describing what this
- command does.
-
- \sa text() QUndoStack::createUndoAction() QUndoStack::createRedoAction()
-*/
-
-void QUndoCommand::setText(const QString &text)
-{
- d->text = text;
-}
-
-/*!
- \since 4.4
-
- Returns the number of child commands in this command.
-
- \sa child()
-*/
-
-int QUndoCommand::childCount() const
-{
- return d->child_list.count();
-}
-
-/*!
- \since 4.4
-
- Returns the child command at \a index.
-
- \sa childCount(), QUndoStack::command()
-*/
-
-const QUndoCommand *QUndoCommand::child(int index) const
-{
- if (index < 0 || index >= d->child_list.count())
- return 0;
- return d->child_list.at(index);
-}
-
-#endif // QT_NO_UNDOCOMMAND
-
-#ifndef QT_NO_UNDOSTACK
-
-/*!
- \class QUndoStack
- \brief The QUndoStack class is a stack of QUndoCommand objects.
- \since 4.2
-
- For an overview of Qt's Undo Framework, see the
- \l{Overview of Qt's Undo Framework}{overview document}.
-
- An undo stack maintains a stack of commands that have been applied to a
- document.
-
- New commands are pushed on the stack using push(). Commands can be
- undone and redone using undo() and redo(), or by triggering the
- actions returned by createUndoAction() and createRedoAction().
-
- QUndoStack keeps track of the \a current command. This is the command
- which will be executed by the next call to redo(). The index of this
- command is returned by index(). The state of the edited object can be
- rolled forward or back using setIndex(). If the top-most command on the
- stack has already been redone, index() is equal to count().
-
- QUndoStack provides support for undo and redo actions, command
- compression, command macros, and supports the concept of a
- \e{clean state}.
-
- \section1 Undo and Redo Actions
-
- QUndoStack provides convenient undo and redo QAction objects, which
- can be inserted into a menu or a toolbar. When commands are undone or
- redone, QUndoStack updates the text properties of these actions
- to reflect what change they will trigger. The actions are also disabled
- when no command is available for undo or redo. These actions
- are returned by QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
-
- \section1 Command Compression and Macros
-
- Command compression is useful when several commands can be compressed
- into a single command that can be undone and redone in a single operation.
- For example, when a user types a character in a text editor, a new command
- is created. This command inserts the character into the document at the
- cursor position. However, it is more convenient for the user to be able
- to undo or redo typing of whole words, sentences, or paragraphs.
- Command compression allows these single-character commands to be merged
- into a single command which inserts or deletes sections of text.
- For more information, see QUndoCommand::mergeWith() and push().
-
- A command macro is a sequence of commands, all of which are undone and
- redone in one go. Command macros are created by giving a command a list
- of child commands.
- Undoing or redoing the parent command will cause the child commands to
- be undone or redone. Command macros may be created explicitly
- by specifying a parent in the QUndoCommand constructor, or by using the
- convenience functions beginMacro() and endMacro().
-
- Although command compression and macros appear to have the same effect to the
- user, they often have different uses in an application. Commands that
- perform small changes to a document may be usefully compressed if there is
- no need to individually record them, and if only larger changes are relevant
- to the user.
- However, for commands that need to be recorded individually, or those that
- cannot be compressed, it is useful to use macros to provide a more convenient
- user experience while maintaining a record of each command.
-
- \section1 Clean State
-
- QUndoStack supports the concept of a clean state. When the
- document is saved to disk, the stack can be marked as clean using
- setClean(). Whenever the stack returns to this state through undoing and
- redoing commands, it emits the signal cleanChanged(). This signal
- is also emitted when the stack leaves the clean state. This signal is
- usually used to enable and disable the save actions in the application,
- and to update the document's title to reflect that it contains unsaved
- changes.
-
- \sa QUndoCommand, QUndoView
-*/
-
-#ifndef QT_NO_ACTION
-
-QUndoAction::QUndoAction(const QString &prefix, QObject *parent)
- : QAction(parent)
-{
- m_prefix = prefix;
-}
-
-void QUndoAction::setPrefixedText(const QString &text)
-{
- QString s = m_prefix;
- if (!m_prefix.isEmpty() && !text.isEmpty())
- s.append(QLatin1Char(' '));
- s.append(text);
- setText(s);
-}
-
-#endif // QT_NO_ACTION
-
-/*! \internal
- Sets the current index to \a idx, emitting appropriate signals. If \a clean is true,
- makes \a idx the clean index as well.
-*/
-
-void QUndoStackPrivate::setIndex(int idx, bool clean)
-{
- Q_Q(QUndoStack);
-
- bool was_clean = index == clean_index;
-
- if (idx != index) {
- index = idx;
- emit q->indexChanged(index);
- emit q->canUndoChanged(q->canUndo());
- emit q->undoTextChanged(q->undoText());
- emit q->canRedoChanged(q->canRedo());
- emit q->redoTextChanged(q->redoText());
- }
-
- if (clean)
- clean_index = index;
-
- bool is_clean = index == clean_index;
- if (is_clean != was_clean)
- emit q->cleanChanged(is_clean);
-}
-
-/*! \internal
- If the number of commands on the stack exceedes the undo limit, deletes commands from
- the bottom of the stack.
-
- Returns true if commands were deleted.
-*/
-
-bool QUndoStackPrivate::checkUndoLimit()
-{
- if (undo_limit <= 0 || !macro_stack.isEmpty() || undo_limit >= command_list.count())
- return false;
-
- int del_count = command_list.count() - undo_limit;
-
- for (int i = 0; i < del_count; ++i)
- delete command_list.takeFirst();
-
- index -= del_count;
- if (clean_index != -1) {
- if (clean_index < del_count)
- clean_index = -1; // we've deleted the clean command
- else
- clean_index -= del_count;
- }
-
- return true;
-}
-
-/*!
- Constructs an empty undo stack with the parent \a parent. The
- stack will initially be in the clean state. If \a parent is a
- QUndoGroup object, the stack is automatically added to the group.
-
- \sa push()
-*/
-
-QUndoStack::QUndoStack(QObject *parent)
- : QObject(*(new QUndoStackPrivate), parent)
-{
-#ifndef QT_NO_UNDOGROUP
- if (QUndoGroup *group = qobject_cast<QUndoGroup*>(parent))
- group->addStack(this);
-#endif
-}
-
-/*!
- Destroys the undo stack, deleting any commands that are on it. If the
- stack is in a QUndoGroup, the stack is automatically removed from the group.
-
- \sa QUndoStack()
-*/
-
-QUndoStack::~QUndoStack()
-{
-#ifndef QT_NO_UNDOGROUP
- Q_D(QUndoStack);
- if (d->group != 0)
- d->group->removeStack(this);
-#endif
- clear();
-}
-
-/*!
- Clears the command stack by deleting all commands on it, and returns the stack
- to the clean state.
-
- Commands are not undone or redone; the state of the edited object remains
- unchanged.
-
- This function is usually used when the contents of the document are
- abandoned.
-
- \sa QUndoStack()
-*/
-
-void QUndoStack::clear()
-{
- Q_D(QUndoStack);
-
- if (d->command_list.isEmpty())
- return;
-
- bool was_clean = isClean();
-
- d->macro_stack.clear();
- qDeleteAll(d->command_list);
- d->command_list.clear();
-
- d->index = 0;
- d->clean_index = 0;
-
- emit indexChanged(0);
- emit canUndoChanged(false);
- emit undoTextChanged(QString());
- emit canRedoChanged(false);
- emit redoTextChanged(QString());
-
- if (!was_clean)
- emit cleanChanged(true);
-}
-
-/*!
- Pushes \a cmd on the stack or merges it with the most recently executed command.
- In either case, executes \a cmd by calling its redo() function.
-
- If \a cmd's id is not -1, and if the id is the same as that of the
- most recently executed command, QUndoStack will attempt to merge the two
- commands by calling QUndoCommand::mergeWith() on the most recently executed
- command. If QUndoCommand::mergeWith() returns true, \a cmd is deleted.
-
- In all other cases \a cmd is simply pushed on the stack.
-
- If commands were undone before \a cmd was pushed, the current command and
- all commands above it are deleted. Hence \a cmd always ends up being the
- top-most on the stack.
-
- Once a command is pushed, the stack takes ownership of it. There
- are no getters to return the command, since modifying it after it has
- been executed will almost always lead to corruption of the document's
- state.
-
- \sa QUndoCommand::id() QUndoCommand::mergeWith()
-*/
-
-void QUndoStack::push(QUndoCommand *cmd)
-{
- Q_D(QUndoStack);
- cmd->redo();
-
- bool macro = !d->macro_stack.isEmpty();
-
- QUndoCommand *cur = 0;
- if (macro) {
- QUndoCommand *macro_cmd = d->macro_stack.last();
- if (!macro_cmd->d->child_list.isEmpty())
- cur = macro_cmd->d->child_list.last();
- } else {
- if (d->index > 0)
- cur = d->command_list.at(d->index - 1);
- while (d->index < d->command_list.size())
- delete d->command_list.takeLast();
- if (d->clean_index > d->index)
- d->clean_index = -1; // we've deleted the clean state
- }
-
- bool try_merge = cur != 0
- && cur->id() != -1
- && cur->id() == cmd->id()
- && (macro || d->index != d->clean_index);
-
- if (try_merge && cur->mergeWith(cmd)) {
- delete cmd;
- if (!macro) {
- emit indexChanged(d->index);
- emit canUndoChanged(canUndo());
- emit undoTextChanged(undoText());
- emit canRedoChanged(canRedo());
- emit redoTextChanged(redoText());
- }
- } else {
- if (macro) {
- d->macro_stack.last()->d->child_list.append(cmd);
- } else {
- d->command_list.append(cmd);
- d->checkUndoLimit();
- d->setIndex(d->index + 1, false);
- }
- }
-}
-
-/*!
- Marks the stack as clean and emits cleanChanged() if the stack was
- not already clean.
-
- Whenever the stack returns to this state through the use of undo/redo
- commands, it emits the signal cleanChanged(). This signal is also
- emitted when the stack leaves the clean state.
-
- \sa isClean(), cleanIndex()
-*/
-
-void QUndoStack::setClean()
-{
- Q_D(QUndoStack);
- if (!d->macro_stack.isEmpty()) {
- qWarning("QUndoStack::setClean(): cannot set clean in the middle of a macro");
- return;
- }
-
- d->setIndex(d->index, true);
-}
-
-/*!
- If the stack is in the clean state, returns true; otherwise returns false.
-
- \sa setClean() cleanIndex()
-*/
-
-bool QUndoStack::isClean() const
-{
- Q_D(const QUndoStack);
- if (!d->macro_stack.isEmpty())
- return false;
- return d->clean_index == d->index;
-}
-
-/*!
- Returns the clean index. This is the index at which setClean() was called.
-
- A stack may not have a clean index. This happens if a document is saved,
- some commands are undone, then a new command is pushed. Since
- push() deletes all the undone commands before pushing the new command, the stack
- can't return to the clean state again. In this case, this function returns -1.
-
- \sa isClean() setClean()
-*/
-
-int QUndoStack::cleanIndex() const
-{
- Q_D(const QUndoStack);
- return d->clean_index;
-}
-
-/*!
- Undoes the command below the current command by calling QUndoCommand::undo().
- Decrements the current command index.
-
- If the stack is empty, or if the bottom command on the stack has already been
- undone, this function does nothing.
-
- \sa redo() index()
-*/
-
-void QUndoStack::undo()
-{
- Q_D(QUndoStack);
- if (d->index == 0)
- return;
-
- if (!d->macro_stack.isEmpty()) {
- qWarning("QUndoStack::undo(): cannot undo in the middle of a macro");
- return;
- }
-
- int idx = d->index - 1;
- d->command_list.at(idx)->undo();
- d->setIndex(idx, false);
-}
-
-/*!
- Redoes the current command by calling QUndoCommand::redo(). Increments the current
- command index.
-
- If the stack is empty, or if the top command on the stack has already been
- redone, this function does nothing.
-
- \sa undo() index()
-*/
-
-void QUndoStack::redo()
-{
- Q_D(QUndoStack);
- if (d->index == d->command_list.size())
- return;
-
- if (!d->macro_stack.isEmpty()) {
- qWarning("QUndoStack::redo(): cannot redo in the middle of a macro");
- return;
- }
-
- d->command_list.at(d->index)->redo();
- d->setIndex(d->index + 1, false);
-}
-
-/*!
- Returns the number of commands on the stack. Macro commands are counted as
- one command.
-
- \sa index() setIndex() command()
-*/
-
-int QUndoStack::count() const
-{
- Q_D(const QUndoStack);
- return d->command_list.size();
-}
-
-/*!
- Returns the index of the current command. This is the command that will be
- executed on the next call to redo(). It is not always the top-most command
- on the stack, since a number of commands may have been undone.
-
- \sa undo() redo() count()
-*/
-
-int QUndoStack::index() const
-{
- Q_D(const QUndoStack);
- return d->index;
-}
-
-/*!
- Repeatedly calls undo() or redo() until the current command index reaches
- \a idx. This function can be used to roll the state of the document forwards
- of backwards. indexChanged() is emitted only once.
-
- \sa index() count() undo() redo()
-*/
-
-void QUndoStack::setIndex(int idx)
-{
- Q_D(QUndoStack);
- if (!d->macro_stack.isEmpty()) {
- qWarning("QUndoStack::setIndex(): cannot set index in the middle of a macro");
- return;
- }
-
- if (idx < 0)
- idx = 0;
- else if (idx > d->command_list.size())
- idx = d->command_list.size();
-
- int i = d->index;
- while (i < idx)
- d->command_list.at(i++)->redo();
- while (i > idx)
- d->command_list.at(--i)->undo();
-
- d->setIndex(idx, false);
-}
-
-/*!
- Returns true if there is a command available for undo; otherwise returns false.
-
- This function returns false if the stack is empty, or if the bottom command
- on the stack has already been undone.
-
- Synonymous with index() == 0.
-
- \sa index() canRedo()
-*/
-
-bool QUndoStack::canUndo() const
-{
- Q_D(const QUndoStack);
- if (!d->macro_stack.isEmpty())
- return false;
- return d->index > 0;
-}
-
-/*!
- Returns true if there is a command available for redo; otherwise returns false.
-
- This function returns false if the stack is empty or if the top command
- on the stack has already been redone.
-
- Synonymous with index() == count().
-
- \sa index() canUndo()
-*/
-
-bool QUndoStack::canRedo() const
-{
- Q_D(const QUndoStack);
- if (!d->macro_stack.isEmpty())
- return false;
- return d->index < d->command_list.size();
-}
-
-/*!
- Returns the text of the command which will be undone in the next call to undo().
-
- \sa QUndoCommand::text() redoText()
-*/
-
-QString QUndoStack::undoText() const
-{
- Q_D(const QUndoStack);
- if (!d->macro_stack.isEmpty())
- return QString();
- if (d->index > 0)
- return d->command_list.at(d->index - 1)->text();
- return QString();
-}
-
-/*!
- Returns the text of the command which will be redone in the next call to redo().
-
- \sa QUndoCommand::text() undoText()
-*/
-
-QString QUndoStack::redoText() const
-{
- Q_D(const QUndoStack);
- if (!d->macro_stack.isEmpty())
- return QString();
- if (d->index < d->command_list.size())
- return d->command_list.at(d->index)->text();
- return QString();
-}
-
-#ifndef QT_NO_ACTION
-
-/*!
- Creates an undo QAction object with the given \a parent.
-
- Triggering this action will cause a call to undo(). The text of this action
- is the text of the command which will be undone in the next call to undo(),
- prefixed by the specified \a prefix. If there is no command available for undo,
- this action will be disabled.
-
- If \a prefix is empty, the default prefix "Undo" is used.
-
- \sa createRedoAction(), canUndo(), QUndoCommand::text()
-*/
-
-QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const
-{
- QString pref = prefix.isEmpty() ? tr("Undo") : prefix;
- QUndoAction *result = new QUndoAction(pref, parent);
- result->setEnabled(canUndo());
- result->setPrefixedText(undoText());
- connect(this, SIGNAL(canUndoChanged(bool)),
- result, SLOT(setEnabled(bool)));
- connect(this, SIGNAL(undoTextChanged(QString)),
- result, SLOT(setPrefixedText(QString)));
- connect(result, SIGNAL(triggered()), this, SLOT(undo()));
- return result;
-}
-
-/*!
- Creates an redo QAction object with the given \a parent.
-
- Triggering this action will cause a call to redo(). The text of this action
- is the text of the command which will be redone in the next call to redo(),
- prefixed by the specified \a prefix. If there is no command available for redo,
- this action will be disabled.
-
- If \a prefix is empty, the default prefix "Redo" is used.
-
- \sa createUndoAction(), canRedo(), QUndoCommand::text()
-*/
-
-QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const
-{
- QString pref = prefix.isEmpty() ? tr("Redo") : prefix;
- QUndoAction *result = new QUndoAction(pref, parent);
- result->setEnabled(canRedo());
- result->setPrefixedText(redoText());
- connect(this, SIGNAL(canRedoChanged(bool)),
- result, SLOT(setEnabled(bool)));
- connect(this, SIGNAL(redoTextChanged(QString)),
- result, SLOT(setPrefixedText(QString)));
- connect(result, SIGNAL(triggered()), this, SLOT(redo()));
- return result;
-}
-
-#endif // QT_NO_ACTION
-
-/*!
- Begins composition of a macro command with the given \a text description.
-
- An empty command described by the specified \a text is pushed on the stack.
- Any subsequent commands pushed on the stack will be appended to the empty
- command's children until endMacro() is called.
-
- Calls to beginMacro() and endMacro() may be nested, but every call to
- beginMacro() must have a matching call to endMacro().
-
- While a macro is composed, the stack is disabled. This means that:
- \list
- \i indexChanged() and cleanChanged() are not emitted,
- \i canUndo() and canRedo() return false,
- \i calling undo() or redo() has no effect,
- \i the undo/redo actions are disabled.
- \endlist
-
- The stack becomes enabled and appropriate signals are emitted when endMacro()
- is called for the outermost macro.
-
- \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 4
-
- This code is equivalent to:
-
- \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 5
-
- \sa endMacro()
-*/
-
-void QUndoStack::beginMacro(const QString &text)
-{
- Q_D(QUndoStack);
- QUndoCommand *cmd = new QUndoCommand();
- cmd->setText(text);
-
- if (d->macro_stack.isEmpty()) {
- while (d->index < d->command_list.size())
- delete d->command_list.takeLast();
- if (d->clean_index > d->index)
- d->clean_index = -1; // we've deleted the clean state
- d->command_list.append(cmd);
- } else {
- d->macro_stack.last()->d->child_list.append(cmd);
- }
- d->macro_stack.append(cmd);
-
- if (d->macro_stack.count() == 1) {
- emit canUndoChanged(false);
- emit undoTextChanged(QString());
- emit canRedoChanged(false);
- emit redoTextChanged(QString());
- }
-}
-
-/*!
- Ends composition of a macro command.
-
- If this is the outermost macro in a set nested macros, this function emits
- indexChanged() once for the entire macro command.
-
- \sa beginMacro()
-*/
-
-void QUndoStack::endMacro()
-{
- Q_D(QUndoStack);
- if (d->macro_stack.isEmpty()) {
- qWarning("QUndoStack::endMacro(): no matching beginMacro()");
- return;
- }
-
- d->macro_stack.removeLast();
-
- if (d->macro_stack.isEmpty()) {
- d->checkUndoLimit();
- d->setIndex(d->index + 1, false);
- }
-}
-
-/*!
- \since 4.4
-
- Returns a const pointer to the command at \a index.
-
- This function returns a const pointer, because modifying a command,
- once it has been pushed onto the stack and executed, almost always
- causes corruption of the state of the document, if the command is
- later undone or redone.
-
- \sa QUndoCommand::child()
-*/
-const QUndoCommand *QUndoStack::command(int index) const
-{
- Q_D(const QUndoStack);
-
- if (index < 0 || index >= d->command_list.count())
- return 0;
- return d->command_list.at(index);
-}
-
-/*!
- Returns the text of the command at index \a idx.
-
- \sa beginMacro()
-*/
-
-QString QUndoStack::text(int idx) const
-{
- Q_D(const QUndoStack);
-
- if (idx < 0 || idx >= d->command_list.size())
- return QString();
- return d->command_list.at(idx)->text();
-}
-
-/*!
- \property QUndoStack::undoLimit
- \brief the maximum number of commands on this stack.
- \since 4.3
-
- When the number of commands on a stack exceedes the stack's undoLimit, commands are
- deleted from the bottom of the stack. Macro commands (commands with child commands)
- are treated as one command. The default value is 0, which means that there is no
- limit.
-
- This property may only be set when the undo stack is empty, since setting it on a
- non-empty stack might delete the command at the current index. Calling setUndoLimit()
- on a non-empty stack prints a warning and does nothing.
-*/
-
-void QUndoStack::setUndoLimit(int limit)
-{
- Q_D(QUndoStack);
-
- if (!d->command_list.isEmpty()) {
- qWarning("QUndoStack::setUndoLimit(): an undo limit can only be set when the stack is empty");
- return;
- }
-
- if (limit == d->undo_limit)
- return;
- d->undo_limit = limit;
- d->checkUndoLimit();
-}
-
-int QUndoStack::undoLimit() const
-{
- Q_D(const QUndoStack);
-
- return d->undo_limit;
-}
-
-/*!
- \property QUndoStack::active
- \brief the active status of this stack.
-
- An application often has multiple undo stacks, one for each opened document. The active
- stack is the one associated with the currently active document. If the stack belongs
- to a QUndoGroup, calls to QUndoGroup::undo() or QUndoGroup::redo() will be forwarded
- to this stack when it is active. If the QUndoGroup is watched by a QUndoView, the view
- will display the contents of this stack when it is active. If the stack does not belong to
- a QUndoGroup, making it active has no effect.
-
- It is the programmer's responsibility to specify which stack is active by
- calling setActive(), usually when the associated document window receives focus.
-
- \sa QUndoGroup
-*/
-
-void QUndoStack::setActive(bool active)
-{
-#ifdef QT_NO_UNDOGROUP
- Q_UNUSED(active);
-#else
- Q_D(QUndoStack);
-
- if (d->group != 0) {
- if (active)
- d->group->setActiveStack(this);
- else if (d->group->activeStack() == this)
- d->group->setActiveStack(0);
- }
-#endif
-}
-
-bool QUndoStack::isActive() const
-{
-#ifdef QT_NO_UNDOGROUP
- return true;
-#else
- Q_D(const QUndoStack);
- return d->group == 0 || d->group->activeStack() == this;
-#endif
-}
-
-/*!
- \fn void QUndoStack::indexChanged(int idx)
-
- This signal is emitted whenever a command modifies the state of the document.
- This happens when a command is undone or redone. When a macro
- command is undone or redone, or setIndex() is called, this signal
- is emitted only once.
-
- \a idx specifies the index of the current command, ie. the command which will be
- executed on the next call to redo().
-
- \sa index() setIndex()
-*/
-
-/*!
- \fn void QUndoStack::cleanChanged(bool clean)
-
- This signal is emitted whenever the stack enters or leaves the clean state.
- If \a clean is true, the stack is in a clean state; otherwise this signal
- indicates that it has left the clean state.
-
- \sa isClean() setClean()
-*/
-
-/*!
- \fn void QUndoStack::undoTextChanged(const QString &undoText)
-
- This signal is emitted whenever the value of undoText() changes. It is
- used to update the text property of the undo action returned by createUndoAction().
- \a undoText specifies the new text.
-*/
-
-/*!
- \fn void QUndoStack::canUndoChanged(bool canUndo)
-
- This signal is emitted whenever the value of canUndo() changes. It is
- used to enable or disable the undo action returned by createUndoAction().
- \a canUndo specifies the new value.
-*/
-
-/*!
- \fn void QUndoStack::redoTextChanged(const QString &redoText)
-
- This signal is emitted whenever the value of redoText() changes. It is
- used to update the text property of the redo action returned by createRedoAction().
- \a redoText specifies the new text.
-*/
-
-/*!
- \fn void QUndoStack::canRedoChanged(bool canRedo)
-
- This signal is emitted whenever the value of canRedo() changes. It is
- used to enable or disable the redo action returned by createRedoAction().
- \a canRedo specifies the new value.
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_UNDOSTACK
diff --git a/src/gui/util/qundostack.h b/src/gui/util/qundostack.h
deleted file mode 100644
index 65941b53c3..0000000000
--- a/src/gui/util/qundostack.h
+++ /dev/null
@@ -1,158 +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 QUNDOSTACK_H
-#define QUNDOSTACK_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAction;
-class QUndoCommandPrivate;
-class QUndoStackPrivate;
-
-#ifndef QT_NO_UNDOCOMMAND
-
-class Q_GUI_EXPORT QUndoCommand
-{
- QUndoCommandPrivate *d;
-
-public:
- explicit QUndoCommand(QUndoCommand *parent = 0);
- explicit QUndoCommand(const QString &text, QUndoCommand *parent = 0);
- virtual ~QUndoCommand();
-
- virtual void undo();
- virtual void redo();
-
- QString text() const;
- void setText(const QString &text);
-
- virtual int id() const;
- virtual bool mergeWith(const QUndoCommand *other);
-
- int childCount() const;
- const QUndoCommand *child(int index) const;
-
-private:
- Q_DISABLE_COPY(QUndoCommand)
- friend class QUndoStack;
-};
-
-#endif // QT_NO_UNDOCOMMAND
-
-#ifndef QT_NO_UNDOSTACK
-
-class Q_GUI_EXPORT QUndoStack : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoStack)
- Q_PROPERTY(bool active READ isActive WRITE setActive)
- Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
-
-public:
- explicit QUndoStack(QObject *parent = 0);
- ~QUndoStack();
- void clear();
-
- void push(QUndoCommand *cmd);
-
- bool canUndo() const;
- bool canRedo() const;
- QString undoText() const;
- QString redoText() const;
-
- int count() const;
- int index() const;
- QString text(int idx) const;
-
-#ifndef QT_NO_ACTION
- QAction *createUndoAction(QObject *parent,
- const QString &prefix = QString()) const;
- QAction *createRedoAction(QObject *parent,
- const QString &prefix = QString()) const;
-#endif // QT_NO_ACTION
-
- bool isActive() const;
- bool isClean() const;
- int cleanIndex() const;
-
- void beginMacro(const QString &text);
- void endMacro();
-
- void setUndoLimit(int limit);
- int undoLimit() const;
-
- const QUndoCommand *command(int index) const;
-
-public Q_SLOTS:
- void setClean();
- void setIndex(int idx);
- void undo();
- void redo();
- void setActive(bool active = true);
-
-Q_SIGNALS:
- void indexChanged(int idx);
- void cleanChanged(bool clean);
- void canUndoChanged(bool canUndo);
- void canRedoChanged(bool canRedo);
- void undoTextChanged(const QString &undoText);
- void redoTextChanged(const QString &redoText);
-
-private:
- Q_DISABLE_COPY(QUndoStack)
- friend class QUndoGroup;
-};
-
-#endif // QT_NO_UNDOSTACK
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QUNDOSTACK_H
diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h
deleted file mode 100644
index 3c7d0e7d85..0000000000
--- a/src/gui/util/qundostack_p.h
+++ /dev/null
@@ -1,111 +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 QUNDOSTACK_P_H
-#define QUNDOSTACK_P_H
-
-#include <private/qobject_p.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qaction.h>
-
-#include "qundostack.h"
-
-QT_BEGIN_NAMESPACE
-class QUndoCommand;
-class QUndoGroup;
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-class QUndoCommandPrivate
-{
-public:
- QUndoCommandPrivate() : id(-1) {}
- QList<QUndoCommand*> child_list;
- QString text;
- int id;
-};
-
-#ifndef QT_NO_UNDOSTACK
-
-class QUndoStackPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QUndoStack)
-public:
- QUndoStackPrivate() : index(0), clean_index(0), group(0), undo_limit(0) {}
-
- QList<QUndoCommand*> command_list;
- QList<QUndoCommand*> macro_stack;
- int index;
- int clean_index;
- QUndoGroup *group;
- int undo_limit;
-
- void setIndex(int idx, bool clean);
- bool checkUndoLimit();
-};
-
-#ifndef QT_NO_ACTION
-class QUndoAction : public QAction
-{
- Q_OBJECT
-public:
- QUndoAction(const QString &prefix, QObject *parent = 0);
-public Q_SLOTS:
- void setPrefixedText(const QString &text);
-private:
- QString m_prefix;
-};
-#endif // QT_NO_ACTION
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_UNDOSTACK
-#endif // QUNDOSTACK_P_H
diff --git a/src/gui/util/qundoview.cpp b/src/gui/util/qundoview.cpp
deleted file mode 100644
index 43c1774b25..0000000000
--- a/src/gui/util/qundoview.cpp
+++ /dev/null
@@ -1,476 +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 "qundostack.h"
-#include "qundoview.h"
-
-#ifndef QT_NO_UNDOVIEW
-
-#include "qundogroup.h"
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qpointer.h>
-#include <QtGui/qicon.h>
-#include <private/qlistview_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QUndoModel : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- QUndoModel(QObject *parent = 0);
-
- QUndoStack *stack() const;
-
- virtual QModelIndex index(int row, int column,
- const QModelIndex &parent = QModelIndex()) const;
- virtual QModelIndex parent(const QModelIndex &child) const;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
- virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
- QModelIndex selectedIndex() const;
- QItemSelectionModel *selectionModel() const;
-
- QString emptyLabel() const;
- void setEmptyLabel(const QString &label);
-
- void setCleanIcon(const QIcon &icon);
- QIcon cleanIcon() const;
-
-public slots:
- void setStack(QUndoStack *stack);
-
-private slots:
- void stackChanged();
- void stackDestroyed(QObject *obj);
- void setStackCurrentIndex(const QModelIndex &index);
-
-private:
- QUndoStack *m_stack;
- QItemSelectionModel *m_sel_model;
- QString m_emty_label;
- QIcon m_clean_icon;
-};
-
-QUndoModel::QUndoModel(QObject *parent)
- : QAbstractItemModel(parent)
-{
- m_stack = 0;
- m_sel_model = new QItemSelectionModel(this, this);
- connect(m_sel_model, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(setStackCurrentIndex(QModelIndex)));
- m_emty_label = tr("<empty>");
-}
-
-QItemSelectionModel *QUndoModel::selectionModel() const
-{
- return m_sel_model;
-}
-
-QUndoStack *QUndoModel::stack() const
-{
- return m_stack;
-}
-
-void QUndoModel::setStack(QUndoStack *stack)
-{
- if (m_stack == stack)
- return;
-
- if (m_stack != 0) {
- disconnect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
- disconnect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
- disconnect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
- }
- m_stack = stack;
- if (m_stack != 0) {
- connect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
- connect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
- connect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
- }
-
- stackChanged();
-}
-
-void QUndoModel::stackDestroyed(QObject *obj)
-{
- if (obj != m_stack)
- return;
- m_stack = 0;
-
- stackChanged();
-}
-
-void QUndoModel::stackChanged()
-{
- reset();
- m_sel_model->setCurrentIndex(selectedIndex(), QItemSelectionModel::ClearAndSelect);
-}
-
-void QUndoModel::setStackCurrentIndex(const QModelIndex &index)
-{
- if (m_stack == 0)
- return;
-
- if (index == selectedIndex())
- return;
-
- if (index.column() != 0)
- return;
-
- m_stack->setIndex(index.row());
-}
-
-QModelIndex QUndoModel::selectedIndex() const
-{
- return m_stack == 0 ? QModelIndex() : createIndex(m_stack->index(), 0);
-}
-
-QModelIndex QUndoModel::index(int row, int column, const QModelIndex &parent) const
-{
- if (m_stack == 0)
- return QModelIndex();
-
- if (parent.isValid())
- return QModelIndex();
-
- if (column != 0)
- return QModelIndex();
-
- if (row < 0 || row > m_stack->count())
- return QModelIndex();
-
- return createIndex(row, column);
-}
-
-QModelIndex QUndoModel::parent(const QModelIndex&) const
-{
- return QModelIndex();
-}
-
-int QUndoModel::rowCount(const QModelIndex &parent) const
-{
- if (m_stack == 0)
- return 0;
-
- if (parent.isValid())
- return 0;
-
- return m_stack->count() + 1;
-}
-
-int QUndoModel::columnCount(const QModelIndex&) const
-{
- return 1;
-}
-
-QVariant QUndoModel::data(const QModelIndex &index, int role) const
-{
- if (m_stack == 0)
- return QVariant();
-
- if (index.column() != 0)
- return QVariant();
-
- if (index.row() < 0 || index.row() > m_stack->count())
- return QVariant();
-
- if (role == Qt::DisplayRole) {
- if (index.row() == 0)
- return m_emty_label;
- return m_stack->text(index.row() - 1);
- } else if (role == Qt::DecorationRole) {
- if (index.row() == m_stack->cleanIndex() && !m_clean_icon.isNull())
- return m_clean_icon;
- return QVariant();
- }
-
- return QVariant();
-}
-
-QString QUndoModel::emptyLabel() const
-{
- return m_emty_label;
-}
-
-void QUndoModel::setEmptyLabel(const QString &label)
-{
- m_emty_label = label;
- stackChanged();
-}
-
-void QUndoModel::setCleanIcon(const QIcon &icon)
-{
- m_clean_icon = icon;
- stackChanged();
-}
-
-QIcon QUndoModel::cleanIcon() const
-{
- return m_clean_icon;
-}
-
-/*!
- \class QUndoView
- \brief The QUndoView class displays the contents of a QUndoStack.
- \since 4.2
-
- \ingroup advanced
-
- QUndoView is a QListView which displays the list of commands pushed on an undo stack.
- The most recently executed command is always selected. Selecting a different command
- results in a call to QUndoStack::setIndex(), rolling the state of the document
- backwards or forward to the new command.
-
- The stack can be set explicitly with setStack(). Alternatively, a QUndoGroup object can
- be set with setGroup(). The view will then update itself automatically whenever the
- active stack of the group changes.
-
- \image qundoview.png
-*/
-
-class QUndoViewPrivate : public QListViewPrivate
-{
- Q_DECLARE_PUBLIC(QUndoView)
-public:
- QUndoViewPrivate() :
-#ifndef QT_NO_UNDOGROUP
- group(0),
-#endif
- model(0) {}
-
-#ifndef QT_NO_UNDOGROUP
- QPointer<QUndoGroup> group;
-#endif
- QUndoModel *model;
-
- void init();
-};
-
-void QUndoViewPrivate::init()
-{
- Q_Q(QUndoView);
-
- model = new QUndoModel(q);
- q->setModel(model);
- q->setSelectionModel(model->selectionModel());
-}
-
-/*!
- Constructs a new view with parent \a parent.
-*/
-
-QUndoView::QUndoView(QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
-}
-
-/*!
- Constructs a new view with parent \a parent and sets the observed stack to \a stack.
-*/
-
-QUndoView::QUndoView(QUndoStack *stack, QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
- setStack(stack);
-}
-
-#ifndef QT_NO_UNDOGROUP
-
-/*!
- Constructs a new view with parent \a parent and sets the observed group to \a group.
-
- The view will update itself autmiatically whenever the active stack of the group changes.
-*/
-
-QUndoView::QUndoView(QUndoGroup *group, QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
- setGroup(group);
-}
-
-#endif // QT_NO_UNDOGROUP
-
-/*!
- Destroys this view.
-*/
-
-QUndoView::~QUndoView()
-{
-}
-
-/*!
- Returns the stack currently displayed by this view. If the view is looking at a
- QUndoGroup, this the group's active stack.
-
- \sa setStack() setGroup()
-*/
-
-QUndoStack *QUndoView::stack() const
-{
- Q_D(const QUndoView);
- return d->model->stack();
-}
-
-/*!
- Sets the stack displayed by this view to \a stack. If \a stack is 0, the view
- will be empty.
-
- If the view was previously looking at a QUndoGroup, the group is set to 0.
-
- \sa stack() setGroup()
-*/
-
-void QUndoView::setStack(QUndoStack *stack)
-{
- Q_D(QUndoView);
-#ifndef QT_NO_UNDOGROUP
- setGroup(0);
-#endif
- d->model->setStack(stack);
-}
-
-#ifndef QT_NO_UNDOGROUP
-
-/*!
- Sets the group displayed by this view to \a group. If \a group is 0, the view will
- be empty.
-
- The view will update itself autmiatically whenever the active stack of the group changes.
-
- \sa group() setStack()
-*/
-
-void QUndoView::setGroup(QUndoGroup *group)
-{
- Q_D(QUndoView);
-
- if (d->group == group)
- return;
-
- if (d->group != 0) {
- disconnect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
- d->model, SLOT(setStack(QUndoStack*)));
- }
-
- d->group = group;
-
- if (d->group != 0) {
- connect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
- d->model, SLOT(setStack(QUndoStack*)));
- d->model->setStack(d->group->activeStack());
- } else {
- d->model->setStack(0);
- }
-}
-
-/*!
- Returns the group displayed by this view.
-
- If the view is not looking at group, this function returns 0.
-
- \sa setGroup() setStack()
-*/
-
-QUndoGroup *QUndoView::group() const
-{
- Q_D(const QUndoView);
- return d->group;
-}
-
-#endif // QT_NO_UNDOGROUP
-
-/*!
- \property QUndoView::emptyLabel
- \brief the label used for the empty state.
-
- The empty label is the topmost element in the list of commands, which represents
- the state of the document before any commands were pushed on the stack. The default
- is the string "<empty>".
-*/
-
-void QUndoView::setEmptyLabel(const QString &label)
-{
- Q_D(QUndoView);
- d->model->setEmptyLabel(label);
-}
-
-QString QUndoView::emptyLabel() const
-{
- Q_D(const QUndoView);
- return d->model->emptyLabel();
-}
-
-/*!
- \property QUndoView::cleanIcon
- \brief the icon used to represent the clean state.
-
- A stack may have a clean state set with QUndoStack::setClean(). This is usually
- the state of the document at the point it was saved. QUndoView can display an
- icon in the list of commands to show the clean state. If this property is
- a null icon, no icon is shown. The default value is the null icon.
-*/
-
-void QUndoView::setCleanIcon(const QIcon &icon)
-{
- Q_D(const QUndoView);
- d->model->setCleanIcon(icon);
-
-}
-
-QIcon QUndoView::cleanIcon() const
-{
- Q_D(const QUndoView);
- return d->model->cleanIcon();
-}
-
-QT_END_NAMESPACE
-
-#include "qundoview.moc"
-
-#endif // QT_NO_UNDOVIEW
diff --git a/src/gui/util/qundoview.h b/src/gui/util/qundoview.h
deleted file mode 100644
index de32a39c54..0000000000
--- a/src/gui/util/qundoview.h
+++ /dev/null
@@ -1,102 +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 QUNDOVIEW_H
-#define QUNDOVIEW_H
-
-#include <QtGui/qlistview.h>
-#include <QtCore/qstring.h>
-
-#ifndef QT_NO_UNDOVIEW
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QUndoViewPrivate;
-class QUndoStack;
-class QUndoGroup;
-class QIcon;
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QUndoView : public QListView
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoView)
- Q_PROPERTY(QString emptyLabel READ emptyLabel WRITE setEmptyLabel)
- Q_PROPERTY(QIcon cleanIcon READ cleanIcon WRITE setCleanIcon)
-
-public:
- explicit QUndoView(QWidget *parent = 0);
- explicit QUndoView(QUndoStack *stack, QWidget *parent = 0);
-#ifndef QT_NO_UNDOGROUP
- explicit QUndoView(QUndoGroup *group, QWidget *parent = 0);
-#endif
- ~QUndoView();
-
- QUndoStack *stack() const;
-#ifndef QT_NO_UNDOGROUP
- QUndoGroup *group() const;
-#endif
-
- void setEmptyLabel(const QString &label);
- QString emptyLabel() const;
-
- void setCleanIcon(const QIcon &icon);
- QIcon cleanIcon() const;
-
-public Q_SLOTS:
- void setStack(QUndoStack *stack);
-#ifndef QT_NO_UNDOGROUP
- void setGroup(QUndoGroup *group);
-#endif
-
-private:
- Q_DISABLE_COPY(QUndoView)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_UNDOVIEW
-#endif // QUNDOVIEW_H
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
deleted file mode 100644
index 854964b784..0000000000
--- a/src/gui/util/util.pri
+++ /dev/null
@@ -1,69 +0,0 @@
-# Qt util module
-
-HEADERS += \
- util/qsystemtrayicon.h \
- util/qcompleter.h \
- util/qcompleter_p.h \
- util/qsystemtrayicon_p.h \
- util/qscroller.h \
- util/qscroller_p.h \
- util/qscrollerproperties.h \
- util/qscrollerproperties_p.h \
- util/qflickgesture_p.h \
- util/qundogroup.h \
- util/qundostack.h \
- util/qundostack_p.h \
- util/qundoview.h
-
-SOURCES += \
- util/qsystemtrayicon.cpp \
- util/qcompleter.cpp \
- util/qscroller.cpp \
- util/qscrollerproperties.cpp \
- util/qflickgesture.cpp \
- util/qundogroup.cpp \
- util/qundostack.cpp \
- util/qundoview.cpp
-
-
-wince* {
- SOURCES += \
- util/qsystemtrayicon_wince.cpp
-} else:win32 {
- SOURCES += \
- util/qsystemtrayicon_win.cpp
-}
-
-unix:x11 {
- SOURCES += \
- util/qsystemtrayicon_x11.cpp
-}
-
-qpa {
- SOURCES += \
- util/qsystemtrayicon_qpa.cpp
-}
-
-!qpa:!x11:mac {
- OBJECTIVE_SOURCES += util/qsystemtrayicon_mac.mm
-}
-
-symbian {
- LIBS += -letext -lplatformenv
- contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
- LIBS += -lsendas2 -lapmime
- contains(QT_CONFIG, s60) {
- contains(CONFIG, is_using_gnupoc) {
- LIBS += -lcommonui
- } else {
- LIBS += -lCommonUI
- }
- }
- } else {
- DEFINES += USE_SCHEMEHANDLER
- }
-}
-
-macx {
- OBJECTIVE_SOURCES += util/qscroller_mac.mm
-}