[kde-doc-english] KDE/kdelibs/kio/kio

David Faure faure at kde.org
Fri Oct 3 01:19:44 CEST 2008


SVN commit 867164 by dfaure:

GUI: The "Overwrite" button when a directory already exists has always confused people,
name it "Write Into" instead, with tooltips that explain what the 4 buttons do in both cases
(files or dirs); separate the effect of those buttons so that "write into all dirs" doesn't
imply "overwrite all files" and vice-versa; same with skipping files vs skipping dirs.
As discussed with JohnFlux and rabauke on irc; fixes #84752.


 M  +59 -45    copyjob.cpp  
 M  +10 -2     renamedialog.cpp  
 M  +16 -2     renamedialog.h  


--- trunk/KDE/kdelibs/kio/kio/copyjob.cpp #867163:867164
@@ -115,8 +115,10 @@
         , m_bSingleFileCopy(false)
         , m_bOnlyRenames(mode==CopyJob::Move)
         , m_dest(dest)
-        , m_bAutoSkip( false )
-        , m_bOverwriteAll( false )
+        , m_bAutoSkipFiles( false )
+        , m_bAutoSkipDirs( false )
+        , m_bOverwriteAllFiles( false )
+        , m_bOverwriteAllDirs( false )
         , m_conflictError(0)
         , m_reportTimer(0)
     {
@@ -162,8 +164,10 @@
     //
     QStringList m_skipList;
     QStringList m_overwriteList;
-    bool m_bAutoSkip;
-    bool m_bOverwriteAll;
+    bool m_bAutoSkipFiles;
+    bool m_bAutoSkipDirs;
+    bool m_bOverwriteAllFiles;
+    bool m_bOverwriteAllDirs;
     int m_conflictError;
 
     QTimer *m_reportTimer;
@@ -193,7 +197,8 @@
     void setNextDirAttribute();
 
     void startRenameJob(const KUrl &slave_url);
-    bool shouldOverwrite( const QString& path ) const;
+    bool shouldOverwriteDir( const QString& path ) const;
+    bool shouldOverwriteFile( const QString& path ) const;
     bool shouldSkip( const QString& path ) const;
     void skipSrc();
 
@@ -774,17 +779,20 @@
     dirsToRemove.removeAll( sourceUrl );
 }
 
-bool CopyJobPrivate::shouldOverwrite( const QString& path ) const
+bool CopyJobPrivate::shouldOverwriteDir( const QString& path ) const
 {
-    if ( m_bOverwriteAll )
+    if ( m_bOverwriteAllDirs )
         return true;
-    Q_FOREACH(const QString& overwritePath, m_overwriteList) {
-        if ( path.startsWith(overwritePath) )
-            return true;
-    }
-    return false;
+    return m_overwriteList.contains(path);
 }
 
+bool CopyJobPrivate::shouldOverwriteFile( const QString& path ) const
+{
+    if ( m_bOverwriteAllFiles )
+        return true;
+    return m_overwriteList.contains(path);
+}
+
 bool CopyJobPrivate::shouldSkip( const QString& path ) const
 {
     Q_FOREACH(const QString& skipPath, m_skipList) {
@@ -808,15 +816,15 @@
         {
             KUrl oldURL = ((SimpleJob*)job)->url();
             // Should we skip automatically ?
-            if ( m_bAutoSkip ) {
+            if ( m_bAutoSkipDirs ) {
                 // We don't want to copy files in this directory, so we put it on the skip list
-              m_skipList.append( oldURL.path( KUrl::AddTrailingSlash ) );
+                m_skipList.append( oldURL.path( KUrl::AddTrailingSlash ) );
                 skip( oldURL );
                 dirs.erase( it ); // Move on to next dir
             } else {
                 // Did the user choose to overwrite already?
-                const QString destFile = (*it).uDest.path();
-                if ( shouldOverwrite( destFile ) ) { // overwrite => just skip
+                const QString destDir = (*it).uDest.path();
+                if ( shouldOverwriteDir( destDir ) ) { // overwrite => just skip
                     emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime, true /* directory */, false /* renamed */ );
                     dirs.erase( it ); // Move on to next dir
                 } else {
@@ -883,7 +891,7 @@
     assert ( !q->hasSubjobs() ); // We should have only one job at a time ...
 
     // Always multi and skip (since there are files after that)
-    RenameDialog_Mode mode = (RenameDialog_Mode)( M_MULTI | M_SKIP );
+    RenameDialog_Mode mode = (RenameDialog_Mode)( M_MULTI | M_SKIP | M_ISDIR );
     // Overwrite only if the existing thing is a dir (no chance with a file)
     if ( m_conflictError == ERR_DIR_ALREADY_EXIST )
     {
@@ -915,7 +923,7 @@
             return;
         case R_RENAME:
         {
-          QString oldPath = (*it).uDest.path( KUrl::AddTrailingSlash );
+            QString oldPath = (*it).uDest.path( KUrl::AddTrailingSlash );
             KUrl newUrl( (*it).uDest );
             newUrl.setPath( newPath );
             emit q->renamed( q, (*it).uDest, newUrl ); // for e.g. kpropsdlg
@@ -959,7 +967,7 @@
         }
         break;
         case R_AUTO_SKIP:
-            m_bAutoSkip = true;
+            m_bAutoSkipDirs = true;
             // fall through
         case R_SKIP:
             m_skipList.append( existingDest );
@@ -976,7 +984,7 @@
             m_processedDirs++;
             break;
         case R_OVERWRITE_ALL:
-            m_bOverwriteAll = true;
+            m_bOverwriteAllDirs = true;
             emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime, true /* directory */, false /* renamed */ );
             // Move on to next dir
             dirs.erase( it );
@@ -1040,7 +1048,7 @@
     if ( job->error() )
     {
         // Should we skip automatically ?
-        if ( m_bAutoSkip )
+        if ( m_bAutoSkipFiles )
         {
             skip( (*it).uSource );
             m_fileProcessedSize = (*it).size;
@@ -1164,7 +1172,7 @@
         bool isDir = true;
 
         if( m_conflictError == ERR_DIR_ALREADY_EXIST )
-            mode = (RenameDialog_Mode) 0;
+            mode = M_ISDIR;
         else
         {
             if ( (*it).uSource == (*it).uDest  ||
@@ -1176,9 +1184,7 @@
             isDir = false;
         }
 
-        if ( m_bSingleFileCopy )
-            mode = (RenameDialog_Mode) ( mode | M_SINGLE );
-        else
+        if ( !m_bSingleFileCopy )
             mode = (RenameDialog_Mode) ( mode | M_MULTI | M_SKIP );
 
         res = q->ui()->askFileRename( q, !isDir ?
@@ -1234,7 +1240,7 @@
         }
         break;
         case R_AUTO_SKIP:
-            m_bAutoSkip = true;
+            m_bAutoSkipFiles = true;
             // fall through
         case R_SKIP:
             // Move on to next file
@@ -1244,7 +1250,7 @@
             m_processedFiles++;
             break;
        case R_OVERWRITE_ALL:
-            m_bOverwriteAll = true;
+            m_bOverwriteAllFiles = true;
             break;
         case R_OVERWRITE:
             // Add to overwrite list, so that copyNextFile knows to overwrite
@@ -1358,11 +1364,11 @@
         // Do we set overwrite ?
         bool bOverwrite;
         const QString destFile = uDest.path();
-        kDebug(7007) << "copying " << destFile;
+        // kDebug(7007) << "copying" << destFile;
         if ( uDest == uSource )
             bOverwrite = false;
         else
-            bOverwrite = shouldOverwrite( destFile );
+            bOverwrite = shouldOverwriteFile( destFile );
 
         m_bCurrentOperationIsLink = false;
         KIO::Job * newjob = 0;
@@ -1669,23 +1675,15 @@
                 m_reportTimer->stop();
 
             // Should we skip automatically ?
-            if ( m_bAutoSkip ) {
-                // Move on to next file
+            bool isDir = (err == ERR_DIR_ALREADY_EXIST);
+            if ((isDir && m_bAutoSkipDirs) || (!isDir && m_bAutoSkipFiles)) {
+                // Move on to next source url
                 skipSrc();
                 return;
-            } else if ( m_bOverwriteAll ) {
+            } else if ((isDir && m_bOverwriteAllDirs) || (!isDir && m_bOverwriteAllFiles)) {
                 ; // nothing to do, stat+copy+del will overwrite
             } else if ( q->isInteractive() ) {
                 QString newPath;
-                // If src==dest, use "overwrite-itself"
-                RenameDialog_Mode mode = (RenameDialog_Mode)
-                                      ( ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE );
-
-                if ( m_srcList.count() > 1 )
-                    mode = (RenameDialog_Mode) ( mode | M_MULTI | M_SKIP );
-                else
-                    mode = (RenameDialog_Mode) ( mode | M_SINGLE );
-
                 // we lack mtime info for both the src (not stated)
                 // and the dest (stated but this info wasn't stored)
                 // Let's do it for local files, at least
@@ -1702,6 +1700,7 @@
                     sizeSrc = stat_buf.st_size;
                     ctimeSrc = stat_buf.st_ctime;
                     mtimeSrc = stat_buf.st_mtime;
+                    isDir = S_ISDIR(stat_buf.st_mode);
                 }
                 if ( dest.isLocalFile() &&
                     KDE_stat(QFile::encodeName(dest.path()), &stat_buf) == 0 ) {
@@ -1710,6 +1709,14 @@
                     mtimeDest = stat_buf.st_mtime;
                 }
 
+                // If src==dest, use "overwrite-itself"
+                RenameDialog_Mode mode = ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE;
+
+                if ( m_srcList.count() > 1 )
+                    mode = (RenameDialog_Mode) ( mode | M_MULTI | M_SKIP );
+                if ( isDir )
+                    mode = (RenameDialog_Mode) ( mode | M_ISDIR );
+
                 RenameDialog_Result r = q->ui()->askFileRename(
                     q,
                     err != ERR_DIR_ALREADY_EXIST ? i18n("File Already Exists") : i18n("Already Exists as Folder"),
@@ -1742,14 +1749,20 @@
                     return;
                 }
                 case R_AUTO_SKIP:
-                    m_bAutoSkip = true;
+                    if (isDir)
+                        m_bAutoSkipDirs = true;
+                    else
+                        m_bAutoSkipFiles = true;
                     // fall through
                 case R_SKIP:
-                    // Move on to next file
+                    // Move on to next url
                     skipSrc();
                     return;
                 case R_OVERWRITE_ALL:
-                    m_bOverwriteAll = true;
+                    if (isDir)
+                        m_bOverwriteAllDirs = true;
+                    else
+                        m_bOverwriteAllFiles = true;
                     break;
                 case R_OVERWRITE:
                     // Add to overwrite list
@@ -1861,7 +1874,8 @@
 
 void KIO::CopyJob::setAutoSkip(bool autoSkip)
 {
-    d_func()->m_bAutoSkip = autoSkip;
+    d_func()->m_bAutoSkipFiles = autoSkip;
+    d_func()->m_bAutoSkipDirs = autoSkip;
 }
 
 CopyJob *KIO::copy(const KUrl& src, const KUrl& dest, JobFlags flags)
--- trunk/KDE/kdelibs/kio/kio/renamedialog.cpp #867163:867164
@@ -108,18 +108,26 @@
 
     if ( ( _mode & M_MULTI ) && ( _mode & M_SKIP ) ) {
         d->bSkip = new QPushButton( i18n( "&Skip" ), this );
+        d->bSkip->setToolTip((_mode & M_ISDIR) ? i18n("Do not copy or move this folder, skip to the next item instead")
+                             : i18n("Do not copy or move this file, skip to the next item instead"));
         connect(d->bSkip, SIGNAL(clicked()), this, SLOT(skipPressed()));
 
         d->bAutoSkip = new QPushButton( i18n( "&Auto Skip" ), this );
+        d->bAutoSkip->setToolTip((_mode & M_ISDIR) ? i18n("Do not copy or move any folder that already exists in the destination folder.\nYou will be prompted again in case of a conflict with an existing file though.")
+                                 : i18n("Do not copy or move any file that already exists in the destination folder.\nYou will be prompted again in case of a conflict with an existing directory though."));
         connect(d->bAutoSkip, SIGNAL(clicked()), this, SLOT(autoSkipPressed()));
     }
 
     if ( _mode & M_OVERWRITE ) {
-        d->bOverwrite = new QPushButton( i18n( "&Overwrite" ), this );
+        const QString text = (_mode & M_ISDIR) ? i18nc("Write files into an existing folder", "&Write Into") : i18n("&Overwrite");
+        d->bOverwrite = new QPushButton(text, this);
+        d->bOverwrite->setToolTip(i18n("Files and folders will be copied into the existing directory, alongside its existing contents.\nYou will be prompted again in case of a conflict with an existing file in the directory."));
         connect(d->bOverwrite, SIGNAL(clicked()), this, SLOT(overwritePressed()));
 
         if ( _mode & M_MULTI ) {
-            d->bOverwriteAll = new QPushButton( i18n( "O&verwrite All" ), this );
+            const QString textAll = (_mode & M_ISDIR) ? i18nc("Write files into any existing directory", "&Write Into All") : i18n("&Overwrite All");
+            d->bOverwriteAll = new QPushButton( textAll, this );
+            d->bOverwriteAll->setToolTip(i18n("Files and folders will be copied into any existing directory, alongside its existing contents.\nYou will be prompted again in case of a conflict with an existing file in a directory, but not in case of another existing directory."));
             connect(d->bOverwriteAll, SIGNAL(clicked()), this, SLOT(overwriteAllPressed()));
         }
     }
--- trunk/KDE/kdelibs/kio/kio/renamedialog.h #867163:867164
@@ -31,8 +31,22 @@
 
 namespace KIO {
 
-// KDE4: get rid of M_OVERWRITE_ITSELF, trigger it internally if src==dest
-enum RenameDialog_Mode { M_OVERWRITE = 1, M_OVERWRITE_ITSELF = 2, M_SKIP = 4, M_SINGLE = 8, M_MULTI = 16, M_RESUME = 32, M_NORENAME = 64 };
+// KDE5: get rid of M_OVERWRITE_ITSELF, trigger it internally if src==dest
+// KDE5: get rid of M_SINGLE. If not multi, then single ;)
+// KDE5: use QFlags to get rid of all the casting!
+/**
+ * M_OVERWRITE: We have an existing dest, show details about it and offer to overwrite it.
+ * M_OVERWRITE_ITSELF: Warn that the current operation would overwrite a file with itself,
+ *                     which is not allowed.
+ * M_SKIP: Offer a "Skip" button, to skip other files too. Requires M_MULTI.
+ * M_SINGLE: Deprecated and unused, please ignore.
+ * M_MULTI: Set if the current operation concerns multiple files, so it makes sense
+ *  to offer buttons that apply the user's choice to all files/folders.
+ * M_RESUME: Offer a "Resume" button (plus "Resume All" if M_MULTI)
+ * M_NORENAME: Don't offer a "Rename" button
+ * M_ISDIR: The dest is a directory, so label the "overwrite" button something like "merge" instead.
+ */
+enum RenameDialog_Mode { M_OVERWRITE = 1, M_OVERWRITE_ITSELF = 2, M_SKIP = 4, M_SINGLE = 8, M_MULTI = 16, M_RESUME = 32, M_NORENAME = 64, M_ISDIR = 128 };
 
 /**
  * The result of open_RenameDialog().



More information about the kde-doc-english mailing list