class AlgorithmMonitorDialog(QDialog):
    """
    Displays progress of all running algorithms.
    """
    def __init__(self, parent, model):
        super(AlgorithmMonitorDialog, self).__init__(parent)
        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(3)
        self.tree.setSelectionMode(QTreeWidget.NoSelection)
        self.tree.setColumnWidth(0, 220)
        self.tree.setHeaderLabels(['Algorithm', 'Progress', ''])
        header = self.tree.header()
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Fixed)
        header.setStretchLastSection(False)

        button_layout = QHBoxLayout()
        self.close_button = QPushButton('Close')
        button_layout.addStretch()
        button_layout.addWidget(self.close_button)

        layout = QVBoxLayout()
        layout.addWidget(self.tree)
        layout.addLayout(button_layout)
        self.setLayout(layout)

        self.setWindowTitle('Mantid - Algorithm progress')
        self.setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png"))
        self.resize(500, 300)

        self.presenter = AlgorithmProgressDialogPresenter(self, model)
        self.presenter.update_gui()

    def update(self, data):
        """
        Update the gui elements.
        :param data: Data in format of AlgorithmProgressModel.get_running_algorithm_data()
        """
        self.tree.clear()
        for alg_data in data:
            name, id, properties = alg_data
            item = QTreeWidgetItem([name])
            self.tree.addTopLevelItem(item)
            progress_bar = QProgressBar()
            progress_bar.setAlignment(Qt.AlignHCenter)
            self.presenter.add_progress_bar(id, progress_bar)
            cancel_button = CancelButton(self.presenter, id)
            self.tree.setItemWidget(item, 1, progress_bar)
            self.tree.setItemWidget(item, 2, cancel_button)
            for prop in properties:
                item.addChild(QTreeWidgetItem(prop))
Beispiel #2
0
class AlgorithmMonitorDialog(QDialog):
    """
    Displays progress of all running algorithms.
    """
    def __init__(self, parent, model):
        super(AlgorithmMonitorDialog, self).__init__(parent)
        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(3)
        self.tree.setSelectionMode(QTreeWidget.NoSelection)
        self.tree.setColumnWidth(0, 220)
        self.tree.setHeaderLabels(['Algorithm', 'Progress', ''])
        header = self.tree.header()
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Fixed)
        header.setStretchLastSection(False)

        button_layout = QHBoxLayout()
        self.close_button = QPushButton('Close')
        button_layout.addStretch()
        button_layout.addWidget(self.close_button)

        layout = QVBoxLayout()
        layout.addWidget(self.tree)
        layout.addLayout(button_layout)
        self.setLayout(layout)

        self.setWindowTitle('Mantid - Algorithm progress')
        self.setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png"))
        self.resize(500, 300)

        self.presenter = AlgorithmProgressDialogPresenter(self, model)
        self.presenter.update_gui()

    def update(self, data):
        """
        Update the gui elements.
        :param data: Data in format of AlgorithmProgressModel.get_running_algorithm_data()
        """
        self.tree.clear()
        for alg_data in data:
            name, id, properties = alg_data
            item = QTreeWidgetItem([name])
            self.tree.addTopLevelItem(item)
            progress_bar = QProgressBar()
            progress_bar.setAlignment(Qt.AlignHCenter)
            self.presenter.add_progress_bar(id, progress_bar)
            cancel_button = CancelButton(self.presenter, id)
            self.tree.setItemWidget(item, 1, progress_bar)
            self.tree.setItemWidget(item, 2, cancel_button)
            for prop in properties:
                item.addChild(QTreeWidgetItem(prop))
