summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac4
-rw-r--r--data/.gitignore1
-rw-r--r--data/Makefile.am9
-rw-r--r--data/tp-monitor-gtk.gschema.xml10
-rw-r--r--src/Makefile.am2
-rw-r--r--src/gui_config.cc32
-rw-r--r--src/gui_config.hh21
-rw-r--r--src/gui_gtk.cc50
-rw-r--r--src/gui_main.hh3
-rw-r--r--src/gui_qt.cc49
-rw-r--r--src/monitor-gui.cc15
12 files changed, 187 insertions, 11 deletions
diff --git a/Makefile.am b/Makefile.am
index 770835c..50d865f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,4 +4,4 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.sub configure depcomp install-sh ltmain.sh \
missing config.rpath mkinstalldirs compile
-SUBDIRS = src test
+SUBDIRS = src data test
diff --git a/configure.ac b/configure.ac
index 73270bc..149af5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -122,6 +122,8 @@ gtk_need="gtk+-3.0 >= 3.20"
PKG_CHECK_EXISTS([$gtk_need],
[PKG_CHECK_MODULES([GTK], [$gtk_need])
have_gtk=1])
+AS_IF([test x$have_gtk == x1],
+ [GLIB_GSETTINGS])
AM_CONDITIONAL([HAVE_GTK],[test "x$have_gtk" = "x1"])
# QT
@@ -138,6 +140,6 @@ AM_CONDITIONAL([HAVE_QT],[test "x$have_qt" = "x1"])
# Finish up
AC_CONFIG_HEADERS([src/config.h])
-AC_OUTPUT([Makefile src/Makefile test/Makefile])
+AC_OUTPUT([Makefile src/Makefile data/Makefile test/Makefile])
AC_MSG_NOTICE([SSL library used: $ssl_name])
diff --git a/data/.gitignore b/data/.gitignore
new file mode 100644
index 0000000..576d028
--- /dev/null
+++ b/data/.gitignore
@@ -0,0 +1 @@
+/*.gschema.valid
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..98066a8
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,9 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+
+gsettings_SCHEMAS = tp-monitor-gtk.gschema.xml
+EXTRA_DIST = $(gsettings_SCHEMAS)
+
+if HAVE_GTK
+@GSETTINGS_RULES@
+endif
diff --git a/data/tp-monitor-gtk.gschema.xml b/data/tp-monitor-gtk.gschema.xml
new file mode 100644
index 0000000..9dde64c
--- /dev/null
+++ b/data/tp-monitor-gtk.gschema.xml
@@ -0,0 +1,10 @@
+<schemalist>
+ <schema id="org.the_jk.tp.Monitor" path="/org/the_jk/tp/Monitor/">
+ <key name="connect" type="s">
+ <default>""</default>
+ <description>
+ Last monitor host connected to
+ </description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/src/Makefile.am b/src/Makefile.am
index 37d29fa..9cd0884 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,7 +55,7 @@ tp_monitor_SOURCES = monitor-cmd.cc
tp_monitor_LDADD = libmonitor.a libtp.a @THREAD_LIBS@
tp_monitor_CXXFLAGS = $(AM_CXXFLAGS) -DVERSION='"@VERSION@"' @THREAD_CFLAGS@
-libmonitor_gui_a_SOURCES = monitor-gui.cc gui_hexdump.cc
+libmonitor_gui_a_SOURCES = monitor-gui.cc gui_hexdump.cc gui_config.cc
libmonitor_gui_a_CXXFLAGS = $(AM_CXXFLAGS) -DVERSION='"@VERSION@"' \
@THREAD_CFLAGS@
diff --git a/src/gui_config.cc b/src/gui_config.cc
new file mode 100644
index 0000000..5fa5506
--- /dev/null
+++ b/src/gui_config.cc
@@ -0,0 +1,32 @@
+// -*- mode: c++; c-basic-offset: 2; -*-
+
+#include "common.hh"
+
+#include "gui_config.hh"
+
+#include <string.h>
+
+bool GuiConfig::load_name(std::string const& UNUSED(name)) {
+ return false;
+}
+
+bool GuiConfig::load_file(std::string const& UNUSED(filename)) {
+ return false;
+}
+
+bool GuiConfig::get(std::string const& key, bool fallback) {
+ auto ret = static_cast<Config*>(this)->get(key, nullptr);
+ if (!ret) return fallback;
+ return strcmp(ret, "true") == 0;
+}
+
+bool GuiConfig::good() const {
+ return true;
+}
+
+std::string const& GuiConfig::last_error() const {
+ return EMPTY;
+}
+
+// static
+std::string const GuiConfig::EMPTY;
diff --git a/src/gui_config.hh b/src/gui_config.hh
new file mode 100644
index 0000000..97b343f
--- /dev/null
+++ b/src/gui_config.hh
@@ -0,0 +1,21 @@
+// -*- mode: c++; c-basic-offset: 2; -*-
+
+#ifndef GUI_CONFIG_HH
+#define GUI_CONFIG_HH
+
+#include "config.hh"
+
+class GuiConfig : public Config {
+public:
+ bool load_name(std::string const& name) override;
+ bool load_file(std::string const& filename) override;
+ bool get(std::string const& key, bool fallback) override;
+
+ bool good() const override;
+ std::string const& last_error() const override;
+
+private:
+ static const std::string EMPTY;
+};
+
+#endif // GUI_CONFIG_HH
diff --git a/src/gui_gtk.cc b/src/gui_gtk.cc
index 99172e3..4c1cc13 100644
--- a/src/gui_gtk.cc
+++ b/src/gui_gtk.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "gui_about.hh"
+#include "gui_config.hh"
#include "gui_form.hh"
#include "gui_formapply.hh"
#include "gui_listmodel.hh"
@@ -510,11 +511,53 @@ private:
std::unordered_map<Attribute, GtkTextTag*> tags_;
};
+class GtkConfig : public GuiConfig {
+public:
+ GtkConfig()
+ : settings_(g_settings_new("org.the_jk.tp.Monitor")) {
+ }
+
+ ~GtkConfig() override {
+ g_settings_sync();
+ }
+
+ using Config::get;
+ std::string const& get(std::string const& key,
+ std::string const& fallback) override {
+ auto variant = g_settings_get_user_value(settings_.get(), key.c_str());
+ if (!variant) return fallback;
+ memory_[key] = g_variant_get_string(variant, nullptr);
+ g_variant_unref(variant);
+ return memory_[key];
+ }
+ char const* get(std::string const& key,
+ char const* fallback) override {
+ auto variant = g_settings_get_user_value(settings_.get(), key.c_str());
+ if (!variant) return fallback;
+ memory_[key] = g_variant_get_string(variant, nullptr);
+ g_variant_unref(variant);
+ return memory_[key].c_str();
+ }
+ bool is_set(std::string const& key) override {
+ auto variant = g_settings_get_user_value(settings_.get(), key.c_str());
+ if (!variant) return false;
+ g_variant_unref(variant);
+ return true;
+ }
+ void set(std::string const& key, std::string const& value) override {
+ g_settings_set_string(settings_.get(), key.c_str(), value.c_str());
+ }
+
+private:
+ shared_gobject<GSettings> settings_;
+ std::unordered_map<std::string, std::string> memory_;
+};
+
class GtkGuiMain : public virtual GuiMain, public GtkGuiWindow {
public:
GtkGuiMain(std::string const& title, uint32_t width, uint32_t height)
: title_(title), width_(width), height_(height), split_(0.5),
- menu_(nullptr), statusbar_(nullptr) {
+ config_(new GtkConfig()), menu_(nullptr), statusbar_(nullptr) {
}
void set_menu(GuiMenu* menu) override {
@@ -643,6 +686,10 @@ private:
return true;
}
+ Config* config() override {
+ return config_.get();
+ }
+
std::string title_;
uint32_t width_;
uint32_t height_;
@@ -651,6 +698,7 @@ private:
shared_gobject<MainApp> app_;
shared_gobject<ListModel> listmodel_;
std::unique_ptr<AttributedText> package_;
+ std::unique_ptr<GtkConfig> config_;
Observers<GuiMain::Listener*> observers_;
GuiMenu* menu_;
GuiStatusBar* statusbar_;
diff --git a/src/gui_main.hh b/src/gui_main.hh
index af35106..83c0f8d 100644
--- a/src/gui_main.hh
+++ b/src/gui_main.hh
@@ -10,6 +10,7 @@
#include "gui_attrtext.hh"
#include "gui_window.hh"
+class Config;
class GuiListModel;
class GuiMenu;
class GuiStatusBar;
@@ -59,6 +60,8 @@ public:
virtual void add_to_clipboard(std::string const& data,
std::string const& mimetype = "") = 0;
+ virtual Config* config() = 0;
+
protected:
GuiMain() {}
};
diff --git a/src/gui_qt.cc b/src/gui_qt.cc
index dcfd320..d54975e 100644
--- a/src/gui_qt.cc
+++ b/src/gui_qt.cc
@@ -19,6 +19,7 @@
#include <QMimeData>
#include <QProgressBar>
#include <QPushButton>
+#include <QSettings>
#include <QSocketNotifier>
#include <QSplitter>
#include <QStatusBar>
@@ -35,6 +36,7 @@
#include <vector>
#include "gui_about.hh"
+#include "gui_config.hh"
#include "gui_form.hh"
#include "gui_formapply.hh"
#include "gui_htmlattrtext.hh"
@@ -315,12 +317,50 @@ private:
GuiListModel* const model_;
};
+class QtGuiConfig : public GuiConfig {
+public:
+ QtGuiConfig()
+ : settings_(new QSettings("org.the_jk", "tp.Monitor")) {
+ }
+
+ ~QtGuiConfig() override {
+ settings_->sync();
+ }
+
+ using Config::get;
+ std::string const& get(std::string const& key,
+ std::string const& fallback) override {
+ memory_[key] = settings_->value(QString::fromStdString(key),
+ QString::fromStdString(fallback))
+ .toString().toStdString();
+ return memory_[key];
+ }
+ char const* get(std::string const& key, char const* fallback) override {
+ auto k = QString::fromStdString(key);
+ if (!settings_->contains(k)) return fallback;
+ memory_[key] = settings_->value(k).toString().toStdString();
+ return memory_[key].c_str();
+ }
+ bool is_set(std::string const& key) override {
+ return settings_->contains(QString::fromStdString(key));
+ }
+
+ void set(std::string const& key, std::string const& value) override {
+ settings_->setValue(QString::fromStdString(key),
+ QString::fromStdString(value));
+ }
+
+private:
+ std::unique_ptr<QSettings> settings_;
+ std::unordered_map<std::string, std::string> memory_;
+};
+
class QtGuiMain : public GuiMain, public QtGuiWindow {
public:
QtGuiMain(std::string const& title, uint32_t width, uint32_t height)
: title_(title), width_(width), height_(height), split_(0.7),
- menu_(nullptr), statusbar_(nullptr), splitter_(nullptr),
- top_(nullptr), bottom_(nullptr) {
+ menu_(nullptr), statusbar_(nullptr), config_(new QtGuiConfig()),
+ splitter_(nullptr), top_(nullptr), bottom_(nullptr) {
}
void set_menu(GuiMenu* menu) override {
@@ -438,6 +478,10 @@ public:
clipboard->setMimeData(mimedata);
}
+ Config* config() override {
+ return config_.get();
+ }
+
private:
static bool valid_utf8(std::string const& data) {
QTextCodec::ConverterState state;
@@ -480,6 +524,7 @@ private:
std::unique_ptr<QMainWindow> main_;
std::unique_ptr<SizeHintLayout> layout_;
std::unique_ptr<QWidget> center_;
+ std::unique_ptr<QtGuiConfig> config_;
QSplitter* splitter_;
QWidget* top_;
QTextEdit* bottom_;
diff --git a/src/monitor-gui.cc b/src/monitor-gui.cc
index dacc318..fbbcfb9 100644
--- a/src/monitor-gui.cc
+++ b/src/monitor-gui.cc
@@ -7,6 +7,7 @@
#include <unordered_map>
#include <vector>
+#include "config.hh"
#include "gui_about.hh"
#include "gui_formapply.hh"
#include "gui_hexdump.hh"
@@ -242,23 +243,26 @@ private:
class ConnectFormDelegate : public GuiFormApply::Delegate {
public:
- ConnectFormDelegate(Monitor* monitor)
- : monitor_(monitor) {
+ ConnectFormDelegate(Monitor* monitor, Config* config)
+ : monitor_(monitor), config_(config) {
}
void apply(GuiFormApply* form) override {
std::string host;
uint16_t port;
- if (!parse_address(form->get_string("address"), &host, &port)) {
+ auto const& addr = form->get_string("address");
+ if (!parse_address(addr, &host, &port)) {
form->set_error("Invalid address, expects HOST[:PORT]");
form->applied(false);
return;
}
+ config_->set("connect", addr);
monitor_->connect(host, port);
}
private:
Monitor* monitor_;
+ Config* config_;
};
public:
@@ -317,7 +321,7 @@ public:
} else if (id == ACTION_CONNECT) {
setup_monitor();
auto dlg = std::unique_ptr<GuiFormApply::Delegate>(
- new ConnectFormDelegate(monitor_.get()));
+ new ConnectFormDelegate(monitor_.get(), main_->config()));
auto lst = std::unique_ptr<GuiFormApply::Listener>(
new ConnectFormListener());
connect_.reset(
@@ -325,7 +329,8 @@ public:
"Enter address for monitor to connect to",
"Connect",
dlg.get()));
- connect_->add_string("address", "Address", "");
+ connect_->add_string("address", "Address",
+ main_->config()->get("connect", ""));
connect_->add_listener(lst.get());
if (connect_->show(main_.get())) {
monitor_->attach();