[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