diff --git a/app/urlinfo.h b/app/urlinfo.h new file mode 100644 index 0000000000..529608ee64 --- /dev/null +++ b/app/urlinfo.h @@ -0,0 +1,127 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Milian Wolff + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef URLINFO_H +#define URLINFO_H + +#include + +#include +#include +#include +#include +#include + +/** + * Represents a file to be opened, consisting of its URL and the cursor to jump to. + */ +class UrlInfo +{ +public: + /** + * Parses a file path argument and determines its line number and column and full path + * @param path path passed on e.g. command line to parse into an URL + */ + UrlInfo(QString path = QString()) + : cursor(KTextEditor::Cursor::invalid()) + { + /** + * construct url: + * - make relative paths absolute using the current working directory + * - prefer local file, if in doubt! + */ + url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile); + + /** + * in some cases, this will fail, e.g. if you have line/column specs like test.c:10:1 + * => fallback: assume a local file and just convert it to an url + */ + if (!url.isValid()) { + /** + * create absolute file path, we will e.g. pass this over dbus to other processes + */ + url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(path)); + } + + /** + * Allow opening specific lines in documents, like mydoc.cpp:10 + * also supports columns, i.e. mydoc.cpp:10:42 + * ignores trailing colons, as compile errors often use that format + */ + if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) { + /** + * update path from url, might have been file://... + */ + path = url.toLocalFile(); + + /** + * try to match the line/colum spec, else we are done here + */ + const auto match = QRegularExpression(QStringLiteral(":(\\d+)(?::(\\d+))?:?$")).match(path); + if (!match.isValid()) + return; + + /** + * cut away the line/column specification from the path and update the url + */ + path.chop(match.capturedLength()); + url = QUrl::fromLocalFile(path); + + /** + * set right cursor position + */ + int line = match.captured(1).toInt() - 1; + // don't use an invalid column when the line is valid + int column = qMax(0, match.captured(2).toInt() - 1); + cursor = {line, column}; + } + } + + /** + * url computed out of the passed path + */ + QUrl url; + + /** + * initial cursor position, if any found inside the path as line/colum specification at the end + */ + KTextEditor::Cursor cursor; +}; + +QDataStream& operator<<(QDataStream& stream, const UrlInfo& info) +{ + stream << info.url; + stream << info.cursor.line(); + stream << info.cursor.column(); + return stream; +} + +QDataStream& operator>>(QDataStream& stream, UrlInfo& info) +{ + stream >> info.url; + int line, column; + stream >> line; + stream >> column; + info.cursor.setLine(line); + info.cursor.setColumn(column); + return stream; +} + +#endif // URLINFO_H