plugin_manager.py
Go to the documentation of this file.
00001 # Copyright (c) 2011, Dirk Thomas, Dorian Scholz, TU Darmstadt
00002 # All rights reserved.
00003 #
00004 # Redistribution and use in source and binary forms, with or without
00005 # modification, are permitted provided that the following conditions
00006 # are met:
00007 #
00008 #   * Redistributions of source code must retain the above copyright
00009 #     notice, this list of conditions and the following disclaimer.
00010 #   * Redistributions in binary form must reproduce the above
00011 #     copyright notice, this list of conditions and the following
00012 #     disclaimer in the documentation and/or other materials provided
00013 #     with the distribution.
00014 #   * Neither the name of the TU Darmstadt nor the names of its
00015 #     contributors may be used to endorse or promote products derived
00016 #     from this software without specific prior written permission.
00017 #
00018 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00027 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00028 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 # POSSIBILITY OF SUCH DAMAGE.
00030 
00031 import os
00032 import time
00033 import traceback
00034 
00035 from python_qt_binding.QtCore import qCritical, qDebug, QObject, QSettings, Qt, qWarning, Signal, Slot
00036 
00037 from .errors import PluginLoadError
00038 from .plugin_handler_container import PluginHandlerContainer
00039 from .plugin_handler_direct import PluginHandlerDirect
00040 from .plugin_instance_id import PluginInstanceId
00041 from .plugin_menu import PluginMenu
00042 from .settings import Settings
00043 from .settings_proxy import SettingsProxy
00044 
00045 
00046 class PluginManager(QObject):
00047 
00048     """
00049     Manager of plugin life cycle.
00050     It creates a specific `PluginHandler` for each plugin instance and maintains the perspective specific set of running plugins.
00051     """
00052 
00053     plugins_about_to_change_signal = Signal()
00054     plugins_changed_signal = Signal()
00055     plugin_help_signal = Signal(object)
00056     save_settings_completed_signal = Signal()
00057     close_application_signal = Signal()
00058     _deferred_reload_plugin_signal = Signal(str)
00059 
00060     discovery_cache_max_age = 60 * 60 * 24  # one day
00061 
00062     def __init__(self, plugin_provider, settings, application_context, settings_prefix=''):
00063         super(PluginManager, self).__init__()
00064         self.setObjectName('PluginManager')
00065 
00066         self._plugin_provider = plugin_provider
00067         self._settings = Settings(SettingsProxy(settings), '/'.join([x for x in ['plugin_manager', settings_prefix] if x != '']))
00068         self._application_context = application_context
00069 
00070         self._main_window = None
00071         self._container_manager = None
00072         self._plugin_menu = None
00073         self._minimized_dock_widgets_toolbar = None
00074 
00075         self._global_settings = None
00076         self._perspective_settings = None
00077         self._plugin_descriptors = None
00078         self._running_plugins = {}
00079 
00080         self._number_of_ongoing_calls = None
00081 
00082         if self._application_context.options.multi_process or self._application_context.options.embed_plugin:
00083             try:
00084                 from .plugin_handler_xembed import PluginHandlerXEmbed  # @UnusedImport
00085             except ImportError:
00086                 qCritical('PluginManager.__init__() multiprocess-mode only available under linux')
00087                 exit(-1)
00088 
00089         # force connection type to queued, to delay the 'reloading' giving the 'unloading' time to finish
00090         self._deferred_reload_plugin_signal.connect(self._reload_plugin_load, type=Qt.QueuedConnection)
00091 
00092         if self._application_context.provide_app_dbus_interfaces:
00093             from .plugin_manager_dbus_interface import PluginManagerDBusInterface
00094             self._dbus_service = PluginManagerDBusInterface(self, self._application_context)
00095 
00096     def set_main_window(self, main_window, menu_bar, container_manager):
00097         self._main_window = main_window
00098         self._container_manager = container_manager
00099         self.plugins_changed_signal.connect(self._container_manager.restore_state_of_containers)
00100         if menu_bar is not None:
00101             self._plugin_menu = PluginMenu(menu_bar, self)
00102             self._plugin_menu.load_plugin_signal.connect(self.load_plugin)
00103             self._plugin_menu.unload_plugin_signal.connect(self.unload_plugin)
00104 
00105     def set_minimized_dock_widgets_toolbar(self, toolbar):
00106         self._minimized_dock_widgets_toolbar = toolbar
00107 
00108     def discover(self):
00109         # skip discover if called multiple times
00110         if self._plugin_descriptors is not None:
00111             return
00112         self._plugin_descriptors = {}
00113 
00114         # register discovered plugins
00115         plugin_descriptors = self._discover()
00116         for plugin_descriptor in plugin_descriptors:
00117             self._plugin_descriptors[plugin_descriptor.plugin_id()] = plugin_descriptor
00118 
00119             if self._plugin_menu is not None:
00120                 self._plugin_menu.add_plugin(plugin_descriptor)
00121 
00122         if self._container_manager is not None:
00123             descriptor = self._container_manager.get_container_descriptor()
00124             self._plugin_descriptors[descriptor.plugin_id()] = descriptor
00125             if self._plugin_menu is not None:
00126                 self._container_manager.add_to_plugin_menu(self._plugin_menu)
00127 
00128     def _discover(self):
00129         discovery_data = self._settings.get_settings('discovery_data')
00130         # check timestamp of the cached discovery data
00131         cache_stamp = self._settings.value('discovery_timestamp', default_value=None)
00132         if cache_stamp:
00133             cache_stamp = float(cache_stamp)
00134 
00135         # wipe cached data when forcing discovery or when cache is to old (or from the future)
00136         now = time.time()
00137         if self._application_context.options.force_discover or not cache_stamp or cache_stamp > now or cache_stamp + PluginManager.discovery_cache_max_age < now:
00138             qDebug('PluginManager._discover() force discovery of plugins')
00139             cache_stamp = None
00140             for k in discovery_data.all_keys():
00141                 discovery_data.remove(k)
00142         else:
00143             qDebug('PluginManager._discover() using cached plugin discovery information')
00144 
00145         plugin_descriptors = self._plugin_provider.discover(discovery_data)
00146 
00147         # store timestamp and newly discovered data
00148         if not cache_stamp:
00149             self._settings.set_value('discovery_timestamp', now)
00150 
00151         return plugin_descriptors
00152 
00153     def find_plugins_by_name(self, lookup_name):
00154         plugins = {}
00155         for plugin_id, plugin_full_name in self.get_plugins().items():
00156             if plugin_full_name.lower().find(lookup_name.lower()) >= 0 or plugin_id.lower().find(lookup_name.lower()) >= 0:
00157                 plugins[plugin_id] = plugin_full_name
00158         return plugins
00159 
00160     def get_plugins(self):
00161         self.discover()
00162         plugins = {}
00163         for plugin_id, plugin_descriptor in self._plugin_descriptors.items():
00164             plugins[plugin_id] = '/'.join(plugin_descriptor.attributes().get('class_type', 'unknown').split('::'))
00165         return plugins
00166 
00167     def is_plugin_running(self, plugin_id, serial_number):
00168         instance_id = PluginInstanceId(plugin_id, serial_number)
00169         return str(instance_id) in self._running_plugins
00170 
00171 
00172     @Slot(str)
00173     @Slot(str, int)
00174     def load_plugin(self, plugin_id, serial_number=None, argv=None):
00175         qDebug('PluginManager.load_plugin(%s, %s)' % (str(plugin_id), str(serial_number) if serial_number is not None else ''))
00176         # save state of top-level widgets
00177         self.plugins_about_to_change_signal.emit()
00178         if serial_number is None:
00179             serial_number = self._next_serial_number(plugin_id)
00180         instance_id = PluginInstanceId(plugin_id, serial_number)
00181         self._load_plugin_load(instance_id, self._load_plugin_restore, argv)
00182 
00183     def _next_serial_number(self, plugin_id):
00184         # convert from unicode
00185         plugin_id = str(plugin_id)
00186         # collect serial numbers of all running instances of the specific plugin
00187         used_serial_numbers = {}
00188         for info in self._running_plugins.values():
00189             if info['instance_id'].plugin_id == plugin_id:
00190                 used_serial_numbers[info['instance_id'].serial_number] = None
00191 
00192         # find first not used serial number
00193         serial_number = 1
00194         while serial_number in used_serial_numbers:
00195             serial_number = serial_number + 1
00196         return serial_number
00197 
00198     def _load_plugin_load(self, instance_id, callback, argv=None):
00199         # if the requested instance is already running, do nothing
00200         if str(instance_id) in self._running_plugins:
00201             raise Exception('PluginManager._load_plugin(%s) instance already loaded' % str(instance_id))
00202 
00203         # containers are pseudo-plugins and handled by a special handler
00204         if self._container_manager is not None and instance_id.plugin_id == self._container_manager.get_container_descriptor().plugin_id():
00205             handler = PluginHandlerContainer(self, self._main_window, instance_id, self._application_context, self._container_manager)
00206 
00207         # use platform specific handler for multiprocess-mode if available
00208         elif self._application_context.options.multi_process or self._application_context.options.embed_plugin:
00209             try:
00210                 from .plugin_handler_xembed import PluginHandlerXEmbed
00211                 handler = PluginHandlerXEmbed(self, self._main_window, instance_id, self._application_context, self._container_manager, argv)
00212             except ImportError:
00213                 qCritical('PluginManager._load_plugin() could not load plugin in a separate process')
00214                 return
00215 
00216         # use direct handler for in-process plugins
00217         else:
00218             handler = PluginHandlerDirect(self, self._main_window, instance_id, self._application_context, self._container_manager, argv)
00219 
00220         handler.set_minimized_dock_widgets_toolbar(self._minimized_dock_widgets_toolbar)
00221 
00222         plugin_descriptor = self._plugin_descriptors[instance_id.plugin_id]
00223         handler.set_plugin_descriptor(plugin_descriptor)
00224 
00225         self._add_running_plugin(instance_id, handler)
00226         handler.load(self._plugin_provider, callback)
00227 
00228     def _add_running_plugin(self, instance_id, handler):
00229         if self._plugin_menu is not None:
00230             plugin_descriptor = self._plugin_descriptors[instance_id.plugin_id]
00231             self._plugin_menu.add_instance(plugin_descriptor, instance_id)
00232 
00233         info = {
00234             'handler': handler,
00235             'instance_id': instance_id
00236         }
00237         self._running_plugins[str(instance_id)] = info
00238 
00239     def _load_plugin_restore(self, handler, exception):
00240         qDebug('PluginManager._load_plugin_restore()')
00241         self._load_plugin_completed(handler, exception)
00242         if exception is None:
00243             # restore settings after load
00244             self._restore_plugin_settings(handler.instance_id(), self._emit_load_plugin_completed)
00245 
00246     def _load_plugin_completed(self, handler, exception):
00247         instance_id = handler.instance_id()
00248         if exception is not None:
00249             if isinstance(exception, PluginLoadError):
00250                 qWarning('PluginManager._load_plugin() could not load plugin "%s": %s' % (instance_id.plugin_id, exception))
00251             else:
00252                 qCritical('PluginManager._load_plugin() could not load plugin "%s"%s' % (instance_id.plugin_id, (':\n%s' % traceback.format_exc() if exception != True else '')))
00253             self._remove_running_plugin(instance_id)
00254             # quit embed application
00255             if self._application_context.options.embed_plugin:
00256                 exit(-1)
00257             return
00258 
00259         qDebug('PluginManager._load_plugin(%s) successful' % str(instance_id))
00260 
00261         handler.close_signal.connect(self.unload_plugin)
00262         handler.reload_signal.connect(self.reload_plugin)
00263         handler.help_signal.connect(self._emit_plugin_help_signal)
00264 
00265     def _emit_plugin_help_signal(self, instance_id_str):
00266         instance_id = PluginInstanceId(instance_id=instance_id_str)
00267         plugin_descriptor = self._plugin_descriptors[instance_id.plugin_id]
00268         self.plugin_help_signal.emit(plugin_descriptor)
00269 
00270     def _restore_plugin_settings(self, instance_id, callback):
00271         if self._global_settings is not None and self._perspective_settings is not None:
00272             info = self._running_plugins[str(instance_id)]
00273             plugin_settings = self._global_settings.get_settings('plugin__' + instance_id.tidy_plugin_str())
00274             instance_settings = self._perspective_settings.get_settings('plugin__' + instance_id.tidy_str())
00275             handler = info['handler']
00276             handler.restore_settings(plugin_settings, instance_settings, callback)
00277         else:
00278             callback(instance_id)
00279 
00280     def _emit_load_plugin_completed(self, instance_id):
00281         qDebug('PluginManager._emit_load_plugin_completed()')
00282         # restore state of top-level widgets
00283         self.plugins_changed_signal.emit()
00284 
00285 
00286     @Slot(str)
00287     def unload_plugin(self, instance_id_str):
00288         # unloading a plugin with locked perspective or running standalone triggers close of application
00289         if self._application_context.options.lock_perspective or self._application_context.options.standalone_plugin:
00290             self._close_application_signal()
00291             return
00292         instance_id = PluginInstanceId(instance_id=instance_id_str)
00293         qDebug('PluginManager.unload_plugin(%s)' % str(instance_id))
00294         # save state of top-level widgets
00295         self.plugins_about_to_change_signal.emit()
00296         # save settings before shutdown and unloading
00297         self._save_plugin_settings(instance_id, self._unload_plugin_shutdown)
00298 
00299     def _save_plugin_settings(self, instance_id, callback):
00300         if self._global_settings is not None and self._perspective_settings is not None:
00301             info = self._running_plugins[str(instance_id)]
00302             plugin_settings = self._global_settings.get_settings('plugin__' + instance_id.tidy_plugin_str())
00303             instance_settings = self._perspective_settings.get_settings('plugin__' + instance_id.tidy_str())
00304             handler = info['handler']
00305             handler.save_settings(plugin_settings, instance_settings, callback)
00306         else:
00307             callback(instance_id)
00308 
00309     def _unload_plugin_shutdown(self, instance_id):
00310         qDebug('PluginManager._unload_plugin_shutdown(%s)' % str(instance_id))
00311         self._shutdown_plugin(instance_id, self._unload_plugin_unload)
00312 
00313     def _shutdown_plugin(self, instance_id, callback):
00314         # shutdown plugin before unloading
00315         info = self._running_plugins[str(instance_id)]
00316         handler = info['handler']
00317         handler.close_signal.disconnect(self.unload_plugin)
00318         handler.shutdown_plugin(callback)
00319 
00320     def _unload_plugin_unload(self, instance_id):
00321         qDebug('PluginManager._unload_plugin_unload(%s)' % str(instance_id))
00322         self._unload_plugin(instance_id, self._unload_plugin_completed)
00323 
00324     def _unload_plugin(self, instance_id, callback=None):
00325         # unload plugin
00326         info = self._running_plugins[str(instance_id)]
00327         handler = info['handler']
00328         handler.unload(callback)
00329 
00330     def _unload_plugin_completed(self, instance_id):
00331         qDebug('PluginManager._unload_plugin_completed(%s)' % str(instance_id))
00332         self._remove_running_plugin(instance_id)
00333 
00334     def _remove_running_plugin(self, instance_id):
00335         if self._plugin_menu is not None:
00336             self._plugin_menu.remove_instance(instance_id)
00337         info = self._running_plugins[str(instance_id)]
00338         self._running_plugins.pop(str(instance_id))
00339 
00340 
00341     @Slot(str)
00342     def reload_plugin(self, instance_id_str):
00343         instance_id = PluginInstanceId(instance_id=instance_id_str)
00344         qDebug('PluginManager.reload_plugin(%s)' % str(instance_id))
00345         # save state of top-level widgets
00346         self.plugins_about_to_change_signal.emit()
00347         self._reload_plugin_save(instance_id)
00348 
00349     def _reload_plugin_save(self, instance_id):
00350         # save settings before unloading
00351         self._save_plugin_settings(instance_id, self._reload_plugin_shutdown)
00352 
00353     def _reload_plugin_shutdown(self, instance_id):
00354         qDebug('PluginManager._reload_plugin_shutdown(%s)' % str(instance_id))
00355         self._shutdown_plugin(instance_id, self._reload_plugin_unload)
00356 
00357     def _reload_plugin_unload(self, instance_id):
00358         qDebug('PluginManager._reload_plugin_unload(%s)' % str(instance_id))
00359         self._unload_plugin(instance_id, self._reload_plugin_schedule_load)
00360 
00361     def _reload_plugin_schedule_load(self, instance_id):
00362         qDebug('PluginManager._reload_plugin_schedule_load(%s)' % str(instance_id))
00363         self._remove_running_plugin(instance_id)
00364         self._deferred_reload_plugin_signal.emit(str(instance_id))
00365 
00366     def _reload_plugin_load(self, instance_id_str):
00367         instance_id = PluginInstanceId(instance_id=instance_id_str)
00368         qDebug('PluginManager._reload_plugin_load(%s)' % str(instance_id))
00369         self._load_plugin_load(instance_id, self._reload_plugin_restore)
00370 
00371     def _reload_plugin_restore(self, handler, exception):
00372         qDebug('PluginManager._reload_plugin_restore()')
00373         self._load_plugin_completed(handler, exception)
00374         if exception is None:
00375             # restore settings after load
00376             self._restore_plugin_settings(handler.instance_id(), self._emit_load_plugin_completed)
00377 
00378 
00379     def save_settings(self, global_settings, perspective_settings):
00380         self._save_settings(global_settings, perspective_settings, self._save_settings_callback)
00381 
00382     def _save_settings(self, global_settings, perspective_settings, callback):
00383         qDebug('PluginManager.save_settings()')
00384         self._global_settings = global_settings.get_settings('pluginmanager')
00385         self._perspective_settings = perspective_settings.get_settings('pluginmanager')
00386         self._store_running_plugins()
00387         # trigger async call on all running plugins
00388         self._number_of_ongoing_calls = len(self._running_plugins)
00389         if self._number_of_ongoing_calls > 0:
00390             for info in self._running_plugins.values():
00391                 self._save_plugin_settings(info['instance_id'], callback)
00392         else:
00393             callback()
00394 
00395     def _store_running_plugins(self):
00396         if self._perspective_settings is not None:
00397             plugins = {}
00398             for info in self._running_plugins.values():
00399                 instance_id = info['instance_id']
00400                 plugin_id = instance_id.plugin_id
00401                 if plugin_id not in plugins:
00402                     plugins[plugin_id] = []
00403                 plugins[plugin_id].append(instance_id.serial_number)
00404             self._perspective_settings.set_value('running-plugins', plugins)
00405 
00406     def _save_settings_callback(self, instance_id=None):
00407         if instance_id is not None:
00408             self._number_of_ongoing_calls = self._number_of_ongoing_calls - 1
00409         if self._number_of_ongoing_calls == 0:
00410             qDebug('PluginManager.save_settings() completed')
00411             self._number_of_ongoing_calls = None
00412             self.save_settings_completed_signal.emit()
00413 
00414 
00415     def close_application(self, global_settings, perspective_settings):
00416         self._save_settings(global_settings, perspective_settings, self._close_application_save_callback)
00417 
00418     def _close_application_save_callback(self, instance_id=None):
00419         self._save_settings_callback(instance_id)
00420         if self._number_of_ongoing_calls is None:
00421             self._close_application_shutdown_plugins()
00422 
00423     def _close_application_shutdown_plugins(self):
00424         # trigger async call on all running plugins
00425         self._number_of_ongoing_calls = len(self._running_plugins)
00426         if self._number_of_ongoing_calls > 0:
00427             for info in self._running_plugins.values():
00428                 self._shutdown_plugin(info['instance_id'], self._close_application_shutdown_callback)
00429         else:
00430             self._close_application_shutdown_callback()
00431 
00432     def _close_application_shutdown_callback(self, instance_id=None):
00433         if instance_id is not None:
00434             self._number_of_ongoing_calls = self._number_of_ongoing_calls - 1
00435         if self._number_of_ongoing_calls == 0:
00436             qDebug('PluginManager.close_application() completed')
00437             self._number_of_ongoing_calls = None
00438             self._close_application_signal()
00439 
00440     def _close_application_signal(self):
00441         self._plugin_provider.shutdown()
00442         self.close_application_signal.emit()
00443 
00444 
00445     def restore_settings(self, global_settings, perspective_settings):
00446         qDebug('PluginManager.restore_settings()')
00447         self._global_settings = global_settings.get_settings('pluginmanager')
00448         self._perspective_settings = perspective_settings.get_settings('pluginmanager')
00449         self._restore_settings_save_obsolete()
00450 
00451     def _restore_settings_save_obsolete(self):
00452         # trigger shutdown of obsolete plugins
00453         plugins = self._restore_running_plugins_get_plugins()
00454         obsolete = []
00455         for instance_id in self._running_plugins.keys():
00456             if instance_id not in plugins.keys():
00457                 obsolete.append(PluginInstanceId(instance_id=instance_id))
00458         self._number_of_ongoing_calls = len(obsolete)
00459         if self._number_of_ongoing_calls > 0:
00460             qDebug('PluginManager.restore_settings() unloading %d obsolete plugins' % self._number_of_ongoing_calls)
00461             for instance_id in obsolete:
00462                 self._shutdown_plugin(instance_id, self._restore_settings_unload_obsolete)
00463         else:
00464             self._restore_settings_unload_obsolete_callback()
00465 
00466     def _restore_running_plugins_get_plugins(self):
00467         plugins = {}
00468         if self._perspective_settings is not None:
00469             data = self._perspective_settings.value('running-plugins', {})
00470             for plugin_id, serial_numbers in data.items():
00471                 for serial_number in serial_numbers:
00472                     instance_id = PluginInstanceId(plugin_id, serial_number)
00473                     plugins[str(instance_id)] = instance_id
00474         return plugins
00475 
00476     def _restore_settings_unload_obsolete(self, instance_id):
00477         # trigger unload of obsolete plugins
00478         self._unload_plugin(instance_id, self._restore_settings_unload_obsolete_callback)
00479 
00480     def _restore_settings_unload_obsolete_callback(self, instance_id=None):
00481         if instance_id is not None:
00482             self._number_of_ongoing_calls = self._number_of_ongoing_calls - 1
00483             self._remove_running_plugin(instance_id)
00484         if self._number_of_ongoing_calls == 0:
00485             if instance_id is not None:
00486                 qDebug('PluginManager.restore_settings() all obsolete plugins unloaded')
00487             self._number_of_ongoing_calls = None
00488             self._restore_settings_load_missing()
00489 
00490     def _restore_settings_load_missing(self):
00491         # trigger_load of not yet loaded plugins
00492         plugins = self._restore_running_plugins_get_plugins()
00493         loading = []
00494         for instance_id_str, instance_id in plugins.items():
00495             if instance_id_str not in self._running_plugins.keys():
00496                 loading.append(instance_id)
00497         self._number_of_ongoing_calls = len(loading)
00498         if self._number_of_ongoing_calls > 0:
00499             qDebug('PluginManager.restore_settings() loading %d plugins' % self._number_of_ongoing_calls)
00500             for instance_id in loading:
00501                 self._load_plugin_load(instance_id, self._restore_settings_load_missing_callback)
00502         else:
00503             self._restore_settings_load_missing_callback()
00504 
00505     def _restore_settings_load_missing_callback(self, handler=None, exception=None):
00506         if handler is not None:
00507             self._number_of_ongoing_calls = self._number_of_ongoing_calls - 1
00508             self._load_plugin_completed(handler, exception)
00509         if self._number_of_ongoing_calls == 0:
00510             if handler is not None:
00511                 qDebug('PluginManager.restore_settings() all missing plugins loaded')
00512             self._number_of_ongoing_calls = None
00513             self._restore_settings_restore()
00514 
00515     def restore_settings_without_plugins(self, global_settings, perspective_settings):
00516         qDebug('PluginManager.restore_settings_without_plugins()')
00517         self._global_settings = global_settings.get_settings('pluginmanager')
00518         self._perspective_settings = perspective_settings.get_settings('pluginmanager')
00519         self._restore_settings_restore()
00520 
00521     def _restore_settings_restore(self):
00522         # trigger restore settings for all running plugins
00523         self._number_of_ongoing_calls = len(self._running_plugins)
00524         if self._number_of_ongoing_calls > 0:
00525             for info in self._running_plugins.values():
00526                 self._restore_plugin_settings(info['instance_id'], self._restore_settings_restore_callback)
00527         else:
00528             self._restore_settings_restore_callback()
00529 
00530     def _restore_settings_restore_callback(self, instance_id=None):
00531         if instance_id is not None:
00532             self._number_of_ongoing_calls = self._number_of_ongoing_calls - 1
00533         if self._number_of_ongoing_calls == 0:
00534             if instance_id is not None:
00535                 qDebug('PluginManager.restore_settings() all plugin settings restored')
00536             self._number_of_ongoing_calls = None
00537             # restore state of top-level widgets
00538             self.plugins_changed_signal.emit()


qt_gui
Author(s): Dirk Thomas
autogenerated on Mon Oct 6 2014 03:57:52