[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: Better solution for allowing slash in filenames
From: David Faure <faure () kde ! org>
Date: 2008-01-18 16:44:14
Message-ID: 200801181744.14452.faure () kde ! org
[Download RAW message or body]
KDE 3.x and KDE 4.0 allow slashes in filenames by encoding them as %2F (and % as %%),
a nice trick by Torben in KDE-1, but which leads to unexpected behavior (like "foo%" and "foo%%"
both showing up as "foo%" in konqueror, the real path and the visible filename being different, etc).
I found a much better solution to allow '/' without all this escaping: using a unicode character
that looks like a slash but that isn't '/': QChar(0x2044), also known as "FRACTION SLASH".
Looks quite nice IMHO: http://web.davidfaure.fr/kde/slash.jpg
Ah... of course there's one downside: if you name a file "http://www.kde.org" you can't
copy paste that name into the webbrowser as a URL, since the slashes are not real slashes anymore.
Oh well, corner case of the corner case...
--
David Faure, faure@kde.org, sponsored by Trolltech to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).
["slash.diff" (text/x-diff)]
Index: kio/global.cpp
===================================================================
--- kio/global.cpp (revision 762501)
+++ kio/global.cpp (working copy)
@@ -132,41 +132,14 @@ KIO_EXPORT QString KIO::itemsSummaryStri
KIO_EXPORT QString KIO::encodeFileName( const QString & _str )
{
QString str( _str );
-
- int i = 0;
- while ( ( i = str.indexOf( '%', i ) ) != -1 ) {
- str.replace( i, 1, "%%");
- i += 2;
- }
- while ( ( i = str.indexOf( '/' ) ) != -1 )
- str.replace( i, 1, "%2f");
+ str.replace('/', QChar(0x2044)); // "Fraction slash"
return str;
}
KIO_EXPORT QString KIO::decodeFileName( const QString & _str )
{
- const int len = _str.length();
- QString text;
- text.reserve(len);
- for ( int i = 0; i < len ; ++i ) {
- if ( _str[i] == '%' && i+1 < len ) {
- const QChar nextChar = _str[i+1];
- if ( nextChar == '%' ) { // %% -> %
- text.append(QLatin1Char('%'));
- ++i;
- } else if ( nextChar == '2' && (i+2<len) && _str[i+2].toLower()=='f' ) { // %2f -> /
- text.append(QLatin1Char('/'));
- i += 2;
- } else {
- text.append(QLatin1Char('%'));
- }
- } else {
- text.append(_str[i]);
- }
- }
- text.squeeze();
-
- return text;
+ // Nothing to decode. "Fraction slash" is fine in filenames.
+ return _str;
}
KIO_EXPORT QString KIO::Job::errorString() const
Index: tests/kfileitemtest.cpp
===================================================================
--- tests/kfileitemtest.cpp (revision 762501)
+++ tests/kfileitemtest.cpp (working copy)
@@ -208,15 +208,9 @@ void KFileItemTest::testDecodeFileName_d
QTest::addColumn<QString>("filename");
QTest::addColumn<QString>("expectedText");
- QTest::newRow("no %") << "filename" << "filename";
- QTest::newRow("%2f at end") << "foo%2f" << "foo/";
- QTest::newRow("%2f at begin") << "%2f" << "/";
- QTest::newRow("%2F") << "foo%2Fbar" << "foo/bar";
- QTest::newRow("%%") << "%%" << "%";
- QTest::newRow("%%%%") << "%%%%" << "%%";
- QTest::newRow("%x") << "%x" << "%x";
- QTest::newRow("%x%") << "%x%" << "%x%";
- QTest::newRow("%2f as result") << "foo%%2f" << "foo%2f";
+ QTest::newRow("simple") << "filename" << "filename";
+ QTest::newRow("/ at end") << QString("foo") + QChar(0x2044) << QString("foo") + QChar(0x2044);
+ QTest::newRow("/ at begin") << QString(QChar(0x2044)) << QString(QChar(0x2044));
}
@@ -232,14 +226,9 @@ void KFileItemTest::testEncodeFileName_d
QTest::addColumn<QString>("text");
QTest::addColumn<QString>("expectedFileName");
- QTest::newRow("no %") << "filename" << "filename";
- QTest::newRow("%2f at end") << "foo/" << "foo%2f";
- QTest::newRow("%2f at begin") << "/" << "%2f";
- QTest::newRow("%%") << "%" << "%%";
- QTest::newRow("%%%%") << "%%" << "%%%%";
- QTest::newRow("%x") << "%x" << "%%x";
- QTest::newRow("%x%") << "%x%" << "%%x%%";
- QTest::newRow("%2f as input") << "foo%2f" << "foo%%2f";
+ QTest::newRow("simple") << "filename" << "filename";
+ QTest::newRow("/ at end") << "foo/" << QString("foo") + QChar(0x2044);
+ QTest::newRow("/ at begin") << "/" << QString(QChar(0x2044));
}
void KFileItemTest::testEncodeFileName()
Index: tests/kdirmodeltest.cpp
===================================================================
--- tests/kdirmodeltest.cpp (revision 762501)
+++ tests/kdirmodeltest.cpp (working copy)
@@ -45,7 +45,7 @@ void KDirModelTest::initTestCase()
* PATH/toplevelfile_1
* PATH/toplevelfile_2
* PATH/toplevelfile_3
- * PATH/file%2fslash
+ * PATH/specialchars%:
* PATH/subdir
* PATH/subdir/testfile
* PATH/subdir/subsubdir
@@ -55,7 +55,7 @@ void KDirModelTest::initTestCase()
m_topLevelFileNames << "toplevelfile_1"
<< "toplevelfile_2"
<< "toplevelfile_3"
- << "file%2fslash";
+ << "specialchars%:";
foreach(QString f, m_topLevelFileNames) {
createTestFile(path+f);
}
@@ -87,13 +87,13 @@ void KDirModelTest::fillModel( bool relo
m_fileIndex = idx;
else if (item.url().fileName() == "toplevelfile_2")
m_secondFileIndex = idx;
- else if (item.url().fileName().endsWith("slash"))
- m_slashFileIndex = idx;
+ else if (item.url().fileName().startsWith("special"))
+ m_specialFileIndex = idx;
}
QVERIFY(m_dirIndex.isValid());
QVERIFY(m_fileIndex.isValid());
QVERIFY(m_secondFileIndex.isValid());
- QVERIFY(m_slashFileIndex.isValid());
+ QVERIFY(m_specialFileIndex.isValid());
// Now list subdir/
QVERIFY(m_dirModel.canFetchMore(m_dirIndex));
@@ -179,8 +179,8 @@ void KDirModelTest::testNames()
QString fileName = m_dirModel.data(m_fileIndex, Qt::DisplayRole).toString();
QCOMPARE(fileName, QString("toplevelfile_1"));
- QString slashFileName = m_dirModel.data(m_slashFileIndex, Qt::DisplayRole).toString();
- QCOMPARE(slashFileName, QString("file/slash"));
+ QString specialFileName = m_dirModel.data(m_specialFileIndex, Qt::DisplayRole).toString();
+ QCOMPARE(specialFileName, QString("specialchars%:"));
QString dirName = m_dirModel.data(m_dirIndex, Qt::DisplayRole).toString();
QCOMPARE(dirName, QString("subdir"));
Index: tests/kdirmodeltest.h
===================================================================
--- tests/kdirmodeltest.h (revision 762501)
+++ tests/kdirmodeltest.h (working copy)
@@ -58,7 +58,7 @@ private:
KTempDir m_tempDir;
KDirModel m_dirModel;
QModelIndex m_fileIndex;
- QModelIndex m_slashFileIndex;
+ QModelIndex m_specialFileIndex;
QModelIndex m_secondFileIndex;
QModelIndex m_dirIndex;
QModelIndex m_fileInDirIndex;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic