Subversion Repositories Scribus

Rev

Rev 17735 | Rev 20691 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5116 tsoots 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
/***************************************************************************
8
 *   Copyright (C) 2005 by Riku Leino                                      *
9
 *   riku@scribus.info                                                     *
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 *   This program is distributed in the hope that it will be useful,       *
17
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19
 *   GNU General Public License for more details.                          *
20
 *                                                                         *
21
 *   You should have received a copy of the GNU General Public License     *
22
 *   along with this program; if not, write to the                         *
23
 *   Free Software Foundation, Inc.,                                       *
18122 mrdocs 24
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
5116 tsoots 25
 ***************************************************************************/
26
 
27
#include "undomanager.h"
28
#include "undoobject.h"
29
#include "undostack.h"
30
 
31
UndoStack::UndoStack(int maxSize) : maxSize_(maxSize)
32
{
33
 
34
}
35
 
36
bool UndoStack::action(UndoState *state)
37
{
38
    redoActions_.clear();
39
    undoActions_.insert(undoActions_.begin(), state);
40
    bool needsPopping = checkSize(); // only store maxSize_ amount of actions
41
 
42
    return needsPopping;
43
}
44
 
45
bool UndoStack::undo(uint steps, int objectId)
46
{
47
        for (uint i = 0; i < steps && !undoActions_.empty(); ++i) {
48
                UndoState *tmpUndoState = 0;
49
                if (objectId == Um::GLOBAL_UNDO_MODE)
50
                {
51
                        tmpUndoState = undoActions_[0];
52
                        undoActions_.erase(undoActions_.begin());
53
                }
54
                else
55
                { // object specific mode (search the correct state)
56
                        StateList::iterator it;
57
                        for (it = undoActions_.begin(); it != undoActions_.end(); ++it)
58
                        {
59
                                UndoObject *tmp = (*it)->undoObject();
60
                                if (tmp && tmp->getUId() == static_cast<ulong>(objectId))
61
                                {
62
                                        tmpUndoState = *it;
63
                                        undoActions_.erase(it);
64
                                        break;
65
                                }
17735 craig 66
                                else if((*it)->isTransaction())
67
                                {
68
                                        TransactionState *ts = dynamic_cast<TransactionState*>(*it);
69
                                        if(ts->containsOnly(objectId))
70
                                        {
71
                                                tmpUndoState = *it;
72
                                                undoActions_.erase(it);
73
                                                break;
74
                                        }
75
                                }
5116 tsoots 76
                        }
77
                }
78
 
79
                redoActions_.insert(redoActions_.begin(), tmpUndoState); // push to the redo actions
80
                tmpUndoState->undo();
81
        }
82
 
83
        return true;
84
}
85
 
86
bool UndoStack::redo(uint steps, int objectId)
87
{
88
        for (uint i = 0; i < steps && !redoActions_.empty(); ++i) {
89
                UndoState *tmpRedoState = 0;
90
                if (objectId == Um::GLOBAL_UNDO_MODE)
91
                {
92
                        tmpRedoState = redoActions_[0];
93
                        redoActions_.erase(redoActions_.begin());
94
                }
95
                else
96
                { // object specific mode (search the correct state)
97
                        StateList::iterator it;
98
                        for (it = redoActions_.begin(); it != redoActions_.end(); ++it)
99
                        {
100
                                UndoObject *tmp = (*it)->undoObject();
101
                                if (tmp && tmp->getUId() == static_cast<ulong>(objectId))
102
                                {
103
                                        tmpRedoState = *it;
104
                                        redoActions_.erase(it);
105
                                        break;
106
                                }
17735 craig 107
                                else if((*it)->isTransaction())
108
                                {
109
                                        TransactionState *ts = dynamic_cast<TransactionState*>(*it);
110
                                        if(ts->containsOnly(objectId))
111
                                        {
112
                                                tmpRedoState = *it;
113
                                                redoActions_.erase(it);
114
                                                break;
115
                                        }
116
                                }
5116 tsoots 117
                        }
118
                }
119
 
120
                undoActions_.insert(undoActions_.begin(), tmpRedoState); // push to the undo actions
121
                tmpRedoState->redo();
122
        }
123
 
124
        return true;
125
}
126
 