Beispiel #3
0
    def generate_context_menu(self, pos: QPoint):
        """
        Generate a context menu for contextMenuEvent

        Parameters
        ----------
        pos : QPoint
            The point where the context menu was requested
        """
        model_menu = QMenu()
        skip_text = "skip me"

        # Add filterbox to the context menu
        txt_box = QLineEdit(model_menu)
        txt_box.setPlaceholderText("Filter")
        txt_box.setClearButtonEnabled(True)
        txt_box_action = QWidgetAction(model_menu)
        txt_box_action.setDefaultWidget(txt_box)
        model_menu.addAction(txt_box_action)

        # Add result treeview to the context menu
        tree_view = QTreeWidget(model_menu)
        tree_view.header().close()
        tree_view_action = QWidgetAction(model_menu)
        tree_view_action.setDefaultWidget(tree_view)
        model_menu.addAction(tree_view_action)

        top_level_items = {}
        for cat in self._scene.registry.categories():
            item = QTreeWidgetItem(tree_view)
            item.setText(0, cat)
            item.setData(0, Qt.UserRole, skip_text)
            top_level_items[cat] = item

        registry = self._scene.registry
        for model, category in registry.registered_models_category_association(
        ).items():
            self.parent = top_level_items[category]
            item = QTreeWidgetItem(self.parent)
            item.setText(0, model)
            item.setData(0, Qt.UserRole, model)

        tree_view.expandAll()

        def click_handler(item):
            model_name = item.data(0, Qt.UserRole)
            if model_name == skip_text:
                return

            type_ = self._scene.registry.create(model_name)
            if type_:
                node = self._scene.create_node(type_)
                pos_view = self.mapToScene(pos)
                node.graphics_object.setPos(pos_view)
                self._scene.node_placed.emit(node)
            else:
                logger.debug("Model not found")

            model_menu.close()

        tree_view.itemClicked.connect(click_handler)

        # Setup filtering
        def filter_handler(text):
            for name, top_lvl_item in top_level_items.items():
                for i in range(top_lvl_item.childCount()):
                    child = top_lvl_item.child(i)
                    model_name = child.data(0, Qt.UserRole)
                    child.setHidden(text not in model_name)

        txt_box.textChanged.connect(filter_handler)

        # make sure the text box gets focus so the user doesn't have to click on it
        txt_box.setFocus()
        return model_menu
Beispiel #4
0
class CalculationPrepare(QDialog):
    """
    :type mask_path_list: list[QLineEdit]
    :type mask_mapper_list: list[MaskMapper]
    """
    def __init__(self, file_list, calculation_plan, measurement_file_path,
                 settings, batch_manager):
        """

        :param file_list: list of files to proceed
        :type file_list: list[str]
        :param calculation_plan: calculation plan for this run
        :type calculation_plan: CalculationPlan
        :param measurement_file_path: path to measurement result file
        :type measurement_file_path: str
        :param settings: settings object
        :type settings: PartSettings
        :type batch_manager: CalculationManager
        """
        super().__init__()
        self.setWindowTitle("Calculation start")
        self.file_list = file_list
        self.calculation_plan = calculation_plan
        self.measurement_file_path = measurement_file_path
        self.settings = settings
        self.batch_manager = batch_manager
        self.info_label = QLabel(
            "Information, <i><font color='blue'>warnings</font></i>, "
            "<b><font color='red'>errors</font><b>")
        self.voxel_size = Spacing("Voxel size", settings.image.spacing,
                                  settings.get("units_value", Units.nm))
        all_prefix = os.path.commonprefix(file_list)
        if not os.path.exists(all_prefix):
            all_prefix = os.path.dirname(all_prefix)
        if not os.path.isdir(all_prefix):
            all_prefix = os.path.dirname(all_prefix)
        self.base_prefix = QLineEdit(all_prefix, self)
        self.base_prefix.setReadOnly(True)
        self.result_prefix = QLineEdit(all_prefix, self)
        self.result_prefix.setReadOnly(True)
        self.base_prefix_btn = QPushButton("Choose data prefix")
        self.base_prefix_btn.clicked.connect(self.choose_data_prefix)
        self.result_prefix_btn = QPushButton("Choose save prefix")
        self.result_prefix_btn.clicked.connect(self.choose_result_prefix)
        self.sheet_name = QLineEdit("Sheet1")
        self.sheet_name.textChanged.connect(self.verify_data)
        self.measurement_file_path_view = QLineEdit(measurement_file_path)
        self.measurement_file_path_view.setReadOnly(True)

        self.mask_path_list = []
        self.mask_mapper_list = self.calculation_plan.get_list_file_mask()
        mask_file_list = []
        for i, el in enumerate(self.mask_mapper_list):
            if isinstance(el, MaskFile):
                mask_file_list.append((i, el))
        mask_path_layout = QGridLayout()
        for i, (pos, mask_file) in enumerate(mask_file_list):
            if mask_file.name == "":
                mask_path_layout.addWidget(
                    right_label("Path to file {} with mask mapping".format(i +
                                                                           1)))
            else:
                mask_path_layout.addWidget(
                    right_label(
                        "Path to file {} with mask mapping for name: {}".
                        format(i + 1, mask_file.name)))
            mask_path = QLineEdit(self)
            mask_path.setReadOnly(True)
            self.mask_path_list.append(mask_path)
            set_path = QPushButton("Choose file", self)
            set_path.clicked.connect(self.set_mapping_mask(i, pos))
            mask_path_layout.addWidget(mask_path, i, 1)
            mask_path_layout.addWidget(set_path, i, 2)

        self.state_list = np.zeros(
            (len(self.file_list), len(self.mask_mapper_list)), dtype=np.uint8)

        self.file_list_widget = QTreeWidget()
        self.file_list_widget.header().close()

        self.execute_btn = QPushButton("Execute")
        self.execute_btn.clicked.connect(self.accept)
        self.cancel_btn = QPushButton("Cancel")
        self.cancel_btn.clicked.connect(self.close)

        layout = QGridLayout()
        layout.addWidget(self.info_label, 0, 0, 1, 5)
        layout.addWidget(self.voxel_size, 1, 0, 1, 5)
        layout.addWidget(right_label("Measurement sheet name:"), 3, 3)
        layout.addWidget(self.sheet_name, 3, 4)
        layout.addWidget(right_label("Measurement file path:"), 2, 3)
        layout.addWidget(self.measurement_file_path_view, 2, 4)

        layout.addWidget(right_label("Data prefix:"), 2, 0)
        layout.addWidget(self.base_prefix, 2, 1)
        layout.addWidget(self.base_prefix_btn, 2, 2)
        layout.addWidget(right_label("Save prefix:"), 3, 0)
        layout.addWidget(self.result_prefix, 3, 1)
        layout.addWidget(self.result_prefix_btn, 3, 2)
        layout.addLayout(mask_path_layout, 4, 0, 1, 0)

        layout.addWidget(self.file_list_widget, 5, 0, 3, 6)
        btn_layout = QHBoxLayout()
        btn_layout.addWidget(self.execute_btn)
        btn_layout.addStretch()
        btn_layout.addWidget(self.cancel_btn)
        layout.addLayout(btn_layout, 8, 0, 1, 0)
        self.setLayout(layout)
        self.verify_data()

    def choose_data_prefix(self):
        dial = QFileDialog()
        dial.setAcceptMode(QFileDialog.AcceptOpen)
        dial.setFileMode(QFileDialog.Directory)
        dial.setDirectory(self.base_prefix.text())
        dial.setHistory(dial.history() + self.settings.get_path_history())
        if dial.exec_():
            dir_path = str(dial.selectedFiles()[0])
            self.base_prefix.setText(dir_path)

    def choose_result_prefix(self):
        dial = QFileDialog()
        dial.setOption(QFileDialog.DontUseNativeDialog, True)
        dial.setAcceptMode(QFileDialog.AcceptOpen)
        dial.setFileMode(QFileDialog.Directory)
        dial.setDirectory(self.result_prefix.text())
        dial.setHistory(dial.history() + self.settings.get_path_history())
        if dial.exec_():
            dir_path = str(dial.selectedFiles()[0])
            self.result_prefix.setText(dir_path)

    def set_mapping_mask(self, i, pos):
        def mapping_dialog():
            dial = QFileDialog(self, "Select file")
            dial.setHistory(dial.history() + self.settings.get_path_history())
            base_path = str(self.base_prefix.text()).strip()
            if base_path != "":
                dial.setDirectory(base_path)
            dial.setFileMode(QFileDialog.ExistingFile)
            if dial.exec_():
                path = str(dial.selectedFiles())
                self.mask_path_list[i].setText(path)
                file_mapper: MaskFile = self.mask_mapper_list[pos]
                file_mapper.set_map_path(path)

        return mapping_dialog

    def get_data(self):
        res = {
            "file_list": self.file_list,
            "base_prefix": str(self.base_prefix.text()),
            "result_prefix": str(self.result_prefix.text()),
            "measurement_file_path":
            str(self.measurement_file_path_view.text()),
            "sheet_name": str(self.sheet_name.text()),
            "calculation_plan": self.calculation_plan,
            "voxel_size": self.voxel_size.get_values(),
        }
        return Calculation(**res)

    def verify_data(self):
        self.execute_btn.setEnabled(True)
        text = (
            "information, <i><font color='blue'>warnings</font></i>, <b><font color='red'>errors</font></b><br>"
            "The voxel size is for file in which metadata do not contains this information<br>"
        )
        if not self.batch_manager.is_valid_sheet_name(
                str(self.measurement_file_path_view.text()),
                str(self.sheet_name.text())):
            text += "<i><font color='blue'>Sheet name already in use</i></font><br>"
            self.execute_btn.setDisabled(True)
        if self.state_list.size > 0:
            val = np.unique(self.state_list)
            if 1 in val:
                self.execute_btn.setDisabled(True)
                text += "<i><font color='blue'>Some mask map file are not set</font></i><br>"
            if 2 in val:
                self.execute_btn.setDisabled(True)
                text += "<b><font color='red'>Some mask do not exists</font><b><br>"

        text = text[:-4]
        self.info_label.setText(text)

    def showEvent(self, event):
        super().showEvent(event)
        ok_icon = QIcon(os.path.join(icons_dir, "task-accepted.png"))
        bad_icon = QIcon(os.path.join(icons_dir, "task-reject.png"))
        warn_icon = QIcon(os.path.join(icons_dir, "task-attempt.png"))
        all_prefix = os.path.commonprefix(self.file_list)
        if not os.path.exists(all_prefix):
            all_prefix = os.path.dirname(all_prefix)
        for file_num, file_path in enumerate(self.file_list):
            widget = QTreeWidgetItem(self.file_list_widget)
            widget.setText(0, os.path.relpath(file_path, all_prefix))
            if not os.path.exists(file_path):
                widget.setIcon(0, bad_icon)
                widget.setToolTip(0, "File do not exists")
                sub_widget = QTreeWidgetItem(widget)
                sub_widget.setText(0, "File do not exists")
                continue
            for mask_num, mask_mapper in enumerate(self.mask_mapper_list):
                if mask_mapper.is_ready():
                    mask_path = mask_mapper.get_mask_path(file_path)
                    exist = os.path.exists(mask_path)
                    if exist:
                        sub_widget = QTreeWidgetItem(widget)
                        sub_widget.setText(
                            0, "Mask {} ok".format(mask_mapper.name))
                        sub_widget.setIcon(0, ok_icon)
                        self.state_list[file_num, mask_num] = 0
                    else:
                        sub_widget = QTreeWidgetItem(widget)
                        sub_widget.setText(
                            0,
                            "Mask {} do not exists (path: {})".format(
                                mask_mapper.name,
                                os.path.relpath(mask_path, all_prefix)),
                        )
                        sub_widget.setIcon(0, bad_icon)
                        self.state_list[file_num, mask_num] = 2
                else:
                    sub_widget = QTreeWidgetItem(widget)
                    sub_widget.setText(
                        0, "Mask {} unknown".format(mask_mapper.name))
                    sub_widget.setIcon(0, warn_icon)
                    self.state_list[file_num, mask_num] = 1
            if self.state_list.shape[1] == 0:
                state = 0
            else:
                state = self.state_list[file_num].max()

            if state == 0:
                widget.setIcon(0, ok_icon)
            elif state == 1:
                widget.setIcon(0, warn_icon)
            else:
                widget.setIcon(0, bad_icon)