diff --git a/autotests/kfilewidgettest.cpp b/autotests/kfilewidgettest.cpp --- a/autotests/kfilewidgettest.cpp +++ b/autotests/kfilewidgettest.cpp @@ -362,6 +362,13 @@ << filter << QStringLiteral("some.txt") << QStringLiteral("some.txt"); + + // \" in filename + QTest::newRow("\"some\".txt") + << "\"some\".txt" + << filter + << QStringLiteral("\"some\".txt") + << QStringLiteral("\"some\".txt"); } void testSetFilterForSave() diff --git a/src/filewidgets/kfilewidget.cpp b/src/filewidgets/kfilewidget.cpp --- a/src/filewidgets/kfilewidget.cpp +++ b/src/filewidgets/kfilewidget.cpp @@ -1327,6 +1327,7 @@ const QUrl currUrl = ops->url(); if (urlList.count() > 1) { + // implementation must be compatible with tokenize() QString urls; for (const QUrl &url : urlList) { urls += QStringLiteral("\"%1\"").arg(relativePathOrUrl(currUrl, url)) + QLatin1Char(' '); @@ -1735,7 +1736,7 @@ return urlList; } -// FIXME: current implementation drawback: a filename can't contain quotes +// FIXME: current implementation drawback: a filename can't contain '" "' QList KFileWidgetPrivate::tokenize(const QString &line) const { // qDebug(); @@ -1747,8 +1748,7 @@ } QString name; - const int count = line.count(QLatin1Char('"')); - if (count == 0) { // no " " -> assume one single file + if (!line.contains(QStringLiteral("\" \""))) { if (!QDir::isAbsolutePath(line)) { u = u.adjusted(QUrl::RemoveFilename); u.setPath(u.path() + line); @@ -1762,15 +1762,20 @@ return urls; } - int start = 0; - int index1 = -1, index2 = -1; + int index1 = 0, index2 = -1; while (true) { - index1 = line.indexOf(QLatin1Char('"'), start); - index2 = line.indexOf(QLatin1Char('"'), index1 + 1); + index1 = line.indexOf(QStringLiteral("\""), index1); + // find next word separator + index2 = line.indexOf(QStringLiteral("\" \""), index1 + 1); - if (index1 < 0 || index2 < 0) { + if (index1 < 0) { break; } + if (index2 == -1) { + // when no word separator is found + // grab everything left until last character + index2 = line.length() -1; + } // get everything between the " " name = line.mid(index1 + 1, index2 - index1 - 1); @@ -1792,7 +1797,7 @@ urls.append(_u); } - start = index2 + 1; + index1 = index2 + 1; } return urls; diff --git a/tests/kfilewidgettest_saving_gui.cpp b/tests/kfilewidgettest_saving_gui.cpp --- a/tests/kfilewidgettest_saving_gui.cpp +++ b/tests/kfilewidgettest_saving_gui.cpp @@ -28,8 +28,8 @@ QApplication app(argc, argv); KFileWidget* fileWidget = new KFileWidget(QUrl(QStringLiteral("kfiledialog:///SaveDialog")), nullptr); - fileWidget->setOperationMode(KFileWidget::Saving); - fileWidget->setMode(KFile::File); + fileWidget->setOperationMode(KFileWidget::Opening); + fileWidget->setMode(KFile::Files); fileWidget->setAttribute(Qt::WA_DeleteOnClose); fileWidget->okButton()->show();