Beispiel #1
0
class ExecuteWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.ctrl = QApplication.instance().ctrl
        self.ctrl.switch_language.connect(self.on_switch_language)
        self.ctrl.switch_configuration.connect(self.on_switch_configuration)
        self.paras = self.ctrl.paras
        self.conf = GuiConf()
        self.setWindowTitle(_("Execute %s") % self.paras.configuration_name())
        self.executor_thread = None
        self.splitter_event_moved = False
        self.splitter_title_moved = False
        self.init_ui()
        self.show()

    def init_ui(self):
        vbox = QVBoxLayout()

        self.splitter_title = QSplitter(Qt.Vertical)
        self.splitter_event = QSplitter(Qt.Vertical)
        self.splitter_title.splitterMoved.connect(self.on_splitter_title_moved)
        self.splitter_event.splitterMoved.connect(self.on_splitter_event_moved)

        self.lbl_events_title1 = QLabel(_("Main events"))
        self.splitter_title.addWidget(self.lbl_events_title1)

        self.lbl_events_title2 = QLabel(_("Resources"))
        self.splitter_title.addWidget(self.lbl_events_title2)

        self.lbl_events_title3 = QLabel(_("Errors"))
        self.splitter_title.addWidget(self.lbl_events_title3)

        self.pte_events1 = QTextBrowser()
        self.pte_events1.setOpenExternalLinks(True)
        self.pte_events1.setOpenLinks(False)
        self.pte_events1.anchorClicked.connect(self.on_anchor_clicked)
        self.pte_events1.setLineWrapMode(QTextEdit.NoWrap)
        self.splitter_event.addWidget(self.pte_events1)

        self.pte_events2 = QTextBrowser()
        self.pte_events2.setOpenExternalLinks(True)
        self.pte_events2.setOpenLinks(False)
        self.pte_events2.anchorClicked.connect(self.on_anchor_clicked)
        self.pte_events2.setLineWrapMode(QTextEdit.NoWrap)
        self.splitter_event.addWidget(self.pte_events2)

        self.pte_events3 = QPlainTextEdit()
        self.pte_events3.setReadOnly(True)
        self.pte_events3.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.pte_events3.setStyleSheet(Style.red_text())
        self.pte_events3.setCenterOnScroll(True)
        self.splitter_event.addWidget(self.pte_events3)

        self.splitter_title.setStretchFactor(0, 5)
        self.splitter_title.setStretchFactor(1, 3)
        self.splitter_title.setStretchFactor(2, 1)
        self.splitter_event.setStretchFactor(0, 5)
        self.splitter_event.setStretchFactor(1, 3)
        self.splitter_event.setStretchFactor(2, 1)
        hbox_splitters = QHBoxLayout()
        hbox_splitters.addWidget(self.splitter_title, 0)
        hbox_splitters.addWidget(self.splitter_event, 5)
        vbox.addLayout(hbox_splitters)

        lbl_box = QHBoxLayout()
        self.lbl_processing = QLabel(_("Processing:"))
        self.lbl_processing_file = QLabel("")
        self.lbl_processing.setVisible(False)
        self.lbl_processing_file.setVisible(False)
        lbl_box.addWidget(self.lbl_processing)
        lbl_box.addWidget(self.lbl_processing_file)
        lbl_box.addStretch(1)
        vbox.addLayout(lbl_box)

        btn_box = QHBoxLayout()
        btn_box.addStretch(1)
        self.chk_trial_run = QCheckBox(_("Trial run"))
        self.chk_trial_run.setChecked(not self.paras.is_saving_sitemaps)
        btn_box.addWidget(self.chk_trial_run)
        self.btn_run = QPushButton(_("Run"))
        self.btn_run.clicked.connect(self.on_btn_run_clicked)
        btn_box.addWidget(self.btn_run)
        self.btn_stop = QPushButton(_("Stop"))
        self.btn_stop.clicked.connect(self.on_btn_stop_clicked)
        self.normal_style = self.btn_stop.styleSheet()
        self.btn_stop.setEnabled(False)
        btn_box.addWidget(self.btn_stop)
        self.btn_close = QPushButton(_("Close"))
        self.btn_close.clicked.connect(self.on_btn_close_clicked)
        btn_box.addWidget(self.btn_close)
        vbox.addLayout(btn_box)

        self.setLayout(vbox)
        self.resize(self.conf.execute_widget_width(),
                    self.conf.execute_widget_height())

    def on_splitter_title_moved(self, pos, index):
        self.splitter_title_moved = True
        if not self.splitter_event_moved:
            self.splitter_event.moveSplitter(pos, index)
        self.splitter_title_moved = False

    def on_splitter_event_moved(self, pos, index):
        self.splitter_event_moved = True
        if not self.splitter_title_moved:
            self.splitter_title.moveSplitter(pos, index)
        self.splitter_event_moved = False

    def on_switch_language(self):
        self.setWindowTitle(_("Execute %s") % self.paras.configuration_name())
        self.lbl_events_title1.setText(_("Main events"))
        self.lbl_events_title2.setText(_("Resources"))
        self.lbl_events_title3.setText(_("Errors"))
        self.lbl_processing.setText(_("Processing:"))
        self.chk_trial_run.setText(_("Trial run"))
        self.btn_run.setText(_("Run"))
        self.btn_stop.setText(_("Stop"))
        self.btn_close.setText(_("Close"))

    def on_switch_configuration(self, name=None):
        LOG.debug("Switch configuration: %s" % name)
        self.paras = self.ctrl.paras
        self.setWindowTitle(_("Execute %s") % self.paras.configuration_name())
        self.chk_trial_run.setChecked(not self.paras.is_saving_sitemaps)

    def on_btn_run_clicked(self):
        if self.paras.select_mode == SelectMode.simple:
            selector = Selector()
            if self.paras.simple_select_file:
                selector.include(self.paras.simple_select_file)
        else:
            selector = self.ctrl.selector
        self.paras.is_saving_sitemaps = not self.chk_trial_run.isChecked()
        self.pte_events1.setPlainText("")
        self.pte_events2.setPlainText("")
        self.pte_events3.setPlainText("")
        self.lbl_processing.setVisible(True)
        self.lbl_processing_file.setVisible(True)

        self.btn_close.setEnabled(False)
        self.btn_run.setEnabled(False)
        self.chk_trial_run.setEnabled(False)
        self.btn_stop.setEnabled(True)
        self.btn_stop.setStyleSheet(Style.alarm())

        self.executor_thread = ExecutorThread(self.paras, selector, self)
        self.executor_thread.signal_exception.connect(self.on_signal_exception)
        self.executor_thread.ask_confirmation.connect(self.on_ask_confirmation)
        self.executor_thread.signal_main_event.connect(
            self.on_signal_main_event)
        self.executor_thread.signal_minor_event.connect(
            self.on_signal_minor_event)
        self.executor_thread.signal_next_file.connect(self.on_signal_next_file)
        self.executor_thread.signal_end_processing.connect(
            self.on_signal_end_processing)
        self.executor_thread.finished.connect(self.on_executor_thread_finished)
        self.executor_thread.start()
        self.update()

    def on_btn_stop_clicked(self):
        self.btn_stop.setStyleSheet(self.normal_style)
        self.btn_stop.setEnabled(False)
        self.executor_thread.requestInterruption()

    def on_signal_exception(self, msg):
        self.pte_events3.appendHtml(msg)
        self.update()

    def on_ask_confirmation(self, text, i_text, answer):
        msg_box = QMessageBox()
        msg_box.setText(text)
        i_text += "\n\n"
        i_text += _("Ok to proceed?")
        msg_box.setInformativeText(i_text)
        msg_box.setIcon(QMessageBox.Question)
        msg_box.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        msg_box.setDefaultButton(QMessageBox.Yes)
        exe = msg_box.exec()
        if exe == QMessageBox.No:
            answer.answer = False
        else:
            answer.answer = True
        answer.answered = True

    def on_signal_main_event(self, msg):
        self.pte_events1.append(msg)
        self.update()

    def on_signal_minor_event(self, msg):
        self.pte_events2.append(msg)
        self.update()

    def on_signal_next_file(self, filename):
        lfn = len(filename)
        ww = (self.width() - 150) / 7
        www = int(ww / 2)
        if lfn > ww:
            filename = filename[:www] + "..." + filename[lfn - www:]
        self.lbl_processing_file.setText(filename)
        self.update()

    def on_signal_end_processing(self, paras):
        self.ctrl.update_configuration(paras)

    def on_executor_thread_finished(self):
        self.btn_stop.setStyleSheet(self.normal_style)
        self.btn_stop.setEnabled(False)
        self.btn_close.setEnabled(True)
        self.btn_run.setEnabled(True)
        self.chk_trial_run.setEnabled(True)
        self.lbl_processing.setVisible(False)
        self.lbl_processing_file.setVisible(False)
        self.update()

    def on_anchor_clicked(self, url):
        QDesktopServices.openUrl(QUrl(url))

    def on_btn_close_clicked(self):
        if self.windowState() & Qt.WindowFullScreen:
            self.setWindowState(Qt.WindowMaximized)
        else:
            self.close()

    def closeEvent(self, event):
        if self.executor_thread:
            self.executor_thread.requestInterruption()
        if self.windowState() & Qt.WindowFullScreen:
            self.setWindowState(Qt.WindowMaximized)
            event.ignore()
        else:
            self.conf.set_execute_widget_width(self.width())
            self.conf.set_execute_widget_height(self.height())
            self.conf.persist()
            event.accept()
