Пример #1
0
    def update(self, structure):
        for n, v in structure.items():
            items = self.findItems(n, Qt.MatchExactly)
            if len(items) == 0:
                item = QTreeWidgetItem([n, '{} points'.format(v['nValues'])])
                for m, w in v['axes'].items():
                    childItem = QTreeWidgetItem(
                        [m, '{} points'.format(w['nValues'])])
                    childItem.setDisabled(True)
                    item.addChild(childItem)

                self.addTopLevelItem(item)
                item.setExpanded(True)

            else:
                item = items[0]
                item.setText(1, '{} points'.format(v['nValues']))
                for m, w in v['axes'].items():
                    for k in range(item.childCount()):
                        if item.child(k).text(0) == m:
                            item.child(k).setText(
                                1, '{} points'.format(w['nValues']))

        curSelection = self.selectedItems()
        if len(curSelection) == 0:
            item = self.topLevelItem(0)
            if item:
                item.setSelected(True)
Пример #2
0
    def on_tree_item_expanded(self, item: QTreeWidgetItem):
        """
        展开时从父LE中载入数据
        :param item:
        :return:
        """
        logging.info("on_tree_item_expanded")
        try:
            if item.text(0) == "File Version":
                logging.info("File Version->expanded")
                for index in range(item.childCount()):
                    child = item.child(index)
                    v = self.file_version_le.text()
                    le: QLineEdit = self.tree.itemWidget(child, 1)
                    le.setText(str(eval(v)[index]))

            elif item.text(0) == "Product Version":
                logging.info("Product Version->expanded")
                for index in range(item.childCount()):
                    child = item.child(index)
                    v = self.product_version_le.text()
                    le: QLineEdit = self.tree.itemWidget(child, 1)
                    le.setText(str(eval(v)[index]))
            else:
                logging.info("not concern item->expanded")
        except Exception as e:
            logging.error(e)
Пример #3
0
    def __init__(self, model, view):

        self.model = model
        self.view = view

        tw = view.tw

        tw.setHeaderLabels(['MyTest'])

        tctx = QTreeWidgetItem(["CTX"])
        tvdx = QTreeWidgetItem(["ROIs"])
        tdos = QTreeWidgetItem(["DOSs"])
        tlet = QTreeWidgetItem(["LETs"])

        tctx.setCheckState(0, Qt.Checked)

        # tctx.addChild(QTreeWidgetItem([model.ctx]))

        for i, item in enumerate(model.vdx):
            # child = QTreeWidgetItem(parent)
            tvdx.addChild(QTreeWidgetItem([item]))
            child = tvdx.child(i)
            child.setCheckState(0, Qt.Checked)

        for i, item in enumerate(model.dos):
            tdos.addChild(QTreeWidgetItem([item]))
            child = tdos.child(i)
            child.setCheckState(0, Qt.Checked)

        for item in model.let:
            tlet.addChild(QTreeWidgetItem([item]))

        tw.addTopLevelItem(tctx)
        tw.addTopLevelItem(tvdx)
        tw.addTopLevelItem(tdos)
        tw.addTopLevelItem(tlet)

        tctx.setExpanded(
            True)  # should be set, after it was added to the TreeWidget
        tvdx.setExpanded(True)
        tdos.setExpanded(True)
        tlet.setExpanded(True)

        self.setup_callbacks(view)

        self.tvdx = tvdx
        self.popup_menu_ctx = self.create_popup_menu_ctx()
        self.popup_menu_vdx = self.create_popup_menu_vdx()
Пример #4
0
 def getSubItemFromSubTask(self, item: QTreeWidgetItem,
                           sub_task: PlotSubTask):
     for i in range(item.childCount()):
         sub_item = item.child(i)
         if sub_item.data(0, Qt.UserRole) == sub_task:
             return sub_item
     return None
Пример #5
0
    def on_point_toggle(self, item: QtWidgets.QTreeWidgetItem,
                        column: int) -> None:
        """ Callback for toggling point selection

        Adds/removes points to background removal queue

        Args:
            item (QtWidgets.QTreeWidgetItme):
                toggled widget item
            column (int):
                mandatory unused argument in signal
        """
        if item.childCount() == 0:
            # a bit inefficient here (e.g dynamic programming could help)
            treepath = ''
            node = item
            while node is not None:
                treepath = '/' + node.text(0) + treepath
                node = node.parent()
            # remove prepended '/'
            treepath = treepath[1:]

            index = self.pointPlotSelect.findText(treepath)
            if index < 0 and item.checkState(0):
                self.pointPlotSelect.addItem(treepath)
            elif index >= 0 and not item.checkState(0):
                self.pointPlotSelect.removeItem(index)

        else:
            for child in [
                    item.child(index) for index in range(item.childCount())
            ]:
                child.setCheckState(0, item.checkState(0))
Пример #6
0
    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and \
                    not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()
Пример #7
0
 def get_timestamp_from_child(self, child: QTreeWidgetItem):
     """ Returns the timestamp of a given tree widget item
         to identify specific items.
         Args:
             child: The item from which to get the timestamp
     """
     return child.child(1).text(1)
Пример #8
0
    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()
Пример #9
0
    def del_option(self, parent: QTreeWidgetItem, child: QTreeWidgetItem):

        self.blockSignals(True)
        parent.removeChild(child)

        selected_option = False
        for i in range(parent.childCount()):
            parent.child(i).setData(0, 35, i)
            if parent.child(i).checkState(0) == Qt.Checked:
                selected_option = True

        if parent.childCount() > 0 and not selected_option:
            parent.child(0).setCheckState(0, Qt.Checked)

        self.blockSignals(False)
        self.itemRemoved.emit(parent, parent.indexOfChild(child))
        self.update_size()
Пример #10
0
 def set_gray(self, item: QtWidgets.QTreeWidgetItem):
     """  将item置为灰色,不用 setDisabled 的原因是会导致 currentItem() 失效 """
     item.setForeground(0, QtCore.Qt.gray)
     data = item.data(0, QtCore.Qt.UserRole)
     if data is not None:
         item.setIcon(0, QtGui.QIcon(':/icon/not_connect_16.png'))
     for i in range(item.childCount()):
         self.set_gray(item.child(i))
Пример #11
0
 def getTreeWidgetItemJsonData(treeWidgetItem: QTreeWidgetItem):
     """
     从TreeWidgetItem解析出json数据
     :param treeWidgetItem: treeWidgetItem
     :return: json数据
     """
     text = treeWidgetItem.text(0)
     if text == "[]":
         jsonData = []
         for i in range(0, treeWidgetItem.childCount()):
             res = WidgetUtil.getTreeWidgetItemJsonData(
                 treeWidgetItem.child(i))
             jsonData.append(res)
         print(jsonData)
         return jsonData
     elif text == "{}":
         jsonData = {}
         for i in range(0, treeWidgetItem.childCount()):
             child = treeWidgetItem.child(i)
             res = WidgetUtil.getTreeWidgetItemJsonData(child)
             print("root key: " + child.text(0) + " value: " + str(res))
             jsonData = {**jsonData, **res}
         print(jsonData)
         return jsonData
     elif treeWidgetItem.data(0, Qt.UserRole):
         # 末端节点
         dataType = treeWidgetItem.data(1, Qt.UserRole)
         print(DataTypeUtil.parseByType(text, dataType))
         res = DataTypeUtil.parseByType(text, dataType)
         print("末端节点 -> %s dataType -> %d parse res -> %s" %
               (text, dataType, str(res)))
         return res
     else:
         jsonData = {}
         list = []
         for i in range(0, treeWidgetItem.childCount()):
             child = treeWidgetItem.child(i)
             res = WidgetUtil.getTreeWidgetItemJsonData(child)
             list.append(res)
         if len(list) == 1:
             jsonData[text] = list[0]
         else:
             jsonData[text] = list
         print(jsonData)
         return jsonData
Пример #12
0
 def recurse(parent_item: QTreeWidgetItem):
     for i in range(parent_item.childCount()):
         child = parent_item.child(i)
         grand_children = child.childCount()
         if grand_children > 0:
             recurse(child)
         else:
             if child.checkState(0) == Qt.Checked:
                 checked_items.append(child)
Пример #13
0
    def populate(self):
        model = self.model
        settings = model.settings
        item_store: ItemStore = settings[settings.P_ITEM_STORE]
        self.tree.clear()

        imgs.sig_image_load.connect(self.image_loaded)

        for k, v in item_store.store_items.items():
            prices = v.prices
            if prices is not None:
                tli = QTreeWidgetItem(
                    self.tree, [k, v.name, '', str(v.expires)])
                self.tree.addTopLevelItem(tli)
                ret = self.load_gear_icon(k, tli)
                tli.setText(2, MONNIES_FORMAT.format(prices[0]))
                for i, p in enumerate(v.prices[1:]):
                    twi = QTreeWidgetItem(
                        ['', v.name, MONNIES_FORMAT.format(p), ''])
                    tli.addChild(twi)
                lV = 0
                if ret is not None:
                    name, grade, itype = ret
                    res_class_str = class_enum_to_str(itype)
                    res_grade_str = grade_enum_to_str(grade)
                    gt_str = class_grade_to_gt_str(res_class_str,
                                                   res_grade_str, name)
                    gear_type = gear_types[gt_str]
                    for idx, lvl in gear_type.idx_lvl_map.items():
                        if idx > lV:
                            lV = idx
                        lvl_e_t = gear_type.bin_mp(idx)
                        child = tli.child(lvl_e_t - 1)
                        if child is not None:
                            lvl = gear_type.idx_lvl_map[idx - 1]
                            prev_text = child.text(0)
                            if prev_text.strip() == '':
                                text = str(lvl)
                            else:
                                text = '{}, {}'.format(prev_text, lvl)
                            child.setText(0, text)
                    child = tli.child(tli.childCount() - 1)
                    child.setText(0, gear_type.idx_lvl_map[lV])
Пример #14
0
 def treelist_creatgrpitem(self, item_group):
     """Create group item."""
     treelist = self.maintabwidget.tab_classify.treelist
     # Creat TopLevel Group
     tree_group = treelist.findItems(item_group[0], Qt.MatchFixedString, 0)
     if tree_group:
         group = tree_group[0]
     else:
         group = QTreeWidgetItem(treelist)
         group.setText(0, item_group[0])
     # Creat SubGroup
     subgroup = None
     childcount = group.childCount()
     for i in range(childcount):
         if item_group[1] == group.child(i).text(0):
             subgroup = group.child(i)
             break
     if not subgroup:
         subgroup = QTreeWidgetItem(group)
         subgroup.setText(0, item_group[1])
     return subgroup
Пример #15
0
 def tree_elem_generator(tree_elem: ElementTree.Element,
                         tree_item: QTreeWidgetItem):
     for i in range(tree_item.childCount()):
         child_item = tree_item.child(i)
         attrib = dict()
         for i in range(1, self.columnNum):
             if child_item.text(i):
                 attrib[self.header_labels_list[i]] = child_item.text(i)
         child_elem = ElementTree.SubElement(tree_elem,
                                             child_item.text(0),
                                             attrib=attrib)
         tree_elem_generator(child_elem, child_item)
Пример #16
0
    def del_option(self, parent: QTreeWidgetItem, child: QTreeWidgetItem):
        """ Called to remove option from parent. """
        self.blockSignals(True)

        parent.removeChild(child)
        selected_option = False
        for i in range(parent.childCount()):
            parent.child(i).setData(0, INDEX_SLOT, i)
            if parent.child(i).checkState(0) == Qt.Checked:
                selected_option = True

        if parent.childCount() > 0 and not selected_option:
            parent.child(0).setCheckState(0, Qt.Checked)

        # Deselects if no options left
        if not parent.childCount():
            parent.setCheckState(0, Qt.Unchecked)

        self.blockSignals(False)

        self.update_size()
Пример #17
0
    def _select_children(self, top_item: QtWidgets.QTreeWidgetItem,
                         value: bool):
        """Recursive select children from parent."""
        pi.logger.debug("RevPiFiles._select_children")

        for i in range(top_item.childCount()):
            item = top_item.child(i)
            if item.type() == NodeType.DIR:
                item.setSelected(value)
                self._select_children(item, value)
            elif item.type() == NodeType.FILE:
                item.setSelected(value)
Пример #18
0
    def populate(self):
        model = self.model
        settings = model.settings
        item_store: ItemStore = settings[settings.P_ITEM_STORE]
        self.tree.clear()

        imgs.sig_image_load.connect(self.image_loaded)

        for k, v in item_store.store_items.items():
            prices = v.prices
            if prices is not None:
                tli = QTreeWidgetItem(
                    self.tree, [k, v.name, '', str(v.expires)])
                self.tree.addTopLevelItem(tli)
                gd = self.load_gear_icon(k, tli)
                tli.setText(2, MONNIES_FORMAT.format(prices[0]))
                for i, p in enumerate(v.prices[1:]):
                    twi = QTreeWidgetItem(
                        ['', v.name, MONNIES_FORMAT.format(p), ''])
                    tli.addChild(twi)
                if gd is not None:  # If ret is none this is a gear item not a material
                    gear_type = gd.get_gear_type()
                    for idx, lvl in gear_type.idx_lvl_map.items():
                        if idx == 0:
                            continue
                        lvl_e_t = gear_type.bin_mp(idx)
                        child = tli.child(lvl_e_t - 1)
                        if child is not None:
                            lvl = gear_type.idx_lvl_map[
                                idx -
                                1]  # MP cost of PRI is, target DUO's cost
                            prev_text = child.text(0)
                            if prev_text.strip() == '':
                                text = str(lvl)
                            else:
                                text = '{}, {}'.format(prev_text, lvl)
                            child.setText(0, text)
                    child = tli.child(tli.childCount() - 1)
                    child.setText(
                        0, gear_type.idx_lvl_map[len(gear_type.map) - 1])
Пример #19
0
 def add(self):
     # gets selected item and makes a child
     parent = self.ui.treeWidget.currentItem()
     child = QTreeWidgetItem()
     # adds to tree, expands, makes the child editable, and adds a checkbox
     parent.addChild(child)
     parent.setExpanded(True)
     if child.child(0) is None:
         child.setFlags(child.flags()
                        | Qt.ItemIsUserCheckable
                        | Qt.ItemIsEditable
                        | Qt.ItemIsEnabled)
         child.setCheckState(0, Qt.Unchecked)
Пример #20
0
 def findSubItemByName(
         self, name: str,
         root: QtWidgets.QTreeWidgetItem) -> QtWidgets.QTreeWidgetItem:
     for i in range(root.childCount()):
         item: QtWidgets.QTreeWidgetItem = root.child(i)
         if item.type() == 0:
             rec = self.findSubItemByName(name, item)
             if rec is not None:
                 return rec
         else:
             if item.text(0) == name:
                 return item
     return None
Пример #21
0
 def update_index(master: QTreeWidgetItem) -> None:
     """
     更新子节点 索引信息
     :return:
     """
     # QTreeWidgetItem(self.group_tree).text(0)
     # 获取子节点个数
     count = master.childCount()
     # 根据索引获取子节点
     for index in range(count):
         child = master.child(index)
         # 在线主机 (0)
         child.setText(0, str(index + 1))
Пример #22
0
 def set_default(self, item: QtWidgets.QTreeWidgetItem):
     """ 将 item 恢复为默认颜色 """
     style = self.parent().ui_config.get('main_window',
                                         'style',
                                         fallback='normal_style')
     data = item.data(0, QtCore.Qt.UserRole)
     if data is not None:
         item.setIcon(0, self.icons[0])
     if style == "dark_style":
         item.setForeground(0, QtCore.Qt.white)
     else:
         item.setForeground(0, QtCore.Qt.black)
     for i in range(item.childCount()):
         self.set_default(item.child(i))
