Beispiel #1
0
    def _update_row(self,
                    pkg: PackageView,
                    update_check_enabled: bool = True,
                    change_update_col: bool = True):
        self._set_col_icon(0, pkg)
        self._set_col_name(1, pkg)
        self._set_col_version(2, pkg)
        self._set_col_description(3, pkg)
        self._set_col_publisher(4, pkg)
        self._set_col_type(5, pkg)
        self._set_col_installed(6, pkg)
        self._set_col_actions(7, pkg)

        if change_update_col and update_check_enabled:
            if pkg.model.installed and not pkg.model.is_update_ignored(
            ) and pkg.model.update:
                col_update = QCustomToolbar()
                col_update.add_space()
                col_update.add_widget(
                    UpgradeToggleButton(pkg=pkg,
                                        root=self.window,
                                        i18n=self.i18n,
                                        checked=pkg.update_checked if
                                        pkg.model.can_be_updated() else False,
                                        clickable=pkg.model.can_be_updated()))
                col_update.add_space()
            else:
                col_update = QLabel()

            self.setCellWidget(pkg.table_index, 8, col_update)
Beispiel #2
0
    def _set_col_installed(self, col: int, pkg: PackageView):
        toolbar = QCustomToolbar()
        toolbar.add_space()

        if pkg.model.installed:
            if pkg.model.can_be_uninstalled():

                def uninstall():
                    self._uninstall(pkg)

                item = self._gen_row_button(
                    text=self.i18n['uninstall'].capitalize(),
                    name='bt_uninstall',
                    callback=uninstall,
                    tip=self.i18n['manage_window.bt_uninstall.tip'])
            else:
                item = None

        elif pkg.model.can_be_installed():

            def install():
                self._install_app(pkg)

            item = self._gen_row_button(
                text=self.i18n['install'].capitalize(),
                name='bt_install',
                callback=install,
                tip=self.i18n['manage_window.bt_install.tip'])
        else:
            item = None

        toolbar.add_widget(item)
        toolbar.add_space()
        self.setCellWidget(pkg.table_index, col, toolbar)
Beispiel #3
0
    def _set_col_actions(self, col: int, pkg: PackageView):
        toolbar = QCustomToolbar()
        toolbar.setObjectName('app_actions')
        toolbar.add_space()

        if pkg.model.installed:

            def run():
                self.window.begin_launch_package(pkg)

            bt = IconButton(i18n=self.i18n,
                            action=run,
                            tooltip=self.i18n['action.run.tooltip'])
            bt.setObjectName('app_run')

            if not pkg.model.can_be_run():
                bt.setEnabled(False)
                bt.setProperty('_enabled', 'false')

            toolbar.layout().addWidget(bt)

        settings = self.has_any_settings(pkg)

        if pkg.model.installed:

            def handle_custom_actions():
                self.show_pkg_actions(pkg)

            bt = IconButton(i18n=self.i18n,
                            action=handle_custom_actions,
                            tooltip=self.i18n['action.settings.tooltip'])
            bt.setObjectName('app_actions')
            bt.setEnabled(bool(settings))
            toolbar.layout().addWidget(bt)

        if not pkg.model.installed:

            def show_screenshots():
                self.window.begin_show_screenshots(pkg)

            bt = IconButton(i18n=self.i18n,
                            action=show_screenshots,
                            tooltip=self.i18n['action.screenshots.tooltip'])
            bt.setObjectName('app_screenshots')

            if not pkg.model.has_screenshots():
                bt.setEnabled(False)
                bt.setProperty('_enabled', 'false')

            toolbar.layout().addWidget(bt)

        def show_info():
            self.window.begin_show_info(pkg)

        bt = IconButton(i18n=self.i18n,
                        action=show_info,
                        tooltip=self.i18n['action.info.tooltip'])
        bt.setObjectName('app_info')
        bt.setEnabled(bool(pkg.model.has_info()))
        toolbar.layout().addWidget(bt)

        self.setCellWidget(pkg.table_index, col, toolbar)
