Пример #1
0
    def setup_starting_area_elements(self):
        game_description = default_prime2_game_description()
        world_to_group = {}
        self._starting_location_for_area = {}

        for row, world in enumerate(game_description.world_list.worlds):
            for column, is_dark_world in enumerate([False, True]):
                group_box = QGroupBox(self.starting_locations_contents)
                group_box.setTitle(world.correct_name(is_dark_world))
                vertical_layout = QVBoxLayout(group_box)
                vertical_layout.setContentsMargins(8, 4, 8, 4)
                vertical_layout.setSpacing(2)
                vertical_layout.setAlignment(QtCore.Qt.AlignTop)
                group_box.vertical_layout = vertical_layout

                world_to_group[world.correct_name(is_dark_world)] = group_box
                self.starting_locations_layout.addWidget(group_box, row, column)

        for world in game_description.world_list.worlds:
            for area in sorted(world.areas, key=lambda a: a.name):
                group_box = world_to_group[world.correct_name(area.in_dark_aether)]
                check = QtWidgets.QCheckBox(group_box)
                check.setText(area.name)
                check.area_location = AreaLocation(world.world_asset_id, area.area_asset_id)
                check.stateChanged.connect(functools.partial(self._on_check_starting_area, check))
                group_box.vertical_layout.addWidget(check)
                self._starting_location_for_area[area.area_asset_id] = check

        self.starting_area_quick_fill_ship.clicked.connect(self._starting_location_on_select_ship)
        self.starting_area_quick_fill_save_station.clicked.connect(self._starting_location_on_select_save_station)
Пример #2
0
    def setup_location_pool_elements(self):
        self.randomization_mode_combo.setItemData(0, RandomizationMode.FULL)
        self.randomization_mode_combo.setItemData(
            1, RandomizationMode.MAJOR_MINOR_SPLIT)
        self.randomization_mode_combo.currentIndexChanged.connect(
            self._on_update_randomization_mode)

        game_description = default_prime2_game_description()
        world_to_group = {}
        self._location_pool_for_node = {}

        for world in game_description.world_list.worlds:
            for is_dark_world in [False, True]:
                group_box = QGroupBox(self.excluded_locations_area_contents)
                group_box.setTitle(world.correct_name(is_dark_world))
                vertical_layout = QVBoxLayout(group_box)
                vertical_layout.setContentsMargins(8, 4, 8, 4)
                vertical_layout.setSpacing(2)
                group_box.vertical_layout = vertical_layout

                world_to_group[world.correct_name(is_dark_world)] = group_box
                self.excluded_locations_area_layout.addWidget(group_box)

        for world, area, node in game_description.world_list.all_worlds_areas_nodes:
            if not isinstance(node, PickupNode):
                continue

            group_box = world_to_group[world.correct_name(area.in_dark_aether)]
            check = QtWidgets.QCheckBox(group_box)
            check.setText(game_description.world_list.node_name(node))
            check.node = node
            check.stateChanged.connect(
                functools.partial(self._on_check_location, check))
            group_box.vertical_layout.addWidget(check)
            self._location_pool_for_node[node] = check
Пример #3
0
    def setup_location_pool_elements(self):
        self.randomization_mode_combo.setItemData(0, RandomizationMode.FULL)
        self.randomization_mode_combo.setItemData(
            1, RandomizationMode.MAJOR_MINOR_SPLIT)
        self.randomization_mode_combo.currentIndexChanged.connect(
            self._on_update_randomization_mode)

        vertical_layouts = [
            QtWidgets.QVBoxLayout(self.excluded_locations_area_contents),
            QtWidgets.QVBoxLayout(self.excluded_locations_area_contents),
        ]
        for layout in vertical_layouts:
            self.excluded_locations_area_layout.addLayout(layout)

        world_list = self.game_description.world_list
        self._location_pool_for_node = {}

        nodes_by_world = collections.defaultdict(list)
        node_names = {}
        pickup_match = re.compile(r"Pickup \(([^\)]+)\)")

        for world in world_list.worlds:
            for is_dark_world in dark_world_flags(world):
                for area in world.areas:
                    if area.in_dark_aether != is_dark_world:
                        continue
                    for node in area.nodes:
                        if isinstance(node, PickupNode):
                            nodes_by_world[world.correct_name(
                                is_dark_world)].append(node)
                            match = pickup_match.match(node.name)
                            if match is not None:
                                node_name = match.group(1)
                            else:
                                node_name = node.name
                            node_names[
                                node] = f"{world_list.nodes_to_area(node).name} ({node_name})"

        for i, world_name in enumerate(sorted(nodes_by_world.keys())):
            group_box = QGroupBox(self.excluded_locations_area_contents)
            group_box.setTitle(world_name)
            vertical_layout = QVBoxLayout(group_box)
            vertical_layout.setContentsMargins(8, 4, 8, 4)
            vertical_layout.setSpacing(2)
            group_box.vertical_layout = vertical_layout
            vertical_layouts[i % len(vertical_layouts)].addWidget(group_box)

            for node in sorted(nodes_by_world[world_name], key=node_names.get):
                check = QtWidgets.QCheckBox(group_box)
                check.setText(node_names[node])
                check.node = node
                check.stateChanged.connect(
                    functools.partial(self._on_check_location, check))
                group_box.vertical_layout.addWidget(check)
                self._location_pool_for_node[node] = check

        for layout in vertical_layouts:
            layout.addSpacerItem(
                QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum,
                                      QtWidgets.QSizePolicy.Expanding))
Пример #4
0
    def _add_widget_for_requirement_array(self, requirement: Requirement):
        parents = [(self.parent, self.grid_layout)]
        self.grid_layout.setAlignment(Qt.AlignTop)

        next_title = ""

        current_depth = 0
        for depth, text in data_writer.pretty_print_requirement(requirement):
            if depth > current_depth:
                group_box = QGroupBox(parents[current_depth][0])
                group_box.setTitle(next_title)
                self._elements.append(group_box)
                vertical_layout = QVBoxLayout(group_box)
                vertical_layout.setAlignment(Qt.AlignTop)
                parents[current_depth][1].addWidget(group_box)
                parents.append((group_box, vertical_layout))

            elif depth < current_depth:
                parents.pop()

            current_depth = depth
            if "of the following" in text:
                next_title = text
            else:
                label = QLabel(parents[current_depth][0])
                label.setText(text)
                self._elements.append(label)
                parents[current_depth][1].addWidget(label)
Пример #5
0
    def __init__(self, parent, level_ref: LevelRef):
        title = f"Palette Groups for Object Set {level_ref.level.object_set_number}"

        super(PaletteViewer, self).__init__(parent, title=title)

        self.level_ref = level_ref

        layout = QGridLayout(self)

        for palette_group in range(PALETTE_GROUPS_PER_OBJECT_SET):
            group_box = QGroupBox()
            group_box.setTitle(f"Palette Group {palette_group}")

            group_box_layout = QVBoxLayout(group_box)
            group_box_layout.setSpacing(0)

            palette = load_palette_group(
                self.level_ref.level.object_set_number, palette_group)

            for palette_no in range(PALETTES_PER_PALETTES_GROUP):
                group_box_layout.addWidget(PaletteWidget(palette, palette_no))

            row = palette_group // self.palettes_per_row
            col = palette_group % self.palettes_per_row

            layout.addWidget(group_box, row, col)
Пример #6
0
    def _create_pickup_spoilers(self, game_description: GameDescription):
        if game_description == self._pickup_spoiler_current_game:
            return

        for groups in self._pickup_spoiler_world_to_group.values():
            groups.deleteLater()

        self._pickup_spoiler_current_game = game_description
        self.pickup_spoiler_show_all_button.currently_show_all = True
        self.pickup_spoiler_buttons.clear()

        self._pickup_spoiler_world_to_group = {}
        nodes_in_world = collections.defaultdict(list)

        for world, area, node in game_description.world_list.all_worlds_areas_nodes:
            if isinstance(node, PickupNode):
                world_name = world.correct_name(area.in_dark_aether)
                nodes_in_world[world_name].append(
                    (f"{area.name} - {node.name}", node.pickup_index))
                continue

        for world_name in sorted(nodes_in_world.keys()):
            group_box = QGroupBox(self.pickup_spoiler_scroll_contents)
            group_box.setTitle(world_name)
            vertical_layout = QVBoxLayout(group_box)
            vertical_layout.setContentsMargins(8, 4, 8, 4)
            vertical_layout.setSpacing(2)
            group_box.vertical_layout = vertical_layout

            vertical_layout.horizontal_layouts = []
            self._pickup_spoiler_world_to_group[world_name] = group_box
            self.pickup_spoiler_scroll_content_layout.addWidget(group_box)

            for area_name, pickup_index in sorted(nodes_in_world[world_name],
                                                  key=lambda it: it[0]):
                horizontal_layout = QHBoxLayout()
                horizontal_layout.setSpacing(2)

                label = QLabel(group_box)
                label.setText(area_name)
                horizontal_layout.addWidget(label)
                horizontal_layout.label = label

                push_button = QPushButton(group_box)
                push_button.setFlat(True)
                push_button.setText("Hidden")
                push_button.item_is_hidden = True
                push_button.pickup_index = pickup_index
                push_button.clicked.connect(
                    partial(self._toggle_pickup_spoiler, push_button))
                push_button.item_name = "Nothing was Set, ohno"
                push_button.row = horizontal_layout
                horizontal_layout.addWidget(push_button)
                horizontal_layout.button = push_button
                self.pickup_spoiler_buttons.append(push_button)

                group_box.vertical_layout.addLayout(horizontal_layout)
                group_box.vertical_layout.horizontal_layouts.append(
                    horizontal_layout)
Пример #7
0
class Ui_dlgAddUser(QDialog):
    def __init__(self):
        super().__init__()
        self.setupUi()

    def setupUi(self):
        self.setObjectName("dlgAddUser")
        self.resize(335, 154)
        self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint)
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QGroupBox(self)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout = QVBoxLayout(self.groupBox)
        self.verticalLayout.setObjectName("verticalLayout")
        self.leFullName = QLineEdit(self.groupBox)
        self.leFullName.setObjectName("leFullName")
        self.verticalLayout.addWidget(self.leFullName)
        self.leUsuario = QLineEdit(self.groupBox)
        self.leUsuario.setObjectName("leUsuario")
        self.verticalLayout.addWidget(self.leUsuario)
        self.lePassword = QLineEdit(self.groupBox)
        self.lePassword.setObjectName("lePassword")
        self.lePassword.setEchoMode(QLineEdit.Password)
        self.verticalLayout.addWidget(self.lePassword)
        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.pbAddUser = QPushButton(self)
        self.pbAddUser.setObjectName("pbAddUser")
        self.horizontalLayout.addWidget(self.pbAddUser)
        self.pbCancel = QPushButton(self)
        self.pbCancel.setObjectName("pbCancel")
        self.horizontalLayout.addWidget(self.pbCancel)
        self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)

        self.retranslateUi()
        QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle(
            QApplication.translate("dlgAddUser", "Dialog", None, -1))
        self.groupBox.setTitle(
            QApplication.translate("dlgAddUser", "GroupBox", None, -1))
        self.leFullName.setPlaceholderText(
            QApplication.translate("dlgAddUser", "Ingresar nombre completo",
                                   None, -1))
        self.leUsuario.setPlaceholderText(
            QApplication.translate("dlgAddUser", "Ingrese nombre de usuario",
                                   None, -1))
        self.lePassword.setPlaceholderText(
            QApplication.translate("dlgAddUser", "Ingrese su clave", None, -1))
        self.pbAddUser.setText(
            QApplication.translate("dlgAddUser", "Add user", None, -1))
        self.pbCancel.setText(
            QApplication.translate("dlgAddUser", "Cancel", None, -1))
Пример #8
0
    def _create_pickup_spoilers(self):
        self.pickup_spoiler_show_all_button.clicked.connect(
            self._toggle_show_all_pickup_spoiler)
        self.pickup_spoiler_show_all_button.currently_show_all = True

        self._create_pickup_spoiler_combobox()

        game_description = default_prime2_game_description()
        world_to_group = {}

        for world in game_description.world_list.worlds:
            for is_dark_world in [False, True]:
                group_box = QGroupBox(self.pickup_spoiler_scroll_contents)
                group_box.setTitle(world.correct_name(is_dark_world))
                vertical_layout = QVBoxLayout(group_box)
                vertical_layout.setContentsMargins(8, 4, 8, 4)
                vertical_layout.setSpacing(2)
                group_box.vertical_layout = vertical_layout

                vertical_layout.horizontal_layouts = []
                world_to_group[world.correct_name(is_dark_world)] = group_box
                self.pickup_spoiler_scroll_content_layout.addWidget(group_box)

        for world, area, node in game_description.world_list.all_worlds_areas_nodes:
            if not isinstance(node, PickupNode):
                continue

            group_box = world_to_group[world.correct_name(area.in_dark_aether)]
            horizontal_layout = QHBoxLayout()
            horizontal_layout.setSpacing(2)

            label = QLabel(group_box)
            label.setText(game_description.world_list.node_name(node))
            horizontal_layout.addWidget(label)
            horizontal_layout.label = label

            push_button = QPushButton(group_box)
            push_button.setFlat(True)
            push_button.setText("Hidden")
            push_button.item_is_hidden = True
            push_button.pickup_index = node.pickup_index
            push_button.clicked.connect(
                partial(self._toggle_pickup_spoiler, push_button))
            push_button.item_name = "Nothing was Set, ohno"
            push_button.row = horizontal_layout
            horizontal_layout.addWidget(push_button)
            horizontal_layout.button = push_button
            self.pickup_spoiler_buttons.append(push_button)

            group_box.vertical_layout.addLayout(horizontal_layout)
            group_box.vertical_layout.horizontal_layouts.append(
                horizontal_layout)
Пример #9
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.thread_pool = QThreadPool()
        self.thread_pool.setMaxThreadCount(1)
        self.active_thread_count = 0

    def init_ui(self):
        self.setWindowTitle('Thread Example 2')
        self.setFixedSize(800, 400)
        self.group_box_1 = QGroupBox(self)
        self.group_box_1.setTitle('GroupBox Test Thread')
        self.group_box_1.resize(350, 275)
        self.button_start = QPushButton('Start', self.group_box_1)
        self.button_stop = QPushButton('Stop', self.group_box_1)
        self.button_start.move(0, 30)
        self.button_stop.move(90, 30)
        self.show()

        self.button_start.clicked.connect(self.on_button_start_click)
        self.button_stop.clicked.connect(self.on_button_stop_click)

    def on_button_start_click(self):
        self.button_start.setEnabled(False)
        self.active_thread_count = 0
        links = [
            'google.com', 'youtube.com', 'instagram.com', 'twitter.com',
            'netflix.com'
        ]
        self.threads = []
        for link in links:
            self.thread = MyThread(link)
            self.thread.signals.finished.connect(self.on_finish)
            self.threads.append(self.thread)

        for thread in self.threads:
            self.thread_pool.start(thread)
            self.active_thread_count += 1

    def on_button_stop_click(self):
        print('Threads stopping...')
        self.button_start.setEnabled(False)
        self.thread_pool.clear()
        self.active_thread_count = self.thread_pool.activeThreadCount()

    def on_finish(self):
        self.active_thread_count -= 1
        if self.active_thread_count == 0:
            print('Finished All Jobs')
            self.button_start.setEnabled(True)
Пример #10
0
def load(parent):
    global plugin_widget, main_window, ui
    main_window = parent
    plugin_widget = QGroupBox()
    plugin_widget.setTitle('')
    ui = Ui_GroupBox()
    ui.setupUi(plugin_widget)
    ui.checkBox_asp_asn.clicked.connect(show_motifs)
    ui.checkBox_glu_his.clicked.connect(show_motifs)
    ui.checkBox_his_his.clicked.connect(show_motifs)
    ui.checkBox_ser_backbone.clicked.connect(show_motifs)
    ui.checkBox_asp_backbone.clicked.connect(show_motifs)
    ui.checkBox_his_ser.clicked.connect(show_motifs)
    ui.checkBox_asp_ser.clicked.connect(show_motifs)
Пример #11
0
def load(parent):
    global plugin_widget, main_window, ui
    main_window = parent
    plugin_widget = QGroupBox()
    plugin_widget.setTitle('')
    ui = Ui_GroupBox()
    ui.setupUi(plugin_widget)
    ui.pushButton_plot_occupancy.clicked.connect(plot_occupancy)
    ui.pushButton_save_occupancy.clicked.connect(save_occupancy)
    ui.pushButton_plot_jo.clicked.connect(plot_jo)
    ui.pushButton_save_jo.clicked.connect(save_jo)
    ui.pushButton_plot_timeseries.clicked.connect(plot_timeseries)
    ui.pushButton_save_timeseries.clicked.connect(save_timeseries)
    ui.checkBox_color_segments_occupancy.clicked.connect(toggle_stacked)
Пример #12
0
def load(parent):
    global plugin_widget, main_window, ui
    main_window = parent
    plugin_widget = QGroupBox()
    plugin_widget.setTitle('')
    ui = Ui_GroupBox()
    ui.setupUi(plugin_widget)
    ui.pushButton_degree_plot.clicked.connect(plot_centrality)
    ui.pushButton_degree_save.clicked.connect(save_centrality)
    ui.groupBox_per_residue.toggled.connect(toggle_histogram)
    ui.groupBox_histogram.toggled.connect(toggle_per_residue)
    ui.checkBox_normalized.toggled.connect(update_min_max)
    ui.checkBox_averaged_frames.toggled.connect(update_min_max)
    ui.radioButton_degree.toggled.connect(update_min_max)
    ui.radioButton_betweenness.toggled.connect(update_min_max)
Пример #13
0
class UiMainWindow:

    def __init__(self, window: QMainWindow, vscreen: VScreen):
        self.window = window
        self.vscreen = vscreen

        window.setWindowFlags(Qt.Window
                              | Qt.MSWindowsFixedSizeDialogHint
                              | Qt.WindowMinimizeButtonHint
                              | Qt.WindowCloseButtonHint
                              | Qt.CustomizeWindowHint)

        self.centralWidget = QWidget()
        self.centralWidget.setLayout(QVBoxLayout())
        self.centralWidget.layout().setContentsMargins(0, 0, 0, 0)
        window.setCentralWidget(self.centralWidget)

        self.monitor_overview_widget = VScreenOverview(vscreen, window)
        self.centralWidget.layout().addWidget(self.monitor_overview_widget)

        self.sub_widget = QWidget()
        self.sub_layout = QVBoxLayout()
        self.sub_widget.setLayout(self.sub_layout)
        self.centralWidget.layout().addWidget(self.sub_widget)

        self.monitor_info_group = QGroupBox()
        self.monitor_info_group.setLayout(QHBoxLayout())

        for monitor in self.vscreen.monitor_order:
            info_box = QGroupBox("Monitor Information")
            info_box.ui = UiMonitorInfoBox(info_box, monitor)
            self.monitor_info_group.layout().addWidget(info_box)
        self.sub_layout.addWidget(self.monitor_info_group)

        self.button_group = QDialogButtonBox(Qt.Horizontal)
        self.button_group.setStyleSheet('* { button-layout: 2 }')
        self.close_button = self.button_group.addButton("Close", QDialogButtonBox.RejectRole)
        self.adjust_button = self.button_group.addButton("Adjust", QDialogButtonBox.ActionRole)
        self.about_button = self.button_group.addButton("About", QDialogButtonBox.HelpRole)
        self.sub_layout.addWidget(self.button_group)

        self.translate_ui()

    def translate_ui(self):
        self.window.setWindowTitle("HwMonitorAlignment")
        self.monitor_info_group.setTitle("Monitor Setup Information")
        self.close_button.setText("Close")
        self.adjust_button.setText("Adjust")
Пример #14
0
    def _create_categories_boxes(self, item_database: ItemDatabase, size_policy):
        self._boxes_for_category = {}

        categories = set()
        for major_item in item_database.major_items.values():
            if not major_item.required:
                categories.add(major_item.item_category)

        all_categories = list(iterate_enum(ItemCategory))
        for major_item_category in sorted(categories, key=lambda it: all_categories.index(it)):
            category_box = QGroupBox(self.scroll_area_contents)
            category_box.setTitle(major_item_category.long_name)
            category_box.setSizePolicy(size_policy)
            category_box.setObjectName(f"category_box {major_item_category}")

            category_layout = QGridLayout(category_box)
            category_layout.setObjectName(f"category_layout {major_item_category}")

            self.item_pool_layout.addWidget(category_box)
            self._boxes_for_category[major_item_category] = category_box, category_layout, {}
Пример #15
0
    def _init_widgets(self):

        # status
        status_box = QGroupBox(self)
        status_box.setTitle("Status")

        self._status_table = QStatusTable(self._controller)
        self._status_table.status = "ready"

        status_layout = QVBoxLayout()
        status_layout.addWidget(self._status_table)

        status_box.setLayout(status_layout)

        # table

        self._team_table = QTeamTable(self._controller)
        team_box = QGroupBox(self)
        team_box.setTitle("Team")

        # operations

        # pull function button
        pullfunc_btn = QPushButton(self)
        pullfunc_btn.setText("Pull func")
        pullfunc_btn.setToolTip("Pull current function from the selected user")
        pullfunc_btn.clicked.connect(self._on_pullfunc_clicked)

        # push function button
        pushfunc_btn = QPushButton()
        pushfunc_btn.setText('Push func')
        pushfunc_btn.setToolTip("Push current function to the repo")
        pushfunc_btn.clicked.connect(self._on_pushfunc_clicked)

        # pull patches button
        pullpatches_btn = QPushButton(self)
        pullpatches_btn.setText("Pull patches")
        pullpatches_btn.setToolTip("Pull all patches from the selected user")
        pullpatches_btn.clicked.connect(self._on_pullpatches_clicked)

        actions_box = QGroupBox(self)
        actions_box.setTitle("Actions")
        actions_layout = QHBoxLayout()
        actions_layout.addWidget(pullfunc_btn)
        actions_layout.addWidget(pushfunc_btn)
        actions_layout.addWidget(pullpatches_btn)
        actions_box.setLayout(actions_layout)

        team_layout = QVBoxLayout()
        team_layout.addWidget(self._team_table)
        team_layout.addWidget(actions_box)
        team_box.setLayout(team_layout)

        main_layout = QVBoxLayout()
        main_layout.addWidget(status_box)
        main_layout.addWidget(team_box)

        self.setLayout(main_layout)
Пример #16
0
    def _add_widget_for_requirement_array(self, requirement: Requirement):
        self.grid_layout.setAlignment(Qt.AlignTop)

        parents: List[Tuple[QGroupBox, QVBoxLayout]] = [(self.parent, self.grid_layout)]

        for depth, text in randovania.game_description.pretty_print.pretty_print_requirement(requirement):
            if "of the following" in text:
                parent = parents[depth]
                group_box = QGroupBox(parent[0])
                group_box.setContentsMargins(8, 0, 2, 6)
                group_box.setTitle(text)
                self._elements.append(group_box)
                vertical_layout = QVBoxLayout(group_box)
                vertical_layout.setAlignment(Qt.AlignTop)
                parent[1].addWidget(group_box)
                if len(parents) <= depth + 1:
                    parents.append(None)
                parents[depth + 1] = (group_box, vertical_layout)
            else:
                label = QLabel(parents[depth][0])
                label.setText(text)
                self._elements.append(label)
                parents[depth][1].addWidget(label)