Пример #23
0
    def item_removed(self, item: QTreeWidgetItem, index):
        """
        Parent who had child removed. Updates settings and numbering of settings_data 35
        TODO: Apply named constant variables to data entries instead of numbers.
              Constants defined in parameter_tree.py
        """

        def get_index(data, option_name):
            try:
                return data[parameter_name]['options'].index(option_name)
            except KeyError:
                # TODO: Logging
                # print(f'Profile {profile} has no parameter {parameter_name}, skipping')
                return None
            except ValueError:
                # print(f'Profile {profile} does not have the option {option_name}, skipping')
                return None

        parameter_name = item.data(0, DISPLAY_NAME_SLOT)
        option_name = self.settings.parameters[parameter_name]['options'][index]

        has_option = []
        for profile, data in self.settings.profiles_data.items():
            new_index = get_index(data, option_name)

            if new_index is not None and data[parameter_name]['active option'] == new_index:
                has_option.append(profile)

        if has_option:
            self.alert_message('Error',
                               f'One or more profiles has this as the selected option:',
                               f'\t{", ".join(has_option)}')
            return

        item.treeWidget().del_option(item, item.child(index))

        self.settings.remove_parameter_option(item.data(0, DISPLAY_NAME_SLOT), index)

        # Deletes from profiles
        for profile, data in self.settings.profiles_data.items():
            new_index = get_index(data, option_name)
            if new_index is None:
                continue
            del data[parameter_name]['options'][new_index]
            new_index = data[parameter_name]['active option']
            new_index -= 1 if new_index > 0 else 0
            data[parameter_name]['active option'] = new_index

        self.file_handler.save_profiles(self.settings.profiles_data)
        self.file_handler.save_settings(self.settings.settings_data)
Пример #24
0
    def parameter_updater(self, item: QTreeWidgetItem, col=None, save=True):
        """Handles updating the options for a parameter."""
        if 'Custom' != self.tab1.profile_dropdown.currentText():
            self.tab1.profile_dropdown.addItem('Custom')
            self.tab1.profile_dropdown.setCurrentText('Custom')
            self.settings.user_options['current_profile'] = ''

        if item.data(0, LEVEL_SLOT) == 0:
            if item.data(0, DATA_SLOT) in self.settings.need_parameters:
                result = self.alert_message('Warning!', 'This parameter needs an option!', 'There are no options!\n'
                                                                                           'Would you make one?', True)
                if result == QMessageBox.Yes:
                    success = self.add_option(item)

                    if not success:
                        item.treeWidget().blockSignals(True)
                        item.setCheckState(0, Qt.Unchecked)
                        item.treeWidget().blockSignals(False)
                        item.treeWidget().check_dependency(item)
                else:
                    item.treeWidget().blockSignals(True)
                    item.setCheckState(0, Qt.Unchecked)
                    item.treeWidget().blockSignals(False)
                    item.treeWidget().check_dependency(item)

            if item.checkState(0) == Qt.Checked:
                self.settings[item.data(0, DATA_SLOT)]['state'] = True
                if item.data(0, DATA_SLOT) == 'Download location':
                    for i in range(item.childCount()):
                        self.parameter_updater(item.child(i), save=False)

            else:
                self.settings[item.data(0, DATA_SLOT)]['state'] = False
                if item.data(0, DATA_SLOT) == 'Download location':
                    self.tab2.download_lineedit.setText(path_shortener(self.local_dl_path))
                    self.tab2.download_lineedit.setToolTip(self.local_dl_path)

        elif item.data(0, LEVEL_SLOT) == 1:
            # Settings['Settings'][Name of setting]['active option']] = index of child
            self.settings[item.parent().data(0, DATA_SLOT)]['active option'] = item.data(0, INDEX_SLOT)
            if item.parent().data(0, DATA_SLOT) == 'Download location':
                if item.checkState(0) == Qt.Checked:
                    self.tab2.download_lineedit.setText(item.data(0, DISPLAY_NAME_SLOT))
                    self.tab2.download_lineedit.setToolTip(item.data(0, DATA_SLOT))

        if save:
            self.file_handler.save_settings(self.settings.settings_data)
Пример #25
0
    def recursive_tree_item(self, item: QTreeWidgetItem, depth=0):
        # Root 아이템 부터 돌면서 아이템 내용을 Dict 형태로 생성
        for child in [item.child(i) for i in range(item.childCount())]:
            columns = [child.data(i, Qt.DisplayRole) for i in
                       range(child.columnCount())]
            # 위젯 및 체크박스 사용 여부 검사
            buf = ''
            w = child.treeWidget().itemWidget(child, 1)
            check = (child.data(1, Qt.CheckStateRole))
            if w:
                buf = w.get_value()
            if check:
                buf = ["checked", "---", "unchecked"][child.checkState(check)]
            qDebug("{} {}".format("\t" * depth, str(columns) + ' ' + str(buf)))

            if child.childCount():
                self.recursive_tree_item(child, depth + 1)
Пример #26
0
 def set_choices(
     self, item: QTreeWidgetItem = None, choices: List[TriggerChoice] = None
 ):
     if not item:
         item = self.root
         choices = profile.trigger_choices
     for choice in choices:
         for i in range(item.childCount()):
             child = item.child(i)
             if isinstance(child, TriggerGroup):
                 if child.container.name == choice.name and choice.type_ == "group":
                     child.setCheckState(
                         0, Qt.Checked if choice.enabled else Qt.Unchecked
                     )
                     if choice.group:
                         self.set_choices(child, choice.group)
             else:
                 if child.trigger.name == choice.name and choice.type_ == "trigger":
                     child.setCheckState(
                         0, Qt.Checked if choice.enabled else Qt.Unchecked
                     )
Пример #27
0
 def get_choices(self, item: QTreeWidgetItem = None):
     choices = []
     if not item:
         item = self.root
     for i in range(item.childCount()):
         child = item.child(i)
         if isinstance(child, TriggerGroup):
             choices.append(
                 TriggerChoice(
                     name=child.container.name,
                     enabled=True if child.checkState(0) else False,
                     group=self.get_choices(child),
                 )
             )
         elif isinstance(child, TriggerItem):
             choices.append(
                 TriggerChoice(
                     name=child.trigger.name,
                     enabled=True if child.checkState(0) else False,
                     type_="trigger",
                 )
             )
     return choices
Пример #28
0
 def _filter_branch(self, search_terms: List[str],
                    parent: QtWidgets.QTreeWidgetItem) -> int:
     visible_children = 0
     for c in range(parent.childCount()):
         child = parent.child(c)
         item_type = child.data(0, self.ROLE_ITEM_TYPE)
         if item_type == self.ITEM_TYPE_TOOL:
             child_text = child.text(0).lower()
             child_help = child.toolTip(0).lower()
             visible_children += 1
             item_hidden = False
             for term in search_terms:
                 if term not in child_text and term not in child_help:
                     item_hidden = True
                     break
             child.setHidden(item_hidden)
             if item_hidden:
                 visible_children -= 1
         elif item_type == self.ITEM_TYPE_COLLECTION:
             visible_children += self._filter_branch(search_terms, child)
         else:
             raise NotImplementedError
     parent.setHidden(visible_children == 0)
     return visible_children
Пример #29
0
 def _set_check_state_to_tree(self, item: QTreeWidgetItem, check_state: Qt.CheckState):
     for i in range(item.childCount()):
         child = item.child(i)
         child.setCheckState(0, check_state)
         self._set_check_state_to_tree(child, check_state)
