diff --git a/autotests/kurlnavigatortest.cpp b/autotests/kurlnavigatortest.cpp --- a/autotests/kurlnavigatortest.cpp +++ b/autotests/kurlnavigatortest.cpp @@ -203,6 +203,11 @@ QTest::newRow("homeDir") << QStringLiteral("~") << QUrl::fromLocalFile(QDir::homePath()); KUser user(KUser::UseRealUserID); QTest::newRow("userHomeDir") << (QStringLiteral("~") + user.loginName()) << QUrl::fromLocalFile(user.homeDir()); + QTest::newRow("relativeFile") << QStringLiteral(".dotfile") << QUrl::fromLocalFile(QStringLiteral("/home/foo/.dotfile")); + QTest::newRow("relativeDir") << QStringLiteral("some_directory") << QUrl::fromLocalFile(QStringLiteral("/home/foo/some_directory")); + QTest::newRow("tildePath") << QStringLiteral("~/dir") << QUrl::fromUserInput(QStringLiteral("dir"), QDir::homePath(), QUrl::AssumeLocalFile); + QTest::newRow("pathwithtilde") << QStringLiteral("/home/user/dir/~/subdir") << QUrl::fromLocalFile(QStringLiteral("/home/user/dir/~/subdir")); + QTest::newRow("dotslash") << QStringLiteral("./~") << QUrl::fromLocalFile(QStringLiteral("/home/foo/~")); } void KUrlNavigatorTest::testUrlParsing() @@ -213,6 +218,7 @@ m_navigator->setLocationUrl(QUrl()); m_navigator->setUrlEditable(true); m_navigator->editor()->setCurrentText(input); + m_navigator->setDirectory(QUrl::fromLocalFile("/home/foo")); QCOMPARE(m_navigator->uncommittedUrl(), url); QTest::keyClick(m_navigator->editor(), Qt::Key_Enter); QCOMPARE(m_navigator->locationUrl(), url); diff --git a/src/filewidgets/kurlnavigator.h b/src/filewidgets/kurlnavigator.h --- a/src/filewidgets/kurlnavigator.h +++ b/src/filewidgets/kurlnavigator.h @@ -195,6 +195,9 @@ */ bool isUrlEditable() const; + void setDirectory(const QUrl &url); + QUrl directory() const; + /** * Shows the full path of the URL even if a place represents a part of the URL. * Assuming that a place called "Pictures" uses the URL /home/user/Pictures. diff --git a/src/filewidgets/kurlnavigator.cpp b/src/filewidgets/kurlnavigator.cpp --- a/src/filewidgets/kurlnavigator.cpp +++ b/src/filewidgets/kurlnavigator.cpp @@ -192,6 +192,7 @@ QStringList m_customProtocols; QWidget *m_dropWidget; KUrlNavigator *q; + KUrlCompletion *m_urlCompletion; }; KUrlNavigator::Private::Private(KUrlNavigator *q, KFilePlacesModel *placesModel) : @@ -250,8 +251,8 @@ m_pathBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength); m_pathBox->installEventFilter(q); - KUrlCompletion *kurlCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); - m_pathBox->setCompletionObject(kurlCompletion); + m_urlCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion); + m_pathBox->setCompletionObject(m_urlCompletion); m_pathBox->setAutoDeleteCompletionObject(true); connect(m_pathBox, SIGNAL(returnPressed()), @@ -1002,13 +1003,24 @@ QUrl KUrlNavigator::uncommittedUrl() const { - KUriFilterData filteredData(d->m_pathBox->currentText().trimmed()); + QString input = d->m_pathBox->currentText().trimmed(); + + // Always expand starting ~/ to $HOME. We want all inputs starting with it to point home directory. + // The reason this expansion is performed here, is that kshorturifilter will not return the desired result + // if said directory does not exist. + if (input.startsWith(QStringLiteral("~/"))) { + input.replace(0, 1, QDir::homePath()); + } + + const QUrl url = QUrl::fromUserInput(input, directory().path(), QUrl::AssumeLocalFile); + KUriFilterData filteredData(url, input); filteredData.setCheckForExecutables(false); + if (KUriFilter::self()->filterUri(filteredData, QStringList() << QStringLiteral("kshorturifilter") << QStringLiteral("kurisearchfilter"))) { return filteredData.uri(); - } else { - return QUrl::fromUserInput(filteredData.typedString()); } + + return url; } void KUrlNavigator::setLocationUrl(const QUrl &newUrl) @@ -1234,6 +1246,17 @@ return d->m_dropWidget; } +void KUrlNavigator::setDirectory(const QUrl &url) +{ + d->m_urlCompletion->setDir(url); +} + +QUrl KUrlNavigator::directory() const +{ + return d->m_urlCompletion->dir(); +} + + #ifndef KIOFILEWIDGETS_NO_DEPRECATED const QUrl &KUrlNavigator::url() const { diff --git a/src/widgets/kurifilter.h b/src/widgets/kurifilter.h --- a/src/widgets/kurifilter.h +++ b/src/widgets/kurifilter.h @@ -222,6 +222,13 @@ */ KUriFilterData(); + /** + * Creates a KUriFilterData object from the given URL and given string + * @param url + * @param typedString + */ + explicit KUriFilterData(const QUrl &url, const QString &typedString); + /** * Creates a KUriFilterData object from the given URL. * diff --git a/src/widgets/kurifilter.cpp b/src/widgets/kurifilter.cpp --- a/src/widgets/kurifilter.cpp +++ b/src/widgets/kurifilter.cpp @@ -262,6 +262,11 @@ { } +KUriFilterData::KUriFilterData(const QUrl &url, const QString &typedString) + : d(new KUriFilterDataPrivate(url, typedString)) +{ +} + KUriFilterData::KUriFilterData(const QUrl &url) : d(new KUriFilterDataPrivate(url, url.toString())) {