forget the past.
forget the past.
# Copyright (c) 2004 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, 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 License for more details
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""This module contains some tools to handle main application and plugins
configuration.
"""
__revision__ = '$Id: config_tools.py,v 1.12 2006-04-23 13:53:52 nico Exp $'
from os.path import join
import gtk, gobject
from pigg.mvc import Controller
from pigg.form import PyFormModel
from pigg.wgenerator import notebook_generate
from logilab.common.configuration import Configuration, OptionValueError
from oobrother.uiutils.basemixins import WindowMixIn, PluggableFrameMixIn, \
MenuControlledWindowMixIn
from oobrother.uiutils.trees import init_treeview_columns
from oobrother.sysutils import OOBROTHER_HOME
# from oobrother import get_path
__metaclass__ = type
def format_config_entry(opt_name, opt_dict):
"""format a config entry to a schema line"""
opt_type = opt_dict['type']
if opt_type in ('choice', 'multiple_choice'):
extra_args = (opt_dict['choices'],)
else:
extra_args = ()
return (opt_name, opt_type, opt_name.replace('_', ' '),
extra_args, False, opt_dict.get('default'))
def schema_from_config(config):
"""return a schema as expected by `gtkmv.form.PyFormModel`, built
from a `logilab.common.configuration.Configuration` instance.
"""
return [format_config_entry(opt_name, opt_dict)
for opt_name, opt_dict in config.options]
def notebook_from_config(config, model, ctrl):
"""generates and returns a gtk note book according to the given
`logilab.common.configuration.Configuration` instance
"""
nb_def = {}
for opt_name, opt_dict in config.options:
if opt_dict.get('type') is None:
continue
section = opt_dict.get('group', config.name)
attr_def = format_config_entry(opt_name, opt_dict)
nb_def.setdefault(section, []).append(attr_def)
return notebook_generate(nb_def.items(), model, ctrl)
def build_config_model(configurables):
"""creates an returns a tree model from a configuration tree"""
store = gtk.TreeStore(gobject.TYPE_STRING, # configuration section
gobject.TYPE_PYOBJECT, # The configuration object
)
for configurable in configurables:
fill_config_store(store, configurable, None)
return store
def fill_config_store(store, configurable, tree_iter):
"""recursive build of a tree model for a configuration tree"""
new_iter = store.append(tree_iter, [configurable.name, configurable])
for subconfig in configurable.subconfiguration():
fill_config_store(store, subconfig, new_iter)
def configuration_models(configurables):
"""return a list of configurable object (ie configuration node with
a 'cfg' attribute set)
"""
result = []
for configurable in configurables:
if configurable.cfg:
result.append(configurable.cfg.model)
result += configuration_models(configurable.subconfiguration())
return result
class ConfigurableNode:
def __init__(self, name, cfg=None, children=()):
self.name = name
self.cfg = cfg # optionel pluggable config object
self._children = children
def subconfiguration(self):
"""return a list of configuration nodes for subconfiguration
"""
return self._children
class PluggableConfig(Configuration):
"""extends `logilab.common.configuration.Configuration` to handle
gui specific stuff (model, ctrl, pluggable widget
"""
def __init__(self, name, config_file, options):
if config_file:
config_file = join(OOBROTHER_HOME, config_file)
Configuration.__init__(self, config_file, options, name)
self.wdg = None
assert options
assert config_file
self.model = ConfigurationModel(self)
try:
self.load_file_configuration()
except OptionValueError, ex:
log(LOG_ERR, '%s: %s', (config_file, ex))
self.model.update()
self.ctrl = Controller(self.model)
self.wdg = notebook_from_config(self, self.model, self.ctrl).wdg
self.wdg.show_all()
class ConfigurationModel(PyFormModel):
"""a gtkmv model using a `logilab.common.configuration.Configuration`
instance as backend
"""
def __init__(self, config, schema=None):
self.config = config
if schema is None:
schema = schema_from_config(config)
self.schema = schema
PyFormModel.__init__(self, self.schema, {})
def update(self):
"""update the model values from the backend values"""
for attr in self.schema:
attr = attr[0]
self.set_value(attr, self.config[attr])
self._orig_data = self._data.copy()
def _commit(self):
"""write back the model's content (the form is completed at this point)
"""
modifs = self.get_modifications()
if not modifs:
log(LOG_DEBUG, 'no modification to save to %s' %
self.config.config_file)
return
for key, value in modifs.items():
try:
self.config.global_set_option(key, value)
except KeyError:
self.config.set_option(key, value)
self.config.generate_config(open(self.config.config_file, 'w'))
log(LOG_INFO, '%s written' % self.config.config_file)
class GlobalConfigurationModel:
"""the global configuration model is used to connect all the models
related to application's configuration and editable by the
configuration window.
It only defines necessary methods from the Model interface.
"""
def __init__(self, models):
self._models = models
def commit(self):
"""commit all models"""
for model in self._models:
model.commit()
def rollback(self):
"""rollback all models"""
for model in self._models:
model.rollback()
def notify_all(self):
"""ask each model to notify its observers"""
for model in self._models:
model.notify_all()
def get_modifications(self):
"""return the modification of each model merged alltogether"""
modifs = {}
for model in self._models:
modifs.update(model.get_modifications())
return modifs