34 from python_qt_binding
import loadUi
35 from python_qt_binding.QtCore
import QByteArray, qDebug, QObject, QSignalMapper, Signal, Slot
36 from python_qt_binding.QtGui
import QIcon, QValidator
37 from python_qt_binding.QtWidgets
import QAction, QFileDialog, QInputDialog, QMessageBox
45 """Check if the argument is a string which works for both Python 2 and 3.""" 47 return isinstance(s, basestring)
49 return isinstance(s, str)
53 """Manager for perspectives associated with specific sets of `Settings`.""" 55 perspective_changed_signal = Signal(str)
56 save_settings_signal = Signal(Settings, Settings)
57 restore_settings_signal = Signal(Settings, Settings)
58 restore_settings_without_plugin_changes_signal = Signal(Settings, Settings)
62 def __init__(self, settings, application_context):
63 super(PerspectiveManager, self).
__init__()
64 self.setObjectName(
'PerspectiveManager')
77 self.
perspectives = self._settings_proxy.value(
'',
'perspectives', [])
89 if application_context.provide_app_dbus_interfaces:
91 self.
_dbus_server = PerspectiveManagerDBusInterface(self, application_context)
99 create_action = QAction(
'&Create perspective...', self._menu_manager.menu)
100 create_action.setIcon(QIcon.fromTheme(
'list-add'))
102 self._menu_manager.add_suffix(create_action)
104 self.
_remove_action = QAction(
'&Remove perspective...', self._menu_manager.menu)
105 self._remove_action.setEnabled(
False)
106 self._remove_action.setIcon(QIcon.fromTheme(
'list-remove'))
110 self._menu_manager.add_suffix(
None)
112 import_action = QAction(
'&Import...', self._menu_manager.menu)
113 import_action.setIcon(QIcon.fromTheme(
'document-open'))
115 self._menu_manager.add_suffix(import_action)
117 export_action = QAction(
'&Export...', self._menu_manager.menu)
118 export_action.setIcon(QIcon.fromTheme(
'document-save-as'))
120 self._menu_manager.add_suffix(export_action)
129 name = self._settings_proxy.value(
'',
'current-perspective',
'Default')
130 elif hide_and_without_plugin_changes:
133 without_plugin_changes=hide_and_without_plugin_changes)
137 @Slot(str, bool, bool)
139 self, name, settings_changed=
True, save_before=
True, without_plugin_changes=
False):
150 self, name, settings_changed, save_before, without_plugin_changes=
False):
152 name = str(name.replace(
'/',
'__'))
154 qDebug(
'PerspectiveManager.switch_perspective() switching to perspective "%s"' % name)
168 if not self._current_perspective.startswith(self.
HIDDEN_PREFIX):
173 self.perspective_changed_signal.emit(self._current_perspective.lstrip(self.
HIDDEN_PREFIX))
175 if not without_plugin_changes:
176 self.restore_settings_signal.emit(
179 self.restore_settings_without_plugin_changes_signal.emit(
188 callback(*callback_args)
196 clone_perspective = self._create_perspective_dialog.clone_checkbox.isChecked()
199 name, settings_changed=
not clone_perspective, save_before=
False)
205 'share',
'qt_gui',
'resource',
'perspective_create.ui')
209 class CustomValidator(QValidator):
212 super(CustomValidator, self).
__init__(parent)
214 def fixup(self, value):
215 value = value.replace(
'/',
'')
217 def validate(self, value, pos):
218 if value.find(
'/') != -1:
219 pos = value.find(
'/')
220 return (QValidator.Invalid, value, pos)
222 return (QValidator.Intermediate, value, pos)
223 return (QValidator.Acceptable, value, pos)
224 self._create_perspective_dialog.perspective_name_edit.setValidator(CustomValidator())
227 self._create_perspective_dialog.perspective_name_edit.setText(
'')
228 self._create_perspective_dialog.clone_checkbox.setChecked(
True)
229 self._create_perspective_dialog.clone_checkbox.setVisible(show_cloning)
232 return_value = self._create_perspective_dialog.exec_()
233 if return_value == self._create_perspective_dialog.Rejected:
236 name = str(self._create_perspective_dialog.perspective_name_edit.text()).lstrip(
240 self._menu_manager.menu,
241 self.tr(
'Empty perspective name'),
242 self.tr(
'The name of the perspective must be non-empty.'))
246 self._menu_manager.menu,
247 self.tr(
'Duplicate perspective name'),
248 self.tr(
'A perspective with the same name already exists.'))
255 if name.find(
'/') != -1:
257 'PerspectiveManager._create_perspective() name cannot contain forward slashes (/)')
259 qDebug(
'PerspectiveManager._create_perspective(%s, %s)' % (name, clone_perspective))
261 self.perspectives.append(name)
262 self._settings_proxy.set_value(
'',
'perspectives', self.
perspectives)
274 if clone_perspective:
276 keys = self._perspective_settings.all_keys()
278 value = self._perspective_settings.value(key)
279 new_settings.set_value(key, value)
288 action = QAction(name, self._menu_manager.menu)
289 action.setCheckable(
True)
290 self._perspective_mapper.setMapping(action, name)
291 action.triggered.connect(self._perspective_mapper.map)
294 self._menu_manager.add_item(action)
296 if self._menu_manager.count_items() > 1:
297 self._remove_action.setEnabled(
True)
303 name, return_value = QInputDialog.getItem(
304 self._menu_manager.menu, self._menu_manager.tr(
'Remove perspective'),
305 self._menu_manager.tr(
'Select the perspective'), names, 0,
False)
308 if return_value == QInputDialog.Rejected:
314 raise UserWarning(
'unknown perspective: %s' % name)
315 qDebug(
'PerspectiveManager._remove_perspective(%s)' % str(name))
318 self.perspectives.remove(name)
319 self._settings_proxy.set_value(
'',
'perspectives', self.
perspectives)
326 self._menu_manager.remove_item(name)
329 if self._menu_manager.count_items() < 2:
330 self._remove_action.setEnabled(
False)
333 file_name, _ = QFileDialog.getOpenFileName(
334 self._menu_manager.menu, self.tr(
'Import perspective from file'),
335 self.
_file_path, self.tr(
'Perspectives (*.perspective)'))
336 if file_name
is None or file_name ==
'':
339 perspective_name = os.path.basename(file_name)
340 suffix =
'.perspective' 341 if perspective_name.endswith(suffix):
342 perspective_name = perspective_name[:-len(suffix)]
345 if perspective_name
is None:
358 file_handle = open(path,
'r') 360 data = json.loads(file_handle.read())
369 """Set dictionary key-value pairs on Settings instance.""" 370 keys = data.get(
'keys', {})
372 settings.set_value(key, keys[key])
373 groups = data.get(
'groups', {})
375 sub = settings.get_settings(group)
379 save_file_name = os.path.join(
381 suffix =
'.perspective' 382 if not save_file_name.endswith(suffix):
383 save_file_name += suffix
384 file_name, _ = QFileDialog.getSaveFileName(
385 self._menu_manager.menu, self.tr(
'Export perspective to file'),
386 save_file_name, self.tr(
'Perspectives (*.perspective)'))
387 if file_name
is None or file_name ==
'':
402 file_handle = open(file_name,
'w')
403 file_handle.write(json.dumps(data, indent=2, separators=(
',',
': ')))
407 """Convert data of Settings instance to dictionary.""" 409 for key
in settings.child_keys():
410 keys[str(key)] = settings.value(key)
412 for group
in settings.child_groups():
413 sub = settings.get_settings(group)
415 return {
'keys': keys,
'groups': groups}
418 keys = data.get(
'keys', {})
420 keys[key] = convert_function(keys[key])
421 groups = data.get(
'groups', {})
427 if value[
'type'] ==
'repr':
428 return eval(value[
'repr'])
429 elif value[
'type'] ==
'repr(QByteArray.hex)':
430 return QByteArray.fromHex(eval(value[
'repr(QByteArray.hex)']))
432 'PerspectiveManager._import_value() unknown serialization type (%s)' % value[
'type'])
436 if value.__class__.__name__ ==
'QByteArray':
437 hex_value = value.toHex()
438 data[
'repr(QByteArray.hex)'] = \
440 data[
'type'] =
'repr(QByteArray.hex)' 444 for i
in range(1, value.size(), 2):
446 character = value.at(i)
448 if character >=
' ' and character <=
'~':
449 characters += character
452 except UnicodeDecodeError:
454 data[
'pretty-print'] = characters
458 data[
'type'] =
'repr' 462 if reimported != value:
464 'PerspectiveManager._export_value() stored value can not be restored (%s)' %
470 """Strip binding specific prefix from type string.""" 471 parts = obj.__class__.__module__.split(
'.')
472 if len(parts) > 1
and parts[1] ==
'QtCore':
473 prefix =
'.'.join(parts[:2])
474 data = data.replace(prefix,
'QtCore', 1)
_create_perspective_dialog
def _get_dict_from_settings(self, settings)
def _on_remove_perspective(self)
def __init__(self, settings, application_context)
def _create_perspective(self, name, clone_perspective=True)
def _switch_perspective(self, name, settings_changed, save_before, without_plugin_changes=False)
def _on_create_perspective(self)
def _add_perspective_action(self, name)
def _remove_perspective(self, name)
def _set_dict_on_settings(self, data, settings)
def _create_perspective_continued(self, name, clone_perspective)
def _choose_new_perspective_name(self, show_cloning=True)
def switch_perspective(self, name, settings_changed=True, save_before=True, without_plugin_changes=False)
def set_perspective(self, name, hide_and_without_plugin_changes=False)
def _on_import_perspective(self)
def _strip_qt_binding_prefix(self, obj, data)
def _import_value(self, value)
def _on_export_perspective_continued(self, file_name)
def _get_perspective_settings(self, perspective_name)
def save_settings_completed(self)
def _on_export_perspective(self)
def import_perspective_from_file(self, path, perspective_name)
def _convert_values(self, data, convert_function)
def _export_value(self, value)