Permalink
Browse files

Implemented GConf connection for settings storage and use it for 'Nat…

…ural Scrolling' option
  • Loading branch information...
1 parent b909b2e commit 4043f63e75de31a10cfc31d8287bd42e8918bebe @zedtux zedtux committed Aug 18, 2011
@@ -1,7 +1,5 @@
<interface>
-
<requires lib="gtk+" version="2.16" />
-
<object class="AboutNaturalscrollingDialog" id="about_naturalscrolling_dialog">
<property name="license" translatable="yes"># Copyright (C) 2011 Eumorphed UG, Charalampos Emmanouilidis &lt;ce@eumorphed.com&gt;
#
@@ -16,13 +14,15 @@
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
-</property><property name="copyright" translatable="yes">Copyright (C) 2011 Eumorphed UG, Charalampos Emmanouilidis &lt;ce@eumorphed.com&gt;</property><property name="can_focus">False</property>
+ </property>
+ <property name="copyright" translatable="yes">Copyright (C) 2011 Eumorphed UG, Charalampos Emmanouilidis &lt;ce@eumorphed.com&gt;</property>
+ <property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="icon">../media/naturalscrolling.svg</property>
<property name="type_hint">normal</property>
<property name="program_name">Natural Scrolling</property>
<property name="authors">Copyright (C) 2011 Eumorphed UG, Charalampos Emmanouilidis &lt;ce@eumorphed.com&gt;
-</property>
+Guillaume Hain &lt;zedtux@zedroot.org&gt;</property>
<property name="logo">../media/naturalscrolling.svg</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
@@ -48,4 +48,4 @@
</object>
</child>
</object>
-</interface>
+</interface>
@@ -4,58 +4,50 @@
import gtk
import appindicator
-from naturalscrolling_lib import naturalscrollingconfig
+from naturalscrolling_lib import naturalscrollingconfig
from naturalscrolling_lib import SwissKnife
+from naturalscrolling_lib.GConfSettings import *
from naturalscrolling.AboutNaturalscrollingDialog import AboutNaturalscrollingDialog
import gettext
from gettext import gettext as _
gettext.textdomain('naturalscrolling')
-class NaturalscrollingIndicator:
+class NaturalscrollingIndicator:
+
def __init__(self):
self.AboutDialog = AboutNaturalscrollingDialog
- self.pingfrequency = 1 # in seconds
- self.mouseids = self.get_slave_pointer()
- self.ind = appindicator.Indicator("natural-scrolling-indicator", 'natural-scrolling-status-not-activated', appindicator.CATEGORY_APPLICATION_STATUS)
+ self.mouseid = self.get_slave_pointer()
+ self.ind = appindicator.Indicator(
+ "natural-scrolling-indicator",
+ "natural-scrolling-status-not-activated",
+ appindicator.CATEGORY_APPLICATION_STATUS
+ )
+ self.settings = GConfSettings()
media_path = "%s/media/" % naturalscrollingconfig.get_data_path()
self.ind.set_icon_theme_path(media_path)
- self.ind.set_attention_icon ("natural-scrolling-status-activated")
+ self.ind.set_attention_icon("natural-scrolling-status-activated")
self.menu_setup()
self.ind.set_menu(self.menu)
- def get_slave_pointer (self):
+ def get_slave_pointer(self):
xinput_reader = SwissKnife.XinputReader()
xinput = SwissKnife.Xinput()
- slavepointer = xinput_reader.get_slave_pointer (xinput.list())
-
- print slavepointer
-
- return slavepointer
+ return xinput_reader.get_slave_pointer(xinput.list())[0]
- def isreversed (self):
- inreverseorder = False
-
- for id in self.mouseids:
- map = os.popen('xinput get-button-map %s' % id).read().strip()
- if '5 4' in map:
- inreverseorder = True
- break
-
- return inreverseorder
-
-
def menu_setup(self):
self.menu = gtk.Menu()
#natural scrolling
self.menu_item_natural_scrolling = gtk.CheckMenuItem(_('Natural Scrolling'))
- if self.isreversed():
- self.menu_item_natural_scrolling.set_active(True)
+ self.enable_natural_scrolling(
+ self.settings.key(GCONF_NATURAL_SCROLLING_KEY).is_enable()
+ )
self.menu_item_natural_scrolling.connect('activate', self.on_natural_scrolling_toggled)
+ self.settings.server().fire_me_when_update_on_key(GCONF_NATURAL_SCROLLING_KEY, self.enable_natural_scrolling)
self.menu_item_natural_scrolling.show()
#seperator 1
@@ -98,30 +90,35 @@ def menu_setup(self):
self.menu.append(self.menu_item_seperator2)
self.menu.append(self.menu_item_quit)
-
- def check_scrolling (self):
- if self.isreversed():
+ def enable_natural_scrolling(self, enabled):
+ """
+ Global method to apply or not Natural Scrolling
+ """
+ map = os.popen('xinput get-button-map %s' % self.mouseid).read().strip()
+
+ if enabled == True:
+ map = map.replace('4 5', '5 4')
+ self.settings.key(GCONF_NATURAL_SCROLLING_KEY).enable()
self.ind.set_status(appindicator.STATUS_ATTENTION)
else:
+ map = map.replace('5 4', '4 5')
+ self.settings.key(GCONF_NATURAL_SCROLLING_KEY).disable()
self.ind.set_status(appindicator.STATUS_ACTIVE)
-
- return True
+
+ self.menu_item_natural_scrolling.set_active(enabled)
+
+ os.system('xinput set-button-map %s %s' %(self.mouseid, map))
def on_natural_scrolling_toggled(self, widget, data=None):
- map = ''
- for id in self.mouseids:
- map = os.popen ('xinput get-button-map %s' % id).read().strip()
-
- if self.isreversed():
- map = map.replace ('5 4', '4 5')
- else:
- map = map.replace ('4 5', '5 4')
-
- os.system ('xinput set-button-map %s %s' % (id, map))
-
+ """
+ Fired method when user click on gtk.CheckMenuItem 'Natural Scrolling'
+ """
+ self.enable_natural_scrolling(widget.get_active())
def on_start_at_login_clicked(self, widget, data=None):
-
+ """
+ Fired method when user click on gtk.CheckMenuItem 'Start at login'
+ """
if not os.path.exists(naturalscrollingconfig.get_auto_start_path()):
os.makedirs(naturalscrollingconfig.get_auto_start_path())
@@ -130,7 +127,7 @@ def on_start_at_login_clicked(self, widget, data=None):
if not auto_start_file_exists:
source = open(naturalscrollingconfig.get_data_path() + "/" + naturalscrollingconfig.get_auto_start_file_name(), "r")
destination = open(naturalscrollingconfig.get_auto_start_file_path(), "w")
- destination.write (source.read())
+ destination.write(source.read())
destination.close() and source.close()
else:
if auto_start_file_exists:
@@ -141,13 +138,9 @@ def on_about_clicked(self, widget, data=None):
response = about.run()
about.destroy()
-
def main(self):
- self.check_scrolling()
- gtk.timeout_add(self.pingfrequency * 1000, self.check_scrolling)
gtk.main()
-
def quit(self, widget):
sys.exit(0)
@@ -24,8 +24,6 @@
import gtk
from naturalscrolling import NaturalscrollingIndicator
-
-#from naturalscrolling_lib import set_up_logging, preferences, get_version
from naturalscrolling_lib import set_up_logging, get_version
def parse_options():
@@ -42,21 +40,6 @@ def main():
'constructor for your class instances'
parse_options()
- # preferences
- # set some values for our first session
- # TODO: replace defaults with your own values
- default_preferences = {
- 'example_entry': 'I remember stuff',
- }
-
- #preferences.update(default_preferences)
- # user's stored preferences are used for 2nd and subsequent sessions
- #preferences.db_connect()
- #preferences.load()
-
# Run the application.
indicator = NaturalscrollingIndicator.NaturalscrollingIndicator()
indicator.main()
-
- #preferences.save()
-
@@ -0,0 +1,166 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+### BEGIN LICENSE
+# Copyright (C) 2011 Guillaume Hain <zedtux@zedroot.org>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+### END LICENSE
+
+import gconf
+
+## GConf setup
+
+# GConf root path
+GCONF_ROOT_DIR = "/apps/naturalscrolling"
+
+# Natural Scrolling keys path definition
+GCONF_NATURAL_SCROLLING_KEY = GCONF_ROOT_DIR + "/natural_scrolling"
+
+# Natural Scrolling keys type definition
+gconf_keys = {GCONF_NATURAL_SCROLLING_KEY: bool}
+
+
+## Exception classes
+class InvalidKey(Exception):
+ """ Raised class when key is unknown """
+
+class InvalidKeyType(Exception):
+ """ Raised class when key type is unknown """
+
+class GConfServer(object):
+ # Singleton
+ _instance = None
+ _init_done = False
+ def __new__(cls, *args, **kwargs):
+ if not cls._instance:
+ cls._instance = super(GConfServer, cls).__new__(
+ cls, *args, **kwargs
+ )
+ return cls._instance
+
+ def __init__(self):
+ """
+ Open connection to GConf
+ and connect to callback on naturalscrolling keys updates
+ """
+ if self._init_done:
+ return
+
+ if not hasattr(self, "__key_update_observators"):
+ self.__key_update_observators = {}
+
+ if not hasattr(self, "client"):
+ # Get GConf client:
+ self.client = gconf.client_get_default()
+
+ # Add the root directory to the list of directories that our GConf
+ # client will watch for changes:
+ self.client.add_dir(GCONF_ROOT_DIR, gconf.CLIENT_PRELOAD_NONE)
+
+ # Assign a callback function for when changes are made to keys in
+ # the root directory namespace:
+ self.client.notify_add(GCONF_ROOT_DIR, self.on_settings_changed)
+
+ self._init_done = True
+
+ def fire_me_when_update_on_key(self, key, method):
+ """
+ Register a Class instance method to fire
+ swhen the given an update on the given key have been catched
+ """
+ self.__key_update_observators[key] = method
+
+ def on_settings_changed(self, client, timestamp, entry, *extra):
+ """
+ This is the callback function that is called when the keys in our
+ namespace change (such as editing them with gconf-editor).
+ """
+ key = entry.get_key()
+ if not key in gconf_keys:
+ raise InvalidKey("Unknown key %s" % key)
+
+ if not key in self.__key_update_observators:
+ return
+
+ # Execute observer's method passing GConf key value as parameter
+ self.__key_update_observators[key](entry.get_value().get_bool())
+
+class GConfKey(object):
+
+ def __init__(self, key):
+ if not key in gconf_keys:
+ raise InvalidKey("Unknown key %s" % key)
+
+ self.__gconf = GConfServer().client
+ self.__value = None
+ self.__key = key
+ self.__type = gconf_keys[key]
+ self.get_value()
+
+ def get_value(self):
+ """
+ Magic method to read the value from GConf (auto cast)
+ """
+ if self.__type == bool:
+ self.__value = self.__gconf.get_bool(self.__key)
+ elif self.__type == str:
+ self.__value = self.__gconf.get_string(self.__key)
+ elif self.__type == int:
+ self.__value = self.__gconf.get_int(self.__key)
+ else:
+ raise InvalidKeyType("Invalid key type %s" % self.__type)
+
+ def set_value(self):
+ """
+ Magic method to write the value to GConf (auto cast)
+ """
+ if self.__type == bool:
+ self.__gconf.set_bool(self.__key, self.__value)
+ elif self.__type == str:
+ self.__gconf.set_string(self.__key, self.__value)
+ elif self.__type == int:
+ self.__gconf.set_int(self.__key, self.__value)
+ else:
+ raise InvalidKeyType("Invalid key type %s" % self.__type)
+
+ def is_enable(self):
+ return self.__value == True
+
+ def enable(self):
+ """
+ Set a boolean key value to True
+ """
+ self.__value = 1
+ self.set_value()
+
+ def disable(self):
+ """
+ Set a boolean key value to False
+ """
+ self.__value = 0
+ self.set_value()
+
+class GConfSettings(object):
+
+ def server(self):
+ """
+ Return the Singleton instance of the GConfServer
+ """
+ return GConfServer()
+
+ def key(self, key):
+ """
+ Ruby styled method to define which is the key to check
+ This method return an instance of the GConfKey class
+ otherwise raise a InvalidKey or InvalidKeyType
+ """
+ return GConfKey(key)
Oops, something went wrong.

0 comments on commit 4043f63

Please sign in to comment.