kdecore: re-use KUrl::AdjustPathOption for KUrl::fileName() and KUrl::directory()

so that it is clear that the options shall affect only the result, also for
local files the correct thing can be done regardless of the trailing slash
as is done in KUrl::upUrl()

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-26 20:47:38 +03:00
parent 065100c799
commit eac8fd79cc
11 changed files with 48 additions and 141 deletions

View file

@ -521,50 +521,16 @@ QString KUrl::toMimeDataString() const
return url();
}
QString KUrl::fileName(const DirectoryOptions &options) const
QString KUrl::fileName(AdjustPathOption trailing) const
{
Q_ASSERT(options != 0); // Disallow options == false
QString fname;
const QString path = this->path();
int len = path.length();
if (len == 0) {
return fname;
const QString urlpath = path();
if (urlpath.isEmpty()) {
return urlpath;
}
if (!(options & ObeyTrailingSlash)) {
while (len >= 1 && path[len - 1] == QLatin1Char('/')) {
len--;
}
} else if (path[len - 1] == QLatin1Char('/')) {
return fname;
if (!urlpath.contains(QLatin1Char('/'))) {
return urlpath;
}
// Does the path only consist of '/' characters ?
if (len == 1 && path[0] == QLatin1Char('/')) {
return fname;
}
// Skip last n slashes
int n = 1;
int i = len;
do {
i = path.lastIndexOf(QLatin1Char('/'), i - 1);
} while (--n && i > 0);
// If ( i == -1 ) => the first character is not a '/'
// So it's some URL like file:blah.tgz, return the whole path
if (i == -1) {
if (len == path.length()) {
fname = path;
} else {
// Might get here if _strip_trailing_slash is true
fname = path.left(len);
}
} else {
fname = path.mid(i + 1, len - i - 1); // TO CHECK
}
return fname;
return trailingSlash(trailing, QFileInfo(urlpath).fileName());
}
void KUrl::addPath(const QString &txt)
@ -593,36 +559,13 @@ void KUrl::addPath(const QString &txt)
setPath(strPath + txt.mid(i));
}
QString KUrl::directory(const DirectoryOptions &options) const
QString KUrl::directory(AdjustPathOption trailing) const
{
Q_ASSERT(options != 0); // Disallow options == false
QString result = path();
if (!(options & ObeyTrailingSlash)) {
result = trailingSlash(RemoveTrailingSlash, result);
QString urlpath = path();
if (urlpath.isEmpty() || urlpath == QLatin1String("/")) {
return urlpath;
}
if (result.isEmpty() || result == QLatin1String("/")) {
return result;
}
int i = result.lastIndexOf(QLatin1Char('/'));
// If ( i == -1 ) => the first character is not a '/'
// So it's some URL like file:blah.tgz, with no path
if (i == -1) {
return QString();
}
if (i == 0) {
return QString(QLatin1Char('/'));
}
if (options & AppendTrailingSlash) {
result = result.left(i + 1);
} else {
result = result.left(i);
}
return result;
return trailingSlash(trailing, QFileInfo(urlpath).path());
}
KUrl KUrl::upUrl() const
@ -643,7 +586,7 @@ KUrl KUrl::upUrl() const
}
if (isLocalFile()) {
// the only way to be sure is to stat because the path can include or omit the trailing
// the only way to be sure is to stat() because the path can include or omit the trailing
// slash (indicating if it is directory)
QString newpath;
QFileInfo urlinfo(urlpath);
@ -698,7 +641,7 @@ QString KUrl::relativeUrl(const KUrl &base_url, const KUrl &url)
QString relURL;
if ((base_url.path() != url.path()) || (base_url.query() != url.query())) {
bool dummy = false;
QString basePath = base_url.directory(KUrl::ObeyTrailingSlash);
QString basePath = base_url.directory(KUrl::LeaveTrailingSlash);
relURL = _relativePath(basePath, url.path(), dummy);
relURL += url.query();
}

View file

@ -416,63 +416,30 @@ public:
* Any reference is reset.
*
* @param txt The filename to be set. It is considered to be decoded. If the
* current path ends with '/' then @p txt int just appended, otherwise
* current path ends with '/' then @p txt is just appended, otherwise
* all text behind the last '/' in the current path is erased and
* @p txt is appended then. It does not matter whether @p txt starts
* with '/' or not.
*/
void setFileName(const QString &txt);
/**
* option to be used in fileName and directory
*/
enum DirectoryOption {
/**
* This tells whether a trailing '/' should be ignored.
*
* If the flag is not set, for both <tt>file:///hallo/torben/</tt> and <tt>file:///hallo/torben</tt>
* the fileName is "torben" and the path is "hallo"
*
* If the flag is set, then everything behind the last '/'is considered to be the filename.
* So "hallo/torben" will be the path and the filename will be empty.
*/
ObeyTrailingSlash = 0x02,
/**
* tells whether the returned result should end with '/' or not.
* If the flag is set, '/' is added to the end of the path
*
* If the path is empty or just "/" then this flag has no effect.
*
* This option should only be used in directory(), it has no effect in fileName()
*/
AppendTrailingSlash = 0x04,
/**
* Opposite of ObeyTrailingSlash (default)
* fileName("file:/foo/") and fileName("file:/foo") is "foo" in both cases.
*/
IgnoreTrailingSlash = 0x01
};
Q_DECLARE_FLAGS(DirectoryOptions, DirectoryOption)
/**
* Returns the filename of the path.
* @param options a set of DirectoryOption flags. (StripTrailingSlashFromResult has no effect)
* @param trailing use to add or remove a trailing slash to/from the path. See adjustPath
* @return The filename of the current path. The returned string is decoded. Null
* if there is no file (and thus no path).
*/
QString fileName(const DirectoryOptions& options = IgnoreTrailingSlash) const;
QString fileName(AdjustPathOption trailing = RemoveTrailingSlash) const;
/**
* Returns the directory of the path.
* @param options a set of DirectoryOption flags
* @param trailing use to add or remove a trailing slash to/from the path. See adjustPath
* @return The directory part of the current path. Everything between the last and the second last '/'
* is returned. For example <tt>file:///hallo/torben/</tt> would return "/hallo/torben/" while
* <tt>file:///hallo/torben</tt> would return "hallo/". The returned string is decoded.
* QString() is returned when there is no path.
*/
QString directory(const DirectoryOptions& options = IgnoreTrailingSlash) const;
QString directory(AdjustPathOption trailing = RemoveTrailingSlash) const;
/**
* Set the directory to @p dir, leaving the filename empty.
@ -665,8 +632,6 @@ private:
operator QString() const; // forbidden, use url(), prettyUrl(), or pathOrUrl() instead.
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KUrl::DirectoryOptions)
Q_DECLARE_METATYPE(KUrl)
Q_DECLARE_METATYPE(KUrl::List)

View file

@ -24,15 +24,15 @@
Boston, MA 02110-1301, USA.
*/
#include "kfilewidget.h"
#include <config-kfile.h>
#include "kfilewidget.h"
#include "kfileplacesview.h"
#include "kfileplacesmodel.h"
#include "kfilebookmarkhandler_p.h"
#include "kurlcombobox.h"
#include "kurlnavigator.h"
#include "kfilepreviewgenerator.h"
#include <config-kfile.h>
#include <kactioncollection.h>
#include <kdiroperator.h>
@ -51,24 +51,24 @@
#include <kio/jobuidelegate.h>
#include <kio/netaccess.h>
#include <kio/scheduler.h>
#include <kio/kfileitemdelegate.h>
#include <krecentdirs.h>
#include <kdebug.h>
#include <kio/kfileitemdelegate.h>
#include <kde_file.h>
#include <QtCore/QTimer>
#include <QtGui/QCheckBox>
#include <QtGui/QDockWidget>
#include <QtGui/QLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QSplitter>
#include <QtGui/QAbstractProxyModel>
#include <QtGui/qevent.h>
#include <QtGui/QApplication>
#include <kshell.h>
#include <kmessagebox.h>
#include <QTimer>
#include <QCheckBox>
#include <QDockWidget>
#include <QLayout>
#include <QLabel>
#include <QLineEdit>
#include <QSplitter>
#include <QAbstractProxyModel>
#include <QResizeEvent>
#include <QApplication>
class KFileWidgetPrivate
{
public:

View file

@ -468,7 +468,7 @@ void CopyJobPrivate::sourceStated(const UDSEntry& entry, const KUrl& sourceUrl)
//kDebug(7007) << "Source is a file (or a symlink), or we are linking -> no recursive listing";
if (srcurl.isLocalFile()) {
const QString parentDir = srcurl.directory(KUrl::ObeyTrailingSlash);
const QString parentDir = srcurl.directory(KUrl::LeaveTrailingSlash);
m_parentDirs.insert(parentDir);
}
@ -820,7 +820,7 @@ void CopyJobPrivate::startRenameJob( const KUrl& slave_url )
// Silence KDirWatch notifications, otherwise performance is horrible
if (m_currentSrcURL.isLocalFile()) {
const QString parentDir = m_currentSrcURL.directory(KUrl::ObeyTrailingSlash);
const QString parentDir = m_currentSrcURL.directory(KUrl::LeaveTrailingSlash);
if (!m_parentDirs.contains(parentDir)) {
m_parentDirs.insert(parentDir);
}
@ -1848,7 +1848,7 @@ void CopyJobPrivate::slotResultRenaming( KJob* job )
kDebug(7007) << "Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls";
const QString _src( m_currentSrcURL.toLocalFile() );
const QString _dest( dest.toLocalFile() );
const QString _tmpPrefix = m_currentSrcURL.directory(KUrl::ObeyTrailingSlash|KUrl::AppendTrailingSlash);
const QString _tmpPrefix = m_currentSrcURL.directory(KUrl::AddTrailingSlash);
KTemporaryFile tmpFile;
tmpFile.setPrefix(_tmpPrefix);
const bool openOk = tmpFile.open();

View file

@ -372,7 +372,7 @@ void DeleteJobPrivate::currentSourceStated(bool isDir, bool isLink)
}
}
if (url.isLocalFile()) {
const QString parentDir = url.directory(KUrl::IgnoreTrailingSlash);
const QString parentDir = url.directory(KUrl::RemoveTrailingSlash);
m_parentDirs.insert(parentDir);
}
}

View file

@ -989,8 +989,7 @@ void KDirListerCache::slotFileRenamed( const QString &_src, const QString &_dst
// Check to see if a URL exists, and if so, if only the file part has changed,
// only update the name and not the underlying URL.
bool nameOnly = !fileitem->entry().stringValue( KIO::UDSEntry::UDS_URL ).isEmpty();
nameOnly &= src.directory( KUrl::IgnoreTrailingSlash | KUrl::AppendTrailingSlash ) ==
dst.directory( KUrl::IgnoreTrailingSlash | KUrl::AppendTrailingSlash );
nameOnly &= src.directory( KUrl::AddTrailingSlash ) == dst.directory( KUrl::AddTrailingSlash );
if (!nameOnly && fileitem->isDir()) {
renameDir( src, dst );

View file

@ -769,7 +769,7 @@ bool KDirModel::setData( const QModelIndex & index, const QVariant & value, int
if (newName.isEmpty() || newName == item.text() || (newName == QLatin1String(".")) || (newName == QLatin1String("..")))
return true;
KUrl newurl(item.url());
newurl.setPath(newurl.directory(KUrl::AppendTrailingSlash) + KIO::encodeFileName(newName));
newurl.setPath(newurl.directory(KUrl::AddTrailingSlash) + KIO::encodeFileName(newName));
KIO::Job * job = KIO::moveAs(item.url(), newurl, newurl.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags);
job->ui()->setAutoErrorHandlingEnabled(true);
// undo handling

View file

@ -77,7 +77,7 @@ QByteArray KRemoteEncoding::encode(const KUrl& url) const
QByteArray KRemoteEncoding::directory(const KUrl& url, bool ignore_trailing_slash) const
{
QString dir = url.directory(ignore_trailing_slash ? KUrl::DirectoryOptions(KUrl::IgnoreTrailingSlash) : KUrl::ObeyTrailingSlash);
QString dir = url.directory(ignore_trailing_slash ? KUrl::KUrl::RemoveTrailingSlash : KUrl::LeaveTrailingSlash);
return encode(dir);
}

View file

@ -460,10 +460,10 @@ public:
}
// The directory with a trailing '/'
QString dir() const {
return m_kurl.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash);
return m_kurl.directory(KUrl::AddTrailingSlash);
}
QString file() const {
return m_kurl.fileName(KUrl::ObeyTrailingSlash);
return m_kurl.fileName(KUrl::LeaveTrailingSlash);
}
// The initial, unparsed, url, as a string.
@ -1027,7 +1027,7 @@ bool KUrlCompletionPrivate::urlCompletion(const KUrlCompletionPrivate::MyURL& ur
return false;
// url does not specify a valid directory
if (url_dir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash).isEmpty())
if (url_dir.directory(KUrl::AddTrailingSlash).isEmpty())
return false;
// automatic completion is disabled
@ -1042,7 +1042,7 @@ bool KUrlCompletionPrivate::urlCompletion(const KUrlCompletionPrivate::MyURL& ur
url_dir.setFileName(QString()); // not really nesseccary, but clear the filename anyway...
// Remove escapes
QString directory = unescape(url_dir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash));
QString directory = unescape(url_dir.directory(KUrl::AddTrailingSlash));
url_dir.setPath(directory);

View file

@ -313,7 +313,7 @@ void PreviewJobPrivate::startPreview()
items.append(item);
if (!bNeedCache && bSave &&
(kit.url().protocol() != "file" ||
!kit.url().directory( KUrl::AppendTrailingSlash ).startsWith(thumbRoot)) &&
!kit.url().directory( KUrl::AddTrailingSlash ).startsWith(thumbRoot)) &&
itemplugin->property("CacheThumbnail").toBool()) {
bNeedCache = true;
}
@ -553,7 +553,7 @@ void PreviewJobPrivate::slotThumbData(KIO::Job *, const QByteArray &data)
bool save = bSave &&
currentItem.plugin->property("CacheThumbnail").toBool() &&
(currentItem.item.url().protocol() != "file" ||
!currentItem.item.url().directory( KUrl::AppendTrailingSlash ).startsWith(thumbRoot)) && !sequenceIndex;
!currentItem.item.url().directory( KUrl::AddTrailingSlash ).startsWith(thumbRoot)) && !sequenceIndex;
QImage thumb;
QDataStream s(data);
s >> thumb;

View file

@ -1323,7 +1323,7 @@ void Ftp::stat(const KUrl &url)
KUrl tempurl( url );
tempurl.setPath( path ); // take the clean one
QString listarg; // = tempurl.directory(KUrl::ObeyTrailingSlash);
QString listarg; // = tempurl.directory(KUrl::LeaveTrailingSlash);
QString parentDir;
QString filename = tempurl.fileName();
Q_ASSERT(!filename.isEmpty());
@ -1351,7 +1351,7 @@ void Ftp::stat(const KUrl &url)
if (!isDir)
{
// It is a file or it doesn't exist, try going to parent directory
parentDir = tempurl.directory(KUrl::AppendTrailingSlash);
parentDir = tempurl.directory(KUrl::AddTrailingSlash);
// With files we can do "LIST <filename>" to avoid listing the whole dir
listarg = filename;
}