Пример #30
0
class TreeController(object):
    """
    Idea is that the tree is entirely controlled by modifying the main_model.
    After modification, update_tree() is called, which will populate accordingly.
    """

    def __init__(self, model, view, ctrl):
        """
        :param MyModel model:
        :param view:
        """
        self.model = model
        self.view = view
        self.pctrl = ctrl.plot  # this is only needed to trigger canvas update, if tree change.
        tw = view.treeWidget

        # QTreeWidgetItem placeholders, only the top level nodes.
        self.tctx = None
        self.tvdx = None
        self.tplans = None
        self.tdos = None
        self.tlet = None

        # These "articial" objects are made since they do not exist in pytrip.model
        self._doscol = DosCollection()
        self._letcol = LetCollection()
        self._plancol = PlanCollection()

        # setup the submenus:
        self.tmc = TreeMenuController(model, view, ctrl)  # self, else it goes out of scope?

        # connect checkbox change state to callback
        tw.itemClicked.connect(self.on_checked_changed)

    def on_checked_changed(self, pos):
        """
        If checkbox is changed in the TreeWidget, then then corresponding object is removed
        or added to the plot_model.
        """
        logger.debug("on_checked_changed() {}".format(pos))

        pm = self.model.plot
        obj = pos.data(0, Qt.UserRole)
        # state = pos.data(0, Qt.CheckStateRole)
        # tw = self.view.tw

        if pos.checkState(0) == Qt.Unchecked:
            if isinstance(obj, pt.CtxCube):
                logger.debug("set pm.ctx = None")
                pm.ctx = None

            if isinstance(obj, pt.Voi):
                logger.debug("remove Voi {}".format(obj.name))
                if obj in pm.vois:
                    pm.vois.remove(obj)
                else:
                    logger.warning("Tried to remove Voi {} which is not in pm.vois.")

            if isinstance(obj, pte.Plan):
                logger.debug("remove Plan {}".format(obj.name))
                if obj in pm.plans:
                    pm.plans.remove(obj)
                else:
                    logger.warning("Tried to remove Plan {} which is not in pm.plans.")

            # TODO: Field

            if isinstance(obj, pt.DosCube):
                logger.debug("set pm.dos = None")
                pm.dos = None

            if isinstance(obj, pt.LETCube):
                logger.debug("set pm.let = None")
                pm.let = None

        else:  # select something and add it to model.plot
            logger.debug("{} isChecked(True)".format(pos))
            if isinstance(obj, pt.CtxCube):
                pm.ctx = obj
            if isinstance(obj, pt.Voi):
                if obj not in pm.vois:
                    pm.vois.append(obj)
            if isinstance(obj, pt.DosCube):
                pm.dos = obj
            if isinstance(obj, pt.LETCube):
                pm.let = obj

        # trigger update plot after model was changed.
        self.pctrl.update_viewcanvas()

        for i, item in enumerate(pm.vois):
            logger.debug("pm.vois {}:{}".format(i, item.name))

    def update_tree(self):
        """
        Syncs the tree with the main_model, adding and removing items accordingly.
        """
        logger.debug("update_tree()")
        self._model_sync_add_items()
        self._model_sync_remove_items()

    def _model_sync_add_items(self):
        """
        Syncs the tree with the main_model, adding and removing items accordingly.

        TODO: this can probably be programmed more elegantly.
        """
        self._add_ctx()
        self._add_vdxvoi()
        self._add_plans()
        self._add_dos()
        self._add_let()

    def _add_ctx(self):
        """
        """
        model = self.model
        tw = self.view.treeWidget

        # CTX data
        if model.ctx and not self._in_tree(model.ctx):
            # Add CTX to tree widget.
            tw.setHeaderLabels(["'{}'".format(model.ctx.basename)])  # TODO:patient name

            self.tctx = QTreeWidgetItem([model.ctx.basename])
            self.tctx.setData(0, Qt.UserRole, model.ctx)
            tw.addTopLevelItem(self.tctx)
            self.tctx.setCheckState(0, Qt.Checked)

    def _add_vdxvoi(self):
        """
        """
        model = self.model
        tw = self.view.treeWidget

        # VDX data
        if model.vdx and not self._in_tree(model.vdx):
            self.tvdx = QTreeWidgetItem(["ROIs: " + model.vdx.basename])
            self.tvdx.setData(0, Qt.UserRole, model.vdx)
            tw.addTopLevelItem(self.tvdx)
            self.tvdx.setExpanded(True)

        # VOIs
        if model.vdx and model.vdx.vois:
            vois = model.vdx.vois
            for i, voi in enumerate(vois):
                # Add only Vois which are not in the tree.
                if not self._in_tree(voi):
                    self.tvdx.addChild(QTreeWidgetItem([voi.name]))
                    child = self.tvdx.child(i)
                    child.setData(0, Qt.UserRole, voi)
                    child.setCheckState(0, Qt.Checked)

    def _add_plans(self):
        """
        """
        model = self.model
        tw = self.view.treeWidget

        # Plans node:
        if model.plans and not self.tplans:
            self.tplans = QTreeWidgetItem(["Plans:"])
            self.tplans.setData(0, Qt.UserRole, self._plancol)
            tw.addTopLevelItem(self.tplans)
            self.tplans.setExpanded(True)

        # Plans has one child for each plan.
        if model.plans:
            for i, plan in enumerate(model.plans):
                # Add only plans, which are not already in the tree
                if not self._in_tree(plan):
                    self.tplans.addChild(QTreeWidgetItem([plan.basename]))
                    child = self.tplans.child(i)
                    child.setData(0, Qt.UserRole, plan)
                    child.setCheckState(0, Qt.Checked)

    def _add_dos(self):
        """
        """
        model = self.model
        tw = self.view.treeWidget

        # Add the top level DOS node:
        if model.dos and not self.tdos:
            self.tdos = QTreeWidgetItem(["Dose Cubes"])
            self.tdos.setData(0, Qt.UserRole, self._doscol)
            tw.addTopLevelItem(self.tdos)
            self.tdos.setExpanded(True)

        # Each DosCube will be treated as a child to the top level DOS node.
        if model.dos:
            for i, dos in enumerate(model.dos):
                if not self._in_tree(dos):
                    self.tdos.addChild(QTreeWidgetItem([dos.basename]))
                    child = self.tdos.child(i)
                    child.setData(0, Qt.UserRole, dos)
                    child.setCheckState(0, Qt.Checked)

    def _add_let(self):
        """
        """
        model = self.model
        tw = self.view.treeWidget

        # Add the top level LET node:
        if model.let and not self.tlet:
            self.tlet = QTreeWidgetItem(["LET Cubes"])
            self.tlet.setData(0, Qt.UserRole, self._letcol)
            tw.addTopLevelItem(self.tlet)
            self.tlet.setExpanded(True)

        # Each LETCube will be treated as a child to the top level DOS node.
        if model.let:
            for i, let in enumerate(model.let):
                if not self._in_tree(let):
                    self.tlet.addChild(QTreeWidgetItem([let.basename]))
                    child = self.tlet.child(i)
                    child.setData(0, Qt.UserRole, let)
                    child.setCheckState(0, Qt.Checked)

    def _model_sync_remove_items(self):
        """
        Sync TreeWidget with data model.
        If items are found in TreeWidget, which are not found in
        data model, the item will be removed from TreeWidget.
        """

        tw = self.view.treeWidget

        lo = self._flat_model()

        root = tw.invisibleRootItem()
        count = root.childCount()

        # Check if TreeWidget item data object is found in model.
        # if not, remove it from TreeWidget.
        for i in range(count):
            item = root.child(i)
            if item:
                _obj = item.data(0, Qt.UserRole)
                if _obj not in lo:
                    (item.parent() or root).removeChild(item)

                count2 = item.childCount()
                for j in range(count2):
                    item2 = item.child(j)
                    if item2:
                        _obj = item2.data(0, Qt.UserRole)
                        if _obj not in lo:
                            (item2.parent() or root).removeChild(item)

    def _flat_model(self):
        """ Produces a searchable and flat array of model data
        which should be displayed in the TreeWidget.
        This array will be used for syncing the treeWidget items with the model items.
        """
        model = self.model

        # Check for items to be removed.
        # First lets make a flat list of all pytrip objects in the model (called "lo"):
        lo = [model.ctx, model.vdx]
        if model.vdx:
            if model.vdx.vois:
                lo += model.vdx.vois  # extend the list with a list of voi objects
        if model.dos:
            lo += model.dos
        if model.let:
            lo += model.let
        if model.plans:
            lo += model.plans
            for plan in model.plans:
                if plan.fields:
                    lo += plan.fields
        # TODO: this part needs some rework.
        # The top level nodes: plans, dos and let
        # should not be removed, if they hold data. They do not have a class, tough
        # Therefore this little hack for now:
        if model.dos:
            lo += [self._doscol]
        if model.let:
            lo += [self._letcol]
        if model.plans:
            lo += [self._plancol]

        return lo

    def _in_tree(self, obj):
        """
        Crawls the entire treewidget, and search for the object.
        Returns corresponding QTreeWidgetItem, if found, else None.

        :params PyTRiPobject obj: such as CtxCube, DosCube, VdxCube, Plan, ...etc
        """
        tw = self.view.treeWidget

        root = tw.invisibleRootItem()
        count = root.childCount()

        for i in range(count):
            child = root.child(i)
            _obj = child.data(0, Qt.UserRole)
            if obj == _obj:
                return child

            count2 = child.childCount()
            for j in range(count2):
                child2 = child.child(j)
                _obj = child2.data(0, Qt.UserRole)
                if obj == _obj:
                    return child2

        return None
