예제 #1
0
    def __init__(self, parent, cmdp):
        QtWidgets.QDialog.__init__(self, parent)
        self.setObjectName('PreferencesDialog')
        self._active_group = None
        self._active_profile = cmdp.preferences.profile
        self._params = []
        self._cmdp = cmdp

        self.ui = Ui_PreferencesDialog()
        self.ui.setupUi(self)
        self._target_widget = None

        self._definitions = self._cmdp.preferences.definitions
        if self._definitions['name'] != '/':
            raise ValueError('unexpected root')
        self._definitions_tree_map = {}

        self._tree_model = QtGui.QStandardItemModel(self)
        self._tree_model.setHorizontalHeaderLabels(['Name'])
        self.ui.treeView.setModel(self._tree_model)
        self.ui.treeView.setHeaderHidden(True)
        self.ui.treeView.selectionModel().currentChanged.connect(
            self._on_tree_item_changed)
        self._tree_populate(self._tree_model.invisibleRootItem(),
                            self._definitions)

        select_mode_index = self._tree_model.index(0, 0)
        self.ui.treeView.setCurrentIndex(select_mode_index)
        self.ui.treeView.expandAll()
        self._on_tree_item_changed(select_mode_index, None)
        self.ui.profileComboBox.currentIndexChanged.connect(
            self._on_profile_combo_box_change)
        self._profile_combobox_update()

        self.ui.profileActivateButton.pressed.connect(
            self._on_profile_activate_button)
        self.ui.profileResetButton.pressed.connect(
            self._on_profile_reset_button)
        self.ui.profileNewButton.pressed.connect(self._on_profile_new_button)
        self.ui.helpButton.pressed.connect(self._help)

        self.ui.okButton.pressed.connect(self.accept)
        self.ui.cancelButton.pressed.connect(self.reject)
        self.ui.resetButton.pressed.connect(self.preferences_reset)

        self._cmdp.subscribe('!preferences/profile/add', self._on_profile_add)
        self._cmdp.subscribe('!preferences/profile/remove',
                             self._on_profile_remove)
        self._cmdp.subscribe('Appearance/Theme', self._on_theme)

        self._refresh_topic = f'!preferences/_ui/refresh_{id(self)}'
        self._cmdp.register(self._refresh_topic, self._refresh)
예제 #2
0
 def __init__(self, cfg_def, cfg):
     QtWidgets.QDialog.__init__(self)
     self._active_group = None
     self._params = []
     self._cfg_def = cfg_def
     self.cfg_orig = cfg
     self._cfg = copy.deepcopy(cfg)
     self.ui = Ui_PreferencesDialog()
     self.ui.setupUi(self)
     self._model = QtGui.QStandardItemModel()
     for entry in self._cfg_def['children']:
         item = QtGui.QStandardItem(entry['name'])
         self._model.appendRow(item)
     self.ui.groupListView.setModel(self._model)
     self.ui.groupListView.selectionModel().selectionChanged.connect(
         self.on_selection_change)
     self.ui.groupListView.setCurrentIndex(self._model.item(0).index())
     self.ui.okButton.pressed.connect(self.accept)
     self.ui.cancelButton.pressed.connect(self.cancel)
     self.ui.resetButton.pressed.connect(self.cfg_reset)
예제 #3
0
class PreferencesDialog(QtWidgets.QDialog):
    def __init__(self, parent, cmdp):
        QtWidgets.QDialog.__init__(self, parent)
        self._active_group = None
        self._active_profile = cmdp.preferences.profile
        self._params = []
        self._cmdp = cmdp
        self.ui = Ui_PreferencesDialog()
        self.ui.setupUi(self)

        self._definitions = self._cmdp.preferences.definitions
        if self._definitions['name'] != '/':
            raise ValueError('unexpected root')
        self._definitions_tree_map = {}

        self._tree_model = QtGui.QStandardItemModel(self)
        self._tree_model.setHorizontalHeaderLabels(['Name'])
        self.ui.treeView.setModel(self._tree_model)
        self.ui.treeView.setHeaderHidden(True)
        self.ui.treeView.selectionModel().currentChanged.connect(
            self._on_tree_item_changed)
        self._tree_populate(self._tree_model.invisibleRootItem(),
                            self._definitions)

        select_mode_index = self._tree_model.index(0, 0)
        self.ui.treeView.setCurrentIndex(select_mode_index)
        self.ui.treeView.expandAll()
        self._on_tree_item_changed(select_mode_index, None)
        self.ui.profileComboBox.currentIndexChanged.connect(
            self._on_profile_combo_box_change)
        self._profile_combobox_update()

        self.ui.profileActivateButton.pressed.connect(
            self._on_profile_activate_button)
        self.ui.profileResetButton.pressed.connect(
            self._on_profile_reset_button)
        self.ui.profileNewButton.pressed.connect(self._on_profile_new_button)

        self.ui.okButton.pressed.connect(self.accept)
        self.ui.cancelButton.pressed.connect(self.reject)
        self.ui.resetButton.pressed.connect(self.preferences_reset)

        self._cmdp.subscribe('!preferences/profile/add', self._on_profile_add)
        self._cmdp.subscribe('!preferences/profile/remove',
                             self._on_profile_remove)

    def _on_profile_combo_box_change(self, index):
        profile = self.ui.profileComboBox.currentText()
        self._profile_change(profile)

    def _on_profile_add(self, topic, data):
        log.info('_on_profile_add(%s)  %s', data, self._active_profile)
        self._profile_change(data)

    def _on_profile_remove(self, topic, data):
        log.info('_on_profile_remove(%s) : %s', data, self._active_profile)
        if data == self._active_profile:
            self._profile_change()

    def _profile_change(self, profile=None):
        if profile is None:
            profile = self._cmdp.preferences.profile
        if profile == self._active_profile:
            return
        if profile != self._active_profile:
            self._active_profile = profile
            self._profile_combobox_update()
            self._on_tree_item_changed(self.ui.treeView.currentIndex(), None)

    def _on_profile_activate_button(self):
        self._cmdp.invoke('!preferences/profile/set', self._active_profile)
        self.ui.profileActivateButton.setEnabled(False)

    def _on_profile_reset_button(self):
        if self._active_profile in preferences_defaults.PROFILES_RESET:
            preferences_defaults.restore(self._cmdp.preferences,
                                         self._active_profile)
        else:
            self._cmdp.invoke('!preferences/profile/remove',
                              self._active_profile)

    def _on_profile_new_button(self):
        profile, success = QtWidgets.QInputDialog.getText(
            self, 'Enter profile name', 'Profile Name:')
        if not success:
            return
        if profile in self._cmdp.preferences.profiles:
            log.warning('Already exists - switch to it')
            self._cmdp.invoke('!preferences/profile/set', profile)
        else:
            self._cmdp.invoke('!preferences/profile/add', profile)

    def _profile_combobox_update(self):
        if self._active_profile not in self._cmdp.preferences.profiles:
            self._active_profile = self._cmdp.preferences.profile
        comboBoxConfig(self.ui.profileComboBox,
                       self._cmdp.preferences.profiles, self._active_profile)
        reset_text = 'Reset' if self._active_profile in preferences_defaults.PROFILES_RESET else 'Erase'
        self.ui.profileResetButton.setText(reset_text)
        self.ui.profileActivateButton.setEnabled(
            self._active_profile != self._cmdp.preferences.profile)

    def _tree_populate(self, parent, d):
        if 'children' not in d:
            return

        for name, child in d['children'].items():
            definition_name = child['name']
            if '#' in name or name.startswith(
                    '_') or not child['name'].endswith('/'):
                continue
            child_children = [
                x for x in child.get('children', {}).keys()
                if '#' not in x and not x.startswith('_')
            ]
            if not len(child_children):
                continue
            child_item = QtGui.QStandardItem(name)

            # WARNING: setData with dict causes key reordering.  Store str and lookup.
            self._definitions_tree_map[definition_name] = child
            child_item.setData(definition_name, QtCore.Qt.UserRole + 1)

            parent.appendRow(child_item)
            self._tree_populate(child_item, child)

    def _clear(self):
        if self._active_group is not None:
            for param in self._params:
                param.unpopulate(self.ui.targetWidget)
            self._params = []
        self._active_group = None

    @QtCore.Slot(object, object)
    def _on_tree_item_changed(self, model_index, model_index_old):
        self._clear()
        definition_name = self._tree_model.data(model_index,
                                                QtCore.Qt.UserRole + 1)
        data = self._definitions_tree_map[definition_name]
        self._populate_selected(data)

    def _populate_selected(self, data):
        if 'children' not in data:
            return
        self._active_group = data['name']
        for name, child in data['children'].items():
            if 'children' in child:
                continue
            if '#' in name or name.startswith('_') or child['name'].endswith(
                    '/'):
                continue
            self._populate_entry(name, child)

    def _populate_entry(self, name, entry):
        p = widget_factory(self._cmdp,
                           entry['name'],
                           profile=self._active_profile)
        if p is not None:
            p.populate(self.ui.targetWidget)
            self._params.append(p)

    def on_selection_change(self, selection):
        log.info('on_selection_change(%r)', selection)
        model_index_list = selection.indexes()
        if len(model_index_list) != 1:
            # force the first item
            self.ui.groupListView.setCurrentIndex(self._model.item(0).index())
            return
        self._clear()
        name = model_index_list[0].data()
        self._populate(name)

    def preferences_reset(self):
        active_group = self._active_group
        self._clear()
        self._populate(active_group)

    def exec_(self):
        self._cmdp.invoke('!command_group/start')
        rv = QtWidgets.QDialog.exec_(self)
        self._cmdp.invoke('!command_group/end')
        if rv == 0:
            self._cmdp.invoke('!undo')
예제 #4
0
class PreferencesDialog(QtWidgets.QDialog):

    def __init__(self, parent, cmdp):
        QtWidgets.QDialog.__init__(self, parent)
        self._active_group = None
        self._active_profile = cmdp.preferences.profile
        self._params = []
        self._cmdp = cmdp
        self.ui = Ui_PreferencesDialog()
        self.ui.setupUi(self)

        self._definitions = self._cmdp.preferences.definitions
        if self._definitions['name'] != '/':
            raise ValueError('unexpected root')
        self._definitions_tree_map = {}

        self._tree_model = QtGui.QStandardItemModel(self)
        self._tree_model.setHorizontalHeaderLabels(['Name'])
        self.ui.treeView.setModel(self._tree_model)
        self.ui.treeView.setHeaderHidden(True)
        self.ui.treeView.selectionModel().currentChanged.connect(self._on_tree_item_changed)
        self._tree_populate(self._tree_model.invisibleRootItem(), self._definitions)

        select_mode_index = self._tree_model.index(0, 0)
        self.ui.treeView.setCurrentIndex(select_mode_index)
        self.ui.treeView.expandAll()
        self._on_tree_item_changed(select_mode_index, None)
        self.ui.profileComboBox.currentIndexChanged.connect(self._on_profile_combo_box_change)
        self._profile_combobox_update()

        self.ui.profileActivateButton.pressed.connect(self._on_profile_activate_button)
        self.ui.profileResetButton.pressed.connect(self._on_profile_reset_button)
        self.ui.profileNewButton.pressed.connect(self._on_profile_new_button)
        self.ui.helpButton.pressed.connect(self._help)

        self.ui.okButton.pressed.connect(self.accept)
        self.ui.cancelButton.pressed.connect(self.reject)
        self.ui.resetButton.pressed.connect(self.preferences_reset)

        self._cmdp.subscribe('!preferences/profile/add', self._on_profile_add)
        self._cmdp.subscribe('!preferences/profile/remove', self._on_profile_remove)

        self._refresh_topic = f'!preferences/_ui/refresh_{id(self)}'
        self._cmdp.register(self._refresh_topic, self._refresh)

    def _help(self):
        display_help(self, 'preferences')

    def _refresh(self, topic, value):
        self._redraw_right_pane()

    def _on_profile_combo_box_change(self, index):
        profile = self.ui.profileComboBox.currentText()
        self._profile_change(profile)

    def _on_profile_add(self, topic, data):
        log.info('_on_profile_add(%s)  %s', data, self._active_profile)
        self._profile_change(data)

    def _on_profile_remove(self, topic, data):
        log.info('_on_profile_remove(%s) : %s', data, self._active_profile)
        if data == self._active_profile:
            self._profile_change()

    def _profile_change(self, profile=None):
        if profile is None:
            profile = self._cmdp.preferences.profile
        if profile == self._active_profile:
            return
        if profile != self._active_profile:
            self._active_profile = profile
            self._profile_combobox_update()
        self._redraw_right_pane()

    def _on_profile_activate_button(self):
        self._cmdp.invoke('!preferences/profile/set', self._active_profile)
        self.ui.profileActivateButton.setEnabled(False)

    def _on_profile_reset_button(self):
        self._profile_reset()

    def _profile_reset(self, prefix=''):
        log.info('profile_reset start %s : %s', self._active_profile, prefix)
        existing = self._cmdp.preferences.state_export()['profiles'][self._active_profile]
        if self._active_profile in preferences_defaults.PROFILES_RESET:
            default_profile = preferences_defaults.Preferences(app='joulescope_config')
            preferences_defaults.defaults(default_profile)
            defaults = default_profile.state_export()['profiles'][self._active_profile]
        else:
            defaults = {}
        for key, new_value in defaults.items():
            if key.startswith(prefix):
                existing.pop(key, None)  # remove if possible
                self._cmdp.invoke('!preferences/preference/set', (key, new_value, self._active_profile))
        for key, old_value in existing.items():
            if '#' in key or key[-1] == '/' or '/_' in key:
                continue
            if key.startswith(prefix):
                self._cmdp.invoke('!preferences/preference/clear', (key, self._active_profile))
        # special case state preferences
        if prefix == '' or prefix == 'General':
            self._cmdp.invoke('!preferences/preference/set', ('_window', None, self._active_profile))
        self._cmdp.invoke(self._refresh_topic, None)
        log.info('profile_reset done %s : %s', self._active_profile, prefix)

    def _on_profile_new_button(self):
        profile, success = QtWidgets.QInputDialog.getText(self, 'Enter profile name', 'Profile Name:')
        if not success:
            return
        if profile in self._cmdp.preferences.profiles:
            log.warning('Already exists - switch to it')
            self._cmdp.invoke('!preferences/profile/set', profile)
        else:
            self._cmdp.invoke('!preferences/profile/add', profile)
        self._redraw_right_pane()

    def _profile_combobox_update(self):
        if self._active_profile not in self._cmdp.preferences.profiles:
            self._active_profile = self._cmdp.preferences.profile
        comboBoxConfig(self.ui.profileComboBox, self._cmdp.preferences.profiles, self._active_profile)
        reset_text = 'Reset' if self._active_profile in preferences_defaults.PROFILES_RESET else 'Erase'
        self.ui.profileResetButton.setText(reset_text)
        self.ui.profileActivateButton.setEnabled(self._active_profile != self._cmdp.preferences.profile)

    def _tree_populate(self, parent, d):
        if 'children' not in d:
            return

        for name, child in d['children'].items():
            definition_name = child['name']
            if '#' in name or name.startswith('_') or not child['name'].endswith('/'):
                continue
            child_children = [x for x in child.get('children', {}).keys() if '#' not in x and not x.startswith('_')]
            if not len(child_children):
                continue
            child_item = QtGui.QStandardItem(name)

            # WARNING: setData with dict causes key reordering.  Store str and lookup.
            self._definitions_tree_map[definition_name] = child
            child_item.setData(definition_name, QtCore.Qt.UserRole + 1)

            parent.appendRow(child_item)
            self._tree_populate(child_item, child)

    def _clear(self):
        if self._active_group is not None:
            for param in self._params:
                param.unpopulate(self.ui.targetWidget)
            self._params = []
        self._active_group = None

    @QtCore.Slot(object, object)
    def _on_tree_item_changed(self, model_index, model_index_old):
        self._clear()
        definition_name = self._tree_model.data(model_index, QtCore.Qt.UserRole + 1)
        data = self._definitions_tree_map[definition_name]
        self._populate_selected(data)

    def _populate_selected(self, data):
        if 'children' not in data:
            return
        self._active_group = data['name']
        for name, child in data['children'].items():
            if 'children' in child:
                continue
            if '#' in name or name.startswith('_') or child['name'].endswith('/'):
                continue
            self._populate_entry(name, child)

    def _populate_entry(self, name, entry):
        p = widget_factory(self._cmdp, entry['name'], profile=self._active_profile)
        if p is not None:
            p.populate(self.ui.targetWidget)
            self._params.append(p)

    def preferences_reset(self):
        self._profile_reset(self._active_group)

    def exec_(self):
        self._cmdp.invoke('!command_group/start')
        rv = QtWidgets.QDialog.exec_(self)
        self._cmdp.invoke('!command_group/end')
        self._clear()
        if rv == 0:
            self._cmdp.invoke('!undo')
        return rv

    def _redraw_right_pane(self):
        self._clear()
        self._on_tree_item_changed(self.ui.treeView.currentIndex(), None)
예제 #5
0
class PreferencesDialog(QtWidgets.QDialog):
    def __init__(self, cfg_def, cfg):
        QtWidgets.QDialog.__init__(self)
        self._active_group = None
        self._params = []
        self._cfg_def = cfg_def
        self.cfg_orig = cfg
        self._cfg = copy.deepcopy(cfg)
        self.ui = Ui_PreferencesDialog()
        self.ui.setupUi(self)
        self._model = QtGui.QStandardItemModel()
        for entry in self._cfg_def['children']:
            item = QtGui.QStandardItem(entry['name'])
            self._model.appendRow(item)
        self.ui.groupListView.setModel(self._model)
        self.ui.groupListView.selectionModel().selectionChanged.connect(
            self.on_selection_change)
        self.ui.groupListView.setCurrentIndex(self._model.item(0).index())
        self.ui.okButton.pressed.connect(self.accept)
        self.ui.cancelButton.pressed.connect(self.cancel)
        self.ui.resetButton.pressed.connect(self.cfg_reset)

    def update(self):
        if self._active_group is None:
            return
        for param in self._params:
            self._cfg[self._active_group][param.name] = param.value

    def _clear(self):
        if self._active_group is not None:
            for param in self._params:
                param.unpopulate(self.ui.targetWidget)
            self._params = []
        self._active_group = None

    def _populate(self, group_name: str):
        group = find_child_by_name(self._cfg_def, group_name)
        if group is None:
            return
        self._active_group = group_name

        for entry in group['children']:
            name = entry['name']
            value = self._cfg[self._active_group][name]
            p = None
            tooltip = ''
            if 'brief' in entry:
                tooltip = '<span><p>%s</p>' % entry['brief']
                if 'detail' in entry:
                    tooltip += '<p>%s</p>' % entry['detail']
                tooltip += '</span>'
            if entry['type'] == 'str' and 'options' in entry:
                options = [x['name'] for x in entry['options']]
                p = guiparams.Enum(name, value, options, tooltip=tooltip)
            elif entry['type'] == 'bool':
                if isinstance(value, str):
                    value = value.lower()
                value = value in [True, 'true', 'on']
                p = guiparams.Bool(name, value, tooltip=tooltip)
            elif entry['type'] == 'path':
                attributes = entry.get('attributes', [])
                if 'dir' in attributes:
                    p = guiparams.Directory(name, value, tooltip=tooltip)
                elif 'exists' in attributes:
                    p = guiparams.FileOpen(name, value, tooltip=tooltip)
                else:
                    p = guiparams.FileSave(name, value, tooltip=tooltip)
            if p is not None:
                p.populate(self.ui.targetWidget)
                self._params.append(p)

    def on_selection_change(self, selection):
        log.info('on_selection_change(%r)', selection)
        model_index_list = selection.indexes()
        if len(model_index_list) != 1:
            # force the first item
            self.ui.groupListView.setCurrentIndex(self._model.item(0).index())
            return

        self.update()
        self._clear()

        name = model_index_list[0].data()
        self._populate(name)

    def cancel(self):
        self.update()
        if self.cfg_orig == self._cfg:
            QtWidgets.QDialog.reject(self)
        elif confirmDiscard(self):
            QtWidgets.QDialog.reject(self)

    def cfg_reset(self):
        active_group = self._active_group
        self._clear()
        self._cfg = validate(self._cfg_def, {})
        self._populate(active_group)

    def exec_(self):
        if QtWidgets.QDialog.exec_(self) == 1:
            self.update()
            return self._cfg  # accepted!
        return None