[gedit-latex/remove-prefs: 1/3] Seperate tool preferences from preferences
- From: John Stowers <jstowers src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit-latex/remove-prefs: 1/3] Seperate tool preferences from preferences
- Date: Mon, 27 Jun 2011 10:14:45 +0000 (UTC)
commit d3695d8e1526d503fa7401bfb7cc435707ae854f
Author: John Stowers <john stowers gmail com>
Date: Mon Jun 27 09:44:04 2011 +1200
Seperate tool preferences from preferences
* Migrate tool preferences to GObject signals
for change notification
* add @singleton decorator and use that
latex/base/windowactivatable.py | 16 +--
latex/preferences/Makefile.am | 1 +
latex/preferences/__init__.py | 260 ++-------------------------------------
latex/preferences/dialog.py | 33 +++---
latex/preferences/tools.py | 221 +++++++++++++++++++++++++++++++++
latex/util.py | 13 ++
6 files changed, 270 insertions(+), 274 deletions(-)
---
diff --git a/latex/base/windowactivatable.py b/latex/base/windowactivatable.py
index 72897fe..129d27c 100644
--- a/latex/base/windowactivatable.py
+++ b/latex/base/windowactivatable.py
@@ -28,15 +28,16 @@ import string
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(name)s - %(message)s")
-from ..preferences import Preferences, IPreferencesMonitor
+from ..preferences import Preferences
from ..preferences.dialog import PreferencesDialog
+from ..preferences.tools import ToolPreferences
from ..tools import ToolAction
from ..tools.views import ToolView
from config import UI, WINDOW_SCOPE_VIEWS, EDITOR_SCOPE_VIEWS, ACTIONS
from . import File, SideView, BottomView, WindowContext
from decorators import GeditTabDecorator
-class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Configurable, IPreferencesMonitor):
+class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Configurable):
__gtype_name__ = "LaTeXWindowActivatable"
"""
@@ -67,7 +68,8 @@ class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Co
Called when the window extension is activated
"""
self._preferences = Preferences()
- self._preferences.register_monitor(self)
+ self._tool_preferences = ToolPreferences()
+ self._tool_preferences.connect("tools-changed", self._on_tools_changed)
#
# initialize context object
@@ -97,7 +99,7 @@ class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Co
"""
# save preferences and stop listening
self._preferences.save()
- self._preferences.remove_monitor(self)
+ self._tool_preferences.save()
# destroy tab decorators
self._active_tab_decorator = None
@@ -259,7 +261,7 @@ class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Co
i = 1 # counting tool actions
accel_counter = 1 # counting tool actions without custom accel
- for tool in self._preferences.tools:
+ for tool in self._tool_preferences.tools:
# hopefully unique action name
name = "Tool%sAction" % i
@@ -312,10 +314,6 @@ class LaTeXWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Co
self._save_action.activate()
def _on_tools_changed(self):
- # FIXME: tools reload doesn't work
- # UPDATE: should work now
-
- # see IPreferencesMonitor._on_tools_changed
self._log.debug("_on_tools_changed")
# remove tool actions and ui
diff --git a/latex/preferences/Makefile.am b/latex/preferences/Makefile.am
index c845283..b06742d 100644
--- a/latex/preferences/Makefile.am
+++ b/latex/preferences/Makefile.am
@@ -2,6 +2,7 @@ plugindir = $(libdir)/gedit/plugins/latex/preferences
plugin_PYTHON = \
dialog.py \
+ tools.py \
__init__.py
-include $(top_srcdir)/git.mk
diff --git a/latex/preferences/__init__.py b/latex/preferences/__init__.py
index 12e1efb..9b5cea4 100644
--- a/latex/preferences/__init__.py
+++ b/latex/preferences/__init__.py
@@ -22,11 +22,13 @@
preferences
"""
+from gi.repository import GObject
+
from logging import getLogger
+import xml.etree.ElementTree as ElementTree
from ..base.resources import find_resource, MODE_READWRITE
-from ..tools import Tool, Job
-from ..tools.postprocess import GenericPostProcessor, RubberPostProcessor, LaTeXPostProcessor
+from ..util import singleton
def str_to_bool(x):
"""
@@ -53,42 +55,7 @@ class IPreferencesMonitor(object):
A simple key-value-pair has changed
"""
- def _on_tools_changed(self):
- """
- The Tools have changed
- """
-
-
-# ElementTree is part of Python 2.5
-# TODO: see http://effbot.org/zone/element-index.htm
-import xml.etree.ElementTree as ElementTree
-
-import uuid
-
-
-class ObjectCache(object):
- """
- """
-
- # TODO:
-
- def __init__(self):
- """
- """
- self.__objects = None
- self.__ids = None
-
- def save(self, id, object):
- self.__ids[object] = id
- self.__objects.append(object)
-
- def find_id(self, object):
- return self.__ids[object]
-
- def delete(self, id):
- pass
-
-
+ singleton
class Preferences(object):
"""
A simple map storing preferences as key-value-pairs
@@ -96,42 +63,12 @@ class Preferences(object):
_log = getLogger("Preferences")
- # maps names to classes
- POST_PROCESSORS = {"GenericPostProcessor" : GenericPostProcessor,
- "LaTeXPostProcessor" : LaTeXPostProcessor,
- "RubberPostProcessor" : RubberPostProcessor}
-
- def __new__(cls):
- if not '_instance' in cls.__dict__:
- cls._instance = object.__new__(cls)
- return cls._instance
-
def __init__(self):
- if not '_ready' in dir(self):
- #
- # init Preferences singleton
- #
-
-# self.preferences = { "ConnectOutlineToEditor" : True,
-# "ErrorBackgroundColor" : "#ffdddd",
-# "WarningBackgroundColor" : "#ffffcf",
-# "SpellingBackgroundColor" : "#ffeccf",
-# "LightForeground" : "#957d47" }
-
- self.__monitors = []
-
- self.__preferences_changed = False
- self.__tools_changed = False
-
- # TODO: use some object cache mechanism instead of those fields
- self.__tool_objects = None
- self.__tool_ids = None
-
- # parse
- self.__preferences = ElementTree.parse(find_resource("preferences.xml", MODE_READWRITE)).getroot()
- self.__tools = ElementTree.parse(find_resource("tools.xml", MODE_READWRITE)).getroot()
-
- self._ready = True
+ self.__monitors = []
+ self.__preferences_changed = False
+ self.__preferences = ElementTree.parse(
+ find_resource("preferences.xml", MODE_READWRITE)).getroot()
+ self._log.debug("Constructed")
def register_monitor(self, monitor):
"""
@@ -139,9 +76,6 @@ class Preferences(object):
@param monitor: an object implementing IPreferencesMonitor
"""
-
- # TODO: support a flag indicating which parts are to be monitored
-
self.__monitors.append(monitor)
def remove_monitor(self, monitor):
@@ -164,9 +98,6 @@ class Preferences(object):
return default_value
else:
return value_element.text
-
- # TODO: use this as soon as ElementTree 1.3 is part of Python:
- #return self.__preferences.findtext(".//value[ key='%s']" % key, default_value)
def get_bool(self, key, default_value=None):
"""
@@ -175,9 +106,6 @@ class Preferences(object):
return str_to_bool(self.get(key, default_value))
def __find_value_element(self, key):
- # TODO: use this as soon as ElementTree 1.3 is part of Python:
- #value_element = self.__preferences.find(".//value[ key='%s']" % key)
-
for element in self.__preferences.findall("value"):
if element.get("key") == key:
return element
@@ -197,167 +125,9 @@ class Preferences(object):
self.__preferences_changed = True
- # notify monitors
for monitor in self.__monitors:
monitor._on_value_changed(key, value)
- def __notify_tools_changed(self):
- """
- Notify monitors that the Tools have changed
- """
- for monitor in self.__monitors:
- monitor._on_tools_changed()
-
- @property
- def tools(self):
- """
- Return all Tools
- """
- self.__tool_ids = {}
-
- tools = []
-
- for tool_element in self.__tools.findall("tool"):
- jobs = []
- for job_element in tool_element.findall("job"):
- jobs.append(Job(job_element.text.strip(), str_to_bool(job_element.get("mustSucceed")), self.POST_PROCESSORS[job_element.get("postProcessor")]))
-
- assert not tool_element.get("extensions") is None
-
- extensions = tool_element.get("extensions").split()
- accelerator = tool_element.get("accelerator")
- id = tool_element.get("id")
- tool = Tool(tool_element.get("label"), jobs, tool_element.get("description"), accelerator, extensions)
- self.__tool_ids[tool] = id
-
- tools.append(tool)
-
- return tools
-
- def __find_tool_element(self, id):
- """
- Find the tool element with the given id
- """
- for element in self.__tools.findall("tool"):
- if element.get("id") == id:
- return element
- self._log.warning("<tool id='%s'> not found" % id)
- return None
-
- def save_or_update_tool(self, tool):
- """
- Save or update the XML subtree for the given Tool
-
- @param tool: a Tool object
- """
- tool_element = None
- if tool in self.__tool_ids:
- # find tool tag
- self._log.debug("Tool element found, updating...")
-
- id = self.__tool_ids[tool]
- tool_element = self.__find_tool_element(id)
- else:
- # create new tool tag
- self._log.debug("Creating new Tool...")
-
- id = str(uuid.uuid4()) # random UUID
- self.__tool_ids[tool] = id
-
- tool_element = ElementTree.SubElement(self.__tools, "tool")
- tool_element.set("id", id)
-
- tool_element.set("label", tool.label)
- tool_element.set("description", tool.description)
- tool_element.set("extensions", " ".join(tool.extensions))
- if tool.accelerator is None:
- if "accelerator" in tool_element.attrib.keys():
- del tool_element.attrib["accelerator"]
- else:
- tool_element.set("accelerator", tool.accelerator)
-
- # remove all jobs
- for job_element in tool_element.findall("job"):
- tool_element.remove(job_element)
-
- # append new jobs
- for job in tool.jobs:
- job_element = ElementTree.SubElement(tool_element, "job")
- job_element.set("mustSucceed", str(job.must_succeed))
- job_element.set("postProcessor", job.post_processor.name)
- job_element.text = job.command_template
-
- self.__tools_changed = True
- self.__notify_tools_changed()
-
- def swap_tools(self, tool_1, tool_2):
- """
- Swap the order of two Tools
- """
- # grab their ids
- id_1 = self.__tool_ids[tool_1]
- id_2 = self.__tool_ids[tool_2]
-
- if id_1 == id_2:
- self._log.warning("Two tools have the same id. Please modify tools.xml to have unique id's.")
- return
-
- self._log.debug("Tool IDs are {%s: %s, %s, %s}" % (tool_1.label, id_1, tool_2.label, id_2))
-
- tool_element_1 = None
- tool_element_2 = None
-
- # find the XML elements and current indexes of the tools
- i = 0
- for tool_element in self.__tools:
- if tool_element.get("id") == id_1:
- tool_element_1 = tool_element
- index_1 = i
- elif tool_element.get("id") == id_2:
- tool_element_2 = tool_element
- index_2 = i
-
- if not (tool_element_1 is None or tool_element_2 is None):
- break
-
- i += 1
-
- self._log.debug("Found XML elements, indexes are {%s: %s, %s, %s}" % (tool_1.label, index_1, tool_2.label, index_2))
-
- # successively replace each of them by the other in the XML model
- self.__tools.remove(tool_element_1)
- self.__tools.insert(index_1, tool_element_2)
-
- self._log.debug("Replaced first tool by second in list")
-
- self.__tools.remove(tool_element_2)
- self.__tools.insert(index_2, tool_element_1)
-
- self._log.debug("Replaced second tool by first in list")
-
- # notify changes
- self.__tools_changed = True
- self.__notify_tools_changed()
-
- def delete_tool(self, tool):
- """
- Delete the given Tool
-
- @param tool: a Tool object
- """
- try:
- id = self.__tool_ids[tool]
- tool_element = self.__find_tool_element(id)
- self.__tools.remove(tool_element)
-
- del self.__tool_ids[tool]
-
- self.__tools_changed = True
- except KeyError, e:
- self._log.error("delete_tool: %s" % e)
-
- self.__notify_tools_changed()
-
def save(self):
"""
Save the preferences to XML
@@ -369,12 +139,4 @@ class Preferences(object):
tree.write(find_resource("preferences.xml", MODE_READWRITE), encoding="utf-8")
self.__preferences_changed = False
-
- if self.__tools_changed:
- self._log.debug("Saving tools...")
-
- tree = ElementTree.ElementTree(self.__tools)
- tree.write(find_resource("tools.xml", MODE_READWRITE), encoding="utf-8")
-
- self.__tools_changed = False
-
\ No newline at end of file
+
diff --git a/latex/preferences/dialog.py b/latex/preferences/dialog.py
index 0097900..b8d67c6 100644
--- a/latex/preferences/dialog.py
+++ b/latex/preferences/dialog.py
@@ -28,7 +28,10 @@ from gi.repository import Gdk
from ..base.resources import find_resource, MODE_READWRITE
from ..util import GladeInterface
-from . import Preferences, IPreferencesMonitor
+from ..tools import Tool, Job
+
+from . import Preferences
+from .tools import ToolPreferences
def _insert_column_with_attributes(view, pos, title, rend, **kwargs):
print kwargs
@@ -98,9 +101,6 @@ class PreferencesColorProxy(object):
return "#%02x%02x%02x" % (r, g, b)
-from ..tools import Tool, Job
-
-
class ConfigureToolDialog(GladeInterface):
"""
Wraps the dialog for setting up a Tool
@@ -146,7 +146,7 @@ class ConfigureToolDialog(GladeInterface):
tool.jobs = []
for row in self._store_job:
- pp_class = self._preferences.POST_PROCESSORS[row[2]]
+ pp_class = self._tool_preferences.POST_PROCESSORS[row[2]]
tool.jobs.append(Job(row[0], row[1], pp_class))
tool.extensions = []
@@ -199,7 +199,7 @@ class ConfigureToolDialog(GladeInterface):
commandRenderer.connect("edited", self._on_job_command_edited)
self._store_pp = Gtk.ListStore(str)
- for p in self._preferences.POST_PROCESSORS.iterkeys():
+ for p in self._tool_preferences.POST_PROCESSORS.iterkeys():
self._store_pp.append([p])
ppRenderer = Gtk.CellRendererCombo()
@@ -351,7 +351,7 @@ class ConfigureToolDialog(GladeInterface):
-class PreferencesDialog(GladeInterface, IPreferencesMonitor):
+class PreferencesDialog(GladeInterface):
"""
This controls the configure dialog
"""
@@ -383,6 +383,7 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
#
# tools
#
+ self._tool_preferences = ToolPreferences()
# grab widgets
@@ -398,8 +399,9 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
_insert_column_with_attributes(self._view_tool, -1, "File Extensions", Gtk.CellRendererText(), text=1)
# init tool and listen to tool changes
- self.__load_tools()
- self._preferences.register_monitor(self)
+ self._load_tools()
+ self._tool_preferences.connect("tools-changed", self._on_tools_changed)
+
# misc
check_hide_box = self.find_widget("checkHideBox")
@@ -458,11 +460,10 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
value = togglebutton.get_active()
self._preferences.set("HideBoxWarnings", value)
- def _on_tools_changed(self):
- # see IPreferencesMonitor._on_tools_changed
- self.__load_tools()
+ def _on_tools_changed(self, tools):
+ self._load_tools()
- def __load_tools(self):
+ def _load_tools(self):
# save cursor
store, iter = self._view_tool.get_selection().get_selected()
if iter is None:
@@ -473,7 +474,7 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
# reload tools
self._store_tool.clear()
- for tool in self._preferences.tools:
+ for tool in self._tool_preferences.tools:
self._store_tool.append(["<b>%s</b>" % tool.label, ", ".join(tool.extensions), tool])
# restore cursor
@@ -527,7 +528,7 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
tool_2 = store.get_value(iter_next, 2)
# swap tools in preferences
- self._preferences.swap_tools(tool_1, tool_2)
+ self._tool_preferences.swap_tools(tool_1, tool_2)
# adjust selection
self._view_tool.get_selection().select_path(str(index_next))
@@ -538,7 +539,7 @@ class PreferencesDialog(GladeInterface, IPreferencesMonitor):
tool = Tool("New Tool", [], "", [".tex"])
if not dialog.run(tool) is None:
- self._preferences.save_or_update_tool(tool)
+ self._tool_preferences.save_or_update_tool(tool)
def _on_delete_bib_clicked(self, button):
pass
diff --git a/latex/preferences/tools.py b/latex/preferences/tools.py
new file mode 100644
index 0000000..74fbbba
--- /dev/null
+++ b/latex/preferences/tools.py
@@ -0,0 +1,221 @@
+# -*- coding: utf-8 -*-
+
+# This file is part of the Gedit LaTeX Plugin
+#
+# Copyright (C) 2010 Michael Zeising
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public Licence as published by the Free Software
+# Foundation; either version 2 of the Licence, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more
+# details.
+#
+# You should have received a copy of the GNU General Public Licence along with
+# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+# Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+from gi.repository import GObject
+
+from logging import getLogger
+from uuid import uuid4
+import xml.etree.ElementTree as ElementTree
+
+from ..base.resources import find_resource, MODE_READWRITE
+from ..tools import Tool, Job
+from ..tools.postprocess import GenericPostProcessor, RubberPostProcessor, LaTeXPostProcessor
+from ..util import singleton
+from . import str_to_bool
+
+ singleton
+class ToolPreferences(GObject.GObject):
+
+ __gsignals__ = {
+ "tools-changed": (
+ GObject.SignalFlags.RUN_LAST, None, []),
+ }
+
+ _log = getLogger("ToolPreferences")
+
+ # maps names to classes
+ POST_PROCESSORS = {"GenericPostProcessor" : GenericPostProcessor,
+ "LaTeXPostProcessor" : LaTeXPostProcessor,
+ "RubberPostProcessor" : RubberPostProcessor}
+
+ def __init__(self):
+ GObject.GObject.__init__(self)
+ self.__tool_objects = None
+ self.__tool_ids = None
+ self.__tools_changed = False
+ self.__tools = ElementTree.parse(
+ find_resource("tools.xml", MODE_READWRITE)).getroot()
+ self._log.debug("Constructed")
+
+ def __notify_tools_changed(self):
+ self.emit("tools-changed")
+
+ @property
+ def tools(self):
+ """
+ Return all Tools
+ """
+ self.__tool_ids = {}
+
+ tools = []
+
+ for tool_element in self.__tools.findall("tool"):
+ jobs = []
+ for job_element in tool_element.findall("job"):
+ jobs.append(Job(job_element.text.strip(), str_to_bool(job_element.get("mustSucceed")), self.POST_PROCESSORS[job_element.get("postProcessor")]))
+
+ assert not tool_element.get("extensions") is None
+
+ extensions = tool_element.get("extensions").split()
+ accelerator = tool_element.get("accelerator")
+ id = tool_element.get("id")
+ tool = Tool(tool_element.get("label"), jobs, tool_element.get("description"), accelerator, extensions)
+ self.__tool_ids[tool] = id
+
+ tools.append(tool)
+
+ return tools
+
+ def __find_tool_element(self, id):
+ """
+ Find the tool element with the given id
+ """
+ for element in self.__tools.findall("tool"):
+ if element.get("id") == id:
+ return element
+ self._log.warning("<tool id='%s'> not found" % id)
+ return None
+
+ def save_or_update_tool(self, tool):
+ """
+ Save or update the XML subtree for the given Tool
+
+ @param tool: a Tool object
+ """
+ tool_element = None
+ if tool in self.__tool_ids:
+ # find tool tag
+ self._log.debug("Tool element found, updating...")
+
+ id = self.__tool_ids[tool]
+ tool_element = self.__find_tool_element(id)
+ else:
+ # create new tool tag
+ self._log.debug("Creating new Tool...")
+
+ id = str(uuid4())
+ self.__tool_ids[tool] = id
+
+ tool_element = ElementTree.SubElement(self.__tools, "tool")
+ tool_element.set("id", id)
+
+ tool_element.set("label", tool.label)
+ tool_element.set("description", tool.description)
+ tool_element.set("extensions", " ".join(tool.extensions))
+ if tool.accelerator is None:
+ if "accelerator" in tool_element.attrib.keys():
+ del tool_element.attrib["accelerator"]
+ else:
+ tool_element.set("accelerator", tool.accelerator)
+
+ # remove all jobs
+ for job_element in tool_element.findall("job"):
+ tool_element.remove(job_element)
+
+ # append new jobs
+ for job in tool.jobs:
+ job_element = ElementTree.SubElement(tool_element, "job")
+ job_element.set("mustSucceed", str(job.must_succeed))
+ job_element.set("postProcessor", job.post_processor.name)
+ job_element.text = job.command_template
+
+ self.__tools_changed = True
+ self.__notify_tools_changed()
+
+ def swap_tools(self, tool_1, tool_2):
+ """
+ Swap the order of two Tools
+ """
+ # grab their ids
+ id_1 = self.__tool_ids[tool_1]
+ id_2 = self.__tool_ids[tool_2]
+
+ if id_1 == id_2:
+ self._log.warning("Two tools have the same id. Please modify tools.xml to have unique id's.")
+ return
+
+ self._log.debug("Tool IDs are {%s: %s, %s, %s}" % (tool_1.label, id_1, tool_2.label, id_2))
+
+ tool_element_1 = None
+ tool_element_2 = None
+
+ # find the XML elements and current indexes of the tools
+ i = 0
+ for tool_element in self.__tools:
+ if tool_element.get("id") == id_1:
+ tool_element_1 = tool_element
+ index_1 = i
+ elif tool_element.get("id") == id_2:
+ tool_element_2 = tool_element
+ index_2 = i
+
+ if not (tool_element_1 is None or tool_element_2 is None):
+ break
+
+ i += 1
+
+ self._log.debug("Found XML elements, indexes are {%s: %s, %s, %s}" % (tool_1.label, index_1, tool_2.label, index_2))
+
+ # successively replace each of them by the other in the XML model
+ self.__tools.remove(tool_element_1)
+ self.__tools.insert(index_1, tool_element_2)
+
+ self._log.debug("Replaced first tool by second in list")
+
+ self.__tools.remove(tool_element_2)
+ self.__tools.insert(index_2, tool_element_1)
+
+ self._log.debug("Replaced second tool by first in list")
+
+ # notify changes
+ self.__tools_changed = True
+ self.__notify_tools_changed()
+
+ def delete_tool(self, tool):
+ """
+ Delete the given Tool
+
+ @param tool: a Tool object
+ """
+ try:
+ id = self.__tool_ids[tool]
+ tool_element = self.__find_tool_element(id)
+ self.__tools.remove(tool_element)
+
+ del self.__tool_ids[tool]
+
+ self.__tools_changed = True
+ except KeyError, e:
+ self._log.error("delete_tool: %s" % e)
+
+ self.__notify_tools_changed()
+
+ def save(self):
+ """
+ Save the preferences to XML
+ """
+ if self.__tools_changed:
+ self._log.debug("Saving tools...")
+
+ tree = ElementTree.ElementTree(self.__tools)
+ tree.write(find_resource("tools.xml", MODE_READWRITE), encoding="utf-8")
+
+ self.__tools_changed = False
+
diff --git a/latex/util.py b/latex/util.py
index c83e76a..77b8119 100644
--- a/latex/util.py
+++ b/latex/util.py
@@ -28,6 +28,19 @@ the project
import logging
from gi.repository import GdkPixbuf
+def singleton(cls):
+ """
+ Singleton decorator that works with GObject derived types. The 'recommended'
+ python one - http://wiki.python.org/moin/PythonDecoratorLibrary#Singleton
+ does not (interacts badly with GObjectMeta
+ """
+ instances = {}
+ def getinstance():
+ if cls not in instances:
+ instances[cls] = cls()
+ return instances[cls]
+ return getinstance
+
def require(arg_name, *allowed_types):
"""
Type-checking decorator (see http://code.activestate.com/recipes/454322/)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]