[california] Remember last displayed view when starting: Bug #730603
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california] Remember last displayed view when starting: Bug #730603
- Date: Fri, 30 May 2014 01:22:46 +0000 (UTC)
commit 056878374f3e6f387f8736c26923a93ed24b121a
Author: Jim Nelson <jim yorba org>
Date: Thu May 29 18:21:58 2014 -0700
Remember last displayed view when starting: Bug #730603
Last displayed view (month, week, etc.) is stored in GSettings via
bound properties.
Makefile.am | 2 +
configure.ac | 2 +
data/Makefile.am | 12 +++++
data/org.yorba.california.gschema.xml | 14 ++++++
src/Makefile.am | 1 +
src/application/california-application.vala | 50 +++++++++++++++++++++-
src/application/california-settings.vala | 61 +++++++++++++++++++++++++++
src/base/base-object.vala | 17 +++++++
src/calendar/calendar-system.vala | 2 +-
src/host/host-main-window.vala | 25 ++++++++++-
src/view/month/month-controller.vala | 7 +++
src/view/view-controllable.vala | 7 +++
src/view/week/week-controller.vala | 7 +++
13 files changed, 203 insertions(+), 4 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index d691c19..b4b1897 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,6 +25,8 @@ EXTRA_DIST = \
intltool-update.in\
$(NULL)
+BUILT_SOURCES =
+
CLEANFILES =
DISTCLEANFILES = \
diff --git a/configure.ac b/configure.ac
index 7a15354..8cdcbe2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,8 @@ PKG_CHECK_MODULES(CALIFORNIA, [
AC_SUBST(CALIFORNIA_CFLAGS)
AC_SUBST(CALIFORNIA_LIBS)
+GLIB_GSETTINGS
+
#
# configure switches
#
diff --git a/data/Makefile.am b/data/Makefile.am
index 3629caa..5fa5269 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -5,13 +5,25 @@ data_desktop_DATA = $(data_desktop_in_files:.desktop.in=.desktop)
data_appdatadir = $(datadir)/appdata
data_appdata_DATA = data/california.appdata.xml
+gsettings_SCHEMAS = data/org.yorba.california.gschema.xml
+ GSETTINGS_RULES@
+
+# Local build of California's GSettings schema to allow executing from build dir
+data/gschemas.compiled: data/org.yorba.california.gschema.xml
+ @echo Building local GSettings schema...
+ @glib-compile-schemas data/
+
+BUILT_SOURCES += data/gschemas.compiled
+
EXTRA_DIST += \
$(data_desktop_in_files) \
data/california.appdata.xml \
+ data/org.yorba.california.gschema.xml \
$(NULL)
CLEANFILES += \
$(data_desktop_DATA) \
+ data/gschemas.compiled \
$(NULL)
DISTCLEANFILES += \
diff --git a/data/org.yorba.california.gschema.xml b/data/org.yorba.california.gschema.xml
new file mode 100644
index 0000000..88cedb0
--- /dev/null
+++ b/data/org.yorba.california.gschema.xml
@@ -0,0 +1,14 @@
+<schemalist>
+
+<schema id="org.yorba.california" path="/org/yorba/california/">
+ <key name="calendar-view" type="s">
+ <default>"month"</default>
+ <summary>Current calendar view</summary>
+ <description>
+ Legal values include "week" and "month".
+ </description>
+ </key>
+</schema>
+
+</schemalist>
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 67612c2..5cdbef3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,6 +25,7 @@ california_VALASOURCES = \
application/california-application.vala \
application/california-commandline.vala \
application/california-resource.vala \
+ application/california-settings.vala \
application/main.vala \
\
backing/backing.vala \
diff --git a/src/application/california-application.vala b/src/application/california-application.vala
index 996ce75..711c3e0 100644
--- a/src/application/california-application.vala
+++ b/src/application/california-application.vala
@@ -58,8 +58,50 @@ public class Application : Gtk.Application {
{ ACTION_PROCESS_FILE, on_process_file, "s" }
};
+ /**
+ * The executable's location on the filesystem.
+ *
+ * This will be null until { link local_command_line} is executed.
+ */
+ public File? exec_file { get; private set; default = null; }
+
+ /**
+ * The executable's parent directory on the filesystem.
+ *
+ * This will be null until { link local_command_line} is executed.
+ */
+ public File? exec_dir { owned get { return (exec_file != null) ? exec_file.get_parent() : null; } }
+
+ /**
+ * The configured prefix directory as a File.
+ */
+ public File prefix_dir { owned get { return File.new_for_path(PREFIX); } }
+
+ /**
+ * Whether or not the running executable is the installed executable (if installed at all).
+ *
+ * False if { link local_command_line} hasn't executed yet.
+ */
+ public bool is_installed {
+ get {
+ return (exec_dir != null) ? exec_dir.has_prefix(prefix_dir) : false;
+ }
+ }
+
+ /**
+ * If not installed, returns the root of the build directory (which may not be the location
+ * of the main executable).
+ *
+ * null if { link is_installed} is true.
+ */
+ public File? build_root_dir {
+ owned get {
+ // currently the build system stores the exec in the src/ directory
+ return (!is_installed && exec_dir != null) ? exec_dir.get_parent() : null;
+ }
+ }
+
private Host.MainWindow? main_window = null;
- private File? exec_file = null;
private Application() {
Object (application_id: ID);
@@ -107,6 +149,7 @@ public class Application : Gtk.Application {
// unit initialization
try {
+ Settings.init();
Host.init();
Manager.init();
Activator.init();
@@ -128,6 +171,7 @@ public class Application : Gtk.Application {
Activator.terminate();
Manager.terminate();
Host.terminate();
+ Settings.terminate();
base.shutdown();
}
@@ -145,7 +189,9 @@ public class Application : Gtk.Application {
base.activate();
}
- // Presents a modal error dialog to the user
+ /*
+ * Presents a modal error dialog to the user.
+ */
public void error_message(string msg) {
Gtk.MessageDialog dialog = new Gtk.MessageDialog(main_window, Gtk.DialogFlags.MODAL,
Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, "%s", msg);
diff --git a/src/application/california-settings.vala b/src/application/california-settings.vala
new file mode 100644
index 0000000..226c03e
--- /dev/null
+++ b/src/application/california-settings.vala
@@ -0,0 +1,61 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California {
+
+/**
+ * Various application settings for California (stored in GSettings) available as a singleton.
+ */
+
+public class Settings : BaseObject {
+ public const string PROP_CALENDAR_VIEW = "calendar-view";
+
+ // GSettings schema identifier.
+ private const string SCHEMA_ID = "org.yorba.california";
+
+ // schema key ids may be the same as property names, but want to keep them different in case
+ // one or the other changes
+ private const string KEY_CALENDAR_VIEW = "calendar-view";
+
+ public static Settings instance { get; private set; }
+
+ public string calendar_view { get; set; }
+
+ private GLib.Settings settings;
+
+ private Settings() {
+ // construct after env is in place
+ settings = new GLib.Settings(SCHEMA_ID);
+
+ // bind GSettings values to properties here, which callers may access directly or bind to
+ // themselves (with a bit more type safety)
+ settings.bind(KEY_CALENDAR_VIEW, this, PROP_CALENDAR_VIEW, SettingsBindFlags.DEFAULT);
+ }
+
+ internal static void init() throws Error {
+ // this needs to be available before initialization
+ assert(Application.instance.exec_file != null);
+
+ // if not running installed executable, point GSettings to our copy in the build directory
+ if (!Application.instance.is_installed) {
+ File schema_dir = Application.instance.build_root_dir.get_child("data");
+ Environment.set_variable("GSETTINGS_SCHEMA_DIR", schema_dir.get_path(), true);
+ }
+
+ instance = new Settings();
+ }
+
+ internal static void terminate() {
+ instance = null;
+ }
+
+ public override string to_string() {
+ return get_class().get_type().name();
+ }
+}
+
+}
+
diff --git a/src/base/base-object.vala b/src/base/base-object.vala
index 99025b4..97779dd 100644
--- a/src/base/base-object.vala
+++ b/src/base/base-object.vala
@@ -4,6 +4,10 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+// It's either this or double-unref Binding objects; see
+// https://bugzilla.gnome.org/show_bug.cgi?id=730967
+extern void g_binding_unbind(Binding *binding);
+
namespace California {
/**
@@ -15,6 +19,19 @@ public abstract class BaseObject : Object {
}
/**
+ * Helper for unbinding properties until g_binding_unbind() is bound.
+ *
+ * See [[https://bugzilla.gnome.org/show_bug.cgi?id=730967]]
+ */
+ public static void unbind_property(ref Binding? binding) {
+ if (binding == null)
+ return;
+
+ g_binding_unbind(binding);
+ binding = null;
+ }
+
+ /**
* Returns a string representation of the object ''for debugging and logging only''.
*
* String conversion for other purposes (user labels, serialization, etc.) should be handled
diff --git a/src/calendar/calendar-system.vala b/src/calendar/calendar-system.vala
index 8bd745e..090d695 100644
--- a/src/calendar/calendar-system.vala
+++ b/src/calendar/calendar-system.vala
@@ -91,7 +91,7 @@ public class System : BaseObject {
*/
public signal void timezone_changed(Timezone old_timezone, Timezone new_timezone);
- private Settings system_clock_format_schema = new Settings(CLOCK_FORMAT_SCHEMA);
+ private GLib.Settings system_clock_format_schema = new GLib.Settings(CLOCK_FORMAT_SCHEMA);
private uint date_timer_id = 0;
private System() {
diff --git a/src/host/host-main-window.vala b/src/host/host-main-window.vala
index 579f169..ddb084a 100644
--- a/src/host/host-main-window.vala
+++ b/src/host/host-main-window.vala
@@ -51,6 +51,8 @@ public class MainWindow : Gtk.ApplicationWindow {
private Gtk.Stack view_stack = new Gtk.Stack();
private Gtk.HeaderBar headerbar = new Gtk.HeaderBar();
private Gtk.Button today = new Gtk.Button.with_label(_("_Today"));
+ private Binding view_stack_binding;
+ private Gee.HashSet<string> view_stack_ids = new Gee.HashSet<string>();
public MainWindow(Application app) {
Object (application: app);
@@ -161,6 +163,26 @@ public class MainWindow : Gtk.ApplicationWindow {
layout.pack_end(view_stack, true, true, 0);
add(layout);
+
+ // bind stack's visible child property to the settings for it, both ways ... because we want
+ // to initialize with the settings, use it as the source w/ SYNC_CREATE
+ view_stack_binding = Settings.instance.bind_property(Settings.PROP_CALENDAR_VIEW, view_stack,
+ "visible-child-name", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL,
+ transform_setting_to_calendar_view);
+
+ // to prevent storing the different children's names as the widget is destroyed (cleared,
+ // i.e. remove each one by one), unbind before that occurs
+ view_stack.destroy.connect(() => { BaseObject.unbind_property(ref view_stack_binding); });
+ }
+
+ // only allow known stack children ids through
+ private bool transform_setting_to_calendar_view(Binding binding, Value source, ref Value target) {
+ if (!view_stack_ids.contains(source.get_string()))
+ return false;
+
+ target = source;
+
+ return true;
}
public override void map() {
@@ -172,7 +194,8 @@ public class MainWindow : Gtk.ApplicationWindow {
}
private void add_controller(View.Controllable controller) {
- view_stack.add_titled(controller.get_container(), controller.title, controller.title);
+ view_stack_ids.add(controller.id);
+ view_stack.add_titled(controller.get_container(), controller.id, controller.title);
controller.get_container().show_all();
}
diff --git a/src/view/month/month-controller.vala b/src/view/month/month-controller.vala
index 60ef605..022173b 100644
--- a/src/view/month/month-controller.vala
+++ b/src/view/month/month-controller.vala
@@ -16,6 +16,8 @@ namespace California.View.Month {
public class Controller : BaseObject, View.Controllable {
public const string PROP_MONTH_OF_YEAR = "month-of-year";
+ public const string VIEW_ID = "month";
+
// number of Grids to keep in GtkStack and cache (in terms of months) ... this should be an
// even number, as it is halved to determine neighboring months depths
private const int CACHE_NEIGHBORS_COUNT = 4;
@@ -45,6 +47,11 @@ public class Controller : BaseObject, View.Controllable {
/**
* @inheritDoc
*/
+ public string id { get { return VIEW_ID; } }
+
+ /**
+ * @inheritDoc
+ */
public string title { get { return _("Month"); } }
/**
diff --git a/src/view/view-controllable.vala b/src/view/view-controllable.vala
index f25b92a..d004fb0 100644
--- a/src/view/view-controllable.vala
+++ b/src/view/view-controllable.vala
@@ -21,6 +21,13 @@ public interface Controllable : Object {
public const string PROP_FIRST_OF_WEEK = "first-of-week";
/**
+ * A short string uniquely identifying this view.
+ *
+ * Since this value will be persisted, it's important it does not change without good reason.
+ */
+ public abstract string id { get; }
+
+ /**
* A user-visible string (short) representing this view.
*/
public abstract string title { get; }
diff --git a/src/view/week/week-controller.vala b/src/view/week/week-controller.vala
index fbba969..ab602f2 100644
--- a/src/view/week/week-controller.vala
+++ b/src/view/week/week-controller.vala
@@ -13,6 +13,8 @@ namespace California.View.Week {
public class Controller : BaseObject, View.Controllable {
public const string PROP_WEEK = "week";
+ public const string VIEW_ID = "week";
+
private const int CACHE_NEIGHBORS_COUNT = 4;
private class ViewContainer : Gtk.Stack, View.Container {
@@ -32,6 +34,11 @@ public class Controller : BaseObject, View.Controllable {
/**
* @inheritDoc
*/
+ public string id { get { return VIEW_ID; } }
+
+ /**
+ * @inheritDoc
+ */
public string title { get { return _("Week"); } }
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]