Пример #17
0
class SaveDialog(QDialog):
    def __init__(self, main_window, nodes_dict: dict, last_export_dir: str):
        super(SaveDialog, self).__init__(parent=main_window)

        self.create_UI()

        self.main_window = main_window
        self.nodes = nodes_dict
        self.export_nodes = []
        self.nodes_check_box_list = []
        self.export_dir = last_export_dir
        self.package_name = ''
        self.set_package_name(self.export_dir)

        # add node-checkboxes
        node_keys = list(self.nodes.keys())
        nodes_list_widget = self.nodes_scroll_area.takeWidget()
        for i in range(len(node_keys)):
            n = node_keys[i]
            node_check_box = QCheckBox(n.title)
            node_check_box.setObjectName('node_check_box_' + str(i))
            node_check_box.setChecked(self.nodes[n])
            nodes_list_widget.layout().addWidget(node_check_box)
            self.nodes_check_box_list.append(node_check_box)
        nodes_list_widget.adjustSize()
        self.nodes_scroll_area.setWidget(nodes_list_widget)

    def create_UI(self):

        # main layouts and widgets
        self.main_vertical_layout = QVBoxLayout(self)
        self.horizontal_layout = QHBoxLayout(self)
        self.nodes_vertical_layout = QVBoxLayout(self)
        self.nodes_vertical_layout.setAlignment(Qt.AlignTop)
        self.export_widget = QWidget(self)
        self.export_widget.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)
        self.export_layout = QVBoxLayout(self)
        self.export_layout.setAlignment(Qt.AlignTop)
        self.export_widget.setLayout(self.export_layout)

        # nodes selection section
        self.nodes_group_box = QGroupBox(self)

        self.nodes_group_box.setLayout(QVBoxLayout(self))
        self.nodes_group_box.setTitle('Select nodes to export')

        self.nodes_scroll_area = QScrollArea(self)
        self.nodes_list_widget = QWidget()
        self.nodes_list_widget.setLayout(self.nodes_vertical_layout)

        select_all_button = QPushButton('select all')
        select_all_button.clicked.connect(self.select_all)
        deselect_all_button = QPushButton('deselect all')
        deselect_all_button.clicked.connect(self.deselect_all)
        self.nodes_vertical_layout.addWidget(select_all_button)
        self.nodes_vertical_layout.addWidget(deselect_all_button)

        self.nodes_scroll_area.setWidget(self.nodes_list_widget)
        self.nodes_group_box.layout().addWidget(self.nodes_scroll_area)

        # export settings section
        self.select_package_dir_button = QPushButton('Select package dir',
                                                     self)
        self.select_package_dir_button.clicked.connect(self.select_package_dir)

        self.package_dir_label = QLabel()

        self.export_button = QPushButton('export', self)
        self.export_button.clicked.connect(self.export)

        self.export_layout.addWidget(self.select_package_dir_button)
        self.export_layout.addWidget(self.package_dir_label)
        self.export_layout.addWidget(self.export_button)

        # button box
        self.button_box = QDialogButtonBox(self)
        self.button_box.setStandardButtons(QDialogButtonBox.Ok)
        self.button_box.button(QDialogButtonBox.Ok).clicked.connect(
            self.close_)

        # merge layouts
        self.horizontal_layout.addWidget(self.nodes_group_box)
        self.horizontal_layout.addWidget(self.export_widget)
        self.main_vertical_layout.addLayout(self.horizontal_layout)
        self.main_vertical_layout.addWidget(self.button_box)

        self.setWindowTitle('Export Nodes')
        self.resize(500, 300)

    def select_all(self):
        for cb in self.nodes_check_box_list:
            cb.setChecked(True)

    def deselect_all(self):
        for cb in self.nodes_check_box_list:
            cb.setChecked(False)

    def select_package_dir(self):
        self.export_dir = QFileDialog.getExistingDirectory(
            self,
            'Select the package folder where your nodes shall be exported at',
            '../packages')
        self.set_package_name(self.export_dir)

    def set_package_name(self, path: str):
        self.package_name = os.path.basename(path)
        self.package_dir_label.setText('package dir: ' + path)

    def get_selected_nodes(self):
        nodes = []
        node_keys = list(self.nodes.keys())
        for i in range(len(self.nodes_check_box_list)):
            check_box: QCheckBox = self.nodes_check_box_list[i]
            if check_box.isChecked():
                nodes.append(node_keys[int(check_box.objectName()[15:])])

        return nodes

    def export(self):
        self.export_nodes = self.get_selected_nodes()

        nodes_dict = {}
        module_name_separator = '___'

        nodes_list = []
        node_titles_count = {}  # title (str) : number (int)
        for i in range(len(self.export_nodes)):
            n: Node = self.export_nodes[i]

            c_w: NodeContentWidget = n.content_widget

            node_number = 0
            title = c_w.get_node_title()
            if title in node_titles_count.values():
                node_number = node_titles_count[title]  # index
                node_titles_count[title] += 1
            else:
                node_titles_count[title] = 1

            node_data = c_w.get_json_data(
                package_name=self.package_name,
                module_name_separator=module_name_separator,
                number=node_number)

            nodes_list.append(node_data)

        nodes_dict['nodes'] = nodes_list

        info_dict = {'type': 'Ryven nodes package'}

        whole_dict = {
            **info_dict,
            **nodes_dict
        }  # merges single two dictionaries to one

        json_data = json.dumps(whole_dict)
        print(json_data)

        # create dirs and save files
        if not os.path.isdir(self.export_dir + '/nodes'):
            os.mkdir(self.export_dir + '/nodes')

        save_file(self.export_dir + '/' + self.package_name + '.rpc',
                  json_data)

        for i in range(len(self.export_nodes)):
            n = self.export_nodes[i]
            module_name = nodes_list[i]['module name']

            # create node folder
            node_dir = self.export_dir + '/nodes/' + module_name
            if not os.path.isdir(node_dir):
                os.mkdir(node_dir)

            # create widgets folder
            widgets_dir = node_dir + '/widgets'
            if not os.path.isdir(widgets_dir):
                os.mkdir(widgets_dir)

            n.content_widget.save_metacode_files(
                node_dir=node_dir,
                widgets_dir=widgets_dir,
                module_name_separator=module_name_separator,
                module_name=module_name)

    def close_(self):
        self.main_window.last_exported_nodes = self.get_selected_nodes()
        self.main_window.last_export_path = self.export_dir
        self.close()
Пример #18
0
class Ui_GroupBox(object):
    def setupUi(self, GroupBox):
        if not GroupBox.objectName():
            GroupBox.setObjectName(u"GroupBox")
        GroupBox.resize(528, 576)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(GroupBox.sizePolicy().hasHeightForWidth())
        GroupBox.setSizePolicy(sizePolicy)
        self.verticalLayout_2 = QVBoxLayout(GroupBox)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.groupBox = QGroupBox(GroupBox)
        self.groupBox.setObjectName(u"groupBox")
        self.verticalLayout_4 = QVBoxLayout(self.groupBox)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
        self.horizontalLayout_7 = QHBoxLayout()
        self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
        self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_7.addItem(self.horizontalSpacer_7)

        self.pushButton_degree_save = QPushButton(self.groupBox)
        self.pushButton_degree_save.setObjectName(u"pushButton_degree_save")

        self.horizontalLayout_7.addWidget(self.pushButton_degree_save)

        self.verticalLayout_4.addLayout(self.horizontalLayout_7)

        self.verticalLayout_2.addWidget(self.groupBox)

        self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                            QSizePolicy.Expanding)

        self.verticalLayout_2.addItem(self.verticalSpacer_2)

        self.groupBox_degree = QGroupBox(GroupBox)
        self.groupBox_degree.setObjectName(u"groupBox_degree")
        self.verticalLayout_3 = QVBoxLayout(self.groupBox_degree)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.radioButton_betweenness = QRadioButton(self.groupBox_degree)
        self.radioButton_betweenness.setObjectName(u"radioButton_betweenness")

        self.horizontalLayout_2.addWidget(self.radioButton_betweenness)

        self.radioButton_degree = QRadioButton(self.groupBox_degree)
        self.radioButton_degree.setObjectName(u"radioButton_degree")
        self.radioButton_degree.setChecked(True)

        self.horizontalLayout_2.addWidget(self.radioButton_degree)

        self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_2.addItem(self.horizontalSpacer_5)

        self.verticalLayout_3.addLayout(self.horizontalLayout_2)

        self.checkBox_averaged_frames = QCheckBox(self.groupBox_degree)
        self.checkBox_averaged_frames.setObjectName(
            u"checkBox_averaged_frames")
        self.checkBox_averaged_frames.setChecked(True)

        self.verticalLayout_3.addWidget(self.checkBox_averaged_frames)

        self.checkBox_normalized = QCheckBox(self.groupBox_degree)
        self.checkBox_normalized.setObjectName(u"checkBox_normalized")

        self.verticalLayout_3.addWidget(self.checkBox_normalized)

        self.groupBox_per_residue = QGroupBox(self.groupBox_degree)
        self.groupBox_per_residue.setObjectName(u"groupBox_per_residue")
        self.groupBox_per_residue.setCheckable(True)
        self.verticalLayout = QVBoxLayout(self.groupBox_per_residue)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.horizontalLayout_6 = QHBoxLayout()
        self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
        self.label_2 = QLabel(self.groupBox_per_residue)
        self.label_2.setObjectName(u"label_2")

        self.horizontalLayout_6.addWidget(self.label_2)

        self.comboBox = QComboBox(self.groupBox_per_residue)
        self.comboBox.setObjectName(u"comboBox")

        self.horizontalLayout_6.addWidget(self.comboBox)

        self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_6.addItem(self.horizontalSpacer_2)

        self.verticalLayout.addLayout(self.horizontalLayout_6)

        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.label_10 = QLabel(self.groupBox_per_residue)
        self.label_10.setObjectName(u"label_10")
        self.label_10.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout.addWidget(self.label_10)

        self.lineEdit_degree_residue_ids = QLineEdit(self.groupBox_per_residue)
        self.lineEdit_degree_residue_ids.setObjectName(
            u"lineEdit_degree_residue_ids")

        self.horizontalLayout.addWidget(self.lineEdit_degree_residue_ids)

        self.horizontalSpacer_6 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer_6)

        self.verticalLayout.addLayout(self.horizontalLayout)

        self.verticalLayout_3.addWidget(self.groupBox_per_residue)

        self.groupBox_histogram = QGroupBox(self.groupBox_degree)
        self.groupBox_histogram.setObjectName(u"groupBox_histogram")
        self.groupBox_histogram.setCheckable(True)
        self.groupBox_histogram.setChecked(False)
        self.verticalLayout_5 = QVBoxLayout(self.groupBox_histogram)
        self.verticalLayout_5.setObjectName(u"verticalLayout_5")
        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
        self.label_56 = QLabel(self.groupBox_histogram)
        self.label_56.setObjectName(u"label_56")
        self.label_56.setMaximumSize(QSize(16777215, 16777215))
        self.label_56.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout_3.addWidget(self.label_56)

        self.lineEdit_bins = QLineEdit(self.groupBox_histogram)
        self.lineEdit_bins.setObjectName(u"lineEdit_bins")
        self.lineEdit_bins.setMinimumSize(QSize(50, 0))
        self.lineEdit_bins.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout_3.addWidget(self.lineEdit_bins)

        self.label_55 = QLabel(self.groupBox_histogram)
        self.label_55.setObjectName(u"label_55")
        self.label_55.setMaximumSize(QSize(16777215, 16777215))
        self.label_55.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout_3.addWidget(self.label_55)

        self.lineEdit_minimum = QLineEdit(self.groupBox_histogram)
        self.lineEdit_minimum.setObjectName(u"lineEdit_minimum")
        self.lineEdit_minimum.setMinimumSize(QSize(50, 0))
        self.lineEdit_minimum.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout_3.addWidget(self.lineEdit_minimum)

        self.label_17 = QLabel(self.groupBox_histogram)
        self.label_17.setObjectName(u"label_17")
        self.label_17.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout_3.addWidget(self.label_17)

        self.lineEdit_maximum = QLineEdit(self.groupBox_histogram)
        self.lineEdit_maximum.setObjectName(u"lineEdit_maximum")
        self.lineEdit_maximum.setMinimumSize(QSize(50, 0))
        self.lineEdit_maximum.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout_3.addWidget(self.lineEdit_maximum)

        self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_3.addItem(self.horizontalSpacer_3)

        self.verticalLayout_5.addLayout(self.horizontalLayout_3)

        self.horizontalLayout_8 = QHBoxLayout()
        self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
        self.checkBox_cumulative_histogram = QCheckBox(self.groupBox_histogram)
        self.checkBox_cumulative_histogram.setObjectName(
            u"checkBox_cumulative_histogram")

        self.horizontalLayout_8.addWidget(self.checkBox_cumulative_histogram)

        self.horizontalSpacer_12 = QSpacerItem(40, 20, QSizePolicy.Fixed,
                                               QSizePolicy.Minimum)

        self.horizontalLayout_8.addItem(self.horizontalSpacer_12)

        self.checkBox_stacked_histogram = QCheckBox(self.groupBox_histogram)
        self.checkBox_stacked_histogram.setObjectName(
            u"checkBox_stacked_histogram")

        self.horizontalLayout_8.addWidget(self.checkBox_stacked_histogram)

        self.horizontalSpacer_11 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                               QSizePolicy.Minimum)

        self.horizontalLayout_8.addItem(self.horizontalSpacer_11)

        self.verticalLayout_5.addLayout(self.horizontalLayout_8)

        self.horizontalLayout_9 = QHBoxLayout()
        self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
        self.checkBox_color_segments_occupancy = QCheckBox(
            self.groupBox_histogram)
        self.checkBox_color_segments_occupancy.setObjectName(
            u"checkBox_color_segments_occupancy")
        self.checkBox_color_segments_occupancy.setChecked(True)

        self.horizontalLayout_9.addWidget(
            self.checkBox_color_segments_occupancy)

        self.horizontalSpacer_9 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_9.addItem(self.horizontalSpacer_9)

        self.verticalLayout_5.addLayout(self.horizontalLayout_9)

        self.verticalLayout_3.addWidget(self.groupBox_histogram)

        self.horizontalLayout_5 = QHBoxLayout()
        self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
        self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                            QSizePolicy.Minimum)

        self.horizontalLayout_5.addItem(self.horizontalSpacer)

        self.pushButton_degree_plot = QPushButton(self.groupBox_degree)
        self.pushButton_degree_plot.setObjectName(u"pushButton_degree_plot")
        self.pushButton_degree_plot.setAutoDefault(False)

        self.horizontalLayout_5.addWidget(self.pushButton_degree_plot)

        self.verticalLayout_3.addLayout(self.horizontalLayout_5)

        self.verticalLayout_2.addWidget(self.groupBox_degree)

        self.retranslateUi(GroupBox)

        QMetaObject.connectSlotsByName(GroupBox)

    # setupUi

    def retranslateUi(self, GroupBox):
        GroupBox.setWindowTitle(
            QCoreApplication.translate("GroupBox", u"GroupBox", None))
        self.groupBox.setTitle(
            QCoreApplication.translate("GroupBox", u"All centrality measures",
                                       None))
        self.pushButton_degree_save.setText(
            QCoreApplication.translate("GroupBox", u"Data", None))
        self.groupBox_degree.setTitle(
            QCoreApplication.translate("GroupBox", u"Plots", None))
        self.radioButton_betweenness.setText(
            QCoreApplication.translate("GroupBox", u"betweenness centrality",
                                       None))
        self.radioButton_degree.setText(
            QCoreApplication.translate("GroupBox", u"degree centrality", None))
        #if QT_CONFIG(tooltip)
        self.checkBox_averaged_frames.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Toggle, if absolute number of connections or time averaged number of connections are used.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.checkBox_averaged_frames.setText(
            QCoreApplication.translate("GroupBox", u"average across frames",
                                       None))
        self.checkBox_normalized.setText(
            QCoreApplication.translate("GroupBox", u"normalized", None))
        self.groupBox_per_residue.setTitle(
            QCoreApplication.translate("GroupBox", u"Per Residue", None))
        self.label_2.setText(
            QCoreApplication.translate("GroupBox", u"segment: ", None))
        self.label_10.setText(
            QCoreApplication.translate("GroupBox", u"residue ids: ", None))
        self.lineEdit_degree_residue_ids.setPlaceholderText(
            QCoreApplication.translate("GroupBox", u"e.g. 0-12, 20, 70-90",
                                       None))
        self.groupBox_histogram.setTitle(
            QCoreApplication.translate("GroupBox", u"Histogram", None))
        self.label_56.setText(
            QCoreApplication.translate("GroupBox", u"# of bins", None))
        self.lineEdit_bins.setText(
            QCoreApplication.translate("GroupBox", u"10", None))
        self.label_55.setText(
            QCoreApplication.translate("GroupBox", u"min. value", None))
        self.lineEdit_minimum.setText(
            QCoreApplication.translate("GroupBox", u"0.0", None))
        self.label_17.setText(
            QCoreApplication.translate("GroupBox", u"max. value", None))
        self.lineEdit_maximum.setText(
            QCoreApplication.translate("GroupBox", u"1.0", None))
        self.checkBox_cumulative_histogram.setText(
            QCoreApplication.translate("GroupBox", u"cumulative", None))
        self.checkBox_stacked_histogram.setText(
            QCoreApplication.translate("GroupBox", u"stacked", None))
        #if QT_CONFIG(tooltip)
        self.checkBox_color_segments_occupancy.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.checkBox_color_segments_occupancy.setText(
            QCoreApplication.translate("GroupBox", u"color by segment", None))
        #if QT_CONFIG(tooltip)
        self.pushButton_degree_plot.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Compute the number of H bonds per residue. Results are colored by segment.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.pushButton_degree_plot.setText(
            QCoreApplication.translate("GroupBox", u"Plot", None))
Пример #19
0
class DatasheetView(QMainWindow):

    def __init__(self, pdfPath=None, pageNumber=1):
        
        super().__init__()

        # initialize data files
        # self.fileStore = path.join(path.curdir, "/files")
        # mkdir(self.fileStore)
        self.svgFiles = []


        # window dimensions
        self.top = 300
        self.left = 800
        self.width = 860
        self.height = 980

        self.setGeometry(self.left, self.top, self.width, self.height)
        
        # window title
        self.setWindowTitle("Hello")


        # sets up main layout -- splitters
        self.initUILayout()  
        self.initUIToolbar()

        self.populatePDF(pdfPath, pageNumber)

        self.show()


    def initUILayout(self):

        # set left-side, Dynamic View
        self.dynamicViewDisplay = QLabel()

        self.vBoxA = QVBoxLayout()
        self.vBoxA.addWidget(self.dynamicViewDisplay)
        
        self.groupA = QGroupBox()
        self.groupA.setTitle("Dynamic Veiw")
        self.groupA.setLayout(self.vBoxA)
        
        # set left-side, Static View
        self.staticViewDisplay = QLabel()
        
        self.vBoxB = QVBoxLayout()
        self.vBoxB.addWidget(self.staticViewDisplay)

        self.groupB = QGroupBox()
        self.groupB.setTitle("Static View")
        self.groupB.setLayout(self.vBoxB)


        # add Dynamic and Static Views to resizeable left-side Splitter
        self.altViewSplit = QSplitter(Qt.Vertical)
        self.altViewSplit.addWidget(self.groupA)
        self.altViewSplit.addWidget(self.groupB)
        


        # set up Tools View section
        self.toolsTabView = QTabWidget()
        self.toolsTabView.setTabsClosable(True)
        self.toolsTabView.setMovable(True)
        self.toolsTabView.setDocumentMode(True)

        # self.toolsTabView.setTabBarAutoHide(True)

        # add attribute for storing page notes
        self.notesDB = []
        self.notesDisplay = QListWidget(self)
        self.notesDisplay.setMaximumHeight(200)

        # add ToC to Tools View
        self.ToCListView = QListWidget()
        self.toolsTabView.addTab(self.ToCListView, "Table of Contents")

        # add notes list to tools view
        self.toolsTabView.addTab(self.notesDisplay, "Notes")

        # add tools view to the left-side splitter
        self.altViewSplit.addWidget(self.toolsTabView)




        # set right-side view -- SVG Viewer
        self.mainDisplay = QSvgWidget()

        
        self.vBoxMain = QVBoxLayout()
        self.vBoxMain.addWidget(self.mainDisplay)

        self.notesArea = QLineEdit()
        self.notesArea.setPlaceholderText("Add a note about this page...")
        self.notesArea.returnPressed.connect(self.onAddNote)
        
        self.vBoxMain.addWidget(self.notesArea)

        self.mainViewGroup = QGroupBox()
        self.mainViewGroup.setTitle("Main View")
        self.mainViewGroup.setLayout(self.vBoxMain)


        # join both sides together
        self.leftRightSplit = QSplitter(Qt.Horizontal)
        self.leftRightSplit.addWidget(self.altViewSplit)
        self.leftRightSplit.addWidget(self.mainViewGroup)        


        self.setCentralWidget(self.leftRightSplit)







    def initUIToolbar(self):

        mainMenu = self.menuBar() # get the menu bar already in use by this QMainWindow class
        
        fileMenu = mainMenu.addMenu("File")
        editMenu = mainMenu.addMenu("Edit")
        LayoutMenu = mainMenu.addMenu("Layout")
        AboutMenu = mainMenu.addMenu("About")

        saveAction = fileMenu.addAction("Save")
        quitAction = fileMenu.addAction("Exit Bettersheets")
        quitAction.triggered.connect(self.quitApp)
        copyAction = editMenu.addAction("Copy")
        resetAction = LayoutMenu.addAction("Reset Default Layout")

        # mainMenu.setNativeMenuBar(True)
        # mainMenu.show()

        self. toolBar = self.addToolBar("Tools")
        self.toolBar.addAction(saveAction)
        self.toolBar.addAction(copyAction)
        



    def contextMenuEvent(self, event):
        # return super().contextMenuEvent(event)
        contextMenu = QMenu()
        
        selectAction = contextMenu.addAction("Select Area")
        extractAction = contextMenu.addAction("Extract Content")
        openAction = contextMenu.addAction("Open PDF")
        closeAction = contextMenu.addAction("Close PDF")
        quitAction = contextMenu.addAction("Quit")

        triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos()))

        if triggered_action == quitAction:
            self.quitApp()

    def quitApp(self):
        self.close()


    def onAddNote(self):
        print("note added")

        text = self.notesArea.text()

        if text:
            self.notesDB.append(text)
            self.notesDisplay.clear()
            self.notesDisplay.addItems(self.notesDB)
            self.notesArea.clear()

    def populatePDF(self, pdfPath, pageNumber):

        if pdfPath:
            self.document = PDFContext(pdfPath, pageNumber)
            
            ToC = self.document.getToC()
            ToC_headings_list = [x[1] for x in ToC]
            self.ToCListView.clear()
            self.ToCListView.addItems(ToC_headings_list)

            # display page in main view
            self.document.openPDF(pdfPath, pageNumber)
            self.SVGString = self.document.getRender(self.document.currentPageNumber)

            # set filename of current PDF
            self.pdfName = path.split(pdfPath)[1].split('.')[0]

            # write current page to .svg file
            file_loc = self._writeSVGToFile_(self.pdfName, pageNumber, self.SVGString)

            # open the file we just wrote to
            self.mainDisplay.load(file_loc)
            

    @staticmethod
    def _writeSVGToFile_(pdfName: str, pageNumber: int, svg_string: str) -> str:
        """
        return the full file path we just wrote
        """
        
        file_loc = f"./src/main/files/{pdfName}-page-{pageNumber}.svg"

        with open(file_loc , 'w') as f:  
            f.write(svg_string)

        print("File_loc: ", file_loc)
        return file_loc
Пример #20
0
    def _create_ammo_pickup_boxes(self, size_policy,
                                  item_database: ItemDatabase):
        """
        Creates the GroupBox with SpinBoxes for selecting the pickup count of all the ammo
        :param item_database:
        :return:
        """

        self._ammo_maximum_spinboxes = collections.defaultdict(list)
        self._ammo_pickup_widgets = {}

        resource_database = default_database.resource_database_for(self.game)
        broad_to_category = {
            ItemCategory.BEAM_RELATED: ItemCategory.BEAM,
            ItemCategory.MORPH_BALL_RELATED: ItemCategory.MORPH_BALL,
            ItemCategory.MISSILE_RELATED: ItemCategory.MISSILE,
        }

        for ammo in item_database.ammo.values():
            category_box, category_layout, _ = self._boxes_for_category[
                broad_to_category[ammo.broad_category]]

            pickup_box = QGroupBox(category_box)
            pickup_box.setSizePolicy(size_policy)
            pickup_box.setTitle(ammo.name + "s")
            layout = QGridLayout(pickup_box)
            layout.setObjectName(f"{ammo.name} Box Layout")
            current_row = 0

            for ammo_item in ammo.items:
                item = resource_database.get_by_type_and_index(
                    ResourceType.ITEM, ammo_item)

                target_count_label = QLabel(pickup_box)
                target_count_label.setText(f"{item.long_name} Target" if len(
                    ammo.items) > 1 else "Target count")

                maximum_spinbox = QSpinBox(pickup_box)
                maximum_spinbox.setMaximum(ammo.maximum)
                maximum_spinbox.valueChanged.connect(
                    partial(self._on_update_ammo_maximum_spinbox, ammo_item))
                self._ammo_maximum_spinboxes[ammo_item].append(maximum_spinbox)

                layout.addWidget(target_count_label, current_row, 0)
                layout.addWidget(maximum_spinbox, current_row, 1)
                current_row += 1

            count_label = QLabel(pickup_box)
            count_label.setText("Pickup Count")
            count_label.setToolTip(
                "How many instances of this expansion should be placed.")

            pickup_spinbox = QSpinBox(pickup_box)
            pickup_spinbox.setMaximum(AmmoState.maximum_pickup_count())
            pickup_spinbox.valueChanged.connect(
                partial(self._on_update_ammo_pickup_spinbox, ammo))

            layout.addWidget(count_label, current_row, 0)
            layout.addWidget(pickup_spinbox, current_row, 1)
            current_row += 1

            if ammo.temporaries:
                require_major_item_check = QCheckBox(pickup_box)
                require_major_item_check.setText(
                    "Requires the major item to work?")
                require_major_item_check.stateChanged.connect(
                    partial(self._on_update_ammo_require_major_item, ammo))
                layout.addWidget(require_major_item_check, current_row, 0, 1,
                                 2)
                current_row += 1
            else:
                require_major_item_check = None

            expected_count = QLabel(pickup_box)
            expected_count.setWordWrap(True)
            expected_count.setText(_EXPECTED_COUNT_TEXT_TEMPLATE)
            expected_count.setToolTip(
                "Some expansions may provide 1 extra, even with no variance, if the total count "
                "is not divisible by the pickup count.")
            layout.addWidget(expected_count, current_row, 0, 1, 2)
            current_row += 1

            self._ammo_pickup_widgets[ammo] = AmmoPickupWidgets(
                pickup_spinbox, expected_count, pickup_box,
                require_major_item_check)
            category_layout.addWidget(pickup_box)
Пример #21
0
class NumberConversion(QWidget):
    def __init__(self):
        super(NumberConversion, self).__init__()

        # App attributes
        self.bin_format_base = None
        self.bin_format_base_byte = None

        # Use language settings
        self.ml = ManageLng()

        main_layout = QGridLayout()
        self.setLayout(main_layout)

        # Input
        self.inputbox = QGroupBox(
            self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name"))
        self.inputbox.setMaximumWidth(400)

        main_layout.addWidget(self.inputbox, 0, 0)

        inputbox_layout = QGridLayout()
        inputbox_layout.setHorizontalSpacing(25)
        inputbox_layout.setVerticalSpacing(35)
        inputbox_layout.setAlignment(Qt.AlignCenter)

        self.inputbox.setLayout(inputbox_layout)

        self.input_number_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab"))
        self.input_number_textfield = QLineEdit()
        self.input_number_textfield.setPlaceholderText("192")
        self.input_number_textfield.setAlignment(Qt.AlignCenter)
        self.input_number_textfield.returnPressed.connect(self.convert_action)

        inputbox_layout.addWidget(self.input_number_label,
                                  0,
                                  0,
                                  alignment=Qt.AlignCenter)
        inputbox_layout.addWidget(self.input_number_textfield, 0, 1)

        button_layout = QVBoxLayout()
        self.bin_button = QRadioButton(
            self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox"))
        self.bin_button.clicked.connect(
            lambda: self.input_number_textfield.setPlaceholderText("11100010"))
        self.dec_button = QRadioButton(
            self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox"))
        self.dec_button.clicked.connect(
            lambda: self.input_number_textfield.setPlaceholderText("192"))
        self.hex_button = QRadioButton(
            self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox"))
        self.hex_button.clicked.connect(
            lambda: self.input_number_textfield.setPlaceholderText("FF"))
        self.dec_button.setChecked(True)
        button_layout.addWidget(self.bin_button)
        button_layout.addWidget(self.dec_button)
        button_layout.addWidget(self.hex_button)
        inputbox_layout.addLayout(button_layout, 0, 3, 1, 2)

        self.convert_button = QPushButton(
            self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn"))
        self.convert_button.clicked.connect(self.convert_action)
        self.convert_button.setIcon(QIcon("static/images/exchange.png"))
        inputbox_layout.addWidget(self.convert_button,
                                  1,
                                  1,
                                  alignment=Qt.AlignCenter)

        # Output
        self.outputbox = QGroupBox(
            self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name"))
        main_layout.addWidget(self.outputbox, 0, 1)
        outputbox_layout = QGridLayout()
        outputbox_layout.setHorizontalSpacing(25)
        self.outputbox.setLayout(outputbox_layout)

        self.bin_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab"))
        self.bin_label.setAlignment(Qt.AlignCenter)

        self.dec_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab"))
        self.dec_label.setAlignment(Qt.AlignCenter)

        self.hex_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab"))
        self.hex_label.setAlignment(Qt.AlignCenter)

        self.bin_output = QLineEdit()
        self.bin_output.setReadOnly(True)
        self.bin_output.setAlignment(Qt.AlignCenter)

        self.dec_output = QLineEdit()
        self.dec_output.setReadOnly(True)
        self.dec_output.setAlignment(Qt.AlignCenter)

        self.hex_output = QLineEdit()
        self.hex_output.setReadOnly(True)
        self.hex_output.setAlignment(Qt.AlignCenter)

        self.bin_output_copy_button = QPushButton(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.bin_output_copy_button.setIcon(
            QIcon("static/images/copy_clipboard.png"))
        self.bin_output_copy_button.clicked.connect(
            lambda: copy_action(self.bin_output.text()))

        self.dec_output_copy_button = QPushButton(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.dec_output_copy_button.setIcon(
            QIcon("static/images/copy_clipboard.png"))
        self.dec_output_copy_button.clicked.connect(
            lambda: copy_action(self.dec_output.text()))

        self.hex_output_copy_button = QPushButton(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.hex_output_copy_button.setIcon(
            QIcon("static/images/copy_clipboard.png"))
        self.hex_output_copy_button.clicked.connect(
            lambda: copy_action(self.hex_output.text()))

        outputbox_layout.addWidget(self.bin_label, 0, 0)
        outputbox_layout.addWidget(self.bin_output, 0, 1)
        outputbox_layout.addWidget(self.bin_output_copy_button, 0, 2)

        outputbox_layout.addWidget(self.dec_label, 1, 0)
        outputbox_layout.addWidget(self.dec_output, 1, 1)
        outputbox_layout.addWidget(self.dec_output_copy_button, 1, 2)

        outputbox_layout.addWidget(self.hex_label, 2, 0)
        outputbox_layout.addWidget(self.hex_output, 2, 1)
        outputbox_layout.addWidget(self.hex_output_copy_button, 2, 2)

        # IP address/mask number conversion
        self.ip_address_number_conversion_box = QGroupBox(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name"))
        main_layout.addWidget(self.ip_address_number_conversion_box, 1, 0, 1,
                              2)

        ip_address_number_conversion_layout = QGridLayout()
        ip_address_number_conversion_layout.setAlignment(Qt.AlignCenter)
        ip_address_number_conversion_layout.setHorizontalSpacing(25)
        ip_address_number_conversion_layout.setVerticalSpacing(24)
        self.ip_address_number_conversion_box.setLayout(
            ip_address_number_conversion_layout)

        self.input_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab"))
        self.input_label.setAlignment(Qt.AlignCenter)
        self.input_label.setMaximumWidth(150)
        self.input_textfield = QLineEdit()
        self.input_textfield.setPlaceholderText("192.168.1.1")
        self.input_textfield.setAlignment(Qt.AlignLeft)
        self.input_textfield.setMaximumWidth(300)
        self.input_textfield.setAlignment(Qt.AlignCenter)
        self.input_textfield.returnPressed.connect(self.convert_action_2)
        ip_address_number_conversion_layout.addWidget(self.input_label, 0, 0)
        ip_address_number_conversion_layout.addWidget(self.input_textfield, 0,
                                                      1)

        button_layout_2 = QVBoxLayout()
        self.dec_to_bin_button = QRadioButton(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin"))
        self.dec_to_bin_button.clicked.connect(
            lambda: self.input_textfield.setPlaceholderText("192.168.1.1"))
        self.dec_to_bin_button.setMaximumWidth(150)

        self.bin_to_dec_button = QRadioButton(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec"))
        self.bin_to_dec_button.clicked.connect(
            lambda: self.input_textfield.setPlaceholderText(
                "11000000.10101000.00000001.00000001"))
        self.bin_to_dec_button.setMaximumWidth(150)
        self.dec_to_bin_button.setChecked(True)
        button_layout_2.addWidget(self.dec_to_bin_button)
        button_layout_2.addWidget(self.bin_to_dec_button)
        ip_address_number_conversion_layout.addLayout(button_layout_2, 0, 2)

        self.output_label = QLabel(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab"))
        self.output_label.setAlignment(Qt.AlignCenter)
        self.output_textfield = QLineEdit()
        self.output_textfield.setMaximumWidth(300)
        self.output_textfield.setReadOnly(True)
        self.output_textfield.setAlignment(Qt.AlignCenter)
        ip_address_number_conversion_layout.addWidget(self.output_label, 1, 0)
        ip_address_number_conversion_layout.addWidget(self.output_textfield, 1,
                                                      1)

        self.output_textfield_copy_button = QPushButton(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn"))
        self.output_textfield_copy_button.setIcon(
            QIcon("static/images/copy_clipboard.png"))
        self.output_textfield_copy_button.clicked.connect(
            lambda: copy_action(self.output_textfield.text()))
        ip_address_number_conversion_layout.addWidget(
            self.output_textfield_copy_button, 1, 2, alignment=Qt.AlignLeft)

        self.convert_button_2 = QPushButton(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn"))
        self.convert_button_2.clicked.connect(self.convert_action_2)
        self.convert_button_2.setIcon(QIcon("static/images/exchange.png"))
        ip_address_number_conversion_layout.addWidget(
            self.convert_button_2, 2, 0, 1, 3, alignment=Qt.AlignHCenter)

    def convert_action(self):
        if is_empty(self.input_number_textfield.text()):
            PopupWindow("warning",
                        self.ml.get_tr_text("tab_num_conv_warning01"),
                        self.input_number_textfield)
        else:
            if self.bin_button.isChecked():
                self.source_bin(self.input_number_textfield.text())
            elif self.dec_button.isChecked():
                self.source_dec(self.input_number_textfield.text())
            else:
                self.source_hex(self.input_number_textfield.text())

    def source_bin(self, bin_number):
        bin_number_corrected = get_corrected_number(bin_number)
        bin_number_corrected_byte = bin_number_corrected.rjust(8, "0")
        if not is_correct_binary(bin_number_corrected):
            PopupWindow("warning",
                        self.ml.get_tr_text("tab_num_conv_warning02"),
                        self.input_number_textfield)
        else:
            if 0 <= int(bin_number_corrected, 2) <= 255:
                if bin_number_corrected != bin_number_corrected_byte:
                    self.bin_format_base = bin_number_corrected
                    self.bin_format_base_byte = bin_number_corrected_byte
                    bin_format = get_bin_format(
                        self.bin_format_base,
                        self.ml.get_tr_text("byte_format_str"),
                        self.bin_format_base_byte)
                else:
                    bin_format = self.bin_format_base
            else:
                bin_format = bin_number_corrected
            dec_format = str(int(bin_number_corrected, 2))
            hex_format = hex(int(bin_number_corrected, 2)).replace("0x",
                                                                   "").upper()
            self.bin_output.setText(bin_format)
            self.dec_output.setText(dec_format)
            self.hex_output.setText(hex_format)

    def source_dec(self, dec_number):
        dec_number_corrected = get_corrected_number(dec_number)
        if not is_correct_decimal(dec_number_corrected):
            PopupWindow("warning",
                        self.ml.get_tr_text("tab_num_conv_warning03"),
                        self.input_number_textfield)
        else:
            if 0 <= int(dec_number_corrected) <= 255:
                self.bin_format_base = bin(int(dec_number_corrected)).replace(
                    "0b", "")
                self.bin_format_base_byte = self.bin_format_base.rjust(8, "0")
                if self.bin_format_base != self.bin_format_base_byte:
                    bin_format = get_bin_format(
                        self.bin_format_base,
                        self.ml.get_tr_text("byte_format_str"),
                        self.bin_format_base_byte)
                else:
                    bin_format = self.bin_format_base
            else:
                bin_format = bin(int(dec_number_corrected)).replace("0b", "")
            dec_format = dec_number_corrected
            hex_format = hex(int(dec_number_corrected)).replace("0x",
                                                                "").upper()
            self.bin_output.setText(bin_format)
            self.dec_output.setText(dec_format)
            self.hex_output.setText(hex_format)

    def source_hex(self, hex_number):
        hex_number_corrected = get_corrected_number(hex_number).upper()
        if not is_correct_hexadecimal(hex_number_corrected):
            PopupWindow("warning",
                        self.ml.get_tr_text("tab_num_conv_warning04"),
                        self.input_number_textfield)
        else:
            if 0 <= int(hex_number_corrected, 16) <= 255:
                self.bin_format_base = bin(int(hex_number_corrected,
                                               16)).replace("0b", "")
                self.bin_format_base_byte = self.bin_format_base.rjust(8, "0")
                if self.bin_format_base != self.bin_format_base_byte:
                    bin_format = get_bin_format(
                        self.bin_format_base,
                        self.ml.get_tr_text("byte_format_str"),
                        self.bin_format_base_byte)
                else:
                    bin_format = self.bin_format_base
            else:
                bin_format = bin(int(hex_number_corrected,
                                     16)).replace("0b", "")
            dec_format = str(int(hex_number_corrected, 16))
            hex_format = hex_number_corrected
            self.bin_output.setText(bin_format)
            self.dec_output.setText(dec_format)
            self.hex_output.setText(hex_format)

    def convert_action_2(self):
        if is_empty(self.input_textfield.text()):
            PopupWindow("warning",
                        self.ml.get_tr_text("tab_num_conv_warning05"),
                        self.input_textfield)
        elif self.dec_to_bin_button.isChecked():
            if is_correct_any_ip_dec(self.input_textfield.text()):
                self.output_textfield.setText(
                    dec_to_bin(self.input_textfield.text()))
            else:
                PopupWindow("warning",
                            self.ml.get_tr_text("tab_num_conv_warning06"),
                            self.input_textfield)
        else:
            if is_correct_any_ip_bin(self.input_textfield.text()):
                self.output_textfield.setText(
                    bin_to_dec(self.input_textfield.text()))
            else:
                PopupWindow("warning",
                            self.ml.get_tr_text("tab_num_conv_warning07"),
                            self.input_textfield)

    def re_translate_ui(self, lang):
        self.ml = ManageLng(lang)

        self.inputbox.setTitle(
            self.ml.get_tr_text("tab_num_conv_inputbox_gbox_name"))
        self.input_number_label.setText(
            self.ml.get_tr_text("tab_num_conv_inputbox_in_number_lab"))
        self.bin_button.setText(
            self.ml.get_tr_text("tab_num_conv_inputbox_bin_chkbox"))
        self.dec_button.setText(
            self.ml.get_tr_text("tab_num_conv_inputbox_dec_chkbox"))
        self.hex_button.setText(
            self.ml.get_tr_text("tab_num_conv_inputbox_hex_chkbox"))
        self.convert_button.setText(
            self.ml.get_tr_text("tab_num_conv_inputbox_conv_btn"))
        self.outputbox.setTitle(
            self.ml.get_tr_text("tab_num_conv_outputbox_gbox_name"))
        self.bin_label.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_bin_lab"))
        self.dec_label.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_dec_lab"))
        self.hex_label.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_hex_lab"))
        self.bin_output_copy_button.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.dec_output_copy_button.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.hex_output_copy_button.setText(
            self.ml.get_tr_text("tab_num_conv_outputbox_copy_btn"))
        self.ip_address_number_conversion_box.setTitle(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_gbox_name"))
        self.input_label.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_in_lab"))
        self.dec_to_bin_button.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_dectobin"))
        self.bin_to_dec_button.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_bintodec"))
        self.output_label.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_out_lab"))
        self.output_textfield_copy_button.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_copy_btn"))
        self.convert_button_2.setText(
            self.ml.get_tr_text("tab_num_conv_ip_mask_conv_convert_btn"))

        if self.bin_output.text():
            self.bin_output.setText(
                get_bin_format(self.bin_format_base,
                               self.ml.get_tr_text("byte_format_str"),
                               self.bin_format_base_byte))
Пример #22
0
    def __init__(self, targetImage=None, axeSize=500, layer=None, parent=None):
        super().__init__(layer=layer, targetImage=targetImage, parent=parent)

        #######################################
        # Libraw correspondences:
        # rgb_xyz_matrix is libraw cam_xyz
        # camera_whitebalance is libraw cam_mul
        # daylight_whitebalance is libraw pre_mul
        # dng correspondences:
        # ASSHOTNEUTRAL tag value is (X,Y,Z) =  1 / rawpyObj.camera_whitebalance
        ##########################################
        rawpyObj = layer.parentImage.rawImage

        # constants and as shot values
        self.XYZ2CameraMatrix = rawpyObj.rgb_xyz_matrix[:3, :]
        self.XYZ2CameraInverseMatrix = np.linalg.inv(self.XYZ2CameraMatrix)
        # initial post processing multipliers (as shot)
        m1, m2, m3, m4 = rawpyObj.camera_whitebalance
        self.asShotMultipliers = (
            m1 / m2, 1.0, m3 / m2, m4 / m2
        )  # normalization is mandatory : for nef files white balance is around 256
        self.asShotTemp, self.asShotTint = multipliers2TemperatureAndTint(
            *1 / np.array(self.asShotMultipliers[:3]), self.XYZ2CameraMatrix)
        self.rawMultipliers = self.asShotMultipliers  # rawpyObj.camera_whitebalance # = 1/(dng ASSHOTNEUTRAL tag value)
        self.sampleMultipliers = False
        self.samples = []
        ########################################
        # XYZ-->Camera conversion matrix:
        # Last row is zero for RGB cameras (cf. rawpy and libraw docs).
        # type ndarray, shape (4,3)
        #########################################

        # attributes initialized in setDefaults, declared here for the sake of correctness
        self.tempCorrection, self.tintCorrection, self.expCorrection, self.highCorrection,\
                                                   self.contCorrection, self.satCorrection, self.brCorrection = [None] * 7
        # contrast spline vie (initialized by setContrastSpline)
        self.contrastForm = None
        # tone spline view (initialized by setToneSpline)
        self.toneForm = None
        # dock containers for contrast and tome forms
        self.dockC, self.dockT = None, None
        # options
        optionList0, optionNames0 = ['Auto Brightness', 'Preserve Highlights'
                                     ], ['Auto Expose', 'Preserve Highlights']
        optionList1, optionNames1 = ['Auto WB', 'Camera WB', 'User WB'
                                     ], ['Auto', 'Camera (As Shot)', 'User']
        optionList2, optionNames2 = [
            'cpLookTable', 'cpToneCurve', 'manualCurve'
        ], [
            'Use Camera Profile Look Table', 'Show Tone Curves',
            'Show Contrast Curve'
        ]
        self.listWidget1 = optionsWidget(
            options=optionList0,
            optionNames=optionNames0,
            exclusive=False,
            changed=lambda: self.dataChanged.emit(1))
        self.listWidget2 = optionsWidget(
            options=optionList1,
            optionNames=optionNames1,
            exclusive=True,
            changed=lambda: self.dataChanged.emit(1))
        self.listWidget3 = optionsWidget(
            options=optionList2,
            optionNames=optionNames2,
            exclusive=False,
            changed=lambda: self.dataChanged.emit(2))
        self.options = UDict(
            (self.listWidget1.options, self.listWidget2.options,
             self.listWidget3.options))
        # display the 'as shot' temperature
        item = self.listWidget2.item(1)
        item.setText(item.text() + ' : %d' % self.asShotTemp)

        # temperature slider
        self.sliderTemp = QbLUeSlider(Qt.Horizontal)
        self.sliderTemp.setStyleSheet(
            QbLUeSlider.bLueSliderDefaultColorStylesheet)
        self.sliderTemp.setRange(0, 100)
        self.sliderTemp.setSingleStep(1)

        self.tempLabel = QLabel()
        self.tempLabel.setText("Temp")

        self.tempValue = QLabel()
        font = self.tempValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("10000")
        h = metrics.height()
        self.tempValue.setMinimumSize(w, h)
        self.tempValue.setMaximumSize(w, h)
        self.tempValue.setText(
            str("{:.0f}".format(self.slider2Temp(self.sliderTemp.value()))))

        self.sliderTemp.valueChanged.connect(
            self.tempUpdate)  # signal send new value as parameter
        self.sliderTemp.sliderReleased.connect(lambda: self.tempUpdate(
            self.sliderTemp.value()))  # signal pass no parameter

        # tint slider
        self.sliderTint = QbLUeSlider(Qt.Horizontal)
        self.sliderTint.setStyleSheet(
            QbLUeSlider.bLueSliderDefaultIMGColorStylesheet)
        self.sliderTint.setRange(0, 150)

        self.sliderTint.setSingleStep(1)

        self.tintLabel = QLabel()
        self.tintLabel.setText("Tint")

        self.tintValue = QLabel()
        font = self.tempValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("100")
        h = metrics.height()
        self.tintValue.setMinimumSize(w, h)
        self.tintValue.setMaximumSize(w, h)
        self.tintValue.setText(
            str("{:.0f}".format(self.sliderTint2User(
                self.sliderTint.value()))))

        self.sliderTint.valueChanged.connect(self.tintUpdate)
        self.sliderTint.sliderReleased.connect(lambda: self.tintUpdate(
            self.sliderTint.value()))  # signal pass no parameter)

        ######################
        # From libraw and dcraw sources:
        # Exposure and brightness are curve transformations.
        # Exposure curve is y = alpha*x, with cubic root ending; it is applied before demosaicing.
        # Brightness is (similar to) y = x**alpha and part of gamma transformation from linear sRGB to RGB.
        # Exposure and brightness both dilate the histogram towards highlights.
        # Exposure dilatation is uniform (homothety), brightness dilataion is
        # maximum for the midtones and the highlghts are preserved.
        # As a consequence, normal workflow begins with the adjustment of exposure,
        # to fill the entire range of the histogram and to adjust the highlights. Next,
        # one adjusts the brightness to put the midtones at the level we want them to be.
        # Cf. https://www.cambridgeincolour.com/forums/thread653.htm
        #####################

        # profile combo
        self.dngDict = self.setCameraProfilesCombo()

        # cameraProfilesCombo index changed event handler

        def cameraProfileUpdate(value):
            self.dngDict = self.cameraProfilesCombo.itemData(value)
            if self.options['cpToneCurve']:
                toneCurve = dngProfileToneCurve(
                    self.dngDict.get('ProfileToneCurve', []))
                self.toneForm.baseCurve = [
                    QPointF(x * axeSize, -y * axeSize)
                    for x, y in zip(toneCurve.dataX, toneCurve.dataY)
                ]
                self.toneForm.update()
            # recompute as shot temp and tint using new profile
            self.asShotTemp, self.asShotTint = multipliers2TemperatureAndTint(
                *1 / np.array(self.asShotMultipliers[:3]),
                self.XYZ2CameraMatrix,
                dngDict=self.dngDict
            )  # TODO 6/12/19 added keyword dngDict validate
            # display updated as shot temp
            item = self.listWidget2.item(1)
            item.setText(item.text().split(":")[0] + ': %d' % self.asShotTemp)
            # invalidate cache
            self.layer.bufCache_HSV_CV32 = None
            self.dataChanged.emit(2)  # 2 = no postprocessing

        self.cameraProfilesCombo.currentIndexChanged.connect(
            cameraProfileUpdate)

        # denoising combo
        self.denoiseCombo = QComboBox()
        items = OrderedDict([('Off', 0), ('Medium', 1), ('Full', 2)])
        for key in items:
            self.denoiseCombo.addItem(key, items[key])

        # denoiseCombo index changed event handler
        def denoiseUpdate(value):
            self.denoiseValue = self.denoiseCombo.itemData(value)
            self.dataChanged.emit(1)

        self.denoiseCombo.currentIndexChanged.connect(denoiseUpdate)

        # overexposed area restoration
        self.overexpCombo = QComboBox()
        items = OrderedDict([('Clip', 0), ('Ignore', 1), ('Blend', 2),
                             ('Reconstruct', 3)])
        for key in items:
            self.overexpCombo.addItem(key, items[key])

        # overexpCombo index changed event handler
        def overexpUpdate(value):
            self.overexpValue = self.overexpCombo.itemData(value)
            self.dataChanged.emit(1)

        self.overexpCombo.currentIndexChanged.connect(overexpUpdate)

        # exp slider
        self.sliderExp = QbLUeSlider(Qt.Horizontal)
        self.sliderExp.setStyleSheet(QbLUeSlider.bLueSliderDefaultBWStylesheet)
        self.sliderExp.setRange(0, 100)

        self.sliderExp.setSingleStep(1)

        self.expLabel = QLabel()
        self.expLabel.setText("Exp.")

        self.expValue = QLabel()
        font = self.expValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("+1.0")
        h = metrics.height()
        self.expValue.setMinimumSize(w, h)
        self.expValue.setMaximumSize(w, h)
        self.expValue.setText(
            str("{:.1f}".format(self.slider2Exp(self.sliderExp.value()))))

        # exp done event handler
        def expUpdate(value):
            self.expValue.setText(
                str("{:+.1f}".format(
                    self.sliderExp2User(self.sliderExp.value()))))
            # move not yet terminated or value not modified
            if self.sliderExp.isSliderDown() or self.slider2Exp(
                    value) == self.expCorrection:
                return
            try:
                self.sliderExp.valueChanged.disconnect()
                self.sliderExp.sliderReleased.disconnect()
            except RuntimeError:
                pass
            # rawpy: expCorrection range is -2.0...3.0, boiling down to exp_shift range 2**(-2)=0.25...2**3=8.0
            self.expCorrection = self.slider2Exp(self.sliderExp.value())
            self.dataChanged.emit(1)
            self.sliderExp.valueChanged.connect(
                expUpdate)  # send new value as parameter
            self.sliderExp.sliderReleased.connect(lambda: expUpdate(
                self.sliderExp.value()))  # signal pass no parameter

        self.sliderExp.valueChanged.connect(
            expUpdate)  # send new value as parameter
        self.sliderExp.sliderReleased.connect(lambda: expUpdate(
            self.sliderExp.value()))  # signal pass no parameter

        # brightness slider
        brSlider = QbLUeSlider(Qt.Horizontal)
        brSlider.setRange(1, 101)

        self.sliderExp.setSingleStep(1)

        brSlider.setStyleSheet(QbLUeSlider.bLueSliderDefaultBWStylesheet)

        self.sliderBrightness = brSlider
        brLabel = QLabel()
        brLabel.setText("Bright.")

        self.brValue = QLabel()
        font = self.expValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("+99")
        h = metrics.height()
        self.brValue.setMinimumSize(w, h)
        self.brValue.setMaximumSize(w, h)
        self.brValue.setText(
            str("{:+d}".format(
                int(self.brSlider2User(self.sliderBrightness.value())))))

        # brightness done event handler
        def brUpdate(value):
            self.brValue.setText(
                str("{:+d}".format(
                    int(self.brSlider2User(self.sliderBrightness.value())))))
            # move not yet terminated or value not modified
            if self.sliderBrightness.isSliderDown() or self.slider2Br(
                    value) == self.brCorrection:
                return
            try:
                self.sliderBrightness.valueChanged.disconnect()
                self.sliderBrightness.sliderReleased.disconnect()
            except RuntimeError:
                pass
            self.brCorrection = self.slider2Br(self.sliderBrightness.value())
            self.dataChanged.emit(1)
            self.sliderBrightness.sliderReleased.connect(
                lambda: brUpdate(self.sliderBrightness.value()))
            self.sliderBrightness.valueChanged.connect(
                brUpdate)  # send new value as parameter

        self.sliderBrightness.valueChanged.connect(
            brUpdate)  # send new value as parameter
        self.sliderBrightness.sliderReleased.connect(
            lambda: brUpdate(self.sliderBrightness.value()))

        # contrast slider
        self.sliderCont = QbLUeSlider(Qt.Horizontal)
        self.sliderCont.setStyleSheet(
            QbLUeSlider.bLueSliderDefaultBWStylesheet)
        self.sliderCont.setRange(0, 20)

        self.sliderCont.setSingleStep(1)

        self.contLabel = QLabel()
        self.contLabel.setText("Cont.")

        self.contValue = QLabel()
        font = self.contValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("100")
        h = metrics.height()
        self.contValue.setMinimumSize(w, h)
        self.contValue.setMaximumSize(w, h)
        self.contValue.setText(
            str("{:.0f}".format(self.slider2Cont(self.sliderCont.value()))))

        # cont done event handler
        def contUpdate(value):
            self.contValue.setText(
                str("{:.0f}".format(self.slider2Cont(
                    self.sliderCont.value()))))
            # move not yet terminated or value not modified
            if self.sliderCont.isSliderDown() or self.slider2Cont(
                    value) == self.tempCorrection:
                return
            try:
                self.sliderCont.valueChanged.disconnect()
                self.sliderCont.sliderReleased.disconnect()
            except RuntimeError:
                pass
            self.contCorrection = self.slider2Cont(self.sliderCont.value())
            self.contValue.setText(str("{:+d}".format(self.contCorrection)))
            # force to recalculate the spline
            self.layer.autoSpline = True
            self.dataChanged.emit(
                3)  # no postprocessing and no camera profile stuff
            self.sliderCont.valueChanged.connect(
                contUpdate)  # send new value as parameter
            self.sliderCont.sliderReleased.connect(lambda: contUpdate(
                self.sliderCont.value()))  # signal has no parameter

        self.sliderCont.valueChanged.connect(
            contUpdate)  # send new value as parameter
        self.sliderCont.sliderReleased.connect(lambda: contUpdate(
            self.sliderCont.value()))  # signal has no parameter

        # saturation slider
        self.sliderSat = QbLUeSlider(Qt.Horizontal)
        self.sliderSat.setStyleSheet(
            QbLUeSlider.bLueSliderDefaultColorStylesheet)
        self.sliderSat.setRange(0, 100)

        self.sliderSat.setSingleStep(1)

        satLabel = QLabel()
        satLabel.setText("Sat.")

        self.satValue = QLabel()
        font = self.satValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("+10")
        h = metrics.height()
        self.satValue.setMinimumSize(w, h)
        self.satValue.setMaximumSize(w, h)
        self.satValue.setText(
            str("{:+d}".format(self.slider2Sat(self.sliderSat.value()))))
        """sat done event handler"""

        def satUpdate(value):
            self.satValue.setText(
                str("{:+d}".format(self.slider2Sat(self.sliderSat.value()))))
            # move not yet terminated or value not modified
            if self.sliderSat.isSliderDown() or self.slider2Sat(
                    value) == self.satCorrection:
                return
            try:
                self.sliderSat.valueChanged.disconnect()
                self.sliderSat.sliderReleased.disconnect()
            except RuntimeError:
                pass
            self.satCorrection = self.slider2Sat(self.sliderSat.value())
            self.dataChanged.emit(
                3)  # no post processing and no camera profile stuff
            self.sliderSat.valueChanged.connect(
                satUpdate)  # send new value as parameter
            self.sliderSat.sliderReleased.connect(lambda: satUpdate(
                self.sliderSat.value()))  # signal has no parameter

        self.sliderSat.valueChanged.connect(
            satUpdate)  # send new value as parameter
        self.sliderSat.sliderReleased.connect(lambda: satUpdate(
            self.sliderSat.value()))  # signal has no parameter

        # layout
        l = QVBoxLayout()
        l.addWidget(self.listWidget3)
        hl01 = QHBoxLayout()
        hl01.addWidget(QLabel('Camera Profile'))
        hl01.addWidget(self.cameraProfilesCombo)
        l.addLayout(hl01)
        hl0 = QHBoxLayout()
        hl0.addWidget(QLabel('Denoising'))
        hl0.addWidget(self.denoiseCombo)
        l.addLayout(hl0)
        hl00 = QHBoxLayout()
        hl00.addWidget(QLabel('Overexp. Restoration'))
        hl00.addWidget(self.overexpCombo)
        l.addLayout(hl00)
        hl1 = QHBoxLayout()
        hl1.addWidget(self.expLabel)
        hl1.addWidget(self.expValue)
        hl1.addWidget(self.sliderExp)
        l.addLayout(hl1)
        hl8 = QHBoxLayout()
        hl8.addWidget(brLabel)
        hl8.addWidget(self.brValue)
        hl8.addWidget(self.sliderBrightness)
        l.addLayout(hl8)
        l.addWidget(self.listWidget1)
        vl1 = QVBoxLayout()
        vl1.addWidget(self.listWidget2)
        gb1 = QGroupBox()
        gb1.setTitle('White Balance')
        hl2 = QHBoxLayout()
        hl2.addWidget(self.tempLabel)
        hl2.addWidget(self.tempValue)
        hl2.addWidget(self.sliderTemp)
        hl3 = QHBoxLayout()
        hl3.addWidget(self.tintLabel)
        hl3.addWidget(self.tintValue)
        hl3.addWidget(self.sliderTint)
        vl1.addLayout(hl2)
        vl1.addLayout(hl3)
        gb1.setLayout(vl1)
        l.addWidget(gb1)
        hl4 = QHBoxLayout()
        hl4.addWidget(self.contLabel)
        hl4.addWidget(self.contValue)
        hl4.addWidget(self.sliderCont)
        hl7 = QHBoxLayout()
        hl7.addWidget(satLabel)
        hl7.addWidget(self.satValue)
        hl7.addWidget(self.sliderSat)

        # separator
        sep = QFrame()
        sep.setFrameShape(QFrame.HLine)
        sep.setFrameShadow(QFrame.Sunken)
        l.addWidget(sep)
        l.addLayout(hl4)
        l.addLayout(hl7)
        l.addStretch(1)
        self.setLayout(l)
        self.adjustSize()
        self.setDefaults()
        self.setWhatsThis("""<b>Development of raw files</b><br>
                    <b>Default settings</b> are a good starting point.<br>
                    A <b>Tone Curve</b> is applied to the raw image prior to postprocessing.<br> 
                    The cuvre can be edited by checking the option
                    <b>Show Tone Curve</b>; this option works best with manual exposure.<br>
                    <b>Contrast</b> correction is based on an automatic algorithm 
                    well suited to multi-mode histograms.<br>
                    <b>Brightness, Contrast</b> and <b>Saturation</b> levels</b> are 
                    adjustable with the correponding sliders.<br>
                    The <b>Contrast Curve</b> can be edited manually by checking 
                    the option <b>Show Contrast Curve</b>.<br>
                    Uncheck <b>Auto Expose</b> to adjust the exposure manually.<br>
                    The <b>OverExp. Rest.</b> slider controls the mode of restoration of overexposed areas. 
                    Valid values are 0 to 3 (0=clip;1=unclip;2=blend;3=rebuild); (with Auto Exposed 
                    checked the mode is clip).<br>
                    """)  # end of setWhatsThis
Пример #23
0
class Ui_GroupBox(object):
    def setupUi(self, GroupBox):
        if not GroupBox.objectName():
            GroupBox.setObjectName(u"GroupBox")
        GroupBox.resize(535, 520)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(GroupBox.sizePolicy().hasHeightForWidth())
        GroupBox.setSizePolicy(sizePolicy)
        self.verticalLayout_2 = QVBoxLayout(GroupBox)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.groupBox_occupancy_histogram = QGroupBox(GroupBox)
        self.groupBox_occupancy_histogram.setObjectName(
            u"groupBox_occupancy_histogram")
        self.verticalLayout = QVBoxLayout(self.groupBox_occupancy_histogram)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.label_56 = QLabel(self.groupBox_occupancy_histogram)
        self.label_56.setObjectName(u"label_56")
        self.label_56.setMaximumSize(QSize(16777215, 16777215))
        self.label_56.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout.addWidget(self.label_56)

        self.lineEdit_bins = QLineEdit(self.groupBox_occupancy_histogram)
        self.lineEdit_bins.setObjectName(u"lineEdit_bins")
        self.lineEdit_bins.setMinimumSize(QSize(50, 0))
        self.lineEdit_bins.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout.addWidget(self.lineEdit_bins)

        self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer_3)

        self.label_55 = QLabel(self.groupBox_occupancy_histogram)
        self.label_55.setObjectName(u"label_55")
        self.label_55.setMaximumSize(QSize(16777215, 16777215))
        self.label_55.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout.addWidget(self.label_55)

        self.lineEdit_minimum = QLineEdit(self.groupBox_occupancy_histogram)
        self.lineEdit_minimum.setObjectName(u"lineEdit_minimum")
        self.lineEdit_minimum.setMinimumSize(QSize(50, 0))
        self.lineEdit_minimum.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout.addWidget(self.lineEdit_minimum)

        self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer_2)

        self.label_17 = QLabel(self.groupBox_occupancy_histogram)
        self.label_17.setObjectName(u"label_17")
        self.label_17.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)

        self.horizontalLayout.addWidget(self.label_17)

        self.lineEdit_maximum = QLineEdit(self.groupBox_occupancy_histogram)
        self.lineEdit_maximum.setObjectName(u"lineEdit_maximum")
        self.lineEdit_maximum.setMinimumSize(QSize(50, 0))
        self.lineEdit_maximum.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout.addWidget(self.lineEdit_maximum)

        self.verticalLayout.addLayout(self.horizontalLayout)

        self.horizontalLayout_7 = QHBoxLayout()
        self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
        self.checkBox_cumulative_histogram = QCheckBox(
            self.groupBox_occupancy_histogram)
        self.checkBox_cumulative_histogram.setObjectName(
            u"checkBox_cumulative_histogram")

        self.horizontalLayout_7.addWidget(self.checkBox_cumulative_histogram)

        self.horizontalSpacer_12 = QSpacerItem(40, 20, QSizePolicy.Fixed,
                                               QSizePolicy.Minimum)

        self.horizontalLayout_7.addItem(self.horizontalSpacer_12)

        self.checkBox_stacked_histogram = QCheckBox(
            self.groupBox_occupancy_histogram)
        self.checkBox_stacked_histogram.setObjectName(
            u"checkBox_stacked_histogram")

        self.horizontalLayout_7.addWidget(self.checkBox_stacked_histogram)

        self.horizontalSpacer_11 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                               QSizePolicy.Minimum)

        self.horizontalLayout_7.addItem(self.horizontalSpacer_11)

        self.verticalLayout.addLayout(self.horizontalLayout_7)

        self.horizontalLayout_6 = QHBoxLayout()
        self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
        self.checkBox_color_segments_occupancy = QCheckBox(
            self.groupBox_occupancy_histogram)
        self.checkBox_color_segments_occupancy.setObjectName(
            u"checkBox_color_segments_occupancy")
        self.checkBox_color_segments_occupancy.setChecked(True)

        self.horizontalLayout_6.addWidget(
            self.checkBox_color_segments_occupancy)

        self.horizontalSpacer_9 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_6.addItem(self.horizontalSpacer_9)

        self.verticalLayout.addLayout(self.horizontalLayout_6)

        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                            QSizePolicy.Minimum)

        self.horizontalLayout_2.addItem(self.horizontalSpacer)

        self.pushButton_save_occupancy = QPushButton(
            self.groupBox_occupancy_histogram)
        self.pushButton_save_occupancy.setObjectName(
            u"pushButton_save_occupancy")

        self.horizontalLayout_2.addWidget(self.pushButton_save_occupancy)

        self.pushButton_plot_occupancy = QPushButton(
            self.groupBox_occupancy_histogram)
        self.pushButton_plot_occupancy.setObjectName(
            u"pushButton_plot_occupancy")
        self.pushButton_plot_occupancy.setAutoDefault(False)

        self.horizontalLayout_2.addWidget(self.pushButton_plot_occupancy)

        self.verticalLayout.addLayout(self.horizontalLayout_2)

        self.verticalLayout_2.addWidget(self.groupBox_occupancy_histogram)

        self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                            QSizePolicy.Expanding)

        self.verticalLayout_2.addItem(self.verticalSpacer_2)

        self.groupBox_nb_connections = QGroupBox(GroupBox)
        self.groupBox_nb_connections.setObjectName(u"groupBox_nb_connections")
        self.verticalLayout_3 = QVBoxLayout(self.groupBox_nb_connections)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.horizontalLayout_5 = QHBoxLayout()
        self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
        self.checkBox_color_segments_timeseries = QCheckBox(
            self.groupBox_nb_connections)
        self.checkBox_color_segments_timeseries.setObjectName(
            u"checkBox_color_segments_timeseries")
        self.checkBox_color_segments_timeseries.setChecked(True)

        self.horizontalLayout_5.addWidget(
            self.checkBox_color_segments_timeseries)

        self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_5.addItem(self.horizontalSpacer_7)

        self.verticalLayout_3.addLayout(self.horizontalLayout_5)

        self.horizontalLayout_4 = QHBoxLayout()
        self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
        self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_4.addItem(self.horizontalSpacer_5)

        self.pushButton_save_timeseries = QPushButton(
            self.groupBox_nb_connections)
        self.pushButton_save_timeseries.setObjectName(
            u"pushButton_save_timeseries")

        self.horizontalLayout_4.addWidget(self.pushButton_save_timeseries)

        self.pushButton_plot_timeseries = QPushButton(
            self.groupBox_nb_connections)
        self.pushButton_plot_timeseries.setObjectName(
            u"pushButton_plot_timeseries")
        self.pushButton_plot_timeseries.setAutoDefault(False)

        self.horizontalLayout_4.addWidget(self.pushButton_plot_timeseries)

        self.verticalLayout_3.addLayout(self.horizontalLayout_4)

        self.verticalLayout_2.addWidget(self.groupBox_nb_connections)

        self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                          QSizePolicy.Expanding)

        self.verticalLayout_2.addItem(self.verticalSpacer)

        self.groupBox_joint_occupancy = QGroupBox(GroupBox)
        self.groupBox_joint_occupancy.setObjectName(
            u"groupBox_joint_occupancy")
        self.verticalLayout_4 = QVBoxLayout(self.groupBox_joint_occupancy)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
        self.horizontalLayout_10 = QHBoxLayout()
        self.horizontalLayout_10.setObjectName(u"horizontalLayout_10")
        self.radioButton_scatter = QRadioButton(self.groupBox_joint_occupancy)
        self.radioButton_scatter.setObjectName(u"radioButton_scatter")
        self.radioButton_scatter.setChecked(True)

        self.horizontalLayout_10.addWidget(self.radioButton_scatter)

        self.label_3 = QLabel(self.groupBox_joint_occupancy)
        self.label_3.setObjectName(u"label_3")

        self.horizontalLayout_10.addWidget(self.label_3)

        self.lineEdit_scatter_size = QLineEdit(self.groupBox_joint_occupancy)
        self.lineEdit_scatter_size.setObjectName(u"lineEdit_scatter_size")
        self.lineEdit_scatter_size.setMaximumSize(QSize(50, 16777215))

        self.horizontalLayout_10.addWidget(self.lineEdit_scatter_size)

        self.horizontalSpacer_10 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                               QSizePolicy.Minimum)

        self.horizontalLayout_10.addItem(self.horizontalSpacer_10)

        self.verticalLayout_4.addLayout(self.horizontalLayout_10)

        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
        self.radioButton_heatmap = QRadioButton(self.groupBox_joint_occupancy)
        self.radioButton_heatmap.setObjectName(u"radioButton_heatmap")

        self.horizontalLayout_3.addWidget(self.radioButton_heatmap)

        self.horizontalSpacer_4 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_3.addItem(self.horizontalSpacer_4)

        self.pushButton_save_jo = QPushButton(self.groupBox_joint_occupancy)
        self.pushButton_save_jo.setObjectName(u"pushButton_save_jo")

        self.horizontalLayout_3.addWidget(self.pushButton_save_jo)

        self.pushButton_plot_jo = QPushButton(self.groupBox_joint_occupancy)
        self.pushButton_plot_jo.setObjectName(u"pushButton_plot_jo")
        self.pushButton_plot_jo.setAutoDefault(False)

        self.horizontalLayout_3.addWidget(self.pushButton_plot_jo)

        self.verticalLayout_4.addLayout(self.horizontalLayout_3)

        self.verticalLayout_2.addWidget(self.groupBox_joint_occupancy)

        self.retranslateUi(GroupBox)

        QMetaObject.connectSlotsByName(GroupBox)

    # setupUi

    def retranslateUi(self, GroupBox):
        GroupBox.setWindowTitle(
            QCoreApplication.translate("GroupBox", u"GroupBox", None))
        self.groupBox_occupancy_histogram.setTitle(
            QCoreApplication.translate("GroupBox", u"Occupancy histogram",
                                       None))
        self.label_56.setText(
            QCoreApplication.translate("GroupBox", u"# of bins", None))
        self.lineEdit_bins.setText(
            QCoreApplication.translate("GroupBox", u"10", None))
        self.label_55.setText(
            QCoreApplication.translate("GroupBox", u"min. occupancy", None))
        self.lineEdit_minimum.setText(
            QCoreApplication.translate("GroupBox", u"0.0", None))
        self.label_17.setText(
            QCoreApplication.translate("GroupBox", u"max. occupancy", None))
        self.lineEdit_maximum.setText(
            QCoreApplication.translate("GroupBox", u"1.0", None))
        self.checkBox_cumulative_histogram.setText(
            QCoreApplication.translate("GroupBox", u"cumulative", None))
        self.checkBox_stacked_histogram.setText(
            QCoreApplication.translate("GroupBox", u"stacked", None))
        #if QT_CONFIG(tooltip)
        self.checkBox_color_segments_occupancy.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.checkBox_color_segments_occupancy.setText(
            QCoreApplication.translate("GroupBox", u"color by segment", None))
        self.pushButton_save_occupancy.setText(
            QCoreApplication.translate("GroupBox", u"Data", None))
        #if QT_CONFIG(tooltip)
        self.pushButton_plot_occupancy.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p>Compute histogram of H bond occupancies. Counts the number of H bonds with an occupancy equal or greater than the respective value.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.pushButton_plot_occupancy.setText(
            QCoreApplication.translate("GroupBox", u"Plot", None))
        self.groupBox_nb_connections.setTitle(
            QCoreApplication.translate("GroupBox",
                                       u"Number of connections time series",
                                       None))
        #if QT_CONFIG(tooltip)
        self.checkBox_color_segments_timeseries.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Toggle if histogram bars are colored by segment or molecule. With colors turned on, comparing to other analyses is not possible.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.checkBox_color_segments_timeseries.setText(
            QCoreApplication.translate("GroupBox", u"color by segment", None))
        self.pushButton_save_timeseries.setText(
            QCoreApplication.translate("GroupBox", u"Data", None))
        #if QT_CONFIG(tooltip)
        self.pushButton_plot_timeseries.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Compute the number of H bonds per frame.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.pushButton_plot_timeseries.setText(
            QCoreApplication.translate("GroupBox", u"Plot", None))
        self.groupBox_joint_occupancy.setTitle(
            QCoreApplication.translate("GroupBox", u"Joint Occupancy", None))
        self.radioButton_scatter.setText(
            QCoreApplication.translate("GroupBox", u"scatter plot", None))
        self.label_3.setText(
            QCoreApplication.translate("GroupBox", u"with dot size", None))
        self.lineEdit_scatter_size.setText(
            QCoreApplication.translate("GroupBox", u"1", None))
        self.lineEdit_scatter_size.setPlaceholderText(
            QCoreApplication.translate("GroupBox", u"0 - 100", None))
        self.radioButton_heatmap.setText(
            QCoreApplication.translate("GroupBox", u"heatmap", None))
        self.pushButton_save_jo.setText(
            QCoreApplication.translate("GroupBox", u"Data", None))
        #if QT_CONFIG(tooltip)
        self.pushButton_plot_jo.setToolTip(
            QCoreApplication.translate(
                "GroupBox",
                u"<html><head/><body><p align=\"justify\">Compute the joint occupancy of the H bond network. The joint occupancy is true, if all H bonds of the network are present in a frame and false otherwise.</p></body></html>",
                None))
        #endif // QT_CONFIG(tooltip)
        self.pushButton_plot_jo.setText(
            QCoreApplication.translate("GroupBox", u"Plot", None))
Пример #24
0
class App(QWidget):
    def __init__(self, bk, prefs):
        super().__init__()

        self.bk = bk
        self.prefs = prefs
        self.update = False

        # Install translator for the DOCXImport plugin dialog.
        # Use the Sigil language setting unless manually overridden.
        plugin_translator = QTranslator()
        if prefs['language_override'] is not None:
            print('Plugin preferences language override in effect')
            qmf = '{}_{}'.format(bk._w.plugin_name.lower(),
                                 prefs['language_override'])
        else:
            qmf = '{}_{}'.format(bk._w.plugin_name.lower(), bk.sigil_ui_lang)
        print(
            qmf,
            os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations'))
        plugin_translator.load(
            qmf,
            os.path.join(bk._w.plugin_dir, bk._w.plugin_name, 'translations'))
        print(QCoreApplication.instance().installTranslator(plugin_translator))

        self._ok_to_close = False

        self.FTYPE_MAP = {
            'smap': {
                'title': _translate('App', 'Select custom style-map file'),
                'defaultextension': '.txt',
                'filetypes': 'Text Files (*.txt);;All files (*.*)',
            },
            'css': {
                'title': _translate('App', 'Select custom CSS file'),
                'defaultextension': '.css',
                'filetypes': 'CSS Files (*.css)',
            },
            'docx': {
                'title': _translate('App', 'Select DOCX file'),
                'defaultextension': '.docx',
                'filetypes': 'DOCX Files (*.docx)',
            },
        }

        # Check online github files for newer version
        if self.prefs['check_for_updates']:
            self.update, self.newversion = self.check_for_update()
        self.initUI()

    def initUI(self):
        main_layout = QVBoxLayout(self)

        self.setWindowTitle('DOCXImport')
        self.upd_layout = QVBoxLayout()
        self.update_label = QLabel()
        self.update_label.setAlignment(Qt.AlignCenter)
        self.upd_layout.addWidget(self.update_label)
        self.get_update_button = QPushButton()
        self.get_update_button.clicked.connect(self.get_update)
        self.upd_layout.addWidget(self.get_update_button)
        main_layout.addLayout(self.upd_layout)
        if not self.update:
            self.update_label.hide()
            self.get_update_button.hide()

        self.details_grid = QGridLayout()
        self.epub2_select = QRadioButton()
        self.epub2_select.setText('EPUB2')
        self.epubType = QButtonGroup()
        self.epubType.addButton(self.epub2_select)
        self.details_grid.addWidget(self.epub2_select, 0, 0, 1, 1)
        self.checkbox_get_updates = QCheckBox()
        self.details_grid.addWidget(self.checkbox_get_updates, 0, 1, 1, 1)
        self.epub3_select = QRadioButton()
        self.epub3_select.setText('EPUB3')
        self.epubType.addButton(self.epub3_select)
        self.details_grid.addWidget(self.epub3_select, 1, 0, 1, 1)
        main_layout.addLayout(self.details_grid)
        self.checkbox_get_updates.setChecked(self.prefs['check_for_updates'])
        if self.prefs['epub_version'] == '2.0':
            self.epub2_select.setChecked(True)
        elif self.prefs['epub_version'] == '3.0':
            self.epub3_select.setChecked(True)
        else:
            self.epub2_select.setChecked(True)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle('')
        self.verticalLayout_2 = QVBoxLayout(self.groupBox)
        self.docx_grid = QGridLayout()
        self.docx_label = QLabel()
        self.docx_grid.addWidget(self.docx_label, 0, 0, 1, 1)
        self.docx_path = QLineEdit()
        self.docx_grid.addWidget(self.docx_path, 1, 0, 1, 1)
        self.choose_docx_button = QPushButton()
        self.choose_docx_button.setText('...')
        self.docx_grid.addWidget(self.choose_docx_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.docx_grid)
        self.choose_docx_button.clicked.connect(
            lambda: self.fileChooser('docx', self.docx_path))
        if len(self.prefs['lastDocxPath']):
            self.docx_path.setText(self.prefs['lastDocxPath'])
        self.docx_path.setEnabled(False)

        self.smap_grid = QGridLayout()
        self.checkbox_smap = QCheckBox(self.groupBox)
        self.smap_grid.addWidget(self.checkbox_smap, 0, 0, 1, 1)
        self.cust_smap_path = QLineEdit(self.groupBox)
        self.smap_grid.addWidget(self.cust_smap_path, 1, 0, 1, 1)
        self.choose_smap_button = QPushButton(self.groupBox)
        self.choose_smap_button.setText('...')
        self.smap_grid.addWidget(self.choose_smap_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.smap_grid)
        self.checkbox_smap.setChecked(self.prefs['useSmap'])
        self.checkbox_smap.stateChanged.connect(lambda: self.chkBoxActions(
            self.checkbox_smap, self.choose_smap_button))
        self.choose_smap_button.clicked.connect(
            lambda: self.fileChooser('smap', self.cust_smap_path, self.
                                     checkbox_smap, self.choose_smap_button))
        if len(self.prefs['useSmapPath']):
            self.cust_smap_path.setText(self.prefs['useSmapPath'])
        self.cust_smap_path.setEnabled(False)
        self.chkBoxActions(self.checkbox_smap, self.choose_smap_button)

        self.css_grid = QGridLayout()
        self.checkbox_css = QCheckBox(self.groupBox)
        self.css_grid.addWidget(self.checkbox_css, 0, 0, 1, 1)
        self.cust_css_path = QLineEdit(self.groupBox)
        self.css_grid.addWidget(self.cust_css_path, 1, 0, 1, 1)
        self.choose_css_button = QPushButton(self.groupBox)
        self.choose_css_button.setText('...')
        self.css_grid.addWidget(self.choose_css_button, 1, 1, 1, 1)
        self.verticalLayout_2.addLayout(self.css_grid)
        self.checkbox_css.setChecked(self.prefs['useCss'])
        self.checkbox_css.stateChanged.connect(lambda: self.chkBoxActions(
            self.checkbox_css, self.choose_css_button))
        self.choose_css_button.clicked.connect(
            lambda: self.fileChooser('css', self.cust_css_path, self.
                                     checkbox_css, self.choose_css_button))
        if len(self.prefs['useCssPath']):
            self.cust_css_path.setText(self.prefs['useCssPath'])
        self.cust_css_path.setEnabled(False)
        self.chkBoxActions(self.checkbox_css, self.choose_css_button)

        main_layout.addWidget(self.groupBox)
        self.checkbox_debug = QCheckBox()
        main_layout.addWidget(self.checkbox_debug)
        self.checkbox_debug.setChecked(self.prefs['debug'])

        spacerItem = QSpacerItem(20, 15, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        main_layout.addItem(spacerItem)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self._ok_clicked)
        button_box.rejected.connect(self._cancel_clicked)
        main_layout.addWidget(button_box)
        self.retranslateUi(self)
        if self.prefs['qt_geometry'] is not None:
            try:
                self.restoreGeometry(
                    QByteArray.fromHex(
                        self.prefs['qt_geometry'].encode('ascii')))
            except:
                pass
        self.show()

    def retranslateUi(self, App):
        self.update_label.setText(_translate('App', 'Plugin Update Available'))
        self.get_update_button.setText(_translate('App',
                                                  'Go to download page'))
        self.checkbox_get_updates.setText(
            _translate('App', 'Check for plugin updates'))
        self.docx_label.setText(_translate('App', 'DOCX File to import'))
        self.checkbox_smap.setText(_translate('App', 'Use Custom Style Map'))
        self.checkbox_css.setText(_translate('App', 'Use Custom CSS'))
        self.checkbox_debug.setText(
            _translate('App',
                       'Debug Mode (change takes effect next plugin run)'))

    def fileChooser(self, ftype, qlineedit, qcheck=None, qbutton=None):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        title = self.FTYPE_MAP[ftype]['title']
        startfolder = self.prefs['lastDir'][ftype]
        ffilter = self.FTYPE_MAP[ftype]['filetypes']
        inpath, _ = QFileDialog.getOpenFileName(self,
                                                title,
                                                startfolder,
                                                ffilter,
                                                options=options)
        if len(inpath):
            qlineedit.setEnabled(True)
            qlineedit.setText(os.path.normpath(inpath))
            self.prefs['lastDir'][ftype] = os.path.dirname(inpath)
            qlineedit.setEnabled(False)
        else:
            if qcheck is not None:
                qcheck.setChecked(False)
            if qbutton is not None:
                qbutton.setEnabled(False)

    def chkBoxActions(self, chk, btn):
        btn.setEnabled(chk.isChecked())

    def cmdDo(self):
        global _DETAILS
        self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode(
            'ascii')
        self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked()
        self.prefs['epub_version'] = self.epubType.checkedButton().text(
        )[-1] + '.0'
        self.prefs['debug'] = self.checkbox_debug.isChecked()
        _DETAILS['vers'] = self.epubType.checkedButton().text()[-1] + '.0'
        self.prefs['useSmap'] = self.checkbox_smap.isChecked()
        if self.checkbox_smap.isChecked():
            if len(self.cust_smap_path.text()):
                self.prefs['useSmapPath'] = self.cust_smap_path.text()
                _DETAILS['smap'] = (self.checkbox_smap.isChecked(),
                                    self.cust_smap_path.text())
            else:
                # Message box that no file is selected
                return
        self.prefs['useCss'] = self.checkbox_css.isChecked()
        if self.checkbox_css.isChecked():
            if len(self.cust_css_path.text()):
                self.prefs['useCssPath'] = self.cust_css_path.text()
                _DETAILS['css'] = (self.checkbox_css.isChecked(),
                                   self.cust_css_path.text())
            else:
                # Message box that no file is selected
                return
        if len(self.docx_path.text()):
            self.prefs['lastDocxPath'] = self.docx_path.text()
            _DETAILS['docx'] = self.docx_path.text()
        else:
            # Message box that no file is selected
            return

    def check_for_update(self):
        '''Use updatecheck.py to check for newer versions of the plugin'''
        chk = UpdateChecker(self.prefs['last_time_checked'], self.bk._w)
        update_available, online_version, time = chk.update_info()
        # update preferences with latest date/time/version
        self.prefs['last_time_checked'] = time
        if online_version is not None:
            self.prefs['last_online_version'] = online_version
        if update_available:
            return (True, online_version)
        return (False, online_version)

    def get_update(self):
        url = DOWNLOAD_PAGE
        if self.update:
            latest = '/tag/v{}'.format(self.newversion)
            url = url + latest
        webbrowser.open_new_tab(url)

    def _ok_clicked(self):
        self._ok_to_close = True
        self.cmdDo()
        self.bk.savePrefs(self.prefs)
        QCoreApplication.instance().quit()

    def _cancel_clicked(self):
        self._ok_to_close = True
        '''Close aborting any changes'''
        self.prefs['qt_geometry'] = self.saveGeometry().toHex().data().decode(
            'ascii')
        self.prefs['check_for_updates'] = self.checkbox_get_updates.isChecked()
        self.prefs['debug'] = self.checkbox_debug.isChecked()
        self.bk.savePrefs(self.prefs)
        QCoreApplication.instance().quit()

    def closeEvent(self, event):
        if self._ok_to_close:
            event.accept()  # let the window close
        else:
            self._cancel_clicked()
Пример #25
0
class DataBrowserMain(QWidget):
    sliceUpdated = Signal(int, int, int, int)

    def __init__(self, parent):
        super(DataBrowserMain, self).__init__(parent)

        # data import
        self.brkraw_obj = self.parent().brkraw_obj
        self.selectedScan = None
        self.selectedScanTR = None

        self.set_viewer_frame()
        self.set_controller_frame()
        self.set_gridlayouts()
        self.set_font()
        # self.set_palette()  # TODO
        self.set_size()
        self.set_objectnames()
        self.set_texts()
        self.ratio_container = []
        self.init_connection()
        self.inactivate_widgets()  # Inactivate during startup

    def init_connection(self):
        self.parent().dataSelected.connect(
            self.selectScanEvent)  # run selectScanEvent when data selected
        self.event_timer = QTimer()
        self.event_timer.timeout.connect(self.sliceUpdateEvent)  #
        self.sliceUpdated.connect(self.updateImage)

        self.xaxis_slider.valueChanged.connect(self.xaxis_spinbox.setValue)
        self.xaxis_spinbox.valueChanged.connect(self.xaxis_slider.setValue)
        self.yaxis_slider.valueChanged.connect(self.yaxis_spinbox.setValue)
        self.yaxis_spinbox.valueChanged.connect(self.yaxis_slider.setValue)
        self.zaxis_slider.valueChanged.connect(self.zaxis_spinbox.setValue)
        self.zaxis_spinbox.valueChanged.connect(self.zaxis_slider.setValue)
        self.frame_slider.valueChanged.connect(self.frame_spinbox.setValue)
        self.frame_spinbox.valueChanged.connect(self.frame_slider.setValue)

        self.axial_view.pointed.connect(self.axialview_pointing_event)
        self.sagittal_view.pointed.connect(self.sagittalview_pointing_event)
        self.coronal_view.pointed.connect(self.coronalview_pointing_event)

        self.connect_sliders_to_update()

    def sagittalview_pointing_event(self, pos_x, pos_y, meta):
        max_x = self.yaxis_slider.maximum()
        max_y = self.zaxis_slider.maximum()

        # print(pos_x, pos_y, max_x, max_y)
        self.yaxis_slider.setValue(int(max_x * pos_x))
        self.zaxis_slider.setValue(max_y - int(max_y * pos_y))
        # print(int(max_x * pos_x), int(max_y * pos_y))

    def axialview_pointing_event(self, pos_x, pos_y, meta):
        max_x = self.yaxis_slider.maximum()
        max_y = self.xaxis_slider.maximum()

        # print(pos_x, pos_y, max_x, max_y)
        self.yaxis_slider.setValue(int(max_x * pos_x))
        self.xaxis_slider.setValue(int(max_y * pos_y))
        # print(int(max_x * pos_x), int(max_y * pos_y))

    def coronalview_pointing_event(self, pos_x, pos_y, meta):
        max_x = self.xaxis_slider.maximum()
        max_y = self.zaxis_slider.maximum()

        # print(pos_x, pos_y, max_x, max_y)
        self.xaxis_slider.setValue(int(max_x * pos_x))
        self.zaxis_slider.setValue(max_y - int(max_y * pos_y))
        # print(int(max_x * pos_x), int(max_y * pos_y))

    def sliderChangeEvent(self):
        self.event_timer.start(10)

    def sliceUpdateEvent(self):
        # This will executed only when timer timeout
        x = self.xaxis_slider.value()
        y = self.yaxis_slider.value()
        z = self.zaxis_slider.value()
        t = self.frame_slider.value()
        self.sliceUpdated.emit(x, y, z, t)
        self.event_timer.stop()

    @staticmethod
    def slice_data(dataobj, slice_orient, slice_num):
        if slice_orient == 'axial':
            sliced_data = dataobj[:, :, slice_num]
        elif slice_orient == 'sagittal':
            sliced_data = dataobj[:, slice_num, ::-1]
        elif slice_orient == 'coronal':
            sliced_data = dataobj[slice_num, :, ::-1]
        else:
            popup_error_dialog(UnexpectedError.message)
            return None
        return sliced_data

    def updateImage(self, x, y, z, frame):
        if len(self.selectedScan.shape) == 4:
            dataobj = self.selectedScan[:, :, :, frame]
        else:
            dataobj = self.selectedScan[...]

        data_xy = self.slice_data(dataobj, 'axial', z)
        data_yz = self.slice_data(dataobj, 'sagittal', x)
        data_xz = self.slice_data(dataobj, 'coronal', y)
        ratio_xy, ratio_yz, ratio_xz = self.ratio_container
        # ratio_xy, ratio_yz, ratio_xz = 1, 1, 1

        qm_xy = convert_arr2qpixmap(data_xy, ratio_xy)
        qm_yz = convert_arr2qpixmap(data_yz, ratio_yz)
        qm_xz = convert_arr2qpixmap(data_xz, ratio_xz)

        self.axial_view.setPixmap(qm_xy)
        self.sagittal_view.setPixmap(qm_yz)
        self.coronal_view.setPixmap(qm_xz)

    def selectScanEvent(self, delivery_package: list):
        """ this event is occurring when a scan selected on scanlist """
        self.axial_view.setEnabled(True)
        self.sagittal_view.setEnabled(True)
        self.coronal_view.setEnabled(True)
        self.selectedScan, affine, resol, self.selectedScanTR, is_localizer = delivery_package
        self.selectedScanTR /= 1000

        from slfmri.imgman import reorient_to_ras, determine_slice_plane
        slice_plane_ref = dict(sagittal=0, coronal=1, axial=2)

        if is_localizer:
            img_container = dict()
            for i, aff in enumerate(affine):
                size = config.get('ImageViewer', 'size')
                data = self.selectedScan[..., i]
                slice_plane = determine_slice_plane(2, aff, resol)
                ras_data, ras_resol = reorient_to_ras(data[:, :, np.newaxis],
                                                      aff, resol)
                slice_axis = slice_plane_ref[slice_plane]
                ras_data = ras_data.mean(slice_axis)
                ras_resol = np.delete(ras_resol, slice_axis)
                qpixmap = convert_arr2qpixmap(ras_data, ras_resol, size)
                img_container[slice_plane] = qpixmap

            self.update_axisview(img_container)
        else:
            # other than localizer
            self.init_data(self.selectedScan)
            matrix_size = np.asarray(self.selectedScan.shape)
            resol = np.asarray(resol)
            fov = matrix_size[:3] * resol
            self.ratio_container = [
                fov[0] / fov[1], fov[1] / fov[2], fov[0] / fov[2]
            ]
            # reset value
            init_x, init_y, init_z = (np.asarray(self.selectedScan.shape[:3]) /
                                      2.0).astype(int)
            init_f = 0

            self.disconnect_sliders_to_update()
            self.xaxis_slider.setValue(init_x)
            self.yaxis_slider.setValue(init_y)
            self.zaxis_slider.setValue(init_z)
            self.frame_slider.setValue(init_f)
            self.connect_sliders_to_update()
            self.updateImage(init_x, init_y, init_z, init_f)

    def connect_sliders_to_update(self):
        # connect to check slice update
        self.xaxis_slider.valueChanged.connect(self.sliderChangeEvent)
        self.yaxis_slider.valueChanged.connect(self.sliderChangeEvent)
        self.zaxis_slider.valueChanged.connect(self.sliderChangeEvent)
        self.frame_slider.valueChanged.connect(self.sliderChangeEvent)

    def disconnect_sliders_to_update(self):
        # disconnect to check slice update
        self.xaxis_slider.valueChanged.disconnect(self.sliderChangeEvent)
        self.yaxis_slider.valueChanged.disconnect(self.sliderChangeEvent)
        self.zaxis_slider.valueChanged.disconnect(self.sliderChangeEvent)
        self.frame_slider.valueChanged.disconnect(self.sliderChangeEvent)

    def init_data(self, dataobj):
        self.slicecontrol_pane.setEnabled(True)
        dim = len(dataobj.shape)
        if dim == 3:
            size_x, size_y, size_z = dataobj.shape
            size_frame = None
        elif dim == 4:
            size_x, size_y, size_z, size_frame = dataobj.shape
        else:
            popup_error_dialog(UnexpectedError.message)
            return None

        # init sliders and spinboxes
        self.xaxis_slider.setRange(0, size_x - 1)
        self.yaxis_slider.setRange(0, size_y - 1)
        self.zaxis_slider.setRange(0, size_z - 1)

        self.xaxis_spinbox.setRange(0, size_x - 1)
        self.yaxis_spinbox.setRange(0, size_y - 1)
        self.zaxis_spinbox.setRange(0, size_z - 1)

        if dim == 3:
            self.frame_label.setDisabled(True)
            self.frame_slider.setDisabled(True)
            self.frame_spinbox.setDisabled(True)
        else:
            self.frame_label.setEnabled(True)
            self.frame_slider.setEnabled(True)
            self.frame_spinbox.setEnabled(True)
            self.frame_slider.setRange(0, size_frame - 1)
            self.frame_spinbox.setRange(0, size_frame - 1)

    def update_axisview(self, img_container: dict):
        for view_plane, pixmap in img_container.items():
            if view_plane == 'axial':
                self.axial_view.setPixmap(pixmap)
            elif view_plane == 'sagittal':
                self.sagittal_view.setPixmap(pixmap)
            else:
                self.coronal_view.setPixmap(pixmap)

    def inactivate_widgets(self):
        self.slicecontrol_pane.setDisabled(True)
        self.graph_frame.setDisabled(True)

    def set_navigationmode(self):
        # mouse click will navigate slice.
        pass

    def set_drawingmode(self):
        # roi drawing function
        pass

    def mask_data_handler(self):
        # mask later handler
        pass

    def slider_event_related(self):
        # slider for slicing.
        pass

    def set_viewer_frame(self):
        self.imageframe = QFrame(self)
        self.axial_view = SliceViewer(self.imageframe)
        self.axial_view.setDisabled(True)
        self.sagittal_view = SliceViewer(self.imageframe)
        self.sagittal_view.setDisabled(True)
        self.coronal_view = SliceViewer(self.imageframe)
        self.coronal_view.setDisabled(True)

        # TODO: Will reactivate these on later version
        # self.axial_title = QLabel(self.imageframe)
        # self.coronal_title = QLabel(self.imageframe)
        # self.sagittal_title = QLabel(self.imageframe)
        #
        # self.axialL_label = QLabel(self.imageframe)
        # self.axialA_label = QLabel(self.imageframe)
        # self.axialR_label = QLabel(self.imageframe)
        # self.axialP_label = QLabel(self.imageframe)
        #
        # self.sagittalS_label = QLabel(self.imageframe)
        # self.sagittalA_label = QLabel(self.imageframe)
        # self.sagittalI_label = QLabel(self.imageframe)
        # self.sagittalP_label = QLabel(self.imageframe)
        #
        # self.coronalL_label = QLabel(self.imageframe)
        # self.coronalS_label = QLabel(self.imageframe)
        # self.coronalR_label = QLabel(self.imageframe)
        # self.coronalI_label = QLabel(self.imageframe)
        #
        # self.axial_title.setTextFormat(Qt.MarkdownText)
        # self.axialL_label.setTextFormat(Qt.MarkdownText)
        # self.axialA_label.setTextFormat(Qt.MarkdownText)
        # self.axialR_label.setTextFormat(Qt.MarkdownText)
        # self.axialP_label.setTextFormat(Qt.MarkdownText)
        #
        # self.sagittal_title.setTextFormat(Qt.MarkdownText)
        # self.sagittalS_label.setTextFormat(Qt.MarkdownText)
        # self.sagittalA_label.setTextFormat(Qt.MarkdownText)
        # self.sagittalI_label.setTextFormat(Qt.MarkdownText)
        # self.sagittalP_label.setTextFormat(Qt.MarkdownText)
        #
        # self.coronal_title.setTextFormat(Qt.MarkdownText)
        # self.coronalL_label.setTextFormat(Qt.MarkdownText)
        # self.coronalS_label.setTextFormat(Qt.MarkdownText)
        # self.coronalR_label.setTextFormat(Qt.MarkdownText)
        # self.coronalI_label.setTextFormat(Qt.MarkdownText)
        #
        # self.axial_title.setAlignment(Qt.AlignCenter)
        # self.axialL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
        # self.axialA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        # self.axialR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)
        # self.axialP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
        #
        # self.sagittal_title.setAlignment(Qt.AlignCenter)
        # self.sagittalS_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
        # self.sagittalA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        # self.sagittalI_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)
        # self.sagittalP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
        #
        # self.coronal_title.setAlignment(Qt.AlignCenter)
        # self.coronalL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
        # self.coronalS_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        # self.coronalR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)
        # self.coronalI_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)

    def set_controller_frame(self):
        self.controller_frame = QFrame(self)
        self.slicecontrol_pane = QGroupBox(self.controller_frame)
        self.frame_spinbox = QSpinBox(self.slicecontrol_pane)

        self.xaxis_label = QLabel(self.slicecontrol_pane)
        self.yaxis_label = QLabel(self.slicecontrol_pane)
        self.zaxis_label = QLabel(self.slicecontrol_pane)
        self.frame_label = QLabel(self.slicecontrol_pane)

        self.xaxis_slider = QSlider(self.slicecontrol_pane)
        self.yaxis_slider = QSlider(self.slicecontrol_pane)
        self.zaxis_slider = QSlider(self.slicecontrol_pane)
        self.frame_slider = QSlider(self.slicecontrol_pane)

        self.xaxis_spinbox = QSpinBox(self.slicecontrol_pane)
        self.yaxis_spinbox = QSpinBox(self.slicecontrol_pane)
        self.zaxis_spinbox = QSpinBox(self.slicecontrol_pane)

        self.graph_frame = QFrame(self)
        self.graph_view = pg.PlotWidget(self.graph_frame)
        self.graph_view.setBackground('w')

        # TODO: Will reactivate these on later version
        # self.graph_view = QGraphicsView(self.graph_frame)
        # self.graphcontrol_pane = QGroupBox(self.graph_frame)
        # self.addmask_button = QPushButton(self.graphcontrol_pane)
        # self.removemask_button = QPushButton(self.graphcontrol_pane)
        # self.mask_listview = QListView(self.graphcontrol_pane)
        # self.savepng_button = QPushButton(self.graphcontrol_pane)
        # self.savecsv_button = QPushButton(self.graphcontrol_pane)

        self.axial_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.sagittal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.coronal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

        self.xaxis_slider.setOrientation(Qt.Horizontal)
        self.yaxis_slider.setOrientation(Qt.Horizontal)
        self.zaxis_slider.setOrientation(Qt.Horizontal)
        self.frame_slider.setOrientation(Qt.Horizontal)

        self.slicecontrol_pane.setAlignment(Qt.AlignCenter)
        self.xaxis_label.setAlignment(Qt.AlignCenter)
        self.yaxis_label.setAlignment(Qt.AlignCenter)
        self.zaxis_label.setAlignment(Qt.AlignCenter)
        self.frame_label.setAlignment(Qt.AlignCenter)
        # TODO: Will reactivate these on later version
        # self.graphcontrol_pane.setAlignment(Qt.AlignCenter)

    def set_size(self):
        size = int(config.get('ImageViewer', 'size'))
        self.imageframe.setLineWidth(0)
        self.axial_view.setMinimumSize(QSize(size, size))
        self.axial_view.setMaximumSize(QSize(size, size))
        self.axial_view.setLineWidth(0)
        self.sagittal_view.setMinimumSize(QSize(size, size))
        self.sagittal_view.setMaximumSize(QSize(size, size))
        self.sagittal_view.setLineWidth(0)
        self.coronal_view.setMinimumSize(QSize(size, size))
        self.coronal_view.setMaximumSize(QSize(size, size))
        self.coronal_view.setLineWidth(0)

        # TODO: Will reactivate these on later version
        # self.axialL_label.setMinimumSize(QSize(20, 0))
        # self.axialA_label.setMinimumSize(QSize(0, 20))
        # self.axialR_label.setMinimumSize(QSize(20, 0))
        # self.axialP_label.setMinimumSize(QSize(0, 20))
        # self.sagittalS_label.setMinimumSize(QSize(20, 0))
        # self.sagittalA_label.setMinimumSize(QSize(0, 20))
        # self.sagittalI_label.setMinimumSize(QSize(20, 0))
        # self.sagittalP_label.setMinimumSize(QSize(0, 20))
        # self.coronalL_label.setMinimumSize(QSize(20, 0))
        # self.coronalS_label.setMinimumSize(QSize(0, 20))
        # self.coronalR_label.setMinimumSize(QSize(20, 0))
        # self.coronalI_label.setMinimumSize(QSize(0, 20))

        self.controller_frame.setMinimumSize(QSize(300, 300))
        self.controller_frame.setMaximumSize(QSize(400, 300))
        self.graph_frame.setMinimumSize(QSize(0, 300))
        self.graph_frame.setMaximumSize(QSize(4000, 4000))
        self.graph_view.setMaximumSize(QSize(4000, 600))

        # TODO: Will reactivate these on later version
        # self.graphcontrol_pane.setMinimumSize(QSize(300, 0))
        # self.graphcontrol_pane.setMaximumSize(QSize(300, 4000))
        # self.addmask_button.setMinimumSize(QSize(30, 0))
        # self.addmask_button.setMaximumSize(QSize(30, 4000))
        # self.removemask_button.setMinimumSize(QSize(30, 0))
        # self.removemask_button.setMaximumSize(QSize(30, 4000))

    def set_font(self):
        self.arial_8 = QFont()
        self.arial_8.setFamily(u"Arial")
        self.arial_8.setPointSize(8)
        self.setFont(self.arial_8)
        # TODO: Will reactivate these on later version
        # self.axial_title.setFont(self.arial_8)
        # self.coronal_title.setFont(self.arial_8)
        # self.sagittal_title.setFont(self.arial_8)
        # self.axialL_label.setFont(self.arial_8)
        # self.axialA_label.setFont(self.arial_8)
        # self.axialR_label.setFont(self.arial_8)
        # self.axialP_label.setFont(self.arial_8)
        # self.sagittalS_label.setFont(self.arial_8)
        # self.sagittalA_label.setFont(self.arial_8)
        # self.sagittalI_label.setFont(self.arial_8)
        # self.sagittalP_label.setFont(self.arial_8)
        # self.coronalL_label.setFont(self.arial_8)
        # self.coronalS_label.setFont(self.arial_8)
        # self.coronalR_label.setFont(self.arial_8)
        # self.coronalI_label.setFont(self.arial_8)
        self.slicecontrol_pane.setFont(self.arial_8)

        # TODO: Will reactivate these on later version
        # self.xaxis_label.setFont(self.arial_8)
        # self.yaxis_label.setFont(self.arial_8)
        # self.zaxis_label.setFont(self.arial_8)
        # self.frame_label.setFont(self.arial_8)
        # self.graphcontrol_pane.setFont(self.arial_8)
        # self.addmask_button.setFont(self.arial_8)
        # self.removemask_button.setFont(self.arial_8)
        # self.savepng_button.setFont(self.arial_8)
        # self.savecsv_button.setFont(self.arial_8)

    def set_palette(self):
        # Brush
        gray_text = QBrush(QColor(171, 171, 171, 255))
        gray_text.setStyle(Qt.SolidPattern)
        black_background = QBrush(QColor(0, 0, 0, 255))
        black_background.setStyle(Qt.SolidPattern)

        self.orientation_label_palette = QPalette()
        self.orientation_label_palette.setBrush(QPalette.Active,
                                                QPalette.WindowText, gray_text)
        self.orientation_label_palette.setBrush(QPalette.Inactive,
                                                QPalette.WindowText, gray_text)
        self.orientation_label_palette.setBrush(QPalette.Disabled,
                                                QPalette.WindowText, gray_text)
        self.ortho_viewer_palette = QPalette()
        self.ortho_viewer_palette.setBrush(QPalette.Active, QPalette.Base,
                                           black_background)
        self.ortho_viewer_palette.setBrush(QPalette.Inactive, QPalette.Base,
                                           black_background)
        self.ortho_viewer_palette.setBrush(QPalette.Disabled, QPalette.Base,
                                           black_background)

        self.axialA_label.setPalette(self.orientation_label_palette)
        self.axialL_label.setPalette(self.orientation_label_palette)
        self.axialR_label.setPalette(self.orientation_label_palette)
        self.axialP_label.setPalette(self.orientation_label_palette)
        self.axial_view.setPalette(self.ortho_viewer_palette)
        self.sagittalS_label.setPalette(self.orientation_label_palette)
        self.sagittalA_label.setPalette(self.orientation_label_palette)
        self.sagittalI_label.setPalette(self.orientation_label_palette)
        self.sagittalP_label.setPalette(self.orientation_label_palette)
        self.sagittal_view.setPalette(self.ortho_viewer_palette)
        self.coronalL_label.setPalette(self.orientation_label_palette)
        self.coronalS_label.setPalette(self.orientation_label_palette)
        self.coronalR_label.setPalette(self.orientation_label_palette)
        self.coronalI_label.setPalette(self.orientation_label_palette)
        self.coronal_view.setPalette(self.ortho_viewer_palette)

    def set_gridlayouts(self):
        self.axial_gridLayout = QGridLayout()
        self.coronal_gridLayout = QGridLayout()
        self.sagittal_gridLayout = QGridLayout()
        self.imagecont_gridLayout = QGridLayout(self.slicecontrol_pane)
        self.imageframe_gridLayout = QGridLayout(self.imageframe)
        # self.graphcontrol_gridLayout = QGridLayout(self.graphcontrol_pane)
        self.verticalLayout = QVBoxLayout(self.controller_frame)
        self.horizontalLayout = QHBoxLayout(self.graph_frame)
        self.main_gridLayout = QGridLayout(self)
        # TODO: Will reactivate these on later version
        # self.imageframe_gridLayout.addWidget(self.axial_title, 0, 1, 1, 1)
        # self.imageframe_gridLayout.addWidget(self.coronal_title, 0, 2, 1, 1)
        # self.imageframe_gridLayout.addWidget(self.sagittal_title, 0, 0, 1, 1)
        # self.axial_gridLayout.addWidget(self.axialL_label, 1, 0, 1, 1)
        # self.axial_gridLayout.addWidget(self.axialA_label, 0, 1, 1, 1)
        # self.axial_gridLayout.addWidget(self.axialR_label, 1, 2, 1, 1)
        # self.axial_gridLayout.addWidget(self.axialP_label, 2, 1, 1, 1)
        self.axial_gridLayout.addWidget(self.axial_view, 1, 1, 1, 1)
        # self.sagittal_gridLayout.addWidget(self.sagittalS_label, 1, 0, 1, 1)
        # self.sagittal_gridLayout.addWidget(self.sagittalA_label, 0, 1, 1, 1)
        # self.sagittal_gridLayout.addWidget(self.sagittalI_label, 1, 2, 1, 1)
        # self.sagittal_gridLayout.addWidget(self.sagittalP_label, 2, 1, 1, 1)
        self.sagittal_gridLayout.addWidget(self.sagittal_view, 1, 1, 1, 1)
        # self.coronal_gridLayout.addWidget(self.coronalL_label, 1, 0, 1, 1)
        # self.coronal_gridLayout.addWidget(self.coronalS_label, 0, 1, 1, 1)
        # self.coronal_gridLayout.addWidget(self.coronalR_label, 1, 2, 1, 1)
        # self.coronal_gridLayout.addWidget(self.coronalI_label, 2, 1, 1, 1)
        self.coronal_gridLayout.addWidget(self.coronal_view, 1, 1, 1, 1)
        self.imagecont_gridLayout.addWidget(self.xaxis_label, 0, 0, 1, 1)
        self.imagecont_gridLayout.addWidget(self.xaxis_slider, 0, 1, 1, 1)
        self.imagecont_gridLayout.addWidget(self.xaxis_spinbox, 0, 2, 1, 1)
        self.imagecont_gridLayout.addWidget(self.yaxis_label, 1, 0, 1, 1)
        self.imagecont_gridLayout.addWidget(self.yaxis_slider, 1, 1, 1, 1)
        self.imagecont_gridLayout.addWidget(self.yaxis_spinbox, 1, 2, 1, 1)
        self.imagecont_gridLayout.addWidget(self.zaxis_label, 2, 0, 1, 1)
        self.imagecont_gridLayout.addWidget(self.zaxis_slider, 2, 1, 1, 1)
        self.imagecont_gridLayout.addWidget(self.zaxis_spinbox, 2, 2, 1, 1)
        self.imagecont_gridLayout.addWidget(self.frame_label, 3, 0, 1, 1)
        self.imagecont_gridLayout.addWidget(self.frame_slider, 3, 1, 1, 1)
        self.imagecont_gridLayout.addWidget(self.frame_spinbox, 3, 2, 1, 1)
        self.imageframe_gridLayout.addLayout(self.axial_gridLayout, 1, 1, 1, 1)
        self.imageframe_gridLayout.addLayout(self.coronal_gridLayout, 1, 2, 1,
                                             1)
        self.imageframe_gridLayout.addLayout(self.sagittal_gridLayout, 1, 0, 1,
                                             1)
        # self.graphcontrol_gridLayout.addWidget(self.addmask_button, 3, 0, 1, 1)
        # self.graphcontrol_gridLayout.addWidget(self.removemask_button, 3, 1, 1, 1)
        # self.graphcontrol_gridLayout.addWidget(self.mask_listview, 0, 0, 1, 5)
        # self.graphcontrol_gridLayout.addWidget(self.savepng_button, 3, 4, 1, 1)
        # self.graphcontrol_gridLayout.addWidget(self.savecsv_button, 3, 3, 1, 1)
        self.verticalLayout.addWidget(self.slicecontrol_pane)
        self.horizontalLayout.addWidget(self.graph_view)
        # self.horizontalLayout.addWidget(self.graphcontrol_pane)
        self.main_gridLayout.addWidget(self.imageframe, 0, 0, 1, 2)
        self.main_gridLayout.addWidget(self.controller_frame, 1, 0, 1, 1)
        self.main_gridLayout.addWidget(self.graph_frame, 1, 1, 1, 1)

    def set_objectnames(self):
        self.setObjectName(u"data_browser")
        self.imageframe.setObjectName(u"image_frame")
        self.axial_gridLayout.setObjectName(u"axial_gridLayout")
        self.coronal_gridLayout.setObjectName(u"coronal_gridLayout")
        self.sagittal_gridLayout.setObjectName(u"sagittal_gridLayout")
        # TODO: Will reactivate these on later version
        # self.axial_title.setObjectName(u"axial_label")
        # self.coronal_title.setObjectName(u"coronal_label")
        # self.sagittal_title.setObjectName(u"sagittal_label")
        self.axial_view.setObjectName(u"axial_view")
        self.sagittal_view.setObjectName(u"sagittal_view")
        self.coronal_view.setObjectName(u"coronal_view")
        # self.axialL_label.setObjectName(u"axialL_label")
        # self.axialR_label.setObjectName(u"axialR_label")
        # self.axialA_label.setObjectName(u"axialA_label")
        # self.axialP_label.setObjectName(u"axialP_label")
        # self.sagittalS_label.setObjectName(u"sagittalS_label")
        # self.sagittalA_label.setObjectName(u"sagittalA_label")
        # self.sagittalI_label.setObjectName(u"sagittalI_label")
        # self.sagittalP_label.setObjectName(u"sagittalP_label")
        # self.coronalL_label.setObjectName(u"coronalL_label")
        # self.coronalS_label.setObjectName(u"coronalS_label")
        # self.coronalR_label.setObjectName(u"coronalR_label")
        # self.coronalI_label.setObjectName(u"coronalI_label")
        self.controller_frame.setObjectName(u"controller_frame")
        self.slicecontrol_pane.setObjectName(u"slicecontrol_pane")
        self.xaxis_label.setObjectName(u"xaxis_label")
        self.xaxis_slider.setObjectName(u"xaxis_slider")
        self.xaxis_spinbox.setObjectName(u"xaxis_spinbox")
        self.yaxis_label.setObjectName(u"yaxis_label")
        self.yaxis_slider.setObjectName(u"yaxis_slider")
        self.yaxis_spinbox.setObjectName(u"yaxis_spinbox")
        self.zaxis_label.setObjectName(u"zaxis_label")
        self.zaxis_slider.setObjectName(u"zaxis_slider")
        self.zaxis_spinbox.setObjectName(u"zaxis_spinbox")
        self.frame_label.setObjectName(u"frame_label")
        self.frame_slider.setObjectName(u"frame_slider")
        self.frame_spinbox.setObjectName(u"frame_spinbox")
        self.graph_frame.setObjectName(u"graph_frame")
        self.graph_view.setObjectName(u"graph_view")
        # TODO: Will reactivate these on later version
        # self.graphcontrol_pane.setObjectName(u"graphcontrol_pane")
        # self.addmask_button.setObjectName(u"addmask_button")
        # self.removemask_button.setObjectName(u"removemask_button")
        # self.mask_listview.setObjectName(u"mask_listview")
        # self.savepng_button.setObjectName(u"savepng_button")
        # self.savecsv_button.setObjectName(u"savecsv_button")
        self.imagecont_gridLayout.setObjectName(u"imagecont_gridLayout")
        self.imageframe_gridLayout.setObjectName(u"imageframe_gridLayout")
        # self.graphcontrol_gridLayout.setObjectName(u"graphcontrol_gridLayout")
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.main_gridLayout.setObjectName(u"main_gridLayout")
        QMetaObject.connectSlotsByName(self)

    def set_texts(self):
        self.setWindowTitle(u"Data Browser")
        # TODO: Will reactivate these on later version
        # self.axial_title.setText(u"**Axial**")
        # self.coronal_title.setText(u"**Coronal**")
        # self.sagittal_title.setText(u"**Sagittal**")
        # self.sagittalS_label.setText(u"**S**")
        # self.sagittalA_label.setText(u"**A**")
        # self.sagittalI_label.setText(u"**I**")
        # self.sagittalP_label.setText(u"**P**")
        # self.axialL_label.setText(u"**L**")
        # self.axialA_label.setText(u"**A**")
        # self.axialR_label.setText(u"**R**")
        # self.axialP_label.setText( u"**P**")
        # self.coronalL_label.setText(u"**L**")
        # self.coronalS_label.setText(u"**S**")
        # self.coronalR_label.setText(u"**R**")
        # self.coronalI_label.setText(u"**I**")
        self.slicecontrol_pane.setTitle(u"Slice Control Pane")
        self.xaxis_label.setText(u"x")
        self.yaxis_label.setText(u"y")
        self.zaxis_label.setText(u"z")
        self.frame_label.setText(u"Frame")
        # TODO: Will reactivate these on later version
        # self.graphcontrol_pane.setTitle(u"Graph Control Pane")
        # self.addmask_button.setText(u"+")
        # self.removemask_button.setText(u"-")
        # self.savepng_button.setText(u"toPNG")
        # self.savecsv_button.setText(u"toCSV")

    def plot_timecourse(self, x, y):
        self.graph_frame.setEnabled(True)
        self.graph_view.clear()
        pen = pg.mkPen(color=(255, 0, 0))
        if x is None:
            x = [0]
            y = [y]
            self.graph_view.plot(x, y, pen=pen, symbol='o')
        else:
            self.graph_view.plot(x, y, pen=pen)

    def get_coord(self):
        x = self.xaxis_slider.value()
        y = self.yaxis_slider.value()
        z = self.zaxis_slider.value()
        return (x, y, z)
class ChapterSelectionSetting(GlobalSetting):
    tab_clicked_signal = Signal()
    activation_signal = Signal(bool)

    def __init__(self):
        super().__init__()
        self.create_properties()
        self.create_widgets()
        self.setup_widgets()
        self.connect_signals()

    def create_widgets(self):
        self.chapter_source_label = QLabel("Chapter Source Folder:")
        self.chapter_extension_label = QLabel("Chapter Extension:")
        self.chapter_source_lineEdit = ChapterSourceLineEdit()
        self.chapter_source_button = ChapterSourceButton()
        self.chapter_extensions_comboBox = ChapterExtensionsCheckableComboBox()
        self.chapter_match_layout = MatchChapterLayout(parent=self)
        self.chapter_options_layout = QHBoxLayout()
        self.MainLayout = QVBoxLayout()
        self.main_layout = QGridLayout()
        self.chapter_main_groupBox = QGroupBox()
        self.chapter_match_groupBox = QGroupBox("Chapter Matching")
        self.chapter_match_groupBox.setLayout(self.chapter_match_layout)

    def setup_widgets(self):
        self.setup_chapter_main_groupBox()
        self.setup_layouts()

    # noinspection PyUnresolvedReferences
    def connect_signals(self):
        self.chapter_main_groupBox.toggled.connect(self.activate_tab)
        self.chapter_source_button.clicked_signal.connect(
            self.update_folder_path)
        self.chapter_source_lineEdit.edit_finished_signal.connect(
            self.update_folder_path)
        self.chapter_extensions_comboBox.close_list.connect(
            self.check_extension_changes)
        self.chapter_match_layout.sync_chapter_files_with_global_files_after_swap_signal.connect(
            self.sync_chapter_files_with_global_files)
        self.tab_clicked_signal.connect(self.tab_clicked)

    def create_properties(self):
        self.folder_path = ""
        self.files_names_list = []
        self.files_names_absolute_list = []
        self.current_chapter_extensions = [Default_Chapter_Extension]

    def setup_layouts(self):
        self.setup_chapter_options_layout()
        self.setup_main_layout()
        self.setLayout(self.MainLayout)
        self.MainLayout.addWidget(self.chapter_main_groupBox)

    def setup_chapter_options_layout(self):
        self.chapter_options_layout.addWidget(self.chapter_extensions_comboBox)
        self.chapter_options_layout.addStretch()

    def setup_main_layout(self):
        self.main_layout.addWidget(self.chapter_source_label, 0, 0)
        self.main_layout.addWidget(self.chapter_source_lineEdit, 0, 1, 1, 1)
        self.main_layout.addWidget(self.chapter_source_button, 0, 2)
        self.main_layout.addWidget(self.chapter_extension_label, 1, 0)
        self.main_layout.addLayout(self.chapter_options_layout, 1, 1, 1, 2)
        self.main_layout.addWidget(self.chapter_match_groupBox, 2, 0, 1, -1)

    def setup_chapter_main_groupBox(self):
        self.chapter_main_groupBox.setParent(self)
        self.chapter_main_groupBox.setLayout(self.main_layout)
        self.chapter_main_groupBox.setTitle("Chapters")
        self.chapter_main_groupBox.setCheckable(True)
        self.chapter_main_groupBox.setChecked(True)

    def update_folder_path(self, new_path: str):
        if new_path != "":
            self.chapter_source_lineEdit.setText(new_path)
            self.update_files_lists(new_path)
            self.show_chapter_files_list()

    def update_files_lists(self, folder_path):
        if folder_path == "" or folder_path.isspace():
            self.folder_path = ""
            self.chapter_source_lineEdit.setText("")
            return
        try:
            self.folder_path = folder_path
            self.files_names_list = self.get_files_list(self.folder_path)
            self.files_names_absolute_list = get_files_names_absolute_list(
                self.files_names_list, self.folder_path)
        except Exception as e:
            invalid_path_dialog = InvalidPathDialog()
            invalid_path_dialog.execute()

    def check_extension_changes(self, new_extensions):
        if self.current_chapter_extensions != new_extensions:
            self.current_chapter_extensions = new_extensions
            self.update_files_lists(self.folder_path)
            self.show_chapter_files_list()

    def get_files_list(self, folder_path):
        temp_files_names = sort_names_like_windows(
            names_list=os.listdir(folder_path))
        temp_files_names_absolute = get_files_names_absolute_list(
            temp_files_names, folder_path)
        current_extensions = self.chapter_extensions_comboBox.currentData()
        result = []
        for i in range(len(temp_files_names)):
            if os.path.isdir(temp_files_names_absolute[i]):
                continue
            if os.path.getsize(temp_files_names_absolute[i]) == 0:
                continue
            for j in range(len(current_extensions)):
                temp_file_extension_start_index = temp_files_names[i].rfind(
                    ".")
                if temp_file_extension_start_index == -1:
                    continue
                temp_file_extension = temp_files_names[i][
                    temp_file_extension_start_index + 1:]
                if temp_file_extension.lower() == current_extensions[j].lower(
                ):
                    result.append(temp_files_names[i])
                    break
        return result

    def show_chapter_files_list(self):
        self.update_other_classes_variables()
        self.chapter_match_layout.show_chapter_files()

    def update_other_classes_variables(self):
        self.change_global_last_path_directory()
        self.change_global_chapter_list()
        self.chapter_source_button.set_is_there_old_file(
            len(self.files_names_list) > 0)
        self.chapter_source_lineEdit.set_is_there_old_file(
            len(self.files_names_list) > 0)
        self.chapter_extensions_comboBox.set_is_there_old_file(
            len(self.files_names_list) > 0)
        self.chapter_source_lineEdit.set_current_folder_path(self.folder_path)
        self.chapter_extensions_comboBox.set_current_folder_path(
            self.folder_path)
        self.chapter_extensions_comboBox.set_current_files_list(
            self.files_names_list)

    def change_global_chapter_list(self):
        GlobalSetting.CHAPTER_FILES_LIST = self.files_names_list
        GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = self.files_names_absolute_list

    def show_video_files_list(self):
        if self.chapter_main_groupBox.isChecked():
            self.chapter_match_layout.show_video_files()

    def activate_tab(self, on):
        if on:
            self.show_video_files_list()
        else:
            self.chapter_source_lineEdit.setText("")
            self.chapter_match_layout.clear_tables()
            self.folder_path = ""
            self.files_names_list = []
            self.files_names_absolute_list = []
            self.current_chapter_extensions = [Default_Chapter_Extension]
            self.chapter_extensions_comboBox.setData(
                self.current_chapter_extensions)
            GlobalSetting.CHAPTER_FILES_LIST = []
            GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = []
            GlobalSetting.CHAPTER_TRACK_NAME = ""
            GlobalSetting.CHAPTER_DELAY = 0.0
            GlobalSetting.CHAPTER_SET_DEFAULT = False
            GlobalSetting.CHAPTER_SET_FORCED = False
            GlobalSetting.CHAPTER_LANGUAGE = ""
        self.activation_signal.emit(on)
        GlobalSetting.CHAPTER_ENABLED = on

    def mousePressEvent(self, QMouseEvent):
        if QMouseEvent.buttons() == Qt.RightButton:
            self.chapter_match_layout.clear_chapter_selection()
        if (QMouseEvent.buttons() == Qt.RightButton or QMouseEvent.buttons()
                == Qt.LeftButton) and (self.chapter_source_lineEdit.text()
                                       == ""):
            self.chapter_source_lineEdit.setText(self.folder_path)
        return QWidget.mousePressEvent(self, QMouseEvent)

    def showEvent(self, a0: QtGui.QShowEvent) -> None:
        super().showEvent(a0)
        if self.chapter_main_groupBox.isChecked():
            self.show_video_files_list()

    def change_global_last_path_directory(self):
        if self.folder_path != "" and not self.folder_path.isspace():
            GlobalSetting.LAST_DIRECTORY_PATH = self.folder_path

    def tab_clicked(self):
        if self.chapter_main_groupBox.isChecked():
            self.show_chapter_files_list()
            self.show_video_files_list()
        if not GlobalSetting.JOB_QUEUE_EMPTY:
            self.disable_editable_widgets()
        else:
            self.enable_editable_widgets()

    def disable_editable_widgets(self):
        self.chapter_source_lineEdit.setEnabled(False)
        self.chapter_source_button.setEnabled(False)
        self.chapter_extensions_comboBox.setEnabled(False)
        self.chapter_main_groupBox.setCheckable(False)
        self.chapter_match_layout.disable_editable_widgets()

    def enable_editable_widgets(self):
        self.chapter_source_lineEdit.setEnabled(True)
        self.chapter_source_button.setEnabled(True)
        self.chapter_extensions_comboBox.setEnabled(True)
        if GlobalSetting.CHAPTER_ENABLED:
            self.chapter_main_groupBox.setCheckable(True)
        else:
            self.chapter_main_groupBox.setCheckable(True)
            GlobalSetting.CHAPTER_ENABLED = False
            self.chapter_main_groupBox.setChecked(
                GlobalSetting.CHAPTER_ENABLED)
        self.chapter_match_layout.enable_editable_widgets()

    def sync_chapter_files_with_global_files(self):
        self.files_names_list = GlobalSetting.CHAPTER_FILES_LIST
        GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST = get_files_names_absolute_list(
            self.files_names_list, self.folder_path)
        self.files_names_absolute_list = GlobalSetting.CHAPTER_FILES_ABSOLUTE_PATH_LIST
        self.update_other_classes_variables()
Пример #27
0
class MuxSettingTab(QWidget):
    tab_clicked_signal = Signal()
    start_muxing_signal = Signal()
    update_task_bar_progress_signal = Signal(int)
    update_task_bar_paused_signal = Signal()
    update_task_bar_clear_signal = Signal()

    def __init__(self):
        super().__init__()
        self.create_widgets()
        self.setup_widgets()
        self.connect_signals()

    def connect_signals(self):
        self.tab_clicked_signal.connect(self.tab_clicked)

        self.destination_path_button.clicked.connect(self.open_select_destination_folder_dialog)

        self.only_keep_those_audios_checkBox.stateChanged.connect(
            self.only_keep_those_audios_multi_choose_comboBox.check_box_state_changed)

        self.only_keep_those_subtitles_checkBox.stateChanged.connect(
            self.only_keep_those_subtitles_multi_choose_comboBox.check_box_state_changed)

        self.make_this_audio_default_checkBox.disable_combo_box.connect(self.disable_make_this_audio_default_comboBox)

        self.make_this_subtitle_default_checkBox.disable_combo_box.connect(
            self.disable_make_this_subtitle_default_comboBox)

        self.control_queue_button.add_to_queue_clicked_signal.connect(self.add_to_queue_button_clicked)
        self.control_queue_button.start_multiplexing_clicked_signal.connect(self.start_multiplexing_button_clicked)
        self.control_queue_button.pause_multiplexing_clicked_signal.connect(self.pause_multiplexing_button_clicked)

        self.clear_job_queue_button.clicked.connect(self.clear_job_queue_button_clicked)

        self.only_keep_those_audios_multi_choose_comboBox.closeList.connect(self.only_keep_those_audios_close_list)

        self.only_keep_those_subtitles_multi_choose_comboBox.closeList.connect(
            self.only_keep_those_subtitles_close_list)

        self.make_this_audio_default_comboBox.currentTextChanged.connect(
            self.make_this_audio_default_comboBox_text_changed)

        self.make_this_subtitle_default_comboBox.currentTextChanged.connect(
            self.make_this_subtitle_default_comboBox_text_changed)

        self.abort_on_errors_checkBox.stateChanged.connect(self.abort_on_errors_state_changed)

        self.keep_log_file_checkBox.stateChanged.connect(self.keep_log_file_state_changed)
        self.job_queue_layout.update_task_bar_progress_signal.connect(self.update_task_bar_progress)
        self.job_queue_layout.paused_done_signal.connect(self.paused_done)
        self.job_queue_layout.cancel_done_signal.connect(self.cancel_done)
        self.job_queue_layout.finished_all_jobs_signal.connect(self.finished_all_jobs)
        self.job_queue_layout.pause_from_error_occurred_signal.connect(self.pause_multiplexing_button_clicked)

    def setup_widgets(self):
        self.setup_mux_setting_groupBox()
        self.setup_job_queue_groupBox()
        self.setup_destination_path_label()
        self.setup_destination_path_lineEdit()
        self.setup_destination_path_button()
        self.setup_abort_on_errors_checkBox()
        self.setup_discard_old_attachments_checkBox()
        self.setup_keep_log_file_checkBox()
        self.setup_clear_job_queue_button()
        self.setup_tool_tip_hint()
        self.setup_layouts()

    def setup_layouts(self):
        self.setup_MainLayout()
        self.mux_setting_groupBox.setLayout(self.mux_setting_layout)
        self.job_queue_groupBox.setLayout(self.job_queue_layout)
        self.setup_mux_tools_layout_first_row()
        self.setup_mux_tools_layout_second_row()
        self.setup_mux_setting_layout()
        self.setLayout(self.MainLayout)

    # noinspection PyAttributeOutsideInit
    def create_widgets(self):
        self.MainLayout = QVBoxLayout()
        self.mux_setting_groupBox = QGroupBox(self)
        self.job_queue_groupBox = QGroupBox(self)
        self.mux_setting_layout = QGridLayout()
        self.job_queue_layout = JobQueueLayout()
        self.destination_path_label = QLabel()
        self.destination_path_lineEdit = QLineEdit()
        self.destination_path_button = QPushButton()
        self.only_keep_those_audios_checkBox = OnlyKeepThoseAudiosCheckBox()
        self.only_keep_those_subtitles_checkBox = OnlyKeepThoseSubtitlesCheckBox()
        self.only_keep_those_audios_multi_choose_comboBox = AudioTracksCheckableComboBox()
        self.only_keep_those_subtitles_multi_choose_comboBox = SubtitleTracksCheckableComboBox()
        self.make_this_audio_default_checkBox = MakeThisAudioDefaultCheckBox()
        self.make_this_subtitle_default_checkBox = MakeThisSubtitleDefaultCheckBox()
        self.make_this_audio_default_comboBox = MakeThisTrackDefaultComboBox()
        self.make_this_subtitle_default_comboBox = MakeThisTrackDefaultComboBox()
        self.abort_on_errors_checkBox = QCheckBox()
        self.discard_old_attachments_checkBox = QCheckBox()
        self.keep_log_file_checkBox = QCheckBox()
        self.control_queue_button = ControlQueueButton()
        self.clear_job_queue_button = QPushButton()
        self.mux_tools_layout_first_row = QHBoxLayout()
        self.mux_tools_layout_second_row = QHBoxLayout()
        self.job_queue_tools_layout = QHBoxLayout()

    def setup_mux_setting_layout(self):
        self.mux_setting_layout.addWidget(self.destination_path_label, 0, 0)
        self.mux_setting_layout.addWidget(self.destination_path_lineEdit, 0, 1)
        self.mux_setting_layout.addWidget(self.destination_path_button, 0, 2)
        self.mux_setting_layout.addWidget(self.only_keep_those_audios_checkBox, 1, 0)
        self.mux_setting_layout.addWidget(self.only_keep_those_subtitles_checkBox, 2, 0)
        self.mux_setting_layout.addLayout(self.mux_tools_layout_first_row, 1, 1)
        self.mux_setting_layout.addLayout(self.mux_tools_layout_second_row, 2, 1)

    def setup_mux_tools_layout_first_row(self):
        self.mux_tools_layout_first_row.addWidget(self.only_keep_those_audios_multi_choose_comboBox, 2)
        self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_checkBox, 1)
        self.mux_tools_layout_first_row.addWidget(self.make_this_audio_default_comboBox, 2)
        self.mux_tools_layout_first_row.addWidget(self.abort_on_errors_checkBox, 1)
        self.mux_tools_layout_first_row.addWidget(self.keep_log_file_checkBox)

    def setup_mux_tools_layout_second_row(self):
        self.mux_tools_layout_second_row.addWidget(self.only_keep_those_subtitles_multi_choose_comboBox, 2)
        self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_checkBox, 1)
        self.mux_tools_layout_second_row.addWidget(self.make_this_subtitle_default_comboBox, 2)
        self.mux_tools_layout_second_row.addWidget(self.control_queue_button, 1)
        self.mux_tools_layout_second_row.addWidget(self.clear_job_queue_button, 1)

    def setup_clear_job_queue_button(self):
        self.clear_job_queue_button.setText("Clear All")
        self.clear_job_queue_button.setIcon(GlobalFiles.CleanIcon)
        self.clear_job_queue_button.setDisabled(True)

    def setup_keep_log_file_checkBox(self):
        self.keep_log_file_checkBox.setText("Keep Log File")
        self.keep_log_file_checkBox.setToolTip("log file will located in the source folder after finished muxing")

    def setup_discard_old_attachments_checkBox(self):
        self.discard_old_attachments_checkBox.setText("Discard Old Attachments ")

    def setup_abort_on_errors_checkBox(self):
        self.abort_on_errors_checkBox.setText("Abort On Errors")
        self.abort_on_errors_checkBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)

    def setup_destination_path_button(self):
        self.destination_path_button.setIcon(GlobalFiles.SelectFolderIcon)

    def setup_destination_path_lineEdit(self):
        self.destination_path_lineEdit.setPlaceholderText("Enter Destination Folder Path")
        self.destination_path_lineEdit.setClearButtonEnabled(True)

    def setup_destination_path_label(self):
        self.destination_path_label.setText("Videos Destination Folder :")

    def setup_MainLayout(self):
        self.MainLayout.addWidget(self.mux_setting_groupBox)
        self.MainLayout.addWidget(self.job_queue_groupBox)

    def setup_job_queue_groupBox(self):
        self.job_queue_groupBox.setTitle("Job Queue")

    def setup_mux_setting_groupBox(self):
        self.mux_setting_groupBox.setTitle("Mux Setting")

    def paintEvent(self, event: QPaintEvent):
        self.update_widgets_size()
        super().paintEvent(event)

    def resizeEvent(self, event: QResizeEvent):
        self.job_queue_layout.update_layout()
        super().resizeEvent(event)

    def update_widgets_size(self):
        self.only_keep_those_subtitles_multi_choose_comboBox.resize(
            self.only_keep_those_audios_multi_choose_comboBox.width(),
            self.only_keep_those_audios_multi_choose_comboBox.height(),
        )

        self.make_this_subtitle_default_checkBox.resize(
            self.make_this_audio_default_checkBox.width(),
            self.make_this_audio_default_checkBox.height(),
        )
        self.make_this_subtitle_default_checkBox.move(
            self.make_this_audio_default_checkBox.x(),
            self.make_this_subtitle_default_checkBox.y(),
        )

        self.make_this_subtitle_default_comboBox.resize(
            self.make_this_audio_default_comboBox.width(),
            self.make_this_audio_default_comboBox.height(),
        )
        self.make_this_subtitle_default_comboBox.move(
            self.make_this_audio_default_comboBox.x(),
            self.make_this_subtitle_default_comboBox.y(),
        )

        self.control_queue_button.move(
            self.abort_on_errors_checkBox.x(),
            self.control_queue_button.y(),
        )

        self.clear_job_queue_button.move(
            self.control_queue_button.x() + self.control_queue_button.width() + 5,
            self.clear_job_queue_button.y(),
        )

    def open_select_destination_folder_dialog(self):
        temp_folder_path = QFileDialog.getExistingDirectory(self, caption="Choose Destination Folder",
                                                            dir=GlobalSetting.LAST_DIRECTORY_PATH, )
        if temp_folder_path == "" or temp_folder_path.isspace():
            return
        elif Path(temp_folder_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH):
            invalid_dialog = InvalidPathDialog(
                error_message="Source and destination videos can't be in the same folder")
            invalid_dialog.execute()
            return
        else:
            self.destination_path_lineEdit.setText(str(Path(temp_folder_path)))
            GlobalSetting.LAST_DIRECTORY_PATH = self.destination_path_lineEdit.text()
            GlobalSetting.DESTINATION_FOLDER_PATH = self.destination_path_lineEdit.text()

    def check_destination_path(self):
        temp_destination_path = self.destination_path_lineEdit.text()
        try:
            if temp_destination_path == "" or temp_destination_path.isspace():
                temp_destination_path = "[Empty Path]"
                raise Exception(
                    "[WinError 998] Empty path is Not a valid path : " + temp_destination_path)
            # check if system is windows so path must have # SOME_LETTER:\
            if os.name == 'nt':
                if temp_destination_path[1:3] != ":\\" and self.destination_path_lineEdit.text()[
                                                           1:3] != ":/":
                    raise Exception("[WinError 999] Not a valid path : " + temp_destination_path)
            makedirs(temp_destination_path, exist_ok=True)
            ## test if i can write into this path:
            test_file_name = str(time.time()) + ".txt"
            test_file_name_absolute = os.path.join(Path(temp_destination_path), Path(test_file_name))
            try:
                with open(test_file_name_absolute, 'w+') as test_file:
                    test_file.write("Test")
                os.remove(test_file_name_absolute)
            except Exception as e:
                write_to_log_file(e)
                invaild_dialog = InvalidPathDialog(window_title="Permission Denied",
                                                   error_message="MKV Muxing Batch GUI lacks write "
                                                                 "permissions on Destination folder")
                invaild_dialog.execute()
                self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
                return False
        except Exception as e:
            write_to_log_file(e)
            error_message = ""
            if temp_destination_path == "[Empty Path]":
                error_message = "Enter a valid destination path"
            else:
                error_message = temp_destination_path + "\nisn't a valid path!"
            invalid_dialog = InvalidPathDialog(error_message=error_message)
            invalid_dialog.execute()
            self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
            return False
        if Path(temp_destination_path) == Path(GlobalSetting.VIDEO_SOURCE_PATH):
            invalid_dialog = InvalidPathDialog(
                error_message="Source and destination videos can't be in the same folder")
            invalid_dialog.execute()
            self.destination_path_lineEdit.setText(GlobalSetting.DESTINATION_FOLDER_PATH)
            return False
        GlobalSetting.DESTINATION_FOLDER_PATH = temp_destination_path
        return True

    def setup_tool_tip_hint(self):
        self.only_keep_those_subtitles_multi_choose_comboBox.set_tool_tip_hint()
        self.only_keep_those_audios_multi_choose_comboBox.set_tool_tip_hint()
        self.make_this_subtitle_default_checkBox.set_tool_tip_hint_no_check()
        self.make_this_audio_default_checkBox.set_tool_tip_hint_no_check()

    def add_to_queue_button_clicked(self):
        self.job_queue_layout.setup_queue()
        self.enable_muxing_setting()
        if not GlobalSetting.JOB_QUEUE_EMPTY:
            self.disable_editable_widgets()
            self.control_queue_button.set_state_start_multiplexing()
            self.clear_job_queue_button.setDisabled(False)
            change_global_LogFilePath()
        else:
            self.enable_editable_widgets()
            self.setup_enable_options_for_mkv_only_options()

    def tab_clicked(self):
        self.job_queue_layout.show_necessary_table_columns()
        self.setup_enable_options_for_mkv_only_options()

    def setup_enable_options_for_mkv_only_options(self):
        if GlobalSetting.JOB_QUEUE_EMPTY:
            if GlobalSetting.VIDEO_SOURCE_MKV_ONLY:
                self.only_keep_those_audios_checkBox.setEnabled(True)
                self.only_keep_those_subtitles_checkBox.setEnabled(True)
                self.make_this_audio_default_checkBox.setEnabled(True)
                self.make_this_subtitle_default_checkBox.setEnabled(True)
                self.only_keep_those_audios_checkBox.setToolTip("")
                self.only_keep_those_subtitles_checkBox.setToolTip("")
                self.make_this_audio_default_comboBox.setToolTip("")
                self.make_this_subtitle_default_comboBox.setToolTip("")
                self.setup_tool_tip_hint()
            else:

                self.only_keep_those_subtitles_checkBox.setCheckState(Qt.Unchecked)
                self.only_keep_those_audios_checkBox.setCheckState(Qt.Unchecked)
                self.make_this_audio_default_checkBox.setCheckState(Qt.Unchecked)
                self.make_this_subtitle_default_checkBox.setCheckState(Qt.Unchecked)

                self.only_keep_those_audios_checkBox.setEnabled(False)
                self.only_keep_those_subtitles_checkBox.setEnabled(False)
                self.make_this_audio_default_checkBox.setEnabled(False)
                self.make_this_subtitle_default_checkBox.setEnabled(False)
                self.only_keep_those_audios_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                "are Mkv only")
                self.only_keep_those_subtitles_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                   "are Mkv only")

                self.make_this_audio_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                 "are Mkv only")

                self.make_this_subtitle_default_checkBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                    "are Mkv only")
                self.make_this_audio_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                 "are Mkv only")
                self.make_this_subtitle_default_comboBox.setToolTip("<b>[Disabled]</b> Only works when video files "
                                                                    "are Mkv only")
                self.only_keep_those_audios_multi_choose_comboBox.setToolTip(
                    "<b>[Disabled]</b> Only works when video files "
                    "are Mkv only")
                self.only_keep_those_subtitles_multi_choose_comboBox.setToolTip(
                    "<b>[Disabled]</b> Only works when video files "
                    "are Mkv only")

    def clear_job_queue_button_clicked(self):
        self.job_queue_layout.clear_queue()
        self.control_queue_button.set_state_add_to_queue()
        self.clear_job_queue_button.setDisabled(True)
        self.control_queue_button.setDisabled(False)
        self.enable_editable_widgets()
        self.enable_muxing_setting()
        self.setup_enable_options_for_mkv_only_options()
        self.update_task_bar_clear_signal.emit()

    def disable_editable_widgets(self):
        self.only_keep_those_subtitles_checkBox.setEnabled(False)
        self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled(False)
        self.only_keep_those_audios_checkBox.setEnabled(False)
        self.only_keep_those_audios_multi_choose_comboBox.setEnabled(False)
        self.make_this_subtitle_default_checkBox.setEnabled(False)
        self.make_this_subtitle_default_comboBox.setEnabled(False)
        self.make_this_audio_default_checkBox.setEnabled(False)
        self.make_this_audio_default_comboBox.setEnabled(False)

    def enable_editable_widgets(self):
        self.only_keep_those_subtitles_checkBox.setEnabled(True)
        self.only_keep_those_subtitles_multi_choose_comboBox.setEnabled(
            self.only_keep_those_subtitles_checkBox.isChecked())
        self.only_keep_those_audios_checkBox.setEnabled(True)
        self.only_keep_those_audios_multi_choose_comboBox.setEnabled(self.only_keep_those_audios_checkBox.isChecked())
        self.make_this_subtitle_default_checkBox.setEnabled(True)
        self.make_this_subtitle_default_comboBox.setEnabled(self.make_this_subtitle_default_checkBox.isChecked())
        self.make_this_audio_default_checkBox.setEnabled(True)
        self.make_this_audio_default_comboBox.setEnabled(self.make_this_audio_default_checkBox.isChecked())

    def only_keep_those_audios_close_list(self):
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_LANGUAGES = self.only_keep_those_audios_multi_choose_comboBox.languages
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_AUDIOS_TRACKS = self.only_keep_those_audios_multi_choose_comboBox.tracks

    def only_keep_those_subtitles_close_list(self):
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_LANGUAGES = self.only_keep_those_subtitles_multi_choose_comboBox.languages
        GlobalSetting.MUX_SETTING_ONLY_KEEP_THOSE_SUBTITLES_TRACKS = self.only_keep_those_subtitles_multi_choose_comboBox.tracks

    def disable_make_this_subtitle_default_comboBox(self, state):
        self.make_this_subtitle_default_comboBox.setDisabled(state)
        if state:
            self.make_this_subtitle_default_comboBox.setCurrentIndex(-1)

    def disable_make_this_audio_default_comboBox(self, state):
        self.make_this_audio_default_comboBox.setDisabled(state)
        if state:
            self.make_this_audio_default_comboBox.setCurrentIndex(-1)

    def make_this_audio_default_comboBox_text_changed(self):
        GlobalSetting.MUX_SETTING_MAKE_THIS_AUDIO_DEFAULT_TRACK = str(
            self.make_this_audio_default_comboBox.currentText())

    def make_this_subtitle_default_comboBox_text_changed(self):
        GlobalSetting.MUX_SETTING_MAKE_THIS_SUBTITLE_DEFAULT_TRACK = str(
            self.make_this_subtitle_default_comboBox.currentText())

    def update_task_bar_progress(self, new_progress):
        self.update_task_bar_progress_signal.emit(new_progress)

    def enable_muxing_setting(self):
        self.destination_path_lineEdit.setEnabled(True)
        self.destination_path_button.setEnabled(True)
        self.abort_on_errors_checkBox.setEnabled(True)
        self.keep_log_file_checkBox.setEnabled(True)

    def disable_muxing_setting(self):
        self.destination_path_lineEdit.setEnabled(False)
        self.destination_path_button.setEnabled(False)
        self.abort_on_errors_checkBox.setEnabled(False)
        self.keep_log_file_checkBox.setEnabled(False)

    @staticmethod
    def abort_on_errors_state_changed(state):
        GlobalSetting.MUX_SETTING_ABORT_ON_ERRORS = bool(state)

    @staticmethod
    def keep_log_file_state_changed(state):
        GlobalSetting.MUX_SETTING_KEEP_LOG_FILE = bool(state)

    def start_multiplexing_button_clicked(self):
        at_least_one_muxing_setting_has_been_selected = check_if_at_least_one_muxing_setting_has_been_selected()
        if at_least_one_muxing_setting_has_been_selected:
            destination_path_valid = self.check_destination_path()
            if destination_path_valid:
                self.setup_log_file()
                self.control_queue_button.set_state_pause_multiplexing()
                self.disable_muxing_setting()
                self.job_queue_layout.start_muxing()
                self.start_muxing_signal.emit()
                self.clear_job_queue_button.setDisabled(True)

    def pause_multiplexing_button_clicked(self):
        self.job_queue_layout.pause_muxing()
        self.control_queue_button.setDisabled(True)
        self.control_queue_button.set_state_pausing_multiplexing()

    def paused_done(self):
        self.control_queue_button.set_state_resume_multiplexing()
        self.clear_job_queue_button.setDisabled(False)
        self.control_queue_button.setDisabled(False)
        self.update_task_bar_paused_signal.emit()

    def cancel_done(self):
        self.disable_editable_widgets()
        self.enable_muxing_setting()
        self.control_queue_button.set_state_start_multiplexing()
        self.clear_job_queue_button.setDisabled(False)
        change_global_LogFilePath()

    def finished_all_jobs(self):
        self.enable_editable_widgets()
        self.enable_muxing_setting()
        self.setup_enable_options_for_mkv_only_options()
        self.control_queue_button.set_state_start_multiplexing()
        self.control_queue_button.setDisabled(True)
        self.clear_job_queue_button.setDisabled(False)
        self.update_task_bar_clear_signal.emit()
        GlobalSetting.JOB_QUEUE_EMPTY = True
        check_if_want_to_keep_log_file()

    def setup_log_file(self):
        if self.control_queue_button.state == "START":
            open(GlobalFiles.LogFilePath, 'w+').close()
Пример #28
0
class DatasheetView(QMainWindow):
    def __init__(self, pdfPath=None, openPages=[1]):

        super().__init__()

        if pdfPath:
            self.myPdfContext = PDFContext(pdfPath, openPages)

        # store diretory for debugging purposes
        self.svgDirectory = self.myPdfContext.directory

        # window dimensions
        self.top = 300
        self.left = 800
        self.width = 860
        self.height = 980

        self.setGeometry(self.left, self.top, self.width, self.height)

        # window title
        self.setWindowTitle("BetterSheets")

        # sets up main layout -- splitters
        self.initUILayout()
        self.initUIToolbar()
        self.initToC()

        # self.initPdfViewer()  # must be called after initUI to ensure PDFContext object exists
        self.show()

        print(self.mainDisplay.getVisibleChild())

    def initUILayout(self):

        # set left-side, Dynamic View
        self.dynamicViewDisplay = QLabel()

        self.vBoxA = QVBoxLayout()
        self.vBoxA.addWidget(self.dynamicViewDisplay)

        self.groupA = QGroupBox()
        self.groupA.setTitle("Dynamic Veiw")
        self.groupA.setLayout(self.vBoxA)

        # set left-side, Static View
        self.staticViewDisplay = QLabel()

        self.vBoxB = QVBoxLayout()
        self.vBoxB.addWidget(self.staticViewDisplay)

        self.groupB = QGroupBox()
        self.groupB.setTitle("Static View")
        self.groupB.setLayout(self.vBoxB)

        # add Dynamic and Static Views to resizeable left-side Splitter
        self.altViewSplit = QSplitter(Qt.Vertical)
        self.altViewSplit.addWidget(self.groupA)
        self.altViewSplit.addWidget(self.groupB)

        # set up Tools View section
        self.toolsTabView = QTabWidget()
        self.toolsTabView.setTabsClosable(True)
        self.toolsTabView.setMovable(True)
        self.toolsTabView.setDocumentMode(True)
        # self.toolsTabView.setTabBarAutoHide(True)

        # add attribute for storing page notes
        self.notesDB = []
        self.notesDisplay = QListWidget(self)
        self.notesDisplay.setMaximumHeight(200)

        # add ToC to Tools View
        self.ToCListView = QListWidget()
        self.toolsTabView.addTab(self.ToCListView, "Table of Contents")

        # add notes list to tools view
        self.toolsTabView.addTab(self.notesDisplay, "Notes")

        # add tools view to the left-side splitter
        self.altViewSplit.addWidget(self.toolsTabView)

        # set up main viewport
        self.mainDisplay = QDatasheetPageDisplayWidget(self.myPdfContext)
        self.mainDisplay.renderPages(1, 4)

        self.mainScroller = QScrollArea(self)
        self.mainScroller.setWidget(self.mainDisplay)
        self.mainScroller.setWidgetResizable(True)
        self.mainScroller.setBackgroundRole(QtGui.QPalette.Dark)
        self.mainScroller.setFixedHeight(800)

        print(self.mainScroller.viewport().childrenRect())

        # set up document tools

        self.hBoxDocTools = QHBoxLayout()

        self.searchLabel = QLabel("Search: ")
        self.searchBox = QLineEdit()
        self.searchBox.setPlaceholderText("Search")

        # self.

        self.vBoxMain = QVBoxLayout()
        self.vBoxMain.addWidget(self.mainScroller)

        self.notesArea = QLineEdit()
        self.notesArea.setPlaceholderText("Add a note about this page...")
        self.notesArea.returnPressed.connect(self.onAddNote)

        self.vBoxMain.addWidget(self.notesArea)

        self.mainViewGroup = QGroupBox()
        self.mainViewGroup.setTitle("Main View")
        self.mainViewGroup.setLayout(self.vBoxMain)

        # join both sides together
        self.leftRightSplit = QSplitter(Qt.Horizontal)
        self.leftRightSplit.addWidget(self.altViewSplit)
        self.leftRightSplit.addWidget(self.mainViewGroup)

        self.setCentralWidget(self.leftRightSplit)

    def initUIToolbar(self):

        mainMenu = self.menuBar(
        )  # get the menu bar already in use by this QMainWindow subclass

        fileMenu = mainMenu.addMenu("File")
        editMenu = mainMenu.addMenu("Edit")
        LayoutMenu = mainMenu.addMenu("Layout")
        AboutMenu = mainMenu.addMenu("About")

        saveAction = fileMenu.addAction("Save")
        quitAction = fileMenu.addAction("Exit Bettersheets")
        quitAction.triggered.connect(self.quitApp)
        copyAction = editMenu.addAction("Copy")
        resetAction = LayoutMenu.addAction("Reset Default Layout")

        self.toolBar = self.addToolBar("Tools")
        self.toolBar.addAction(saveAction)
        self.toolBar.addAction(copyAction)

    def contextMenuEvent(self, event):
        # return super().contextMenuEvent(event)
        contextMenu = QMenu()

        selectAction = contextMenu.addAction("Select Area")
        extractAction = contextMenu.addAction("Extract Content")
        openAction = contextMenu.addAction("Open PDF")
        closeAction = contextMenu.addAction("Close PDF")
        quitAction = contextMenu.addAction("Quit")

        triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos()))

        if triggered_action == quitAction:
            self.quitApp()

    def quitApp(self):
        self.close()

    def onAddNote(self):
        print("note added")

        text = self.notesArea.text()

        if text:
            self.notesDB.append(text)
            self.notesDisplay.clear()
            self.notesDisplay.addItems(self.notesDB)
            self.notesArea.clear()

    def initPdfViewer(self, openPages: int):
        pass

    def initToC(self):

        # get table of contents
        ToC = self.myPdfContext.getToC()
        ToC_headings_list = [x[1] for x in ToC]

        self.ToCListView.clear()
        self.ToCListView.addItems(ToC_headings_list)
Пример #29
0
class Ui_FilewriterCtrl(object):
    def setupUi(self, FilewriterCtrl):
        FilewriterCtrl.resize(649, 450)
        broker_placeholder_text = "address:port/topic"
        self.central_widget = QWidget(FilewriterCtrl)
        self.vertical_layout_2 = QVBoxLayout(self.central_widget)
        self.vertical_layout = QVBoxLayout()
        self.horizontal_layout = QHBoxLayout()
        self.horizontal_layout.setContentsMargins(-1, -1, 0, -1)
        self.status_layout = QVBoxLayout()
        self.status_layout.setContentsMargins(-1, -1, -1, 0)
        self.status_topic_layout = QHBoxLayout()
        self.status_topic_layout.setContentsMargins(-1, -1, -1, 0)
        self.status_broker_label = QLabel(self.central_widget)
        self.status_topic_layout.addWidget(self.status_broker_label)
        self.status_broker_edit = QLineEdit(self.central_widget)
        self.status_broker_edit.setPlaceholderText(broker_placeholder_text)

        self.status_topic_layout.addWidget(self.status_broker_edit)
        self.status_layout.addLayout(self.status_topic_layout)
        self.line_2 = QFrame(self.central_widget)
        self.line_2.setFrameShape(QFrame.HLine)
        self.line_2.setFrameShadow(QFrame.Sunken)
        self.status_layout.addWidget(self.line_2)
        self.file_writer_table_group = QGroupBox(self.central_widget)
        size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(1)
        size_policy.setHeightForWidth(
            self.file_writer_table_group.sizePolicy().hasHeightForWidth())
        self.file_writer_table_group.setSizePolicy(size_policy)
        self.vertical_layout_4 = QVBoxLayout(self.file_writer_table_group)
        self.vertical_layout_3 = QVBoxLayout()
        self.file_writers_list = QTreeView(self.file_writer_table_group)
        self.file_writers_list.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.file_writers_list.setIndentation(0)
        self.vertical_layout_3.addWidget(self.file_writers_list)
        self.vertical_layout_4.addLayout(self.vertical_layout_3)
        self.status_layout.addWidget(self.file_writer_table_group)
        self.files_group = QGroupBox(self.central_widget)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(4)
        size_policy.setHeightForWidth(
            self.files_group.sizePolicy().hasHeightForWidth())
        self.files_group.setSizePolicy(size_policy)
        self.vertical_layout_6 = QVBoxLayout(self.files_group)
        self.files_list = QTreeView(self.files_group)
        self.files_list.setIndentation(0)
        self.vertical_layout_6.addWidget(self.files_list)
        self.vertical_layout_5 = QVBoxLayout()
        self.horizontal_layout_4 = QHBoxLayout()
        spacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                             QSizePolicy.Minimum)
        self.horizontal_layout_4.addItem(spacer)
        self.stop_file_writing_button = QPushButton(self.files_group)
        self.stop_file_writing_button.setEnabled(False)
        self.horizontal_layout_4.addWidget(self.stop_file_writing_button)
        self.vertical_layout_5.addLayout(self.horizontal_layout_4)
        self.vertical_layout_6.addLayout(self.vertical_layout_5)
        self.status_layout.addWidget(self.files_group)
        self.horizontal_layout.addLayout(self.status_layout)
        self.line = QFrame(self.central_widget)
        self.line.setFrameShape(QFrame.VLine)
        self.line.setFrameShadow(QFrame.Sunken)
        self.horizontal_layout.addWidget(self.line)

        self.command_layout = QVBoxLayout()
        self.command_layout.setContentsMargins(-1, 0, -1, 0)
        self.command_broker_layout = QHBoxLayout()
        self.command_broker_label = QLabel(self.central_widget)
        self.command_broker_layout.addWidget(self.command_broker_label)
        self.command_broker_edit = QLineEdit(self.central_widget)
        self.command_broker_edit.setPlaceholderText(broker_placeholder_text)
        self.command_broker_layout.addWidget(self.command_broker_edit)
        self.command_layout.addLayout(self.command_broker_layout)
        self.command_widget = FilewriterCommandWidget(FilewriterCtrl)
        self.command_layout.addWidget(self.command_widget)

        self.horizontal_layout.addLayout(self.command_layout)
        self.vertical_layout.addLayout(self.horizontal_layout)
        self.vertical_layout_2.addLayout(self.vertical_layout)
        FilewriterCtrl.setCentralWidget(self.central_widget)

        self.status_broker_label.setText("Status broker")
        self.file_writer_table_group.setTitle("File-writers")
        self.files_group.setTitle("Files")
        self.stop_file_writing_button.setText("Stop file-writing")
        self.command_broker_label.setText("Command broker")
        self.command_broker_edit.setPlaceholderText("address:port/topic")

        QMetaObject.connectSlotsByName(FilewriterCtrl)