class ExtensionMenu(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent=parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.categoryTW.header().setSectionResizeMode(0, QHeaderView.Fixed)
        self.ui.categoryTW.header().setSectionResizeMode(1, QHeaderView.Fixed)
        self.setFixedSize(self.size())

        self.groupHead = None
        self.extensions = []
        self.stat = {}
        self.user_defined = 0
        self.extFile = 'extenstion_Category'
        self.read()

        self.ui.categoryTW.itemDoubleClicked.connect(self.modify)

        self.ui.addPB.clicked.connect(self.addRow)
        self.ui.removePB.clicked.connect(self.removeRow)
        self.ui.buttonBox.accepted.connect(self.write)
        self.ui.buttonBox.rejected.connect(self.reject)

    def addRow(self):
        editcategory = EditCategory(self, self.extensions)
        reply = editcategory.run()
        if reply != None:
            category, extensions = reply
            self.extensions += extensions.split(', ')
            treeitem = QTreeWidgetItem(self.groupHead, [category, extensions])
            treeitem.setTextAlignment(0, Qt.AlignTop | Qt.AlignLeft)

    def modify(self, item, column):
        parent = item.parent()
        if parent == None or parent.text(0) == 'Primitive':
            return None
        editcategory = EditCategory(self, self.extensions, item.text(0),
                                    item.text(1))
        previous = item.text(1).split(', ')
        reply = editcategory.run()
        if reply != None:
            category, extensions = reply
            if extensions != item.text(1):
                for p in previous:
                    self.extensions.remove(p)
                self.extensions += extensions.split(', ')
            item.setText(0, category)
            item.setText(1, extensions)

    def read(self):
        stat = {}
        with open(self.extFile, 'r', encoding='utf-8') as fle:
            stat = json.load(fle)
        self.stat['Primitive'] = stat['Primitive']
        self.user_defined = len(list(stat['User-defined'].keys()))
        for label, categorydict in stat.items():
            self.groupHead = QTreeWidgetItem(self.ui.categoryTW, [label])
            for category, extensionList in categorydict.items():
                self.extensions += extensionList
                treeitem = QTreeWidgetItem(
                    self.groupHead, [category, ", ".join(extensionList)])
                treeitem.setTextAlignment(0, Qt.AlignTop | Qt.AlignLeft)
        self.ui.categoryTW.setItemDelegate(MyDelegate())

    def removeRow(self):
        items = self.ui.categoryTW.selectedItems()
        flag = False
        for item in items:
            parent = item.parent()
            if parent == None or parent.text(0) == 'Primitive':
                flag = True
            else:
                parent.removeChild(item)
        if flag:
            QMessageBox.warning(self, "Alert",
                                "You can't delete primitive category.")

    def write(self):
        if self.groupHead.childCount() == self.user_defined:
            self.reject()
        else:
            self.stat['User-defined'] = {}
            for index in range(self.groupHead.childCount()):
                category = self.groupHead.child(index).text(0)
                extensionList = self.groupHead.child(index).text(1).split(', ')
                self.stat['User-defined'][category] = extensionList
            with open(self.extFile, 'w', encoding='utf-8') as fle:
                json.dump(self.stat, fle, ensure_ascii=False, indent=4)
            QMessageBox.information(self, "Info", "Data saved.")
            self.accept()
Пример #32
0
class MainDialog(QDialog, Ui_MainDialog):

    """The main dialog of QGIS2Web plugin."""
    items = {}

    def __init__(self, iface):
        QDialog.__init__(self)
        self.setupUi(self)
        self.iface = iface

        self.previewUrl = None
        self.layer_search_combo = None
        self.exporter_combo = None

        self.feedback = FeedbackDialog(self)
        self.feedback.setModal(True)

        stgs = QSettings()

        self.restoreGeometry(stgs.value("qgis2web/MainDialogGeometry",
                                        QByteArray(), type=QByteArray))

        if stgs.value("qgis2web/previewOnStartup", Qt.Checked) == Qt.Checked:
            self.previewOnStartup.setCheckState(Qt.Checked)
        else:
            self.previewOnStartup.setCheckState(Qt.Unchecked)
        if (stgs.value("qgis2web/closeFeedbackOnSuccess", Qt.Checked) ==
                Qt.Checked):
            self.closeFeedbackOnSuccess.setCheckState(Qt.Checked)
        else:
            self.closeFeedbackOnSuccess.setCheckState(Qt.Unchecked)
        self.previewFeatureLimit.setText(
            stgs.value("qgis2web/previewFeatureLimit", "1000"))

        self.paramsTreeOL.setSelectionMode(QAbstractItemView.SingleSelection)
        self.preview = None
        if webkit_available:
            widget = QWebView()
            self.preview = widget
            try:
                # if os.environ["TRAVIS"]:
                self.preview.setPage(WebPage())
            except:
                print("Failed to set custom webpage")
            webview = self.preview.page()
            webview.setNetworkAccessManager(QgsNetworkAccessManager.instance())
            self.preview.settings().setAttribute(
                QWebSettings.DeveloperExtrasEnabled, True)
        else:
            widget = QTextBrowser()
            widget.setText(self.tr('Preview is not available since QtWebKit '
                                   'dependency is missing on your system'))
        self.right_layout.insertWidget(0, widget)
        self.populateConfigParams(self)
        self.populate_layers_and_groups(self)
        self.populateLayerSearch()

        writer = WRITER_REGISTRY.createWriterFromProject()
        self.setStateToWriter(writer)

        self.exporter = EXPORTER_REGISTRY.createFromProject()
        self.exporter_combo.setCurrentIndex(
            self.exporter_combo.findText(self.exporter.name()))
        self.exporter_combo.currentIndexChanged.connect(
            self.exporterTypeChanged)

        self.toggleOptions()
        if webkit_available:
            if self.previewOnStartup.checkState() == Qt.Checked:
                self.autoUpdatePreview()
            self.buttonPreview.clicked.connect(self.previewMap)
        else:
            self.buttonPreview.setDisabled(True)
        self.layersTree.model().dataChanged.connect(self.populateLayerSearch)
        self.ol3.clicked.connect(self.changeFormat)
        self.leaflet.clicked.connect(self.changeFormat)
        self.buttonExport.clicked.connect(self.saveMap)
        helpText = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                "helpFile.md")
        self.helpField.setSource(QUrl.fromLocalFile(helpText))
        if webkit_available:
            self.devConsole = QWebInspector(self.verticalLayoutWidget_2)
            self.devConsole.setFixedHeight(0)
            self.devConsole.setObjectName("devConsole")
            self.devConsole.setPage(self.preview.page())
            self.devConsole.hide()
            self.right_layout.insertWidget(1, self.devConsole)
        self.filter = devToggleFilter()
        self.filter.devToggle.connect(self.showHideDevConsole)
        self.installEventFilter(self.filter)
        self.setModal(False)

    @pyqtSlot(bool)
    def showHideDevConsole(self, visible):
        self.devConsole.setVisible(visible)

    def changeFormat(self):
        self.autoUpdatePreview()
        self.toggleOptions()

    def exporterTypeChanged(self):
        new_exporter_name = self.exporter_combo.currentText()
        try:
            self.exporter = [
                e for e in EXPORTER_REGISTRY.getExporters()
                if e.name() == new_exporter_name][0]()
        except:
            pass

    def currentMapFormat(self):
        """
        Returns the currently selected map writer type
        """
        return self.getWriterFactory().type()

    def getWriterFactory(self):
        """
        Returns a factory to create the currently selected map writer
        """
        if self.mapFormat.checkedButton() == self.ol3:
            return OpenLayersWriter
        elif self.mapFormat.checkedButton() == self.leaflet:
            return LeafletWriter

    def createWriter(self):
        """
        Creates a writer object reflecting the current settings
        in the dialog
        """
        writer = self.getWriterFactory()()
        (writer.layers, writer.groups, writer.popup,
         writer.visible, writer.json,
         writer.cluster, writer.getFeatureInfo) = self.getLayersAndGroups()
        writer.params = self.getParameters()
        return writer

    def showErrorMessage(self, error):
        """
        Shows an error message in the preview window
        """
        html = "<html>"
        html += "<head></head>"
        html += "<style>body {font-family: sans-serif;}</style>"
        html += "<body><h1>Error</h1>"
        html += "<p>qgis2web produced an error:</p><code>"
        html += error
        html += "</code></body></html>"
        if self.preview:
            self.preview.setHtml(html)

    def showFeedbackMessage(self, title, message):
        """
        Shows a feedback message in the preview window
        """
        html = "<html>"
        html += "<head></head>"
        html += "<style>body {font-family: sans-serif;}</style>"
        html += "<body><h1>{}</h1>".format(title)
        html += "<p>{}</p>".format(message)
        html += "</body></html>"
        if self.preview:
            self.preview.setHtml(html)

    def toggleOptions(self):
        currentWriter = self.getWriterFactory()
        for param, value in specificParams.items():
            treeParam = self.paramsTreeOL.findItems(param,
                                                    (Qt.MatchExactly |
                                                     Qt.MatchRecursive))[0]
            if currentWriter == OpenLayersWriter:
                if value == "OL3":
                    treeParam.setDisabled(False)
                else:
                    treeParam.setDisabled(True)
            else:
                if value == "OL3":
                    treeParam.setDisabled(True)
                else:
                    treeParam.setDisabled(False)
        for option, value in specificOptions.items():
            treeOptions = self.layersTree.findItems(option,
                                                    (Qt.MatchExactly |
                                                     Qt.MatchRecursive))
            for treeOption in treeOptions:
                if currentWriter == OpenLayersWriter:
                    if value == "OL3":
                        treeOption.setDisabled(False)
                    else:
                        treeOption.setDisabled(True)
                else:
                    if value == "OL3":
                        treeOption.setDisabled(True)
                    else:
                        treeOption.setDisabled(False)

    def createPreview(self):
        writer = self.createWriter()
        return writer.write(self.iface,
                            dest_folder=utils.tempFolder()).index_file

    def shouldAutoPreview(self):
        """
        Returns a tuple, with a bool for whether the preview should
        automatically be generated, and a string for explanations
        as to why the preview cannot be automatically generated
        """
        writer = self.createWriter()
        total_features = 0
        for layer in writer.layers:
            if isinstance(layer, QgsVectorLayer):
                total_features += layer.featureCount()

        if total_features > int(self.previewFeatureLimit.text()):
            # Too many features => too slow!
            return (False, self.tr('<p>A large number of features are '
                                   'present in the map. Generating the '
                                   'preview may take some time.</p>'
                                   '<p>Click Update Preview to generate the '
                                   'preview anyway.</p>'))

        return (True, None)

    def autoUpdatePreview(self):
        """
        Triggered when a preview will be automatically generated, i.e.
        not as a result of the user manually clicking the
        Update Preview button.
        """
        (auto_preview, message) = self.shouldAutoPreview()
        if not auto_preview:
            self.showFeedbackMessage(self.tr('Preview Map'), message)
        else:
            self.previewMap()

    def previewMap(self):
        preview_file = self.createPreview()
        self.loadPreviewFile(preview_file)

    def saveMap(self):
        writer = self.createWriter()
        write_folder = self.exporter.exportDirectory()
        if not write_folder:
            return

        self.feedback.reset()
        self.feedback.show()
        results = writer.write(self.iface,
                               dest_folder=write_folder,
                               feedback=self.feedback)
        self.feedback.showFeedback('Success')
        if self.closeFeedbackOnSuccess.checkState() == Qt.Checked:
            self.feedback.close()
        result = self.exporter.postProcess(results, feedback=self.feedback)
        if result and (not os.environ.get('CI') and
                       not os.environ.get('TRAVIS')):
            webbrowser.open_new_tab(self.exporter.destinationUrl())

    def populate_layers_and_groups(self, dlg):
        """Populate layers on QGIS into our layers and group tree view."""
        root_node = QgsProject.instance().layerTreeRoot()
        tree_groups = []
        tree_layers = root_node.findLayers()
        self.layers_item = QTreeWidgetItem()
        self.layers_item.setText(0, "Layers and Groups")
        self.layersTree.setColumnCount(3)

        for tree_layer in tree_layers:
            layer = tree_layer.layer()
            if (layer.type() != QgsMapLayer.PluginLayer and
                    layer.customProperty("ol_layer_type") is None):
                try:
                    if layer.type() == QgsMapLayer.VectorLayer:
                        testDump = layer.renderer().dump()
                    layer_parent = tree_layer.parent()
                    if layer_parent.parent() is None:
                        item = TreeLayerItem(self.iface, layer,
                                             self.layersTree, dlg)
                        self.layers_item.addChild(item)
                    else:
                        if layer_parent not in tree_groups:
                            tree_groups.append(layer_parent)
                except:
                    QgsMessageLog.logMessage(traceback.format_exc(),
                                             "qgis2web",
                                             level=Qgis.Critical)

        for tree_group in tree_groups:
            group_name = tree_group.name()
            group_layers = [
                tree_layer.layer() for tree_layer in tree_group.findLayers()]
            item = TreeGroupItem(group_name, group_layers, self.layersTree)
            self.layers_item.addChild(item)

        self.layersTree.addTopLevelItem(self.layers_item)
        self.layersTree.expandAll()
        self.layersTree.resizeColumnToContents(0)
        self.layersTree.resizeColumnToContents(1)
        for i in range(self.layers_item.childCount()):
            item = self.layers_item.child(i)
            if item.checkState(0) != Qt.Checked:
                item.setExpanded(False)

    def populateLayerSearch(self):
        self.layer_search_combo.clear()
        self.layer_search_combo.addItem("None")
        (layers, groups, popup, visible,
         json, cluster, getFeatureInfo) = self.getLayersAndGroups()
        for count, layer in enumerate(layers):
            if layer.type() == layer.VectorLayer:
                options = []
                fields = layer.fields()
                for f in fields:
                    fieldIndex = fields.indexFromName(unicode(f.name()))
                    editorWidget = layer.editorWidgetSetup(fieldIndex).type()
                    if editorWidget == 'Hidden':
                        continue
                    options.append(unicode(f.name()))
                for option in options:
                    displayStr = unicode(layer.name() + ": " + option)
                    self.layer_search_combo.insertItem(0, displayStr)
                    sln = utils.safeName(layer.name())
                    self.layer_search_combo.setItemData(
                        self.layer_search_combo.findText(displayStr),
                        sln + "_" + unicode(count))

    def configureExporter(self):
        self.exporter.configure()

    def populateConfigParams(self, dlg):
        """ Populates the dialog with option items and widgets """
        self.items = defaultdict(dict)
        tree = dlg.paramsTreeOL

        configure_export_action = QAction('...', self)
        configure_export_action.triggered.connect(self.configureExporter)

        params = getParams(configure_exporter_action=configure_export_action)
        for group, settings in params.items():
            item = QTreeWidgetItem()
            item.setText(0, group)
            for param, value in settings.items():
                subitem = self.createOptionItem(tree_widget=tree,
                                                parent_item=item,
                                                parameter=param,
                                                default_value=value)
                item.addChild(subitem)
                self.items[group][param] = subitem
            self.paramsTreeOL.addTopLevelItem(item)
            item.sortChildren(0, Qt.AscendingOrder)
        self.paramsTreeOL.expandAll()
        self.paramsTreeOL.resizeColumnToContents(0)
        self.paramsTreeOL.resizeColumnToContents(1)
        self.layer_search_combo.removeItem(1)

    def createOptionItem(self, tree_widget, parent_item,
                         parameter, default_value):
        """create the tree item corresponding to an option parameter"""
        action = None
        if isinstance(default_value, dict):
            action = default_value['action']
            default_value = default_value['option']

        subitem = TreeSettingItem(parent_item, tree_widget,
                                  parameter, default_value, action)
        if parameter == 'Layer search':
            self.layer_search_combo = subitem.combo
        elif parameter == 'Exporter':
            self.exporter_combo = subitem.combo

        return subitem

    def setStateToWriter(self, writer):
        """
        Sets the dialog state to match the specified writer
        """
        self.selectMapFormat(writer)
        self.setStateToParams(writer.params)

    def setStateToParams(self, params):
        """
        Sets the dialog state to match the specified parameters
        """
        for group, settings in self.items.items():
            for param, item in settings.items():
                value = params[group][param]
                item.setValue(value)

    def selectMapFormat(self, writer):
        """
        Updates dialog state to match the specified writer format
        """
        self.ol3.setChecked(isinstance(writer, OpenLayersWriter))
        self.leaflet.setChecked(isinstance(writer, LeafletWriter))

    def loadPreviewFile(self, file):
        """
        Loads a web based preview from a local file path
        """
        self.previewUrl = QUrl.fromLocalFile(file)
        if self.preview:
            self.preview.settings().clearMemoryCaches()
            self.preview.setUrl(self.previewUrl)

    def getParameters(self):
        parameters = defaultdict(dict)
        for group, settings in self.items.items():
            for param, item in settings.items():
                parameters[group][param] = item.value()
                if param == "Layer search":
                    parameters["Appearance"]["Search layer"] = (
                        self.layer_search_combo.itemData(
                            self.layer_search_combo.currentIndex()))
        return parameters

    def saveParameters(self):
        """
        Saves current dialog state to project
        """
        WRITER_REGISTRY.saveWriterToProject(self.createWriter())
        EXPORTER_REGISTRY.writeToProject(self.exporter)

    def getLayersAndGroups(self):
        layers = []
        groups = {}
        popup = []
        visible = []
        json = []
        cluster = []
        getFeatureInfo = []
        for i in range(self.layers_item.childCount()):
            item = self.layers_item.child(i)
            if isinstance(item, TreeLayerItem):
                if item.checkState(0) == Qt.Checked:
                    layers.append(item.layer)
                    popup.append(item.popup)
                    visible.append(item.visible)
                    json.append(item.json)
                    cluster.append(item.cluster)
                    getFeatureInfo.append(item.getFeatureInfo)
            else:
                group = item.name
                groupLayers = []
                if item.checkState(0) != Qt.Checked:
                    continue
                for layer in item.layers:
                    groupLayers.append(layer)
                    layers.append(layer)
                    popup.append({})
                    if item.visible:
                        visible.append(True)
                    else:
                        visible.append(False)
                    if hasattr(item, "json") and item.json:
                        json.append(True)
                    else:
                        json.append(False)
                    if hasattr(item, "cluster") and item.cluster:
                        cluster.append(True)
                    else:
                        cluster.append(False)
                    if hasattr(item, "getFeatureInfo") and item.getFeatureInfo:
                        getFeatureInfo.append(True)
                    else:
                        getFeatureInfo.append(False)
                groups[group] = groupLayers[::-1]

        return (layers[::-1],
                groups,
                popup[::-1],
                visible[::-1],
                json[::-1],
                cluster[::-1],
                getFeatureInfo[::-1])

    def reject(self):
        self.saveParameters()
        (layers, groups, popup, visible,
         json, cluster, getFeatureInfo) = self.getLayersAndGroups()
        for layer, pop, vis in zip(layers, popup, visible):
            attrDict = {}
            for attr in pop:
                attrDict['attr'] = pop[attr]
                layer.setCustomProperty("qgis2web/popup/" + attr, pop[attr])
            layer.setCustomProperty("qgis2web/Visible", vis)

        QSettings().setValue(
            "qgis2web/MainDialogGeometry", self.saveGeometry())

        QSettings().setValue("qgis2web/previewOnStartup",
                             self.previewOnStartup.checkState())
        QSettings().setValue("qgis2web/closeFeedbackOnSuccess",
                             self.closeFeedbackOnSuccess.checkState())
        QSettings().setValue("qgis2web/previewFeatureLimit",
                             self.previewFeatureLimit.text())

        QDialog.close(self)

    def closeEvent(self, event):
        if self.devConsole or self.devConsole.isVisible() and self.preview:
            del self.devConsole
            del self.preview

        self.reject()
        event.accept()
    def addOverlaysToTreeWidget(self, overlayDict, forbiddenOverlays,
                                preSelectedOverlays, singleOverlaySelection):
        self.singleOverlaySelection = singleOverlaySelection
        testItem = QTreeWidgetItem("a")
        for keys in list(overlayDict.keys()):
            if overlayDict[keys] in forbiddenOverlays:
                continue
            else:
                boolStat = False
                split = keys.split("/")
            for i in range(len(split)):
                if len(split) == 1:
                    newItemsChild = OverlayTreeWidgetItem(
                        overlayDict[keys], keys)
                    self.addTopLevelItem(newItemsChild)
                    boolStat = False
                    if overlayDict[keys] in preSelectedOverlays:
                        newItemsChild.setCheckState(0, Qt.Checked)
                    else:
                        newItemsChild.setCheckState(0, Qt.Unchecked)

                elif i + 1 == len(split) and len(split) > 1:
                    newItemsChild = OverlayTreeWidgetItem(
                        overlayDict[keys], keys)
                    testItem.addChild(newItemsChild)
                    if overlayDict[keys] in preSelectedOverlays:
                        newItemsChild.setCheckState(0, Qt.Checked)
                    else:
                        newItemsChild.setCheckState(0, Qt.Unchecked)

                elif self.topLevelItemCount() == 0 and i + 1 < len(split):
                    newItem = QTreeWidgetItem([split[i]])
                    self.addTopLevelItem(newItem)
                    testItem = newItem
                    boolStat = True

                elif self.topLevelItemCount() != 0 and i + 1 < len(split):
                    if boolStat == False:
                        for n in range(self.topLevelItemCount()):
                            if self.topLevelItem(n).text(0) == split[i]:
                                testItem = self.topLevelItem(n)
                                boolStat = True
                                break
                            elif n + 1 == self.topLevelItemCount():
                                newItem = QTreeWidgetItem([split[i]])
                                self.addTopLevelItem(newItem)
                                testItem = newItem
                                boolStat = True

                    elif testItem.childCount() == 0:
                        newItem = QTreeWidgetItem([split[i]])
                        testItem.addChild(newItem)
                        testItem = newItem
                        boolStat = True
                    else:
                        for x in range(testItem.childCount()):
                            if testItem.child(x).text(0) == split[i]:
                                testItem = testItem.child(x)
                                boolStat = True
                                break
                            elif x + 1 == testItem.childCount():
                                newItem = QTreeWidgetItem([split[i]])
                                testItem.addChild(newItem)
                                testItem = newItem
                                boolStat = True
