diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-17 23:39:35 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-17 23:39:35 +0000 |
commit | f48aef5ed7f2e333984766d9ceb02e01ecbd47a7 (patch) | |
tree | 6ed79de882f3051cf7999a9cee2b633d8daabeab /src/undomanager.cpp | |
download | dolphin-f48aef5ed7f2e333984766d9ceb02e01ecbd47a7.tar.gz dolphin-f48aef5ed7f2e333984766d9ceb02e01ecbd47a7.zip |
Added old KDE3 version of dolphin
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/dolphin@1076309 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/undomanager.cpp')
-rw-r--r-- | src/undomanager.cpp | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/src/undomanager.cpp b/src/undomanager.cpp new file mode 100644 index 0000000..5869e4b --- /dev/null +++ b/src/undomanager.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "undomanager.h" +#include <klocale.h> +#include <kio/netaccess.h> +#include <qtimer.h> +#include <assert.h> + +#include "dolphin.h" +#include "dolphinstatusbar.h" +#include "progressindicator.h" + +DolphinCommand::DolphinCommand() : + m_type(Copy), + m_macroIndex(-1) +{ + // Implementation note: DolphinCommands are stored in a QValueList, whereas + // QValueList requires a default constructor of the added class. + // Instead of expressing this implementation detail to the interface by adding a + // Type::Undefined just Type::Copy is used to assure that all members have + // a defined state. +} + +DolphinCommand::DolphinCommand(Type type, + const KURL::List& source, + const KURL& dest) : + m_type(type), + m_macroIndex(-1), + m_source(source), + m_dest(dest) +{ +} + +DolphinCommand::~DolphinCommand() +{ +} + +DolphinCommand& DolphinCommand::operator = (const DolphinCommand& command) +{ + m_type = command.m_type; + m_source = command.m_source; + m_dest = command.m_dest; + return *this; +} + +UndoManager& UndoManager::instance() +{ + static UndoManager* instance = 0; + if (instance == 0) { + instance = new UndoManager(); + } + return *instance; +} + +void UndoManager::addCommand(const DolphinCommand& command) +{ + ++m_historyIndex; + + if (m_recordMacro) { + DolphinCommand macroCommand = command; + macroCommand.m_macroIndex = m_macroCounter; + m_history.insert(m_history.at(m_historyIndex), macroCommand); + } + else { + m_history.insert(m_history.at(m_historyIndex), command); + } + + emit undoAvailable(true); + emit undoTextChanged(i18n("Undo: %1").arg(commandText(command))); + + // prevent an endless growing of the Undo history + if (m_historyIndex > 10000) { + m_history.erase(m_history.begin()); + --m_historyIndex; + } +} + +void UndoManager::beginMacro() +{ + assert(!m_recordMacro); + m_recordMacro = true; + ++m_macroCounter; +} + +void UndoManager::endMacro() +{ + assert(m_recordMacro); + m_recordMacro = false; +} + +void UndoManager::undo() +{ + if (m_recordMacro) { + endMacro(); + } + + if (m_historyIndex < 0) { + return; + } + + int progressCount = 0; + int macroCount = 1; + calcStepsCount(macroCount, progressCount); + + m_progressIndicator = new ProgressIndicator(i18n("Executing undo operation..."), + i18n("Executed undo operation."), + progressCount); + + for (int i = 0; i < macroCount; ++i) { + const DolphinCommand command = m_history[m_historyIndex]; + --m_historyIndex; + if (m_historyIndex < 0) { + emit undoAvailable(false); + emit undoTextChanged(i18n("Undo")); + } + else { + emit undoTextChanged(i18n("Undo: %1").arg(commandText(m_history[m_historyIndex]))); + } + + if (m_historyIndex < static_cast<int>(m_history.count()) - 1) { + emit redoAvailable(true); + emit redoTextChanged(i18n("Redo: %1").arg(commandText(command))); + } + else { + emit redoAvailable(false); + emit redoTextChanged(i18n("Redo")); + } + + KURL::List sourceURLs = command.source(); + KURL::List::Iterator it = sourceURLs.begin(); + const KURL::List::Iterator end = sourceURLs.end(); + const QString destURL(command.destination().prettyURL(+1)); + + KIO::Job* job = 0; + switch (command.type()) { + case DolphinCommand::Link: + case DolphinCommand::Copy: { + KURL::List list; + while (it != end) { + const KURL deleteURL(destURL + (*it).filename()); + list.append(deleteURL); + ++it; + } + job = KIO::del(list, false, false); + break; + } + + case DolphinCommand::Move: { + KURL::List list; + const KURL newDestURL((*it).directory()); + while (it != end) { + const KURL newSourceURL(destURL + (*it).filename()); + list.append(newSourceURL); + ++it; + } + job = KIO::move(list, newDestURL, false); + break; + } + + case DolphinCommand::Rename: { + assert(sourceURLs.count() == 1); + KIO::NetAccess::move(command.destination(), (*it)); + break; + } + + case DolphinCommand::Trash: { + while (it != end) { + // TODO: use KIO::special for accessing the trash protocol. See + // also Dolphin::slotJobResult() for further details. + const QString originalFileName((*it).filename().section('-', 1)); + KURL newDestURL(destURL + originalFileName); + KIO::NetAccess::move(*it, newDestURL); + ++it; + + m_progressIndicator->execOperation(); + } + break; + } + + case DolphinCommand::CreateFolder: + case DolphinCommand::CreateFile: { + KIO::NetAccess::del(command.destination(), &Dolphin::mainWin()); + break; + } + } + + if (job != 0) { + // Execute the jobs in a synchronous manner and forward the progress + // information to the Dolphin statusbar. + connect(job, SIGNAL(percent(KIO::Job*, unsigned long)), + this, SLOT(slotPercent(KIO::Job*, unsigned long))); + KIO::NetAccess::synchronousRun(job, &Dolphin::mainWin()); + } + + m_progressIndicator->execOperation(); + } + + delete m_progressIndicator; + m_progressIndicator = 0; +} + +void UndoManager::redo() +{ + if (m_recordMacro) { + endMacro(); + } + + const int maxHistoryIndex = m_history.count() - 1; + if (m_historyIndex >= maxHistoryIndex) { + return; + } + ++m_historyIndex; + + int progressCount = 0; + int macroCount = 1; + calcStepsCount(macroCount, progressCount); + + m_progressIndicator = new ProgressIndicator(i18n("Executing redo operation..."), + i18n("Executed redo operation."), + progressCount); + + for (int i = 0; i < macroCount; ++i) { + const DolphinCommand command = m_history[m_historyIndex]; + if (m_historyIndex >= maxHistoryIndex) { + emit redoAvailable(false); + emit redoTextChanged(i18n("Redo")); + } + else { + emit redoTextChanged(i18n("Redo: %1").arg(commandText(m_history[m_historyIndex + 1]))); + } + + emit undoAvailable(true); + emit undoTextChanged(i18n("Undo: %1").arg(commandText(command))); + + Dolphin& dolphin = Dolphin::mainWin(); + + KURL::List sourceURLs = command.source(); + KURL::List::Iterator it = sourceURLs.begin(); + const KURL::List::Iterator end = sourceURLs.end(); + + KIO::Job* job = 0; + switch (command.type()) { + case DolphinCommand::Link: { + job = KIO::link(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Copy: { + job = KIO::copy(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Rename: + case DolphinCommand::Move: { + job = KIO::move(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Trash: { + const QString destURL(command.destination().prettyURL()); + while (it != end) { + // TODO: use KIO::special for accessing the trash protocol. See + // also Dolphin::slotJobResult() for further details. + const QString originalFileName((*it).filename().section('-', 1)); + KURL originalSourceURL(destURL + "/" + originalFileName); + KIO::Job* moveToTrashJob = KIO::trash(originalSourceURL); + KIO::NetAccess::synchronousRun(moveToTrashJob, &dolphin); + ++it; + + m_progressIndicator->execOperation(); + } + break; + } + + case DolphinCommand::CreateFolder: { + KIO::NetAccess::mkdir(command.destination(), &dolphin); + break; + } + + case DolphinCommand::CreateFile: { + m_progressIndicator->execOperation(); + KURL::List::Iterator it = sourceURLs.begin(); + assert(sourceURLs.count() == 1); + KIO::CopyJob* copyJob = KIO::copyAs(*it, command.destination(), false); + copyJob->setDefaultPermissions(true); + job = copyJob; + break; + } + } + + if (job != 0) { + // Execute the jobs in a synchronous manner and forward the progress + // information to the Dolphin statusbar. + connect(job, SIGNAL(percent(KIO::Job*, unsigned long)), + this, SLOT(slotPercent(KIO::Job*, unsigned long))); + KIO::NetAccess::synchronousRun(job, &dolphin); + } + + ++m_historyIndex; + m_progressIndicator->execOperation(); + } + + --m_historyIndex; + + delete m_progressIndicator; + m_progressIndicator = 0; +} + +UndoManager::UndoManager() : + m_recordMacro(false), + m_historyIndex(-1), + m_macroCounter(0), + m_progressIndicator(0) +{ +} + +UndoManager::~UndoManager() +{ + delete m_progressIndicator; + m_progressIndicator = 0; +} + +QString UndoManager::commandText(const DolphinCommand& command) const +{ + QString text; + switch (command.type()) { + case DolphinCommand::Copy: text = i18n("Copy"); break; + case DolphinCommand::Move: text = i18n("Move"); break; + case DolphinCommand::Link: text = i18n("Link"); break; + case DolphinCommand::Rename: text = i18n("Rename"); break; + case DolphinCommand::Trash: text = i18n("Move to Trash"); break; + case DolphinCommand::CreateFolder: text = i18n("Create New Folder"); break; + case DolphinCommand::CreateFile: text = i18n("Create New File"); break; + default: break; + } + return text; +} + +void UndoManager::slotPercent(KIO::Job* /* job */, unsigned long /* percent */) +{ + // It is not allowed to update the progress indicator in the context + // of this slot, hence do an asynchronous triggering. + QTimer::singleShot(0, this, SLOT(updateProgress())); +} + +void UndoManager::updateProgress() +{ + m_progressIndicator->execOperation(); +} + +void UndoManager::calcStepsCount(int& macroCount, int& progressCount) +{ + progressCount = 0; + macroCount = 0; + + const int macroIndex = m_history[m_historyIndex].m_macroIndex; + if (macroIndex < 0) { + // default use case: no macro has been recorded + macroCount = 1; + progressCount = m_history[m_historyIndex].source().count(); + return; + } + + // iterate backward for undo... + int i = m_historyIndex; + while ((i >= 0) && (m_history[i].m_macroIndex == macroIndex)) { + ++macroCount; + progressCount += m_history[i].source().count(); + --i; + } + + // iterate forward for redo... + const int max = m_history.count() - 1; + i = m_historyIndex + 1; + while ((i <= max) && (m_history[i].m_macroIndex == macroIndex)) { + ++macroCount; + progressCount += m_history[i].source().count(); + ++i; + } +} + +#include "undomanager.moc" + + |