~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/widgets/util/qundogroup.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtGui module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qundogroup.h"
 
43
#include "qundostack.h"
 
44
#include "qundostack_p.h"
 
45
 
 
46
#ifndef QT_NO_UNDOGROUP
 
47
 
 
48
QT_BEGIN_NAMESPACE
 
49
 
 
50
class QUndoGroupPrivate : public QObjectPrivate
 
51
{
 
52
    Q_DECLARE_PUBLIC(QUndoGroup)
 
53
public:
 
54
    QUndoGroupPrivate() : active(0) {}
 
55
 
 
56
    QUndoStack *active;
 
57
    QList<QUndoStack*> stack_list;
 
58
};
 
59
 
 
60
/*!
 
61
    \class QUndoGroup
 
62
    \brief The QUndoGroup class is a group of QUndoStack objects.
 
63
    \since 4.2
 
64
    \inmodule QtWidgets
 
65
 
 
66
    For an overview of the Qt's undo framework, see the
 
67
    \l{qundo.html}{overview}.
 
68
 
 
69
    An application often has multiple undo stacks, one for each opened document. At the
 
70
    same time, an application usually has one undo action and one redo action, which
 
71
    triggers undo or redo in the active document.
 
72
 
 
73
    QUndoGroup is a group of QUndoStack objects, one of which may be active. It has
 
74
    an undo() and redo() slot, which calls QUndoStack::undo() and QUndoStack::redo()
 
75
    for the active stack. It also has the functions createUndoAction() and createRedoAction().
 
76
    The actions returned by these functions behave in the same way as those returned by
 
77
    QUndoStack::createUndoAction() and QUndoStack::createRedoAction() of the active
 
78
    stack.
 
79
 
 
80
    Stacks are added to a group with addStack() and removed with removeStack(). A stack
 
81
    is implicitly added to a group when it is created with the group as its parent
 
82
    QObject.
 
83
 
 
84
    It is the programmer's responsibility to specify which stack is active by
 
85
    calling QUndoStack::setActive(), usually when the associated document window receives focus.
 
86
    The active stack may also be set with setActiveStack(), and is returned by activeStack().
 
87
 
 
88
    When a stack is added to a group using addStack(), the group does not take ownership
 
89
    of the stack. This means the stack has to be deleted separately from the group. When
 
90
    a stack is deleted, it is automatically removed from a group. A stack may belong to
 
91
    only one group. Adding it to another group will cause it to be removed from the previous
 
92
    group.
 
93
 
 
94
    A QUndoGroup is also useful in conjunction with QUndoView. If a QUndoView is
 
95
    set to watch a group using QUndoView::setGroup(), it will update itself to display
 
96
    the active stack.
 
97
*/
 
98
 
 
99
/*!
 
100
    Creates an empty QUndoGroup object with parent \a parent.
 
101
 
 
102
    \sa addStack()
 
103
*/
 
104
 
 
105
QUndoGroup::QUndoGroup(QObject *parent)
 
106
    : QObject(*new QUndoGroupPrivate(), parent)
 
107
{
 
108
}
 
109
 
 
110
/*!
 
111
    Destroys the QUndoGroup.
 
112
*/
 
113
QUndoGroup::~QUndoGroup()
 
114
{
 
115
    // Ensure all QUndoStacks no longer refer to this group.
 
116
    Q_D(QUndoGroup);
 
117
    QList<QUndoStack *>::iterator it = d->stack_list.begin();
 
118
    QList<QUndoStack *>::iterator end = d->stack_list.end();
 
119
    while (it != end) {
 
120
        (*it)->d_func()->group = 0;
 
121
        ++it;
 
122
    }
 
123
}
 
124
 
 
125
/*!
 
126
    Adds \a stack to this group. The group does not take ownership of the stack. Another
 
127
    way of adding a stack to a group is by specifying the group as the stack's parent
 
128
    QObject in QUndoStack::QUndoStack(). In this case, the stack is deleted when the
 
129
    group is deleted, in the usual manner of QObjects.
 
130
 
 
131
    \sa removeStack(), stacks(), QUndoStack::QUndoStack()
 
132
*/
 
133
 
 
134
void QUndoGroup::addStack(QUndoStack *stack)
 
135
{
 
136
    Q_D(QUndoGroup);
 
137
 
 
138
    if (d->stack_list.contains(stack))
 
139
        return;
 
140
    d->stack_list.append(stack);
 
141
 
 
142
    if (QUndoGroup *other = stack->d_func()->group)
 
143
        other->removeStack(stack);
 
144
    stack->d_func()->group = this;
 
145
}
 
146
 
 
147
/*!
 
148
    Removes \a stack from this group. If the stack was the active stack in the group,
 
149
    the active stack becomes 0.
 
150
 
 
151
    \sa addStack(), stacks(), QUndoStack::~QUndoStack()
 
152
*/
 
153
 
 
154
void QUndoGroup::removeStack(QUndoStack *stack)
 
155
{
 
156
    Q_D(QUndoGroup);
 
157
 
 
158
    if (d->stack_list.removeAll(stack) == 0)
 
159
        return;
 
160
    if (stack == d->active)
 
161
        setActiveStack(0);
 
162
    stack->d_func()->group = 0;
 
163
}
 
164
 
 
165
/*!
 
166
    Returns a list of stacks in this group.
 
167
 
 
168
    \sa addStack(), removeStack()
 
169
*/
 
170
 
 
171
QList<QUndoStack*> QUndoGroup::stacks() const
 
172
{
 
173
    Q_D(const QUndoGroup);
 
174
    return d->stack_list;
 
175
}
 
176
 
 
177
/*!
 
178
    Sets the active stack of this group to \a stack.
 
179
 
 
180
    If the stack is not a member of this group, this function does nothing.
 
181
 
 
182
    Synonymous with calling QUndoStack::setActive() on \a stack.
 
183
 
 
184
    The actions returned by createUndoAction() and createRedoAction() will now behave
 
185
    in the same way as those returned by \a stack's QUndoStack::createUndoAction()
 
186
    and QUndoStack::createRedoAction().
 
187
 
 
188
    \sa QUndoStack::setActive(), activeStack()
 
189
*/
 
190
 
 
191
void QUndoGroup::setActiveStack(QUndoStack *stack)
 
192
{
 
193
    Q_D(QUndoGroup);
 
194
    if (d->active == stack)
 
195
        return;
 
196
 
 
197
    if (d->active != 0) {
 
198
        disconnect(d->active, SIGNAL(canUndoChanged(bool)),
 
199
                    this, SIGNAL(canUndoChanged(bool)));
 
200
        disconnect(d->active, SIGNAL(undoTextChanged(QString)),
 
201
                    this, SIGNAL(undoTextChanged(QString)));
 
202
        disconnect(d->active, SIGNAL(canRedoChanged(bool)),
 
203
                    this, SIGNAL(canRedoChanged(bool)));
 
204
        disconnect(d->active, SIGNAL(redoTextChanged(QString)),
 
205
                    this, SIGNAL(redoTextChanged(QString)));
 
206
        disconnect(d->active, SIGNAL(indexChanged(int)),
 
207
                    this, SIGNAL(indexChanged(int)));
 
208
        disconnect(d->active, SIGNAL(cleanChanged(bool)),
 
209
                    this, SIGNAL(cleanChanged(bool)));
 
210
    }
 
211
 
 
212
    d->active = stack;
 
213
 
 
214
    if (d->active == 0) {
 
215
        emit canUndoChanged(false);
 
216
        emit undoTextChanged(QString());
 
217
        emit canRedoChanged(false);
 
218
        emit redoTextChanged(QString());
 
219
        emit cleanChanged(true);
 
220
        emit indexChanged(0);
 
221
    } else {
 
222
        connect(d->active, SIGNAL(canUndoChanged(bool)),
 
223
                this, SIGNAL(canUndoChanged(bool)));
 
224
        connect(d->active, SIGNAL(undoTextChanged(QString)),
 
225
                this, SIGNAL(undoTextChanged(QString)));
 
226
        connect(d->active, SIGNAL(canRedoChanged(bool)),
 
227
                this, SIGNAL(canRedoChanged(bool)));
 
228
        connect(d->active, SIGNAL(redoTextChanged(QString)),
 
229
                this, SIGNAL(redoTextChanged(QString)));
 
230
        connect(d->active, SIGNAL(indexChanged(int)),
 
231
                this, SIGNAL(indexChanged(int)));
 
232
        connect(d->active, SIGNAL(cleanChanged(bool)),
 
233
                this, SIGNAL(cleanChanged(bool)));
 
234
        emit canUndoChanged(d->active->canUndo());
 
235
        emit undoTextChanged(d->active->undoText());
 
236
        emit canRedoChanged(d->active->canRedo());
 
237
        emit redoTextChanged(d->active->redoText());
 
238
        emit cleanChanged(d->active->isClean());
 
239
        emit indexChanged(d->active->index());
 
240
    }
 
241
 
 
242
    emit activeStackChanged(d->active);
 
243
}
 
244
 
 
245
/*!
 
246
    Returns the active stack of this group.
 
247
 
 
248
    If none of the stacks are active, or if the group is empty, this function
 
249
    returns 0.
 
250
 
 
251
    \sa setActiveStack(), QUndoStack::setActive()
 
252
*/
 
253
 
 
254
QUndoStack *QUndoGroup::activeStack() const
 
255
{
 
256
    Q_D(const QUndoGroup);
 
257
    return d->active;
 
258
}
 
259
 
 
260
/*!
 
261
    Calls QUndoStack::undo() on the active stack.
 
262
 
 
263
    If none of the stacks are active, or if the group is empty, this function
 
264
    does nothing.
 
265
 
 
266
    \sa redo(), canUndo(), setActiveStack()
 
267
*/
 
268
 
 
269
void QUndoGroup::undo()
 
270
{
 
271
    Q_D(QUndoGroup);
 
272
    if (d->active != 0)
 
273
        d->active->undo();
 
274
}
 
275
 
 
276
/*!
 
277
    Calls QUndoStack::redo() on the active stack.
 
278
 
 
279
    If none of the stacks are active, or if the group is empty, this function
 
280
    does nothing.
 
281
 
 
282
    \sa undo(), canRedo(), setActiveStack()
 
283
*/
 
284
 
 
285
 
 
286
void QUndoGroup::redo()
 
287
{
 
288
    Q_D(QUndoGroup);
 
289
    if (d->active != 0)
 
290
        d->active->redo();
 
291
}
 
292
 
 
293
/*!
 
294
    Returns the value of the active stack's QUndoStack::canUndo().
 
295
 
 
296
    If none of the stacks are active, or if the group is empty, this function
 
297
    returns false.
 
298
 
 
299
    \sa canRedo(), setActiveStack()
 
300
*/
 
301
 
 
302
bool QUndoGroup::canUndo() const
 
303
{
 
304
    Q_D(const QUndoGroup);
 
305
    return d->active != 0 && d->active->canUndo();
 
306
}
 
307
 
 
308
/*!
 
309
    Returns the value of the active stack's QUndoStack::canRedo().
 
310
 
 
311
    If none of the stacks are active, or if the group is empty, this function
 
312
    returns false.
 
313
 
 
314
    \sa canUndo(), setActiveStack()
 
315
*/
 
316
 
 
317
bool QUndoGroup::canRedo() const
 
318
{
 
319
    Q_D(const QUndoGroup);
 
320
    return d->active != 0 && d->active->canRedo();
 
321
}
 
322
 
 
323
/*!
 
324
    Returns the value of the active stack's QUndoStack::undoText().
 
325
 
 
326
    If none of the stacks are active, or if the group is empty, this function
 
327
    returns an empty string.
 
328
 
 
329
    \sa redoText(), setActiveStack()
 
330
*/
 
331
 
 
332
QString QUndoGroup::undoText() const
 
333
{
 
334
    Q_D(const QUndoGroup);
 
335
    return d->active == 0 ? QString() : d->active->undoText();
 
336
}
 
337
 
 
338
/*!
 
339
    Returns the value of the active stack's QUndoStack::redoText().
 
340
 
 
341
    If none of the stacks are active, or if the group is empty, this function
 
342
    returns an empty string.
 
343
 
 
344
    \sa undoText(), setActiveStack()
 
345
*/
 
346
 
 
347
QString QUndoGroup::redoText() const
 
348
{
 
349
    Q_D(const QUndoGroup);
 
350
    return d->active == 0 ? QString() : d->active->redoText();
 
351
}
 
352
 
 
353
/*!
 
354
    Returns the value of the active stack's QUndoStack::isClean().
 
355
 
 
356
    If none of the stacks are active, or if the group is empty, this function
 
357
    returns true.
 
358
 
 
359
    \sa setActiveStack()
 
360
*/
 
361
 
 
362
bool QUndoGroup::isClean() const
 
363
{
 
364
    Q_D(const QUndoGroup);
 
365
    return d->active == 0 || d->active->isClean();
 
366
}
 
367
 
 
368
#ifndef QT_NO_ACTION
 
369
 
 
370
/*!
 
371
    Creates an undo QAction object with parent \a parent.
 
372
 
 
373
    Triggering this action will cause a call to QUndoStack::undo() on the active stack.
 
374
    The text of this action will always be the text of the command which will be undone
 
375
    in the next call to undo(), prefixed by \a prefix. If there is no command available
 
376
    for undo, if the group is empty or if none of the stacks are active, this action will
 
377
    be disabled.
 
378
 
 
379
    If \a prefix is empty, the default template "Undo %1" is used instead of prefix.
 
380
    Before Qt 4.8, the prefix "Undo" was used by default.
 
381
 
 
382
    \sa createRedoAction(), canUndo(), QUndoCommand::text()
 
383
*/
 
384
 
 
385
QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const
 
386
{
 
387
    QUndoAction *result = new QUndoAction(prefix, parent);
 
388
    if (prefix.isEmpty())
 
389
        result->setTextFormat(tr("Undo %1"), tr("Undo", "Default text for undo action"));
 
390
 
 
391
    result->setEnabled(canUndo());
 
392
    result->setPrefixedText(undoText());
 
393
    connect(this, SIGNAL(canUndoChanged(bool)),
 
394
            result, SLOT(setEnabled(bool)));
 
395
    connect(this, SIGNAL(undoTextChanged(QString)),
 
396
            result, SLOT(setPrefixedText(QString)));
 
397
    connect(result, SIGNAL(triggered()), this, SLOT(undo()));
 
398
    return result;
 
399
}
 
400
 
 
401
/*!
 
402
    Creates an redo QAction object with parent \a parent.
 
403
 
 
404
    Triggering this action will cause a call to QUndoStack::redo() on the active stack.
 
405
    The text of this action will always be the text of the command which will be redone
 
406
    in the next call to redo(), prefixed by \a prefix. If there is no command available
 
407
    for redo, if the group is empty or if none of the stacks are active, this action will
 
408
    be disabled.
 
409
 
 
410
    If \a prefix is empty, the default template "Redo %1" is used instead of prefix.
 
411
    Before Qt 4.8, the prefix "Redo" was used by default.
 
412
 
 
413
    \sa createUndoAction(), canRedo(), QUndoCommand::text()
 
414
*/
 
415
 
 
416
QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const
 