Пример #34
0
class DeviceDialog(QDialog, Ui_DeviceDialog):
    """
        Function and Event handling class for the Ui_DeviceDialog.
    """
    qtcb_enumerate = pyqtSignal(str, str, str, type((0,)), type((0,)), int, int)
    qtcb_connected = pyqtSignal(int)

    def __init__(self, parent):
        QDialog.__init__(self, parent, get_modeless_dialog_flags())

        self._logger_window = parent

        self.device_name_by_device_identifier = {}

        for display_name, device_spec in device_specs.items():
            self.device_name_by_device_identifier[device_spec['class'].DEVICE_IDENTIFIER] = display_name

        self.qtcb_enumerate.connect(self.cb_enumerate)
        self.qtcb_connected.connect(self.cb_connected)

        self.host = None
        self.port = None
        self.secret = None

        self.ipcon = IPConnection()
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.qtcb_connected.emit)
        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.qtcb_enumerate.emit)

        self.setupUi(self)

        self.btn_add_device.clicked.connect(self.btn_add_device_clicked)
        self.btn_refresh.clicked.connect(self.btn_refresh_clicked)
        self.btn_close.clicked.connect(self.btn_close_clicked)
        self.tree_widget.itemActivated.connect(self.add_item)

        self.connected_uids = []
        self.available_item = QTreeWidgetItem(['No devices available'])
        self.supported_item = QTreeWidgetItem(['Supported devices'])

        self.tree_widget.addTopLevelItem(self.available_item)
        self.tree_widget.addTopLevelItem(self.supported_item)

        for device_name in device_specs:
            self.supported_item.addChild(QTreeWidgetItem([device_name]))

        self.supported_item.sortChildren(0, Qt.AscendingOrder)
        self.supported_item.setExpanded(True)

    def cb_connected(self, connect_reason):
        self.tree_widget.clearSelection()
        self.available_item.takeChildren()
        self.available_item.setExpanded(True)
        self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port))

        self.connected_uids = []

        if self.secret != None:
            self.ipcon.set_auto_reconnect(False) # don't auto-reconnect on authentication error

            try:
                self.ipcon.authenticate(self.secret)
            except:
                try:
                    self.ipcon.disconnect()
                except:
                    pass

                if connect_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
                    extra = ' after auto-reconnect'
                else:
                    extra = ''

                self.available_item.setText(0, 'Could not authenticate' + extra)
                return

            self.ipcon.set_auto_reconnect(True)

        try:
            self.ipcon.enumerate()
        except:
            pass

    def cb_enumerate(self, uid, connected_uid, position,
                     hardware_version, firmware_version,
                     device_identifier, enumeration_type):
        if enumeration_type in [IPConnection.ENUMERATION_TYPE_AVAILABLE,
                                IPConnection.ENUMERATION_TYPE_CONNECTED]:
            if uid not in self.connected_uids:
                display_name = self.device_name_by_device_identifier.get(device_identifier)

                if display_name != None:
                    self.connected_uids.append(uid)
                    self.available_item.addChild(QTreeWidgetItem(['{0} [{1}]'.format(display_name, uid)]))
                    self.available_item.setText(0, 'Devices available at {0}:{1}'.format(self.host, self.port))
                    self.available_item.sortChildren(0, Qt.AscendingOrder)
        else:
            if uid in self.connected_uids:
                self.connected_uids.remove(uid)

            for i in range(self.available_item.childCount()):
                child = self.available_item.child(i)

                if '[{0}]'.format(uid) in child.text(0):
                    self.available_item.takeChild(i)
                    break

            if self.available_item.childCount() == 0:
                self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port))

    def btn_add_device_clicked(self):
        for item in self.tree_widget.selectedItems():
            if item == self.available_item or item == self.supported_item:
                continue

            self._logger_window.add_device_to_tree(self.create_device_config(item.text(0)))

    def btn_refresh_clicked(self):
        try:
            self.ipcon.disconnect()
        except:
            pass

        self.tree_widget.clearSelection()
        self.available_item.takeChildren()
        self.available_item.setExpanded(True)

        self.connected_uids = []
        self.host = self._logger_window.combo_host.currentText()
        self.port = self._logger_window.spin_port.value()
        if self._logger_window.check_authentication.isChecked():
            self.secret = self._logger_window.edit_secret.text()

            try:
                self.secret.encode('ascii')
            except:
                self.secret = None
                self.available_item.setText(0, 'Authentication secret cannot contain non-ASCII characters')
                return
        else:
            self.secret = None

        try:
            self.ipcon.connect(self.host, self.port)
            self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port))
        except:
            self.available_item.setText(0, 'Could not connect to {0}:{1}'.format(self.host, self.port))

    def btn_close_clicked(self):
        self.close()

    def add_item(self, item):
        if item == self.available_item or item == self.supported_item:
            return

        self._logger_window.add_device_to_tree(self.create_device_config(item.text(0)))

    def create_device_config(self, item_text):
        name, uid = Utilities.parse_device_name(item_text) # FIXME
        device_spec = device_specs[name]

        if uid == None: # FIXME
            uid = ''

        device = {
            'host': 'default',
            'name': name,
            'uid': uid,
            'values': {},
            'options': {}
        }

        for value_spec in device_spec['values']:
            device['values'][value_spec['name']] = {'interval': 0}

            if value_spec['subvalues'] != None:
                device['values'][value_spec['name']]['subvalues'] = {}

                for subvalue_name in value_spec['subvalues']:
                    device['values'][value_spec['name']]['subvalues'][subvalue_name] = True

        if device_spec['options'] != None:
            for option_spec in device_spec['options']:
                device['options'][option_spec['name']] = {'value': option_spec['default']}

        return device
Пример #35
0
    def update(self, *, network: Network, servers: dict, use_tor: bool):
        self.clear()

        # connected servers
        connected_servers_item = QTreeWidgetItem([_("Connected nodes"), ''])
        connected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
        chains = network.get_blockchains()
        n_chains = len(chains)
        for chain_id, interfaces in chains.items():
            b = blockchain.blockchains.get(chain_id)
            if b is None: continue
            name = b.get_name()
            if n_chains > 1:
                x = QTreeWidgetItem([name + '@%d'%b.get_max_forkpoint(), '%d'%b.height()])
                x.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CHAIN)
                x.setData(0, self.CHAIN_ID_ROLE, b.get_id())
            else:
                x = connected_servers_item
            for i in interfaces:
                star = ' *' if i == network.interface else ''
                item = QTreeWidgetItem([f"{i.server.to_friendly_name()}" + star, '%d'%i.tip])
                item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CONNECTED_SERVER)
                item.setData(0, self.SERVER_ADDR_ROLE, i.server)
                item.setToolTip(0, str(i.server))
                x.addChild(item)
            if n_chains > 1:
                connected_servers_item.addChild(x)

        # disconnected servers
        disconnected_servers_item = QTreeWidgetItem([_("Other known servers"), ""])
        disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
        connected_hosts = set([iface.host for ifaces in chains.values() for iface in ifaces])
        protocol = PREFERRED_NETWORK_PROTOCOL
        for _host, d in sorted(servers.items()):
            if _host in connected_hosts:
                continue
            if _host.endswith('.onion') and not use_tor:
                continue
            port = d.get(protocol)
            if port:
                server = ServerAddr(_host, port, protocol=protocol)
                item = QTreeWidgetItem([server.net_addr_str(), ""])
                item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER)
                item.setData(0, self.SERVER_ADDR_ROLE, server)
                disconnected_servers_item.addChild(item)

        self.addTopLevelItem(connected_servers_item)
        self.addTopLevelItem(disconnected_servers_item)

        connected_servers_item.setExpanded(True)
        for i in range(connected_servers_item.childCount()):
            connected_servers_item.child(i).setExpanded(True)
        disconnected_servers_item.setExpanded(True)

        # headers
        h = self.header()
        h.setStretchLastSection(False)
        h.setSectionResizeMode(0, QHeaderView.Stretch)
        h.setSectionResizeMode(1, QHeaderView.ResizeToContents)

        super().update()