Beispiel #2
0
class WorkWidget(QWidget):

    work_started = pyqtSignal()
    work_ended = pyqtSignal()

    def __init__(self, work="", title_style=Style.h2()):
        QWidget.__init__(self)
        self.ctrl = QApplication.instance().ctrl
        self.ctrl.switch_language.connect(self.on_switch_language)
        self.ctrl.switch_configuration.connect(self.on_switch_configuration)
        self.paras = self.ctrl.paras
        self.conf = GuiConf()
        # work should be a verb: Execute, Transport ...
        self.work = work
        self.title_style = title_style
        self.setWindowTitle(_(self.work))
        self.executor_thread = None
        self.splitter_event_moved = False
        self.splitter_title_moved = False
        self.init_ui()
        self.show()

    def init_ui(self):
        vbox = QVBoxLayout()

        self.label_title = QLabel("%s %s" % (_(self.work), self.paras.configuration_name()))
        font = QFont()
        font.setPointSize(18)
        font.setBold(True)
        self.label_title.setFont(font)
        self.label_title.setContentsMargins(10, 5, 5, 7)
        self.label_title.setStyleSheet(self.title_style)
        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.label_title, 1)
        vbox.addLayout(hbox1)

        self.splitter_title = QSplitter(Qt.Vertical)
        self.splitter_event = QSplitter(Qt.Vertical)
        self.splitter_title.splitterMoved.connect(self.on_splitter_title_moved)
        self.splitter_event.splitterMoved.connect(self.on_splitter_event_moved)

        self.lbl_events_title1 = QLabel(_("Main events"))
        self.splitter_title.addWidget(self.lbl_events_title1)

        self.lbl_events_title2 = QLabel(_("Resources"))
        self.splitter_title.addWidget(self.lbl_events_title2)

        self.lbl_events_title3 = QLabel(_("Errors"))
        self.splitter_title.addWidget(self.lbl_events_title3)

        self.pte_events1 = QTextBrowser()
        self.pte_events1.setOpenExternalLinks(True)
        self.pte_events1.setOpenLinks(False)
        self.pte_events1.anchorClicked.connect(self.on_anchor_clicked)
        self.pte_events1.setLineWrapMode(QTextEdit.NoWrap)
        self.splitter_event.addWidget(self.pte_events1)

        self.pte_events2 = QTextBrowser()
        self.pte_events2.setOpenExternalLinks(True)
        self.pte_events2.setOpenLinks(False)
        self.pte_events2.anchorClicked.connect(self.on_anchor_clicked)
        self.pte_events2.setLineWrapMode(QTextEdit.NoWrap)
        self.splitter_event.addWidget(self.pte_events2)

        self.pte_events3 = QPlainTextEdit()
        self.pte_events3.setReadOnly(True)
        self.pte_events3.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.pte_events3.setStyleSheet(Style.red_text())
        self.pte_events3.setCenterOnScroll(True)
        self.splitter_event.addWidget(self.pte_events3)

        self.splitter_title.setStretchFactor(0, 5)
        self.splitter_title.setStretchFactor(1, 3)
        self.splitter_title.setStretchFactor(2, 1)
        self.splitter_event.setStretchFactor(0, 5)
        self.splitter_event.setStretchFactor(1, 3)
        self.splitter_event.setStretchFactor(2, 1)
        hbox_splitters = QHBoxLayout()
        hbox_splitters.addWidget(self.splitter_title, 0)
        hbox_splitters.addWidget(self.splitter_event, 5)
        vbox.addLayout(hbox_splitters)

        lbl_box = QHBoxLayout()
        self.lbl_processing = QLabel(_("Processing:"))
        self.lbl_processing_file = QLabel("")
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.lbl_processing_file.setFont(font)
        self.lbl_processing.setFont(font)
        self.lbl_processing.setVisible(False)
        self.lbl_processing_file.setVisible(False)
        lbl_box.addWidget(self.lbl_processing)
        lbl_box.addWidget(self.lbl_processing_file)
        lbl_box.addStretch(1)
        vbox.addLayout(lbl_box)

        btn_box = QHBoxLayout()
        btn_box.addStretch(1)
        self.chk_trial_run = QCheckBox(_("Trial run"))
        self.chk_trial_run.setChecked(not self.paras.is_saving_sitemaps)
        btn_box.addWidget(self.chk_trial_run)
        self.btn_run = QPushButton(_("Run"))
        self.btn_run.clicked.connect(self.on_btn_run_clicked)
        btn_box.addWidget(self.btn_run)
        self.btn_stop = QPushButton(_("Stop"))
        self.btn_stop.clicked.connect(self.on_btn_stop_clicked)
        self.normal_style = self.btn_stop.styleSheet()
        self.btn_stop.setEnabled(False)
        btn_box.addWidget(self.btn_stop)
        self.btn_close = QPushButton(_("Close"))
        self.btn_close.clicked.connect(self.on_btn_close_clicked)
        btn_box.addWidget(self.btn_close)
        vbox.addLayout(btn_box)

        self.setLayout(vbox)
        self.resize(self.conf.work_widget_width(self.work), self.conf.work_widget_height(self.work))

    def on_splitter_title_moved(self, pos, index):
        self.splitter_title_moved = True
        if not self.splitter_event_moved:
            self.splitter_event.moveSplitter(pos, index)
        self.splitter_title_moved = False

    def on_splitter_event_moved(self, pos, index):
        self.splitter_event_moved = True
        if not self.splitter_title_moved:
            self.splitter_title.moveSplitter(pos, index)
        self.splitter_event_moved = False

    def on_switch_language(self):
        self.setWindowTitle(_(self.work))
        self.label_title.setText("%s %s" % (_(self.work), self.paras.configuration_name()))
        self.lbl_events_title1.setText(_("Main events"))
        self.lbl_events_title2.setText(_("Resources"))
        self.lbl_events_title3.setText(_("Errors"))
        self.lbl_processing.setText(_("Processing:"))
        self.chk_trial_run.setText(_("Trial run"))
        self.btn_run.setText(_("Run"))
        self.btn_stop.setText(_("Stop"))
        self.btn_close.setText(_("Close"))

    def on_switch_configuration(self, name=None):
        LOG.debug("Switch configuration: %s" % name)
        self.paras = self.ctrl.paras
        self.label_title.setText("%s %s" % (_(self.work), self.paras.configuration_name()))

    def on_anchor_clicked(self, url):
        QDesktopServices.openUrl(QUrl(url))

    def on_btn_run_clicked(self):
        self.work_started.emit()
        self.pte_events1.setPlainText("")
        self.pte_events2.setPlainText("")
        self.pte_events3.setPlainText("")
        self.lbl_processing.setVisible(True)
        self.lbl_processing_file.setVisible(True)

        self.btn_close.setEnabled(False)
        self.btn_run.setEnabled(False)
        self.chk_trial_run.setEnabled(False)
        self.btn_stop.setEnabled(True)
        self.btn_stop.setStyleSheet(Style.alarm())

    def on_btn_stop_clicked(self):
        self.btn_stop.setStyleSheet(self.normal_style)
        self.btn_stop.setEnabled(False)
        self.on_signal_main_event(_("Interrupt requested..."))
        if self.executor_thread:
            self.executor_thread.requestInterruption()

    def on_signal_exception(self, msg):
        self.pte_events3.appendHtml(msg)
        self.update()

    def on_ask_confirmation(self, text, i_text, answer):
        msg_box = QMessageBox()
        msg_box.setWindowTitle(_("MPT"))
        msg_box.setText(text)
        i_text += "\n\n"
        i_text += _("Ok to proceed?")
        msg_box.setInformativeText(i_text)
        msg_box.setIcon(QMessageBox.Question)
        msg_box.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        msg_box.setDefaultButton(QMessageBox.Yes)
        exe = msg_box.exec()
        if exe == QMessageBox.No:
            answer.answer = False
        else:
            answer.answer = True
        answer.answered = True

    def on_signal_main_event(self, msg):
        self.pte_events1.append(msg)
        self.update()

    def on_signal_minor_event(self, msg):
        self.pte_events2.append(msg)
        self.update()

    def on_signal_next_file(self, filename):
        lfn = len(filename)
        ww = (self.width() - 150)/7
        www = int(ww/2)
        if lfn > ww:
            filename = filename[:www] + "..." + filename[lfn - www:]
        self.lbl_processing_file.setText(filename)
        self.update()

    def on_signal_end_processing(self, paras):
        self.ctrl.update_configuration(paras)

    def on_executor_thread_finished(self):
        self.btn_stop.setStyleSheet(self.normal_style)
        self.btn_stop.setEnabled(False)
        self.btn_close.setEnabled(True)
        self.btn_run.setEnabled(True)
        self.chk_trial_run.setEnabled(True)
        self.lbl_processing.setVisible(False)
        self.lbl_processing_file.setVisible(False)
        self.update()
        self.work_ended.emit()

    def on_btn_close_clicked(self):
        if self.windowState() & Qt.WindowFullScreen:
            self.setWindowState(Qt.WindowMaximized)
        else:
            self.close()
            self.destroy()

    def closeEvent(self, event):
        LOG.debug("Closing event on work window %s" % self.work)
        if self.executor_thread:
            self.executor_thread.requestInterruption()
        if self.windowState() & Qt.WindowFullScreen:
            self.setWindowState(Qt.WindowMaximized)
            event.ignore()
        else:
            self.save_dimensions()
            self.exit_if_last()
            event.accept()

    def save_dimensions(self):
        LOG.debug("Saving dimensions for work-window %s" % self.work)
        self.conf.set_work_widget_width(self.work, self.width())
        self.conf.set_work_widget_height(self.work, self.height())
        self.conf.persist()

    def exit_if_last(self):
        count_windows = 0
        for window in QApplication.instance().topLevelWindows():
            if window.type() == 1 or window.type() == 15:
                count_windows += 1

        LOG.debug("Testing for last window. window_count=%d" % count_windows)
        if count_windows == 1:
            LOG.debug("Closing last window")
            QApplication.instance().quit()