Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konqueror / src / konqundomanager.cpp
blob37e76d3a705ce265cd5ba51456d890c85c9aefbf
1 /* This file is part of the KDE project
2 Copyright 2007 David Faure <faure@kde.org>
3 Copyright 2007 Eduardo Robles Elvira <edulix@gmail.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 #include "konqundomanager.h"
22 #include "konqsettingsxt.h"
23 #include "konqcloseditem.h"
24 #include "konqclosedwindowsmanager.h"
25 #include <QAction>
26 #include <QByteArray>
27 #include <QFile>
28 #include <QTimer>
29 #include <QVariant>
30 #include <kio/fileundomanager.h>
31 #include <kdebug.h>
32 #include <klocale.h>
35 KonqUndoManager::KonqUndoManager(QWidget* parent)
36 : QObject(parent)
38 connect( KIO::FileUndoManager::self(), SIGNAL(undoAvailable(bool)),
39 this, SLOT(slotFileUndoAvailable(bool)) );
40 connect( KIO::FileUndoManager::self(), SIGNAL(undoTextChanged(QString)),
41 this, SLOT(slotFileUndoTextChanged(QString)) );
43 connect(KonqClosedWindowsManager::self(),
44 SIGNAL(addWindowInOtherInstances(KonqUndoManager *, KonqClosedWindowItem *)), this,
45 SLOT( slotAddClosedWindowItem(KonqUndoManager *, KonqClosedWindowItem *) ));
46 connect(KonqClosedWindowsManager::self(),
47 SIGNAL(removeWindowInOtherInstances(KonqUndoManager *, const KonqClosedWindowItem *)), this,
48 SLOT( slotRemoveClosedWindowItem(KonqUndoManager *, const KonqClosedWindowItem *) ));
49 m_populated = false;
52 KonqUndoManager::~KonqUndoManager()
54 disconnect( KIO::FileUndoManager::self(), SIGNAL(undoAvailable(bool)),
55 this, SLOT(slotFileUndoAvailable(bool)) );
56 disconnect( KIO::FileUndoManager::self(), SIGNAL(undoTextChanged(QString)),
57 this, SLOT(slotFileUndoTextChanged(QString)) );
59 disconnect(KonqClosedWindowsManager::self(),
60 SIGNAL(addWindowInOtherInstances(KonqUndoManager *, KonqClosedWindowItem *)), this,
61 SLOT( slotAddClosedWindowItem(KonqUndoManager *, KonqClosedWindowItem *) ));
62 disconnect(KonqClosedWindowsManager::self(),
63 SIGNAL(removeWindowInOtherInstances(KonqUndoManager *, const KonqClosedWindowItem *)), this,
64 SLOT( slotRemoveClosedWindowItem(KonqUndoManager *, const KonqClosedWindowItem *) ));
66 // Clear the closed item lists but only remove closed windows items
67 // in this window
68 clearClosedItemsList(true);
71 void KonqUndoManager::populate()
73 if(m_populated)
74 return;
75 m_populated = true;
77 const QList<KonqClosedWindowItem *> closedWindowItemList =
78 KonqClosedWindowsManager::self()->closedWindowItemList();
80 QListIterator<KonqClosedWindowItem *> i(closedWindowItemList);
82 // This loop is done backwards because slotAddClosedWindowItem prepends the
83 // elements to the list, so if we do it forwards the we would get an inverse
84 // order of closed windows
85 for(i.toBack(); i.hasPrevious(); )
86 slotAddClosedWindowItem(0L, i.previous());
89 void KonqUndoManager::slotFileUndoAvailable(bool)
91 emit undoAvailable(this->undoAvailable());
94 bool KonqUndoManager::undoAvailable() const
96 if (!m_closedItemList.isEmpty() || KonqClosedWindowsManager::self()->undoAvailable())
97 return true;
98 else
99 return (m_supportsFileUndo && KIO::FileUndoManager::self()->undoAvailable());
102 QString KonqUndoManager::undoText() const
104 if (!m_closedItemList.isEmpty()) {
105 const KonqClosedItem* closedItem = m_closedItemList.first();
106 if (closedItem->serialNumber() > KIO::FileUndoManager::self()->currentCommandSerialNumber()) {
107 const KonqClosedTabItem* closedTabItem =
108 dynamic_cast<const KonqClosedTabItem *>(closedItem);
109 if(closedTabItem)
110 return i18n("Und&o: Closed Tab");
111 else
112 return i18n("Und&o: Closed Window");
114 } else if(KonqClosedWindowsManager::self()->undoAvailable())
115 return i18n("Und&o: Closed Window");
117 return KIO::FileUndoManager::self()->undoText();
120 void KonqUndoManager::undo()
122 populate();
123 KIO::FileUndoManager* fileUndoManager = KIO::FileUndoManager::self();
124 if (!m_closedItemList.isEmpty()) {
125 KonqClosedItem* closedItem = m_closedItemList.first();
127 // Check what to undo
128 if (closedItem->serialNumber() > fileUndoManager->currentCommandSerialNumber()) {
129 undoClosedItem(0);
130 return;
133 fileUndoManager->uiInterface()->setParentWidget(qobject_cast<QWidget*>(parent()));
134 fileUndoManager->undo();
137 void KonqUndoManager::slotAddClosedWindowItem(KonqUndoManager *real_sender, KonqClosedWindowItem *closedWindowItem)
139 if(real_sender == this)
140 return;
142 populate();
144 if(m_closedItemList.size() >= KonqSettings::maxNumClosedItems())
146 const KonqClosedItem* last = m_closedItemList.last();
147 const KonqClosedTabItem* lastTab =
148 dynamic_cast<const KonqClosedTabItem *>(last);
149 m_closedItemList.removeLast();
151 // Delete only if it's a tab
152 if(lastTab)
153 delete lastTab;
156 m_closedItemList.prepend(closedWindowItem);
157 emit undoTextChanged(i18n("Und&o: Closed Window"));
158 emit undoAvailable(true);
159 emit closedItemsListChanged();
162 void KonqUndoManager::addClosedWindowItem(KonqClosedWindowItem *closedWindowItem)
164 populate();
165 KonqClosedWindowsManager::self()->addClosedWindowItem(this, closedWindowItem);
168 void KonqUndoManager::slotRemoveClosedWindowItem(KonqUndoManager *real_sender, const KonqClosedWindowItem *closedWindowItem)
170 if(real_sender == this)
171 return;
173 populate();
175 QList<KonqClosedItem *>::iterator it = qFind(m_closedItemList.begin(), m_closedItemList.end(), closedWindowItem);
177 // If the item was found, remove it from the list
178 if(it != m_closedItemList.end()) {
179 m_closedItemList.erase(it);
180 emit undoAvailable(this->undoAvailable());
181 emit closedItemsListChanged();
185 const QList<KonqClosedItem *>& KonqUndoManager::closedItemsList()
187 populate();
188 return m_closedItemList;
191 void KonqUndoManager::undoClosedItem(int index)
193 populate();
194 Q_ASSERT(!m_closedItemList.isEmpty());
195 KonqClosedItem* closedItem = m_closedItemList.at( index );
196 m_closedItemList.removeAt(index);
198 const KonqClosedTabItem* closedTabItem =
199 dynamic_cast<const KonqClosedTabItem *>(closedItem);
200 KonqClosedRemoteWindowItem* closedRemoteWindowItem =
201 dynamic_cast<KonqClosedRemoteWindowItem *>(closedItem);
202 KonqClosedWindowItem* closedWindowItem =
203 dynamic_cast<KonqClosedWindowItem *>(closedItem);
204 if(closedTabItem)
205 emit openClosedTab(*closedTabItem);
206 else if(closedRemoteWindowItem) {
207 emit openClosedWindow(*closedRemoteWindowItem);
208 KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedRemoteWindowItem);
209 } else if(closedWindowItem) {
210 emit openClosedWindow(*closedWindowItem);
211 KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedWindowItem);
212 closedWindowItem->configGroup().deleteGroup();
214 delete closedItem;
215 emit undoAvailable(this->undoAvailable());
216 emit undoTextChanged(this->undoText());
217 emit closedItemsListChanged();
220 void KonqUndoManager::slotClosedItemsActivated(QAction* action)
222 // Open a closed tab
223 const int index = action->data().toInt();
224 undoClosedItem(index);
227 void KonqUndoManager::slotFileUndoTextChanged(const QString& text)
229 // I guess we can always just forward that one?
230 emit undoTextChanged(text);
233 quint64 KonqUndoManager::newCommandSerialNumber()
235 return KIO::FileUndoManager::self()->newCommandSerialNumber();
238 void KonqUndoManager::addClosedTabItem(KonqClosedTabItem* closedTabItem)
240 populate();
242 if(m_closedItemList.size() >= KonqSettings::maxNumClosedItems())
244 const KonqClosedItem* last = m_closedItemList.last();
245 const KonqClosedTabItem* lastTab =
246 dynamic_cast<const KonqClosedTabItem *>(last);
247 m_closedItemList.removeLast();
249 // Delete only if it's a tab
250 if(lastTab)
251 delete lastTab;
254 m_closedItemList.prepend(closedTabItem);
255 emit undoTextChanged(i18n("Und&o: Closed Tab"));
256 emit undoAvailable(true);
259 void KonqUndoManager::updateSupportsFileUndo(bool enable)
261 m_supportsFileUndo = enable;
262 emit undoAvailable(this->undoAvailable());
265 void KonqUndoManager::clearClosedItemsList(bool onlyInthisWindow)
267 populate();
268 // we only DELETE tab items! So we can't do this anymore:
269 // qDeleteAll(m_closedItemList);
270 QList<KonqClosedItem *>::iterator it = m_closedItemList.begin();
271 for (; it != m_closedItemList.end(); ++it)
273 KonqClosedItem *closedItem = *it;
274 const KonqClosedTabItem* closedTabItem =
275 dynamic_cast<const KonqClosedTabItem *>(closedItem);
276 const KonqClosedWindowItem* closedWindowItem =
277 dynamic_cast<const KonqClosedWindowItem *>(closedItem);
279 m_closedItemList.erase(it);
280 if(closedTabItem)
281 delete closedTabItem;
282 else if (closedWindowItem && !onlyInthisWindow) {
283 KonqClosedWindowsManager::self()->removeClosedWindowItem(this, closedWindowItem, true);
284 delete closedWindowItem;
287 emit closedItemsListChanged();
288 emit undoAvailable(this->undoAvailable());
291 void KonqUndoManager::undoLastClosedItem()
293 undoClosedItem(0);
296 #include "konqundomanager.moc"