From: Peter Penz Date: Thu, 18 Jan 2007 06:32:21 +0000 (+0000) Subject: Replaced Dolphins UndoManager and DolphinCommand by KonqUndoManager and KonqOperation... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/76866f783cfd5e84a85b6e9024aa554f3969ecec Replaced Dolphins UndoManager and DolphinCommand by KonqUndoManager and KonqOperations. There are still some minor open issues left (renaming of multiple selected files, no undo support for KonqOperations::mkdir(), redo, ...), but all in all it absolutely makes sense to use a shared code for those operations. svn path=/trunk/playground/utils/dolphin/; revision=624760 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8955ccb21..8e5816edf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,6 @@ set(dolphin_SRCS sidebarpage.cpp statusbarspaceinfo.cpp statusbarmessagelabel.cpp - undomanager.cpp urlbutton.cpp urlnavigator.cpp urlnavigatorbutton.cpp diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index ad144d625..45f99eaeb 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -23,59 +23,54 @@ #include +#include "dolphinapplication.h" +#include "dolphinsettings.h" +#include "dolphinsettingsdialog.h" +#include "dolphinstatusbar.h" +#include "dolphinapplication.h" +#include "urlnavigator.h" +#include "progressindicator.h" +#include "dolphinsettings.h" +#include "bookmarkssidebarpage.h" +#include "infosidebarpage.h" +#include "generalsettings.h" +#include "viewpropertiesdialog.h" +#include "viewproperties.h" + +#include #include -#include #include +#include +#include +#include +#include #include -#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include -//Added by qt3to4: -#include +#include // TODO #include +#include #include #include -#include "urlnavigator.h" -#include "viewpropertiesdialog.h" -#include "viewproperties.h" -#include "dolphinsettings.h" -#include "dolphinsettingsdialog.h" -#include "dolphinstatusbar.h" -#include "dolphinapplication.h" -#include "undomanager.h" -#include "progressindicator.h" -#include "dolphinsettings.h" -#include "bookmarkssidebarpage.h" -#include "infosidebarpage.h" -#include "generalsettings.h" -#include "dolphinapplication.h" - - DolphinMainWindow::DolphinMainWindow() : KMainWindow(0), m_splitter(0), @@ -84,10 +79,19 @@ DolphinMainWindow::DolphinMainWindow() : setObjectName("Dolphin"); m_view[PrimaryIdx] = 0; m_view[SecondaryIdx] = 0; + + KonqUndoManager::incRef(); + + connect(KonqUndoManager::self(), SIGNAL(undoAvailable(bool)), + this, SLOT(slotUndoAvailable(bool))); + connect(KonqUndoManager::self(), SIGNAL(undoTextChanged(const QString&)), + this, SLOT(slotUndoTextChanged(const QString&))); } DolphinMainWindow::~DolphinMainWindow() { + KonqUndoManager::decRef(); + qDeleteAll(m_fileGroupActions); m_fileGroupActions.clear(); @@ -274,16 +278,6 @@ void DolphinMainWindow::updateFilterBarAction(bool show) showFilterBarAction->setChecked(show); } -void DolphinMainWindow::redo() -{ - UndoManager::instance().redo(this); -} - -void DolphinMainWindow::undo() -{ - UndoManager::instance().undo(this); -} - void DolphinMainWindow::openNewMainWindow() { DolphinApplication::app()->createMainWindow()->show(); @@ -301,8 +295,8 @@ void DolphinMainWindow::copyDroppedItems() void DolphinMainWindow::linkDroppedItems() { - KIO::Job* job = KIO::link(m_droppedUrls, m_dropDestination); - addPendingUndoJob(job, DolphinCommand::Link, m_droppedUrls, m_dropDestination); + KonqOperations::copy(this, KonqOperations::LINK, m_droppedUrls, m_dropDestination); + m_undoOperations.append(KonqOperations::LINK); } void DolphinMainWindow::closeEvent(QCloseEvent* event) @@ -401,29 +395,26 @@ void DolphinMainWindow::createFolder() url = baseUrl; url.addPath(name); } - ok = KIO::NetAccess::mkdir(url, this); - // TODO: provide message type hint - if (ok) { + KonqOperations::mkdir(this, url); + + // TODO: is there a possability to check whether the mkdir operation + // has been successful? + //if (ok) { statusBar->setMessage(i18n("Created folder %1.",url.path()), DolphinStatusBar::OperationCompleted); - - DolphinCommand command(DolphinCommand::CreateFolder, KUrl::List(), url); - UndoManager::instance().addCommand(command); - } - else { - // Creating of the folder has been failed. Check whether the creating - // has been failed because a folder with the same name exists... - if (KIO::NetAccess::exists(url, true, this)) { - statusBar->setMessage(i18n("A folder named %1 already exists.",url.path()), - DolphinStatusBar::Error); - } - else { - statusBar->setMessage(i18n("Creating of folder %1 failed.",url.path()), - DolphinStatusBar::Error); - } - - } + //} + //else { + // // Creating of the folder has been failed. Check whether the creating + // // has been failed because a folder with the same name exists... + // if (KIO::NetAccess::exists(url, true, this)) { + // statusBar->setMessage(i18n("A folder named %1 already exists.",url.path()), + // DolphinStatusBar::Error); + // } + // else { + // statusBar->setMessage(i18n("Creating of folder %1 failed.",url.path()), + // DolphinStatusBar::Error); + // } } void DolphinMainWindow::createFile() @@ -515,8 +506,10 @@ void DolphinMainWindow::createFile() KUrl::List list; list.append(sourceUrl); - DolphinCommand command(DolphinCommand::CreateFile, list, destUrl); - UndoManager::instance().addCommand(command); + + // TODO: use the KonqUndoManager/KonqOperations instead. + //DolphinCommand command(DolphinCommand::CreateFile, list, destUrl); + //UndoManager::instance().addCommand(command); } else { @@ -534,9 +527,12 @@ void DolphinMainWindow::rename() void DolphinMainWindow::moveToTrash() { clearStatusBar(); - KUrl::List selectedUrls = m_activeView->selectedUrls(); - KIO::Job* job = KIO::trash(selectedUrls); - addPendingUndoJob(job, DolphinCommand::Trash, selectedUrls, m_activeView->url()); + const KUrl::List selectedUrls = m_activeView->selectedUrls(); + // TODO: per default a message box is opened which asks whether the item + // should really be moved to the trash. This does not make sense, as the + // action can be undone anyway by the user. + KonqOperations::del(this, KonqOperations::TRASH, selectedUrls); + m_undoOperations.append(KonqOperations::TRASH); } void DolphinMainWindow::deleteItems() @@ -609,6 +605,32 @@ void DolphinMainWindow::slotUndoAvailable(bool available) if (undoAction != 0) { undoAction->setEnabled(available); } + + if (available && (m_undoOperations.count() > 0)) { + const KonqOperations::Operation op = m_undoOperations.takeFirst(); + DolphinStatusBar* statusBar = m_activeView->statusBar(); + switch (op) { + case KonqOperations::COPY: + statusBar->setMessage(i18n("Copy operation completed."), + DolphinStatusBar::OperationCompleted); + break; + case KonqOperations::MOVE: + statusBar->setMessage(i18n("Move operation completed."), + DolphinStatusBar::OperationCompleted); + break; + case KonqOperations::LINK: + statusBar->setMessage(i18n("Link operation completed."), + DolphinStatusBar::OperationCompleted); + break; + case KonqOperations::TRASH: + statusBar->setMessage(i18n("Move to trash operation completed."), + DolphinStatusBar::OperationCompleted); + break; + default: + break; + } + + } } void DolphinMainWindow::slotUndoTextChanged(const QString& text) @@ -619,22 +641,6 @@ void DolphinMainWindow::slotUndoTextChanged(const QString& text) } } -void DolphinMainWindow::slotRedoAvailable(bool available) -{ - QAction* redoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Redo)); - if (redoAction != 0) { - redoAction->setEnabled(available); - } -} - -void DolphinMainWindow::slotRedoTextChanged(const QString& text) -{ - QAction* redoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Redo)); - if (redoAction != 0) { - redoAction->setText(text); - } -} - void DolphinMainWindow::cut() { QMimeData* mimeData = new QMimeData(); @@ -995,80 +1001,6 @@ void DolphinMainWindow::editSettings() dlg.exec(); } -void DolphinMainWindow::addUndoOperation(KJob* job) -{ - if (job->error() != 0) { - slotHandleJobError(job); - } - else { - const int id = job->progressId(); - - // set iterator to the executed command with the current id... - Q3ValueList::Iterator it = m_pendingUndoJobs.begin(); - const Q3ValueList::Iterator end = m_pendingUndoJobs.end(); - bool found = false; - while (!found && (it != end)) { - if ((*it).id == id) { - found = true; - } - else { - ++it; - } - } - - if (found) { - DolphinCommand command = (*it).command; - if (command.type() == DolphinCommand::Trash) { - // To be able to perform an undo for the 'Move to Trash' operation - // all source Urls must be updated with the trash Url. E. g. when moving - // a file "test.txt" and a second file "test.txt" to the trash, - // then the filenames in the trash are "0-test.txt" and "1-test.txt". - QMap metaData; - KIO::Job *kiojob = qobject_cast( job ); - if ( kiojob ) - { - metaData = kiojob->metaData(); - } - KUrl::List newSourceUrls; - - KUrl::List sourceUrls = command.source(); - KUrl::List::Iterator sourceIt = sourceUrls.begin(); - const KUrl::List::Iterator sourceEnd = sourceUrls.end(); - - while (sourceIt != sourceEnd) { - QMap::ConstIterator metaIt = metaData.find("trashUrl-" + (*sourceIt).path()); - if (metaIt != metaData.end()) { - newSourceUrls.append(KUrl(metaIt.value())); - } - ++sourceIt; - } - command.setSource(newSourceUrls); - } - - UndoManager::instance().addCommand(command); - m_pendingUndoJobs.erase(it); - - DolphinStatusBar* statusBar = m_activeView->statusBar(); - switch (command.type()) { - case DolphinCommand::Copy: - statusBar->setMessage(i18n("Copy operation completed."), - DolphinStatusBar::OperationCompleted); - break; - case DolphinCommand::Move: - statusBar->setMessage(i18n("Move operation completed."), - DolphinStatusBar::OperationCompleted); - break; - case DolphinCommand::Trash: - statusBar->setMessage(i18n("Move to trash operation completed."), - DolphinStatusBar::OperationCompleted); - break; - default: - break; - } - } - } -} - void DolphinMainWindow::init() { // Check whether Dolphin runs the first time. If yes then @@ -1197,22 +1129,9 @@ void DolphinMainWindow::setupActions() KStandardAction::quit(this, SLOT(quit()), actionCollection()); // setup 'Edit' menu - UndoManager& undoManager = UndoManager::instance(); - KStandardAction::undo(this, - SLOT(undo()), - actionCollection()); - connect(&undoManager, SIGNAL(undoAvailable(bool)), - this, SLOT(slotUndoAvailable(bool))); - connect(&undoManager, SIGNAL(undoTextChanged(const QString&)), - this, SLOT(slotUndoTextChanged(const QString&))); - - KStandardAction::redo(this, - SLOT(redo()), - actionCollection()); - connect(&undoManager, SIGNAL(redoAvailable(bool)), - this, SLOT(slotRedoAvailable(bool))); - connect(&undoManager, SIGNAL(redoTextChanged(const QString&)), - this, SLOT(slotRedoTextChanged(const QString&))); + KStandardAction::undo(KonqUndoManager::self(), + SLOT(undo()), + actionCollection()); KStandardAction::cut(this, SLOT(cut()), actionCollection()); KStandardAction::copy(this, SLOT(copy()), actionCollection()); @@ -1579,28 +1498,14 @@ void DolphinMainWindow::updateGoActions() void DolphinMainWindow::copyUrls(const KUrl::List& source, const KUrl& dest) { - KIO::Job* job = KIO::copy(source, dest); - addPendingUndoJob(job, DolphinCommand::Copy, source, dest); + KonqOperations::copy(this, KonqOperations::COPY, source, dest); + m_undoOperations.append(KonqOperations::COPY); } void DolphinMainWindow::moveUrls(const KUrl::List& source, const KUrl& dest) { - KIO::Job* job = KIO::move(source, dest); - addPendingUndoJob(job, DolphinCommand::Move, source, dest); -} - -void DolphinMainWindow::addPendingUndoJob(KIO::Job* job, - DolphinCommand::Type commandType, - const KUrl::List& source, - const KUrl& dest) -{ - connect(job, SIGNAL(result(KJob*)), - this, SLOT(addUndoOperation(KJob*))); - - UndoInfo undoInfo; - undoInfo.id = job->progressId(); - undoInfo.command = DolphinCommand(commandType, source, dest); - m_pendingUndoJobs.append(undoInfo); + KonqOperations::copy(this, KonqOperations::MOVE, source, dest); + m_undoOperations.append(KonqOperations::MOVE); } void DolphinMainWindow::clearStatusBar() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index c2beb202f..d87717692 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -22,13 +22,13 @@ #ifndef _DOLPHIN_MAINWINDOW_H_ #define _DOLPHIN_MAINWINDOW_H_ +#include "dolphinview.h" + #include #include +#include -#include - -#include "dolphinview.h" -#include "undomanager.h" // for DolphinCommand::Type +#include class KPrinter; class KUrl; @@ -173,15 +173,6 @@ private slots: /** Sets the text of the 'Undo' menu action to \a text. */ void slotUndoTextChanged(const QString& text); - /** - * Updates the state of the 'Redo' menu action dependent - * from the parameter \a available. - */ - void slotRedoAvailable(bool available); - - /** Sets the text of the 'Redo' menu action to \a text. */ - void slotRedoTextChanged(const QString& text); - /** * Copies all selected items to the clipboard and marks * the items as cutted. @@ -303,12 +294,6 @@ private slots: /** Opens the settings dialog for Dolphin. */ void editSettings(); - /** - * Adds the undo operation given by \a job - * to the UndoManager. - */ - void addUndoOperation(KJob* job); - /** Updates the state of all 'View' menu actions. */ void slotViewModeChanged(); @@ -339,12 +324,6 @@ private slots: /** Updates the state of the 'Show filter bar' menu action. */ void updateFilterBarAction(bool show); - /** Executes the redo operation (see UndoManager::Redo ()). */ - void redo(); - - /** Executes the undo operation (see UndoManager::Undo()). */ - void undo(); - /** Open a new main window. */ void openNewMainWindow(); @@ -381,10 +360,6 @@ private: void updateGoActions(); void copyUrls(const KUrl::List& source, const KUrl& dest); void moveUrls(const KUrl::List& source, const KUrl& dest); - void addPendingUndoJob(KIO::Job* job, - DolphinCommand::Type commandType, - const KUrl::List& source, - const KUrl& dest); void clearStatusBar(); /** @@ -413,21 +388,8 @@ private: }; DolphinView* m_view[SecondaryIdx + 1]; - /** - * Asynchronous operations like 'Move' and 'Copy' may only be added as undo - * operation after they have been finished successfully. When an asynchronous - * operation is started, it is added to a pending undo jobs list in the meantime. - * As soon as the job has been finished, the operation is added to the undo mangager. - * @see UndoManager - * @see DolphinMainWindow::addPendingUndoJob - * @see DolphinMainWindow::addUndoOperation - */ - struct UndoInfo - { - int id; - DolphinCommand command; - }; - Q3ValueList m_pendingUndoJobs; + /// remember pending undo operations until they are finished + QList m_undoOperations; /** Contains meta information for creating files. */ struct CreateFileEntry diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index cc22c1fd9..bf92b34f4 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -20,34 +20,35 @@ #include "dolphinview.h" +#include + #include -#include +#include // TODO #include #include #include #include #include -#include #include #include #include #include -#include +#include +#include -#include "urlnavigator.h" #include "dolphinstatusbar.h" #include "dolphinmainwindow.h" #include "dolphindirlister.h" #include "dolphinsortfilterproxymodel.h" -#include "viewproperties.h" #include "dolphindetailsview.h" #include "dolphiniconsview.h" #include "dolphincontextmenu.h" -#include "undomanager.h" -#include "renamedialog.h" -#include "progressindicator.h" #include "filterbar.h" +#include "progressindicator.h" +#include "renamedialog.h" +#include "urlnavigator.h" +#include "viewproperties.h" DolphinView::DolphinView(DolphinMainWindow *mainWindow, QWidget *parent, @@ -233,8 +234,10 @@ void DolphinView::renameSelectedItems() DolphinStatusBar::Error); } else { - UndoManager& undoMan = UndoManager::instance(); - undoMan.beginMacro(); + // TODO: check how this can be integrated into KonqUndoManager/KonqOperations + + //UndoManager& undoMan = UndoManager::instance(); + //undoMan.beginMacro(); assert(newName.contains('#')); @@ -268,8 +271,8 @@ void DolphinView::renameSelectedItems() else if (KIO::NetAccess::file_move(source, dest)) { // TODO: From the users point of view he executed one 'rename n files' operation, // but internally we store it as n 'rename 1 file' operations for the undo mechanism. - DolphinCommand command(DolphinCommand::Rename, source, dest); - undoMan.addCommand(command); + //DolphinCommand command(DolphinCommand::Rename, source, dest); + //undoMan.addCommand(command); } } @@ -278,7 +281,7 @@ void DolphinView::renameSelectedItems() delete progressIndicator; progressIndicator = 0; - undoMan.endMacro(); + //undoMan.endMacro(); } } else { @@ -566,15 +569,15 @@ void DolphinView::rename(const KUrl& source, const QString& newName) ok = KIO::NetAccess::file_move(source, dest); } + const QString destFileName = dest.fileName(); if (ok) { - m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.",source.fileName(), dest.fileName()), + m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.",source.fileName(), destFileName), DolphinStatusBar::OperationCompleted); - DolphinCommand command(DolphinCommand::Rename, source, dest); - UndoManager::instance().addCommand(command); + KonqOperations::rename(this, source, destFileName); } else { - m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.",source.fileName(), dest.fileName()), + m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.",source.fileName(), destFileName), DolphinStatusBar::Error); reload(); } diff --git a/src/undomanager.cpp b/src/undomanager.cpp deleted file mode 100644 index c4d4f2f87..000000000 --- a/src/undomanager.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/*************************************************************************** - * 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 -#include -#include -#include - -#include "dolphinmainwindow.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. - // - // KDE4TODO: QList doesn't require a default constructor iirc - so remove this -} - -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; - - QList::iterator it = m_history.begin(); - it += m_historyIndex; - if (m_recordMacro) { - DolphinCommand macroCommand = command; - macroCommand.m_macroIndex = m_macroCounter; - m_history.insert(it, macroCommand); - } - else { - m_history.insert(it, command); - } - - emit undoAvailable(true); - emit undoTextChanged(i18n("Undo: %1",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; -} - -// KDE4 TODO: consider switching to KCommandHistory (kdeui) for the command history, and to -// KonqCommandRecorder etc. from libkonq/konq_undo.* -void UndoManager::undo(DolphinMainWindow* mainWindow) -{ - if (m_recordMacro) { - endMacro(); - } - - if (m_historyIndex < 0) { - return; - } - - int progressCount = 0; - int macroCount = 1; - calcStepsCount(macroCount, progressCount); - - /* - * KDE4, ### TODO Only here to avoid possible crash - */ - ProgressIndicator progressIndicator(mainWindow, 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",commandText(m_history[m_historyIndex]))); - } - - if (m_historyIndex < static_cast(m_history.count()) - 1) { - emit redoAvailable(true); - emit redoTextChanged(i18n("Redo: %1",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(KUrl::AddTrailingSlash)); - - 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; - - progressIndicator.execOperation(); - } - break; - } - - case DolphinCommand::CreateFolder: - case DolphinCommand::CreateFile: { - KIO::NetAccess::del(command.destination(), mainWindow); - break; - } - } - - if (job != 0) { - // Execute the jobs in a synchronous manner and forward the progress - // information to the Dolphin statusbar. - connect(job, SIGNAL(percent(KJob*, unsigned long)), - this, SLOT(slotPercent(KJob*, unsigned long))); - KIO::NetAccess::synchronousRun(job, mainWindow); - } - - progressIndicator.execOperation(); - } -} - -void UndoManager::redo(DolphinMainWindow *mainWindow) -{ - 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); - - ProgressIndicator progressIndicator(mainWindow, 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",commandText(m_history[m_historyIndex + 1]))); - } - - emit undoAvailable(true); - emit undoTextChanged(i18n("Undo: %1",commandText(command))); - - 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, mainWindow); - ++it; - - progressIndicator.execOperation(); - } - break; - } - - case DolphinCommand::CreateFolder: { - KIO::NetAccess::mkdir(command.destination(), mainWindow); - break; - } - - case DolphinCommand::CreateFile: { - 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(KJob*, unsigned long)), - this, SLOT(slotPercent(KJob*, unsigned long))); - KIO::NetAccess::synchronousRun(job, mainWindow); - } - - ++m_historyIndex; - progressIndicator.execOperation(); - } - - --m_historyIndex; - -} - -UndoManager::UndoManager() : - m_recordMacro(false), - m_historyIndex(-1), - m_macroCounter(0) -{ -} - -UndoManager::~UndoManager() -{ -} - -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(KJob* /* 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() -{ - /* - * ### XXX, TODO, KDE4 make this work when switchting to KonqUndoManager - */ - //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" - - diff --git a/src/undomanager.h b/src/undomanager.h deleted file mode 100644 index 4f0b6682d..000000000 --- a/src/undomanager.h +++ /dev/null @@ -1,201 +0,0 @@ -/*************************************************************************** - * 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 * - ***************************************************************************/ - -#ifndef UNDOMANAGER_H -#define UNDOMANAGER_H - -#include -#include -#include - -#include -#include - -class DolphinMainWindow; - -/** - * @short Represents a file manager command which can be undone and redone. - * - * A command is specified by a type, a list of source Urls and a - * destination Url. - * - * Due to the fixed set of commands a file manager offers this class is - * a very simplified version of the classic command pattern. - * - * @see UndoManager - * @author Peter Penz - */ -class DolphinCommand -{ -public: - enum Type { - Copy, - Move, - Link, - Rename, - Trash, - CreateFolder, - CreateFile - }; - - DolphinCommand(); - DolphinCommand(Type type, const KUrl::List& source, const KUrl& dest); - ~DolphinCommand(); // non-virtual - - DolphinCommand& operator = (const DolphinCommand& command); - Type type() const { return m_type; } - void setSource(const KUrl::List source) { m_source = source; } - const KUrl::List& source() const { return m_source; } - const KUrl& destination() const { return m_dest; } - -private: - Type m_type; - int m_macroIndex; - KUrl::List m_source; - KUrl m_dest; - - friend class UndoManager; // allow to modify m_macroIndex -}; - -/** - * @short Stores all file manager commands which can be undone and redone. - * - * During the undo and redo operations a progress information is - * shown in the status bar. - * - * @author Peter Penz - */ -class UndoManager : public QObject // TODO switch to KonqUndoManager (multi-process, async, more robust on complex operations, no redo though) -{ - Q_OBJECT - -public: - static UndoManager& instance(); - - /** - * Adds the command \a command to the undo list. The command - * can be undone by invoking UndoManager::undo(). - */ - void addCommand(const DolphinCommand& command); - - /** - * Allows to summarize several commands into one macro, which - * can be undo in one stop by UndoManager::undo(). Example - * \code - * UndoManager& undoMan = UndoManager.instance(); - * undoMan.beginMacro(); - * undoMan.addCommand(...); - * undoMan.addCommand(...); - * undoMan.addCommand(...); - * undoMan.endMacro(); - * \endcode - * It is not allowed to do nested macro recordings. - */ - void beginMacro(); - - /** - * Marks the end of a macro command. See UndoManager::beginMacro() - * for sample code. - */ - void endMacro(); - -public slots: - /** - * Performs an undo operation on the last command which has - * been added by UndoManager::addCommand(). - * - * @param mainwindow The mainwindow where to show progress - */ - void undo(DolphinMainWindow* mainwindow); - - /** - * Performs a redo operation on the last command where an undo - * operation has been applied. - * - * @param mainwindow The mainwindow where to show progress - */ - void redo(DolphinMainWindow* mainwindow); - -signals: - /** - * Is emitted if whenever the availability state - * of the current undo operation changes. - */ - void undoAvailable(bool available); - - /** - * Is emitted whenever the text of the current - * undo operation changes - * (e. g. from 'Undo: Delete' to 'Undo: Copy') - */ - void undoTextChanged(const QString& text); - - /** - * Is emitted if whenever the availability state - * of the current redo operation changes. - */ - void redoAvailable(bool available); - - /** - * Is emitted whenever the text of the current - * redo operation changes - * (e. g. from 'Redo: Delete' to 'Redo: Copy') - */ - void redoTextChanged(const QString& text); - -protected: - UndoManager(); - virtual ~UndoManager(); - QString commandText(const DolphinCommand& command) const; - -private slots: - /** - * Slot for the percent information of the I/O slaves. - * Delegates the updating of the progress information - * to UndoManager::updateProgress(). - */ - void slotPercent(KJob* job, unsigned long percent); - - /** - * Updates the progress information of the statusbar - * by accessing the progress indicator information. - */ - void updateProgress(); - -private: - bool m_recordMacro; - int m_historyIndex; - int m_macroCounter; - QList m_history; - - /** - * Dependent from the current history index \a m_historyIndex - * the number of macro commands is written to the output - * parameter \a macroCount. The number of steps for all macro - * commands is written to the output parameter \a progressCount. - * - * Per default \a macroCount is 1 and \a progressCount represents - * the number of operations for one command. - */ - void calcStepsCount(int& macroCount, - int& progressCount); -}; - -#endif