diff options
-rw-r--r-- | doc/katarakt.txt | 5 | ||||
-rw-r--r-- | share/katarakt.ini | 1 | ||||
-rwxr-xr-x | share/synctex-katarakt-vim.py | 2 | ||||
-rw-r--r-- | src/config.cpp | 9 | ||||
-rw-r--r-- | src/config.h | 3 | ||||
-rw-r--r-- | src/dbus/dbus.cpp | 25 | ||||
-rw-r--r-- | src/dbus/dbus.h | 10 | ||||
-rw-r--r-- | src/dbus/source_correlate.cpp | 11 | ||||
-rw-r--r-- | src/dbus/source_correlate.h | 8 | ||||
-rw-r--r-- | src/main.cpp | 27 |
10 files changed, 95 insertions, 6 deletions
diff --git a/doc/katarakt.txt b/doc/katarakt.txt index cc34ccb..bd7e7f6 100644 --- a/doc/katarakt.txt +++ b/doc/katarakt.txt @@ -43,6 +43,8 @@ OPTIONS Quit on initialization failure. *-h*, *--help* :: Print help and exit. +*--single-instance* 'true'|'false':: + Sets *single_instance_per_file* for the present katarakt instance only. CONFIGURATION ------------- @@ -168,6 +170,9 @@ VARIABLES 'bool' *quit_on_init_fail* :: false: Quit katarakt if the document fails to open. +'bool' *single_instance_per_file* :: + If set and katarakt is called with a file that is already shown in another + katarakt instance, then the other katarakt window is activated instead. 'string' *icon_theme* :: The name of your icon theme. Fill in if auto detection fails. diff --git a/share/katarakt.ini b/share/katarakt.ini index afb558a..e3d6a36 100644 --- a/share/katarakt.ini +++ b/share/katarakt.ini @@ -20,6 +20,7 @@ icon_theme= click_link_button=1 drag_view_button=2 select_text_button=1 +single_instance_per_file=false [Keys] set_presentation_layout=1 diff --git a/share/synctex-katarakt-vim.py b/share/synctex-katarakt-vim.py index d01dccf..d655ee5 100755 --- a/share/synctex-katarakt-vim.py +++ b/share/synctex-katarakt-vim.py @@ -100,7 +100,7 @@ except IndexError: vim_session = session_name vim_view_keybind = "ZE" -pdfprocess = subprocess.Popen(['katarakt', pdf_filename]) +pdfprocess = subprocess.Popen(['katarakt', '--single-instance', 'false', pdf_filename]) pdf_pid = pdfprocess.pid view_command = ("qdbus katarakt.pid%d" % pdf_pid + diff --git a/src/config.cpp b/src/config.cpp index 950dc1a..ad8f7d1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -29,6 +29,7 @@ CFG::CFG() : defaults["rect_expansion"] = 2; // viewer options defaults["quit_on_init_fail"] = false; + defaults["single_instance_per_file"] = false; defaults["icon_theme"] = ""; // mouse buttons @@ -145,6 +146,14 @@ bool CFG::has_tmp_value(const char *key) const { return tmp_values.contains(key); } +QVariant CFG::get_most_current_value(const char *key) const { + if (tmp_values.contains(key)) { + return tmp_values[key]; + } else { + return settings.value(QString("Settings/") + key, defaults[key]); + } +} + QStringList CFG::get_keys(const char *action) const { return settings.value(QString("Keys/") + action, keys[action]).toStringList(); } diff --git a/src/config.h b/src/config.h index c85d8e3..caa62ff 100644 --- a/src/config.h +++ b/src/config.h @@ -32,6 +32,9 @@ public: void set_tmp_value(const char *key, QVariant value); bool has_tmp_value(const char *key) const; + /** Return tmp_value (if set) but fall back to normal settings */ + QVariant get_most_current_value(const char *key) const; + QStringList get_keys(const char *action) const; }; diff --git a/src/dbus/dbus.cpp b/src/dbus/dbus.cpp index 6b746e4..a02fb6d 100644 --- a/src/dbus/dbus.cpp +++ b/src/dbus/dbus.cpp @@ -4,6 +4,13 @@ #include <QDBusConnection> #include <QApplication> +#include <QDBusConnectionInterface> +#include <QDBusInterface> +#include <QRegExp> +#include <QString> +#include <QStringList> +#include <QFileInfo> + #include <iostream> @@ -32,3 +39,21 @@ void dbus_init(Viewer *viewer) { } } } + +bool activate_katarakt_with_file(QString file) { + QString filepath = QFileInfo(file).absoluteFilePath(); + QDBusConnection bus = QDBusConnection::sessionBus(); + QStringList services = bus.interface()->registeredServiceNames().value(); + QStringList katarakts = services.filter(QRegExp("^katarakt\\.pid")); + foreach (const QString& katarakt_service, katarakts) { + QDBusInterface dbus_iface(katarakt_service, "/", "katarakt.SourceCorrelate", bus); + QDBusReply<QString> reply = dbus_iface.call("filepath"); + if (reply.isValid()) { + if (reply.value() == filepath) { + dbus_iface.call("focus"); + return true; + } + } + } + return false; +} diff --git a/src/dbus/dbus.h b/src/dbus/dbus.h index 8d0f482..66c3445 100644 --- a/src/dbus/dbus.h +++ b/src/dbus/dbus.h @@ -1,6 +1,7 @@ #ifndef DBUS_H #define DBUS_H +#include <QString> class Viewer; /** @@ -10,4 +11,13 @@ class Viewer; */ void dbus_init(Viewer *viewer); +/** + * Try to find a katarakt instance that has file open + * If such a instance is found, it is activaed using the focus() method via + * dbus and true is returned (false otherwise). + * + * This method works without dbus_init() being called before! + */ +bool activate_katarakt_with_file(QString file); + #endif /* DBUS_H */ diff --git a/src/dbus/source_correlate.cpp b/src/dbus/source_correlate.cpp index a1d349f..9105276 100644 --- a/src/dbus/source_correlate.cpp +++ b/src/dbus/source_correlate.cpp @@ -46,3 +46,14 @@ void SourceCorrelate::emit_edit_signal(int page, int x, int y) { #endif emit edit(file, page, x, y); } + +void SourceCorrelate::focus() { + viewer->activateWindow(); +} + +/** The full filepath of the opened file + */ +QString SourceCorrelate::filepath() { + QFileInfo file = QFileInfo(viewer->get_res()->get_file()); + return file.absoluteFilePath(); +} diff --git a/src/dbus/source_correlate.h b/src/dbus/source_correlate.h index 10b0483..b02302e 100644 --- a/src/dbus/source_correlate.h +++ b/src/dbus/source_correlate.h @@ -21,6 +21,14 @@ public slots: */ void view(QString filename, int page, double x, double y); + /** Lets the katarakt window ask the window manager for the focus + */ + void focus(); + + /** The full filepath of the opened file + */ + QString filepath(); + signals: /** Emitted, if the user requests to edit the source code for a * specific position on a specific page. diff --git a/src/main.cpp b/src/main.cpp index dc3cb8d..f2234c2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,11 +17,12 @@ static void print_help(char *name) { cout << " " << name << " ([OPTIONS] FILE|(-u URL))*" << endl; cout << endl; cout << "Options:" << endl; - cout << " -u, --url Open a URL instead of a local file" << endl; - cout << " -p, --page NUM Start showing page NUM" << endl; - cout << " -f, --fullscreen Start in fullscreen mode" << endl; - cout << " -q, --quit Quit on initialization failure" << endl; - cout << " -h, --help Print this help and exit" << endl; + cout << " -u, --url Open a URL instead of a local file" << endl; + cout << " -p, --page NUM Start showing page NUM" << endl; + cout << " -f, --fullscreen Start in fullscreen mode" << endl; + cout << " -q, --quit Quit on initialization failure" << endl; + cout << " -h, --help Print this help and exit" << endl; + cout << " --single-instance true|false Whether to have a single instance per file" << endl; } int main(int argc, char *argv[]) { @@ -34,6 +35,7 @@ int main(int argc, char *argv[]) { {"fullscreen", no_argument, NULL, 'f'}, {"quit", no_argument, NULL, 'q'}, {"help", no_argument, NULL, 'h'}, + {"single-instance", required_argument, NULL, 0}, {NULL, 0, NULL, 0} }; int option_index = 0; @@ -44,6 +46,15 @@ int main(int argc, char *argv[]) { break; } switch (c) { + case 0: { + const char* option_name = long_options[option_index].name; + if (!strcmp(option_name, "single-instance")) { + // (according to QVariant) any string can be converted to + // bool, so no type check needed here + CFG::get_instance()->set_tmp_value("single_instance_per_file", optarg); + } + break; + } case 'u': download_url = true; break; @@ -89,6 +100,12 @@ int main(int argc, char *argv[]) { } // else no argument given, "open" empty string + if (CFG::get_instance()->get_most_current_value("single_instance_per_file").toBool()) { + if (activate_katarakt_with_file(file)) { + return 0; + } + } + Viewer katarakt(file); if (!katarakt.is_valid()) { return 1; |