Commit c9758a96 authored by Marcell Fülöp's avatar Marcell Fülöp
Browse files

Improved and more complete version

- moved url query string parsing to UrlInfo
- moved delayed setting of cursor pos from KateApp to KateViewManagero
parent 3f6ca8d1
......@@ -205,15 +205,10 @@ bool KateApp::startupKate()
if (noDir) {
doc = openDocUrl(info.url, codec_name, tempfileSet);
// when setting cursor position on startup, the order should be
// queryString, cmdArgs, session (i.e. query overrides both, args override session)
if (info.url.hasQuery()) {
setCursorFromQueryString(doc->views().at(0));
} else if (m_args.isSet(QStringLiteral("line")) || m_args.isSet(QStringLiteral("column"))) {
setCursorFromArgs(doc->views().at(0));
} else if (info.cursor.isValid()) {
if (info.cursor.isValid()) {
setCursor(info.cursor.line(), info.cursor.column());
} else if (m_args.isSet(QStringLiteral("line")) || m_args.isSet(QStringLiteral("column"))) {
setCursorFromArgs(activeMainWindow()->activeView());
}
} else if (!KateApp::self()->pluginManager()->plugin(QStringLiteral("kateprojectplugin"))) {
KMessageBox::sorry(activeKateMainWindow(), i18n("Folders can only be opened when the projects plugin is enabled"));
......@@ -311,30 +306,18 @@ KTextEditor::Document *KateApp::openDocUrl(const QUrl &url, const QString &encod
KTextEditor::Document *doc = nullptr;
if (noDir) {
KateDocumentInfo docInfo;
docInfo.doPostLoadOperations = !url.isLocalFile() && (hasCursorInArgs() || url.hasQuery());
// open a normal file
if (codec) {
doc = mainWindow->viewManager()->openUrl(url, QString::fromLatin1(codec->name()), true, isTempFile);
doc = mainWindow->viewManager()->openUrl(url, QString::fromLatin1(codec->name()), true, isTempFile, docInfo);
} else {
doc = mainWindow->viewManager()->openUrl(url, QString(), true, isTempFile);
doc = mainWindow->viewManager()->openUrl(url, QString(), true, isTempFile, docInfo);
}
} else {
KMessageBox::sorry(mainWindow, i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.", url.url()));
}
// When opening from remote url, 'textChanged' is emitted once loading has finished.
// Connect to each remote document's signal for post-load operations.
if (doc && !doc->url().isLocalFile()) {
auto *connCtx = new QObject(this); // use a dummy object as signal receiver
connect(doc, &KTextEditor::Document::textChanged, connCtx, [this, connCtx](KTextEditor::Document *doc) {
connCtx->deleteLater();
if (doc->url().hasQuery()) {
setCursorFromQueryString(doc->views().empty() ? nullptr : doc->views().at(0));
} else {
setCursorFromArgs(doc->views().empty() ? nullptr : doc->views().at(0));
}
});
}
return doc;
}
......@@ -369,27 +352,12 @@ void KateApp::setCursorFromQueryString(KTextEditor::View *view)
int line = 0;
int column = 0;
bool nav = false;
int pos = -1;
if (!view && !(view = activeKateMainWindow()->activeView())) {
return;
}
QUrlQuery urlQuery;
if (!view->document()->url().hasQuery()) {
// Find orig url with query string in m_args. It's necessary because positional arguments
// are cleaned (in normaliseUrl() in KateDocManager::openUrl()) for local files but not for remote ones.
QRegExp pattern(QLatin1String(view->document()->url().toString().toUtf8().append(".*").constData()));
if ((pos = m_args.positionalArguments().indexOf(pattern)) < 0) {
return;
}
QString positionalArgument = m_args.positionalArguments().at(pos);
UrlInfo info(positionalArgument);
urlQuery = QUrlQuery(info.url);
} else {
urlQuery = QUrlQuery(view->document()->url());
}
QUrlQuery urlQuery(view->document()->url());
QString lineStr = urlQuery.queryItemValue(QStringLiteral("line"));
QString columnStr = urlQuery.queryItemValue(QStringLiteral("column"));
......@@ -398,11 +366,13 @@ void KateApp::setCursorFromQueryString(KTextEditor::View *view)
line > 0 && line--;
nav = true;
}
if (!columnStr.isEmpty()) {
column = columnStr.toInt();
column > 0 && column--;
nav = true;
}
if (nav) {
view->setCursorPosition(KTextEditor::Cursor(line, column));
activeKateMainWindow()->setAutoSaveSettings();
......@@ -425,6 +395,10 @@ bool KateApp::setCursor(int line, int column)
return true;
}
bool KateApp::hasCursorInArgs() {
return m_args.isSet(QStringLiteral("line")) || m_args.isSet(QStringLiteral("c"));
}
bool KateApp::openInput(const QString &text, const QString &encoding)
{
activeKateMainWindow()->viewManager()->openUrl(QUrl(), encoding, true);
......
......@@ -216,6 +216,25 @@ public:
*/
bool setCursor(int line, int column);
/**
* Checks if --line and/or --column args were provided and attempts
* to set cursor position in the provided or active view accordingly.
*
* @param view Optional view to apply changes on.
*/
void setCursorFromArgs(KTextEditor::View *view = nullptr);
/**
* Checks if line or column were provided in query string
* (e.g. file:///file1?line=3&column=4) and attempts to set cursor
* position in the provided or active view accordingly.
*
* @param view Optional view to apply changes on.
*/
void setCursorFromQueryString(KTextEditor::View *view = nullptr);
bool hasCursorInArgs();
/**
* helper to handle stdin input
* open a new document/view, fill it with the text given
......@@ -391,23 +410,6 @@ private:
*/
KateSessionManager m_sessionManager;
/**
* Checks if --line and/or --column args were provided and attempts
* to set cursor position in the provided or active view accordingly.
*
* @param view Optional view to apply changes on.
*/
void setCursorFromArgs(KTextEditor::View *view = nullptr);
/**
* Checks if line or column were provided in query string
* (e.g. file:///file1?line=3&column=4) and attempts to set cursor
* position in the provided or active view accordingly.
*
* @param view Optional view to apply changes on.
*/
void setCursorFromQueryString(KTextEditor::View *view = nullptr);
#ifdef WITH_KUSERFEEDBACK
/**
* user feedback provider
......
......@@ -37,6 +37,7 @@ public:
bool openedByUser = false;
bool openSuccess = true;
bool doPostLoadOperations = false;
};
class KateDocManager : public QObject
......
......@@ -431,6 +431,27 @@ KTextEditor::View *KateViewManager::createView(KTextEditor::Document *doc, KateV
*/
KTextEditor::View *view = (vs ? vs : activeViewSpace())->createView(doc);
/**
* connect to signal here so we can handle post-load
* set cursor position for this view if we need to
*/
KateDocumentInfo *docInfo = KateApp::self()->documentManager()->documentInfo(doc);
if (docInfo->doPostLoadOperations) {
docInfo->doPostLoadOperations = false; // do this only once
QSharedPointer<QMetaObject::Connection> conn(new QMetaObject::Connection());
auto handler = [view, conn](KTextEditor::Document *doc) {
disconnect(*conn);
if (doc->url().hasQuery()) {
KateApp::self()->setCursorFromQueryString(view);
} else {
KateApp::self()->setCursorFromArgs(view);
}
};
*conn = connect(doc, &KTextEditor::Document::textChanged, view, handler);
}
/**
* remember this view, active == false, min age set
* create activity resource
......
......@@ -629,7 +629,9 @@ void KateViewSpace::restoreConfig(KateViewManager *viewMan, const KConfigBase *c
// avoid empty view space
if (m_docToView.isEmpty()) {
viewMan->createView(KateApp::self()->documentManager()->documentList().first(), this);
auto *doc = KateApp::self()->documentManager()->documentList().first();
KateApp::self()->documentManager()->documentInfo(doc)->doPostLoadOperations = !doc->url().isLocalFile() && (KateApp::self()->hasCursorInArgs() || doc->url().hasQuery());
viewMan->createView(doc, this);
}
m_group = groupname; // used for restroing view configs later
......
......@@ -13,6 +13,7 @@
#include <QRegularExpression>
#include <QString>
#include <QUrl>
#include <QUrlQuery>
/**
* Represents a file to be opened, consisting of its URL and the cursor to jump to.
......@@ -89,6 +90,35 @@ public:
* - remote urls, e.g. sftp://1.2.3.4:22/path/to/some/file
*/
url = QUrl::fromUserInput(path, QString(), QUrl::AssumeLocalFile);
/**
* Set cursor position if we can extract from URL query string
*/
if (url.hasQuery()) {
QUrlQuery urlQuery(url);
QString lineStr = urlQuery.queryItemValue(QStringLiteral("line"));
QString columnStr = urlQuery.queryItemValue(QStringLiteral("column"));
int line = 0;
int column = 0;
bool setCursor = false;
if (!lineStr.isEmpty()) {
line = lineStr.toInt();
line > 0 && line--;
setCursor = true;
}
if (!columnStr.isEmpty()) {
column = columnStr.toInt();
column > 0 && column--;
setCursor = true;
}
if (setCursor) {
cursor.setPosition(line, column);
}
}
}
/**
......
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