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