417
{
 
418
    QUndoAction *result = new QUndoAction(prefix, parent);
 
419
    if (prefix.isEmpty())
 
420
        result->setTextFormat(tr("Redo %1"), tr("Redo", "Default text for redo action"));
 
421
 
 
422
    result->setEnabled(canRedo());
 
423
    result->setPrefixedText(redoText());
 
424
    connect(this, SIGNAL(canRedoChanged(bool)),
 
425
            result, SLOT(setEnabled(bool)));
 
426
    connect(this, SIGNAL(redoTextChanged(QString)),
 
427
            result, SLOT(setPrefixedText(QString)));
 
428
    connect(result, SIGNAL(triggered()), this, SLOT(redo()));
 
429
    return result;
 
430
}
 
431
 
 
432
#endif // QT_NO_ACTION
 
433
 
 
434
/*! \fn void QUndoGroup::activeStackChanged(QUndoStack *stack)
 
435
 
 
436
    This signal is emitted whenever the active stack of the group changes. This can happen
 
437
    when setActiveStack() or QUndoStack::setActive() is called, or when the active stack
 
438
    is removed form the group. \a stack is the new active stack. If no stack is active,
 
439
    \a stack is 0.
 
440
 
 
441
    \sa setActiveStack(), QUndoStack::setActive()
 
442
*/
 
443
 
 
444
/*! \fn void QUndoGroup::indexChanged(int idx)
 
445
 
 
446
    This signal is emitted whenever the active stack emits QUndoStack::indexChanged()
 
447
    or the active stack changes.
 
448
 
 
449
    \a idx is the new current index, or 0 if the active stack is 0.
 
450
 
 
451
    \sa QUndoStack::indexChanged(), setActiveStack()
 
452
*/
 
453
 
 
454
/*! \fn void QUndoGroup::cleanChanged(bool clean)
 
455
 
 
456
    This signal is emitted whenever the active stack emits QUndoStack::cleanChanged()
 
457
    or the active stack changes.
 
458
 
 
459
    \a clean is the new state, or true if the active stack is 0.
 
460
 
 
461
    \sa QUndoStack::cleanChanged(), setActiveStack()
 
462
*/
 
463
 
 
464
/*! \fn void QUndoGroup::canUndoChanged(bool canUndo)
 
465
 
 
466
    This signal is emitted whenever the active stack emits QUndoStack::canUndoChanged()
 
467
    or the active stack changes.
 
468
 
 
469
    \a canUndo is the new state, or false if the active stack is 0.
 
470
 
 
471
    \sa QUndoStack::canUndoChanged(), setActiveStack()
 
472
*/
 
473
 
 
474
/*! \fn void QUndoGroup::canRedoChanged(bool canRedo)
 
475
 
 
476
    This signal is emitted whenever the active stack emits QUndoStack::canRedoChanged()
 
477
    or the active stack changes.
 
478
 
 
479
    \a canRedo is the new state, or false if the active stack is 0.
 
480
 
 
481
    \sa QUndoStack::canRedoChanged(), setActiveStack()
 
482
*/
 
483
 
 
484
/*! \fn void QUndoGroup::undoTextChanged(const QString &undoText)
 
485
 
 
486
    This signal is emitted whenever the active stack emits QUndoStack::undoTextChanged()
 
487
    or the active stack changes.
 
488
 
 
489
    \a undoText is the new state, or an empty string if the active stack is 0.
 
490
 
 
491
    \sa QUndoStack::undoTextChanged(), setActiveStack()
 
492
*/
 
493
 
 
494
/*! \fn void QUndoGroup::redoTextChanged(const QString &redoText)
 
495
 
 
496
    This signal is emitted whenever the active stack emits QUndoStack::redoTextChanged()
 
497
    or the active stack changes.
 
498
 
 
499
    \a redoText is the new state, or an empty string if the active stack is 0.
 
500
 
 
501
    \sa QUndoStack::redoTextChanged(), setActiveStack()
 
502
*/
 
503
 
 
504
QT_END_NAMESPACE
 
505
 
 
506
#endif // QT_NO_UNDOGROUP