diff --git a/README.md b/README.md
index bbc7caa83..405658817 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ pgrep -af hamster
###### Ubuntu (tested in 19.04 and 18.04)
```bash
-sudo apt install gettext intltool gconf2 gir1.2-gconf-2.0 python3-gi-cairo python3-distutils python3-dbus python3-xdg
+sudo apt install gettext intltool python3-gi-cairo python3-distutils python3-dbus python3-xdg
# and for documentation
sudo apt install gnome-doc-utils yelp
```
@@ -70,7 +70,7 @@ sudo zypper install gnome-doc-utils xml2po yelp
*RPM-based instructions below should be updated for python3 (issue [#369](https://github.com/projecthamster/hamster/issues/369)).*
-`yum install gettext intltool gnome-python2-gconf dbus-python`
+`yum install gettext intltool dbus-python`
If the hamster help pages are not accessible ("unable to open `help:hamster-time-tracker`"),
then a [Mallard](https://en.wikipedia.org/wiki/Mallard_(documentation))-capable help reader is required,
diff --git a/data/hamster.desktop.in.in b/data/hamster.desktop.in.in
index 24590c64f..a59274cd5 100644
--- a/data/hamster.desktop.in.in
+++ b/data/hamster.desktop.in.in
@@ -2,7 +2,7 @@
Version=1.0
Type=Application
Terminal=false
-_Name=Hamster Time Tracker
+_Name=Hamster
_Comment=Your personal time keeping tool
Icon=hamster
Exec=@BINDIR@/hamster
diff --git a/data/hamster.metainfo.xml b/data/hamster.metainfo.xml
index 5b6a177db..9667aa0f4 100644
--- a/data/hamster.metainfo.xml
+++ b/data/hamster.metainfo.xml
@@ -3,7 +3,7 @@
hamster
CC0-1.0
GPL-3.0+ and CC-BY-SA-3.0
- Hamster Time Tracker
+ Hamster
Your personal time keeping tool
@@ -39,6 +39,7 @@
https://github.com/projecthamster/hamster/blob/master/data/screenshots/overview2.png
+ hamster
https://github.com/projecthamster/hamster/wiki
hamster
diff --git a/data/hamster.schemas.in b/data/hamster.schemas.in
deleted file mode 100644
index a89e33510..000000000
--- a/data/hamster.schemas.in
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
- /schemas/apps/hamster/enable_timeout
- /apps/hamster/enable_timeout
- hamster
- bool
- true
-
- Stop tracking on idle
-
- Stop tracking current activity when computer becomes idle
-
-
-
-
- /schemas/apps/hamster/stop_on_shutdown
- /apps/hamster/stop_on_shutdown
- hamster
- bool
- false
-
- Stop tracking on shutdown
-
- Stop tracking current activity on shutdown
-
-
-
-
- /schemas/apps/hamster/notify_interval
- /apps/hamster/notify_interval
- hamster
- int
- 27
-
- Remind of current task every x minutes
-
- Remind of current task every specified amount of minutes.
- Set to 0 or greater than 120 to disable reminder.
-
-
-
-
- /schemas/apps/hamster/notify_on_idle
- /apps/hamster/notify_on_idle
- hamster
- bool
- false
-
- Also remind when no activity is set
-
- Also remind every notify_interval minutes if no activity
- has been started.
-
-
-
-
- /schemas/apps/hamster/day_start_minutes
- /apps/hamster/day_start_minutes
- hamster
- int
- 330
-
- At what time does the day start (defaults to 5:30AM)
-
- Activities will be counted as to belong to yesterday if
- the current time is less than the specified day start; and
- today, if it is over the time.
- Activities that span two days, will tip over to the side
- where the largest part of the activity is.
-
-
-
-
- /schemas/apps/hamster/workspace_tracking
- /apps/hamster/workspace_tracking
- hamster
- list
- string
- []
-
- Should workspace switch trigger activity switch
-
- List of enabled tracking methods. "name" will enable
- switching activities by name defined in workspace_mapping.
- "memory" will enable switching to the last activity when
- returning to a previous workspace.
-
-
-
-
- /schemas/apps/hamster/workspace_mapping
- /apps/hamster/workspace_mapping
- hamster
- list
- string
- []
-
- Switch activity on workspace change
-
- If switching by name is enabled, this list sets the activity
- names that should be switched to, workspaces represented by
- the index of item.
-
-
-
-
-
-
- /schemas/desktop/gnome/keybindings/hamster/activate_hamster_window
- /desktop/gnome/keybindings/hamster/activate_hamster_window
- hamster
- string
-
-
- Show / hide Time Tracker Window
- Keyboard shortcut for showing / hiding the Time Tracker window.
-
-
-
- /schemas/desktop/gnome/keybindings/hamster/action
- /desktop/gnome/keybindings/hamster/action
- hamster
- string
- hamster toggle
-
- Toggle hamster application window action
- Command for toggling visibility of the hamster application window.
-
-
-
- /schemas/desktop/gnome/keybindings/hamster/name
- /desktop/gnome/keybindings/hamster/name
- hamster
- string
- Toggle hamster application window
-
- Toggle hamster application window
- Toggle visibility of the hamster application window.
-
-
-
-
diff --git a/data/org.gnome.hamster.gschema.xml b/data/org.gnome.hamster.gschema.xml
new file mode 100644
index 000000000..dce4c1611
--- /dev/null
+++ b/data/org.gnome.hamster.gschema.xml
@@ -0,0 +1,22 @@
+
+
+
+ ""
+ The folder the last report was saved to
+
+ The folder the last report was saved to
+
+
+
+
+ 330
+ At what time does the day start (defaults to 5:30AM)
+
+ The hamster day of an activity is the civil date of start time,
+ provided start time is after day-start.
+ On the contrary, if start time is earlier than day-start,
+ then the activity belongs to the previous hamster day.
+
+
+
+
diff --git a/data/wscript_build b/data/wscript_build
index 56a85bf8d..0acf4a77d 100644
--- a/data/wscript_build
+++ b/data/wscript_build
@@ -25,14 +25,6 @@ for filename in ["hamster.desktop"]:
bld.add_group()
-# process .in files with intl_tool
-bld(features = 'intltool_in',
- source = 'hamster.schemas.in',
- target = 'hamster.schemas',
- install_path = bld.env.schemas_destination,
- podir = '../po',
- flags = ['-s', '-u'])
-
bld(features = 'intltool_in',
source = 'hamster.desktop.in',
install_path = '${DATADIR}/applications',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 00a91f702..fadbe6a41 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,7 +3,7 @@
[type: gettext/glade]data/date_range.ui
[type: gettext/glade]data/edit_activity.ui
data/hamster.desktop.in.in
-data/hamster.schemas.in
+data/org.gnome.hamster.gschema.xml
[type: gettext/glade]data/preferences.ui
[type: gettext/python]src/hamster-cli
src/hamster/about.py
diff --git a/src/hamster/about.py b/src/hamster/about.py
index 8069318f9..c6b3507ef 100644
--- a/src/hamster/about.py
+++ b/src/hamster/about.py
@@ -28,8 +28,7 @@ def __init__(self, parent = None):
about = gtk.AboutDialog()
self.window = about
infos = {
- "program-name" : _("Hamster Time Tracker"),
- "name" : _("Time Tracker"), #this should be deprecated in gtk 2.10
+ "program-name" : "Hamster",
"version" : runtime.version,
"comments" : _("Project Hamster — track your time"),
"copyright" : _("Copyright © 2007–2010 Toms Bauģis and others"),
diff --git a/src/hamster/lib/configuration.py b/src/hamster/lib/configuration.py
index 1ce5df639..b26f3984d 100644
--- a/src/hamster/lib/configuration.py
+++ b/src/hamster/lib/configuration.py
@@ -18,7 +18,6 @@
# along with Project Hamster. If not, see .
"""
-gconf part of this code copied from Gimmie (c) Alex Gravely via Conduit (c) John Stowers, 2006
License: GPLv2
"""
@@ -30,13 +29,11 @@
from xdg.BaseDirectory import xdg_data_home
import datetime as dt
+from gi.repository import Gio as gio
+from gi.repository import GLib as glib
from gi.repository import GObject as gobject
from gi.repository import Gtk as gtk
-import gi
-gi.require_version('GConf', '2.0')
-from gi.repository import GConf as gconf
-
class Controller(gobject.GObject):
__gsignals__ = {
@@ -191,149 +188,58 @@ def get_prefs_class():
dialogs = Dialogs()
-class GConfStore(gobject.GObject, Singleton):
+class GSettingsStore(gobject.GObject, Singleton):
"""
- Settings implementation which stores settings in GConf
+ Settings implementation which stores settings in GSettings
Snatched from the conduit project (http://live.gnome.org/Conduit)
"""
- GCONF_DIR = "/apps/hamster/"
- VALID_KEY_TYPES = (bool, str, int, list, tuple)
- DEFAULTS = {
- 'day_start_minutes' : 5 * 60 + 30, # At what time does the day start (5:30AM)
- 'overview_window_box' : [], # X, Y, W, H
- 'overview_window_maximized' : False, # Is overview window maximized
- 'standalone_window_box' : [], # X, Y, W, H
- 'standalone_window_maximized' : False, # Is overview window maximized
- 'last_report_folder' : "~", # Path to directory where the last report was saved
- }
__gsignals__ = {
- "conf-changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT))
+ "changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT))
}
+
def __init__(self):
gobject.GObject.__init__(self)
- self._client = gconf.Client.get_default()
- self._client.add_dir(self.GCONF_DIR[:-1], gconf.ClientPreloadType.PRELOAD_RECURSIVE)
- self._notifications = []
-
- def _fix_key(self, key):
- """
- Appends the GCONF_PREFIX to the key if needed
-
- @param key: The key to check
- @type key: C{string}
- @returns: The fixed key
- @rtype: C{string}
- """
- if not key.startswith(self.GCONF_DIR):
- return self.GCONF_DIR + key
- else:
- return key
+ self._settings = gio.Settings('org.gnome.Hamster')
- def _key_changed(self, client, cnxn_id, entry, data=None):
+ def _key_changed(self, client, key, data=None):
"""
- Callback when a gconf key changes
+ Callback when a GSettings key changes
"""
- key = self._fix_key(entry.key)[len(self.GCONF_DIR):]
- value = self._get_value(entry.value, self.DEFAULTS[key])
-
- self.emit('conf-changed', key, value)
-
-
- def _get_value(self, value, default):
- """calls appropriate gconf function by the default value"""
- vtype = type(default)
-
- if vtype is bool:
- return value.get_bool()
- elif vtype is str:
- return value.get_string()
- elif vtype is int:
- return value.get_int()
- elif vtype in (list, tuple):
- l = []
- for i in value.get_list():
- l.append(i.get_string())
- return l
-
- return None
+ value = self._settings.get_value(key)
+ self.emit('changed', key, value)
def get(self, key, default=None):
"""
Returns the value of the key or the default value if the key is
- not yet in gconf
+ not yet in GSettings
"""
-
- #function arguments override defaults
- if default is None:
- default = self.DEFAULTS.get(key, None)
- vtype = type(default)
-
- #we now have a valid key and type
- if default is None:
- logger.warn("Unknown key: %s, must specify default value" % key)
- return None
-
- if vtype not in self.VALID_KEY_TYPES:
- logger.warn("Invalid key type: %s" % vtype)
- return None
-
- #for gconf refer to the full key path
- key = self._fix_key(key)
-
- if key not in self._notifications:
- self._client.notify_add(key, self._key_changed, None)
- self._notifications.append(key)
-
- value = self._client.get(key)
+ value = self._settings.get_value(key)
if value is None:
- self.set(key, default)
- return default
-
- value = self._get_value(value, default)
- if value is not None:
- return value
+ logger.warn("Unknown GSettings key: %s" % key)
- logger.warn("Unknown gconf key: %s" % key)
- return None
+ return value.unpack()
def set(self, key, value):
"""
- Sets the key value in gconf and connects adds a signal
+ Sets the key value in GSettings and connects adds a signal
which is fired if the key changes
"""
logger.debug("Settings %s -> %s" % (key, value))
- if key in self.DEFAULTS:
- vtype = type(self.DEFAULTS[key])
- else:
- vtype = type(value)
-
- if vtype not in self.VALID_KEY_TYPES:
- logger.warn("Invalid key type: %s" % vtype)
- return False
-
- #for gconf refer to the full key path
- key = self._fix_key(key)
-
- if vtype is bool:
- self._client.set_bool(key, value)
- elif vtype is str:
- self._client.set_string(key, value)
- elif vtype is int:
- self._client.set_int(key, value)
- elif vtype in (list, tuple):
- #Save every value as a string
- strvalues = [str(i) for i in value]
- #self._client.set_list(key, gconf.VALUE_STRING, strvalues)
-
+ default = self._settings.get_default_value(key)
+ assert default is not None
+ self._settings.set_value(key, glib.Variant(default.get_type().dup_string(), value))
return True
+ def bind(self, key, obj, prop):
+ self._settings.bind(key, obj, prop, gio.SettingsBindFlags.DEFAULT)
+
@property
def day_start(self):
"""Start of the hamster day."""
- day_start_minutes = self.get("day_start_minutes")
+ day_start_minutes = self.get("day-start-minutes")
hours, minutes = divmod(day_start_minutes, 60)
return dt.time(hours, minutes)
-conf = GConfStore()
+conf = GSettingsStore()
diff --git a/src/hamster/preferences.py b/src/hamster/preferences.py
index 1f4a32225..7e0d1b7bd 100755
--- a/src/hamster/preferences.py
+++ b/src/hamster/preferences.py
@@ -507,9 +507,7 @@ def on_day_start_changed(self, widget):
return
day_start = day_start.hour * 60 + day_start.minute
-
- conf.set("day_start_minutes", day_start)
-
+ conf.set("day-start-minutes", day_start)
def on_close_button_clicked(self, button):
self.close_window()
diff --git a/src/hamster/widgets/reportchooserdialog.py b/src/hamster/widgets/reportchooserdialog.py
index 5ff2822f3..0db0e981b 100644
--- a/src/hamster/widgets/reportchooserdialog.py
+++ b/src/hamster/widgets/reportchooserdialog.py
@@ -43,7 +43,7 @@ def __init__(self):
gtk.ResponseType.OK))
# try to set path to last known folder or fall back to home
- report_folder = os.path.expanduser(conf.get("last_report_folder"))
+ report_folder = os.path.expanduser(conf.get("last-report-folder"))
if os.path.exists(report_folder):
self.dialog.set_current_folder(report_folder)
else:
@@ -131,7 +131,7 @@ def on_save_button_clicked(self):
categories = []
- conf.set("last_report_folder", os.path.dirname(path))
+ conf.set("last-report-folder", os.path.dirname(path))
# format, path, start_date, end_date
self.emit("report-chosen", format, path)
diff --git a/wscript b/wscript
index 034efb755..35700121b 100644
--- a/wscript
+++ b/wscript
@@ -10,7 +10,7 @@ from waflib import Logs, Utils
def configure(conf):
conf.load('gnu_dirs') # for DATADIR
-
+ conf.load('glib2') # for GSettings support
conf.load('python')
conf.check_python_version(minver=(3,4,0))
@@ -23,16 +23,10 @@ def configure(conf):
conf.env.GETTEXT_PACKAGE = "hamster"
conf.env.PACKAGE = "hamster"
- # gconf_dir is defined in options
- conf.env.schemas_destination = '{}/schemas'.format(conf.options.gconf_dir)
-
conf.recurse("help")
def options(opt):
- opt.add_option('--gconf-dir', action='store', default='/etc/gconf', dest='gconf_dir',
- help='gconf base directory [default: /etc/gconf]')
-
# the waf default value is /usr/local, which causes issues (e.g. #309)
# opt.parser.set_defaults(prefix='/usr') did not update the help string,
# hence need to replace the whole option
@@ -81,27 +75,8 @@ def build(bld):
bld.recurse("po data help")
-
- def manage_gconf_schemas(ctx, action):
- """Install or uninstall hamster gconf schemas.
-
- Requires the stored hamster.schemas
- (usually in /etc/gconf/schemas/) to be present.
-
- Hence install should be a post-fun,
- and uninstall a pre-fun.
- """
-
- assert action in ("install", "uninstall")
- if ctx.cmd == action:
- schemas_file = "{}/hamster.schemas".format(ctx.env.schemas_destination)
- cmd = 'GCONF_CONFIG_SOURCE=$(gconftool-2 --get-default-source) gconftool-2 --makefile-{}-rule {} 1> /dev/null'.format(action, schemas_file)
- err = ctx.exec_command(cmd)
- if err:
- Logs.warn('The following command failed:\n{}'.format(cmd))
- else:
- Logs.pprint('YELLOW', 'Successfully {}ed gconf schemas'.format(action))
-
+ bld(features='glib2',
+ settings_schema_files = ['data/org.gnome.hamster.gschema.xml'])
def update_icon_cache(ctx):
"""Update the gtk icon cache."""
@@ -116,6 +91,4 @@ def build(bld):
Logs.pprint('YELLOW', 'Successfully updated GTK icon cache')
- bld.add_post_fun(lambda bld: manage_gconf_schemas(bld, "install"))
bld.add_post_fun(update_icon_cache)
- bld.add_pre_fun(lambda bld: manage_gconf_schemas(bld, "uninstall"))