source: trunk/src/gui/util/qundoview.cpp@ 878

Last change on this file since 878 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 11.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qundostack.h"
43#include "qundoview.h"
44
45#ifndef QT_NO_UNDOVIEW
46
47#include "qundogroup.h"
48#include <QtCore/qabstractitemmodel.h>
49#include <QtCore/qpointer.h>
50#include <QtGui/qicon.h>
51#include <private/qlistview_p.h>
52
53QT_BEGIN_NAMESPACE
54
55class QUndoModel : public QAbstractItemModel
56{
57 Q_OBJECT
58public:
59 QUndoModel(QObject *parent = 0);
60
61 QUndoStack *stack() const;
62
63 virtual QModelIndex index(int row, int column,
64 const QModelIndex &parent = QModelIndex()) const;
65 virtual QModelIndex parent(const QModelIndex &child) const;
66 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
67 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
68 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
69
70 QModelIndex selectedIndex() const;
71 QItemSelectionModel *selectionModel() const;
72
73 QString emptyLabel() const;
74 void setEmptyLabel(const QString &label);
75
76 void setCleanIcon(const QIcon &icon);
77 QIcon cleanIcon() const;
78
79public slots:
80 void setStack(QUndoStack *stack);
81
82private slots:
83 void stackChanged();
84 void stackDestroyed(QObject *obj);
85 void setStackCurrentIndex(const QModelIndex &index);
86
87private:
88 QUndoStack *m_stack;
89 QItemSelectionModel *m_sel_model;
90 QString m_emty_label;
91 QIcon m_clean_icon;
92};
93
94QUndoModel::QUndoModel(QObject *parent)
95 : QAbstractItemModel(parent)
96{
97 m_stack = 0;
98 m_sel_model = new QItemSelectionModel(this, this);
99 connect(m_sel_model, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
100 this, SLOT(setStackCurrentIndex(QModelIndex)));
101 m_emty_label = tr("<empty>");
102}
103
104QItemSelectionModel *QUndoModel::selectionModel() const
105{
106 return m_sel_model;
107}
108
109QUndoStack *QUndoModel::stack() const
110{
111 return m_stack;
112}
113
114void QUndoModel::setStack(QUndoStack *stack)
115{
116 if (m_stack == stack)
117 return;
118
119 if (m_stack != 0) {
120 disconnect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
121 disconnect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
122 disconnect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
123 }
124 m_stack = stack;
125 if (m_stack != 0) {
126 connect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
127 connect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
128 connect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
129 }
130
131 stackChanged();
132}
133
134void QUndoModel::stackDestroyed(QObject *obj)
135{
136 if (obj != m_stack)
137 return;
138 m_stack = 0;
139
140 stackChanged();
141}
142
143void QUndoModel::stackChanged()
144{
145 reset();
146 m_sel_model->setCurrentIndex(selectedIndex(), QItemSelectionModel::ClearAndSelect);
147}
148
149void QUndoModel::setStackCurrentIndex(const QModelIndex &index)
150{
151 if (m_stack == 0)
152 return;
153
154 if (index == selectedIndex())
155 return;
156
157 if (index.column() != 0)
158 return;
159
160 m_stack->setIndex(index.row());
161}
162
163QModelIndex QUndoModel::selectedIndex() const
164{
165 return m_stack == 0 ? QModelIndex() : createIndex(m_stack->index(), 0);
166}
167
168QModelIndex QUndoModel::index(int row, int column, const QModelIndex &parent) const
169{
170 if (m_stack == 0)
171 return QModelIndex();
172
173 if (parent.isValid())
174 return QModelIndex();
175
176 if (column != 0)
177 return QModelIndex();
178
179 if (row < 0 || row > m_stack->count())
180 return QModelIndex();
181
182 return createIndex(row, column);
183}
184
185QModelIndex QUndoModel::parent(const QModelIndex&) const
186{
187 return QModelIndex();
188}
189
190int QUndoModel::rowCount(const QModelIndex &parent) const
191{
192 if (m_stack == 0)
193 return 0;
194
195 if (parent.isValid())
196 return 0;
197
198 return m_stack->count() + 1;
199}
200
201int QUndoModel::columnCount(const QModelIndex&) const
202{
203 return 1;
204}
205
206QVariant QUndoModel::data(const QModelIndex &index, int role) const
207{
208 if (m_stack == 0)
209 return QVariant();
210
211 if (index.column() != 0)
212 return QVariant();
213
214 if (index.row() < 0 || index.row() > m_stack->count())
215 return QVariant();
216
217 if (role == Qt::DisplayRole) {
218 if (index.row() == 0)
219 return m_emty_label;
220 return m_stack->text(index.row() - 1);
221 } else if (role == Qt::DecorationRole) {
222 if (index.row() == m_stack->cleanIndex() && !m_clean_icon.isNull())
223 return m_clean_icon;
224 return QVariant();
225 }
226
227 return QVariant();
228}
229
230QString QUndoModel::emptyLabel() const
231{
232 return m_emty_label;
233}
234
235void QUndoModel::setEmptyLabel(const QString &label)
236{
237 m_emty_label = label;
238 stackChanged();
239}
240
241void QUndoModel::setCleanIcon(const QIcon &icon)
242{
243 m_clean_icon = icon;
244 stackChanged();
245}
246
247QIcon QUndoModel::cleanIcon() const
248{
249 return m_clean_icon;
250}
251
252/*!
253 \class QUndoView
254 \brief The QUndoView class displays the contents of a QUndoStack.
255 \since 4.2
256
257 \ingroup advanced
258
259 QUndoView is a QListView which displays the list of commands pushed on an undo stack.
260 The most recently executed command is always selected. Selecting a different command
261 results in a call to QUndoStack::setIndex(), rolling the state of the document
262 backwards or forward to the new command.
263
264 The stack can be set explicitly with setStack(). Alternatively, a QUndoGroup object can
265 be set with setGroup(). The view will then update itself automatically whenever the
266 active stack of the group changes.
267
268 \image qundoview.png
269*/
270
271class QUndoViewPrivate : public QListViewPrivate
272{
273 Q_DECLARE_PUBLIC(QUndoView)
274public:
275 QUndoViewPrivate() :
276#ifndef QT_NO_UNDOGROUP
277 group(0),
278#endif
279 model(0) {}
280
281#ifndef QT_NO_UNDOGROUP
282 QPointer<QUndoGroup> group;
283#endif
284 QUndoModel *model;
285
286 void init();
287};
288
289void QUndoViewPrivate::init()
290{
291 Q_Q(QUndoView);
292
293 model = new QUndoModel(q);
294 q->setModel(model);