From ced7cbd022b68c8dedd61b5d34d27b9c1296df15 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Thu, 7 Dec 2006 17:22:51 +0000 Subject: [PATCH] Use a KIO Job for applying the view properties recursively to sub directories. svn path=/trunk/playground/utils/dolphin/; revision=611325 --- src/CMakeLists.txt | 2 +- src/applyviewpropsjob.cpp | 95 +++++++++++++++ ...viewpropsapplier.h => applyviewpropsjob.h} | 80 ++++++------ src/viewpropertiesdialog.cpp | 19 +-- src/viewpropertiesdialog.h | 4 +- src/viewpropsapplier.cpp | 114 ------------------ src/viewpropsprogressinfo.cpp | 88 +++++++------- src/viewpropsprogressinfo.h | 23 ++-- 8 files changed, 198 insertions(+), 227 deletions(-) create mode 100644 src/applyviewpropsjob.cpp rename src/{viewpropsapplier.h => applyviewpropsjob.h} (50%) delete mode 100644 src/viewpropsapplier.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cdec284c8..f49424957 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,7 @@ set(dolphin_SRCS filterbar.cpp protocolcombo.cpp viewpropsprogressinfo.cpp - viewpropsapplier.cpp ) + applyviewpropsjob.cpp ) kde4_automoc(${dolphin_SRCS}) diff --git a/src/applyviewpropsjob.cpp b/src/applyviewpropsjob.cpp new file mode 100644 index 000000000..539c52ee1 --- /dev/null +++ b/src/applyviewpropsjob.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * * + * The code is based on kdelibs/kio/directorysizejob.* * + * (C) 2006 by David Faure * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "applyviewpropsjob.h" +#include "viewproperties.h" + +#include + +ApplyViewPropsJob::ApplyViewPropsJob(const KUrl& dir, + const ViewProperties& viewProps) : + KIO::Job(false), + m_viewProps(0), + m_progress(0), + m_dir(dir) +{ + m_viewProps = new ViewProperties(dir); + m_viewProps->setViewMode(viewProps.viewMode()); + m_viewProps->setShowHiddenFilesEnabled(viewProps.isShowHiddenFilesEnabled()); + m_viewProps->setSorting(viewProps.sorting()); + m_viewProps->setSortOrder(viewProps.sortOrder()); + + startNextJob(dir, viewProps); +} + +ApplyViewPropsJob::~ApplyViewPropsJob() +{ + delete m_viewProps; // the properties are written by the destructor + m_viewProps = 0; +} + +void ApplyViewPropsJob::processNextItem() +{ + emitResult(); +} + +void ApplyViewPropsJob::startNextJob(const KUrl& url, + const ViewProperties& viewProps) +{ + KIO::ListJob* listJob = KIO::listRecursive(url, false); + connect(listJob, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList&)), + SLOT(slotEntries(KIO::Job*, const KIO::UDSEntryList&))); + addSubjob(listJob); +} + +void ApplyViewPropsJob::slotEntries(KIO::Job*, const KIO::UDSEntryList& list) +{ + KIO::UDSEntryList::ConstIterator it = list.begin(); + const KIO::UDSEntryList::ConstIterator end = list.end(); + for (; it != end; ++it) { + const KIO::UDSEntry& entry = *it; + const QString name = entry.stringValue(KIO::UDS_NAME); + if ((name != ".") && (name != ".." ) && entry.isDir()) { + ++m_progress; + + KUrl url(m_dir); + url.addPath(name); + + ViewProperties props(url); + props.setViewMode(m_viewProps->viewMode()); + props.setShowHiddenFilesEnabled(m_viewProps->isShowHiddenFilesEnabled()); + props.setSorting(m_viewProps->sorting()); + props.setSortOrder(m_viewProps->sortOrder()); + } + } +} + +void ApplyViewPropsJob::slotResult(KJob* job) +{ + if (job->error()) { + setError( job->error() ); + setErrorText( job->errorText() ); + } + emitResult(); +} + +#include "applyviewpropsjob.moc" diff --git a/src/viewpropsapplier.h b/src/applyviewpropsjob.h similarity index 50% rename from src/viewpropsapplier.h rename to src/applyviewpropsjob.h index f564a4fe7..d14e1a787 100644 --- a/src/viewpropsapplier.h +++ b/src/applyviewpropsjob.h @@ -1,6 +1,8 @@ /*************************************************************************** - * Copyright (C) 2006 by Peter Penz * - * peter.penz@gmx.at * + * Copyright (C) 2006 by Peter Penz * + * * + * The code is based on kdelibs/kio/kio/directorysizejob.* * + * (C) 2006 by David Faure * * * * 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 * @@ -17,28 +19,37 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef VIEWPROPSAPPLIER_H -#define VIEWPROPSAPPLIER_H -#include -#include +#ifndef APPLYVIEWPROPSJOB_H +#define APPLYVIEWPROPSJOB_H + +#include +#include +#include -class KUrl; -class KDirLister; class ViewProperties; /** - * @brief Applies view properties recursively to sub directories. + * @brief Applies view properties recursively to directories. * - * BIG TODO: This class must be rewritten by inheriting from KJob (see - * also KDirSize as reference). The current implementation gets nuts - * for deep directory hierarchies, as an incredible number of parallel - * KDirLister instances will be created. + * Usage: + * \code + * KJob* job = new ApplyViewPropsJob(dir, viewProps); + * connect(job, SIGNAL(result(KJob*)), + * this, SLOT(slotResult(KJob*))); + * \endcode * - * Anyhow when writing this class I was not aware about the capabilities - * of the KJob class -> lessons learned ;-) + * To be able to show a progress of the operation, the following steps + * are recommended: + * - Use a DirectorySizeJob to count the number of directories. + * - Use a timer to show the current count of directories by invoking + * DirectorySizeJob::totalSubdirs() until the result signal is emitted. + * - Use the ApplyViewPropsJob. + * - Use a timer to show the progress by invoking ApplyViwePropsJob::progress(). + * In combination with the total directory count it is possible to show a + * progress bar now. */ -class ViewPropsApplier : public QObject +class ApplyViewPropsJob : public KIO::Job { Q_OBJECT @@ -49,35 +60,24 @@ public: * @param viewProps View properties for the directory \a dir including its * sub directories. */ - ViewPropsApplier(const KUrl& dir, - const ViewProperties* viewProps = 0); - virtual ~ViewPropsApplier(); + ApplyViewPropsJob(const KUrl& dir, const ViewProperties& viewProps); + virtual ~ApplyViewPropsJob(); + int progress() const { return m_progress; } -signals: - void progress(const KUrl& dir, int count); - void completed(); +private: + void startNextJob(const KUrl & url, const ViewProperties& viewProps); private slots: - void slotCompleted(const KUrl& dir); - void countSubDirs(); + virtual void slotResult(KJob* job); + void slotEntries(KIO::Job*, const KIO::UDSEntryList&); + void processNextItem(); private: - struct RootData { - int refCount; - const ViewProperties* viewProps; - ViewPropsApplier* rootApplier; - }; - - ViewPropsApplier(const KUrl& dir, - RootData* rootData); - - - void start(const KUrl& dir); - void emitProgress(const KUrl& dir, int count); - void emitCompleted(); - - RootData* m_rootData; - KDirLister* m_dirLister; + ViewProperties* m_viewProps; + KFileItemList m_lstItems; + int m_currentItem; + int m_progress; + KUrl m_dir; }; #endif diff --git a/src/viewpropertiesdialog.cpp b/src/viewpropertiesdialog.cpp index 0a4e8bd9d..de5c74a01 100644 --- a/src/viewpropertiesdialog.cpp +++ b/src/viewpropertiesdialog.cpp @@ -125,11 +125,11 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : connect(m_showHiddenFiles, SIGNAL(clicked()), this, SLOT(slotShowHiddenFilesChanged())); connect(m_applyToCurrentFolder, SIGNAL(clicked()), - this, SLOT(slotApplyToCurrentFolder())); + this, SLOT(markAsDirty())); connect(m_applyToSubFolders, SIGNAL(clicked()), - this, SLOT(slotApplyToSubFolders())); + this, SLOT(markAsDirty())); connect(m_applyToAllFolders, SIGNAL(clicked()), - this, SLOT(slotApplyToAllFolders())); + this, SLOT(markAsDirty())); connect(this, SIGNAL(okClicked()), this, SLOT(slotOk())); connect(this, SIGNAL(applyClicked()), this, SLOT(slotApply())); @@ -189,18 +189,7 @@ void ViewPropertiesDialog::slotShowHiddenFilesChanged() m_isDirty = true; } -void ViewPropertiesDialog::slotApplyToCurrentFolder() -{ - m_isDirty = true; -} - -void ViewPropertiesDialog::slotApplyToSubFolders() -{ - //m_viewProps->setValidForSubDirs(true); - m_isDirty = true; -} - -void ViewPropertiesDialog::slotApplyToAllFolders() +void ViewPropertiesDialog::markAsDirty() { m_isDirty = true; } diff --git a/src/viewpropertiesdialog.h b/src/viewpropertiesdialog.h index 79500a998..24accfed0 100644 --- a/src/viewpropertiesdialog.h +++ b/src/viewpropertiesdialog.h @@ -52,9 +52,7 @@ private slots: void slotSortingChanged(int index); void slotSortOrderChanged(int index); void slotShowHiddenFilesChanged(); - void slotApplyToCurrentFolder(); - void slotApplyToSubFolders(); - void slotApplyToAllFolders(); + void markAsDirty(); private: bool m_isDirty; diff --git a/src/viewpropsapplier.cpp b/src/viewpropsapplier.cpp deleted file mode 100644 index f9992a619..000000000 --- a/src/viewpropsapplier.cpp +++ /dev/null @@ -1,114 +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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "viewpropsapplier.h" -#include "viewproperties.h" - -#include -#include -#include - -ViewPropsApplier::ViewPropsApplier(const KUrl& dir, const ViewProperties* viewProps) -{ - m_rootData = new RootData(); - m_rootData->refCount = 0; - m_rootData->viewProps = viewProps; - m_rootData->rootApplier = this; - - start(dir); -} - -ViewPropsApplier::~ViewPropsApplier() -{ - assert(m_rootData != 0); - if (m_rootData->refCount == 0) { - m_rootData->rootApplier->emitCompleted(); - delete m_rootData; - m_rootData = 0; - } - - delete m_dirLister; - m_dirLister = 0; -} - -void ViewPropsApplier::slotCompleted(const KUrl& /*dir*/) -{ - QTimer::singleShot(0, this, SLOT(countSubDirs())); -} - -void ViewPropsApplier::countSubDirs() -{ - KFileItemList list = m_dirLister->items(); - const int dirCount = list.count(); - if (dirCount > 0) { - m_rootData->rootApplier->emitProgress(m_dirLister->url(), dirCount); - - KFileItemList::const_iterator end = list.end(); - for (KFileItemList::const_iterator it = list.begin(); it != end; ++it) { - assert((*it)->isDir()); - const KUrl& subDir = (*it)->url(); - if (m_rootData->viewProps != 0) { - // TODO: provide copy constructor in ViewProperties - ViewProperties props(subDir); - props.setViewMode(m_rootData->viewProps->viewMode()); - props.setShowHiddenFilesEnabled(m_rootData->viewProps->sorting()); - props.setSorting(m_rootData->viewProps->sorting()); - props.setSortOrder(m_rootData->viewProps->sortOrder()); - } - new ViewPropsApplier(subDir, m_rootData); - } - } - - --(m_rootData->refCount); - if ((m_rootData->refCount == 0) || (m_rootData->rootApplier != this)) { - delete this; - } -} - -ViewPropsApplier::ViewPropsApplier(const KUrl& dir, - RootData* rootData) -{ - m_rootData = rootData; - assert(m_rootData != 0); - start(dir); -} - -void ViewPropsApplier::start(const KUrl& dir) -{ - m_dirLister = new KDirLister(); - m_dirLister->setDirOnlyMode(true); - m_dirLister->setAutoUpdate(false); - connect(m_dirLister, SIGNAL(completed(const KUrl&)), - this, SLOT(slotCompleted(const KUrl&))); - m_dirLister->openUrl(dir); - ++(m_rootData->refCount); -} - -void ViewPropsApplier::emitProgress(const KUrl& dir, int count) -{ - emit progress(dir, count); -} - -void ViewPropsApplier::emitCompleted() -{ - emit completed(); -} - -#include "viewpropsapplier.moc" diff --git a/src/viewpropsprogressinfo.cpp b/src/viewpropsprogressinfo.cpp index 680a852fc..610a6912c 100644 --- a/src/viewpropsprogressinfo.cpp +++ b/src/viewpropsprogressinfo.cpp @@ -19,7 +19,7 @@ ***************************************************************************/ #include "viewpropsprogressinfo.h" -#include "viewpropsapplier.h" +#include "applyviewpropsjob.h" #include "viewproperties.h" #include @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -36,13 +36,12 @@ ViewPropsProgressInfo::ViewPropsProgressInfo(QWidget* parent, const KUrl& dir, const ViewProperties* viewProps) : KDialog(parent), - m_dirCount(0), - m_applyCount(0), m_dir(dir), m_viewProps(viewProps), m_label(0), m_progressBar(0), m_dirSizeJob(0), + m_applyViewPropsJob(0), m_timer(0) { setCaption(i18n("Applying view properties")); @@ -60,67 +59,68 @@ ViewPropsProgressInfo::ViewPropsProgressInfo(QWidget* parent, main->setLayout(topLayout); setMainWidget(main); - ViewPropsApplier* applier = new ViewPropsApplier(dir); - connect(applier, SIGNAL(progress(const KUrl&, int)), - this, SLOT(countDirs(const KUrl&, int))); - connect(applier, SIGNAL(completed()), - this, SLOT(applyViewProperties())); - - // TODO: use KDirSize job instead. Current issue: the signal - // 'result' is not emitted with kdelibs 2006-12-05. - - /*m_dirSizeJob = KDirSize::dirSizeJob(dir); + // Use the directory size job to count the number of directories first. This + // allows to give a progress indication for the user when applying the view + // properties later. + m_dirSizeJob = KIO::directorySize(dir); connect(m_dirSizeJob, SIGNAL(result(KJob*)), - this, SLOT(slotResult(KJob*))); + this, SLOT(applyViewProperties())); + // The directory size job cannot emit any progress signal, as it is not aware + // about the total number of directories. Therefor a timer is triggered, which + // periodically updates the current directory count. m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), - this, SLOT(updateDirCounter())); - m_timer->start(300);*/ + this, SLOT(updateProgress())); + m_timer->start(300); + + connect(this, SIGNAL(cancelClicked()), this, SLOT(cancelApplying())); } ViewPropsProgressInfo::~ViewPropsProgressInfo() { + m_timer->stop(); } -void ViewPropsProgressInfo::countDirs(const KUrl& /*dir*/, int count) +void ViewPropsProgressInfo::updateProgress() { - m_dirCount += count; - m_label->setText(i18n("Counting folders: %1", m_dirCount)); + if (m_dirSizeJob != 0) { + const int subdirs = m_dirSizeJob->totalSubdirs(); + m_label->setText(i18n("Counting folders: %1", subdirs)); + } + else { + assert(m_applyViewPropsJob != 0); + const int progress = m_applyViewPropsJob->progress(); + m_progressBar->setValue(progress); + } } -/*void ViewPropsProgressInfo::updateDirCounter() +void ViewPropsProgressInfo::applyViewProperties() { + if (m_dirSizeJob->error()) { + return; + } + const int subdirs = m_dirSizeJob->totalSubdirs(); - m_label->setText(i18n("Counting folders: %1", subdirs)); -} + m_label->setText(i18n("Folders: %1", subdirs)); + m_progressBar->setMaximum(subdirs); -void ViewPropsProgressInfo::slotResult(KJob*) -{ - QTimer::singleShot(0, this, SLOT(applyViewProperties())); -}*/ + m_dirSizeJob = 0; -void ViewPropsProgressInfo::applyViewProperties() -{ - //m_timer->stop(); - //const int subdirs = m_dirSizeJob->totalSubdirs(); - //m_label->setText(i18n("Folders: %1", subdirs)); - //m_progressBar->setMaximum(subdirs); - - m_label->setText(i18n("Folders: %1", m_dirCount)); - m_progressBar->setMaximum(m_dirCount); - - ViewPropsApplier* applier = new ViewPropsApplier(m_dir, m_viewProps); - connect(applier, SIGNAL(progress(const KUrl&, int)), - this, SLOT(showProgress(const KUrl&, int))); - connect(applier, SIGNAL(completed()), + m_applyViewPropsJob = new ApplyViewPropsJob(m_dir, *m_viewProps); + connect(m_applyViewPropsJob, SIGNAL(result(KJob*)), this, SLOT(close())); } -void ViewPropsProgressInfo::showProgress(const KUrl& url, int count) +void ViewPropsProgressInfo::cancelApplying() { - m_applyCount += count; - m_progressBar->setValue(m_applyCount); + if (m_dirSizeJob != 0) { + m_dirSizeJob->doKill(); + } + else { + assert(m_applyViewPropsJob != 0); + m_applyViewPropsJob->doKill(); + } } #include "viewpropsprogressinfo.moc" diff --git a/src/viewpropsprogressinfo.h b/src/viewpropsprogressinfo.h index 6d8b8f0c1..ac591e6bc 100644 --- a/src/viewpropsprogressinfo.h +++ b/src/viewpropsprogressinfo.h @@ -21,8 +21,9 @@ #define VIEWPROPSPROGRESSINFO_H #include +#include -class KDirSize; +class ApplyViewPropsJob; class KJob; class KUrl; class QLabel; @@ -31,8 +32,11 @@ class QTimer; class ViewProperties; /** - * @brief Shows the progress when applying view properties recursively to - * sub directories. + * @brief Shows the progress information when applying view properties + * recursively to a given directory. + * + * It is possible to cancel the applying. In this case the already applied + * view properties won't get reverted. */ class ViewPropsProgressInfo : public KDialog { @@ -53,20 +57,19 @@ public: virtual ~ViewPropsProgressInfo(); private slots: - void countDirs(const KUrl& dir, int count); - //void updateDirCounter(); - //void slotResult(KJob* job); + void updateProgress(); void applyViewProperties(); - void showProgress(const KUrl& url, int count); + void cancelApplying(); private: - int m_dirCount; - int m_applyCount; const KUrl& m_dir; const ViewProperties* m_viewProps; + QLabel* m_label; QProgressBar* m_progressBar; - KDirSize* m_dirSizeJob; + + KIO::DirectorySizeJob* m_dirSizeJob; + ApplyViewPropsJob* m_applyViewPropsJob; QTimer* m_timer; }; -- 2.47.3