Commit 239827ba authored by Albert Astals Cid's avatar Albert Astals Cid
Browse files

Rework how we open urls that have a #

Previously if it was a remote url that had # and a . after the # we
assumed the url had no fragment and everything was filename.

We don't do that anymore, what we do now is try to open the url as
parsed, i.e. before the # is the filename after is the fragment, and if
that fails we try to open everything as filename and nothing as
fragment.

Unfortunately given how kpart internals handle opening local vs remote
urls we need to do this in two places.

Also we have to remove the test that checked that the url was mangled at
the shell level because we don't do that anymore. Unfortunately can't
add a test for the new codepage since it would involve starting an http
server ^_^

Filenames:
  source2e.pdf
  foo#bar.pdf

What works:
 * okular http://localhost/source2e.pdf#subsection.68.3
 * okular file:///srv/http/source2e.pdf#subsection.68.3
 * okular source2e.pdf#subsection.68.3 (in the /srv/http folder)
 * okular source2e.pdf#2
 * okular http://localhost/foo#bar.pdf
 * okular file:///srv/http/foo#bar.pdf
 * okular foo#bar.pdf (in the /srv/http folder)

What doesn't work:
 * okular http://localhost/foo#bar.pdf#2

I think it's a fair limitation that if you want to open a file that contains # in the name and also use a # page marker you need to use the encoded url like okular http://localhost/foo%23bar.pdf#2
after all things like firefox will totally fail opening http://localhost/foo#bar.pdf and will just work if you give the encoded url

BUGS: 426976
parent 023976cc
Pipeline #42096 passed with stage
in 30 minutes and 30 seconds
......@@ -64,12 +64,6 @@ void ShellTest::testUrlArgs_data()
// non-local files
QTest::newRow("http://kde.org/foo.pdf") << "http://kde.org/foo.pdf" << true << QUrl(QStringLiteral("http://kde.org/foo.pdf"));
// make sure we don't have a fragment
QUrl hashInName(QStringLiteral("http://kde.org"));
QVERIFY(hashInName.path().isEmpty());
hashInName.setPath(QStringLiteral("/foo#bar.pdf"));
QVERIFY(hashInName.fragment().isEmpty());
QTest::newRow("http://kde.org/foo#bar.pdf") << "http://kde.org/foo#bar.pdf" << true << hashInName;
QUrl withAnchor(QStringLiteral("http://kde.org/foo.pdf"));
withAnchor.setFragment(QStringLiteral("anchor"));
QTest::newRow("http://kde.org/foo.pdf#anchor") << "http://kde.org/foo.pdf#anchor" << true << withAnchor;
......
......@@ -1152,7 +1152,9 @@ void Part::loadCancelled(const QString &reason)
// so we don't want to show an ugly messagebox just because the document is
// taking more than usual to be recreated
if (m_viewportDirty.pageNumber == -1) {
if (!reason.isEmpty()) {
if (m_urlWithFragment.isValid() && !m_urlWithFragment.isLocalFile()) {
tryOpeningUrlWithFragmentAsName();
} else if (!reason.isEmpty()) {
KMessageBox::error(widget(), i18n("Could not open %1. Reason: %2", url().toDisplayString(), reason));
}
}
......@@ -1685,6 +1687,7 @@ bool Part::openUrl(const QUrl &_url, bool swapInsteadOfOpening)
QUrl url(_url);
if (url.hasFragment()) {
m_urlWithFragment = _url;
const QString dest = url.fragment(QUrl::FullyDecoded);
bool ok = true;
int page = dest.toInt(&ok);
......@@ -1709,6 +1712,8 @@ bool Part::openUrl(const QUrl &_url, bool swapInsteadOfOpening)
m_document->setNextDocumentDestination(dest);
}
url.setFragment(QString());
} else {
m_urlWithFragment.clear();
}
// this calls in sequence the 'closeUrl' and 'openFile' methods
......@@ -1719,15 +1724,27 @@ bool Part::openUrl(const QUrl &_url, bool swapInsteadOfOpening)
setWindowTitleFromDocument();
} else {
resetStartArguments();
/* TRANSLATORS: Adding the reason (%2) why the opening failed (if any). */
QString errorMessage = i18n("Could not open %1. %2", url.toDisplayString(), QStringLiteral("\n%1").arg(m_document->openError()));
KMessageBox::error(widget(), errorMessage);
if (m_urlWithFragment.isValid() && m_urlWithFragment.isLocalFile()) {
openOk = tryOpeningUrlWithFragmentAsName();
} else {
resetStartArguments();
/* TRANSLATORS: Adding the reason (%2) why the opening failed (if any). */
QString errorMessage = i18n("Could not open %1. %2", url.toDisplayString(), QStringLiteral("\n%1").arg(m_document->openError()));
KMessageBox::error(widget(), errorMessage);
}
}
return openOk;
}
bool Part::tryOpeningUrlWithFragmentAsName()
{
QUrl url = m_urlWithFragment;
url.setPath(url.path() + QLatin1Char('#') + url.fragment());
url.setFragment(QString());
return openUrl(url);
}
bool Part::queryClose()
{
if (!isReadWrite() || !isModified())
......
......@@ -296,6 +296,8 @@ private:
void slotShareActionFinished(const QJsonObject &output, int error, const QString &message);
#endif
bool tryOpeningUrlWithFragmentAsName();
static int numberOfParts;
QTemporaryFile *m_tempfile;
......@@ -421,6 +423,10 @@ private:
// String to search in document startup
QString m_textToFindOnOpen;
// Set when opening an url that had fragment so that if it fails opening we try adding the fragment to the filename
// if we're opening http://localhost/foo#bar.pdf and the filename contains an # we can open it after trying to open foo fails
QUrl m_urlWithFragment;
private Q_SLOTS:
void slotAnnotationPreferences();
void slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled);
......
......@@ -45,13 +45,6 @@ QUrl urlFromArg(const QString &_arg, FileExistFunc exist_func, const QString &pa
url.setPath(path.left(hashIndex));
url.setFragment(path.mid(hashIndex + 1));
}
} else if (!url.fragment().isEmpty()) {
// make sure something like http://example.org/foo#bar.pdf is treated as a path name
// but something like http://example.org/foo.pdf#bar is foo.pdf plus an anchor "bar"
if (url.fragment().contains(QLatin1Char('.'))) {
url.setPath(url.path() + QLatin1Char('#') + url.fragment());
url.setFragment(QString());
}
}
if (!pageArg.isEmpty()) {
url.setFragment(pageArg);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment