Exemplo n.º 1
0
    def add_option_handler(self):
        selection = self.view.selectionModel().selectedRows()
        if len(selection) == 0 or len(selection) > 1:
            logging.debug(
                "zero or multiple selections while trying to add new value")
            self.statusbar.showMessage(
                "Please select one option to add new value")
            return

        selected_index = get_root_index(selection[0])
        option = selected_index.data()
        parent = QtCore.QModelIndex()
        for r in range(self.json_model.rowCount(parent)):
            index = self.json_model.index(r, 0, parent)
            item = self.json_model.itemFromIndex(index)
            if index.data() == option:
                if option in mss_default.fixed_dict_options + mss_default.key_value_options:
                    # Cannot add options to fixed structure options
                    self.statusbar.showMessage(
                        "Option already exists. Please change value to your preference or restore to default."
                    )
                    return
                elif option in mss_default.dict_option_structure:
                    # Append dummy value dict to options having a dictionary structure
                    json_data = mss_default.dict_option_structure[option]
                    type_ = match_type(json_data)
                    type_.next(model=self.json_model,
                               data=json_data,
                               parent=item)
                elif option in mss_default.list_option_structure:
                    # Append dummy value to options having a list structure
                    json_data = mss_default.list_option_structure[option]
                    type_ = match_type(json_data)
                    type_.next(model=self.json_model,
                               data=json_data,
                               parent=item)
                    # increase row count in view
                    rows = self.json_model.rowCount(index) - 1
                    new_item = self.json_model.itemFromIndex(
                        self.json_model.index(rows, 0, index))
                    new_item.setData(rows, QtCore.Qt.DisplayRole)
                self.statusbar.showMessage("")
                # expand root item
                proxy_index = self.proxy_model.mapFromSource(index)
                self.view.expand(proxy_index)
                # expand, scroll to and select new item
                rows = self.json_model.rowCount(index) - 1
                new_index = self.json_model.index(rows, 0, index)
                proxy_index = self.proxy_model.mapFromSource(new_index)
                self.view.expand(proxy_index)
                self.view.scrollTo(proxy_index)
                self.view.selectionModel().select(
                    proxy_index, QtCore.QItemSelectionModel.ClearAndSelect
                    | QtCore.QItemSelectionModel.Rows)
                logging.debug(f"Added new value for {option}")
                self.update_view()
                break
Exemplo n.º 2
0
def compare_data(default, user_data):
    """
    Recursively compares two dictionaries based on qt_json_view datatypes
    and returns default or user_data appropriately.

    Arguments:
    default -- Dict to return if datatype not matching
    user_data -- Dict to return if datatype is matching
    """
    # If data is neither list not dict type, compare individual type
    if not isinstance(default, dict) and not isinstance(default, list):
        if isinstance(default, float) and isinstance(user_data, int):
            user_data = float(default)
        if isinstance(match_type(default), UrlType) and isinstance(
                match_type(user_data), StrType):
            return user_data, True
        if isinstance(match_type(default), type(match_type(user_data))):
            return user_data, True
        else:
            return default, False

    data = copy.deepcopy(default)
    matches = []
    # If data is list type, compare all values in list
    if isinstance(default, list) and isinstance(user_data, list):
        if len(default) == len(user_data):
            for i in range(len(default)):
                data[i], match = compare_data(default[i], user_data[i])
                matches.append(match)
        else:
            return default, False

    # If data is dict type, goes through the dict and update
    elif isinstance(default, dict) and isinstance(user_data, dict):
        if default.keys() == user_data.keys():
            for key in default:
                if key in user_data:
                    data[key], match = compare_data(default[key],
                                                    user_data[key])
                    matches.append(match)
                else:
                    matches.append(False)
        else:
            return default, False

    return data, all(matches)
Exemplo n.º 3
0
 def init(self, data, editable_keys=False, editable_values=False):
     """Convert the data to items and populate the model."""
     self.clear()
     self.setHorizontalHeaderLabels(['Key', 'Value'])
     self.editable_keys = editable_keys
     self.editable_values = editable_values
     parent = self.invisibleRootItem()
     type_ = match_type(data)
     parent.setData(type_, TypeRole)
     type_.next(model=self, data=data, parent=parent)
Exemplo n.º 4
0
    def restore_defaults(self):
        def update(data, option, value):
            """Function to update dict at a depth"""
            for k, v in data.items():
                if k == option:
                    data[k] = value
                    break
                if isinstance(v, collections.abc.Mapping):
                    data[k] = update(data.get(k, {}), option, value)
            return data

        selection = self.view.selectionModel().selectedRows()
        if len(selection) == 0:
            logging.debug("no selections while trying to restore defaults")
            self.statusbar.showMessage(
                "Please select one/more options to restore defaults")
            return

        # get list of distinct indexes to restore
        model_data = self.json_model.serialize()
        selected_indexes = set()
        for index in selection:
            root_index, parent_list = get_root_index(index, parents=True)
            added = False
            data = model_data
            for parent in parent_list + [index]:
                data = data[parent.data()]
                if isinstance(data, list):
                    added = True
                    selected_indexes.add(parent)
                    break
            if not added:
                selected_indexes.add(index)

        # ToDo add confirmation dialog here

        options = "\n".join([index.data() for index in selected_indexes])
        logging.debug(
            f"Attempting to restore defaults for the following options\n{options}"
        )

        for index in selected_indexes:
            # check if root option and present in mss_default.key_value_options
            if not index.parent().isValid() and index.data(
            ) in mss_default.key_value_options:
                value_index = self.json_model.index(index.row(), 1,
                                                    QtCore.QModelIndex())
                value_item = self.json_model.itemFromIndex(value_index)
                value_item.setData(default_options[index.data()],
                                   QtCore.Qt.DisplayRole)
                continue

            root_index, parent_list = get_root_index(index, parents=True)
            option = root_index.data()
            model_data = self.json_model.serialize()
            if option in mss_default.fixed_dict_options:
                if index == root_index:
                    json_data = default_options[option]
                else:
                    key = None
                    value = copy.deepcopy(default_options)
                    for parent in parent_list + [index]:
                        parent_data = parent.data()
                        if isinstance(value, list):
                            break
                        key = parent_data
                        value = value[parent_data]
                    data = copy.deepcopy(model_data[option])
                    json_data = update(data, key, value)
            else:
                json_data = default_options[option]
            if model_data[option] == json_data:
                continue
            # remove all rows
            for row in range(self.proxy_model.rowCount(root_index)):
                self.proxy_model.removeRow(0, parent=root_index)
            # add default values
            source_index = self.proxy_model.mapToSource(root_index)
            source_item = self.json_model.itemFromIndex(source_index)
            type_ = match_type(json_data)
            type_.next(model=self.json_model,
                       data=json_data,
                       parent=source_item)

        self.statusbar.showMessage("Defaults restored for selected options")
        self.view.clearSelection()
        self.update_view()