[SCM] Kaboom - Debian KDE 3->4 migration tool branch, master, updated. master/0.9.1-29-g25e0ba2

George Kiagiadakis gkiagia-guest at alioth.debian.org
Sat Apr 4 15:11:38 UTC 2009


The following commit has been merged in the master branch:
commit 25e0ba2dfa323ae97ea411a75d101867fc74ce7c
Author: George Kiagiadakis <gkiagia at users.sourceforge.net>
Date:   Sat Apr 4 18:07:31 2009 +0300

    Don't fail if errors have occured.

diff --git a/choicepage.cpp b/choicepage.cpp
index 4f50420..a59d459 100644
--- a/choicepage.cpp
+++ b/choicepage.cpp
@@ -18,6 +18,7 @@
 */
 #include "choicepage.h"
 #include "diroperations/diroperations.h"
+#include "diroperations/recursivedirjob.h"
 #include "richradiobutton.h"
 #include "diroperations/progresswidget.h"
 #include "kaboomsettings.h"
@@ -250,12 +251,14 @@ void ChoicePage::checkSpaceForBackup()
 
   quint64 dirsize = -1;
   quint64 freespace = DirOperations::freeDirSpace(QDir::homePath());
-  try {
-      dirsize = DirOperations::calculateDirSize(
-                    KaboomSettings::instance().kdehomeDir().canonicalPath(),
-                    d->progresswidget
-                );
-  } catch (const DirOperations::Exception&) {}
+  {
+      RecursiveDirJob *job = RecursiveDirJob::calculateDirSize(
+                                KaboomSettings::instance().kdehomeDir().canonicalPath()
+                            );
+      job->synchronousRun(d->progresswidget);
+      dirsize = qvariant_cast<quint64>(job->result());
+      delete job;
+  }
 
   if(dirsize > freespace)
   {
diff --git a/diroperations/diroperations.cpp b/diroperations/diroperations.cpp
index aa25028..6dd2d4f 100644
--- a/diroperations/diroperations.cpp
+++ b/diroperations/diroperations.cpp
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2007-2009  George Kiagiadakis <gkiagia at users.sourceforge.net>
+    Copyright (C) 2009 George Kiagiadakis <gkiagia at users.sourceforge.net>
     Copyright (C) 2009 Sune Vuorela <sune at vuorela.dk>
 
     This library is free software; you can redistribute it and/or modify
@@ -16,11 +16,9 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "diroperations.h"
-#include "recursivedirjob.h"
 #include <QtCore/QFile>
-#include <QtCore/QEventLoop>
-#include <QtCore/QVariant>
 #include <QtCore/QDebug>
+#include <QtCore/QCoreApplication>
 #include <climits> //for PATH_MAX
 #include <unistd.h> //for readlink()
 #define _FILE_OFFSET_BITS 64
@@ -28,20 +26,6 @@
 
 namespace DirOperations {
 
-QString Exception::what() const
-{
-    switch (m_type) {
-        case OperationCanceled: return tr("User canceled the operation");
-        case AccessDenied: return tr("Access was denied to the file or directory \"%1\"").arg(m_info);
-        case NoSuchFileOrDirectory: return tr("\"%1\": No such file or directory").arg(m_info);
-        case FileOrDirectoryExists: return tr("\"%1\" already exists").arg(m_info);
-        case CopyFail: return tr("Could not copy \"%1\"").arg(m_info);
-        case MkdirFail: return tr("Could not create directory \"%1\"").arg(m_info);
-        case RmFail: return tr("Could not remove \"%1\"").arg(m_info);
-        default: return tr("Unknown error");
-    }
-}
-
 QString bytesToString(quint64 bytes)
 {
     if ( bytes > (1<<30) )
@@ -96,48 +80,4 @@ quint64 totalPartitionSize(const QString & dir)
 
 }
 
-quint64 calculateDirSize(const QString & dir, ProgressDialogInterface *pd)
-{
-    QEventLoop loop;
-    RecursiveDirJob *j = RecursiveDirJob::calculateDirSize(dir);
-    j->setProgressDialogInterface(pd);
-    //we will start the thread as soon as we are in the event loop, because if the thread
-    //finishes too early (before the event loop starts), quit() will not work and we will stay
-    //in this event loop forever.
-    QMetaObject::invokeMethod(j, "start", Qt::QueuedConnection);
-    QObject::connect(j, SIGNAL(finished()), &loop, SLOT(quit()) );
-    loop.exec();
-    j->deleteLater();
-    if ( j->hasError() )
-        throw j->lastError();
-    return qvariant_cast<quint64>(j->result());
-}
-
-void recursiveCpDir(const QString & sourcePath, const QString & destPath,
-                    CopyOptions options, ProgressDialogInterface *pd)
-{
-    QEventLoop loop;
-    RecursiveDirJob *j = RecursiveDirJob::recursiveCpDir(sourcePath, destPath, options);
-    j->setProgressDialogInterface(pd);
-    QMetaObject::invokeMethod(j, "start", Qt::QueuedConnection);
-    QObject::connect(j, SIGNAL(finished()), &loop, SLOT(quit()) );
-    loop.exec();
-    j->deleteLater();
-    if ( j->hasError() )
-        throw j->lastError();
-}
-
-void recursiveRmDir(const QString & dir, ProgressDialogInterface *pd)
-{
-    QEventLoop loop;
-    RecursiveDirJob *j = RecursiveDirJob::recursiveRmDir(dir);
-    j->setProgressDialogInterface(pd);
-    QMetaObject::invokeMethod(j, "start", Qt::QueuedConnection);
-    QObject::connect(j, SIGNAL(finished()), &loop, SLOT(quit()) );
-    loop.exec();
-    j->deleteLater();
-    if ( j->hasError() )
-        throw j->lastError();
-}
-
 } //namespace DirOperations
diff --git a/diroperations/diroperations.h b/diroperations/diroperations.h
index 28abdcc..6fa4a69 100644
--- a/diroperations/diroperations.h
+++ b/diroperations/diroperations.h
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2007-2009  George Kiagiadakis <gkiagia at users.sourceforge.net>
+    Copyright (C) 2009 George Kiagiadakis <gkiagia at users.sourceforge.net>
     Copyright (C) 2009 Sune Vuorela <sune at vuorela.dk>
 
     This library is free software; you can redistribute it and/or modify
@@ -19,43 +19,9 @@
 #define DIROPERATIONS_H
 
 #include <QtCore/QString>
-#include <QtCore/QMetaType>
-#include <QtCore/QCoreApplication>
 
 namespace DirOperations {
 
-    class ProgressDialogInterface
-    {
-    public:
-        virtual ~ProgressDialogInterface() {}
-
-        virtual void setLabelText(const QString & text) = 0;
-        virtual void setMaximum(quint64 max) = 0;
-        virtual void setValue(quint64 value) = 0;
-    };
-
-    class Exception
-    {
-        Q_DECLARE_TR_FUNCTIONS(Exception)
-    public:
-        enum Type { OperationCanceled, AccessDenied, NoSuchFileOrDirectory,
-                    FileOrDirectoryExists, CopyFail, MkdirFail, RmFail, NoError };
-
-        explicit Exception() : m_type(NoError) {}
-        explicit Exception(Type type, const QString & extraInfo = QString())
-                    : m_type(type), m_info(extraInfo) {}
-
-        Type type() const { return m_type; }
-        QString what() const;
-
-    private:
-        Type m_type;
-        QString m_info;
-    };
-
-    enum CopyOption { NoOptions = 0x0, RemoveDestination = 0x1, OverWrite = 0x2 };
-    Q_DECLARE_FLAGS(CopyOptions, CopyOption);
-
     /*! Returns a string that describes the number of bytes given in a human-friendly way.
      * (i.e. suffixed with KiB, MiB, GiB etc...)
      */
@@ -76,25 +42,6 @@ namespace DirOperations {
     /*! Calculates the total space of a partition */
     quint64 totalPartitionSize(const QString & dir);
 
-    /*! Calculates the size of a directory. Works like "du -hs". */
-    quint64 calculateDirSize(const QString & dir, ProgressDialogInterface *pd = 0);
-
-    /*! Copies directory \a sourcePath and all of its contents
-     * to directory \a destPath . Works like "cp -r".
-     * \a options can be the following:
-     * \li NoOptions - Nothing special happens
-     * \li RemoveDestination - It removes the destination directory before trying to copy.
-     * \li OverWrite - If a file exists both in \a sourcePath and in \a destPath, the the file will be overwritten.
-     */
-    void recursiveCpDir(const QString & sourcePath, const QString & destPath,
-                        CopyOptions options = NoOptions, ProgressDialogInterface *pd = 0);
-
-    /*! Deletes directory \a dir and all of its contents. Works like "rm -r". */
-    void recursiveRmDir(const QString & dir, ProgressDialogInterface *pd = 0);
-
 } //namespace DirOperations
 
-Q_DECLARE_OPERATORS_FOR_FLAGS(DirOperations::CopyOptions)
-Q_DECLARE_METATYPE(DirOperations::CopyOptions)
-
 #endif
diff --git a/diroperations/progresswidget.h b/diroperations/progresswidget.h
index 090b1fa..2de13c7 100644
--- a/diroperations/progresswidget.h
+++ b/diroperations/progresswidget.h
@@ -17,12 +17,12 @@
 #ifndef PROGRESSWIDGET_H
 #define PROGRESSWIDGET_H
 
-#include "diroperations.h"
+#include "recursivedirjob.h"
 #include <QWidget>
 class QLabel;
 class QProgressBar;
 
-class ProgressWidget : public QWidget, public DirOperations::ProgressDialogInterface
+class ProgressWidget : public QWidget, public RecursiveDirJob::ProgressDialogInterface
 {
 public:
     ProgressWidget(QWidget *parent = 0);
diff --git a/diroperations/recursivedirjob.cpp b/diroperations/recursivedirjob.cpp
index 0f11e8b..c0ca8f7 100644
--- a/diroperations/recursivedirjob.cpp
+++ b/diroperations/recursivedirjob.cpp
@@ -19,6 +19,9 @@
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QStack>
+#include <QtCore/QList>
+#include <QtCore/QEventLoop>
+#include <QtCore/QVariant>
 #include <QtCore/QDebug>
 
 #include <cstdio> //for perror()
@@ -29,14 +32,26 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-using namespace DirOperations;
+QString RecursiveDirJob::Error::message() const
+{
+    switch (m_type) {
+        case OperationCanceled: return tr("User canceled the operation");
+        case AccessDenied: return tr("Access was denied to the file or directory \"%1\"").arg(m_info);
+        case NoSuchFileOrDirectory: return tr("\"%1\": No such file or directory").arg(m_info);
+        case FileOrDirectoryExists: return tr("\"%1\" already exists").arg(m_info);
+        case CopyFail: return tr("Could not copy \"%1\"").arg(m_info);
+        case MkdirFail: return tr("Could not create directory \"%1\"").arg(m_info);
+        case RmFail: return tr("Could not remove \"%1\"").arg(m_info);
+        default: return tr("Unknown error");
+    }
+}
 
 struct RecursiveDirJob::Private
 {
     RecursiveDirJob::JobType m_jobType;
     QVariantList m_args;
     QVariant m_result;
-    Exception m_exception;
+    QList<Error> m_exceptions;
 };
 
 //static
@@ -61,12 +76,18 @@ RecursiveDirJob* RecursiveDirJob::recursiveRmDir(const QString & dir)
 
 bool RecursiveDirJob::hasError() const
 {
-    return (isFinished()) ? (d->m_exception.type() != Exception::NoError) : false;
+    return (isFinished()) ? (!d->m_exceptions.isEmpty()) : false;
+}
+
+QList<RecursiveDirJob::Error> RecursiveDirJob::errors() const
+{
+    return (isFinished()) ? d->m_exceptions : QList<Error>();
 }
 
-Exception RecursiveDirJob::lastError() const
+void RecursiveDirJob::slotErrorOccured(RecursiveDirJob::Error e)
 {
-    return (isFinished()) ? d->m_exception : Exception();
+    d->m_exceptions.append(e);
+    emit errorOccured(e.message());
 }
 
 QVariant RecursiveDirJob::result() const
@@ -79,6 +100,20 @@ void RecursiveDirJob::setProgressDialogInterface(ProgressDialogInterface *pd)
     m_pd = pd;
 }
 
+void RecursiveDirJob::synchronousRun(ProgressDialogInterface *pd)
+{
+    QEventLoop loop;
+    if (pd) {
+        setProgressDialogInterface(pd);
+    }
+    //we will start the thread as soon as we are in the event loop, because if the thread
+    //finishes too early (before the event loop starts), quit() will not work and we will stay
+    //in this event loop forever.
+    QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
+    QObject::connect(this, SIGNAL(finished()), &loop, SLOT(quit()) );
+    loop.exec();
+}
+
 RecursiveDirJob::RecursiveDirJob(JobType jtype, const QVariantList & arguments)
     : QThread(), d(new Private), m_pd(NULL)
 {
@@ -102,23 +137,23 @@ void RecursiveDirJob::run()
     connect(&helper, SIGNAL(setLabelText(QString)),
             this, SLOT(setLabelText(QString)), Qt::QueuedConnection);
 
-    try {
-        switch( d->m_jobType ) {
-            case CalculateDirSize:
-                d->m_result = helper.calculateDirSize(d->m_args[0].toString());
-                break;
-            case CpDir:
-                helper.recursiveCpDir(d->m_args[0].toString(), d->m_args[1].toString(),
-                                        d->m_args[2].value<CopyOptions>());
-                break;
-            case RmDir:
-                helper.recursiveRmDir(d->m_args[0].toString());
-                break;
-            default:
-                Q_ASSERT(false);
-        }
-    } catch(const Exception & e) {
-        d->m_exception = e;
+    qRegisterMetaType<RecursiveDirJob::Error>();
+    connect(&helper, SIGNAL(errorOccured(RecursiveDirJob::Error)),
+            this, SLOT(slotErrorOccured(RecursiveDirJob::Error)), Qt::QueuedConnection);
+
+    switch( d->m_jobType ) {
+        case CalculateDirSize:
+            d->m_result = helper.calculateDirSize(d->m_args[0].toString());
+            break;
+        case CpDir:
+            helper.recursiveCpDir(d->m_args[0].toString(), d->m_args[1].toString(),
+                                    d->m_args[2].value<CopyOptions>());
+            break;
+        case RmDir:
+            helper.recursiveRmDir(d->m_args[0].toString());
+            break;
+        default:
+            Q_ASSERT(false);
     }
 }
 
@@ -140,8 +175,10 @@ static const QDir::Filters dirFilters = QDir::AllEntries | QDir::NoDotAndDotDot
 quint64 RecursiveDirJobHelper::calculateDirSize(const QString & dir)
 {
     QDir currentDir(dir);
-    if ( !currentDir.exists() )
-        throw Exception(Exception::NoSuchFileOrDirectory, dir);
+    if ( !currentDir.exists() ) {
+        emit errorOccured(Error(Error::NoSuchFileOrDirectory, dir));
+        return 0;
+    }
 
     QFileInfoList currentList = currentDir.entryInfoList(dirFilters);
     QFileInfo currentItem;
@@ -161,15 +198,17 @@ quint64 RecursiveDirJobHelper::calculateDirSize(const QString & dir)
             totalSize += stat_size(currentItem.absoluteFilePath());
 
             if ( currentItem.isDir() && !currentItem.isSymLink() ) {
-                if ( !currentDir.cd(currentItem.fileName()) )
-                    throw Exception(Exception::AccessDenied, currentItem.absoluteFilePath());
-                stack.push(currentList);
-                currentList = currentDir.entryInfoList(dirFilters);
+                if ( !currentDir.cd(currentItem.fileName()) ) {
+                    emit errorOccured(Error(Error::AccessDenied, currentItem.absoluteFilePath()));
+                } else {
+                    stack.push(currentList);
+                    currentList = currentDir.entryInfoList(dirFilters);
+                }
             }
 
             if ( m_reportProgress && (++refreshCounter % 100 == 0) )
                 emit setLabelText( tr("Calculating the size of \"%1\"... %2")
-                                    .arg(dir).arg(bytesToString(totalSize)) );
+                                    .arg(dir).arg(DirOperations::bytesToString(totalSize)) );
 
         } else { // list is empty
             if ( !stack.isEmpty() ){
@@ -185,18 +224,23 @@ quint64 RecursiveDirJobHelper::calculateDirSize(const QString & dir)
     return totalSize;
 }
 
-void RecursiveDirJobHelper::recursiveCpDir(const QString & sourcePath, const QString & destPath, CopyOptions options)
+void RecursiveDirJobHelper::recursiveCpDir(const QString & sourcePath, const QString & destPath,
+                                            RecursiveDirJob::CopyOptions options)
 {
     QDir source(sourcePath);
-    if ( !source.exists() )
-        throw Exception(Exception::NoSuchFileOrDirectory, sourcePath);
+    if ( !source.exists() ) {
+        emit errorOccured(Error(Error::NoSuchFileOrDirectory, sourcePath));
+        return;
+    }
 
     QDir dest(destPath);
     if ( dest.exists() ) {
-        if ( options & DirOperations::RemoveDestination )
+        if ( options & RecursiveDirJob::RemoveDestination )
             recursiveRmDir(destPath);
-        else if ( !(options & DirOperations::OverWrite) )
-            throw Exception(Exception::FileOrDirectoryExists, destPath);
+        else if ( !(options & RecursiveDirJob::OverWrite) ) {
+            emit errorOccured(Error(Error::FileOrDirectoryExists, destPath));
+            return;
+        }
     }
 
     dest.mkdir(dest.absolutePath());
@@ -231,39 +275,47 @@ void RecursiveDirJobHelper::recursiveCpDir(const QString & sourcePath, const QSt
 
             if ( currentItem.isSymLink() )
             {
-                if ( options & OverWrite ) {
+                if ( options & RecursiveDirJob::OverWrite ) {
                     if ( QFile::exists(dest.absoluteFilePath(currentName)) &&
                          !QFile::remove(dest.absoluteFilePath(currentName)) )
-                        throw Exception(Exception::RmFail, dest.absoluteFilePath(currentName));
+                        emit errorOccured(Error(Error::RmFail, dest.absoluteFilePath(currentName)));
                 }
-                if ( !QFile::link( relativeSymLinkTarget(source.absoluteFilePath(currentName)),
+                if ( !QFile::link( DirOperations::relativeSymLinkTarget(source.absoluteFilePath(currentName)),
                                     dest.absoluteFilePath(currentName) ) )
-                    throw Exception(Exception::CopyFail, source.absoluteFilePath(currentName));
+                    emit errorOccured(Error(Error::CopyFail, source.absoluteFilePath(currentName)));
             }
             else if ( currentItem.isDir() )
             {
-                if ( !source.cd(currentName) )
-                    throw Exception(Exception::AccessDenied, source.absoluteFilePath(currentName));
-                if ( !dest.cd(currentName) ) {
+                bool ok = false;
+                if ( !(ok = source.cd(currentName)) ) {
+                    emit errorOccured(Error(Error::AccessDenied, source.absoluteFilePath(currentName)));
+                }
+                if ( ok && !dest.cd(currentName) ) {
                     //if the target dir doesn't exist, create it and try again.
                     if ( !dest.mkdir(currentName) )
-                        throw Exception(Exception::MkdirFail, dest.absoluteFilePath(currentName));
-                    if ( !dest.cd(currentName) )
-                        throw Exception(Exception::AccessDenied, dest.absoluteFilePath(currentName)); //quite impossible
+                        emit errorOccured(Error(Error::MkdirFail, dest.absoluteFilePath(currentName)));
+                    if ( !dest.cd(currentName) ) {
+                         //quite impossible to happen
+                        emit errorOccured(Error(Error::AccessDenied, dest.absoluteFilePath(currentName)));
+                        ok = false;
+                        source.cdUp(); //revert the state of source, as we are not going to copy this dir.
+                    }
                 }
 
-                stack.push(currentList);
-                currentList = source.entryInfoList(dirFilters);
+                if (ok) {
+                    stack.push(currentList);
+                    currentList = source.entryInfoList(dirFilters);
+                }
             }
             else if ( currentItem.isFile() )
             {
-                if ( options & OverWrite ) {
+                if ( options & RecursiveDirJob::OverWrite ) {
                     if ( QFile::exists(dest.absoluteFilePath(currentName)) &&
                          !QFile::remove(dest.absoluteFilePath(currentName)) )
-                        throw Exception(Exception::RmFail, dest.absoluteFilePath(currentName));
+                        emit errorOccured(Error(Error::RmFail, dest.absoluteFilePath(currentName)));
                 }
                 if ( !QFile::copy( source.absoluteFilePath(currentName), dest.absoluteFilePath(currentName) ) )
-                    throw Exception(Exception::CopyFail, source.absoluteFilePath(currentName));
+                    emit errorOccured(Error(Error::CopyFail, source.absoluteFilePath(currentName)));
             }
             else
             {
@@ -337,15 +389,17 @@ void RecursiveDirJobHelper::recursiveRmDir(const QString & dir)
 
             if ( currentItem.isDir() && !currentItem.isSymLink() )
             {
-                if ( !currentDir.cd(currentItem.fileName()) )
-                    throw Exception(Exception::AccessDenied, currentItem.absoluteFilePath());
-                stack.push(currentList);
-                currentList = currentDir.entryInfoList(dirFilters);
+                if ( !currentDir.cd(currentItem.fileName()) ) {
+                    emit errorOccured(Error(Error::AccessDenied, currentItem.absoluteFilePath()));
+                } else {
+                    stack.push(currentList);
+                    currentList = currentDir.entryInfoList(dirFilters);
+                }
             }
             else
             {
                 if ( !currentDir.remove(currentItem.fileName()) )
-                    throw Exception(Exception::RmFail, currentItem.absoluteFilePath());
+                    emit errorOccured(Error(Error::RmFail, currentItem.absoluteFilePath()));
             }
         }
         else // list is empty
@@ -361,7 +415,7 @@ void RecursiveDirJobHelper::recursiveRmDir(const QString & dir)
             currentDir.cdUp();
 
             if ( !currentDir.rmdir(tmpname) )
-                throw Exception(Exception::RmFail, currentDir.absoluteFilePath(tmpname));
+                emit errorOccured(Error(Error::RmFail, currentDir.absoluteFilePath(tmpname)));
 
             if ( quit )
                 break;
diff --git a/diroperations/recursivedirjob.h b/diroperations/recursivedirjob.h
index b67740a..df3913a 100644
--- a/diroperations/recursivedirjob.h
+++ b/diroperations/recursivedirjob.h
@@ -20,24 +20,75 @@
 #include "diroperations.h"
 #include <QtCore/QThread>
 #include <QtCore/QVariant>
+#include <QtCore/QMetaType>
+#include <QtCore/QCoreApplication> //for Q_DECLARE_TR_FUNCTIONS
 
 class RecursiveDirJob : public QThread
 {
     Q_OBJECT
 public:
+
+    class ProgressDialogInterface
+    {
+    public:
+        virtual ~ProgressDialogInterface() {}
+
+        virtual void setLabelText(const QString & text) = 0;
+        virtual void setMaximum(quint64 max) = 0;
+        virtual void setValue(quint64 value) = 0;
+    };
+
+    class Error
+    {
+        Q_DECLARE_TR_FUNCTIONS(Error)
+    public:
+        enum Type { OperationCanceled, AccessDenied, NoSuchFileOrDirectory,
+                    FileOrDirectoryExists, CopyFail, MkdirFail, RmFail, NoError };
+
+        explicit Error() : m_type(NoError) {}
+        explicit Error(Type type, const QString & extraInfo = QString())
+                    : m_type(type), m_info(extraInfo) {}
+
+        Type type() const { return m_type; }
+        QString message() const;
+
+    private:
+        Type m_type;
+        QString m_info;
+    };
+
+    enum CopyOption { NoOptions = 0x0, RemoveDestination = 0x1, OverWrite = 0x2 };
+    Q_DECLARE_FLAGS(CopyOptions, CopyOption);
+
     virtual ~RecursiveDirJob();
 
+    /*! Calculates the size of a directory. Works like "du -hs". */
     static RecursiveDirJob* calculateDirSize(const QString & dir);
+
+    /*! Deletes directory \a dir and all of its contents. Works like "rm -r". */
     static RecursiveDirJob* recursiveRmDir(const QString & dir);
+
+    /*! Copies directory \a sourcePath and all of its contents
+     * to directory \a destPath . Works like "cp -r".
+     * \a options can be the following:
+     * \li NoOptions - Nothing special happens
+     * \li RemoveDestination - It removes the destination directory before trying to copy.
+     * \li OverWrite - If a file exists both in \a sourcePath and in \a destPath, the the file will be overwritten.
+     */
     static RecursiveDirJob* recursiveCpDir(const QString & sourcePath, const QString & destPath,
-                                           DirOperations::CopyOptions options = DirOperations::NoOptions);
+                                           CopyOptions options = NoOptions);
 
-    void setProgressDialogInterface(DirOperations::ProgressDialogInterface *pd);
+    void setProgressDialogInterface(ProgressDialogInterface *pd);
 
     bool hasError() const;
-    DirOperations::Exception lastError() const;
+    QList<Error> errors() const;
     QVariant result() const;
 
+    void synchronousRun(ProgressDialogInterface *pd = NULL);
+
+signals:
+    void errorOccured(const QString & errorMessage);
+
 protected:
     enum JobType { CalculateDirSize, CpDir, RmDir };
     RecursiveDirJob(JobType jtype, const QVariantList & arguments);
@@ -47,12 +98,19 @@ protected:
 private:
     struct Private;
     Private *const d;
-    DirOperations::ProgressDialogInterface *m_pd;
+    ProgressDialogInterface *m_pd;
 
     //these will be called in the main thread.
     Q_PRIVATE_SLOT(m_pd, void setValue(quint64));
     Q_PRIVATE_SLOT(m_pd, void setMaximum(quint64));
     Q_PRIVATE_SLOT(m_pd, void setLabelText(QString));
+
+private slots:
+    void slotErrorOccured(RecursiveDirJob::Error e);
 };
 
+Q_DECLARE_METATYPE(RecursiveDirJob::Error)
+Q_DECLARE_OPERATORS_FOR_FLAGS(RecursiveDirJob::CopyOptions)
+Q_DECLARE_METATYPE(RecursiveDirJob::CopyOptions)
+
 #endif
diff --git a/diroperations/recursivedirjob_p.h b/diroperations/recursivedirjob_p.h
index 105652f..886ed60 100644
--- a/diroperations/recursivedirjob_p.h
+++ b/diroperations/recursivedirjob_p.h
@@ -23,18 +23,20 @@ class RecursiveDirJobHelper : public QObject
 {
     Q_OBJECT
 public:
+    typedef RecursiveDirJob::Error Error;
     RecursiveDirJobHelper(bool reportProgress, QObject *parent = 0)
         : QObject(parent), m_reportProgress(reportProgress) {}
 
     quint64 calculateDirSize(const QString & dir);
     void recursiveCpDir(const QString & sourcePath, const QString & destPath,
-                        DirOperations::CopyOptions options);
+                        RecursiveDirJob::CopyOptions options);
     void recursiveRmDir(const QString & dir);
 
 signals:
     void setValue(quint64 value);
     void setMaximum(quint64 maxValue);
     void setLabelText(QString text);
+    void errorOccured(RecursiveDirJob::Error e);
 
 private:
     bool m_reportProgress;
diff --git a/migrationpage.cpp b/migrationpage.cpp
index a39f4d9..212ad9c 100644
--- a/migrationpage.cpp
+++ b/migrationpage.cpp
@@ -18,7 +18,7 @@
 #include "migrationpage.h"
 #include "choicepage.h"
 #include "migrationpage_p.h"
-#include "diroperations/diroperations.h"
+#include "diroperations/recursivedirjob.h"
 #include "kaboomsettings.h"
 #include "migrationtool.h"
 
@@ -40,9 +40,7 @@ MigrationPagePrivate::MigrationPagePrivate(MigrationPage* parent)
   start->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
   start->setMinimumSize(start->minimumSizeHint().width()+30, start->minimumSizeHint().height()+10);
 
-  error = new QLabel;
-  error->setWordWrap(true);
-  error->setAlignment(Qt::AlignJustify);
+  error = new QTextBrowser;
   QPalette pal = error->palette();
   pal.setColor(QPalette::Text, Qt::red);
   error->setPalette(pal);
@@ -113,66 +111,67 @@ void MigrationPagePrivate::doMagic()
   {
     if(KaboomSettings::instance().kdehomeDir().exists())
     {
-      try
-      {
-        DirOperations::recursiveCpDir(KaboomSettings::instance().kdehomeDir().canonicalPath(),
-                                      KaboomSettings::instance().kde3backupDir().path(),
-                                      DirOperations::RemoveDestination, progress);
-      }
-      catch (DirOperations::Exception &e)
-      {
-        qDebug() << e.what();
-        errorhandling(e.what());
-        // emit q->error(e) or something
-      }
       qDebug() << "doing recursive copy of .kde to .kde3-backup";
+      RecursiveDirJob *job = RecursiveDirJob::recursiveCpDir(KaboomSettings::instance().kdehomeDir().canonicalPath(),
+                                                             KaboomSettings::instance().kde3backupDir().path(),
+                                                             RecursiveDirJob::RemoveDestination);
+      connect(job, SIGNAL(errorOccured(QString)), this, SLOT(errorhandling(QString)) );
+      job->synchronousRun(progress);
+      delete job;
     }
   }
-  try
+
+  RecursiveDirJob *job = NULL;
+  switch(selection)
   {
-    switch(selection)
-    {
       case MigrationTool::Migrate:
         progress->setMaximum(1); //fake the progress bar progress.
         progress->setValue(1);
         qDebug() << "do nothing, let kconf_update do magic";
         break;
       case MigrationTool::Merge:
-        DirOperations::recursiveCpDir(KaboomSettings::instance().kde4homeDir().canonicalPath(),
-                                      KaboomSettings::instance().kdehomeDir().canonicalPath(),
-                                      DirOperations::OverWrite,progress);
+        job = RecursiveDirJob::recursiveCpDir(KaboomSettings::instance().kde4homeDir().canonicalPath(),
+                                              KaboomSettings::instance().kdehomeDir().canonicalPath(),
+                                              RecursiveDirJob::OverWrite);
         qDebug() << "do magic experimental merge";
         break;
       case MigrationTool::Clean:
         qDebug() << "do recursive rm of .kde dir if exists";
-        DirOperations::recursiveRmDir(KaboomSettings::instance().kdehomeDir().path(), progress);
+        job = RecursiveDirJob::recursiveRmDir(KaboomSettings::instance().kdehomeDir().path());
         break;
       case MigrationTool::Move:
-        DirOperations::recursiveCpDir(KaboomSettings::instance().kde4homeDir().canonicalPath(),
-                                      KaboomSettings::instance().kdehomeDir().path(),
-                                      DirOperations::RemoveDestination, progress);
+        job = RecursiveDirJob::recursiveCpDir(KaboomSettings::instance().kde4homeDir().canonicalPath(),
+                                              KaboomSettings::instance().kdehomeDir().path(),
+                                              RecursiveDirJob::RemoveDestination);
         qDebug() << "move .kde4 over .kde";
         break;
-    }
   }
-  catch(DirOperations::Exception & e)
-  {
-    errorhandling(e.what());
+
+  if ( job ) {
+    connect(job, SIGNAL(errorOccured(QString)), this, SLOT(errorhandling(QString)) );
+    job->synchronousRun(progress);
+    delete job;
   }
-  if (!error->text().isEmpty()) // if errors, ...
+
+  if (!error->toPlainText().isEmpty()) // if errors, ...
   {
-    q->wizard()->setOptions(q->wizard()->options()&QWizard::DisabledBackButtonOnLastPage); //allow people going back now.>
+    q->wizard()->setOptions(q->wizard()->options() & ~QWizard::DisabledBackButtonOnLastPage); //allow people going back now.>
   } else {
       text->setText(tr("Completed successfully."));
   }
   complete=true;
   emit q->completeChanged();
 }
+
 void MigrationPagePrivate::errorhandling(const QString& err)
 {
   q->wizard()->button(QWizard::CancelButton)->setEnabled(!err.isEmpty());
   static_cast<MigrationTool*>(q->wizard())->setMigrationError(err);
-  error->setText(err);
+  if ( err.isEmpty() ) {
+      error->clear();
+  } else {
+      error->append(err);
+  }
   errorbox->setVisible(!err.isEmpty());
 }
 
diff --git a/migrationpage_p.h b/migrationpage_p.h
index dd6dd8a..0a9a1a9 100644
--- a/migrationpage_p.h
+++ b/migrationpage_p.h
@@ -34,15 +34,15 @@ class MigrationPagePrivate : public QObject
     ProgressWidget *progress;
     QPushButton *start;
     MigrationPage *q;
-    QLabel *error;
+    QTextBrowser *error;
     QGroupBox *errorbox;
     bool backup;
     bool complete;
-    void errorhandling(const QString &s = QString::null);
     void setupPage();
     bool haveSomethingToDo();
   public slots:
     void doMagic();
+    void errorhandling(const QString &s = QString());
 };
 
 #endif // MigrationPagePrivate

-- 
Kaboom - Debian KDE 3->4 migration tool



More information about the pkg-kde-commits mailing list