dabo Commit
Revision 2201
Date: 2006-06-05 13:26:19 -0700 (Mon, 05 Jun 2006)
Author: ed
Changed:
U trunk/dabo/dObject.py
U trunk/dabo/dPref.py
Log:
Added two new properties to dObject: BasePrefKey and PreferenceManager.
'BasePrefKey' defines the identifying key used to store preferences for that
particular object; 'PreferenceManager' is a reference to a dPref object whose
key is automatically set to self.BasePrefKey.
Cleaned up some poor naming choices for atts in dPref, and added a restriction
that if there is no key value set, the values set in the object will not be
persisted to the database. There is simply too much potential for harm when
multiple applications are writing preferences to the same namespace. It is much
better to require a key that can be as complex as you like; the more complex,
the less chance of a conflict. For example, the key for the Class Designer app
might be something like 'dabo.ide.ClassDesigner.app', which is unlikely to
clash with any other app's preferences.
Diff:
Modified: trunk/dabo/dObject.py
===================================================================
--- trunk/dabo/dObject.py 2006-06-05 12:53:45 UTC (rev 2200)
+++ trunk/dabo/dObject.py 2006-06-05 20:26:19 UTC (rev 2201)
@@ -6,13 +6,13 @@
from dabo.lib.doDefaultMixin import DoDefaultMixin
from dabo.lib.eventMixin import EventMixin
from dabo.lib.autosuper import autosuper
+from dabo.dPref import dPref
from dabo.dLocalize import _
class dObject(autosuper, DoDefaultMixin, PropertyHelperMixin,
EventMixin):
- """ The basic ancestor of all dabo objects.
- """
+ """ The basic ancestor of all dabo objects."""
# Subclasses can set these to False, in which case they are responsible
# for maintaining the following call order:
# self._beforeInit()
@@ -25,6 +25,9 @@
_call_beforeInit, _call_afterInit, _call_initProperties = True, True,
True
def __init__(self, properties=None, *args, **kwargs):
+ # Holds the base preference key
+ self._basePrefKey = ""
+ self._preferenceManager = None
self._properties = {}
if self._call_beforeInit:
self._beforeInit()
@@ -46,7 +49,7 @@
properties = self._extractKeywordProperties(kwargs,
self._properties)
if kwargs:
# Some kwargs haven't been handled.
- raise TypeError, "__init__() got an unexpected keyword
argument '%s'" % kwargs.keys()[0]
+ raise TypeError, _("__init__() got an unexpected
keyword argument '%s'") % kwargs.keys()[0]
if self._call_afterInit:
self._afterInit()
self.setProperties(properties)
@@ -57,10 +60,7 @@
def beforeInit(self, *args, **kwargs):
- """ Subclass hook.
-
- Called before the object is fully instantiated.
-
+ """ Subclass hook. Called before the object is fully
instantiated.
Usually, user code should override afterInit() instead, but
there may be
cases where you need to set an attribute before the init stage
is fully
underway.
@@ -69,10 +69,7 @@
def afterInit(self):
- """ Subclass hook.
-
- Called after the object's __init__ has run fully.
-
+ """ Subclass hook. Called after the object's __init__ has run
fully.
Subclasses should place their __init__ code here in this hook,
instead of
overriding __init__ directly, to avoid conflicting with base
Dabo behavior.
"""
@@ -80,9 +77,8 @@
def initProperties(self):
- """ Hook for subclasses.
-
- User subclasses should set properties here, such as:
+ """ Hook for subclasses. User subclasses should set properties
+ here, such as:
self.Name = "MyTextBox"
self.BackColor = (192,192,192)
"""
@@ -90,35 +86,30 @@
def initEvents(self):
- """ Hook for subclasses.
-
- User code should do custom event binding here, such as:
+ """ Hook for subclasses. User code should do custom event
binding
+ here, such as:
self.bindEvent(dEvents.GotFocus,
self.customGotFocusHandler)
"""
pass
def _beforeInit(self):
- """Framework subclass hook.
- """
+ """Framework subclass hook."""
self.beforeInit()
def _initProperties(self):
- """Framework subclass hook.
- """
+ """Framework subclass hook."""
self.initProperties()
def _afterInit(self):
- """Framework subclass hook.
- """
+ """Framework subclass hook."""
self.afterInit()
def getAbsoluteName(self):
- """Return the fully qualified name of the object.
- """
+ """Return the fully qualified name of the object."""
names = [self.Name, ]
object = self
while True:
@@ -137,7 +128,7 @@
else:
break
names.reverse()
- return '.'.join(names)
+ return ".".join(names)
def getMethodList(cls, refresh=False):
@@ -197,6 +188,12 @@
setattr(self, nm, newMethod)
+ # Property definitions begin here
+ def _getApplication(self):
+ # dApp saves a ref to itself inside the dabo module object.
+ return dabo.dAppRef
+
+
def _getBaseClass(self):
# Every Dabo baseclass must set self._baseClass explicitly, to
itself. For instance:
# class dBackend(object)
@@ -210,11 +207,19 @@
return None
- def _getApplication(self):
- # dApp saves a ref to itself inside the dabo module object.
- return dabo.dAppRef
-
-
+ def _getBasePrefKey(self):
+ return self._basePrefKey
+
+ def _setBasePrefKey(self, val):
+ if self._constructed():
+ self._basePrefKey = val
+ if self._preferenceManager is not None:
+ if not self._preferenceManager._key:
+ self._preferenceManager._key = val
+ else:
+ self._properties["BasePrefKey"] = val
+
+
def _getClass(self):
try:
return self.__class__
@@ -238,14 +243,11 @@
parent = None
else:
parent = self.Application
-
try:
le = parent.LogEvents
except AttributeError:
le = []
-
return le
-
def _setLogEvents(self, val):
self._logEvents = list(val)
@@ -256,7 +258,6 @@
return self._name
except AttributeError:
return "?"
-
def _setName(self, value):
self._name = str(value)
@@ -271,12 +272,23 @@
except AttributeError:
return None
-
def _setParent(self, obj):
# Subclasses must override as necessary.
self._parent = obj
-
-
+
+
+ def _getPreferenceManager(self):
+ if self._preferenceManager is None:
+ self._preferenceManager = dPref(key=self.BasePrefKey)
+ return self._preferenceManager
+
+ def _setPreferenceManager(self, val):
+ if self._constructed():
+ self._preferenceManager = val
+ else:
+ self._properties["PreferenceManager"] = val
+
+
def _getSuperClass(self):
if self.BaseClass == self.Class:
# The superclass is lower down than Dabo, and useless
to the user.
@@ -286,34 +298,38 @@
Application = property(_getApplication, None, None,
- _("""Object reference to the Dabo Application object.
(read only)."""))
+ _("Read-only object reference to the Dabo Application
object. (dApp)."))
BaseClass = property(_getBaseClass, None, None,
- _("""The base Dabo class of the object. Read-only.
(class)"""))
+ _("The base Dabo class of the object. Read-only.
(class)"))
+ BasePrefKey = property(_getBasePrefKey, _setBasePrefKey, None,
+ _("Base key used when saving/restoring preferences
(str)"))
+
Class = property(_getClass, None, None,
- _("""The class the object is based on. Read-only.
(class)"""))
+ _("The class the object is based on. Read-only.
(class)"))
LogEvents = property(_getLogEvents, _setLogEvents, None,
- _("""Specifies which events to log. (list of strings)
+ _("""Specifies which events to log. (list of strings)
If the first element is 'All', all events except the following
listed events
will be logged.
-
Event logging is resource-intensive, so in addition to setting
this LogEvents
property, you also need to make the following call:
-
>>> dabo.eventLogging = True
"""))
Name = property(_getName, _setName, None,
- _("""The name of the object. (str)"""))
+ _("The name of the object. (str)"))
Parent = property(_getParent, _setParent, None,
- _("""The containing object. (obj)"""))
+ _("The containing object. (obj)"))
+ PreferenceManager = property(_getPreferenceManager,
_setPreferenceManager, None,
+ _("Reference to the Preference Management object
(dPref)"))
+
SuperClass = property(_getSuperClass, None, None,
- _("""The parent class of the object. Read-only.
(class)"""))
+ _("The super class of the object. Read-only. (class)"))
if __name__ == "__main__":
@@ -322,28 +338,28 @@
app = dabo.dApp()
print d.Application
- print "Testing doDefault():"
+ print _("Testing doDefault():")
class TestBase(list, dObject):
# No myMethod here
pass
class MyTest1(TestBase):
def myMethod(self):
- print "MyTest1.myMethod called."
+ print _("MyTest1.myMethod called.")
MyTest1.doDefault()
class MyTest2(MyTest1): pass
class MyTest(MyTest2):
def myMethod(self):
- print "MyTest.myMethod called."
+ print _("MyTest.myMethod called.")
MyTest.doDefault()
- print "Test 1: simple test:"
+ print _("Test 1: simple test:")
t = MyTest()
t.myMethod()
- print "\nTest 2: diamond inheritence test:"
+ print _("\nTest 2: diamond inheritence test:")
class A(dObject):
def meth(self, arg):
@@ -373,28 +389,28 @@
t.meth(testList)
print testList
- print "\n\nTesting super():"
+ print _("\n\nTesting super():")
class TestBase(list, dObject):
# No myMethod here
pass
class MyTest1(TestBase):
def myMethod(self):
- print "MyTest1.myMethod called."
+ print _("MyTest1.myMethod called.")
self.super()
class MyTest2(MyTest1): pass
class MyTest(MyTest2):
def myMethod(self):
- print "MyTest.myMethod called."
+ print _("MyTest.myMethod called.")
self.super()
- print "Test 1: simple test:"
+ print _("Test 1: simple test:")
t = MyTest()
t.myMethod()
- print "\nTest 2: diamond inheritence test:"
+ print _("\nTest 2: diamond inheritence test:")
class A(dObject):
def meth(self, arg):
Modified: trunk/dabo/dPref.py
===================================================================
--- trunk/dabo/dPref.py 2006-06-05 12:53:45 UTC (rev 2200)
+++ trunk/dabo/dPref.py 2006-06-05 20:26:19 UTC (rev 2201)
@@ -9,7 +9,7 @@
dabo.errorLog.write("This class requires SQLite")
# We don't want to deal with these as preferences.
-regularAtts = ("_cache", "_parent", "_name", "_cursor", "_cxn", "_typeDict",
"AutoPersist",
+regularAtts = ("_cache", "_parent", "_key", "_cursor", "_cxn", "_typeDict",
"AutoPersist",
"_autoPersist", "__methods__", "__basicsize__", "__members__",
"_getAttributeNames",
"__itemsize__", "__base__", "__flags__", "__subclasses__",
"__cmp__", "__bases__",
"__dictoffset__", "__call__", "__name__", "__mro__",
"__weakrefoffset__", "mro")
@@ -24,29 +24,30 @@
new dPref object named 'subPref' will be created, and can be referred
to using
'basePref.subPref'.
- Normally you should specify the initial level for your prefs. This will
ensure that
+ Normally you should specify the initial key for your prefs. This will
ensure that
your preference names do not conflict with other dabo preferences. This
is much like
the approach to modules in the Python namespace. Failure to specify a
base
- level puts all of your prefs into the 'root' namespace, where
collisions can more
- easily happen.
+ key would put all of your prefs into the 'root' namespace, where
collisions can more
+ easily happen, and thus is not allowed.
All preference assignments are automatically persisted to the database
unless
- the 'AutoPersist' propertyon this object or one of its 'ancestors' is
set to False.
+ the 'AutoPersist' property on this object or one of its 'ancestors' is
set to False.
When that is False, you must call the persist() method manually, or
your settings
will not be saved. Calling 'persist()' will write any values of that
object and all of its
child objects to the database.
"""
- def __init__(self, level=None, crs=None, cxn=None):
+ def __init__(self, key=None, crs=None, cxn=None):
+ if key is None:
+ self._key = ""
+ else:
+ self._key = key
self._cache = {}
self._autoPersist = True
super(dPref, self).__init__()
self._parent = None
- if level is None:
- self._name = ""
- else:
- self._name = level
self._typeDict = {int: "int", float: "float", long: "long",
str: "str", unicode: "unicode",
- bool: "bool", datetime.date: "date",
datetime.datetime: "datetime"}
+ bool: "bool", list: "list", tuple: "tuple",
datetime.date: "date",
+ datetime.datetime: "datetime"}
if crs is None:
prefdir = utils.getUserDaboDirectory()
self._cxn = dabo.db.dConnection(connectInfo={"dbType":
"SQLite",
@@ -85,7 +86,7 @@
else:
ret = dPref(crs=self._cursor, cxn = self._cxn)
ret._parent = self
- ret._name = att
+ ret._key = att
self._cache[att] = ret
return ret
@@ -113,9 +114,9 @@
"""The key is a concatenation of this object's name and the
names of its
ancestors, separated with periods.
"""
- ret = self._name
+ ret = self._key
if not ret:
- ret = "root"
+ ret = ""
else:
if self._parent is not None:
ret = ".".join((self._parent._getKey(), ret))
@@ -153,6 +154,8 @@
ret = long(val)
elif typ == "bool":
ret = (val == "True")
+ elif typ in ("list", "tuple"):
+ ret = eval(val)
elif typ == "date":
ret = eval("datetime.date%s" % val)
elif typ == "datetime":
@@ -162,7 +165,12 @@
def _persist(self, att, val):
"""Writes the value of the particular att to the database with
the proper key."""
- key = "%s.%s" % (self._getKey(), att)
+ # Make sure that we have a valid key
+ baseKey = self._getKey()
+ if not baseKey:
+ dabo.errorLog.write(_("No base key set; preference will
not be persisted."))
+ return
+ key = "%s.%s" % (baseKey, att)
crs = self._cursor
try:
typ = self._typeDict[type(val)]
@@ -249,7 +257,7 @@
def getPrefKeys(self):
- """Return a list of all preference keys for this level."""
+ """Return a list of all preference keys for this key."""
crs = self._cursor
key = self._getKey()
keylen = len(key) + 1
@@ -267,7 +275,7 @@
def getSubPrefKeys(self):
- """Return a list of all 'child' keys for this level."""
+ """Return a list of all 'child' keys for this key."""
crs = self._cursor
key = self._getKey()
keylen = len(key) + 1
@@ -303,7 +311,7 @@
if __name__ == "__main__":
- a = dPref(level="TESTING")
+ a = dPref(key="TESTING")
a.testValue = "First Level"
a.anotherValue = "Another First"
a.b.testValue = "Second Level"
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev