Example #1
0
    def __init__(self, parent=None):
        super(DataflowWindow, self).__init__(parent)

        # misc initializations
        self.factory = plugins.PluginFactory()
        self.dataflow = plugins.DataflowGraph()
        self.scene = DataflowScene(self.factory, self.dataflow)
        self.scene.setSceneRect(0, 0, 500, 500)
        # result from dataflow
        self.results = {}

        self.timer = QTimer()
        self.connect(self.timer,
                     SIGNAL('timeout()'),
                     self.updateStatusBar)
        self.connect(self.timer,
                     SIGNAL('timeout()'),
                     self.updateFlowStatus)

        # setup menus
        fileMenu = self.menuBar().addMenu('File')
        fileMenu.addAction('New', self.openNew)
        fileMenu.addAction('Load', self.openFile)
        fileMenu.addAction('Save', self.saveFile)

        actionsMenu = ActionsMenu(self.dataflow, self.menuBar())
        self.menuBar().addMenu(actionsMenu)

        # flag to select the correct statusbar message
        self.some_processing_done = False
        self.statusBar().showMessage('Ready')

        # setup dataflow page
        dataflowTab = QWidget()
        self.view = DataflowView()
        self.view.setScene(self.scene)

        self.toolbox = PluginToolbox(factory)
        self.populatePluginToolbox()

        dataflow_tab_layout = QGridLayout()
        dataflow_tab_layout.addWidget(self.toolbox, 0, 0)
        dataflow_tab_layout.addWidget(self.view, 0, 1)
        dataflowTab.setLayout(dataflow_tab_layout)

        # setup report tab
        reportTab = QWidget()

        outputsLabel = QLabel('Data provided by plugins')
        self.outputList = QListWidget()
        self.result_preview = QTextEdit()
        self.result_preview.setReadOnly(True)
        self.html_edit = QTextEdit()
        self.preview_button = QPushButton('Preview report')
        report_tab_layout = QGridLayout()
        report_tab_layout.addWidget(outputsLabel, 0, 0)
        report_tab_layout.addWidget(self.outputList, 1, 0)
        report_tab_layout.addWidget(self.result_preview, 1, 1)
        report_tab_layout.addWidget(self.html_edit, 1, 2)
        report_tab_layout.addWidget(self.preview_button, 2, 2)
        reportTab.setLayout(report_tab_layout)

        self.connect(self.preview_button,
                     SIGNAL('clicked()'),
                     self.show_report)
        self.connect(self.outputList,
                     SIGNAL('currentItemChanged(QListWidgetItem *, QListWidgetItem *)'),
                     self.tmp_show_data)

        # setup tab widget
        tabWidget = QTabWidget()
        tabWidget.addTab(dataflowTab, 'Dataflow')
        tabWidget.addTab(reportTab, 'Output')
        self.setCentralWidget(tabWidget)

        self.timer.start(100)
Example #2
0
class DataflowWindow(QMainWindow):

    def __init__(self, parent=None):
        super(DataflowWindow, self).__init__(parent)

        # misc initializations
        self.factory = plugins.PluginFactory()
        self.dataflow = plugins.DataflowGraph()
        self.scene = DataflowScene(self.factory, self.dataflow)
        self.scene.setSceneRect(0, 0, 500, 500)
        # result from dataflow
        self.results = {}

        self.timer = QTimer()
        self.connect(self.timer,
                     SIGNAL('timeout()'),
                     self.updateStatusBar)
        self.connect(self.timer,
                     SIGNAL('timeout()'),
                     self.updateFlowStatus)

        # setup menus
        fileMenu = self.menuBar().addMenu('File')
        fileMenu.addAction('New', self.openNew)
        fileMenu.addAction('Load', self.openFile)
        fileMenu.addAction('Save', self.saveFile)

        actionsMenu = ActionsMenu(self.dataflow, self.menuBar())
        self.menuBar().addMenu(actionsMenu)

        # flag to select the correct statusbar message
        self.some_processing_done = False
        self.statusBar().showMessage('Ready')

        # setup dataflow page
        dataflowTab = QWidget()
        self.view = DataflowView()
        self.view.setScene(self.scene)

        self.toolbox = PluginToolbox(factory)
        self.populatePluginToolbox()

        dataflow_tab_layout = QGridLayout()
        dataflow_tab_layout.addWidget(self.toolbox, 0, 0)
        dataflow_tab_layout.addWidget(self.view, 0, 1)
        dataflowTab.setLayout(dataflow_tab_layout)

        # setup report tab
        reportTab = QWidget()

        outputsLabel = QLabel('Data provided by plugins')
        self.outputList = QListWidget()
        self.result_preview = QTextEdit()
        self.result_preview.setReadOnly(True)
        self.html_edit = QTextEdit()
        self.preview_button = QPushButton('Preview report')
        report_tab_layout = QGridLayout()
        report_tab_layout.addWidget(outputsLabel, 0, 0)
        report_tab_layout.addWidget(self.outputList, 1, 0)
        report_tab_layout.addWidget(self.result_preview, 1, 1)
        report_tab_layout.addWidget(self.html_edit, 1, 2)
        report_tab_layout.addWidget(self.preview_button, 2, 2)
        reportTab.setLayout(report_tab_layout)

        self.connect(self.preview_button,
                     SIGNAL('clicked()'),
                     self.show_report)
        self.connect(self.outputList,
                     SIGNAL('currentItemChanged(QListWidgetItem *, QListWidgetItem *)'),
                     self.tmp_show_data)

        # setup tab widget
        tabWidget = QTabWidget()
        tabWidget.addTab(dataflowTab, 'Dataflow')
        tabWidget.addTab(reportTab, 'Output')
        self.setCentralWidget(tabWidget)

        self.timer.start(100)

    def populatePluginToolbox(self):
        plugins = self.factory.list_plugins()
        # add plugins to tabs
        for name in  plugins:
            tab_idx = self.toolbox.addTab(name)
            for plugin_name in plugins[name]:
                w = QListWidgetItem(plugin_name)
                # FIXME
                w.setData(100, QVariant('.'.join([name, plugin_name])))
                self.toolbox.widget(tab_idx).addItem(w)

    def openNew(self):
        self.dataflow.clear()
        self.scene.reload_dataflow()
        self.results = {}
        self.outputList.clear()
        self.result_preview.clear()

    def openFile(self):
        fn = QFileDialog.getOpenFileName(self,
                                               "Open File",
                                               os.getcwd())
        text = None
        try:
            with open(fn, 'rb') as fo:
                text = fo.read()
        except EnvironmentError:
            # FIXME
            pass
        if text is not None:
            if self.dataflow.load_XML(text):
                # all OK
                self.scene.reload_dataflow()
            else:
                # FIXME: notify
                pass
            # read report structure
            root = ElementTree.XML(text)
            report_elem = root.find('report')
            print report_elem.find('text')
            report_text = report_elem.find('text').text
            report_text = report_text if report_text is not None else ''
            self.html_edit.setPlainText(report_text)

    def saveFile(self):
        fn = QFileDialog.getSaveFileName(self,
                                         "Save File",
                                         os.getcwd())
        # dump dataflow as XML
        XML_string = self.dataflow.to_XML()
        if XML_string is not None:
            try:
                root = ElementTree.XML(XML_string)
                report_element = ElementTree.SubElement(root, 'report')
                ElementTree.SubElement(report_element, 'text').text = str(self.html_edit.toPlainText())
                XML_string = ElementTree.tostring(root, encoding='UTF-8')
                with open(fn, 'wb') as fo:
                    fo.write(XML_string)
            except (EnvironmentError, ExpatError) as e:
                # FIXME: handle better
                print e

    def updateStatusBar(self):
        if self.dataflow.is_running():
            self.statusBar().showMessage('Processing dataflow')
            self.some_processing_done = True
        elif self.some_processing_done == True:
            self.statusBar().showMessage('Processing done')

    def updateFlowStatus(self):
        if self.dataflow.results_ready() == True:
            self.results = self.dataflow.get_results()
            for plugin_id in self.results:
                text = 'Output from plugin with id: %d' % plugin_id
                self.outputList.addItem(text)

    def show_report(self):
        class ReportDialog(QDialog):
            def __init__(self, text, parent=None):
                super(ReportDialog, self).__init__(parent)
                text_edit = QTextEdit()
                text_edit.setReadOnly(True)
                text_edit.setHtml(result)
                okButton = QPushButton('Close')
                self.connect(okButton,
                             SIGNAL('clicked()'),
                             partial(self.done, 0))

                # layout
                layout = QVBoxLayout()
                layout.addWidget(text_edit)
                button_layout = QHBoxLayout()
                button_layout.addStretch()
                button_layout.addWidget(okButton)
                layout.addLayout(button_layout)
                self.setLayout(layout)

        def preprocess(HTML):
            HTML = ''.join(['<html><body>', str(HTML), '</html></body>'])
            expr = re.compile(r'\$\{(\S*)\}')
            replacement_info = []
            for match in re.finditer(expr, HTML):
                result_id = match.group(1)
                # FIXME: allow result_id strings
                result = self.results[int(result_id)]
                element = result.as_HTML_element()
                replacement_info.append((match.start(), match.end(), element))
            new_HTML = ''
            new_start = 0
            for start, end, replacement_text in replacement_info:
                new_HTML += HTML[new_start:start] + replacement_text
                new_start = end
            new_HTML += HTML[new_start:]
            return new_HTML

        try:
            result = preprocess(self.html_edit.document().toPlainText())
            dialog = ReportDialog(result)
            dialog.exec_()
        except ValueError:
            # html was invalid
            QMessageBox.warning(None,
                                'Invalid HTML',
                                'Report contains errors and cannot be displayed.',
                                QMessageBox.Ok)
        except KeyError:
            # plugin id was invalid
            QMessageBox.warning(None,
                                'Invalid result referenced',
                                'Invalid result referenced.',
                                QMessageBox.Ok)

    def tmp_show_data(self):
        item = self.outputList.currentItem()
        if item is not None:
            i = int(str(item.text()).split(':')[1].strip())
            data = self.results[i].as_HTML_element()
            self.result_preview.setHtml(data)