Пример #30
0
class Card(QWidget):
    def __init__(self, parent: QWidget, card_details: Dict[str, Any]):
        super().__init__()
        if parent is not None:
            self.setParent(parent)
        self.model = create_card(card_details)
        self.setupUi()

    def get_card_background_colour(self):
        if isinstance(self.model, SpellCard):
            return QColor(CardColours[CardType.SPELL])
        elif isinstance(self.model, TrapCard):
            return QColor(CardColours[CardType.TRAP])
        else:
            pass

    def setupUi(self):
        self.main_layout = QVBoxLayout()

        self.name_attr_layout = QHBoxLayout()
        self.name_label = QLabel(self.model.name)
        font = self.name_label.font()
        font.setBold(True)
        font.setCapitalization(QFont.AllUppercase)
        font.setPointSize(12)
        self.name_label.setFont(font)
        self.name_label.setMargin(5)
        pixmap = get_attr_icon(self.model.attribute)
        self.attr_icon = QLabel()
        self.attr_icon.setPixmap(pixmap)
        self.attr_icon.setAlignment(Qt.AlignRight)
        self.name_attr_layout.addWidget(self.name_label)
        self.name_attr_layout.addWidget(self.attr_icon)
        self.main_layout.addLayout(self.name_attr_layout)

        self.level_layout = QHBoxLayout()
        self.main_layout.addLayout(self.level_layout)

        self.picture_frame = QFrame()
        self.picture_frame.setFixedSize(250, 250)
        self.picture_frame.setFrameStyle(QFrame.Box | QFrame.Plain)
        self.picture_frame.setFrameShadow(QFrame.Shadow.Raised)
        self.picture_frame.setLineWidth(1)
        self.picture_frame.setContentsMargins(0, 0, 0, 0)
        self.picture_frame.setLayout(QGridLayout())
        self.image_holder = QLabel()

        pixmap = self._get_card_image()
        self.image_holder.setPixmap(
            pixmap.scaled(
                self.picture_frame.width(),
                self.picture_frame.height(),
                Qt.KeepAspectRatio,
            ))

        self.picture_frame.layout().addWidget(self.image_holder)

        self.main_layout.addWidget(self.picture_frame)

        # Card sets here?

        self.desc_group_box = QGroupBox()
        self.desc_group_box.setMaximumWidth(250)
        self.set_up_group_box()
        self.main_layout.addWidget(self.desc_group_box)

        self.id_label = QLabel(self.model.id)
        self.id_label.setAlignment(Qt.AlignLeft)
        self.id_label.setMargin(5)
        self.main_layout.addWidget(self.id_label)

        self.setLayout(self.main_layout)

        pal = QPalette()
        pal.setColor(QPalette.Background, self.get_card_background_colour())
        self.setAutoFillBackground(True)
        self.setPalette(pal)

    def _get_card_image(self):
        image_name = self.model.img_url.split("/")[-1]

        if os.path.exists(self.get_image_path(image_name)):
            image = Image.open(self.get_image_path(image_name))
        else:
            image_data = requests.get(self.model.img_url).content
            image = Image.open(BytesIO(image_data))
            image.save(self.get_image_path(image_name))
        image = image.crop((44, 106, 380, 438))  # this is about correct
        data = image.tobytes("raw", "RGB")
        qimage = QImage(data, image.size[0], image.size[1],
                        QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(qimage)
        return pixmap

    def get_image_path(self, image_name):
        return os.path.join(os.getcwd(), "images", image_name)

    def set_up_group_box(self):
        self.desc_group_box.setLayout(QVBoxLayout())
        self.desc_label = QLabel(self.model.desc)
        self.desc_label.setWordWrap(True)
        self.desc_group_box.layout().addWidget(self.desc_label)
        if isinstance(self.model, (MonsterCard)):
            self.desc_group_box.setTitle(self.get_group_box_title())
            line = QFrame()
            line.setFrameShape((QFrame.HLine))
            line.setFrameShadow(QFrame.Sunken)
            self.desc_group_box.layout().addWidget(line)
            label = QLabel(
                f"ATK/{self.model.attack}  DEF/{self.model.defence}")
            label.setAlignment(Qt.AlignRight)
            self.desc_group_box.layout().addWidget(label)

    def get_group_box_title(self):
        return "[TEST/TEST]"