1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /*******************************************************************************
21  *  Includes
22  ******************************************************************************/
23 #include "undostackactiongroup.h"
24 
25 #include "../undostack.h"
26 
27 #include <QtCore>
28 #include <QtWidgets>
29 
30 /*******************************************************************************
31  *  Namespace
32  ******************************************************************************/
33 namespace librepcb {
34 
35 /*******************************************************************************
36  *  Constructors / Destructor
37  ******************************************************************************/
38 
UndoStackActionGroup(QAction & undo,QAction & redo,QAction * save,UndoStack * stack,QWidget * msgBoxParent)39 UndoStackActionGroup::UndoStackActionGroup(QAction& undo, QAction& redo,
40                                            QAction* save, UndoStack* stack,
41                                            QWidget* msgBoxParent) noexcept
42   : QObject(nullptr),
43     mUndo(undo),
44     mRedo(redo),
45     mSave(save),
46     mStack(nullptr),
47     mMsgBoxParent(msgBoxParent) {
48   connect(&mUndo, &QAction::triggered, this,
49           &UndoStackActionGroup::undoTriggered);
50   connect(&mRedo, &QAction::triggered, this,
51           &UndoStackActionGroup::redoTriggered);
52   registerToStack(stack);
53 }
54 
~UndoStackActionGroup()55 UndoStackActionGroup::~UndoStackActionGroup() noexcept {
56   unregisterFromStack();
57 }
58 
59 /*******************************************************************************
60  *  General Methods
61  ******************************************************************************/
62 
setUndoStack(UndoStack * stack)63 void UndoStackActionGroup::setUndoStack(UndoStack* stack) noexcept {
64   if (stack != mStack) {
65     unregisterFromStack();
66     registerToStack(stack);
67   }
68 }
69 
70 /*******************************************************************************
71  *  Private Methods
72  ******************************************************************************/
73 
undoTriggered()74 void UndoStackActionGroup::undoTriggered() noexcept {
75   try {
76     if (mStack) mStack->undo();
77   } catch (const Exception& e) {
78     QMessageBox::critical(mMsgBoxParent, tr("Undo failed"), e.getMsg());
79   }
80 }
81 
redoTriggered()82 void UndoStackActionGroup::redoTriggered() noexcept {
83   try {
84     if (mStack) mStack->redo();
85   } catch (const Exception& e) {
86     QMessageBox::critical(mMsgBoxParent, tr("Redo failed"), e.getMsg());
87   }
88 }
89 
unregisterFromStack()90 void UndoStackActionGroup::unregisterFromStack() noexcept {
91   while (mConnections.count() > 0) {
92     disconnect(mConnections.takeLast());
93   }
94   mUndo.setText(QString());
95   mUndo.setEnabled(false);
96   mRedo.setText(QString());
97   mRedo.setEnabled(false);
98   if (mSave) mSave->setEnabled(false);
99   mStack = nullptr;
100 }
101 
registerToStack(UndoStack * stack)102 void UndoStackActionGroup::registerToStack(UndoStack* stack) noexcept {
103   Q_ASSERT(!mStack);
104   if (stack) {
105     mConnections.append(
106         connect(stack, &UndoStack::undoTextChanged, &mUndo, &QAction::setText));
107     mUndo.setText(stack->getUndoText());
108 
109     mConnections.append(connect(stack, &UndoStack::canUndoChanged, &mUndo,
110                                 &QAction::setEnabled));
111     mUndo.setEnabled(stack->canUndo());
112 
113     mConnections.append(
114         connect(stack, &UndoStack::redoTextChanged, &mRedo, &QAction::setText));
115     mRedo.setText(stack->getRedoText());
116 
117     mConnections.append(connect(stack, &UndoStack::canRedoChanged, &mRedo,
118                                 &QAction::setEnabled));
119     mRedo.setEnabled(stack->canRedo());
120 
121     if (mSave) {
122       mConnections.append(connect(stack, &UndoStack::cleanChanged, mSave,
123                                   &QAction::setDisabled));
124       mSave->setDisabled(stack->isClean());
125     }
126   }
127   mStack = stack;
128 }
129 
130 /*******************************************************************************
131  *  End of File
132  ******************************************************************************/
133 
134 }  // namespace librepcb
135