~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/utilities/imageeditor/undomanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ============================================================
2
 
 * File  : undomanager.cpp
3
 
 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
4
 
 *         J�rn Ahrens <joern.ahrens@kdemail.net>
5
 
 * Date  : 2005-02-06
6
 
 * Description : 
7
 
 * 
8
 
 * Copyright 2005 by Renchi Raju, J�rn Ahrens
9
 
 *
10
 
 * This program is free software; you can redistribute it
11
 
 * and/or modify it under the terms of the GNU General
12
 
 * Public License as published by the Free Software Foundation;
13
 
 * either version 2, or (at your option)
14
 
 * 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
 
 * ============================================================ */
22
 
 
23
 
#include <typeinfo>
24
 
 
25
 
#include <qstringlist.h>
26
 
 
27
 
#include "imlibinterface.h"
28
 
#include "undoaction.h"
29
 
#include "undocache.h"
30
 
#include "undomanager.h"
31
 
 
32
 
#include <kdebug.h>
33
 
 
34
 
UndoManager::UndoManager(Digikam::ImlibInterface* iface)
35
 
    : m_iface(iface)
36
 
{
37
 
    m_cache = new UndoCache;
38
 
}
39
 
 
40
 
UndoManager::~UndoManager()
41
 
{
42
 
    clear(true);
43
 
    delete m_cache;
44
 
}
45
 
 
46
 
void UndoManager::addAction(UndoAction* action)
47
 
{
48
 
    if (!action)
49
 
        return;
50
 
 
51
 
    // All redo actions are invalid now
52
 
    clearRedoActions();
53
 
   
54
 
    m_undoActions.push_back(action);
55
 
 
56
 
    if (typeid(*action) == typeid(UndoActionIrreversible))
57
 
    {
58
 
        int   w    = m_iface->origWidth();
59
 
        int   h    = m_iface->origHeight();
60
 
        uint* data = m_iface->getData();
61
 
        
62
 
        m_cache->putData(m_undoActions.size(), w, h, data);
63
 
    }
64
 
}
65
 
 
66
 
void UndoManager::undo()
67
 
{
68
 
    if (m_undoActions.isEmpty())
69
 
        return;
70
 
 
71
 
    UndoAction* action = m_undoActions.back();
72
 
 
73
 
    if (typeid(*action) == typeid(UndoActionIrreversible))
74
 
    {
75
 
        int   w    = m_iface->origWidth();
76
 
        int   h    = m_iface->origHeight();
77
 
        uint* data = m_iface->getData();
78
 
 
79
 
        // save the current state for the redo operation        
80
 
        m_cache->putData(m_undoActions.size() + 1, w, h, data);
81
 
 
82
 
        // and now, undo the action
83
 
        m_cache->getData(m_undoActions.size(), w, h, data, false);
84
 
        m_iface->putData(data, w, h);
85
 
 
86
 
        delete [] data;
87
 
    }
88
 
    else
89
 
    {
90
 
        action->rollBack();
91
 
    }
92
 
    
93
 
    m_undoActions.pop_back();
94
 
    m_redoActions.push_back(action);
95
 
}
96
 
 
97
 
void UndoManager::redo()
98
 
{
99
 
    if(m_redoActions.isEmpty())
100
 
        return;
101
 
    
102
 
    UndoAction *action = m_redoActions.back();
103
 
    
104
 
    if(typeid(*action) == typeid(UndoActionIrreversible))
105
 
    {
106
 
        int  w, h;
107
 
        uint *data;
108
 
        
109
 
        m_cache->getData(m_undoActions.size() + 2, w, h, data, false);
110
 
        m_iface->putData(data, w, h);
111
 
        
112
 
        delete[] data;
113
 
    }
114
 
    else
115
 
    {
116
 
        action->execute();
117
 
    }
118
 
    
119
 
    m_redoActions.pop_back();
120
 
    m_undoActions.push_back(action);
121
 
}
122
 
 
123
 
void UndoManager::clear(bool clearCache)
124
 
{
125
 
    clearUndoActions();
126
 
    clearRedoActions();
127
 
    
128
 
    if(clearCache)
129
 
        m_cache->clear();
130
 
}
131
 
 
132
 
void UndoManager::clearUndoActions()
133
 
{
134
 
    UndoAction *action;
135
 
    QValueList<UndoAction*>::iterator it;
136
 
    
137
 
    for(it = m_undoActions.begin(); it != m_undoActions.end(); ++it)
138
 
    {
139
 
        action = *it;
140
 
        delete action;
141
 
    }
142
 
    m_undoActions.clear();
143
 
}
144
 
 
145
 
void UndoManager::clearRedoActions()
146
 
{
147
 
    if(!anyMoreRedo())
148
 
        return;
149
 
 
150
 
    UndoAction *action;
151
 
    QValueList<UndoAction*>::iterator it;
152
 
 
153
 
    // get the level of the first redo action
154
 
    int level = m_undoActions.size() + 1;
155
 
    for(it = m_redoActions.begin(); it != m_redoActions.end(); ++it)
156
 
    {
157
 
        action = *it;
158
 
        m_cache->erase(level);
159
 
        delete action;
160
 
        level++;
161
 
    }
162
 
    m_cache->erase(level);
163
 
    m_redoActions.clear();
164
 
}
165
 
 
166
 
bool UndoManager::anyMoreUndo()
167
 
{
168
 
    return !m_undoActions.isEmpty();
169
 
}
170
 
 
171
 
bool UndoManager::anyMoreRedo()
172
 
{
173
 
    return !m_redoActions.isEmpty();
174
 
}
175
 
 
176
 
void UndoManager::getUndoHistory(QStringList &titles)
177
 
{
178
 
    QValueList<UndoAction*>::iterator it;
179
 
 
180
 
    for(it = m_undoActions.begin(); it != m_undoActions.end(); ++it)
181
 
    {
182
 
        titles.push_front((*it)->getTitle());
183
 
    }
184
 
}
185
 
 
186
 
void UndoManager::getRedoHistory(QStringList &titles)
187
 
{
188
 
    QValueList<UndoAction*>::iterator it;
189
 
 
190
 
    for(it = m_redoActions.begin(); it != m_redoActions.end(); ++it)
191
 
    {
192
 
        titles.push_front((*it)->getTitle());
193
 
    }
194
 
}