Beispiel #4
0
    def __init__(self, context: ApplicationContext, manager: SoftwareManager,
                 screen_size: QSize, i18n: I18n, manage_window: QWidget,
                 app_config: dict):
        super(PreparePanel,
              self).__init__(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
        self.i18n = i18n
        self.context = context
        self.app_config = app_config
        self.manage_window = manage_window
        self.setWindowTitle('{} ({})'.format(
            __app_name__, self.i18n['prepare_panel.title.start'].lower()))
        self.setMinimumWidth(screen_size.width() * 0.5)
        self.setMinimumHeight(screen_size.height() * 0.35)
        self.setMaximumHeight(screen_size.height() * 0.95)
        self.setLayout(QVBoxLayout())
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        self.manager = manager
        self.tasks = {}
        self.output = {}
        self.added_tasks = 0
        self.ftasks = 0
        self.started_at = None
        self.self_close = False

        self.prepare_thread = Prepare(self.context, manager, self.i18n)
        self.prepare_thread.signal_register.connect(self.register_task)
        self.prepare_thread.signal_update.connect(self.update_progress)
        self.prepare_thread.signal_finished.connect(self.finish_task)
        self.prepare_thread.signal_started.connect(self.start)
        self.prepare_thread.signal_ask_password.connect(self.ask_root_password)
        self.prepare_thread.signal_output.connect(self.update_output)
        self.signal_password_response.connect(
            self.prepare_thread.set_password_reply)

        self.check_thread = CheckFinished()
        self.signal_status.connect(self.check_thread.update)
        self.check_thread.signal_finished.connect(self.finish)

        self.skip_thread = EnableSkip()
        self.skip_thread.signal_timeout.connect(self._enable_skip_button)

        self.progress_thread = AnimateProgress()
        self.progress_thread.signal_change.connect(self._change_progress)

        self.label_top = QLabel()
        self.label_top.setCursor(QCursor(Qt.WaitCursor))
        self.label_top.setText("{}...".format(
            self.i18n['prepare_panel.title.start'].capitalize()))
        self.label_top.setObjectName('prepare_status')
        self.label_top.setAlignment(Qt.AlignHCenter)
        self.layout().addWidget(self.label_top)
        self.layout().addWidget(QLabel())

        self.table = QTableWidget()
        self.table.setObjectName('tasks')
        self.table.setCursor(QCursor(Qt.WaitCursor))
        self.table.setFocusPolicy(Qt.NoFocus)
        self.table.setShowGrid(False)
        self.table.verticalHeader().setVisible(False)
        self.table.horizontalHeader().setVisible(False)
        self.table.horizontalHeader().setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        self.table.setColumnCount(4)
        self.table.setHorizontalHeaderLabels(['' for _ in range(4)])
        self.table.horizontalScrollBar().setCursor(
            QCursor(Qt.PointingHandCursor))
        self.table.verticalScrollBar().setCursor(QCursor(
            Qt.PointingHandCursor))
        self.layout().addWidget(self.table)

        self.textarea_details = QPlainTextEdit(self)
        self.textarea_details.setObjectName('task_details')
        self.textarea_details.setProperty('console', 'true')
        self.textarea_details.resize(self.table.size())
        self.layout().addWidget(self.textarea_details)
        self.textarea_details.setVisible(False)
        self.textarea_details.setReadOnly(True)
        self.textarea_details.setMaximumHeight(100)
        self.current_output_task = None

        self.bottom_widget = QWidget()
        self.bottom_widget.setLayout(QHBoxLayout())
        self.bottom_widget.layout().addStretch()

        bt_hide_details = QPushButton(self.i18n['prepare.bt_hide_details'])
        bt_hide_details.setObjectName('bt_hide_details')
        bt_hide_details.clicked.connect(self.hide_output)
        bt_hide_details.setCursor(QCursor(Qt.PointingHandCursor))
        self.bottom_widget.layout().addWidget(bt_hide_details)
        self.bottom_widget.layout().addStretch()
        self.layout().addWidget(self.bottom_widget)
        self.bottom_widget.setVisible(False)

        self.bt_bar = QCustomToolbar()
        self.bt_close = QPushButton(self.i18n['close'].capitalize())
        self.bt_close.setObjectName('bt_cancel')
        self.bt_close.setCursor(QCursor(Qt.PointingHandCursor))
        self.bt_close.clicked.connect(self.close)
        self.bt_close.setVisible(False)
        self.bt_bar.add_widget(self.bt_close)
        self.bt_bar.add_widget(new_spacer())

        self.progress_bar = QProgressBar()
        self.progress_bar.setObjectName('prepare_progress')
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setVisible(False)
        self.progress_bar.setCursor(QCursor(Qt.WaitCursor))
        self.bt_bar.add_widget(self.progress_bar)
        self.bt_bar.add_widget(new_spacer())

        self.bt_skip = QPushButton(
            self.i18n['prepare_panel.bt_skip.label'].capitalize())
        self.bt_skip.clicked.connect(self.finish)
        self.bt_skip.setEnabled(False)
        self.bt_skip.setCursor(QCursor(Qt.WaitCursor))
        self.bt_bar.add_widget(self.bt_skip)

        self.layout().addWidget(self.bt_bar)
Beispiel #5
0
class PreparePanel(QWidget, TaskManager):

    signal_status = pyqtSignal(int)
    signal_password_response = pyqtSignal(bool, str)

    def __init__(self, context: ApplicationContext, manager: SoftwareManager,
                 screen_size: QSize, i18n: I18n, manage_window: QWidget,
                 app_config: dict):
        super(PreparePanel,
              self).__init__(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
        self.i18n = i18n
        self.context = context
        self.app_config = app_config
        self.manage_window = manage_window
        self.setWindowTitle('{} ({})'.format(
            __app_name__, self.i18n['prepare_panel.title.start'].lower()))
        self.setMinimumWidth(screen_size.width() * 0.5)
        self.setMinimumHeight(screen_size.height() * 0.35)
        self.setMaximumHeight(screen_size.height() * 0.95)
        self.setLayout(QVBoxLayout())
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        self.manager = manager
        self.tasks = {}
        self.output = {}
        self.added_tasks = 0
        self.ftasks = 0
        self.started_at = None
        self.self_close = False

        self.prepare_thread = Prepare(self.context, manager, self.i18n)
        self.prepare_thread.signal_register.connect(self.register_task)
        self.prepare_thread.signal_update.connect(self.update_progress)
        self.prepare_thread.signal_finished.connect(self.finish_task)
        self.prepare_thread.signal_started.connect(self.start)
        self.prepare_thread.signal_ask_password.connect(self.ask_root_password)
        self.prepare_thread.signal_output.connect(self.update_output)
        self.signal_password_response.connect(
            self.prepare_thread.set_password_reply)

        self.check_thread = CheckFinished()
        self.signal_status.connect(self.check_thread.update)
        self.check_thread.signal_finished.connect(self.finish)

        self.skip_thread = EnableSkip()
        self.skip_thread.signal_timeout.connect(self._enable_skip_button)

        self.progress_thread = AnimateProgress()
        self.progress_thread.signal_change.connect(self._change_progress)

        self.label_top = QLabel()
        self.label_top.setCursor(QCursor(Qt.WaitCursor))
        self.label_top.setText("{}...".format(
            self.i18n['prepare_panel.title.start'].capitalize()))
        self.label_top.setObjectName('prepare_status')
        self.label_top.setAlignment(Qt.AlignHCenter)
        self.layout().addWidget(self.label_top)
        self.layout().addWidget(QLabel())

        self.table = QTableWidget()
        self.table.setObjectName('tasks')
        self.table.setCursor(QCursor(Qt.WaitCursor))
        self.table.setFocusPolicy(Qt.NoFocus)
        self.table.setShowGrid(False)
        self.table.verticalHeader().setVisible(False)
        self.table.horizontalHeader().setVisible(False)
        self.table.horizontalHeader().setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        self.table.setColumnCount(4)
        self.table.setHorizontalHeaderLabels(['' for _ in range(4)])
        self.table.horizontalScrollBar().setCursor(
            QCursor(Qt.PointingHandCursor))
        self.table.verticalScrollBar().setCursor(QCursor(
            Qt.PointingHandCursor))
        self.layout().addWidget(self.table)

        self.textarea_details = QPlainTextEdit(self)
        self.textarea_details.setObjectName('task_details')
        self.textarea_details.setProperty('console', 'true')
        self.textarea_details.resize(self.table.size())
        self.layout().addWidget(self.textarea_details)
        self.textarea_details.setVisible(False)
        self.textarea_details.setReadOnly(True)
        self.textarea_details.setMaximumHeight(100)
        self.current_output_task = None

        self.bottom_widget = QWidget()
        self.bottom_widget.setLayout(QHBoxLayout())
        self.bottom_widget.layout().addStretch()

        bt_hide_details = QPushButton(self.i18n['prepare.bt_hide_details'])
        bt_hide_details.setObjectName('bt_hide_details')
        bt_hide_details.clicked.connect(self.hide_output)
        bt_hide_details.setCursor(QCursor(Qt.PointingHandCursor))
        self.bottom_widget.layout().addWidget(bt_hide_details)
        self.bottom_widget.layout().addStretch()
        self.layout().addWidget(self.bottom_widget)
        self.bottom_widget.setVisible(False)

        self.bt_bar = QCustomToolbar()
        self.bt_close = QPushButton(self.i18n['close'].capitalize())
        self.bt_close.setObjectName('bt_cancel')
        self.bt_close.setCursor(QCursor(Qt.PointingHandCursor))
        self.bt_close.clicked.connect(self.close)
        self.bt_close.setVisible(False)
        self.bt_bar.add_widget(self.bt_close)
        self.bt_bar.add_widget(new_spacer())

        self.progress_bar = QProgressBar()
        self.progress_bar.setObjectName('prepare_progress')
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setVisible(False)
        self.progress_bar.setCursor(QCursor(Qt.WaitCursor))
        self.bt_bar.add_widget(self.progress_bar)
        self.bt_bar.add_widget(new_spacer())

        self.bt_skip = QPushButton(
            self.i18n['prepare_panel.bt_skip.label'].capitalize())
        self.bt_skip.clicked.connect(self.finish)
        self.bt_skip.setEnabled(False)
        self.bt_skip.setCursor(QCursor(Qt.WaitCursor))
        self.bt_bar.add_widget(self.bt_skip)

        self.layout().addWidget(self.bt_bar)

    def hide_output(self):
        self.current_output_task = None
        self.textarea_details.setVisible(False)
        self.textarea_details.clear()
        self.bottom_widget.setVisible(False)
        self._resize_columns()
        self.setFocus(Qt.NoFocusReason)

        if not self.bt_bar.isVisible():
            self.bt_bar.setVisible(True)

    def ask_root_password(self):
        valid, root_pwd = RootDialog.ask_password(self.context, self.i18n)
        self.signal_password_response.emit(valid, root_pwd)

    def _enable_skip_button(self):
        self.bt_skip.setEnabled(True)
        self.bt_skip.setCursor(QCursor(Qt.PointingHandCursor))

    def _change_progress(self, value: int):
        self.progress_bar.setValue(value)

    def get_table_width(self) -> int:
        return reduce(operator.add, [
            self.table.columnWidth(i) for i in range(self.table.columnCount())
        ])

    def _resize_columns(self):
        header_horizontal = self.table.horizontalHeader()
        for i in range(self.table.columnCount()):
            header_horizontal.setSectionResizeMode(
                i, QHeaderView.ResizeToContents)

        self.resize(int(self.get_table_width() * 1.05),
                    self.sizeHint().height())

    def show(self):
        super(PreparePanel, self).show()
        self.prepare_thread.start()
        centralize(self)

    def start(self, tasks: int):
        self.started_at = time.time()
        self.check_thread.total = tasks
        self.check_thread.start()
        self.skip_thread.start()

        self.progress_thread.start()

        self.bt_close.setVisible(True)
        self.progress_bar.setVisible(True)

    def closeEvent(self, ev: QCloseEvent):
        if not self.self_close:
            QCoreApplication.exit()

    def register_task(self, id_: str, label: str, icon_path: str):
        self.added_tasks += 1
        self.table.setRowCount(self.added_tasks)
        task_row = self.added_tasks - 1

        icon_widget = QWidget()
        icon_widget.setProperty('container', 'true')
        icon_widget.setLayout(QHBoxLayout())
        icon_widget.layout().setContentsMargins(10, 0, 10, 0)

        bt_icon = QToolButton()
        bt_icon.setObjectName('bt_task')
        bt_icon.setCursor(QCursor(Qt.WaitCursor))
        bt_icon.setEnabled(False)
        bt_icon.setToolTip(self.i18n['prepare.bt_icon.no_output'])

        if icon_path:
            bt_icon.setIcon(QIcon(icon_path))

        def _show_output():
            lines = self.output[id_]

            if lines:
                self.current_output_task = id_
                self.textarea_details.clear()
                self.textarea_details.setVisible(True)

                for l in lines:
                    self.textarea_details.appendPlainText(l)

                self.bottom_widget.setVisible(True)

            self.setFocus(Qt.NoFocusReason)

            if self.bt_bar.isVisible():
                self.bt_bar.setVisible(False)

        bt_icon.clicked.connect(_show_output)
        icon_widget.layout().addWidget(bt_icon)

        self.table.setCellWidget(task_row, 0, icon_widget)

        lb_status = QLabel(label)
        lb_status.setObjectName('task_status')
        lb_status.setProperty('status', 'running')
        lb_status.setCursor(Qt.WaitCursor)
        lb_status.setMinimumWidth(50)
        lb_status.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        lb_status_col = 1
        self.table.setCellWidget(task_row, lb_status_col, lb_status)

        lb_progress = QLabel('{0:.2f}'.format(0) + '%')
        lb_progress.setObjectName('task_progress')
        lb_progress.setProperty('status', 'running')
        lb_progress.setCursor(Qt.WaitCursor)
        lb_progress.setContentsMargins(10, 0, 10, 0)
        lb_progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        lb_progress_col = 2

        self.table.setCellWidget(task_row, lb_progress_col, lb_progress)

        lb_sub = QLabel()
        lb_sub.setObjectName('task_substatus')
        lb_sub.setCursor(Qt.WaitCursor)
        lb_sub.setContentsMargins(10, 0, 10, 0)
        lb_sub.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        lb_sub.setMinimumWidth(50)
        self.table.setCellWidget(task_row, 3, lb_sub)

        self.tasks[id_] = {
            'bt_icon': bt_icon,
            'lb_status': lb_status,
            'lb_status_col': lb_status_col,
            'lb_prog': lb_progress,
            'lb_prog_col': lb_progress_col,
            'progress': 0,
            'lb_sub': lb_sub,
            'finished': False,
            'row': task_row
        }

    def update_progress(self, task_id: str, progress: float, substatus: str):
        task = self.tasks[task_id]

        if progress != task['progress']:
            task['progress'] = progress
            task['lb_prog'].setText('{0:.2f}'.format(progress) + '%')

        if substatus:
            task['lb_sub'].setText('({})'.format(substatus))
        else:
            task['lb_sub'].setText('')

        self._resize_columns()

    def update_output(self, task_id: str, output: str):
        full_output = self.output.get(task_id)

        if full_output is None:
            full_output = []
            self.output[task_id] = full_output
            task = self.tasks[task_id]
            task['bt_icon'].setEnabled(True)
            task['bt_icon'].setCursor(QCursor(Qt.PointingHandCursor))
            task['bt_icon'].setToolTip(self.i18n['prepare.bt_icon.output'])

        full_output.append(output)

        if self.current_output_task == task_id:
            self.textarea_details.appendPlainText(output)

    def finish_task(self, task_id: str):
        task = self.tasks[task_id]

        for key in ('lb_prog', 'lb_status', 'lb_sub'):
            label = task[key]
            label.setProperty('status', 'done')
            label.style().unpolish(label)
            label.style().polish(label)
            label.update()

        task['finished'] = True
        self._resize_columns()

        self.ftasks += 1
        self.signal_status.emit(self.ftasks)

    def finish(self):
        now = time.time()
        self.context.logger.info(
            "{0} tasks finished in {1:.9f} seconds".format(
                self.ftasks, (now - self.started_at)))
        if self.isVisible():
            self.manage_window.show()

            if self.app_config['boot']['load_apps']:
                self.manage_window.begin_refresh_packages()
            else:
                self.manage_window.load_without_packages()

            self.self_close = True
            self.close()