34 from python_qt_binding.QtCore
import \
35 qCritical, qDebug, QObject, Qt, qWarning, Signal, Slot
48 Manager of plugin life cycle. 50 It creates a specific `PluginHandler` for each plugin instance and maintains the perspective 51 specific set of running plugins. 54 plugins_about_to_change_signal = Signal()
55 plugins_changed_signal = Signal()
56 plugin_help_signal = Signal(object)
57 save_settings_completed_signal = Signal()
58 close_application_signal = Signal()
59 _deferred_reload_plugin_signal = Signal(str)
61 discovery_cache_max_age = 60 * 60 * 24
63 def __init__(self, plugin_provider, settings, application_context, settings_prefix=''):
64 super(PluginManager, self).
__init__()
65 self.setObjectName(
'PluginManager')
69 [x
for x
in [
'plugin_manager', settings_prefix]
if x !=
'']))
84 if self._application_context.options.multi_process
or \
85 self._application_context.options.embed_plugin:
89 qCritical(
'PluginManager.__init__() multiprocess-mode only available under linux')
94 self._deferred_reload_plugin_signal.connect(
97 if self._application_context.provide_app_dbus_interfaces:
104 self.plugins_changed_signal.connect(self._container_manager.restore_state_of_containers)
105 if menu_bar
is not None:
107 self._plugin_menu.load_plugin_signal.connect(self.
load_plugin)
108 self._plugin_menu.unload_plugin_signal.connect(self.
unload_plugin)
121 for plugin_descriptor
in plugin_descriptors:
125 self._plugin_menu.add_plugin(plugin_descriptor)
128 descriptor = self._container_manager.get_container_descriptor()
131 self._container_manager.add_to_plugin_menu(self.
_plugin_menu)
134 discovery_data = self._settings.get_settings(
'discovery_data')
136 cache_stamp = self._settings.value(
'discovery_timestamp', default_value=
None)
138 cache_stamp = float(cache_stamp)
142 if self._application_context.options.force_discover
or \
144 cache_stamp > now
or \
145 cache_stamp + PluginManager.discovery_cache_max_age < now:
146 qDebug(
'PluginManager._discover() force discovery of plugins')
148 for k
in discovery_data.all_keys():
149 discovery_data.remove(k)
151 qDebug(
'PluginManager._discover() using cached plugin discovery information')
153 plugin_descriptors = self._plugin_provider.discover(discovery_data)
157 self._settings.set_value(
'discovery_timestamp', now)
159 return plugin_descriptors
163 for plugin_id, plugin_full_name
in self.
get_plugins().items():
164 if plugin_full_name.lower().find(lookup_name.lower()) >= 0
or \
165 plugin_id.lower().find(lookup_name.lower()) >= 0:
166 plugins[plugin_id] = plugin_full_name
172 for plugin_id, plugin_descriptor
in self._plugin_descriptors.items():
173 plugins[plugin_id] =
'/'.join(
174 plugin_descriptor.attributes().get(
'class_type',
'unknown').split(
'::'))
178 return self._plugin_descriptors.get(plugin_id,
None)
187 qDebug(
'PluginManager.load_plugin(%s, %s)' %
188 (str(plugin_id), str(serial_number)
if serial_number
is not None else ''))
190 self.plugins_about_to_change_signal.emit()
191 if serial_number
is None:
198 plugin_id = str(plugin_id)
200 used_serial_numbers = {}
201 for info
in self._running_plugins.values():
202 if info[
'instance_id'].plugin_id == plugin_id:
203 used_serial_numbers[info[
'instance_id'].serial_number] =
None 207 while serial_number
in used_serial_numbers:
208 serial_number = serial_number + 1
215 'PluginManager._load_plugin(%s) instance already loaded' % str(instance_id))
219 instance_id.plugin_id == \
220 self._container_manager.get_container_descriptor().plugin_id():
225 elif self._application_context.options.multi_process
or \
226 self._application_context.options.embed_plugin:
230 PluginHandlerXEmbed(self, self.
_main_window, instance_id,
234 'PluginManager._load_plugin() could not load plugin in a separate process')
244 if instance_id.plugin_id
not in self._plugin_descriptors.keys():
246 'PluginManager._load_plugin() could not load plugin "%s": plugin not available' %
247 (instance_id.plugin_id))
250 handler.set_plugin_descriptor(plugin_descriptor)
258 self._plugin_menu.add_instance(plugin_descriptor, instance_id)
259 handler.label_updated.connect(self._plugin_menu.update_plugin_instance_label)
263 'instance_id': instance_id
268 qDebug(
'PluginManager._load_plugin_restore()')
270 if exception
is None:
275 instance_id = handler.instance_id()
276 if exception
is not None:
277 if isinstance(exception, PluginLoadError):
278 qWarning(
'PluginManager._load_plugin() could not load plugin "%s": %s' %
279 (instance_id.plugin_id, exception))
281 qCritical(
'PluginManager._load_plugin() could not load plugin "%s"%s' %
282 (instance_id.plugin_id, (
':\n%s' % traceback.format_exc()
if 283 isinstance(exception, Exception)
else '')))
286 if self._application_context.options.embed_plugin:
290 qDebug(
'PluginManager._load_plugin(%s) successful' % str(instance_id))
299 self.plugin_help_signal.emit(plugin_descriptor)
304 plugin_settings = self._global_settings.get_settings(
305 'plugin__' + instance_id.tidy_plugin_str())
306 instance_settings = self._perspective_settings.get_settings(
307 'plugin__' + instance_id.tidy_str())
308 handler = info[
'handler']
309 handler.restore_settings(plugin_settings, instance_settings, callback)
311 callback(instance_id)
314 qDebug(
'PluginManager._emit_load_plugin_completed()')
316 self.plugins_changed_signal.emit()
322 if self._application_context.options.lock_perspective
or \
323 self._application_context.options.standalone_plugin:
327 qDebug(
'PluginManager.unload_plugin(%s)' % str(instance_id))
329 self.plugins_about_to_change_signal.emit()
336 plugin_settings = self._global_settings.get_settings(
337 'plugin__' + instance_id.tidy_plugin_str())
338 instance_settings = self._perspective_settings.get_settings(
339 'plugin__' + instance_id.tidy_str())
340 handler = info[
'handler']
341 handler.save_settings(plugin_settings, instance_settings, callback)
343 callback(instance_id)
346 qDebug(
'PluginManager._unload_plugin_shutdown(%s)' % str(instance_id))
352 handler = info[
'handler']
354 handler.shutdown_plugin(callback)
357 qDebug(
'PluginManager._unload_plugin_unload(%s)' % str(instance_id))
363 handler = info[
'handler']
364 handler.unload(callback)
367 qDebug(
'PluginManager._unload_plugin_completed(%s)' % str(instance_id))
373 self._plugin_menu.remove_instance(instance_id)
374 info[
'handler'].label_updated.disconnect(
375 self._plugin_menu.update_plugin_instance_label)
376 self._running_plugins.pop(str(instance_id))
381 qDebug(
'PluginManager.reload_plugin(%s)' % str(instance_id))
383 self.plugins_about_to_change_signal.emit()
391 qDebug(
'PluginManager._reload_plugin_shutdown(%s)' % str(instance_id))
395 qDebug(
'PluginManager._reload_plugin_unload(%s)' % str(instance_id))
399 qDebug(
'PluginManager._reload_plugin_schedule_load(%s)' % str(instance_id))
401 self._deferred_reload_plugin_signal.emit(str(instance_id))
405 qDebug(
'PluginManager._reload_plugin_load(%s)' % str(instance_id))
409 qDebug(
'PluginManager._reload_plugin_restore()')
411 if exception
is None:
419 qDebug(
'PluginManager.save_settings()')
428 for info
in list(self._running_plugins.values()):
436 for info
in self._running_plugins.values():
437 instance_id = info[
'instance_id']
438 plugin_id = instance_id.plugin_id
439 if plugin_id
not in plugins:
440 plugins[plugin_id] = []
441 plugins[plugin_id].append(instance_id.serial_number)
442 self._perspective_settings.set_value(
'running-plugins', plugins)
445 if instance_id
is not None:
448 qDebug(
'PluginManager.save_settings() completed')
450 self.save_settings_completed_signal.emit()
465 for info
in self._running_plugins.values():
472 if instance_id
is not None:
475 qDebug(
'PluginManager.close_application() completed')
480 self._plugin_provider.shutdown()
481 self.close_application_signal.emit()
484 qDebug(
'PluginManager.restore_settings()')
493 for instance_id
in self._running_plugins.keys():
494 if instance_id
not in plugins.keys():
498 qDebug(
'PluginManager.restore_settings() unloading %d obsolete plugins' %
500 for instance_id
in obsolete:
508 data = self._perspective_settings.value(
'running-plugins', {})
509 for plugin_id, serial_numbers
in data.items():
510 for serial_number
in serial_numbers:
512 plugins[str(instance_id)] = instance_id
520 if instance_id
is not None:
524 if instance_id
is not None:
525 qDebug(
'PluginManager.restore_settings() all obsolete plugins unloaded')
533 for instance_id_str, instance_id
in plugins.items():
534 if instance_id_str
not in self._running_plugins.keys():
535 loading.append(instance_id)
538 qDebug(
'PluginManager.restore_settings() loading %d plugins' %
540 for instance_id
in loading:
546 if handler
is not None:
550 if handler
is not None:
551 qDebug(
'PluginManager.restore_settings() all missing plugins loaded')
556 qDebug(
'PluginManager.restore_settings_without_plugins()')
565 for info
in self._running_plugins.values():
572 if instance_id
is not None:
575 if instance_id
is not None:
576 qDebug(
'PluginManager.restore_settings() all plugin settings restored')
579 self.plugins_changed_signal.emit()
def _restore_settings_unload_obsolete_callback(self, instance_id=None)
def load_plugin(self, plugin_id, serial_number=None, argv=None)
def find_plugins_by_name(self, lookup_name)
def restore_settings(self, global_settings, perspective_settings)
def is_plugin_running(self, plugin_id, serial_number)
def reload_plugin(self, instance_id_str)
def _close_application_signal(self)
def _load_plugin_restore(self, handler, exception)
def _save_settings(self, global_settings, perspective_settings, callback)
def _unload_plugin_shutdown(self, instance_id)
def _store_running_plugins(self)
def _emit_load_plugin_completed(self, instance_id)
def set_main_window(self, main_window, menu_bar, container_manager)
def _load_plugin_load(self, instance_id, callback, argv=None)
def save_settings(self, global_settings, perspective_settings)
def get_plugin_descriptor(self, plugin_id)
def _unload_plugin(self, instance_id, callback=None)
def _reload_plugin_save(self, instance_id)
def _restore_settings_load_missing_callback(self, handler=None, exception=None)
def _next_serial_number(self, plugin_id)
def _close_application_shutdown_plugins(self)
def _add_running_plugin(self, instance_id, handler)
def _unload_plugin_unload(self, instance_id)
def set_minimized_dock_widgets_toolbar(self, toolbar)
def _restore_settings_restore_callback(self, instance_id=None)
def _remove_running_plugin(self, instance_id)
def close_application(self, global_settings, perspective_settings)
def _restore_settings_unload_obsolete(self, instance_id)
def _close_application_shutdown_callback(self, instance_id=None)
def _load_plugin_completed(self, handler, exception)
def _reload_plugin_restore(self, handler, exception)
def _emit_plugin_help_signal(self, instance_id_str)
def _restore_settings_save_obsolete(self)
def _reload_plugin_load(self, instance_id_str)
def _restore_plugin_settings(self, instance_id, callback)
def _restore_running_plugins_get_plugins(self)
def __init__(self, plugin_provider, settings, application_context, settings_prefix='')
def _save_plugin_settings(self, instance_id, callback)
def restore_settings_without_plugins(self, global_settings, perspective_settings)
def _restore_settings_load_missing(self)
def _save_settings_callback(self, instance_id=None)
def _unload_plugin_completed(self, instance_id)
def _restore_settings_restore(self)
_minimized_dock_widgets_toolbar
def _reload_plugin_shutdown(self, instance_id)
def _close_application_save_callback(self, instance_id=None)
def unload_plugin(self, instance_id_str)
def _shutdown_plugin(self, instance_id, callback)
def _reload_plugin_schedule_load(self, instance_id)
def _reload_plugin_unload(self, instance_id)