Пример #36
0
 def addOverlaysToTreeWidget(self, overlayDict, forbiddenOverlays, preSelectedOverlays, singleOverlaySelection):
     self.singleOverlaySelection = singleOverlaySelection
     testItem = QTreeWidgetItem("a")
     for keys in list(overlayDict.keys()):
         if overlayDict[keys] in forbiddenOverlays:
             continue
         else:
             boolStat = False
             split = keys.split("/")
         for i in range(len(split)):
             if len(split) == 1:
                 newItemsChild = OverlayTreeWidgetItem(overlayDict[keys], keys)
                 self.addTopLevelItem(newItemsChild)                   
                 boolStat = False
                 if overlayDict[keys] in preSelectedOverlays:
                     newItemsChild.setCheckState(0, Qt.Checked)
                 else:
                     newItemsChild.setCheckState(0, Qt.Unchecked)
                 
             elif i+1 == len(split) and len(split) > 1:
                 newItemsChild = OverlayTreeWidgetItem(overlayDict[keys], keys)
                 testItem.addChild(newItemsChild)
                 if overlayDict[keys] in preSelectedOverlays:
                     newItemsChild.setCheckState(0, Qt.Checked)
                 else:
                     newItemsChild.setCheckState(0, Qt.Unchecked)
                 
             elif self.topLevelItemCount() == 0 and i+1 < len(split):
                 newItem = QTreeWidgetItem([split[i]])
                 self.addTopLevelItem(newItem)
                 testItem = newItem
                 boolStat = True
                 
             elif self.topLevelItemCount() != 0 and i+1 < len(split):
                 if boolStat == False:
                     for n in range(self.topLevelItemCount()):
                         if self.topLevelItem(n).text(0) == split[i]:
                             testItem = self.topLevelItem(n)
                             boolStat = True
                             break
                         elif n+1 == self.topLevelItemCount():
                             newItem = QTreeWidgetItem([split[i]])
                             self.addTopLevelItem(newItem)
                             testItem = newItem
                             boolStat = True
                     
                 elif testItem.childCount() == 0:
                     newItem = QTreeWidgetItem([split[i]])
                     testItem.addChild(newItem)
                     testItem = newItem
                     boolStat = True
                 else:
                     for x in range(testItem.childCount()):
                         if testItem.child(x).text(0) == split[i]:
                             testItem = testItem.child(x)
                             boolStat = True
                             break
                         elif x+1 == testItem.childCount():
                             newItem = QTreeWidgetItem([split[i]])
                             testItem.addChild(newItem)
                             testItem = newItem
                             boolStat = True