127
uint UndoStack::size() const
128
{
129
    return undoActions_.size() + redoActions_.size();
130
}
131
 
132
uint UndoStack::undoItems() const
133
{
134
    return undoActions_.size();
135
}
136
 
137
uint UndoStack::redoItems() const
138
{
139
    return redoActions_.size();
140
}
141
 
142
uint  UndoStack::maxSize() const
143
{
144
    return maxSize_;
145
}
146
 
147
void UndoStack::setMaxSize(uint maxSize)
148
{
149
    maxSize_ = maxSize;
150
    checkSize(); // we may need to remove actions
151
}
152
 
153
bool UndoStack::checkSize() {
154
    if (maxSize_ == 0) // 0 marks for infinite stack size
155
        return false;
156
 
157
    bool needsPopping = size () > maxSize_;
158
 
159
    while (size() > maxSize_) {
160
        if (redoActions_.size() > 0) // clear redo actions first
161
            redoActions_.pop_back();
162
        else
163
            undoActions_.pop_back();
164
    }
165
 
166
    return needsPopping;
167
}
168
 
169
void UndoStack::clear()
170
{
171
        for (uint i = 0; i < undoActions_.size(); ++i)
172
                delete undoActions_[i];
173
        for (uint i = 0; i < redoActions_.size(); ++i)
174
                delete redoActions_[i];
175
        undoActions_.clear();
176
        redoActions_.clear();
177
}
178
 
179
UndoState* UndoStack::getNextUndo(int objectId)
180
{
181
        UndoState *state = 0;
182
        if (!undoActions_.empty())
183
        {
184
                if (objectId == Um::GLOBAL_UNDO_MODE)
185
                        state = undoActions_[0];
186
                else
187
                {
188
                        StateList::iterator it;
189
                        for (it = undoActions_.begin(); it != undoActions_.end(); ++it)
190
                        {
191
                                UndoState*  tmp  = *it;
192
                                TransactionState *ts = dynamic_cast<TransactionState*>(tmp);
17735 craig 193
                                if ((tmp && tmp->undoObject() &&
194
                                                 tmp->undoObject()->getUId() == static_cast<ulong>(objectId)) || (ts && ts->containsOnly(objectId)))
5116 tsoots 195
                                {
196
                                        state = tmp;
197
                                        break;
198
                                }
17735 craig 199
                                else if (ts && ts->contains(objectId))
200
                                        break;
5116 tsoots 201
                        }
202
                }
203
        }
204
        return state;
205
}
206
 
207
UndoState* UndoStack::getNextRedo(int objectId)
208
{
209
        UndoState *state = 0;
210
        if (!redoActions_.empty())
211
        {
212
                if (objectId == Um::GLOBAL_UNDO_MODE)
213
                        state = redoActions_[0];
214
                else
215
                {
216
                        StateList::iterator it;
217
                        for (it = redoActions_.begin(); it != redoActions_.end(); ++it)
218
                        {
219
                                UndoState*  tmp  = *it;
220
                                TransactionState *ts = dynamic_cast<TransactionState*>(tmp);
17735 craig 221
                                if ((tmp && tmp->undoObject() &&
222
                                                 tmp->undoObject()->getUId() == static_cast<ulong>(objectId)) || (ts && ts->containsOnly(objectId)))
5116 tsoots 223
                                {
224
                                        state = tmp;
225
                                        break;
226
                                }
17735 craig 227
                                else if (ts && ts->contains(objectId))
228
                                        break;
5116 tsoots 229
                        }
230
                }
231
        }
232
        return state;
233
}
234
 
235
UndoStack::~UndoStack()
236
{
237
    // no dynamically allocated memory
238
}
239