Esempio n. 1
0
class modulesManager(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.name = "moduleManager"
        self.stacked = stackedWidget(self)
        self.initWidget()
        self.initShape()

    def initWidget(self):
        self.toolbox = tabBox(self)

    def initShape(self):
        self.mainvbox = QVBoxLayout()
        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)

        self.splitter.addWidget(self.toolbox)
        self.splitter.addWidget(self.stacked)

        self.mainvbox.addWidget(self.splitter)
        self.setLayout(self.mainvbox)

        cw = self.toolbox.currentWidget()
        cw.setCurrentItem(cw.item(0))
        cw.emit(SIGNAL("itemPressed(QListWidgetItem *)"), cw.item(0))

    def execute(self):
        args = self.stacked.currentWidget().validateModule()
        self.stacked.currentWidget().launchTask(args)
Esempio n. 2
0
    def test_dock(self):
        reg = global_registry()
        reg = QtWidgetRegistry(reg, parent=self.app)

        toolbox = WidgetToolBox()
        toolbox.setObjectName("widgets-toolbox")
        toolbox.setModel(reg.model())

        text = QTextEdit()
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)

        splitter.addWidget(toolbox)
        splitter.addWidget(text)

        dock = CollapsibleDockWidget()
        dock.setExpandedWidget(splitter)

        toolbar = QToolBar()
        toolbar.addAction("1")
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setFloatable(False)
        dock.setCollapsedWidget(toolbar)

        dock.show()
        self.app.exec_()
Esempio n. 3
0
    def _create_terminal(self):
        assert self._terminal is None, \
            "should only call _create_terminal once"

        self._terminal_button = QToolButton(None)
        self._terminal_button.setToolTip("Toggle command line")
        self._ui.layerWidget.button_row.addWidget(self._terminal_button)
        self._terminal_button.setArrowType(Qt.DownArrow)

        try:
            from .widgets.terminal import glue_terminal
            widget = glue_terminal(data_collection=self._data,
                                   dc=self._data,
                                   hub=self._hub,
                                   **vars(env))
            self._terminal_button.clicked.connect(self._toggle_terminal)
        except Exception as e:  # pylint: disable=W0703
            import traceback
            self._terminal_exception = traceback.format_exc()
            self._setup_terminal_error_dialog(e)
            return

        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)
        splitter.addWidget(self._ui.centralwidget)
        splitter.addWidget(widget)
        splitter.setStretchFactor(0, 5)
        splitter.setStretchFactor(1, 1)

        self.setCentralWidget(splitter)
        self._terminal = widget

        self._hide_terminal()
Esempio n. 4
0
    def createWidget(self):
        """
        Create the widget
        """
        self.diagramScene = QGraphicsScene(self)

        self.view = QGraphicsView(self.diagramScene)

        self.view.setRenderHint(QPainter.Antialiasing)

        # set the main layout
        layout = QVBoxLayout()

        self.logEdit = QTextEdit()
        self.logEdit.setReadOnly(True)

        hSplitter2 = QSplitter(self)
        hSplitter2.setOrientation(Qt.Vertical)

        hSplitter2.addWidget(self.view)
        hSplitter2.addWidget(self.logEdit)

        hSplitter2.setStretchFactor(0, 1)

        layout.addWidget(hSplitter2)
        self.setLayout(layout)
Esempio n. 5
0
class CanvasToolDock(QWidget):
    """Canvas dock widget with widget toolbox, quick help and
    canvas actions.

    """
    def __init__(self, parent=None, **kwargs):
        QWidget.__init__(self, parent, **kwargs)

        self.__setupUi()

    def __setupUi(self):
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        self.toolbox = WidgetToolBox()

        self.help = QuickHelpWidget(objectName="quick-help")

        self.__splitter = QSplitter()
        self.__splitter.setOrientation(Qt.Vertical)

        self.__splitter.addWidget(self.toolbox)
        self.__splitter.addWidget(self.help)

        self.toolbar = DynamicResizeToolBar()
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)

        self.toolbar.setSizePolicy(QSizePolicy.Ignored,
                                   QSizePolicy.Preferred)

        layout.addWidget(self.__splitter, 10)
        layout.addWidget(self.toolbar)

        self.setLayout(layout)
        self.__splitterResizer = SplitterResizer()
        self.__splitterResizer.setSplitterAndWidget(self.__splitter, self.help)

    def setQuickHelpVisible(self, state):
        """Set the quick help box visibility status.
        """
        self.__splitterResizer.setExpanded(state)

    def quickHelpVisible(self):
        return self.__splitterResizer.expanded()

    def setQuickHelpAnimationEnabled(self, enabled):
        """Enable/disable the quick help animation.
        """
        self.__splitterResizer.setAnimationEnabled(enabled)

    def toogleQuickHelpAction(self):
        """Return a checkable QAction for help show/hide.
        """
        return self.__splitterResizer.toogleExpandedAction()
Esempio n. 6
0
    def initUI(self):
        layout = QVBoxLayout(self)
        
        #Input part
        input_label = QLabel(inputlabeltext, self)
        input_label.setWordWrap(True)
        input_field = QLineEdit("MOM: Oh, good!", self)
        input_search = QPushButton("Search!", self)
        
        splitview = QSplitter(self)
        splitview.setOrientation(Qt.Vertical)
        splitview.setChildrenCollapsible(False)
        
        #Results list
        results_label = QLabel(resultslabeltext, self)
        results_label.setWordWrap(True)
        results_list = QTreeWidget()
        results_list.setColumnCount(3) #pointer, refs to pointer, text
        results_list.header().resizeSection(0, 100)
        results_list.header().resizeSection(1, 40)
        results_list.setFocusPolicy(Qt.NoFocus)
        #results_list.setMaximumSize(QSize(16777215, 100))

        stringeditor = self.scripteditcontroller.getview()
        
        #Pack all into the layout
        layout.addWidget(input_label)
        layout.addWidget(input_field)
        layout.addWidget(input_search)
        
        layout.addWidget(results_label)
        #layout.addWidget(results_list)
        #layout.addWidget(stringeditor)
        splitview.addWidget(results_list)
        splitview.addWidget(stringeditor)
        splitview.setSizes([100, 500])
        layout.addWidget(splitview)

        #Connect to actions
        input_search.clicked.connect(self.searchClick)
        results_list.itemSelectionChanged.connect(self.resultSelected)
        
        #Keeps some elements for later use
        self.input_field = input_field
        self.results_list = results_list
        self.stringeditor = stringeditor
        
        #Show the widget
        self.move(300, 150)
        self.setWindowTitle('Pokemon GBA String Editor')    
        self.show()
    def initUI(self):
        layout = QVBoxLayout(self)

        #Input part
        input_label = QLabel(inputlabeltext, self)
        input_label.setWordWrap(True)
        input_field = QLineEdit("MOM: Oh, good!", self)
        input_search = QPushButton("Search!", self)

        splitview = QSplitter(self)
        splitview.setOrientation(Qt.Vertical)
        splitview.setChildrenCollapsible(False)

        #Results list
        results_label = QLabel(resultslabeltext, self)
        results_label.setWordWrap(True)
        results_list = QTreeWidget()
        results_list.setColumnCount(3)  #pointer, refs to pointer, text
        results_list.header().resizeSection(0, 100)
        results_list.header().resizeSection(1, 40)
        results_list.setFocusPolicy(Qt.NoFocus)
        #results_list.setMaximumSize(QSize(16777215, 100))

        stringeditor = self.scripteditcontroller.getview()

        #Pack all into the layout
        layout.addWidget(input_label)
        layout.addWidget(input_field)
        layout.addWidget(input_search)

        layout.addWidget(results_label)
        #layout.addWidget(results_list)
        #layout.addWidget(stringeditor)
        splitview.addWidget(results_list)
        splitview.addWidget(stringeditor)
        splitview.setSizes([100, 500])
        layout.addWidget(splitview)

        #Connect to actions
        input_search.clicked.connect(self.searchClick)
        results_list.itemSelectionChanged.connect(self.resultSelected)

        #Keeps some elements for later use
        self.input_field = input_field
        self.results_list = results_list
        self.stringeditor = stringeditor

        #Show the widget
        self.move(300, 150)
        self.setWindowTitle('Pokemon GBA String Editor')
        self.show()
Esempio n. 8
0
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setMinimumSize(1024, 600)
        self.setWindowTitle("QWebview-plus for Kiwoom")

        self.view = KiwoomWebViewPlus()
        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Horizontal)
        layout = QVBoxLayout(self)
        layout.setMargin(0)
        layout.addWidget(self.splitter)
        self.splitter.addWidget(self.view)
        self.splitter.addWidget(self.view.webInspector)
Esempio n. 9
0
    def __init_widgets__(self):
        """ Initialise the widgets of the window. """
        # The Address/Attachment portion of the window
        self.attach_model = MessageAttachmentModel()

        attach_list = QListView()
        attach_list.setModel(self.attach_model)

        tab_bar_pxm = QPixmap('res/msg_tabbar_r.png')
        self.tab_bar = QTabWidget()
        self.tab_bar.setTabPosition(2)
        self.tab_bar.setIconSize(QSize(16, 16))
        self.tab_bar.addTab(QWidget(), QIcon(tab_bar_pxm.copy(0, 0, 16, 16)),
                            '')
        self.tab_bar.addTab(attach_list, QIcon(tab_bar_pxm.copy(0, 16, 16,
                                                                16)), '')

        # The Composition Properties portion of the window
        self.subject_line = QLineEdit()
        self.subject_line.setPlaceholderText('Subject')
        QObject.connect(self.subject_line, SIGNAL('textEdited(QString)'),
                        self.update_title)
        priority_label = QLabel('Priority:')
        priority_dropdown = QComboBox(self)
        priority_dropdown.addItems(
            ['Highest', 'High', 'Normal', 'Low', 'Lowest'])

        subject_prio_layout = QHBoxLayout()
        subject_prio_layout.addWidget(self.subject_line)
        #        subject_prio_layout.addStretch(1)
        subject_prio_layout.addWidget(priority_label)
        subject_prio_layout.addWidget(priority_dropdown)

        # The actual Composition portion of the window
        self.message = MessageTextEdit(self)

        # The bottom pane
        bottom_pane_layout = QVBoxLayout()
        bottom_pane_layout.addLayout(subject_prio_layout)
        bottom_pane_layout.addWidget(self.message)
        bottom_pane = QWidget()
        bottom_pane.setLayout(bottom_pane_layout)

        # Central widget is the splitter
        splitter = QSplitter()
        splitter.setOrientation(2)
        splitter.addWidget(self.tab_bar)
        splitter.addWidget(bottom_pane)

        self.setCentralWidget(splitter)
Esempio n. 10
0
    def setObject(self, mobj):
        element = moose.element(mobj)
        try:
            view = self.view_dict[element]
        except KeyError:
            view = ObjectEditView(element)
            self.view_dict[element] = view
            view.model().objectNameChanged.connect(self.emitObjectNameChanged)
        view.colorDialog.colorSelected.connect(
            lambda color: self.colorChanged.emit(element, color))
        textEdit = QTextEdit()
        view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        textEdit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        base = QSplitter()
        base.setOrientation(PyQt4.QtCore.Qt.Vertical)
        layout = QVBoxLayout()
        layout.addWidget(view)  #, 0, 0)
        lineedit = QtGui.QLineEdit("Notes:")
        lineedit.setReadOnly(True)
        layout.addWidget(lineedit)

        if (isinstance(mobj, moose.PoolBase)
                or isinstance(mobj, moose.ReacBase)
                or isinstance(mobj, moose.EnzBase)):
            info = moose.Annotator(mobj.path + '/info')
            textEdit.setText(QtCore.QString(info.getField('notes')))
            textEdit.textChanged.connect(
                lambda: info.setField('notes', str(textEdit.toPlainText())))
            layout.addWidget(textEdit)  #,1,0)

            # self.setRowHeight(notesIndex, self.rowHeight(notesIndex) * 3)
        base.setLayout(layout)
        # base.setSizes( [ view.height()
        #                , base.height() - view.height()
        #                ]
        #              )
        # print("a =>", view.height())
        # print("b =>", base.height())

        # layout.setStretch(0,3)
        # layout.setStretch(1,1)
        # layout.setContentsMargins(QMargins(0,0,0,0))
        self.setWidget(base)
        self.setWindowTitle('Edit: %s' % (element.path))
        view.update()
Esempio n. 11
0
    def setObject(self, mobj):
        element = moose.element(mobj)
        try:
            view = self.view_dict[element]
        except KeyError:
            view = ObjectEditView(element)
            self.view_dict[element] = view
            view.model().objectNameChanged.connect(self.emitObjectNameChanged)
        view.colorDialog.colorSelected.connect(lambda color: self.colorChanged.emit(element, color))
        textEdit = QTextEdit()
        view.setSizePolicy( QSizePolicy.Ignored
                          , QSizePolicy.Ignored
                          )
        textEdit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        base = QSplitter()
        base.setOrientation(PyQt4.QtCore.Qt.Vertical)
        layout = QVBoxLayout()
        layout.addWidget(view)#, 0, 0)

        if ( isinstance(mobj, moose.PoolBase)
           or isinstance(mobj,moose.ReacBase)
           or isinstance(mobj,moose.EnzBase)
           ) :
            info = moose.Annotator(mobj.path +'/info')
            textEdit.setText(QtCore.QString(info.getField('notes')))
            textEdit.textChanged.connect(lambda : info.setField('notes', str(textEdit.toPlainText())))
            layout.addWidget(textEdit)#,1,0)

            # self.setRowHeight(notesIndex, self.rowHeight(notesIndex) * 3)
        base.setLayout(layout)
        # base.setSizes( [ view.height()
        #                , base.height() - view.height()
        #                ]
        #              )
        # print("a =>", view.height())
        # print("b =>", base.height())


        # layout.setStretch(0,3)
        # layout.setStretch(1,1)
        # layout.setContentsMargins(QMargins(0,0,0,0))
        self.setWidget(base)
        self.setWindowTitle('Edit: %s' % (element.path))
        view.update()
Esempio n. 12
0
    def createWidgets(self):
        """
        QtWidgets creation
         _______________________
        |                       |
        |       PyEditor        |
        |_______________________|
        |________QSplitter______|
        |                       |
        |       PyEditor        |
        |_______________________|
        """
        self.srcWidget = EditorWidget(
            self.TEST_DEF_EDITOR,
            "Test Definition:",
            self,
            wrappingText=QtHelper.str2bool(
                Settings.instance().readValue(key='Editor/code-wrapping')))
        self.execWidget = EditorWidget(
            self.TEST_EXEC_EDITOR,
            "Test Execution:",
            self,
            wrappingText=QtHelper.str2bool(
                Settings.instance().readValue(key='Editor/code-wrapping')),
            toolbar=False)

        self.srcEditor = self.srcWidget.editor
        self.execEditor = self.execWidget.editor

        layout = QVBoxLayout()

        hSplitter = QSplitter(self)
        hSplitter.setOrientation(Qt.Vertical)

        hSplitter.addWidget(self.srcWidget)
        hSplitter.addWidget(self.execWidget)
        hSplitter.setContentsMargins(0, 0, 0, 0)
        hSplitter.setStretchFactor(0, 1)

        layout.addWidget(hSplitter)
        layout.setContentsMargins(2, 0, 0, 0)

        self.setLayout(layout)
Esempio n. 13
0
class NetWorthView(AccountSheetView):
    def _setup(self):
        self._setupUi()
        self.sheet = self.nwsheet = NetWorthSheet(self.model.bsheet, view=self.treeView)
        self.graph = self.nwgraph = Chart(self.model.nwgraph, view=self.graphView)
        self.piechart = Chart(self.model.pie, view=self.pieChart)
    
    def _setupUi(self):
        self.resize(558, 447)
        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.setSpacing(0)
        self.mainLayout.setMargin(0)
        self.splitterView = QSplitter()
        self.splitterView.setChildrenCollapsible(False)
        self.splitterView.setOrientation(Qt.Vertical)
        self.subSplitterView = QSplitter()
        self.subSplitterView.setChildrenCollapsible(False)
        self.treeView = TreeView(self)
        self.treeView.setAcceptDrops(True)
        self.treeView.setFrameShape(QFrame.NoFrame)
        self.treeView.setFrameShadow(QFrame.Plain)
        self.treeView.setEditTriggers(QAbstractItemView.EditKeyPressed|QAbstractItemView.SelectedClicked)
        self.treeView.setDragEnabled(True)
        self.treeView.setDragDropMode(QAbstractItemView.InternalMove)
        self.treeView.setUniformRowHeights(True)
        self.treeView.setAllColumnsShowFocus(True)
        self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.treeView.header().setStretchLastSection(False)
        self.subSplitterView.addWidget(self.treeView)
        self.pieChart = PieChartView(self)
        self.pieChart.setMinimumSize(300, 0)
        self.subSplitterView.addWidget(self.pieChart)
        self.splitterView.addWidget(self.subSplitterView)
        self.graphView = LineGraphView(self)
        self.graphView.setMinimumSize(0, 200)
        self.splitterView.addWidget(self.graphView)
        self.splitterView.setStretchFactor(0, 1)
        self.splitterView.setStretchFactor(1, 0)
        self.subSplitterView.setStretchFactor(0, 1)
        self.subSplitterView.setStretchFactor(1, 0)
        self.mainLayout.addWidget(self.splitterView)
Esempio n. 14
0
    def g_display(self):
        QWidget.__init__(self)

        layout = QHBoxLayout(self)
        splitter = QSplitter()

        layout.addWidget(splitter)
        splitter.setOrientation(Qt.Horizontal)

        if self.node is not None:
            processus_manager = ModuleProcessusManager()
            evt = processus_manager.get('evt')
            if not self.preview:
                self.evtWidget = evt.getAllEvtFiles()
                if self.evtWidget:
                    splitter.addWidget(self.evtWidget)
                    splitter.setStretchFactor(1, 2)
            else:
                self.evtWidget = evt.previewWidget(long(self.node.this))
                if self.evtWidget:
                    splitter.addWidget(self.evtWidget)
Esempio n. 15
0
    def setup_layout(self):
        outer_layout = QVBoxLayout()
        outer_layout.addWidget(self.menu_bar)
        outer_layout.setStretch(0, 1)

        h_splitter = QSplitter(self)
        h_splitter.setOrientation(Qt.Horizontal)

        # FIRST COLUMN of h_splitter is chromatogram + peakmap:  ############################

        v_splitter1 = QSplitter(self)
        v_splitter1.setOrientation(Qt.Vertical)
        v_splitter1.addWidget(self.eic_plotter)
        v_splitter1.addWidget(self.peakmap_plotter)
        self.peakmap_plotter.setMinimumSize(250, 200)
        v_splitter1.setStretchFactor(0, 1)
        v_splitter1.setStretchFactor(1, 3)

        h_splitter.addWidget(v_splitter1)
        h_splitter.setStretchFactor(0, 2)

        # SECOND COLUMN of h_splittier holds controlx boxes + mz plot #######################

        v_splitter2 = QSplitter(self)
        v_splitter2.setOrientation(Qt.Vertical)

        v_splitter2.addWidget(self.image_scaling_widget)
        v_splitter2.addWidget(self.spectra_selector_widget)
        v_splitter2.addWidget(self.view_range_widget)
        v_splitter2.addWidget(self.history_list)
        v_splitter2.addWidget(self.mz_plotter)

        v_splitter2.setStretchFactor(0, 0)
        v_splitter2.setStretchFactor(1, 0)
        v_splitter2.setStretchFactor(2, 0)
        v_splitter2.setStretchFactor(3, 0)
        v_splitter2.setStretchFactor(4, 1)

        h_splitter.addWidget(v_splitter2)
        h_splitter.setStretchFactor(1, 1)

        # THIRD COLUMN of h_splittier holds control table + buttons ##########################
        if self.table:
            frame = QFrame(self)
            layout = QVBoxLayout(frame)
            frame.setLayout(layout)
            layout.addWidget(self.table_widget)

            button_row_layout = QHBoxLayout(frame)
            button_row_layout.addWidget(self.select_all_peaks)
            button_row_layout.addWidget(self.unselect_all_peaks)
            button_row_layout.addWidget(self.done_button)

            layout.addLayout(button_row_layout)
            h_splitter.addWidget(frame)
            h_splitter.setStretchFactor(2, 2)

        outer_layout.addWidget(h_splitter)
        self.setLayout(outer_layout)
        outer_layout.setStretch(1, 99)
Esempio n. 16
0
    def setup_layout(self):
        outer_layout = QVBoxLayout()
        outer_layout.addWidget(self.menu_bar)
        outer_layout.setStretch(0, 1)

        h_splitter = QSplitter(self)
        h_splitter.setOrientation(Qt.Horizontal)

        # FIRST COLUMN of h_splitter is chromatogram + peakmap:  ############################

        v_splitter1 = QSplitter(self)
        v_splitter1.setOrientation(Qt.Vertical)
        v_splitter1.addWidget(self.eic_plotter)
        v_splitter1.addWidget(self.peakmap_plotter)
        self.peakmap_plotter.setMinimumSize(250, 200)
        v_splitter1.setStretchFactor(0, 1)
        v_splitter1.setStretchFactor(1, 3)

        h_splitter.addWidget(v_splitter1)
        h_splitter.setStretchFactor(0, 2)

        # SECOND COLUMN of h_splittier holds controlx boxes + mz plot #######################

        v_splitter2 = QSplitter(self)
        v_splitter2.setOrientation(Qt.Vertical)

        v_splitter2.addWidget(self.image_scaling_widget)
        v_splitter2.addWidget(self.spectra_selector_widget)
        v_splitter2.addWidget(self.view_range_widget)
        v_splitter2.addWidget(self.history_list)
        v_splitter2.addWidget(self.mz_plotter)

        v_splitter2.setStretchFactor(0, 0)
        v_splitter2.setStretchFactor(1, 0)
        v_splitter2.setStretchFactor(2, 0)
        v_splitter2.setStretchFactor(3, 0)
        v_splitter2.setStretchFactor(4, 1)

        h_splitter.addWidget(v_splitter2)
        h_splitter.setStretchFactor(1, 1)

        # THIRD COLUMN of h_splittier holds control table + buttons ##########################
        if self.table:
            frame = QFrame(self)
            layout = QVBoxLayout(frame)
            frame.setLayout(layout)
            layout.addWidget(self.table_widget)

            button_row_layout = QHBoxLayout(frame)
            button_row_layout.addWidget(self.select_all_peaks)
            button_row_layout.addWidget(self.unselect_all_peaks)
            button_row_layout.addWidget(self.done_button)

            layout.addLayout(button_row_layout)
            h_splitter.addWidget(frame)
            h_splitter.setStretchFactor(2, 2)

        outer_layout.addWidget(h_splitter)
        self.setLayout(outer_layout)
        outer_layout.setStretch(1, 99)
Esempio n. 17
0
 def splitViewSpace(self, viewspace, orientation):
     """Split the given view.
     
     If orientation == Qt.Horizontal, adds a new view to the right.
     If orientation == Qt.Vertical, adds a new view to the bottom.
     
     """
     active = viewspace is self.activeViewSpace()
     splitter = viewspace.parentWidget()
     newspace = ViewSpace(self)
     
     if splitter.count() == 1:
         splitter.setOrientation(orientation)
         size = splitter.sizes()[0]
         splitter.addWidget(newspace)
         splitter.setSizes([size / 2, size / 2])
     elif splitter.orientation() == orientation:
         index = splitter.indexOf(viewspace)
         splitter.insertWidget(index + 1, newspace)
     else:
         index = splitter.indexOf(viewspace)
         newsplitter = QSplitter()
         newsplitter.setOrientation(orientation)
         sizes = splitter.sizes()
         splitter.insertWidget(index, newsplitter)
         newsplitter.addWidget(viewspace)
         splitter.setSizes(sizes)
         size = newsplitter.sizes()[0]
         newsplitter.addWidget(newspace)
         newsplitter.setSizes([size / 2, size / 2])
     self._viewSpaces.insert(0, newspace)
     newspace.showDocument(viewspace.document())
     if active:
         newspace.activeView().setFocus()
     self.actionCollection.window_close_view.setEnabled(self.canCloseViewSpace())
     self.actionCollection.window_close_others.setEnabled(self.canCloseViewSpace())
Esempio n. 18
0
class NetCDF3Browser(QWidget):
    """netCDF-Browser"""

    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(0)
        self.layout.setMargin(0)

        self.toolBar = QFrame(self)
        self.toolBarLayout = QHBoxLayout(self.toolBar)
        self.toolBarLayout.setMargin(2)
        self.toolBarLayout.setSpacing(2)
        self.layout.addWidget(self.toolBar)

        self.loadButton = QToolButton(self.toolBar)
        self.loadButton.setText(QCoreApplication.translate('NetCDF3', 'Open...'))
        self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen)))
        self.loadButton.setToolTip(QCoreApplication.translate('NetCDF3', 'Open a netCDF3 file'))
        self.toolBarLayout.addWidget(self.loadButton)
        self.connect(self.loadButton, SIGNAL('pressed()'), self.loadFile)

        self.dropButton = QToolButton(self.toolBar)
        self.dropButton.setText(QCoreApplication.translate('NetCDF3', 'Close All'))
        self.dropButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.clear)))
        self.dropButton.setToolTip(QCoreApplication.translate('NetCDF3', 'Drop all open netCDF3 files'))
        self.toolBarLayout.addWidget(self.dropButton)
        self.connect(self.dropButton, SIGNAL('pressed()'), self.dropFiles)
        self.dropButton.setEnabled(False)

        self.toolBarLayout.addStretch(100)

        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Vertical)
        self.treeView = QTreeView(self.splitter)
        self.treeView.setAlternatingRowColors(True)
        self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.textBrowser = QTextBrowser(self.splitter)
        self.layout.addWidget(self.splitter)
        self.splitter.setStretchFactor(0, 90)
        self.splitter.setStretchFactor(1, 10)
        self.model = NetCDF3Model()
        self.treeView.setModel(self.model)
        self.treeView.setSortingEnabled(True)
        self.treeView.expandAll()
        self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem)
        self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction)

        ftActions = SimuVis4.Globals.fileTypeActions
        ftActions.addAction(self.loadFile, ('application/x-netcdf',),
            QCoreApplication.translate('NetCDF3', 'Open in netCDF3 browser'), 10)

    def loadFile(self, fn=None):
        if not fn:
            fn = QFileDialog.getOpenFileName(self, QCoreApplication.translate('NetCDF3', "Select netCDF3 file to open"),
                SimuVis4.Globals.defaultFolder)
            if not fn.isEmpty():
                fn = unicode(fn)
                SimuVis4.Globals.defaultFolder, tmp = os.path.split(fn)
            else:
                return
        self.model.addNcFile(fn)
        SimuVis4.Globals.dataBrowser.toolBox.setCurrentWidget(self)

    def dropFiles(self):
        # FIXME: ...
        pass

    def itemAction(self, mi,):
        # FIXME: use a MIME-Handler here
        i = self.model.itemFromIndex(mi)
        t, nc = i.ncItem
        QMessageBox.information(self,
                QCoreApplication.translate('NetCDF3', 'netCDF3: Item clicked'),
                QCoreApplication.translate('NetCDF3', 'You clicked an item in the netCDF3-browser'))

    def showItem(self, mi, pr):
        i = self.model.itemFromIndex(mi)
        t, nc = i.ncItem
        txt = ""
        name = str(i.data().toString())
        if t == 'F':
            p, f = os.path.split(name)
            txt = "<i>File </i><b>%s</b><br> in %s" % (f, p)
        elif t == 'A':
            txt = "<i>Attribute </i><b>%s:</b><br>%s" % (name, escape(unicode(nc)))
        elif t == 'D':
            txt = "<i>Dimension </i><b>%s:</b><br>%s" % (name, str(nc))
        elif t == 'V':
            txt = "<i>Variable </i><b>%s:</b><br>Typecode: %s<br>Dimensions: %s<br>Shape: %s" % \
                (name, nc.typecode(), '*'.join(d for d in nc.dimensions), nc.shape)
        else:
            return
        self.textBrowser.setText(txt)
Esempio n. 19
0
class MikiWindow(QMainWindow):
    def __init__(self, settings, parent=None):
        super(MikiWindow, self).__init__(parent)
        self.setObjectName("mikiWindow")
        self.settings = settings
        self.notePath = settings.notePath

        ################ Setup core components ################
        self.notesTree = MikiTree(self)
        self.quickNoteNav = QLineEdit()
        self.notesTab = QWidget()
        self.completer = SlashPleter()
        self.completer.setModel(self.notesTree.model())
        self.quickNoteNav.setCompleter(self.completer)
        self.notesTree.setObjectName("notesTree")
        self.initTree(self.notePath, self.notesTree)
        self.notesTree.sortItems(0, Qt.AscendingOrder)

        self.ix = None
        self.setupWhoosh()

        self.viewedList = QToolBar(self.tr('Recently Viewed'), self)
        self.viewedList.setIconSize(QSize(16, 16))
        self.viewedList.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.viewedListActions = []
        self.noteSplitter = QSplitter(Qt.Horizontal)

        self.dockIndex = QDockWidget("Index")
        self.dockSearch = QDockWidget("Search")
        self.searchEdit = QLineEdit()
        self.searchView = MikiSearch(self)
        self.searchTab = QWidget()
        self.dockToc = QDockWidget("TOC")
        self.tocTree = TocTree()
        self.dockAttachment = QDockWidget("Attachment")
        self.attachmentView = AttachmentView(self)

        self.notesEdit = MikiEdit(self)
        self.notesEdit.setObjectName("notesEdit")
        MikiHighlighter(self.notesEdit)
        self.notesView = MikiView(self)

        self.findBar = QToolBar(self.tr('Find'), self)
        self.findBar.setFixedHeight(30)
        self.findEdit = QLineEdit(self.findBar)
        self.checkBox = QCheckBox(self.tr('Match case'), self.findBar)

        self.statusBar = QStatusBar(self)
        self.statusLabel = QLabel(self)

        self.altPressed = False


        ################ Setup actions ################
        self.actions = dict()
        self.setupActions()


        ################ Setup mainwindow ################
        self.setupMainWindow()

        # show changelogs after upgrade mikidown
        if self.settings.version < __version__:
            self.changelogHelp()
            self.settings.qsettings.setValue("version", __version__)


    def setupActions(self):

        # Global Actions
        actTabIndex = self.act(self.tr('Switch to Index Tab'),
            lambda: self.raiseDock(self.dockIndex), 'Ctrl+Shift+I')
        actTabSearch = self.act(self.tr('Switch to Search Tab'),
            lambda: self.raiseDock(self.dockSearch), 'Ctrl+Shift+F')
        self.addAction(actTabIndex)
        self.addAction(actTabSearch)

        ################ Menu Actions ################
        # actions in menuFile
        actionNewPage = self.act(self.tr('&New Page...'),
            self.notesTree.newPage, QKeySequence.New)
        self.actions.update(newPage=actionNewPage)

        actionNewSubpage = self.act(self.tr('New Sub&page...'),
            self.notesTree.newSubpage, 'Ctrl+Shift+N')
        self.actions.update(newSubpage=actionNewSubpage)

        actionImportPage = self.act(self.tr('&Import Page...'), self.importPage)
        self.actions.update(importPage=actionImportPage)

        actionNBSettings = self.act(self.tr('Notebook Set&tings...'), self.notebookSettings)
        self.actions.update(NBSettings=actionNBSettings)

        actionMDSettings = self.act(self.tr('&Mikidown Settings...'), self.mikidownSettings)
        self.actions.update(MDSettings=actionMDSettings)

        actionOpenNotebook = self.act(self.tr('&Open Notebook...'),
            self.openNotebook, QKeySequence.Open)
        self.actions.update(openNotebook=actionOpenNotebook)

        actionReIndex = self.act(self.tr('Re-index'), self.reIndex)
        self.actions.update(reIndex=actionReIndex)

        actionSave = self.act(self.tr('&Save'),
            self.saveCurrentNote, QKeySequence.Save)
        actionSave.setEnabled(False)
        self.actions.update(save=actionSave)

        actionSaveAs = self.act(self.tr('Save &As...'),
            self.saveNoteAs, QKeySequence.SaveAs)
        self.actions.update(saveAs=actionSaveAs)

        actionHtml = self.act(self.tr('to &HTML'), self.notesEdit.saveAsHtml)
        self.actions.update(html=actionHtml)

        actionPrint = self.act(self.tr('&Print'),
            self.printNote, QKeySequence.Print)
        self.actions.update(print_=actionPrint)

        actionRenamePage = self.act(self.tr('&Rename Page...'),
            self.notesTree.renamePage, 'F2')
        self.actions.update(renamePage=actionRenamePage)

        actionDelPage = self.act(self.tr('&Delete Page'),
            self.notesTree.delPageWrapper, QKeySequence.Delete)
        self.actions.update(delPage=actionDelPage)

        actionQuit = self.act(self.tr('&Quit'), self.close, QKeySequence.Quit)
        actionQuit.setMenuRole(QAction.QuitRole)
        self.actions.update(quit=actionQuit)

        # actions in menuEdit
        actionUndo = self.act(self.tr('&Undo'),
            lambda: self.notesEdit.undo(), QKeySequence.Undo)
        actionUndo.setEnabled(False)
        self.notesEdit.undoAvailable.connect(actionUndo.setEnabled)
        self.actions.update(undo=actionUndo)

        actionRedo = self.act(self.tr('&Redo'),
            lambda: self.notesEdit.redo(), QKeySequence.Redo)
        actionRedo.setEnabled(False)
        self.notesEdit.redoAvailable.connect(actionRedo.setEnabled)
        self.actions.update(redo=actionRedo)

        actionFindText = self.act(self.tr('&Find Text'),
            self.findBar.setVisible, QKeySequence.Find, True)
        self.actions.update(findText=actionFindText)

        actionFind = self.act(self.tr('Next'),
            self.findText, QKeySequence.FindNext)
        self.actions.update(find=actionFind)

        actionFindPrev = self.act(self.tr('Previous'),
            lambda: self.findText(back=True), QKeySequence.FindPrevious)
        self.actions.update(findPrev=actionFindPrev)

        actionSortLines = self.act(self.tr('&Sort Lines'), self.sortLines)
        self.actions.update(sortLines=actionSortLines)

        actionQuickNav = self.act(self.tr("&Quick Open Note"),
                        self.quickNoteNav.setFocus, 'Ctrl+G')
        self.addAction(actionQuickNav)

        actionInsertImage = self.act(self.tr('&Insert Attachment'),
            self.notesEdit.insertAttachmentWrapper, 'Ctrl+I')
        actionInsertImage.setEnabled(False)
        self.actions.update(insertImage=actionInsertImage)

        # actions in menuView
        actionEdit = self.act(self.tr('Edit'), self.edit, 'Ctrl+E',
            True, QIcon(':/icons/edit.svg'), 'Edit mode (Ctrl+E)')
        self.actions.update(edit=actionEdit)

        actionSplit = self.act(self.tr('Split'), self.liveView, 'Ctrl+R',
            True, QIcon(':/icons/split.svg'), 'Split mode (Ctrl+R)')
        self.actions.update(split=actionSplit)

        actionFlipEditAndView = self.act(self.tr('Flip Edit and View'),
            self.flipEditAndView)
        actionFlipEditAndView.setEnabled(False)
        self.actions.update(flipEditAndView=actionFlipEditAndView)

        #actionLeftAndRight = self.act(
        #    self.tr('Split into Left and Right'), trig=self.leftAndRight)
        #actionUpAndDown = self.act(
        #    self.tr('Split into Up and Down'), trig=self.upAndDown)
        # self.actionLeftAndRight.setEnabled(False)
        # self.actionUpAndDown.setEnabled(False)

        # actions in menuHelp
        actionReadme = self.act(self.tr('README'), self.readmeHelp)
        self.actions.update(readme=actionReadme)

        actionChangelog = self.act(self.tr('Changelog'), self.changelogHelp)
        self.actions.update(changelog=actionChangelog)

        actionAboutQt = self.act(self.tr('About Qt'), qApp.aboutQt)
        self.actions.update(aboutQt=actionAboutQt)


    def setupMainWindow(self):
        self.resize(800, 600)
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((
            screen.width()-size.width())/2, (screen.height()-size.height())/2)
        self.setWindowTitle(
            '{} - {}'.format(self.settings.notebookName, __appname__))

        self.viewedList.setFixedHeight(25)
        self.noteSplitter.addWidget(self.notesEdit)
        self.noteSplitter.addWidget(self.notesView)
        mainSplitter = QSplitter(Qt.Vertical)
        mainSplitter.setChildrenCollapsible(False)
        mainSplitter.addWidget(self.viewedList)
        mainSplitter.addWidget(self.noteSplitter)
        mainSplitter.addWidget(self.findBar)
        self.setCentralWidget(mainSplitter)

        self.searchEdit.returnPressed.connect(self.searchNote)
        self.quickNoteNav.returnPressed.connect(self.openFuncWrapper)
        searchLayout = QVBoxLayout()
        searchLayout.addWidget(self.searchEdit)
        searchLayout.addWidget(self.searchView)
        self.searchTab.setLayout(searchLayout)
        self.tocTree.header().close()

        indexLayout = QVBoxLayout(self.notesTab)
        indexLayout.addWidget(self.quickNoteNav)
        indexLayout.addWidget(self.notesTree)

        self.dockIndex.setObjectName("Index")
        self.dockIndex.setWidget(self.notesTab)
        self.dockSearch.setObjectName("Search")
        self.dockSearch.setWidget(self.searchTab)
        self.dockToc.setObjectName("TOC")
        self.dockToc.setWidget(self.tocTree)
        self.dockAttachment.setObjectName("Attachment")
        self.dockAttachment.setWidget(self.attachmentView)

        self.setDockOptions(QMainWindow.VerticalTabs)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockIndex)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockSearch)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockToc)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockAttachment)
        self.tabifyDockWidget(self.dockIndex, self.dockSearch)
        self.tabifyDockWidget(self.dockSearch, self.dockToc)
        self.tabifyDockWidget(self.dockToc, self.dockAttachment)
        self.setTabPosition(Qt.LeftDockWidgetArea, QTabWidget.North)
        self.dockIndex.raise_()      # Put dockIndex on top of the tab stack

        menuBar = QMenuBar(self)
        self.setMenuBar(menuBar)
        menuFile = menuBar.addMenu(self.tr('&File'))
        menuEdit = menuBar.addMenu(self.tr('&Edit'))
        menuView = menuBar.addMenu(self.tr('&View'))
        menuHelp = menuBar.addMenu(self.tr('&Help'))
        # menuFile
        menuFile.addAction(self.actions['newPage'])
        menuFile.addAction(self.actions['newSubpage'])
        menuFile.addAction(self.actions['NBSettings'])
        menuFile.addAction(self.actions['MDSettings'])
        menuFile.addAction(self.actions['importPage'])
        menuFile.addAction(self.actions['openNotebook'])
        menuFile.addAction(self.actions['reIndex'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['save'])
        menuFile.addAction(self.actions['saveAs'])
        menuFile.addAction(self.actions['print_'])
        menuExport = menuFile.addMenu(self.tr('&Export'))
        menuExport.addAction(self.actions['html'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['renamePage'])
        menuFile.addAction(self.actions['delPage'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['quit'])
        # menuEdit
        menuEdit.addAction(self.actions['undo'])
        menuEdit.addAction(self.actions['redo'])
        menuEdit.addAction(self.actions['findText'])
        menuEdit.addSeparator()
        menuEdit.addAction(self.actions['sortLines'])
        menuEdit.addAction(self.actions['insertImage'])
        # menuView
        menuView.addAction(self.actions['edit'])
        menuView.addAction(self.actions['split'])
        menuView.addAction(self.actions['flipEditAndView'])
        menuShowHide = menuView.addMenu(self.tr('Show/Hide'))
        menuShowHide.addAction(self.dockIndex.toggleViewAction())
        menuShowHide.addAction(self.dockSearch.toggleViewAction())
        menuShowHide.addAction(self.dockToc.toggleViewAction())
        menuShowHide.addAction(self.dockAttachment.toggleViewAction())
        #menuMode = menuView.addMenu(self.tr('Mode'))
        #menuMode.addAction(self.actionLeftAndRight)
        #menuMode.addAction(self.actionUpAndDown)
        # menuHelp
        menuHelp.addAction(self.actions['readme'])
        menuHelp.addAction(self.actions['changelog'])
        menuHelp.addAction(self.actions['aboutQt'])

        toolBar = QToolBar(self.tr("toolbar"), self)
        toolBar.setObjectName("toolbar")       # needed in saveState()
        toolBar.setIconSize(QSize(16, 16))
        toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.addToolBar(Qt.TopToolBarArea, toolBar)
        toolBar.addAction(self.actions['edit'])
        toolBar.addAction(self.actions['split'])
        self.findEdit.returnPressed.connect(self.findText)
        self.findBar.addWidget(self.findEdit)
        self.findBar.addWidget(self.checkBox)
        self.findBar.addAction(self.actions['findPrev'])
        self.findBar.addAction(self.actions['find'])
        self.findBar.setVisible(False)
        self.findBar.visibilityChanged.connect(self.findBarVisibilityChanged)

        self.setStatusBar(self.statusBar)
        self.statusBar.addWidget(self.statusLabel, 1)

        self.notesTree.currentItemChanged.connect(
            self.currentItemChangedWrapper)
        self.tocTree.itemClicked.connect(self.tocNavigate)
        self.notesEdit.textChanged.connect(self.noteEditted)

        self.notesEdit.document(
        ).modificationChanged.connect(self.modificationChanged)

        self.updateRecentViewedNotes()
        notes = self.settings.recentViewedNotes()
        if len(notes) != 0:
            item = self.notesTree.pageToItem(notes[0])
            self.notesTree.setCurrentItem(item)

    def openFuncWrapper(self):
        self.openFunction(self.quickNoteNav.text())()

    def setupWhoosh(self):
        # Initialize whoosh index, make sure notePath/.indexdir exists
        indexdir = self.settings.indexdir
        try:
            self.ix = open_dir(indexdir)
        except:
            QDir().mkpath(indexdir)
            self.ix = create_in(indexdir, self.settings.schema)
            # Fork a process to update index, which benefit responsiveness.
            p = Thread(target=self.whoosh_index, args=())
            p.start()


    def restore(self):
        """ Restore saved geometry and state.
            Set the status of side panels in View Menu correspondently.
        """
        if self.settings.geometry:
            self.restoreGeometry(self.settings.geometry)
        if self.settings.windowstate:
            self.restoreState(self.settings.windowstate)

    def initTree(self, notePath, parent):
        ''' When there exist foo.md, foo.mkd, foo.markdown,
            only one item will be shown in notesTree.
        '''
        if not QDir(notePath).exists():
            return
        notebookDir = QDir(notePath)
        notesList = notebookDir.entryInfoList(['*.md', '*.mkd', '*.markdown'],
                                               QDir.NoFilter,
                                               QDir.Name|QDir.IgnoreCase)
        nl = [note.completeBaseName() for note in notesList]
        noduplicate = list(set(nl))
        for name in noduplicate:
            item = QTreeWidgetItem(parent, [name])
            path = notePath + '/' + name
            self.initTree(path, item)

    def updateToc(self):
        ''' TOC is updated in `updateView`
            tocTree fields: [hdrText, hdrPosition, hdrAnchor]
        '''
        root = self.notesTree.currentPage()
        self.tocTree.clear()
        item = QTreeWidgetItem(self.tocTree, [root, '0'])
        curLevel = 0
        for (level, h, p, a) in parseHeaders(self.notesEdit.toPlainText()):
            val = [h, str(p), a]
            if level == curLevel:
                item = QTreeWidgetItem(item.parent(), val)
            elif level < curLevel:
                item = QTreeWidgetItem(item.parent().parent(), val)
                curLevel = level
            else:
                item = QTreeWidgetItem(item, val)
                curLevel = level
        self.tocTree.expandAll()

    def updateAttachmentView(self):
        # Update attachmentView to show corresponding attachments.
        item = self.notesTree.currentItem()
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(item))
        self.attachmentView.setRootIndex(index)

    def openFile(self, filename):
        fh = QFile(filename)
        try:
            if not fh.open(QIODevice.ReadOnly):
                raise IOError(fh.errorString())
        except IOError as e:
            QMessageBox.warning(self, 'Read Error',
                                'Failed to open %s: %s' % (filename, e))
        finally:
            if fh is not None:
                noteBody = QTextStream(fh).readAll()
                fh.close()
                self.notesEdit.setPlainText(noteBody)
                self.notesView.scrollPosition = QPoint(0, 0)
                # self.actionSave.setEnabled(False)
                self.notesEdit.document().setModified(False)
                self.notesView.updateView()
                self.setCurrentNote()
                self.updateRecentViewedNotes()
                #self.statusLabel.setText(noteFullName)

    def currentItemChangedWrapper(self, current, previous):
        if current is None:
            return
        #if previous != None and self.notesTree.pageExists(previous):
        prev = self.notesTree.itemToPage(previous)
        if self.notesTree.pageExists(prev):
            self.saveNote(previous)

        currentFile = self.notesTree.itemToFile(current)
        self.openFile(currentFile)

        # Update attachmentView to show corresponding attachments.
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(current))
        self.attachmentView.setRootIndex(index)

    def tocNavigate(self, current):
        ''' works for notesEdit now '''
        if current is None:
            return
        pos = int(current.text(1))
        link = "file://" + self.notePath + "/#" + current.text(2)
        # Move cursor to END first will ensure
        # header is positioned at the top of visual area.
        self.notesEdit.moveCursor(QTextCursor.End)
        cur = self.notesEdit.textCursor()
        cur.setPosition(pos, QTextCursor.MoveAnchor)
        self.notesEdit.setTextCursor(cur)
        self.notesView.load(QUrl(link))

    def switchNote(self, num):
        if num < len(self.viewedListActions):
            self.viewedListActions[num].trigger()

    def saveCurrentNote(self):
        item = self.notesTree.currentItem()
        self.saveNote(item)

    def saveNote(self, item):
        if self.notesEdit.document().isModified():
            self.notesEdit.document().setModified(False)
        else:
            return
        self.notesEdit.save(item)

    def saveNoteAs(self):
        self.saveCurrentNote()
        fileName = QFileDialog.getSaveFileName(self, self.tr('Save as'), '',
            '(*.md *.mkd *.markdown);;'+self.tr('All files(*)'))
        if fileName == '':
            return
        if not QFileInfo(fileName).suffix():
            fileName += '.md'
        fh = QFile(fileName)
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << self.notesEdit.toPlainText()
        fh.close()

    def printNote(self):
        printer = QPrinter(QPrinter.HighResolution)
        printer.setCreator(__appname__ + ' ' + __version__)
        printer.setDocName(self.notesTree.currentItem().text(0))
        printdialog = QPrintDialog(printer, self)
        if printdialog.exec() == QDialog.Accepted:
            self.notesView.print_(printer)

    def noteEditted(self):
        """ Continuously get fired while editing"""
        self.updateToc()
        self.notesView.updateLiveView()

    def modificationChanged(self, changed):
        """ Fired one time: modified or not """
        self.actions['save'].setEnabled(changed)
        name = self.notesTree.currentPage()
        self.statusBar.clearMessage()
        if changed:
            self.statusLabel.setText(name + '*')
        else:
            self.statusLabel.setText(name)

    def importPage(self):
        filename = QFileDialog.getOpenFileName(
            self, self.tr('Import file'), '',
            '(*.md *.mkd *.markdown *.txt);;'+self.tr('All files(*)'))
        if filename == '':
            return
        self.importPageCore(filename)

    def importPageCore(self, filename):
        fh = QFile(filename)
        fh.open(QIODevice.ReadOnly)
        fileBody = QTextStream(fh).readAll()
        fh.close()
        page = QFileInfo(filename).completeBaseName()
        fh = QFile(self.notesTree.pageToFile(page))
        if fh.exists():
            QMessageBox.warning(self, 'Import Error',
                'Page already exists: %s' % page)
            dialog = LineEditDialog(self.notePath, self)
            if dialog.exec_():
                page = dialog.editor.text()
                fh.close()
                fh = QFile(self.notesTree.pageToFile(page))
            else:
                return
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << fileBody
        fh.close()
        item = QTreeWidgetItem(self.notesTree, [page])
        self.notesTree.sortItems(0, Qt.AscendingOrder)
        self.notesTree.setCurrentItem(item)

    def openNotebook(self):
        dialog = NotebookListDialog(self)
        if dialog.exec_():
            pass

    def notebookSettings(self):
        dialog = NotebookSettingsDialog(self)
        if dialog.exec_():
            pass

    def mikidownSettings(self):
        dialog = MikidownCfgDialog(self)
        if dialog.exec_():
            pass


    def reIndex(self):
        """ Whoosh index breaks for unknown reasons (sometimes) """
        shutil.rmtree(self.settings.indexdir)
        self.setupWhoosh()

    def act(self, name, trig, shortcut=None, checkable=False,
            icon=None, tooltip=None):
        """ A wrapper to several QAction methods """
        if icon:
            action = QAction(icon, name, self)
        else:
            action = QAction(name, self)
        if shortcut:
            action.setShortcut(QKeySequence(shortcut))
        action.setCheckable(checkable)
        if tooltip:
            action.setToolTip(tooltip)
        action.triggered.connect(trig)
        return action

    def edit(self, viewmode):
        """ Switch between EDIT and VIEW mode. """

        if self.actions['split'].isChecked():
            self.actions['split'].setChecked(False)
        self.notesView.setVisible(not viewmode)
        self.notesEdit.setVisible(viewmode)

        # Gives the keyboard input focus to notesEdit/notesView.
        # Without this, keyboard input may change note text even when
        # notesEdit is invisible.
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.saveCurrentNote()
        self.actions['insertImage'].setEnabled(viewmode)
        #self.actionLeftAndRight.setEnabled(True)
        #self.actionUpAndDown.setEnabled(True)

        # Render the note text as it is.
        self.notesView.updateView()

    def liveView(self, viewmode):
        """ Switch between VIEW and LIVE VIEW mode. """

        self.actions['split'].setChecked(viewmode)
        sizes = self.noteSplitter.sizes()
        if self.actions['edit'].isChecked():
            self.actions['edit'].setChecked(False)
            self.notesView.setVisible(viewmode)
            splitSize = [sizes[0]*0.45, sizes[0]*0.55]
        else:
            self.notesEdit.setVisible(viewmode)
            splitSize = [sizes[1]*0.45, sizes[1]*0.55]

        # setFocus for the same reason as in edit(self, viewmode)
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.actions['flipEditAndView'].setEnabled(viewmode)
        #self.actionUpAndDown.setEnabled(viewmode)
        self.actions['insertImage'].setEnabled(viewmode)
        self.noteSplitter.setSizes(splitSize)
        self.saveCurrentNote()

        # Render the note text as it is.
        self.notesView.updateView()

    def findBarVisibilityChanged(self, visible):
        self.actions['findText'].setChecked(visible)
        if visible:
            self.findEdit.setFocus(Qt.ShortcutFocusReason)

    def findText(self, back=False):
        flags = 0
        if back:
            flags = QTextDocument.FindBackward
        if self.checkBox.isChecked():
            flags = flags | QTextDocument.FindCaseSensitively
        text = self.findEdit.text()
        if not self.findMain(text, flags):
            if text in self.notesEdit.toPlainText():
                cursor = self.notesEdit.textCursor()
                if back:
                    cursor.movePosition(QTextCursor.End)
                else:
                    cursor.movePosition(QTextCursor.Start)
                self.notesEdit.setTextCursor(cursor)
                self.findMain(text, flags)
        # self.notesView.findText(text, flags)

    def findMain(self, text, flags):
        viewFlags = QWebPage.FindFlags(
            flags) | QWebPage.FindWrapsAroundDocument
        if flags:
            self.notesView.findText(text, viewFlags)
            return self.notesEdit.find(text, flags)
        else:
            self.notesView.findText(text)
            return self.notesEdit.find(text)

    def sortLines(self):
        ''' sort selected lines
            TODO: second sort reverse the order
        '''
        cursor = self.notesEdit.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        cursor.setPosition(start)
        cursor.movePosition(QTextCursor.StartOfLine)
        cursor.setPosition(end, mode=QTextCursor.KeepAnchor)
        cursor.movePosition(QTextCursor.EndOfLine, mode=QTextCursor.KeepAnchor)
        text = cursor.selectedText()
        lines = text.split('\u2029')      # '\u2029' is the line break
        sortedLines = sorted(lines)
        cursor.insertText('\n'.join(sortedLines))

    def notesEditInFocus(self, e):
        if e.gotFocus:
            self.actions['insertImage'].setEnabled(True)
        # if e.lostFocus:
        #    self.actionInsertImage.setEnabled(False)

        # QWidget.focusInEvent(self,f)

    def searchNote(self):
        """ Sorting criteria: "title > path > content"
            Search matches are organized into html source.
        """

        pattern = self.searchEdit.text()
        if not pattern:
            return
        results = []
        print("Searching using", pattern)
        with self.ix.searcher() as searcher:
            matches = []
            for f in ["title", "path", "content"]:
                queryp = QueryParser(f, self.ix.schema)
                queryp.add_plugin(RegexPlugin())
                # r"pattern" is the desired regex term format
                query = queryp.parse('r"' + pattern + '"')
                ms = searcher.search(query, limit=None) # default limit is 10!
                for m in ms:
                    if not m in matches:
                        matches.append(m)

            for r in matches:
                title = r['title']
                path = r['path']
                term = r.highlights("content")
                results.append([title, path, term])

            html = ""
            for title, path, hi in results:
                html += ("<p><a href='" + path + "'>" + title +
                         "</a><br/><span class='path'>" +
                         path + "</span><br/>" + hi + "</p>")
            self.searchView.setHtml(html)
            print("Finished searching", pattern)

    def whoosh_index(self):
        it = QTreeWidgetItemIterator(
            self.notesTree, QTreeWidgetItemIterator.All)
        print("Starting complete indexing.")
        writer = self.ix.writer()
        while it.value():
            treeItem = it.value()
            name = self.notesTree.itemToPage(treeItem)
            path = os.path.join(self.notesTree.pageToFile(name)).replace(os.sep, '/')
            print(path)
            fileobj = open(path, 'r')
            content = fileobj.read()
            fileobj.close()
            writer.add_document(
                path=name, title=parseTitle(content, name), content=content)
            it += 1
        writer.commit()
        print("Finished completely reindexing.")

    def listItemChanged(self, row):
        if row != -1:
            item = self.searchList.currentItem().data(Qt.UserRole)
            self.notesTree.setCurrentItem(item)
            flags = QWebPage.HighlightAllOccurrences
            self.notesView.findText(self.searchEdit.text(), flags)

    def setCurrentNote(self):
        item = self.notesTree.currentItem()
        name = self.notesTree.itemToPage(item)

        # Current note is inserted to head of list.
        notes = self.settings.recentViewedNotes()
        for f in notes:
            if f == name:
                notes.remove(f)
        notes.insert(0, name)

        recent_notes_n = Mikibook.settings.value('recentNotesNumber',type=int, defaultValue=20)
        if len(notes) > recent_notes_n:
            del notes[recent_notes_n:]
        self.settings.updateRecentViewedNotes(notes)

    def updateRecentViewedNotes(self):
        """ Switching notes will trigger this.
            When Alt pressed, show note number.
        """

        self.viewedList.clear()
        self.viewedListActions = []

        # Check notes exists.
        viewedNotes = self.settings.recentViewedNotes()
        existedNotes = []
        i = 0
        for f in viewedNotes:
            if self.notesTree.pageExists(f):
                existedNotes.append(f)
                names = f.split('/')
                if self.altPressed and i in range(1, 10):
                    action = self.act(names[-1], self.openFunction(f),
                        'Alt+'+str(i), True, ViewedNoteIcon(i), 'Alt+'+str(i))
                else:
                    action = self.act(names[-1], self.openFunction(f),
                        None, True)
                self.viewedListActions.append(action)
                i += 1

        if not self.altPressed:
            self.settings.updateRecentViewedNotes(existedNotes)
        for action in self.viewedListActions:
            self.viewedList.addAction(action)
        if len(self.viewedListActions):
            self.viewedListActions[0].setChecked(True)

    def openFunction(self, name):
        item = self.notesTree.pageToItem(name)
        return lambda: self.notesTree.setCurrentItem(item)

    def raiseDock(self, widget):
        if not widget.isVisible():
            widget.show()
        if widget == self.dockSearch:
            self.searchEdit.setFocus()
        widget.raise_()

    def flipEditAndView(self):
        index = self.noteSplitter.indexOf(self.notesEdit)
        if index == 0:
            self.noteSplitter.insertWidget(1, self.notesEdit)
        else:
            self.noteSplitter.insertWidget(0, self.notesEdit)

    def leftAndRight(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Horizontal)
        #self.actionLeftAndRight.setEnabled(False)
        #self.actionUpAndDown.setEnabled(True)

    def upAndDown(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Vertical)
        #self.actionUpAndDown.setEnabled(False)
        #self.actionLeftAndRight.setEnabled(True)

    def readmeHelp(self):
        readmeFile = '/usr/share/mikidown/README.mkd'
        if not os.path.exists(readmeFile):
            readmeFile = os.path.join(
                os.path.dirname(os.path.dirname(__file__)), 'README.mkd').replace(os.sep, '/')
        self.importPageCore(readmeFile)

    def changelogHelp(self):
        changeLog = "/usr/share/mikidown/Changelog.md"
        if not os.path.exists(changeLog):
            changeLog = os.path.join(
                os.path.dirname(os.path.dirname(__file__)), 'Changelog.md').replace(os.sep, '/')
        self.importPageCore(changeLog)

    def keyPressEvent(self, event):
        """ When Alt pressed, note number will be shown in viewedList. """
        if event.key() == Qt.Key_Alt:
            self.altPressed = True
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Alt:
            self.altPressed = False
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def closeEvent(self, event):
        """
            saveGeometry: Saves the current geometry and state for
                          top-level widgets
            saveState: Restores the state of this mainwindow's toolbars
                       and dockwidgets
        """
        self.saveCurrentNote()
        self.settings.saveGeometry(self.saveGeometry())
        self.settings.saveWindowState(self.saveState())
        event.accept()
Esempio n. 20
0
class MikiWindow(QMainWindow):
    def __init__(self, settings, parent=None):
        super(MikiWindow, self).__init__(parent)
        self.setObjectName("mikiWindow")
        self.settings = settings
        self.notePath = settings.notePath
        lockPath = os.path.join(settings.notebookPath, '.mikidown_lock')
        if not os.path.exists(lockPath):
            self.lockPathFH = os.open(lockPath,
                                      os.O_CREAT | os.O_EXCL | os.O_RDWR)
        ################ Setup core components ################
        self.notesTree = MikiTree(self)
        self.quickNoteNav = QLineEdit()
        self.notesTab = QWidget()
        self.completer = SlashPleter()
        self.completer.setModel(self.notesTree.model())
        self.quickNoteNav.setCompleter(self.completer)
        self.notesTree.setObjectName("notesTree")
        self.initTree(self.notePath, self.notesTree)
        self.notesTree.sortItems(0, Qt.AscendingOrder)

        self.ix = None
        self.setupWhoosh()

        self.viewedList = QToolBar(self.tr('Recently Viewed'), self)
        self.viewedList.setIconSize(QSize(16, 16))
        self.viewedList.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.viewedListActions = []
        self.noteSplitter = QSplitter(Qt.Horizontal)

        self.dockIndex = QDockWidget(self.tr("Index"))
        self.dockSearch = QDockWidget(self.tr("Search"))
        self.searchEdit = QLineEdit()
        self.searchView = MikiSearch(self)
        self.searchTab = QWidget()
        self.dockToc = QDockWidget(self.tr("TOC"))
        self.tocTree = TocTree()
        self.dockAttachment = QDockWidget(self.tr("Attachment"))
        self.attachmentView = AttachmentView(self)

        self.notesEdit = MikiEdit(self)
        self.notesEdit.setObjectName(self.tr("notesEdit"))
        self.loadHighlighter()
        self.notesView = MikiView(self)

        self.findBar = QToolBar(self.tr('Find'), self)
        self.findBar.setFixedHeight(30)
        self.findEdit = QLineEdit(self.findBar)
        self.checkBox = QCheckBox(self.tr('Match case'), self.findBar)

        self.statusBar = QStatusBar(self)
        self.statusLabel = QLabel(self)

        self.altPressed = False

        ################ Setup actions ################
        self.actions = dict()
        self.setupActions()

        ################ Setup mainwindow ################
        self.setupMainWindow()

        # show changelogs after upgrade mikidown
        if self.settings.version < __version__ or Mikibook.settings.value(
                "version", defaultValue="0") < __version__:
            self.changelogHelp()
            self.settings.qsettings.setValue("version", __version__)
            Mikibook.settings.setValue("version", __version__)

    def loadHighlighter(self):
        fnt = Mikibook.settings.value('editorFont', defaultValue=None)
        fntsize = Mikibook.settings.value('editorFontSize',
                                          type=int,
                                          defaultValue=12)
        header_scales_font = Mikibook.settings.value('headerScaleFont',
                                                     type=bool,
                                                     defaultValue=True)
        if fnt is not None:
            self.notesEdit.setFontFamily(fnt)
            self.notesEdit.setFontPointSize(fntsize)
        h = MikiHighlighter(parent=self.notesEdit,
                            scale_font_sizes=header_scales_font)
        tw = Mikibook.settings.value('tabWidth', type=int, defaultValue=4)
        qfm = QFontMetrics(h.patterns[0][1].font())
        self.notesEdit.setTabStopWidth(tw * qfm.width(' '))

    def setupActions(self):

        # Global Actions
        actTabIndex = self.act(self.tr('Switch to Index Tab'),
                               lambda: self.raiseDock(self.dockIndex),
                               self.tr('Ctrl+Shift+I'))
        actTabSearch = self.act(self.tr('Switch to Search Tab'),
                                lambda: self.raiseDock(self.dockSearch),
                                self.tr('Ctrl+Shift+F'))
        self.addAction(actTabIndex)
        self.addAction(actTabSearch)

        ################ Menu Actions ################
        # actions in menuFile
        actionNewPage = self.act(self.tr('&New Page...'),
                                 self.notesTree.newPage, QKeySequence.New)
        self.actions.update(newPage=actionNewPage)

        actionNewSubpage = self.act(self.tr('New Sub&page...'),
                                    self.notesTree.newSubpage,
                                    self.tr('Ctrl+Shift+N'))
        self.actions.update(newSubpage=actionNewSubpage)

        actionImportPage = self.act(self.tr('&Import Page...'),
                                    self.importPage)
        self.actions.update(importPage=actionImportPage)

        actionNBSettings = self.act(self.tr('Notebook Set&tings...'),
                                    self.notebookSettings)
        self.actions.update(NBSettings=actionNBSettings)

        actionMDSettings = self.act(self.tr('&Mikidown Settings...'),
                                    self.mikidownSettings)
        self.actions.update(MDSettings=actionMDSettings)

        actionOpenNotebook = self.act(self.tr('&Open Notebook...'),
                                      self.openNotebook, QKeySequence.Open)
        self.actions.update(openNotebook=actionOpenNotebook)

        actionReIndex = self.act(self.tr('Re-index'), self.reIndex)
        self.actions.update(reIndex=actionReIndex)

        actionSave = self.act(self.tr('&Save'), self.saveCurrentNote,
                              QKeySequence.Save)
        actionSave.setEnabled(False)
        self.actions.update(save=actionSave)

        actionSaveAs = self.act(self.tr('Save &As...'), self.saveNoteAs,
                                QKeySequence.SaveAs)
        self.actions.update(saveAs=actionSaveAs)

        actionHtml = self.act(self.tr('to &HTML'), self.notesEdit.saveAsHtml)
        self.actions.update(html=actionHtml)

        actionPrint = self.act(self.tr('&Print'), self.printNote,
                               QKeySequence.Print)
        self.actions.update(print_=actionPrint)

        actionRenamePage = self.act(self.tr('&Rename Page...'),
                                    self.notesTree.renamePage, 'F2')
        self.actions.update(renamePage=actionRenamePage)

        actionDelPage = self.act(self.tr('&Delete Page'),
                                 self.notesTree.delPageWrapper,
                                 QKeySequence.Delete)
        self.actions.update(delPage=actionDelPage)

        actionQuit = self.act(self.tr('&Quit'), self.close, QKeySequence.Quit)
        actionQuit.setMenuRole(QAction.QuitRole)
        self.actions.update(quit=actionQuit)

        # actions in menuEdit
        actionUndo = self.act(self.tr('&Undo'), lambda: self.notesEdit.undo(),
                              QKeySequence.Undo)
        actionUndo.setEnabled(False)
        self.notesEdit.undoAvailable.connect(actionUndo.setEnabled)
        self.actions.update(undo=actionUndo)

        actionRedo = self.act(self.tr('&Redo'), lambda: self.notesEdit.redo(),
                              QKeySequence.Redo)
        actionRedo.setEnabled(False)
        self.notesEdit.redoAvailable.connect(actionRedo.setEnabled)
        self.actions.update(redo=actionRedo)

        actionFindText = self.act(self.tr('&Find Text'),
                                  self.findBar.setVisible, QKeySequence.Find,
                                  True)
        self.actions.update(findText=actionFindText)

        actionFindRepl = self.act(self.tr('Find and Replace'),
                                  FindReplaceDialog(self.notesEdit).open,
                                  QKeySequence.Replace)
        self.actions.update(findRepl=actionFindRepl)

        actionFind = self.act(self.tr('Next'), self.findText,
                              QKeySequence.FindNext)
        self.actions.update(find=actionFind)

        actionFindPrev = self.act(self.tr('Previous'),
                                  lambda: self.findText(back=True),
                                  QKeySequence.FindPrevious)
        self.actions.update(findPrev=actionFindPrev)

        actionSortLines = self.act(self.tr('&Sort Lines'), self.sortLines)
        self.actions.update(sortLines=actionSortLines)

        actionQuickNav = self.act(self.tr("&Quick Open Note"),
                                  self.quickNoteNav.setFocus,
                                  self.tr('Ctrl+G'))
        self.addAction(actionQuickNav)

        actionInsertImage = self.act(self.tr('&Insert Attachment'),
                                     self.notesEdit.insertAttachmentWrapper,
                                     self.tr('Ctrl+I'))
        actionInsertImage.setEnabled(False)
        self.actions.update(insertImage=actionInsertImage)

        # actions in menuView
        QIcon.setThemeName(
            Mikibook.settings.value('iconTheme', QIcon.themeName()))
        #print(QIcon.themeName())
        actionEdit = self.act(self.tr('Edit'), self.edit, self.tr('Ctrl+E'),
                              True, QIcon.fromTheme('document-edit'),
                              self.tr('Edit mode (Ctrl+E)'))
        self.actions.update(edit=actionEdit)

        actionSplit = self.act(self.tr('Split'), self.liveView,
                               self.tr('Ctrl+R'), True,
                               QIcon.fromTheme('view-split-left-right'),
                               self.tr('Split mode (Ctrl+R)'))
        self.actions.update(split=actionSplit)

        actionFlipEditAndView = self.act(self.tr('Flip Edit and View'),
                                         self.flipEditAndView)
        actionFlipEditAndView.setEnabled(False)
        self.actions.update(flipEditAndView=actionFlipEditAndView)

        #actionLeftAndRight = self.act(
        #    self.tr('Split into Left and Right'), trig=self.leftAndRight)
        #actionUpAndDown = self.act(
        #    self.tr('Split into Up and Down'), trig=self.upAndDown)
        # self.actionLeftAndRight.setEnabled(False)
        # self.actionUpAndDown.setEnabled(False)

        # actions in menuHelp
        actionReadme = self.act(self.tr('README'), self.readmeHelp)
        self.actions.update(readme=actionReadme)

        actionChangelog = self.act(self.tr('Changelog'), self.changelogHelp)
        self.actions.update(changelog=actionChangelog)

        actionAboutQt = self.act(self.tr('About Qt'), qApp.aboutQt)
        self.actions.update(aboutQt=actionAboutQt)

    def setupMainWindow(self):
        self.resize(800, 600)
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)
        self.setWindowTitle('{} - {}'.format(self.settings.notebookName,
                                             __appname__))

        self.viewedList.setFixedHeight(25)
        self.noteSplitter.addWidget(self.notesEdit)
        self.noteSplitter.addWidget(self.notesView)
        mainSplitter = QSplitter(Qt.Vertical)
        mainSplitter.setChildrenCollapsible(False)
        mainSplitter.addWidget(self.viewedList)
        mainSplitter.addWidget(self.noteSplitter)
        mainSplitter.addWidget(self.findBar)
        self.setCentralWidget(mainSplitter)

        self.searchEdit.returnPressed.connect(self.searchNote)
        self.quickNoteNav.returnPressed.connect(self.openFuncWrapper)
        searchLayout = QVBoxLayout()
        searchLayout.addWidget(self.searchEdit)
        searchLayout.addWidget(self.searchView)
        self.searchTab.setLayout(searchLayout)

        indexLayout = QVBoxLayout(self.notesTab)
        indexLayout.addWidget(self.quickNoteNav)
        indexLayout.addWidget(self.notesTree)

        self.dockIndex.setObjectName("Index")
        self.dockIndex.setWidget(self.notesTab)
        self.dockSearch.setObjectName("Search")
        self.dockSearch.setWidget(self.searchTab)
        self.dockToc.setObjectName("TOC")
        self.dockToc.setWidget(self.tocTree)
        self.dockAttachment.setObjectName("Attachment")
        self.dockAttachment.setWidget(self.attachmentView)

        self.setDockOptions(QMainWindow.VerticalTabs)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockIndex)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockSearch)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockToc)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockAttachment)
        self.tabifyDockWidget(self.dockIndex, self.dockSearch)
        self.tabifyDockWidget(self.dockSearch, self.dockToc)
        self.tabifyDockWidget(self.dockToc, self.dockAttachment)
        self.setTabPosition(Qt.LeftDockWidgetArea, QTabWidget.North)
        self.dockIndex.raise_()  # Put dockIndex on top of the tab stack

        menuBar = QMenuBar(self)
        self.setMenuBar(menuBar)
        menuFile = menuBar.addMenu(self.tr('&File'))
        menuEdit = menuBar.addMenu(self.tr('&Edit'))
        menuView = menuBar.addMenu(self.tr('&View'))
        menuHelp = menuBar.addMenu(self.tr('&Help'))
        # menuFile
        menuFile.addAction(self.actions['newPage'])
        menuFile.addAction(self.actions['newSubpage'])
        menuFile.addAction(self.actions['NBSettings'])
        menuFile.addAction(self.actions['MDSettings'])
        menuFile.addAction(self.actions['importPage'])
        menuFile.addAction(self.actions['openNotebook'])
        menuFile.addAction(self.actions['reIndex'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['save'])
        menuFile.addAction(self.actions['saveAs'])
        menuFile.addAction(self.actions['print_'])
        menuExport = menuFile.addMenu(self.tr('&Export'))
        menuExport.addAction(self.actions['html'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['renamePage'])
        menuFile.addAction(self.actions['delPage'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['quit'])
        # menuEdit
        menuEdit.addAction(self.actions['undo'])
        menuEdit.addAction(self.actions['redo'])
        menuEdit.addAction(self.actions['findText'])
        menuEdit.addAction(self.actions['findRepl'])
        menuEdit.addSeparator()
        menuEdit.addAction(self.actions['sortLines'])
        menuEdit.addAction(self.actions['insertImage'])
        # menuView
        menuView.addAction(self.actions['edit'])
        menuView.addAction(self.actions['split'])
        menuView.addAction(self.actions['flipEditAndView'])
        menuShowHide = menuView.addMenu(self.tr('Show/Hide'))
        menuShowHide.addAction(self.dockIndex.toggleViewAction())
        menuShowHide.addAction(self.dockSearch.toggleViewAction())
        menuShowHide.addAction(self.dockToc.toggleViewAction())
        menuShowHide.addAction(self.dockAttachment.toggleViewAction())
        #menuMode = menuView.addMenu(self.tr('Mode'))
        #menuMode.addAction(self.actionLeftAndRight)
        #menuMode.addAction(self.actionUpAndDown)
        # menuHelp
        menuHelp.addAction(self.actions['readme'])
        menuHelp.addAction(self.actions['changelog'])
        menuHelp.addAction(self.actions['aboutQt'])

        toolBar = QToolBar(self.tr("toolbar"), self)
        toolBar.setObjectName("toolbar")  # needed in saveState()
        #toolBar.setIconSize(QSize(16, 16))
        toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.addToolBar(Qt.TopToolBarArea, toolBar)
        toolBar.addAction(self.actions['edit'])
        toolBar.addAction(self.actions['split'])
        self.findEdit.returnPressed.connect(self.findText)
        self.findBar.addWidget(self.findEdit)
        self.findBar.addWidget(self.checkBox)
        self.findBar.addAction(self.actions['findPrev'])
        self.findBar.addAction(self.actions['find'])
        self.findBar.setVisible(False)
        self.findBar.visibilityChanged.connect(self.findBarVisibilityChanged)

        self.setStatusBar(self.statusBar)
        self.statusBar.addWidget(self.statusLabel, 1)

        self.notesTree.currentItemChanged.connect(
            self.currentItemChangedWrapper)
        self.notesTree.nvwCallback = self.newNoteDisplay
        self.notesTree.nvwtCallback = self.newPlainTextNoteDisplay
        self.tocTree.itemClicked.connect(self.tocNavigate)
        self.notesEdit.textChanged.connect(self.noteEditted)

        self.notesEdit.document().modificationChanged.connect(
            self.modificationChanged)

        self.updateRecentViewedNotes()
        notes = self.settings.recentViewedNotes()
        if len(notes) != 0:
            item = self.notesTree.pageToItem(notes[0])
            self.notesTree.setCurrentItem(item)

    def newNoteDisplay(self, item, anchor=None):
        msn = MikiSepNote(self.settings,
                          item.text(0),
                          self.notesTree.itemToFile(item),
                          plain_text=False,
                          parent=self)
        if anchor:
            msn.note_view.page().mainFrame().scrollToAnchor(anchor)
        msn.show()

    def newPlainTextNoteDisplay(self, item, anchor=None):
        msn = MikiSepNote(self.settings,
                          item.text(0),
                          self.notesTree.itemToFile(item),
                          plain_text=True,
                          parent=self)
        if anchor:
            item = msn.findItemByAnchor(anchor)[0]
            msn.tocNavigate(item)
        msn.show()

    def openFuncWrapper(self):
        self.openFunction(self.quickNoteNav.text())()

    def setupWhoosh(self):
        # Initialize whoosh index, make sure notePath/.indexdir exists
        indexdir = self.settings.indexdir
        try:
            self.ix = open_dir(indexdir)
        except:
            QDir().mkpath(indexdir)
            self.ix = create_in(indexdir, self.settings.schema)
            # Fork a process to update index, which benefit responsiveness.
            p = Thread(target=self.whoosh_index, args=())
            p.start()

    def restore(self):
        """ Restore saved geometry and state.
            Set the status of side panels in View Menu correspondently.
        """
        if self.settings.geometry:
            self.restoreGeometry(self.settings.geometry)
        if self.settings.windowstate:
            self.restoreState(self.settings.windowstate)

    def initTree(self, notePath, parent):
        ''' When there exist foo.md, foo.mkd, foo.markdown,
            only one item will be shown in notesTree.
        '''
        if not QDir(notePath).exists():
            return
        notebookDir = QDir(notePath)
        notesList = notebookDir.entryInfoList(['*.md', '*.mkd', '*.markdown'],
                                              QDir.NoFilter,
                                              QDir.Name | QDir.IgnoreCase)
        nl = [note.completeBaseName() for note in notesList]
        noduplicate = list(set(nl))
        for name in noduplicate:
            item = QTreeWidgetItem(parent, [name])
            path = notePath + '/' + name
            self.initTree(path, item)

    def updateToc(self):
        ''' TOC is updated in `updateView`
            tocTree fields: [hdrText, hdrPosition, hdrAnchor]
        '''
        root = self.notesTree.currentPage()
        strip_math_for_header_parsing = False
        strip_fence_for_header_parsing = False
        if 'asciimathml' in self.settings.extensions:
            strip_math_for_header_parsing = True
        if 'fenced_code' in self.settings.extensions or 'extra' in self.settings.extensions:
            strip_fence_for_header_parsing = True
        self.tocTree.updateToc(
            root,
            parseHeaders(self.notesEdit.toPlainText(),
                         strip_fenced_block=strip_fence_for_header_parsing,
                         strip_ascii_math=strip_math_for_header_parsing))

    def updateAttachmentView(self):
        # Update attachmentView to show corresponding attachments.
        item = self.notesTree.currentItem()
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(item))
        self.attachmentView.setRootIndex(index)

    def openFile(self, filename):
        fh = QFile(filename)
        try:
            if not fh.open(QIODevice.ReadOnly):
                raise IOError(fh.errorString())
        except IOError as e:
            QMessageBox.warning(
                self, self.tr('Read Error'),
                self.tr('Failed to open %s: %s') % (filename, e))
        finally:
            if fh is not None:
                noteBody = QTextStream(fh).readAll()
                fh.close()
                self.notesEdit.setPlainText(noteBody)
                self.notesView.scrollPosition = QPoint(0, 0)
                # self.actionSave.setEnabled(False)
                self.notesEdit.document().setModified(False)
                self.notesView.updateView()
                self.setCurrentNote()
                self.updateRecentViewedNotes()
                #self.statusLabel.setText(noteFullName)

    def currentItemChangedWrapper(self, current, previous):
        if current is None:
            return
        #if previous != None and self.notesTree.pageExists(previous):
        prev = self.notesTree.itemToPage(previous)
        if self.notesTree.pageExists(prev):
            self.saveNote(previous)

        currentFile = self.notesTree.itemToFile(current)
        self.openFile(currentFile)

        # Update attachmentView to show corresponding attachments.
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(current))
        self.attachmentView.setRootIndex(index)

    def tocNavigate(self, current):
        ''' works for notesEdit now '''
        if current is None:
            return
        pos = int(current.text(1))
        link = "file://" + self.notePath + "/#" + current.text(2)
        # Move cursor to END first will ensure
        # header is positioned at the top of visual area.
        self.notesEdit.moveCursor(QTextCursor.End)
        cur = self.notesEdit.textCursor()
        cur.setPosition(pos, QTextCursor.MoveAnchor)
        self.notesEdit.setTextCursor(cur)
        self.notesView.load(QUrl(link))

    def switchNote(self, num):
        if num < len(self.viewedListActions):
            self.viewedListActions[num].trigger()

    def saveCurrentNote(self):
        item = self.notesTree.currentItem()
        self.saveNote(item)

    def saveNote(self, item):
        if self.notesEdit.document().isModified():
            self.notesEdit.document().setModified(False)
        else:
            return
        self.notesEdit.save(item)

    def saveNoteAs(self):
        self.saveCurrentNote()
        fileName = QFileDialog.getSaveFileName(
            self, self.tr('Save as'), '',
            '(*.md *.mkd *.markdown);;' + self.tr('All files(*)'))
        if fileName == '':
            return
        if not QFileInfo(fileName).suffix():
            fileName += '.md'
        fh = QFile(fileName)
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << self.notesEdit.toPlainText()
        fh.close()

    def printNote(self):
        printer = QPrinter(QPrinter.HighResolution)
        printer.setCreator(__appname__ + ' ' + __version__)
        printer.setDocName(self.notesTree.currentItem().text(0))
        printdialog = QPrintDialog(printer, self)
        if printdialog.exec() == QDialog.Accepted:
            self.notesView.print_(printer)

    def noteEditted(self):
        """ Continuously get fired while editing"""
        self.updateToc()
        self.notesView.updateLiveView()

    def modificationChanged(self, changed):
        """ Fired one time: modified or not """
        self.actions['save'].setEnabled(changed)
        name = self.notesTree.currentPage()
        self.statusBar.clearMessage()
        if changed:
            self.statusLabel.setText(name + '*')
        else:
            self.statusLabel.setText(name)

    def importPage(self):
        filename = QFileDialog.getOpenFileName(
            self, self.tr('Import file'), '',
            '(*.md *.mkd *.markdown *.txt);;' + self.tr('All files(*)'))
        if filename == '':
            return
        self.importPageCore(filename)

    def importPageCore(self, filename):
        fh = QFile(filename)
        fh.open(QIODevice.ReadOnly)
        fileBody = QTextStream(fh).readAll()
        fh.close()
        page = QFileInfo(filename).completeBaseName()
        fh = QFile(self.notesTree.pageToFile(page))
        if fh.exists():
            QMessageBox.warning(self, self.tr("Import Error"),
                                self.tr("Page already exists: %s") % page)
            dialog = LineEditDialog(self.notePath, self)
            if dialog.exec_():
                page = dialog.editor.text()
                fh.close()
                fh = QFile(self.notesTree.pageToFile(page))
            else:
                return
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << fileBody
        fh.close()
        item = QTreeWidgetItem(self.notesTree, [page])
        self.notesTree.sortItems(0, Qt.AscendingOrder)
        self.notesTree.setCurrentItem(item)

    def openNotebook(self):
        dialog = NotebookListDialog(self)
        if dialog.exec_():
            pass

    def notebookSettings(self):
        dialog = NotebookSettingsDialog(self)
        if dialog.exec_():
            pass

    def mikidownSettings(self):
        dialog = MikidownCfgDialog(self)
        if dialog.exec_():
            pass

    def reIndex(self):
        """ Whoosh index breaks for unknown reasons (sometimes) """
        shutil.rmtree(self.settings.indexdir)
        self.setupWhoosh()

    def act(self,
            name,
            trig,
            shortcut=None,
            checkable=False,
            icon=None,
            tooltip=None):
        """ A wrapper to several QAction methods """
        if icon:
            action = QAction(icon, name, self)
        else:
            action = QAction(name, self)
        if shortcut:
            action.setShortcut(QKeySequence(shortcut))
        action.setCheckable(checkable)
        if tooltip:
            action.setToolTip(tooltip)
        action.triggered.connect(trig)
        return action

    def edit(self, viewmode):
        """ Switch between EDIT and VIEW mode. """

        if self.actions['split'].isChecked():
            self.actions['split'].setChecked(False)
        self.notesView.setVisible(not viewmode)
        self.notesEdit.setVisible(viewmode)

        # Gives the keyboard input focus to notesEdit/notesView.
        # Without this, keyboard input may change note text even when
        # notesEdit is invisible.
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.saveCurrentNote()
        self.actions['insertImage'].setEnabled(viewmode)
        #self.actionLeftAndRight.setEnabled(True)
        #self.actionUpAndDown.setEnabled(True)

        # Render the note text as it is.
        self.notesView.updateView()

    def liveView(self, viewmode):
        """ Switch between VIEW and LIVE VIEW mode. """

        self.actions['split'].setChecked(viewmode)
        sizes = self.noteSplitter.sizes()
        if self.actions['edit'].isChecked():
            self.actions['edit'].setChecked(False)
            self.notesView.setVisible(viewmode)
            splitSize = [sizes[0] * 0.45, sizes[0] * 0.55]
        else:
            self.notesEdit.setVisible(viewmode)
            splitSize = [sizes[1] * 0.45, sizes[1] * 0.55]

        # setFocus for the same reason as in edit(self, viewmode)
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.actions['flipEditAndView'].setEnabled(viewmode)
        #self.actionUpAndDown.setEnabled(viewmode)
        self.actions['insertImage'].setEnabled(viewmode)
        self.noteSplitter.setSizes(splitSize)
        self.saveCurrentNote()

        # Render the note text as it is.
        self.notesView.updateView()

    def findBarVisibilityChanged(self, visible):
        self.actions['findText'].setChecked(visible)
        if visible:
            self.findEdit.setFocus(Qt.ShortcutFocusReason)

    def findText(self, back=False):
        flags = 0
        if back:
            flags = QTextDocument.FindBackward
        if self.checkBox.isChecked():
            flags = flags | QTextDocument.FindCaseSensitively
        text = self.findEdit.text()
        if not self.findMain(text, flags):
            if text in self.notesEdit.toPlainText():
                cursor = self.notesEdit.textCursor()
                if back:
                    cursor.movePosition(QTextCursor.End)
                else:
                    cursor.movePosition(QTextCursor.Start)
                self.notesEdit.setTextCursor(cursor)
                self.findMain(text, flags)
        # self.notesView.findText(text, flags)

    def findMain(self, text, flags):
        viewFlags = QWebPage.FindFlags(
            flags) | QWebPage.FindWrapsAroundDocument
        if flags:
            self.notesView.findText(text, viewFlags)
            return self.notesEdit.find(text, flags)
        else:
            self.notesView.findText(text)
            return self.notesEdit.find(text)

    def sortLines(self):
        ''' sort selected lines
            TODO: second sort reverse the order
        '''
        cursor = self.notesEdit.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        cursor.setPosition(start)
        cursor.movePosition(QTextCursor.StartOfLine)
        cursor.setPosition(end, mode=QTextCursor.KeepAnchor)
        cursor.movePosition(QTextCursor.EndOfLine, mode=QTextCursor.KeepAnchor)
        text = cursor.selectedText()
        lines = text.split('\u2029')  # '\u2029' is the line break
        sortedLines = sorted(lines)
        cursor.insertText('\n'.join(sortedLines))

    def notesEditInFocus(self, e):
        if e.gotFocus:
            self.actions['insertImage'].setEnabled(True)
        # if e.lostFocus:
        #    self.actionInsertImage.setEnabled(False)

        # QWidget.focusInEvent(self,f)

    def searchNote(self):
        """ Sorting criteria: "title > path > content"
            Search matches are organized into html source.
        """

        pattern = self.searchEdit.text()
        if not pattern:
            return
        results = []
        print("Searching using", pattern)
        with self.ix.searcher() as searcher:
            matches = []
            queryp = QueryParser("content", self.ix.schema)
            #allow escaped qutoes when regex searching
            queryp.add_plugin(
                RegexPlugin(expr=r'r"(?P<text>[^"\\]*(\\.[^"\\]*)*)"'))
            # ~~r"pattern" is the desired regex term format~~ Don't autoforce regexing
            query = queryp.parse(pattern)
            #print("durp durp", query)
            ms = searcher.search(query, limit=None)  # default limit is 10!
            for m in ms:
                #if not m in matches:
                matches.append(m)

            for r in matches:
                title = r['title']
                path = r['path']
                term = r.highlights("content")
                results.append([title, path, term])

            html = ""
            for title, path, hi in results:
                html += ("<p><a href='" + path + "'>" + title +
                         "</a><br/><span class='path'>" + path +
                         "</span><br/>" + hi + "</p>")
            self.searchView.setHtml(html)
            print("Finished searching", pattern)

    def whoosh_index(self):
        it = QTreeWidgetItemIterator(self.notesTree,
                                     QTreeWidgetItemIterator.All)
        print("Starting complete indexing.")
        #writer = self.ix.writer()
        writer = AsyncWriter(self.ix)
        while it.value():
            treeItem = it.value()
            name = self.notesTree.itemToPage(treeItem)
            path = os.path.join(self.notesTree.pageToFile(name)).replace(
                os.sep, '/')
            print(path)
            fileobj = open(path, 'r', encoding='utf-8')
            content = fileobj.read()
            fileobj.close()
            if METADATA_CHECKER.match(
                    content) and 'meta' in self.settings.extensions:
                no_metadata_content = METADATA_CHECKER.sub("",
                                                           content,
                                                           count=1).lstrip()
                self.settings.md.reset().convert(content)
                writer.update_document(
                    path=name,
                    title=parseTitle(content, name),
                    content=no_metadata_content,
                    tags=','.join(self.settings.md.Meta.get('tags',
                                                            [])).strip())
            else:
                writer.add_document(path=name,
                                    title=parseTitle(content, name),
                                    content=content,
                                    tags='')

            it += 1
        writer.commit()
        print("Finished completely reindexing.")

    def listItemChanged(self, row):
        if row != -1:
            item = self.searchList.currentItem().data(Qt.UserRole)
            self.notesTree.setCurrentItem(item)
            flags = QWebPage.HighlightAllOccurrences
            self.notesView.findText(self.searchEdit.text(), flags)

    def setCurrentNote(self):
        item = self.notesTree.currentItem()
        name = self.notesTree.itemToPage(item)

        # Current note is inserted to head of list.
        notes = self.settings.recentViewedNotes()
        for f in notes:
            if f == name:
                notes.remove(f)
        notes.insert(0, name)

        recent_notes_n = Mikibook.settings.value('recentNotesNumber',
                                                 type=int,
                                                 defaultValue=20)
        if len(notes) > recent_notes_n:
            del notes[recent_notes_n:]
        self.settings.updateRecentViewedNotes(notes)

    def updateRecentViewedNotes(self):
        """ Switching notes will trigger this.
            When Alt pressed, show note number.
        """

        self.viewedList.clear()
        self.viewedListActions = []

        # Check notes exists.
        viewedNotes = self.settings.recentViewedNotes()
        existedNotes = []
        i = 0
        for f in viewedNotes:
            if self.notesTree.pageExists(f):
                existedNotes.append(f)
                names = f.split('/')
                if self.altPressed and i in range(1, 10):
                    action = self.act(names[-1], self.openFunction(f),
                                      'Alt+' + str(i), True, ViewedNoteIcon(i),
                                      'Alt+' + str(i))
                else:
                    action = self.act(names[-1], self.openFunction(f), None,
                                      True)
                self.viewedListActions.append(action)
                i += 1

        if not self.altPressed:
            self.settings.updateRecentViewedNotes(existedNotes)
        for action in self.viewedListActions:
            self.viewedList.addAction(action)
        if len(self.viewedListActions):
            self.viewedListActions[0].setChecked(True)

    def openFunction(self, name):
        item = self.notesTree.pageToItem(name)
        return lambda: self.notesTree.setCurrentItem(item)

    def raiseDock(self, widget):
        if not widget.isVisible():
            widget.show()
        if widget == self.dockSearch:
            self.searchEdit.setFocus()
        widget.raise_()

    def flipEditAndView(self):
        index = self.noteSplitter.indexOf(self.notesEdit)
        if index == 0:
            self.noteSplitter.insertWidget(1, self.notesEdit)
        else:
            self.noteSplitter.insertWidget(0, self.notesEdit)

    def leftAndRight(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Horizontal)
        #self.actionLeftAndRight.setEnabled(False)
        #self.actionUpAndDown.setEnabled(True)

    def upAndDown(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Vertical)
        #self.actionUpAndDown.setEnabled(False)
        #self.actionLeftAndRight.setEnabled(True)

    def readmeHelp(self):
        readmeFile = '/usr/share/mikidown/README.mkd'
        if not os.path.exists(readmeFile):
            readmeFile = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                'README.mkd').replace(os.sep, '/')
        self.importPageCore(readmeFile)

    def changelogHelp(self):
        changeLog = "/usr/share/mikidown/Changelog.md"
        if not os.path.exists(changeLog):
            changeLog = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                'Changelog.md').replace(os.sep, '/')
        self.importPageCore(changeLog)

    def keyPressEvent(self, event):
        """ When Alt pressed, note number will be shown in viewedList. """
        if event.key() == Qt.Key_Alt:
            self.altPressed = True
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Alt:
            self.altPressed = False
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def closeEvent(self, event):
        """
            saveGeometry: Saves the current geometry and state for
                          top-level widgets
            saveState: Restores the state of this mainwindow's toolbars
                       and dockwidgets
        """
        self.saveCurrentNote()
        self.ix.close()
        self.notesEdit.ix.close()
        if hasattr(self.notesTree, 'ix'):
            self.notesTree.ix.close()
        self.settings.saveGeometry(self.saveGeometry())
        self.settings.saveWindowState(self.saveState())
        event.accept()
        os.close(self.lockPathFH)
        lockPath = os.path.join(self.settings.notebookPath, '.mikidown_lock')
        os.remove(lockPath)
Esempio n. 21
0
class DSBrowser(QWidget):
    """browser for datastorage databases
       Nodes are identified by a string, containing fields separated by '|'.
       - first filed is a capital letter:
       'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart
       - second field is the database folder
       - third filed is the path of the node in the database
       - for charts the fourth field is the chart name (third is path of sensorgroup in this case)
    """

    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(0)
        self.layout.setMargin(0)

        self.toolBar = QFrame(self)
        self.toolBarLayout = QHBoxLayout(self.toolBar)
        self.toolBarLayout.setMargin(2)
        self.toolBarLayout.setSpacing(2)
        self.layout.addWidget(self.toolBar)

        self.loadButton = QToolButton(self.toolBar)
        self.loadButton.setText(QCoreApplication.translate("DataStorageBrowser", "Open..."))
        self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen)))
        self.loadButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Open a datastorage database"))
        self.toolBarLayout.addWidget(self.loadButton)
        self.connect(self.loadButton, SIGNAL("pressed()"), self.loadDatabase)

        self.expandButton = QToolButton(self.toolBar)
        self.expandButton.setText("Expand/Collapse")
        self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col)))
        self.expandButton.setToolTip(
            QCoreApplication.translate("DataStorageBrowser", "Expand or collapse the whole tree")
        )
        self.toolBarLayout.addWidget(self.expandButton)
        self.connect(self.expandButton, SIGNAL("pressed()"), self.expandCollapseAll)

        self.searchInput = MyLineEdit(self.toolBar)
        self.searchInput.setText(QCoreApplication.translate("DataStorageBrowser", "Enter search text here"))
        self.searchInput.setToolTip(
            QCoreApplication.translate(
                "DataStorageBrowser", "Enter search text using wildcards here, press ENTER again to go to next match!"
            )
        )
        self.toolBarLayout.addWidget(self.searchInput, 100)
        self.connect(self.searchInput, SIGNAL("returnPressed()"), self.searchItem)

        self.helpButton = QToolButton(self.toolBar)
        self.helpButton.setText(QCoreApplication.translate("DataStorageBrowser", "Help"))
        self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help)))
        self.helpButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Show help for DataStorageBrowser"))
        self.toolBarLayout.addWidget(self.helpButton)
        self.connect(self.helpButton, SIGNAL("pressed()"), self.showHelp)

        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Vertical)
        self.treeView = QTreeView(self.splitter)
        self.treeView.setAlternatingRowColors(True)
        self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeView.setAutoExpandDelay(500)
        self.textBrowser = QTextBrowser(self.splitter)
        self.layout.addWidget(self.splitter)
        self.splitter.setStretchFactor(0, 60)
        self.splitter.setStretchFactor(1, 40)
        self.model = DSModel()
        self.treeView.setModel(self.model)
        self.treeView.setSortingEnabled(True)
        self.treeView.expandAll()
        self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem)
        self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction)
        self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu)
        self.selectedNode = None
        self.selectedMI = None
        self.searchText = ""
        self.searchResults = []
        self.collExpand = SimuVis4.Misc.Switcher()

        self.statusBar = SimuVis4.Globals.mainWin.statusBar()

    def loadDatabase(self, dn=None):
        """load a database"""
        if not dn:
            dn = QFileDialog.getExistingDirectory(
                self,
                QCoreApplication.translate("DataStorageBrowser", "Select a folder containing a datastorage database"),
                SimuVis4.Globals.defaultFolder,
            )
            if not dn.isEmpty():
                dn = unicode(dn)
                SimuVis4.Globals.defaultFolder = dn
            else:
                return
        self.model.addDatabase(dn)
        self.treeView.collapseAll()
        self.treeView.expandToDepth(SimuVis4.Globals.config.getint("datastoragebrowser", "expand_tree_depth"))
        self.treeView.resizeColumnToContents(0)

    def showHelp(self):
        SimuVis4.HelpBrowser.showHelp("/plugin/DataStorageBrowser/index.html")

    def showItem(self, mi, pr):
        """show the item at model index mi"""
        t, n = self.model.dsNode(mi)
        txt = ""
        if t == "R":
            txt = rootInfo.substitute(
                name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)
            ) + formatMetaData(n)
        elif t == "P":
            txt = projectInfo.substitute(
                name=n.name, path=escape(n.parent.name), title=escape(n.title), groups=len(n)
            ) + formatMetaData(n)
        elif t == "G":
            txt = groupInfo.substitute(
                name=n.name,
                path="/".join(n.path.split("/")[:-1]),
                title=escape(n.title),
                sensors=len(n),
                charts=len(n.getCharts()),
                start=formatTime(n.timegrid.start),
                stop=formatTime(n.timegrid.stop),
                step=n.timegrid.step,
                timezone=n.timegrid.timezone,
            ) + formatMetaData(n)
        elif t == "S":
            txt = sensorInfo.substitute(
                name=n.name,
                path="/".join(n.path.split("/")[:-1]),
                title=escape(n.title),
                start=formatTime(n.timegrid.start),
                stop=formatTime(n.timegrid.stop),
                step=n.timegrid.step,
                length=n.datalen(),
                timezone=n.timegrid.timezone,
            ) + formatMetaData(n)
        elif t == "C":
            txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path)
        self.textBrowser.setText(txt)
        msg = ": ".join(str(self.model.itemFromIndex(mi).data().toString()).split("|")[1:])
        self.statusBar.showMessage(msg, 5000)

    def searchItem(self):
        """execute the search and highlight the (next) result"""
        txt = str(self.searchInput.text())
        if txt != self.searchText:
            self.searchText = txt
            tmp = self.model.findItems(
                txt, Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive
            )
            self.searchList = [i.index() for i in tmp]
        if self.searchList:
            mi = self.searchList.pop()
            self.treeView.setCurrentIndex(mi)
            self.treeView.expand(mi)
            self.treeView.scrollTo(mi)
        else:
            QMessageBox.information(
                self,
                QCoreApplication.translate("DataStorageBrowser", "No (more) matches!"),
                QCoreApplication.translate(
                    "DataStorageBrowser", "No (more) matches found! Change you search text and try again!"
                ),
            )
            self.searchText = ""

    def expandCollapseAll(self):
        if self.collExpand():
            self.treeView.collapseAll()
        else:
            self.treeView.expandAll()

    def itemAction(self, mi):
        """default action (on doubleclick) for item at model index mi"""
        t, n = self.model.dsNode(mi)
        if t == "S":
            if qwtPlotWindowActive():
                self.addToQwtPlot(n)
            else:
                self.showQwtPlot(n)
        elif t == "C":
            self.showChart(n)

    def showContextMenu(self, pos):
        """show context menu for item at pos"""
        mi = self.treeView.indexAt(pos)
        t, n = self.model.dsNode(mi)
        self.selectedNode = n
        self.selectedMI = mi
        m = QMenu()
        if t == "R":
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Close"), self.closeDatabase)
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Reload"), self.reloadDatabase)
        elif t == "P":
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "New sensorgroup"), self.newSensorGroup)
        elif t == "G":
            nCharts = len(n.getCharts())
            if nCharts > 0:
                txt = str(QCoreApplication.translate("DataStorageBrowser", "Show all charts (%d)")) % nCharts
                m.addAction(txt, self.showAllCharts)
                m.addAction(
                    QCoreApplication.translate("DataStorageBrowser", "Save all charts as images"),
                    self.saveAllChartImages,
                )
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add chart"), self.newChart)
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add/update data"), self.importFiles)
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Export data"), self.exportSensors)
        elif t == "S":
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "New plot (Qwt)"), self.showQwtPlot)
            if qwtPlotWindowActive():
                m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add to plot (Qwt)"), self.addToQwtPlot)
        elif t == "C":
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Show"), self.showChart)
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Delete"), self.deleteItem)
        if t in "RPGS":
            m.addSeparator()
            m.addAction(QCoreApplication.translate("DataStorageBrowser", "Edit metadata"), self.editMetadata)
        a = m.exec_(self.treeView.mapToGlobal(pos))

    def newSensorGroup(self, mi=None):
        if mi is None:
            mi = self.selectedMI
        newSensorGroup(self.model, mi)

    def showChart(self, ch=None):
        if ch is None:
            ch = self.selectedNode
        showChartWindow(ch, maximized=showChartMaximized)

    def importFiles(self, mi=None):
        if mi is None:
            mi = self.selectedMI
        importFiles(self.model, mi)

    def showAllCharts(self, sg=None):
        if sg is None:
            sg = self.selectedNode
        showAllChartWindows(sg, maximized=showChartMaximized)

    def saveAllChartImages(self, sg=None):
        if sg is None:
            sg = self.selectedNode
        saveAllChartImages(sg)

    def exportSensors(self, sg=None):
        if sg is None:
            sg = self.selectedNode
        exportSensors(sg)

    def showQwtPlot(self, se=None):
        if se is None:
            se = self.selectedNode
        showQwtPlotWindow(se, maximized=showChartMaximized)

    def addToQwtPlot(self, se=None):
        if se is None:
            se = self.selectedNode
        addToQwtPlotWindow(se)

    def editMetadata(self, node=None):
        if node is None:
            node = self.selectedNode
        editMetadata(node)

    def closeDatabase(self, mi=None):
        if mi is None:
            mi = self.selectedMI
        self.model.closeDatabase(mi)

    def reloadDatabase(self, mi=None):
        if mi is None:
            mi = self.selectedMI
        dbPath = self.model.dsFolder(mi)
        self.model.closeDatabase(mi)
        self.loadDatabase(dbPath)

    def newChart(self, mi=None):
        """add a chart to sensorgroup at mi using the wizard"""
        if mi is None:
            mi = self.selectedMI
        showNewChartWizard(self.model, mi, self)

    def deleteItem(self, mi=None):
        """delete the item at mi"""
        if mi is None:
            mi = self.selectedMI
        self.model.deleteItem(mi)
Esempio n. 22
0
class __CentralWidget(QWidget):

    ###############################################################################
    # CentralWidget SIGNALS
    ###############################################################################

    """
    splitterCentralRotated()
    """

    ###############################################################################

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.parent = parent
        # This variables are used to save the splitter sizes before hide
        self._splitterMainSizes = None
        self._splitterAreaSizes = None
        self.lateralPanel = None

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        # Create Splitters to divide the UI in: MainPanel, Explorer, Misc
        self._splitterArea = QSplitter(Qt.Horizontal)
        self._splitterMain = QSplitter(Qt.Vertical)

        # Create scrollbar for follow mode
        self.scrollBar = QScrollBar(Qt.Vertical, self)
        self.scrollBar.setFixedWidth(20)
        self.scrollBar.setToolTip("Follow Mode: Scroll the Editors together")
        self.scrollBar.hide()
        self.connect(self.scrollBar, SIGNAL("valueChanged(int)"), self.move_follow_scrolls)

        # Add to Main Layout
        hbox.addWidget(self.scrollBar)
        hbox.addWidget(self._splitterArea)

    def insert_central_container(self, container):
        self.mainContainer = container
        self._splitterMain.insertWidget(0, container)

    def insert_lateral_container(self, container):
        self.lateralPanel = LateralPanel(container)
        self._splitterArea.insertWidget(0, self.lateralPanel)

    def insert_bottom_container(self, container):
        self.misc = container
        self._splitterMain.insertWidget(1, container)

    def showEvent(self, event):
        # Show Event
        QWidget.showEvent(self, event)
        # Avoid recalculate the panel sizes if they are already loaded
        if self._splitterArea.count() == 2:
            return
        # Rearrange widgets on Window
        self._splitterArea.insertWidget(0, self._splitterMain)
        qsettings = QSettings()
        # Lists of sizes as list of QVariant- heightList = [QVariant, QVariant]
        heightList = list(qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3]))
        widthList = list(qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6]))
        self._splitterMainSizes = [int(heightList[0]), int(heightList[1])]
        self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])]
        if not event.spontaneous():
            self.change_misc_visibility()
        if bin(settings.UI_LAYOUT)[-1] == "1":
            self.splitter_central_rotate()
        if bin(settings.UI_LAYOUT >> 1)[-1] == "1":
            self.splitter_misc_rotate()
        if bin(settings.UI_LAYOUT >> 2)[-1] == "1":
            self.splitter_central_orientation()
        # Set the sizes to splitters
        self._splitterMain.setSizes(self._splitterMainSizes)
        self._splitterArea.setSizes(self._splitterAreaSizes)

    def change_misc_visibility(self):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
            self.misc.hide()
            widget = self.mainContainer.get_actual_widget()
            if widget:
                widget.setFocus()
        else:
            self.misc.show()
            self.misc.gain_focus()

    def change_main_visibility(self):
        if self.mainContainer.isVisible():
            self.mainContainer.hide()
        else:
            self.mainContainer.show()

    def change_explorer_visibility(self, force_hide=False):
        if self.lateralPanel.isVisible() or force_hide:
            self._splitterAreaSizes = self._splitterArea.sizes()
            self.lateralPanel.hide()
        else:
            self.lateralPanel.show()

    def splitter_central_rotate(self):
        w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1)
        self._splitterArea.insertWidget(0, w2)
        self._splitterArea.insertWidget(1, w1)
        self.emit(SIGNAL("splitterCentralRotated()"))

    def splitter_central_orientation(self):
        if self._splitterArea.orientation() == Qt.Horizontal:
            self._splitterArea.setOrientation(Qt.Vertical)
        else:
            self._splitterArea.setOrientation(Qt.Horizontal)

    def splitter_misc_rotate(self):
        w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1)
        self._splitterMain.insertWidget(0, w2)
        self._splitterMain.insertWidget(1, w1)

    def splitter_misc_orientation(self):
        if self._splitterMain.orientation() == Qt.Horizontal:
            self._splitterMain.setOrientation(Qt.Vertical)
        else:
            self._splitterMain.setOrientation(Qt.Horizontal)

    def get_area_sizes(self):
        if self.lateralPanel.isVisible():
            self._splitterAreaSizes = self._splitterArea.sizes()
        return self._splitterAreaSizes

    def get_main_sizes(self):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
        return self._splitterMainSizes

    def enable_follow_mode_scrollbar(self, val):
        if val:
            editorWidget = self.mainContainer.get_actual_editor()
            maxScroll = editorWidget.verticalScrollBar().maximum()
            position = editorWidget.verticalScrollBar().value()
            self.scrollBar.setMaximum(maxScroll)
            self.scrollBar.setValue(position)
        self.scrollBar.setVisible(val)

    def move_follow_scrolls(self, val):
        widget = self.mainContainer._tabMain.currentWidget()
        diff = widget._sidebarWidget.highest_line - val
        s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar()
        s2 = self.mainContainer._tabSecondary.currentWidget().verticalScrollBar()
        s1.setValue(val)
        s2.setValue(val + diff)
Esempio n. 23
0
class PythonConsoleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        ##------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)
        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOut)
        self.splitter.addWidget(self.shell)
        #self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        #self.splitterObj.setSizes([0, 0])
        #self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        #self.splitterEditor.addWidget(self.widgetEditor)
        #self.splitterObj.addWidget(self.listClassMethod)
        #self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        ##----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        ##------------------Toolbar Editor-------------------------------------

        ## Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open file")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)
        ## Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        ## Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole",
                                                  "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        ## Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCutEditorConsole.png"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        ## Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        ## Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        ## Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        ## Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        ## Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        ## Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        ## Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        ##----------------Toolbar Console-------------------------------------

        ## Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        ## Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        ## Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Settings")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        ## Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole",
                                                   "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(
            QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        ## Import Processing class
        loadProcessingBt = QCoreApplication.translate(
            "PythonConsole", "Import Processing class")
        self.loadProcessingButton = QAction(self)
        self.loadProcessingButton.setCheckable(False)
        self.loadProcessingButton.setEnabled(True)
        self.loadProcessingButton.setIcon(
            QgsApplication.getThemeIcon("console/iconProcessingConsole.png"))
        self.loadProcessingButton.setMenuRole(QAction.PreferencesRole)
        self.loadProcessingButton.setIconVisibleInMenu(True)
        self.loadProcessingButton.setToolTip(loadProcessingBt)
        self.loadProcessingButton.setText(loadProcessingBt)
        ## Import QtCore class
        loadQtCoreBt = QCoreApplication.translate("PythonConsole",
                                                  "Import PyQt.QtCore class")
        self.loadQtCoreButton = QAction(self)
        self.loadQtCoreButton.setCheckable(False)
        self.loadQtCoreButton.setEnabled(True)
        self.loadQtCoreButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtCoreConsole.png"))
        self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtCoreButton.setIconVisibleInMenu(True)
        self.loadQtCoreButton.setToolTip(loadQtCoreBt)
        self.loadQtCoreButton.setText(loadQtCoreBt)
        ## Import QtGui class
        loadQtGuiBt = QCoreApplication.translate("PythonConsole",
                                                 "Import PyQt.QtGui class")
        self.loadQtGuiButton = QAction(self)
        self.loadQtGuiButton.setCheckable(False)
        self.loadQtGuiButton.setEnabled(True)
        self.loadQtGuiButton.setIcon(
            QgsApplication.getThemeIcon("console/iconQtGuiConsole.png"))
        self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtGuiButton.setIconVisibleInMenu(True)
        self.loadQtGuiButton.setToolTip(loadQtGuiBt)
        self.loadQtGuiButton.setText(loadQtGuiBt)
        ## Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        ## Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(24, 24))
        self.toolBar.setOrientation(Qt.Vertical)
        self.toolBar.setMovable(True)
        self.toolBar.setFloatable(True)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        # self.toolBarEditor.setStyleSheet('QToolBar{background-color: rgb(%s, %s, %s' % tuple(bkgrcolor) + ');\
        #                                   border-right: 1px solid rgb(%s, %s, %s' % tuple(bordercl) + ');}')
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(18, 18))
        self.toolBarEditor.setOrientation(Qt.Vertical)
        self.toolBarEditor.setMovable(True)
        self.toolBarEditor.setFloatable(True)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)

        ## Menu Import Class
        self.classMenu = QMenu()
        self.classMenu.addAction(self.loadProcessingButton)
        self.classMenu.addAction(self.loadQtCoreButton)
        self.classMenu.addAction(self.loadQtGuiButton)
        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        ##------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 0, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 1, 1, 1, 1)

        self.toolBarLayout = QGridLayout(self.widgetButton)
        self.toolBarLayout.setMargin(0)
        self.toolBarLayout.setSpacing(0)
        self.toolBarLayout.addWidget(self.toolBar)
        self.toolBarEditorLayout = QGridLayout(self.widgetButtonEditor)
        self.toolBarEditorLayout.setMargin(0)
        self.toolBarEditorLayout.setSpacing(0)
        self.toolBarEditorLayout.addWidget(self.toolBarEditor)

        ## Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find...")

        if pyqtconfig.Configuration().qt_version >= 0x40700:
            self.lineEditFind.setPlaceholderText(placeHolderTxt)
        else:
            self.lineEditFind.setToolTip(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        ##------------ Add first Tab in Editor -------------------------------

        #self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        ##------------ Signal -------------------------------

        self.findTextButton.toggled.connect(self.findTextEditor)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.loadProcessingButton.triggered.connect(self.processing)
        self.loadQtCoreButton.triggered.connect(self.qtCore)
        self.loadQtGuiButton.triggered.connect(self.qtGui)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.connect(self.listClassMethod,
                     SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
                     self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findText)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

    def _findText(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def processing(self):
        self.shell.commandConsole('processing')

    def qtCore(self):
        self.shell.commandConsole('qtCore')

    def qtGui(self):
        self.shell.commandConsole('qtGui')

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def findTextEditor(self, checked):
        self.widgetFind.show() if checked else self.widgetFind.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath", "")
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList = QFileDialog.getOpenFileNames(self, openFileTr, lastDirPath,
                                                "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError), error:
            msgText = QCoreApplication.translate(
                'PythonConsole',
                'The file <b>{0}</b> could not be saved. Error: {1}').format(
                    tabWidget.path, error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)
Esempio n. 24
0
class MainWindow(QWidget, MainWindowGeneric):

    def __init__(self, parent):
        QWidget.__init__(self)
        MainWindowGeneric.__init__(self)
        self._parent = parent

        self._vbox = QVBoxLayout(self)
        #Splitters
        self.splitterMain = QSplitter()
        self.splitterCentral = QSplitter(Qt.Vertical)
        #Properties Panel
        self._properties = PropertiesWidget(self)
        #Central
        self._central = CentralWidget(self)
        self.show_start_page()
        self.splitterCentral.addWidget(self._central)
        #Display Container
        self.container = DisplayContainer(self)
        self._hide_container()
        self.splitterCentral.addWidget(self.container)
        height = [(self.height() / 3) * 2, self.height() / 3]
        self.splitterCentral.setSizes([height[0], height[1]])
        #Size Central Splitter
        self.splitterMain.addWidget(self.splitterCentral)
        self.splitterMain.addWidget(self._properties)
        width = [(self.width() / 6) * 5, self.width() / 6]
        self.splitterMain.setSizes([width[0], width[1]])
        self._vbox.addWidget(self.splitterMain)

        #flag for reload_file
        self._reloading = False

        #Shortcuts
        shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self)
        shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self)
        shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self)
        shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self)
        shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self)
        shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self)
        shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self)
        shortPrint = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_I), self)
        shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self)
        shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self)
        shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self)
        shortTitleComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_T), self)
        shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self)
        shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self)
        shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self)
        shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self)
        shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self)
        shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self)
        shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self)
        shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self)
        shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self)
        shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self)
        shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self)
        shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self)
        shortFollowMode = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F10), self)
        shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self)
        shortShowProjectsTree = QShortcut(QKeySequence(Qt.ALT + Qt.Key_1), self)
        shortShowSymbolsTree = QShortcut(QKeySequence(Qt.ALT + Qt.Key_2), self)
        #Signal -> Slot
        self.connect(shortCloseTab, SIGNAL("activated()"), self.close_actual_tab)
        self.connect(shortNew, SIGNAL("activated()"), self.new_editor)
        self.connect(shortNewProject, SIGNAL("activated()"), self.new_project)
        self.connect(shortOpen, SIGNAL("activated()"), self.open_file)
        self.connect(shortOpenProject, SIGNAL("activated()"), self.open_project_folder)
        self.connect(shortSave, SIGNAL("activated()"), self.save)
        self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project)
        self.connect(shortPrint, SIGNAL("activated()"), self._print_file)
        self.connect(shortComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().comment())
        self.connect(shortIndentLess, SIGNAL("activated()"), lambda: self._central.obtain_editor().indent_less())
        self.connect(shortHorizontalLine, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_horizontal_line())
        self.connect(shortTitleComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_title_comment())
        self.connect(shortRedo, SIGNAL("activated()"), lambda: self._central.obtain_editor().redo())
        self.connect(shortHideContainer, SIGNAL("activated()"), self._hide_container)
        self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor)
        self.connect(shortHideExplorer, SIGNAL("activated()"), self._hide_explorer)
        self.connect(shortRunFile, SIGNAL("activated()"), self._run_code)
        self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program)
        self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all)
        self.connect(shortFind, SIGNAL("activated()"), self._open_find)
        self.connect(shortFindReplace, SIGNAL("activated()"), self._open_find_replace)
        self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc)
        self.connect(shortSplitHorizontal, SIGNAL("activated()"), lambda: self.split_tab(True))
        self.connect(shortSplitVertical, SIGNAL("activated()"), lambda: self.split_tab(False))
        self.connect(shortFollowMode, SIGNAL("activated()"), self._view_follow_mode)
        self.connect(shortReloadFile, SIGNAL("activated()"), lambda: self.reload_file())
        self.connect(shortShowProjectsTree, SIGNAL("activated()"), self.show_projects_tree)
        self.connect(shortShowSymbolsTree, SIGNAL("activated()"), self.show_symbols_tree)

    def change_window_title(self, title):
        self._parent.setWindowTitle('NINJA-IDE - ' + title)

    def _open_find(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.focus_find(self._central.obtain_editor())

    def _open_find_replace(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.replace_visibility(True)
        self._parent._status.focus_find(self._central.obtain_editor())

    def _print_file(self):
        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.A4)
        if self._central.obtain_editor().path:
            fileName = manage_files.get_basename(self._central.obtain_editor().path)
            fileName = fileName[:fileName.rfind('.')] + '.pdf'
        else:
            fileName = 'newDocument.pdf'
        self.printer.setOutputFileName(fileName)
        dialog = QPrintDialog(self.printer, self)
        if dialog.exec_():
            self.printer.setDocName(manage_files.get_basename(self._central.obtain_editor().path))
            self._central.obtain_editor().document().print_(self.printer)

    def _hide_container(self):
        if self.containerIsVisible:
            self.container.hide()
            self.containerIsVisible = False
            self._central.obtain_editor().setFocus()
        else:
            self.container.show()
            self.containerIsVisible = True
            self.container.gain_focus()

    def _hide_editor(self):
        if self._central.isVisible():
            self._central.hide()
        else:
            self._central.show()

    def _hide_explorer(self):
        if self._properties.isVisible():
            self._properties.hide()
        else:
            self._properties.show()

    def _splitter_central_orientation(self):
        if self.splitterCentral.orientation() == Qt.Horizontal:
            self.splitterCentral.setOrientation(Qt.Vertical)
        else:
            self.splitterCentral.setOrientation(Qt.Horizontal)

    def get_splitter_central_orientation(self):
        return self.splitterCentral.orientation()

    def _splitter_main_orientation(self):
        if self.splitterMain.orientation() == Qt.Horizontal:
            self.splitterMain.setOrientation(Qt.Vertical)
        else:
            self.splitterMain.setOrientation(Qt.Horizontal)

    def get_splitter_main_orientation(self):
        return self.splitterMain.orientation()

    def _splitter_main_rotate(self):
        w = self.splitterMain.widget(0)
        w1 = self.splitterMain.widget(1)
        if type(w) is PropertiesWidget:
            w.setTabPosition(QTabWidget.East)
        else:
            w1.setTabPosition(QTabWidget.West)
        self.splitterMain.insertWidget(0, w1)
        self.splitterMain.insertWidget(1, w)

    def get_splitter_main_position(self):
        w = self.splitterMain.widget(0)
        return w.__class__

    def _splitter_central_rotate(self):
        w = self.splitterCentral.widget(0)
        w1 = self.splitterCentral.widget(1)
        self.splitterCentral.insertWidget(0, w1)
        self.splitterCentral.insertWidget(1, w)

    def get_splitter_central_position(self):
        w = self.splitterCentral.widget(0)
        return w.__class__

    def get_splitter_position_0(self):
        return type(self.splitterCentral.widget(0))

    def get_splitter_main_position_0(self):
        return type(self.splitterMain.widget(0))

    def reload_panels_position(self):
        self.settings = QSettings('NINJA-IDE', 'Kunai')

        self.settings.beginGroup('Preferences')
        self.settings.beginGroup('Interface')

        #first with the splitterCentral
        c = self.splitterCentral.widget(0)
        c1 = self.splitterCentral.widget(1)
        if (type(c) == CentralWidget):
            self.splitterCentral.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], c)
            self.splitterCentral.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], c1)
        else:
            self.splitterCentral.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], c1)
            self.splitterCentral.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], c)
        #now with the splitterMain
        m = self.splitterMain.widget(0)
        m1 = self.splitterMain.widget(1)
        if (type(m) == QSplitter):
            self.splitterMain.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], m)
            self.splitterMain.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], m1)
        else:
            self.splitterMain.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], m1)
            self.splitterMain.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], m)

    def get_open_projects(self):
        return self._properties._treeProjects.get_open_projects()

    def _run_code(self):
        if self.save():
            self.container.show()
            self.containerIsVisible = True
            editor = self._central.obtain_editor()
            ext = self.get_file_extension(editor.path)
            if ext == 'html':
                height = self.height() / 3
                self.splitterCentral.setSizes([height, height * 2])
                self.container.render_web_page(editor.path)
            elif ext == 'py':
                height = self.height() / 3
                self.splitterCentral.setSizes([height * 2, height])
                self.container.run_application(editor.path)
            else:
                self.execute_file(editor.path, ext)

    def _run_program(self, actual=None):
        self.container.show()
        self.containerIsVisible = True
        if actual is None:
            actual = self._properties._treeProjects.actualProject
        if actual is None:
            return
        mainFile = actual.mainFile
        if mainFile == '':
            self._properties._treeProjects.open_project_properties()
            self.containerIsVisible = False
            self.container.hide()
            return
        path = manage_files.create_abs_path(actual.path, mainFile)
        self._central.save_project_files(actual.path)
        lang = actual.lang()
        type_ = actual.projectType
        if lang == 'html':
            height = self.height() / 3
            self.splitterCentral.setSizes([height, height * 2])
            self.container.render_web_page(path)
        elif lang == 'py':
            height = self.height() / 3
            self.splitterCentral.setSizes([height * 2, height])
            self.container.run_application(path, actual.pythonPath)
        else:
            self.execute_program(path, lang, type_)

    def _stop_program(self):
        self.container.kill_application()

    def _hide_all(self):
        if self._properties.isVisible():
            self._properties.hide()
            self.container.hide()
            self._parent._toolbar.hide()
        else:
            if self.containerIsVisible:
                self.container.show()
            self._properties.show()
            self._parent._toolbar.show()

    def show_start_page(self):
        startPage = Browser(resources.start_page_url, None, self)
        self.add_tab(startPage, 'Start Page')

    def show_report_bugs(self):
        bugsPage = Browser(resources.bugs_page)
        self.add_tab(bugsPage, 'Report Bugs!')

    def show_plugins_doc(self):
        bugsPage = Browser(resources.plugins_doc)
        self.add_tab(bugsPage, 'How to Write NINJA-IDE plugins')

    def _show_python_doc(self):
        process = runner.start_pydoc()
        docPage = Browser(process[1], process[0])
        self.add_tab(docPage, 'Python Documentation')

    def new_editor(self, lang='py'):
        if not self._reloading:
            editor = factory_editor(lang, self._central.actual_tab())
            self.add_tab(editor, 'New Document')

    def add_tab(self, component, title):
        self._central.actual_tab().add_tab(component, title)

    def split_tab(self, option):
        if option:
            self._central.show_split(Qt.Horizontal)
        else:
            self._central.show_split(Qt.Vertical)

    def _view_follow_mode(self):
        self._central._show_follow_mode()

    def new_project(self):
        project = WizardNewProject(self)
        project.show()

    def show_preferences(self):
        prefs = PreferencesWindow(self)
        prefs.show()

    def open_document(self, fileName, project=None):
        try:
            if not self._central.actual_tab().is_open(fileName):
                self._central.actual_tab().notOpening = False
                editor = factory_editor(fileName, self._central.actual_tab(), project)
                content = self.read_file_content(fileName)
                editor.setPlainText(content)
                editor.path = fileName
                editor.ask_if_externally_modified = True
                #self.add_tab(editor, self.get_file_name(fileName))
                if not editor.has_write_permission():
                    fileName += ' (Read-Only)'
                self.add_tab(editor, self.get_file_name(fileName))
                self.change_window_title(fileName)
                editor.find_errors_and_check_style()
            else:
                self._central.actual_tab().move_to_open(fileName)
        except Exception, reason:
            print reason
            QMessageBox.information(self, 'Incorrect File', 'The file couldn\'t be open')
        self._central.actual_tab().notOpening = True
Esempio n. 25
0
class MainWindow(QWidget, MainWindowGeneric):
    def __init__(self, parent):
        QWidget.__init__(self)
        MainWindowGeneric.__init__(self)
        self._parent = parent
        self.settings = QSettings('NINJA-IDE', 'Kunai')

        self.settings.beginGroup('Preferences')
        self.settings.beginGroup('Interface')

        self._vbox = QVBoxLayout(self)
        #Splitters
        self.splitterMain = QSplitter()
        self.splitterCentral = QSplitter(Qt.Vertical)
        #Properties Panel
        self._properties = PropertiesWidget(self)
        #Central
        self._central = CentralWidget(self)
        self.show_start_page()
        self.splitterCentral.insertWidget(
            self.settings.value('central_tab_position', 0).toInt()[0],
            self._central)
        #Display Container
        self.container = DisplayContainer(self)
        self._hide_container()
        self.splitterCentral.insertWidget(
            self.settings.value('container_tab_position', 1).toInt()[0],
            self.container)
        height = [(self.height() / 3) * 2, self.height() / 3]
        self.splitterCentral.setSizes([height[self.settings.value('central_tab_position', 0).toInt()[0]], height[self\
        .settings.value('container_tab_position', 1).toInt()[0]]])
        #Size Central Splitter
        self.splitterMain.insertWidget(
            self.settings.value('main_tab_position', 0).toInt()[0],
            self.splitterCentral)
        self.splitterMain.insertWidget(
            self.settings.value('properties_tab_position', 1).toInt()[0],
            self._properties)
        width = [(self.width() / 6) * 5, self.width() / 6]
        self.splitterMain.setSizes([width[self.settings.value('main_tab_position', 0).toInt()[0]],\
         width[self.settings.value('properties_tab_position', 1).toInt()[0]]])
        self._vbox.addWidget(self.splitterMain)

        self.settings.endGroup()  #End General Preferences
        self.settings.endGroup()

        #flag for reload_file
        self._reloading = False

        #Shortcuts
        shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self)
        shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self)
        shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self)
        shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self)
        shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self)
        shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self)
        shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S),
                                 self)
        shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self)
        shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self)
        shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self)
        shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self)
        shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self)
        shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self)
        shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self)
        shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self)
        shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self)
        shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self)
        shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self)
        shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self)
        shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self)
        shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self)
        shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self)
        shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self)
        #Signal -> Slot
        self.connect(shortCloseTab, SIGNAL("activated()"),
                     self.close_actual_tab)
        self.connect(shortNew, SIGNAL("activated()"), self.new_editor)
        self.connect(shortNewProject, SIGNAL("activated()"), self.new_project)
        self.connect(shortOpen, SIGNAL("activated()"), self.open_file)
        self.connect(shortOpenProject, SIGNAL("activated()"),
                     self.open_project_folder)
        self.connect(shortSave, SIGNAL("activated()"), self.save)
        self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project)
        self.connect(shortComment, SIGNAL("activated()"),
                     lambda: self._central.obtain_editor().comment())
        self.connect(shortIndentLess, SIGNAL("activated()"),
                     lambda: self._central.obtain_editor().indent_less())
        self.connect(
            shortHorizontalLine, SIGNAL("activated()"),
            lambda: self._central.obtain_editor().insert_horizontal_line())
        self.connect(shortRedo, SIGNAL("activated()"),
                     lambda: self._central.obtain_editor().redo())
        self.connect(shortHideContainer, SIGNAL("activated()"),
                     self._hide_container)
        self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor)
        self.connect(shortHideExplorer, SIGNAL("activated()"),
                     self._hide_explorer)
        self.connect(shortRunFile, SIGNAL("activated()"), self._run_code)
        self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program)
        self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all)
        self.connect(shortFind, SIGNAL("activated()"), self._open_find)
        self.connect(shortFindReplace, SIGNAL("activated()"),
                     self._open_find_replace)
        self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc)
        self.connect(shortSplitHorizontal, SIGNAL("activated()"),
                     lambda: self.split_tab(True))
        self.connect(shortSplitVertical, SIGNAL("activated()"),
                     lambda: self.split_tab(False))
        self.connect(shortReloadFile, SIGNAL("activated()"),
                     lambda: self.reload_file())

    def change_window_title(self, title):
        self._parent.setWindowTitle('NINJA-IDE - ' + title)

    def _open_find(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.focus_find(self._central.obtain_editor())

    def _open_find_replace(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.replace_visibility(True)
        self._parent._status.focus_find(self._central.obtain_editor())

    def _hide_container(self):
        if self.containerIsVisible:
            self.container.hide()
            self.containerIsVisible = False
            self._central.obtain_editor().setFocus()
        else:
            self.container.show()
            self.containerIsVisible = True
            self.container.gain_focus()

    def _hide_editor(self):
        if self._central.isVisible():
            self._central.hide()
        else:
            self._central.show()

    def _hide_explorer(self):
        if self._properties.isVisible():
            self._properties.hide()
        else:
            self._properties.show()

    def _splitter_central_orientation(self):
        if self.splitterCentral.orientation() == Qt.Horizontal:
            self.splitterCentral.setOrientation(Qt.Vertical)
        else:
            self.splitterCentral.setOrientation(Qt.Horizontal)

    def get_splitter_central_orientation(self):
        return self.splitterCentral.orientation()

    def _splitter_main_orientation(self):
        if self.splitterMain.orientation() == Qt.Horizontal:
            self.splitterMain.setOrientation(Qt.Vertical)
        else:
            self.splitterMain.setOrientation(Qt.Horizontal)

    def get_splitter_main_orientation(self):
        return self.splitterMain.orientation()

    def _splitter_main_rotate(self):
        w = self.splitterMain.widget(0)
        w1 = self.splitterMain.widget(1)
        self.splitterMain.insertWidget(0, w1)
        self.splitterMain.insertWidget(1, w)

    def get_splitter_main_position(self):
        w = self.splitterMain.widget(0)
        return w.__class__

    def _splitter_central_rotate(self):
        w = self.splitterCentral.widget(0)
        w1 = self.splitterCentral.widget(1)
        self.splitterCentral.insertWidget(0, w1)
        self.splitterCentral.insertWidget(1, w)

    def get_splitter_central_position(self):
        w = self.splitterCentral.widget(0)
        return w.__class__

    def get_splitter_position_0(self):
        return type(self.splitterCentral.widget(0))

    def get_splitter_main_position_0(self):
        return type(self.splitterMain.widget(0))

    def reload_panels_position(self):
        self.settings = QSettings('NINJA-IDE', 'Kunai')

        self.settings.beginGroup('Preferences')
        self.settings.beginGroup('Interface')

        #first with the splitterCentral
        c = self.splitterCentral.widget(0)
        c1 = self.splitterCentral.widget(1)
        if (type(c) == CentralWidget):
            self.splitterCentral.insertWidget(
                self.settings.value('central_tab_position', 0).toInt()[0], c)
            self.splitterCentral.insertWidget(
                self.settings.value('container_tab_position', 1).toInt()[0],
                c1)
        else:
            self.splitterCentral.insertWidget(
                self.settings.value('central_tab_position', 0).toInt()[0], c1)
            self.splitterCentral.insertWidget(
                self.settings.value('container_tab_position', 1).toInt()[0], c)
        #now with the splitterMain
        m = self.splitterMain.widget(0)
        m1 = self.splitterMain.widget(1)
        if (type(m) == QSplitter):
            self.splitterMain.insertWidget(
                self.settings.value('central_tab_position', 0).toInt()[0], m)
            self.splitterMain.insertWidget(
                self.settings.value('container_tab_position', 1).toInt()[0],
                m1)
        else:
            self.splitterMain.insertWidget(
                self.settings.value('central_tab_position', 0).toInt()[0], m1)
            self.splitterMain.insertWidget(
                self.settings.value('container_tab_position', 1).toInt()[0], m)

    def get_open_projects(self):
        return self._properties._treeProjects.get_open_projects()

    def _run_code(self):
        if self.save():
            self.container.show()
            self.containerIsVisible = True
            editor = self._central.obtain_editor()
            ext = self.get_file_extension(editor.path)
            if ext == 'html':
                height = self.height() / 3
                self.splitterCentral.setSizes([height, height * 2])
                self.container.render_web_page(editor.path)
            elif ext == 'py':
                height = self.height() / 3
                self.splitterCentral.setSizes([height * 2, height])
                self.container.run_application(editor.path)
            else:
                self.execute_file(editor.path, ext)

    def _run_program(self, actual=None):
        self.container.show()
        self.containerIsVisible = True
        if actual is None:
            actual = self._properties._treeProjects.actualProject
        if actual is None:
            return
        mainFile = actual.mainFile
        if mainFile == '':
            self._properties._treeProjects.open_project_properties()
            self.containerIsVisible = False
            self.container.hide()
            return
        path = manage_files.create_abs_path(actual.path, mainFile)
        self._central.save_project_files(actual.path)
        lang = actual.lang()
        type_ = actual.projectType
        if lang == 'html':
            height = self.height() / 3
            self.splitterCentral.setSizes([height, height * 2])
            self.container.render_web_page(path)
        elif lang == 'py':
            height = self.height() / 3
            self.splitterCentral.setSizes([height * 2, height])
            self.container.run_application(path)
        else:
            self.execute_program(path, lang, type_)

    def _stop_program(self):
        self.container.kill_application()

    def _hide_all(self):
        if self._properties.isVisible():
            self._properties.hide()
            self.container.hide()
            self._parent._toolbar.hide()
        else:
            if self.containerIsVisible:
                self.container.show()
            self._properties.show()
            self._parent._toolbar.show()

    def show_start_page(self):
        startPage = Browser(resources.start_page_url)
        self.add_tab(startPage, 'Start Page')

    def show_report_bugs(self):
        bugsPage = Browser(resources.bugs_page)
        self.add_tab(bugsPage, 'Report Bugs!')

    def _show_python_doc(self):
        process = runner.start_pydoc()
        docPage = Browser(process[1], process[0])
        self.add_tab(docPage, 'Python Documentation')

    def new_editor(self, lang='py'):
        if not self._reloading:
            editor = factory_editor(lang, self._central.actual_tab())
            self.add_tab(editor, 'New Document')

    def add_tab(self, component, title):
        self._central.actual_tab().add_tab(component, title)

    def split_tab(self, option):
        if option:
            self._central.show_split(Qt.Horizontal)
        else:
            self._central.show_split(Qt.Vertical)

    def new_project(self):
        project = WizardNewProject(self)
        project.show()

    def show_preferences(self):
        prefs = PreferencesWindow(self)
        prefs.show()

    def open_document(self, fileName, project=None):
        try:
            if not self._central.actual_tab().is_open(fileName):
                self._central.actual_tab().notOpening = False
                editor = factory_editor(fileName, self._central.actual_tab(),
                                        project)
                content = self.read_file_content(fileName)
                editor.setPlainText(content)
                editor.path = fileName
                editor.ask_if_externally_modified = True
                #self.add_tab(editor, self.get_file_name(fileName))
                if not editor.has_write_permission():
                    fileName += ' (Read-Only)'
                self.add_tab(editor, self.get_file_name(fileName))
                self.change_window_title(fileName)
            else:
                self._central.actual_tab().move_to_open(fileName)
        except Exception, reason:
            print reason
            QMessageBox.information(self, 'Incorrect File',
                                    'The file couldn\'t be open')
        self._central.actual_tab().notOpening = True
Esempio n. 26
0
    def createWidgets(self):
        """
        QtWidgets creation

         ___________   _________________
        |           | |                 |
        |           | |                 |
        |           | |                 |
        | TestsItem | | TextualLogView  |
        |           | |                 |
        |           | |                 |
        |___________| |_________________|
        """
        layout = QHBoxLayout()

        self.logsItem = TestsView.TestsView(parent=self, local=self.local)

        self.resumeView = ResumeView.TextualView(parent=self)
        if QtHelper.str2bool(
                Settings.instance().readValue(key='TestRun/hide-resume-view')):
            self.hideResumeView()

        self.graphView = GraphView.FlowChartView(parent=self)
        self.logsView = TextualView.TextualView2(parent=self)
        self.hexLogsView = DetailedView.DetailedView(parent=self)

        self.displayTab = QTabWidget()

        hSplitter = QSplitter(self)
        hSplitter.setOrientation(Qt.Vertical)

        hSplitter.addWidget(self.resumeView)
        hSplitter.addWidget(self.logsView)
        hSplitter.addWidget(self.hexLogsView)

        self.displayTab.addTab(hSplitter, self.tr('Events'))
        self.displayTab.addTab(self.graphView, self.tr('Diagram'))

        defaultTab = Settings.instance().readValue(
            key='TestRun/default-tab-run')
        self.displayTab.setCurrentIndex(int(defaultTab))

        self.currentEdit = QLineEdit()
        self.currentEdit.setReadOnly(True)
        self.currentEdit.setStyleSheet(
            "QLineEdit { background-color : #F0F0F0; color: grey; }")

        leftFrame = QFrame()
        leftLayout = QVBoxLayout()
        leftLayout.setContentsMargins(0, 0, 0, 0)
        leftFrame.setLayout(leftLayout)

        leftLayout.addWidget(self.currentEdit)
        leftLayout.addWidget(self.displayTab)

        v_splitter = QSplitter(self)
        v_splitter.addWidget(self.logsItem)
        v_splitter.addWidget(leftFrame)
        v_splitter.setStretchFactor(1, 1)

        layout.addWidget(v_splitter)

        self.setLayout(layout)
Esempio n. 27
0
class PlotWidgetContainer(QWidget):

    def __init__(self, modelRoot, *args, **kwargs):

        super(PlotWidgetContainer, self).__init__(*args)
        self.modelRoot = modelRoot
        if len(moose.wildcardFind(modelRoot + "/##[ISA=ChemCompt]")) == 0:
            self.modelType = ELECTRICAL
        else:
            self.modelType = CHEMICAL

        self.model          = moose.element(self.modelRoot)
        if self.modelRoot != "/":
            if moose.exists(modelRoot + "/data"):
                self.data   = moose.element(self.modelRoot + "/data")
            else:
                self.data   = moose.Neutral(self.modelRoot + "/data")

        else:
            self.data       = moose.element("/data")

        self._layout        = QVBoxLayout()
        self.graphs         = QSplitter()
        self.graphs.setOrientation(PyQt4.QtCore.Qt.Vertical)
        self.graphsArea     = QScrollArea()
        # self.graphsLayout   = QGridLayout()
        # self.menubar        = self.createMenuBar()
        self.rowIndex       = 0
            # self.setSizePolicy( QtGui.QSizePolicy.Expanding
        #                   , QtGui.QSizePolicy.Expanding
        #                   )

        self.graphs.setSizePolicy( QtGui.QSizePolicy.Expanding
                                 , QtGui.QSizePolicy.Expanding
                                 )
        self.setAcceptDrops(True)
        # self._layout.setSizeConstraint( QLayout.SetNoConstraint )
        # self.graphs.setLayout(self.graphsLayout)
        self.graphsArea.setWidget(self.graphs)
        self.graphsArea.setWidgetResizable(True)
        self.graphWidgets = []
        # self._layout.addWidget(self.menubar)
        self._layout.addWidget(self.graphsArea)
        self.setLayout(self._layout)

        for graph in self.data.children:
            self.addPlotWidget(graph = graph)

        if len(self.data.children) == 0:
            self.addPlotWidget()

    def deleteWidget(self, graphWidget):
        # print("Deleted => ", graphWidget)
        self.graphWidgets.remove(graphWidget)
        graphWidget.setParent(None)
        graphWidget.close()

    def createMenuBar(self):
        bar = sidebar.sidebar()
        bar.addAction(sidebar.add_graph_action(bar, lambda event: self.addPlotWidget() ))
        # bar.addAction(sidebar.delete_graph_action(bar, lambda event: self.addPlotWidget() ))
        # bar.addAction(sidebar.list_action(bar, self.showPlotView))
        return bar

    def addPlotWidget(self, row = None, col = 0, graph = None):
        if graph == None:
            graph = moose.Neutral(self.data.path + "/graph_" + str(self.rowIndex))
        widget = default.PlotWidget(self.model, graph, self.rowIndex, self)

        if self.modelType == ELECTRICAL:
            for axes in widget.canvas.axes.values():
            # axes.autoscale(False, axis='x', tight=True)
                axes.set_ylim(bottom = -0.07, top= 0.03)

        if row == None:
            row = self.rowIndex
        self.graphs.addWidget(widget)
        self.rowIndex += 1
        self.graphWidgets.append(widget)
        widget.widgetClosedSignal.connect(self.deleteWidget)
        widget.addGraph.connect(lambda event : self.addPlotWidget())
        # widget.resize(1, 1);
        return widget

    def showPlotView(self):
        pass

    def setModelRoot(self, *args):
        pass

    def getMenus(self, *args):
        return []

    def setDataRoot(self, *args):
        pass

    def updatePlots(self):
        for graphWidget in self.graphWidgets:
            graphWidget.updatePlots()

    def rescalePlots(self):
        for graphWidget in self.graphWidgets:
            graphWidget.rescalePlots()

    def extendXAxes(self, xlim):
        for graphWidget in self.graphWidgets:
            graphWidget.extendXAxes(xlim)

    def plotAllData(self):
        for graphWidget in self.graphWidgets:
            graphWidget.plotAllData()
Esempio n. 28
0
class PeakMapExplorer(QDialog):

    def __init__(self, parent=None):
        super(PeakMapExplorer, self).__init__(parent)
        self.setWindowFlags(Qt.Window)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowFlags(Qt.Window)

    def keyPressEvent(self, e):
        if e.key() != Qt.Key_Escape:
            super(PeakMapExplorer, self).keyPressEvent(e)

    def setup(self, peakmap, peakmap2=None, extra_items=None):
        self.setup_widgets_and_layout()
        self.connect_signals_and_slots()
        self.setup_peakmap_plotter(peakmap, peakmap2, extra_items)
        self.setup_processing_parameters()
        self.plot_peakmap()

    def connect_signals_and_slots(self):
        self.params.paramsChanged.connect(self.peakmap_plotter.set_processing_parameters)

    def setup_processing_parameters(self):
        self.params.setup_initial_values(gamma_min=0.05,
                                         gamma_max=10.0,
                                         gamma_start=4.0,
                                         log_scale=True,
                                         imin=self.imin,
                                         imax=self.imax)

    def setup_peakmap_plotter(self, peakmap, peakmap2, extra_items):

        self.peakmap = peakmap  # .getDominatingPeakmap()
        self.dual_mode = peakmap2 is not None
        self.peakmap2 = peakmap2
        if self.dual_mode:
            self.peakmap2 = peakmap2.getDominatingPeakmap()

        (self.rtmin, self.rtmax, self.mzmin, self.mzmax,
                                 self.imin, self.imax) = get_range(peakmap, peakmap2)

        # jparam = PeakMapProcessingParameters(self.params.gamma_start, True, 0, self.imax)
        # self.peakmap_plotter.set_processing_parameters(param)


    def plot_peakmap(self):
        # includes replot:
        self.peakmap_plotter.update_image_limits(self.rtmin, self.rtmax, self.mzmin, self.mzmax)

    def setup_widgets_and_layout(self):

        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)

        self.gridLayout = QGridLayout(self)
        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Horizontal)

        self.peakmap_plotter = PeakmapPlotter(self.splitter)

        self.verticalLayoutWidget = QWidget(self.splitter)
        self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setMargin(0)

        self.params = PeakMapScalingParameters(self.verticalLayoutWidget)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.params.sizePolicy().hasHeightForWidth())
        self.params.setSizePolicy(sizePolicy)

        self.verticalLayout.addWidget(self.params)

        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)
        self.verticalLayout.addItem(spacerItem)
        self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
Esempio n. 29
0
class EventLogViewer(QWidget):
    def __init__(self, node=None, chunks=None, parent=None):
        super(EventLogViewer, self).__init__(parent)

        self.display_mode = 0
        #  self.chunks = chunks
        self.node = node

        self.evtx_parser = EvtxXml(chunks, self.node)

        self.level = [
            ':/audit_success', ':/audit_failure', ':/error', ':/warning',
            ':/info', ':/chat.png'
        ]

        self.txt = [
            'Audit success', 'Audit failure', 'Error', 'Warning',
            'Information', 'Comment'
        ]

        self.disp = None
        self.current_row = 0
        self.widget = None

        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setMargin(3)
        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Horizontal)

        #self.evtx_table_view = QTableWidget(self.splitter)
        self.evtx_table_view = EvtxTableView(self.splitter, self)
        self.admin_pannel = EvtxAdminPannel(self.splitter, chunks or [])

        self.verticalLayout.addWidget(self.splitter)
        self.splitter.setStretchFactor(0, 2)

        if PYQT_VERSION_STR >= "4.5.0":
            self.evtx_table_view.cellDoubleClicked.connect(self.dispEvent)
            self.admin_pannel.admin_events.clicked.connect(
                self.dispAdminEvents)
            self.admin_pannel.choose_event_type.activated.connect(
                self.dispEventType)

            self.admin_pannel.cb.activated.connect(self.dispIdL)
            self.admin_pannel.cbs.activated.connect(self.dispSourceL)

            self.admin_pannel.search_id.clicked.connect(self.dispId)
            self.admin_pannel.search_source.clicked.connect(self.dispSource)
            self.admin_pannel.search_date.clicked.connect(self.dispDate)
        else:
            QObject.connect(self.evtx_table_view,
                            SIGNAL("cellDoubleClicked(int, int)"),
                            self.dispEvent)
            QObject.connect(self.admin_pannel.admin_events,
                            SIGNAL("clicked(bool)"), self.dispAdminEvents)
            QObject.connect(self.admin_pannel.search_id,
                            SIGNAL("clicked(bool)"), self.dispId)
            QObject.connect(self.admin_pannel.search_source,
                            SIGNAL("clicked(bool)"), self.dispSource)
            QObject.connect(self.admin_pannel.search_date,
                            SIGNAL("clicked(bool)"), self.dispSource)
            QObject.connect(self.admin_pannel.choose_event_type,
                            SIGNAL("currentIndexChanged(int)"),
                            self.dispEventType)

    def addEvents(self, events):
        self.evtx_table_view.addEvents(events)

    def display(self, chunks, node=None):
        self.evtx_table_view.clearContents()
        self.evtx_table_view.setRowCount(0)
        nb_chunk = 0
        evtxInfos = []
        for chunk in chunks:
            events = chunk.events()
            for event in events:
                QCoreApplication.processEvents()
                if node:
                    nodePtr = node.uid()
                elif self.node:
                    nodePtr = self.node.uid()
                else:
                    nodePtr = None
                evtxInfo = EvtxInfo(event, events[event], nb_chunk, nodePtr)
                evtxInfos.append(evtxInfo)
            nb_chunk += 1
        self.addEvents(evtxInfos)

    def display_chunk(self, events):
        self.evtx_table_view.clearContents()
        self.evtx_table_view.setRowCount(0)
        evtxInfos = []
        for event in events:
            for evtx in event:
                QCoreApplication.processEvents()
                evtxInfo = EvtxInfo(evtx, event[evtx], event[evtx]['chunk_nb'],
                                    self.node.uid())
                evtxInfos.append(evtxInfo)

    def dispAdminEvents(self, checked):
        self.evtx_table_view.clearContents()
        if self.display_mode == 0:
            error_list = self.evtx_parser.getEventBylevel(2)
            self.admin_pannel.admin_events.setText("All events")
            tmp_list = self.evtx_parser.getEventBylevel(3)
            error_list.extend(tmp_list)
            self.display_mode = 1
            self.display_chunk(error_list)
        elif self.display_mode == 1:
            self.admin_pannel.admin_events.setText("Admin. events")
            self.display_mode = 0
            processus_manager = ModuleProcessusManager()
            evtx = processus_manager.get('evtx')
            chunks = evtx.data(self.node.uid())
            self.display(chunks, self.node)

    def dispId(self, checked):
        txt = self.admin_pannel.id.text()
        if txt == "":
            return
        try:
            event_list = self.evtx_parser.getEventById(int(txt))
            self.evtx_table_view.clearContents()
            self.evtx_table_view.setRowCount(0)
            self.display_chunk(event_list)
        except ValueError:
            pass

    def dispIdL(self):
        txt = self.admin_pannel.id.text()
        txt = self.admin_pannel.cb.currentText()
        try:
            event_list = self.evtx_parser.getEventById(int(txt))
            self.evtx_table_view.clearContents()
            self.evtx_table_view.setRowCount(0)
            self.display_chunk(event_list)
        except ValueError:
            pass

    def fill_log_viewer(self, item):
        ptr = item.data(QListWidgetItem.UserType)
        node = VFS.Get().getNodeById(ptr.toULongLong()[0])

        processus_manager = ModuleProcessusManager()
        evtx = processus_manager.get('evtx')

        self.node = node
        self.evtx_parser.chunks = evtx.data(ptr.toULongLong()[0])
        self.evtx_parser.node = node

        self.admin_pannel.cb = self.admin_pannel.initId(
            evtx.data(ptr.toULongLong()[0]), 'id')
        self.admin_pannel.cbs = self.admin_pannel.initId(
            evtx.data(ptr.toULongLong()[0]), 'source')

        self.display(evtx.data(ptr.toULongLong()[0]), node)

    def dispDate(self, checked):
        date_begin = str(self.admin_pannel.select_date_b.dateTime().toString(
            "yyyy-MM-ddThh:mm:ss"))
        date_end = str(self.admin_pannel.select_date_e.dateTime().toString(
            "yyyy-MM-ddThh:mm:ss"))
        self.evtx_table_view.clearContents()
        self.evtx_table_view.setRowCount(0)
        event_list = self.evtx_parser.getEventsBetween(date_begin, date_end)
        self.display_chunk(event_list)

    def dispSource(self, checked):
        txt = self.admin_pannel.source.text()

        if txt == "":
            return

        self.evtx_table_view.clearContents()
        self.evtx_table_view.setRowCount(0)
        event_list = self.evtx_parser.getEventBySource(txt)
        self.display_chunk(event_list)

    def dispSourceL(self, checked):
        txt = self.admin_pannel.cbs.currentText()

        self.evtx_table_view.clearContents()
        self.evtx_table_view.setRowCount(0)
        event_list = self.evtx_parser.getEventBySource(txt)
        self.display_chunk(event_list)

    def dispEventType(self, index):
        if index == 0:
            processus_manager = ModuleProcessusManager()
            evtx = processus_manager.get('evtx')
            chunks = evtx.data(self.node.uid())
            self.display(chunks, self.node)
        else:
            self.evtx_table_view.clearContents()
            self.evtx_table_view.setRowCount(0)
            event_list = self.evtx_parser.getEventBylevel(index - 1)
            self.display_chunk(event_list)

    def dispEvent(self, row, column):
        item = self.evtx_table_view.item(row, 4)
        offset_str = item.text()
        offset = int(offset_str)

        item = self.evtx_table_view.item(row, 5)
        chunk_str = item.text()
        chunk_nb = int(chunk_str)

        if self.evtx_table_view.columnCount() == 7:
            item = self.evtx_table_view.item(row,
                                             6).data(QTableWidgetItem.Type)
            n = item.toULongLong()[0]
            self.evtx_parser.node = VFS.Get().getNodeById(n)

        xml = self.evtx_parser.getXML(chunk_nb, offset, self.evtx_parser.node)
        xml_str = tostring(xml, "utf-8")

        self.disp = ViewEvtx()
        self.disp.view.setAlternatingRowColors(1)
        self.disp.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.disp.view.setSelectionMode(QAbstractItemView.SingleSelection)

        self.current_row = row
        if not row:
            self.disp.prev_evtx.setEnabled(False)

        if row + 1 == self.evtx_table_view.rowCount():
            self.disp.next_evtx.setEnabled(False)

        self.widget = EvtxTree(xml_str, self.disp)

        self.disp.textEdit.setText(self.widget.doc.toString(3))
        self.disp.view.expandAll()
        self.disp.view.resizeColumnToContents(0)

        if PYQT_VERSION_STR >= "4.5.0":
            self.disp.next_evtx.clicked.connect(self.nextEvent)
            self.disp.prev_evtx.clicked.connect(self.prevEvent)

        self.disp.exec_()

        del self.disp
        self.disp = None

    def nextEvent(self, checked):
        row = self.current_row + 1

        self.disp.prev_evtx.setEnabled(True)

        while row + 1 != self.evtx_table_view.rowCount(
        ) and self.evtx_table_view.isRowHidden(row):
            row += 1

        # row = self.current_row

        item = self.evtx_table_view.item(row, 4)
        offset_str = item.text()
        offset = int(offset_str)

        item = self.evtx_table_view.item(row, 5)
        chunk_str = item.text()
        chunk_nb = int(chunk_str)

        node = None
        if self.evtx_table_view.columnCount() == 7:
            item = self.evtx_table_view.item(row, 6)
            node = VFS.Get().getNodeById(long(item.text()))
        else:
            node = self.node

        self.evtx_table_view.setCurrentCell(row, 0)
        xml = self.evtx_parser.getXML(chunk_nb, offset, node)
        xml_str = tostring(xml, "utf-8")

        self.widget = EvtxTree(xml_str, self.disp)

        self.disp.textEdit.setText(self.widget.doc.toString(3))
        self.disp.view.expandAll()
        self.disp.view.resizeColumnToContents(0)

        self.current_row = row

        while row + 1 != self.evtx_table_view.rowCount():
            row += 1
            if not self.evtx_table_view.isRowHidden(row): return

        self.disp.next_evtx.setEnabled(False)

    def prevEvent(self, checked):
        row = self.current_row - 1

        self.disp.next_evtx.setEnabled(True)

        while row != 0 and self.evtx_table_view.isRowHidden(row):
            row -= 1

        item = self.evtx_table_view.item(row, 4)
        offset_str = item.text()
        offset = int(offset_str)

        item = self.evtx_table_view.item(row, 5)
        chunk_str = item.text()
        chunk_nb = int(chunk_str)

        node = None
        if self.evtx_table_view.columnCount() == 7:
            item = self.evtx_table_view.item(row, 6)
            node = VFS.Get().getNodeById(long(item.text()))
        else:
            node = self.node

        self.current_row = row
        self.evtx_table_view.setCurrentCell(self.current_row, 0)

        xml = self.evtx_parser.getXML(chunk_nb, offset, node)
        xml_str = tostring(xml, "utf-8")

        self.widget = EvtxTree(xml_str, self.disp)

        self.disp.textEdit.setText(self.widget.doc.toString(3))
        self.disp.view.expandAll()
        self.disp.view.resizeColumnToContents(0)

        while row != 0:
            row -= 1
            if not self.evtx_table_view.isRowHidden(row): return

        self.disp.prev_evtx.setEnabled(False)
Esempio n. 30
0
class DSBrowser(QWidget):
    """browser for datastorage databases
       Nodes are identified by a string, containing fields separated by '|'.
       - first filed is a capital letter:
       'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart
       - second field is the database folder
       - third filed is the path of the node in the database
       - for charts the fourth field is the chart name (third is path of sensorgroup in this case)
    """
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(0)
        self.layout.setMargin(0)

        self.toolBar = QFrame(self)
        self.toolBarLayout = QHBoxLayout(self.toolBar)
        self.toolBarLayout.setMargin(2)
        self.toolBarLayout.setSpacing(2)
        self.layout.addWidget(self.toolBar)

        self.loadButton = QToolButton(self.toolBar)
        self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...'))
        self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen)))
        self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database'))
        self.toolBarLayout.addWidget(self.loadButton)
        self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase)

        self.dropButton = QToolButton(self.toolBar)
        self.dropButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Close All'))
        self.dropButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.clear)))
        self.dropButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Drop all open databases'))
        self.toolBarLayout.addWidget(self.dropButton)
        self.connect(self.dropButton, SIGNAL('pressed()'), self.dropDatabases)
        self.dropButton.setEnabled(False)

        self.toolBarLayout.addStretch(100)

        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Vertical)
        self.treeView = QTreeView(self.splitter)
        self.treeView.setAlternatingRowColors(True)
        self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeView.setAutoExpandDelay(500)
        self.textBrowser = QTextBrowser(self.splitter)
        self.layout.addWidget(self.splitter)
        self.splitter.setStretchFactor(0, 60)
        self.splitter.setStretchFactor(1, 40)
        self.model = DSModel()
        self.treeView.setModel(self.model)
        self.treeView.setSortingEnabled(True)
        self.treeView.expandAll()
        self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem)
        self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction)
        self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu)
        self.selectedNode = None
        self.selectedMI = None


    def loadDatabase(self, dn=None):
        """load a database"""
        if not dn:
            dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser',
                "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder)
            if not dn.isEmpty():
                dn = unicode(dn)
                SimuVis4.Globals.defaultFolder = dn
            else:
                return
        self.model.addDatabase(dn)
        self.treeView.expandToDepth(1)


    def dropDatabases(self):
        # FIXME: implement it
        pass


    def showItem(self, mi, pr):
        """show the item at model index mi"""
        t, n = self.model.dsNode(mi)
        txt = ""
        if t == 'R':
            # FIXME: no metadata?
            txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)) # + formatMetaData(n)
        elif t == 'P':
            txt = projectInfo.substitute(name=n.name, title=escape(n.title), groups=len(n)) + formatMetaData(n)
        elif t == 'G':
            txt = groupInfo.substitute(name=n.name, title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n)
        elif t == 'S':
            txt = sensorInfo.substitute(name=n.name, title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop,
                step=n.timegrid.step, length=n.datalen()) + formatMetaData(n)
        elif t == 'C':
            txt = chartInfo.substitute(name=n.name)
        self.textBrowser.setText(txt)


    def itemAction(self, mi):
        """default action (on doubleclick) for item at model index mi"""
        t, n = self.model.dsNode(mi)
        if t == 'R':
            pass
        elif t == 'P':
            pass
        elif t == 'G':
            pass
        elif t == 'S':
            print n
            self.showQwtPlot(n)
        elif t == 'C':
            self.showMplChart(n)


    def showContextMenu(self, pos):
        """show context menu for item at pos"""
        mi = self.treeView.indexAt(pos)
        t, n = self.model.dsNode(mi)
        self.selectedNode = n
        self.selectedMI = mi
        m = QMenu()
        if t in 'RPGS':
            p = m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata)
        if t == 'R':
            pass
        elif t == 'P':
            pass
        elif t == 'G':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart)
        elif t == 'S':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot)
        elif t == 'C':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart)
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem)
        a = m.exec_(self.treeView.mapToGlobal(pos))


    def showMplChart(self, node=None):
        if node is None:
            node = self.selectedNode
        showChartMplWindow(node, maximized=showChartMaximized)


    def showQwtPlot(self, node=None):
        if node is None:
            node = self.selectedNode
        showQwtPlotWindow(node, maximized=showChartMaximized)


    def editMetadata(self, node=None):
        if node is None:
            node = self.selectedNode
        editMetadata(node)


    def newChart(self, mi=None):
        """add a chart to sensorgroup at mi using the wizard"""
        if mi is None:
            mi = self.selectedMI
        showNewChartWizard(self.model, mi)

    def deleteItem(self, mi=None):
        """delete the item at mi"""
        if mi is None:
            mi = self.selectedMI
        self.model.deleteItem(mi)
Esempio n. 31
0
    def __init__(self, manager):
        self.manager = manager
        KDialog.__init__(self, manager.mainwin)
        self.setCaption(i18n("Expansion Manager"))
        self.setButtons(KDialog.ButtonCode(
            KDialog.Help |
            KDialog.Ok | KDialog.Close | KDialog.User1 | KDialog.User2 ))
        self.setButtonGuiItem(KDialog.User1, KStandardGuiItem.remove())
        self.setButtonGuiItem(KDialog.User2, KStandardGuiItem.add())
        self.setHelp("expand")
        
        layout = QVBoxLayout(self.mainWidget())
        layout.setContentsMargins(0, 0, 0, 0)
        
        search = KTreeWidgetSearchLine()
        search.setClickMessage(i18n("Search..."))
        layout.addWidget(search)
        
        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)
        layout.addWidget(splitter)

        tree = QTreeWidget()
        tree.setColumnCount(3)
        tree.setHeaderLabels((i18n("Name"), i18n("Description"), i18n("Shortcut")))
        tree.setRootIsDecorated(False)
        tree.setAllColumnsShowFocus(True)
        search.setTreeWidget(tree)
        splitter.addWidget(tree)
        
        box = KVBox()
        splitter.addWidget(box)
        
        key = KKeySequenceWidget(box)
        key.layout().setContentsMargins(0, 0, 0, 0)
        key.layout().insertStretch(0, 1)
        key.setEnabled(False)
        
        edit = QTextEdit(box)
        edit.setAcceptRichText(False)
        edit.setStyleSheet("QTextEdit { font-family: monospace; }")
        edit.item = None
        edit.dirty = False
        ExpandHighlighter(edit.document())
        
        # whats this etc.
        tree.setWhatsThis(i18n(
            "This is the list of defined expansions.\n\n"
            "Click on a row to see or change the associated text. "
            "Doubleclick a shortcut or its description to change it. "
            "You can also press F2 to edit the current shortcut.\n\n"
            "Use the buttons below to add or remove expansions.\n\n"
            "There are two ways to use the expansion: either type the "
            "shortcut in the text and then call the Expand function, or "
            "just call the Expand function (default shortcut: Ctrl+.), "
            "choose the expansion from the list and press Enter or click Ok."
            ))
            
        edit.setWhatsThis(
            "<html><head><style type='text/css'>"
            "td.short {{ font-family: monospace; font-weight: bold; }}"
            "</style></head><body>"
            "<p>{0}</p><table border=0 width=300 cellspacing=2><tbody>"
            "<tr><td class=short align=center>(|)</td><td>{1}</td></tr>"
            "<tr><td class=short align=center>@</td><td>{2}</td></tr>"
            "</tbody></table></body></html>".format(
            i18n("This is the text associated with the selected shortcut. "
                 "Some characters have special meaning:"),
            i18n("Place the cursor on this spot."),
            i18n("Translate the following pitch."),
            ))
        
        self.searchLine = search
        self.treeWidget = tree
        self.key = key
        self.edit = edit
        
        self.restoreDialogSize(config())
        
        # load the expansions
        for name in sorted(self.manager.expansionsList()):
            self.createItem(name, self.manager.description(name))

        tree.sortByColumn(1, Qt.AscendingOrder)
        tree.setSortingEnabled(True)
        tree.resizeColumnToContents(1)
        
        self.user1Clicked.connect(self.removeItem)
        self.user2Clicked.connect(self.addItem)
        edit.textChanged.connect(self.editChanged)
        search.textChanged.connect(self.checkMatch)
        tree.itemSelectionChanged.connect(self.updateSelection)
        tree.itemChanged.connect(self.itemChanged, Qt.QueuedConnection)
        key.keySequenceChanged.connect(self.keySequenceChanged)
Esempio n. 32
0
class __CentralWidget(QWidget):

    ###############################################################################
    # CentralWidget SIGNALS
    ###############################################################################
    """
    splitterCentralRotated()
    """

    ###############################################################################

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.parent = parent
        #This variables are used to save the splitter sizes before hide
        self._splitterMainSizes = None
        self._splitterAreaSizes = None
        self.lateralPanel = None

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        #Create Splitters to divide the UI in: MainPanel, Explorer, Misc
        self._splitterArea = QSplitter(Qt.Horizontal)
        self._splitterMain = QSplitter(Qt.Vertical)

        #Create scrollbar for follow mode
        self.scrollBar = QScrollBar(Qt.Vertical, self)
        self.scrollBar.setFixedWidth(20)
        self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together')
        self.scrollBar.hide()
        self.connect(self.scrollBar, SIGNAL("valueChanged(int)"),
                     self.move_follow_scrolls)

        #Add to Main Layout
        hbox.addWidget(self.scrollBar)
        hbox.addWidget(self._splitterArea)

    def insert_central_container(self, container):
        self.mainContainer = container
        self._splitterMain.insertWidget(0, container)

    def insert_lateral_container(self, container):
        self.lateralPanel = LateralPanel(container)
        self._splitterArea.insertWidget(0, self.lateralPanel)

    def insert_bottom_container(self, container):
        self.misc = container
        self._splitterMain.insertWidget(1, container)

    def showEvent(self, event):
        #Show Event
        QWidget.showEvent(self, event)
        #Avoid recalculate the panel sizes if they are already loaded
        if self._splitterArea.count() == 2:
            return
        #Rearrange widgets on Window
        self._splitterArea.insertWidget(0, self._splitterMain)
        qsettings = QSettings()
        #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant]
        heightList = list(
            qsettings.value("window/central/mainSize",
                            [(self.height() / 3) * 2,
                             self.height() / 3]))
        widthList = list(
            qsettings.value("window/central/areaSize", [(self.width() / 6) * 5,
                                                        self.width() / 6]))
        self._splitterMainSizes = [int(heightList[0]), int(heightList[1])]
        self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])]
        if not event.spontaneous():
            self.change_misc_visibility()
        if bin(settings.UI_LAYOUT)[-1] == '1':
            self.splitter_central_rotate()
        if bin(settings.UI_LAYOUT >> 1)[-1] == '1':
            self.splitter_misc_rotate()
        if bin(settings.UI_LAYOUT >> 2)[-1] == '1':
            self.splitter_central_orientation()
        #Set the sizes to splitters
        self._splitterMain.setSizes(self._splitterMainSizes)
        self._splitterArea.setSizes(self._splitterAreaSizes)
        self.misc.setVisible(
            qsettings.value("window/show_misc", False, type=bool))

    def change_misc_visibility(self):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
            self.misc.hide()
            widget = self.mainContainer.get_actual_widget()
            if widget:
                widget.setFocus()
        else:
            self.misc.show()
            self.misc.gain_focus()

    def change_main_visibility(self):
        if self.mainContainer.isVisible():
            self.mainContainer.hide()
        else:
            self.mainContainer.show()

    def change_explorer_visibility(self, force_hide=False):
        if self.lateralPanel.isVisible() or force_hide:
            self._splitterAreaSizes = self._splitterArea.sizes()
            self.lateralPanel.hide()
        else:
            self.lateralPanel.show()

    def splitter_central_rotate(self):
        w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1)
        self._splitterArea.insertWidget(0, w2)
        self._splitterArea.insertWidget(1, w1)
        self.emit(SIGNAL("splitterCentralRotated()"))

    def splitter_central_orientation(self):
        if self._splitterArea.orientation() == Qt.Horizontal:
            self._splitterArea.setOrientation(Qt.Vertical)
        else:
            self._splitterArea.setOrientation(Qt.Horizontal)

    def splitter_misc_rotate(self):
        w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1)
        self._splitterMain.insertWidget(0, w2)
        self._splitterMain.insertWidget(1, w1)

    def splitter_misc_orientation(self):
        if self._splitterMain.orientation() == Qt.Horizontal:
            self._splitterMain.setOrientation(Qt.Vertical)
        else:
            self._splitterMain.setOrientation(Qt.Horizontal)

    def get_area_sizes(self):
        if self.lateralPanel.isVisible():
            self._splitterAreaSizes = self._splitterArea.sizes()
        return self._splitterAreaSizes

    def get_main_sizes(self):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
        return self._splitterMainSizes

    def enable_follow_mode_scrollbar(self, val):
        if val:
            editorWidget = self.mainContainer.get_actual_editor()
            maxScroll = editorWidget.verticalScrollBar().maximum()
            position = editorWidget.verticalScrollBar().value()
            self.scrollBar.setMaximum(maxScroll)
            self.scrollBar.setValue(position)
        self.scrollBar.setVisible(val)

    def move_follow_scrolls(self, val):
        widget = self.mainContainer._tabMain.currentWidget()
        diff = widget._sidebarWidget.highest_line - val
        s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar()
        s2 = self.mainContainer._tabSecondary.\
            currentWidget().verticalScrollBar()
        s1.setValue(val)
        s2.setValue(val + diff)
class WWorkspace(QWidget):
    """
    Workspace widget
    """
    WORKSPACE = 0
    UpdateWindowTitle = pyqtSignal(str)
    RecentFile = pyqtSignal(dict)
    BusyCursor = pyqtSignal()
    ArrowCursor = pyqtSignal()

    def __init__(self, parent=None):
        """
        Constructs WWorkspace widget

        Signals emited:
         * updateWindowTitle

        @param parent: 
        @type parent:
        """
        QWidget.__init__(self, parent)
        self.parent = parent
        self.type = self.WORKSPACE
        self.name = self.tr('Workspace')

        # create each part
        WRepositories.initialize(parent=self)
        WDocumentViewer.initialize(parent=self,
                                   iRepo=WRepositories.instance(),
                                   lRepo=WRepositories.LocalRepository,
                                   rRepo=WRepositories.RemoteRepository)
        WDocumentProperties.initialize(parent=self,
                                       iRepo=WRepositories.instance(),
                                       lRepo=WRepositories.LocalRepository,
                                       rRepo=WRepositories.RemoteRepository)
        WHelper.initialize(parent=self)

        # splitter state
        self.splitterState = None
        self.splitterHelperState = None

        # create widget
        self.createWidgets()
        self.createActions()
        self.creationConnections()

    def createWidgets(self):
        """
        QtWidgets creation
           _________                _______________________      _________ 
          /         \__________    |                       |    /         \__
         |                     | Q |                       | Q |             |
         |   WRepositories     | S |                       | S |             |
         |                     | p |                       | p |             |
         |_____________________| l |                       | l |             |  
           _____QSplitter        i |     WDocumentViewer   | i |   WHelper   |
          /         \__________  t |                       | t |             |
         |                     | t |                       | t |             |
         | WDocumentProperties | e |                       | e |             |
         |                     | r |                       | r |             |
         |_____________________|   |_______________________|   |_____________|
        """

        self.wCursorPosition = WCursorPosition(self)
        self.parent.addWidgetToStatusBar(self.wCursorPosition)
        WDocumentProperties.instance().setDisabled(True)

        layout = QHBoxLayout(self)

        #  properties | viewer | helper
        self.vSplitter = QSplitter(self)

        if not QtHelper.str2bool(
                Settings.instance().readValue(key='View/tab-left')):
            self.hSplitter = QSplitter(self)
            self.hSplitter.setOrientation(Qt.Vertical)

            self.hSplitter.addWidget(WRepositories.instance())
            self.hSplitter.addWidget(WDocumentProperties.instance())
            self.hSplitter.setContentsMargins(0, 0, 0, 0)

            self.vSplitter.addWidget(self.hSplitter)
        else:
            WRepositories.instance().hideWidgetsHeader()
            WDocumentProperties.instance().hideWidgetsHeader()

            self.leftTab = QTabWidget(self)
            self.leftTab.addTab(WRepositories.instance(),
                                QIcon(":/folders.png"),
                                self.tr("Repositories"))
            self.leftTab.addTab(WDocumentProperties.instance(),
                                QIcon(":/controls.png"),
                                self.tr("Test Properties"))
            self.vSplitter.addWidget(self.leftTab)

        self.vSplitter.addWidget(WDocumentViewer.instance())
        self.vSplitter.setStretchFactor(1, 1)

        layout.addWidget(self.vSplitter)

        self.hSplitter2 = QSplitter(self)
        self.hSplitter2.setOrientation(Qt.Vertical)

        self.vSplitter.addWidget(self.hSplitter2)
        self.hSplitter2.addWidget(WHelper.instance())

        self.setLayout(layout)

    def creationConnections(self):
        """
        QtSignals connection:
         * WRepositories <=> WDocumentViewer.newTab
         * WDocumentViewer <=> cursorPositionChanged
         * WDocumentViewer <=> focusChanged
        """
        WRepositories.instance().local().OpenFile.connect(
            WDocumentViewer.instance().newTab)

        WDocumentViewer.instance().CursorPositionChanged.connect(
            self.cursorPositionChanged)
        WDocumentViewer.instance().TotalLinesChanged.connect(
            self.totalLinesChanged)
        WDocumentViewer.instance().FocusChanged.connect(self.focusChanged)

        WDocumentViewer.instance().BusyCursor.connect(self.emitBusy)
        WDocumentViewer.instance().ArrowCursor.connect(self.emitIdle)
        WDocumentViewer.instance().CurrentDocumentChanged.connect(
            self.currentDocumentChanged)
        WDocumentViewer.instance().DocumentOpened.connect(self.documentOpened)
        WDocumentViewer.instance().UpdateWindowTitle.connect(
            self.updateWindowTitle)
        WDocumentViewer.instance().DocumentViewerEmpty.connect(
            self.documentViewerEmpty)

        # from testplan when the test selection changed in the tree
        WDocumentViewer.instance().PropertiesChanged.connect(
            self.propertiesChanged)

        if WRepositories.instance().localConfigured != "Undefined":
            if RCI.instance().isAuthenticated():
                WDocumentViewer.instance().RefreshLocalRepository.connect(
                    WRepositories.instance().localRepository.refreshAll)
                WDocumentProperties.instance().RefreshLocalRepository.connect(
                    WRepositories.instance().localRepository.refreshAll)
        WDocumentViewer.instance().RecentFile.connect(self.recentFileUpdated)

        WHelper.instance().ShowAssistant.connect(self.onEnterAssistant)
        WHelper.instance().HideAssistant.connect(self.onLeaveAssistant)

        # new in v16
        WDocumentViewer.instance().ShowPropertiesTab.connect(
            self.onShowPropertiesTab)

    def onShowPropertiesTab(self):
        """
        On show properties tabulation
        """
        if QtHelper.str2bool(
                Settings.instance().readValue(key='View/tab-left')):
            self.leftTab.setCurrentIndex(TAB_PROPERTIES)

    def onEnterAssistant(self):
        """
        On mouse enter in the online helper
        """
        pass

    def onLeaveAssistant(self):
        """
        On mouse leave in the online helper
        """
        pass

    def createActions(self):
        """
        Create qt actions
        """
        self.hideDeveloperModeAction = QtHelper.createAction(
            self,
            self.tr("Developer"),
            self.hideDeveloperMode,
            checkable=True,
            icon=QIcon(":/window-fit.png"),
            shortcut=Settings.instance().readValue(
                key='KeyboardShorcuts/developer'),
            tip=self.tr('Fit the document viewer to maximize the editor area'))
        WDocumentViewer.instance().addActionToolbar(
            action=self.hideDeveloperModeAction)

    def emitBusy(self):
        """
        Emit busy
        """
        self.BusyCursor.emit()

    def emitIdle(self):
        """
        Emit idle
        """
        self.ArrowCursor.emit()

    def hideDeveloperMode(self):
        """
        Hide developer mode
        """
        if not self.hideDeveloperModeAction.isChecked():
            Settings.instance().setValue(key='View/developer', value='False')
            self.deactiveDeveloperView()
        else:
            Settings.instance().setValue(key='View/developer', value='True')
            self.activeDeveloperView()

    def activeDeveloperView(self):
        """
        Activate developer view
        """
        self.splitterState = self.vSplitter.saveState()
        self.vSplitter.setSizes([0, self.vSplitter.sizes()[1], 0])

    def deactiveDeveloperView(self):
        """
        Deactive developer view
        """
        if self.splitterState is not None:
            self.vSplitter.restoreState(self.splitterState)

    def mainSplitterMoved(self, index, pos):
        """
        Memorize the new position of the splitter
        """
        Settings.instance().setValue(key='View/helper-pos',
                                     value=self.vSplitter.sizes()[2])

    def hideHelper(self):
        """
        Hide assistant
        """
        self.splitterHelperState = self.vSplitter.saveState()
        self.vSplitter.setSizes(
            [self.vSplitter.sizes()[0],
             self.vSplitter.sizes()[1], 0])

    def showHelper(self):
        """
        Show assistant
        """
        if self.splitterHelperState is not None:
            self.vSplitter.restoreState(self.splitterHelperState)

    def documentViewerEmpty(self):
        """
        Called to deactivate the WDocumentProperties widget
        Hide the WCursorPosition widget in the status bar
        """
        WDocumentProperties.instance().clear()
        WDocumentProperties.instance().setDisabled(True)
        self.hideStatusBar()
        WDocumentViewer.instance().findWidget.hide()

    def currentDocumentChanged(self, wdocument):
        """
        Called when the current document is changed

        @param wdocument:
        @type wdocument:
        """
        # hide cursor position widget on disconnection or on the welcome page
        if isinstance(wdocument, WDocumentViewer.WelcomePage):
            self.hideStatusBar()

        if not RCI.instance().isAuthenticated():
            WDocumentProperties.instance().setDisabled(True)
            return

        # test properties uneeded for test config, test adapter and library adapters
        # and welcome page
        if isinstance(wdocument, WDocumentViewer.WelcomePage):

            WDocumentProperties.instance().setDisabled(True)
            WDocumentProperties.instance().clear()
        elif isinstance(wdocument, TestConfig.WTestConfig) or isinstance(wdocument, TestAdapter.WTestAdapter) \
                or isinstance(wdocument, TestTxt.WTestTxt)  or isinstance(wdocument, TestLibrary.WTestLibrary) \
                    or isinstance(wdocument, TestPng.WTestPng) :
            WDocumentProperties.instance().setDisabled(True)
            WDocumentProperties.instance().clear()
        else:
            WDocumentProperties.instance().setDocument(wdoc=wdocument)
            WDocumentProperties.instance().setDisabled(False)
            WDocumentProperties.instance().addDescriptions(wdoc=wdocument)
            WDocumentProperties.instance().addParameters(wdoc=wdocument)
            if not isinstance(wdocument, TestData.WTestData):
                WDocumentProperties.instance().addParametersOutput(
                    wdoc=wdocument)
                WDocumentProperties.instance().addProbes(wdoc=wdocument)
                WDocumentProperties.instance().addAgents(wdoc=wdocument)
            WDocumentViewer.instance().updateActions(wdocument=wdocument)

            if isinstance(wdocument, TestData.WTestData):
                WDocumentProperties.instance().disableOutputParameters()
                WDocumentProperties.instance().disableAgents()
                WDocumentProperties.instance().disableProbes()
            else:
                WDocumentProperties.instance().enableOutputParameters()
                WDocumentProperties.instance().enableProbes()
                WDocumentProperties.instance().enableAgents()

            if not isinstance(wdocument, TestAbstract.WTestAbstract):
                WDocumentProperties.instance().disableSteps()
                WDocumentProperties.instance().disableAdapters()
                WDocumentProperties.instance().disableLibraries()
            else:
                WDocumentProperties.instance().addSteps(wdoc=wdocument)
                WDocumentProperties.instance().enableSteps()
                WDocumentProperties.instance().addAdapters(wdoc=wdocument)
                WDocumentProperties.instance().enableAdapters()
                WDocumentProperties.instance().addLibraries(wdoc=wdocument)
                WDocumentProperties.instance().enableLibraries()

            if isinstance(wdocument, TestUnit.WTestUnit) or isinstance(
                    wdocument, TestSuite.WTestSuite):
                WDocumentProperties.instance().enableMarkUnused()
            else:
                WDocumentProperties.instance().disableMarkUnused()

        # disable/enable status bar
        if isinstance(wdocument, TestConfig.WTestConfig) \
                or isinstance(wdocument, TestPlan.WTestPlan) \
                or isinstance(wdocument, TestPng.WTestPng) \
                or  isinstance(wdocument, TestAbstract.WTestAbstract) \
                or isinstance(wdocument, WDocumentViewer.WelcomePage) :
            self.hideStatusBar()
        else:
            self.showStatusBar()
            self.wCursorPosition.setNumberLines(nb=wdocument.editor().lines())

    def propertiesChanged(self, properties, isRoot, testId):
        """
        Called when document propertis changed

        @param properties:
        @param properties: dict

        @param isRoot: 
        @type isRoot:
        """
        if isRoot:
            WDocumentProperties.instance().addDescriptions(wdoc=properties)
            WDocumentProperties.instance().addParameters(wdoc=properties)
            WDocumentProperties.instance().addParametersOutput(wdoc=properties)
            WDocumentProperties.instance().addAgents(wdoc=properties)
            WDocumentProperties.instance().addProbes(wdoc=properties)
            WDocumentProperties.instance().probes.setEnabled(True)
        else:
            WDocumentProperties.instance().addParameters(wdoc=properties)
            WDocumentProperties.instance().addAgents(wdoc=properties)
            WDocumentProperties.instance().addParametersOutput(wdoc=properties)
            WDocumentProperties.instance().probes.clear()
            WDocumentProperties.instance().probes.setEnabled(False)

        # new in v19
        WDocumentProperties.instance().updateCache(properties, isRoot, testId)

    def documentOpened(self, wdocument):
        """
        Called when a document is opened

        @param wdocument:
        @type wdocument:
        """
        WDocumentProperties.instance().setEnabled(True)
        self.currentDocumentChanged(wdocument=wdocument)

    def updateWindowTitle(self, windowTitle):
        """
        Emit the signal "updateWindowTitle" to update 
        the title of the application

        @param windowTitle: new window title
        @type windowTitle: string
        """
        self.UpdateWindowTitle.emit(windowTitle)

    def recentFileUpdated(self, fileDescription):
        """
        Emit the signal "recentFile" to update 
        the title of the application

        @param windowTitle: file descr with the complete path and type
        @type windowTitle: string
        """
        self.RecentFile.emit(fileDescription)

    def focusChanged(self, wdocument):
        """
        Called when the focus of the WDocumentViewer is changed

        @param wdocument:
        @type wdocument:
        """
        WDocumentViewer.instance().updateActions(wdocument=wdocument)
        self.wCursorPosition.setNumberLines(nb=wdocument.editor().lines())

    def totalLinesChanged(self, nb):
        """
        This function is automaticaly called when the cursor changed in both editors
        and enables to update the cursor's position in the widget WCursorPosition

        @param ln: line index
        @type ln: Integer
        
        @param col: column index
        @type col: Integer
        """
        self.wCursorPosition.setNumberLines(nb=nb)

    def cursorPositionChanged(self, ln, col):
        """
        This function is automaticaly called when the cursor changed in both editors
        and enables to update the cursor's position in the widget WCursorPosition

        @param ln: line index
        @type ln: Integer
        
        @param col: column index
        @type col: Integer
        """
        self.wCursorPosition.cursorPositionChanged(ln, col)

    def showStatusBar(self):
        """
        Show WCursorPosition widget
        """
        self.wCursorPosition.show()

    def hideStatusBar(self):
        """
        Hide WCursorPosition widget
        """
        self.wCursorPosition.hide()
Esempio n. 34
0
class EntryView(BaseView):
    def _setup(self):
        self._setupUi()
        self.etable = EntryTable(self.model.etable, view=self.tableView)
        self.efbar = EntryFilterBar(model=self.model.filter_bar, view=self.filterBar)
        self.bgraph = Chart(self.model.bargraph, view=self.barGraphView)
        self.lgraph = Chart(self.model.balgraph, view=self.lineGraphView)
        self._setupColumns() # Can only be done after the model has been connected
        
        self.reconciliationButton.clicked.connect(self.model.toggle_reconciliation_mode)
    
    def _setupUi(self):
        self.resize(483, 423)
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setMargin(0)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setSpacing(0)
        self.filterBar = RadioBox(self)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.filterBar.sizePolicy().hasHeightForWidth())
        self.filterBar.setSizePolicy(sizePolicy)
        self.horizontalLayout.addWidget(self.filterBar)
        self.horizontalLayout.addItem(horizontalSpacer())
        self.reconciliationButton = QPushButton(tr("Reconciliation"))
        self.reconciliationButton.setCheckable(True)
        self.horizontalLayout.addWidget(self.reconciliationButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.splitterView = QSplitter()
        self.splitterView.setOrientation(Qt.Vertical)
        self.splitterView.setChildrenCollapsible(False)
        self.tableView = TableView(self)
        self.tableView.setAcceptDrops(True)
        self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.EditKeyPressed)
        self.tableView.setDragEnabled(True)
        self.tableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setSortingEnabled(True)
        self.tableView.horizontalHeader().setHighlightSections(False)
        self.tableView.horizontalHeader().setMinimumSectionSize(18)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.splitterView.addWidget(self.tableView)
        self.graphView = QStackedWidget(self)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.graphView.sizePolicy().hasHeightForWidth())
        self.graphView.setSizePolicy(sizePolicy)
        self.graphView.setMinimumSize(0, 200)
        self.lineGraphView = LineGraphView()
        self.graphView.addWidget(self.lineGraphView)
        self.barGraphView = BarGraphView()
        self.graphView.addWidget(self.barGraphView)
        self.splitterView.addWidget(self.graphView)
        self.graphView.setCurrentIndex(1)
        self.splitterView.setStretchFactor(0, 1)
        self.splitterView.setStretchFactor(1, 0)
        self.verticalLayout.addWidget(self.splitterView)
    
    def _setupColumns(self):
        h = self.tableView.horizontalHeader()
        h.setMovable(True) # column drag & drop reorder
    
    #--- QWidget override
    def setFocus(self):
        self.etable.view.setFocus()
    
    #--- Public
    def fitViewsForPrint(self, viewPrinter):
        hidden = self.model.mainwindow.hidden_areas
        viewPrinter.fitTable(self.etable)
        if PaneArea.BottomGraph not in hidden:
            viewPrinter.fit(self.graphView.currentWidget(), 300, 150, expandH=True, expandV=True)
    
    def restoreSubviewsSize(self):
        graphHeight = self.model.graph_height_to_restore
        if graphHeight:
            splitterHeight = self.splitterView.height()
            sizes = [splitterHeight-graphHeight, graphHeight]
            self.splitterView.setSizes(sizes)
    
    #--- model --> view
    def refresh_reconciliation_button(self):
        if self.model.can_toggle_reconciliation_mode:
            self.reconciliationButton.setEnabled(True)
            self.reconciliationButton.setChecked(self.model.reconciliation_mode)
        else:
            self.reconciliationButton.setEnabled(False)
            self.reconciliationButton.setChecked(False)
    
    def show_bar_graph(self):
        self.graphView.setCurrentIndex(1)
    
    def show_line_graph(self):
        self.graphView.setCurrentIndex(0)
    
    def update_visibility(self):
        hidden = self.model.mainwindow.hidden_areas
        self.graphView.setHidden(PaneArea.BottomGraph in hidden)
Esempio n. 35
0
class MainWindow(QWidget, MainWindowGeneric):
    def __init__(self, parent):
        QWidget.__init__(self)
        MainWindowGeneric.__init__(self)
        self._parent = parent
        self.settings = QSettings("NINJA-IDE", "Kunai")

        self.settings.beginGroup("Preferences")
        self.settings.beginGroup("Interface")

        self._vbox = QVBoxLayout(self)
        # Splitters
        self.splitterMain = QSplitter()
        self.splitterCentral = QSplitter(Qt.Vertical)
        # Properties Panel
        self._properties = PropertiesWidget(self)
        # Central
        self._central = CentralWidget(self)
        self.show_start_page()
        self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], self._central)
        # Display Container
        self.container = DisplayContainer(self)
        self._hide_container()
        self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], self.container)
        height = [(self.height() / 3) * 2, self.height() / 3]
        self.splitterCentral.setSizes(
            [
                height[self.settings.value("central_tab_position", 0).toInt()[0]],
                height[self.settings.value("container_tab_position", 1).toInt()[0]],
            ]
        )
        # Size Central Splitter
        self.splitterMain.insertWidget(self.settings.value("main_tab_position", 0).toInt()[0], self.splitterCentral)
        self.splitterMain.insertWidget(self.settings.value("properties_tab_position", 1).toInt()[0], self._properties)
        width = [(self.width() / 6) * 5, self.width() / 6]
        self.splitterMain.setSizes(
            [
                width[self.settings.value("main_tab_position", 0).toInt()[0]],
                width[self.settings.value("properties_tab_position", 1).toInt()[0]],
            ]
        )
        self._vbox.addWidget(self.splitterMain)

        self.settings.endGroup()  # End General Preferences
        self.settings.endGroup()

        # flag for reload_file
        self._reloading = False

        # Shortcuts
        shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self)
        shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self)
        shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self)
        shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self)
        shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self)
        shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self)
        shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self)
        shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self)
        shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self)
        shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self)
        shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self)
        shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self)
        shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self)
        shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self)
        shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self)
        shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self)
        shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self)
        shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self)
        shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self)
        shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self)
        shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self)
        shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self)
        shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self)
        # Signal -> Slot
        self.connect(shortCloseTab, SIGNAL("activated()"), self.close_actual_tab)
        self.connect(shortNew, SIGNAL("activated()"), self.new_editor)
        self.connect(shortNewProject, SIGNAL("activated()"), self.new_project)
        self.connect(shortOpen, SIGNAL("activated()"), self.open_file)
        self.connect(shortOpenProject, SIGNAL("activated()"), self.open_project_folder)
        self.connect(shortSave, SIGNAL("activated()"), self.save)
        self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project)
        self.connect(shortComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().comment())
        self.connect(shortIndentLess, SIGNAL("activated()"), lambda: self._central.obtain_editor().indent_less())
        self.connect(
            shortHorizontalLine, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_horizontal_line()
        )
        self.connect(shortRedo, SIGNAL("activated()"), lambda: self._central.obtain_editor().redo())
        self.connect(shortHideContainer, SIGNAL("activated()"), self._hide_container)
        self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor)
        self.connect(shortHideExplorer, SIGNAL("activated()"), self._hide_explorer)
        self.connect(shortRunFile, SIGNAL("activated()"), self._run_code)
        self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program)
        self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all)
        self.connect(shortFind, SIGNAL("activated()"), self._open_find)
        self.connect(shortFindReplace, SIGNAL("activated()"), self._open_find_replace)
        self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc)
        self.connect(shortSplitHorizontal, SIGNAL("activated()"), lambda: self.split_tab(True))
        self.connect(shortSplitVertical, SIGNAL("activated()"), lambda: self.split_tab(False))
        self.connect(shortReloadFile, SIGNAL("activated()"), lambda: self.reload_file())

    def change_window_title(self, title):
        self._parent.setWindowTitle("NINJA-IDE - " + title)

    def _open_find(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.focus_find(self._central.obtain_editor())

    def _open_find_replace(self):
        if not self._parent._status.isVisible():
            self._parent._status.show()
        self._parent._status.replace_visibility(True)
        self._parent._status.focus_find(self._central.obtain_editor())

    def _hide_container(self):
        if self.containerIsVisible:
            self.container.hide()
            self.containerIsVisible = False
            self._central.obtain_editor().setFocus()
        else:
            self.container.show()
            self.containerIsVisible = True
            self.container.gain_focus()

    def _hide_editor(self):
        if self._central.isVisible():
            self._central.hide()
        else:
            self._central.show()

    def _hide_explorer(self):
        if self._properties.isVisible():
            self._properties.hide()
        else:
            self._properties.show()

    def _splitter_central_orientation(self):
        if self.splitterCentral.orientation() == Qt.Horizontal:
            self.splitterCentral.setOrientation(Qt.Vertical)
        else:
            self.splitterCentral.setOrientation(Qt.Horizontal)

    def get_splitter_central_orientation(self):
        return self.splitterCentral.orientation()

    def _splitter_main_orientation(self):
        if self.splitterMain.orientation() == Qt.Horizontal:
            self.splitterMain.setOrientation(Qt.Vertical)
        else:
            self.splitterMain.setOrientation(Qt.Horizontal)

    def get_splitter_main_orientation(self):
        return self.splitterMain.orientation()

    def _splitter_main_rotate(self):
        w = self.splitterMain.widget(0)
        w1 = self.splitterMain.widget(1)
        self.splitterMain.insertWidget(0, w1)
        self.splitterMain.insertWidget(1, w)

    def get_splitter_main_position(self):
        w = self.splitterMain.widget(0)
        return w.__class__

    def _splitter_central_rotate(self):
        w = self.splitterCentral.widget(0)
        w1 = self.splitterCentral.widget(1)
        self.splitterCentral.insertWidget(0, w1)
        self.splitterCentral.insertWidget(1, w)

    def get_splitter_central_position(self):
        w = self.splitterCentral.widget(0)
        return w.__class__

    def get_splitter_position_0(self):
        return type(self.splitterCentral.widget(0))

    def get_splitter_main_position_0(self):
        return type(self.splitterMain.widget(0))

    def reload_panels_position(self):
        self.settings = QSettings("NINJA-IDE", "Kunai")

        self.settings.beginGroup("Preferences")
        self.settings.beginGroup("Interface")

        # first with the splitterCentral
        c = self.splitterCentral.widget(0)
        c1 = self.splitterCentral.widget(1)
        if type(c) == CentralWidget:
            self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], c)
            self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], c1)
        else:
            self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], c1)
            self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], c)
        # now with the splitterMain
        m = self.splitterMain.widget(0)
        m1 = self.splitterMain.widget(1)
        if type(m) == QSplitter:
            self.splitterMain.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], m)
            self.splitterMain.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], m1)
        else:
            self.splitterMain.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], m1)
            self.splitterMain.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], m)

    def get_open_projects(self):
        return self._properties._treeProjects.get_open_projects()

    def _run_code(self):
        if self.save():
            self.container.show()
            self.containerIsVisible = True
            editor = self._central.obtain_editor()
            ext = self.get_file_extension(editor.path)
            if ext == "html":
                height = self.height() / 3
                self.splitterCentral.setSizes([height, height * 2])
                self.container.render_web_page(editor.path)
            elif ext == "py":
                height = self.height() / 3
                self.splitterCentral.setSizes([height * 2, height])
                self.container.run_application(editor.path)
            else:
                self.execute_file(editor.path, ext)

    def _run_program(self, actual=None):
        self.container.show()
        self.containerIsVisible = True
        if actual is None:
            actual = self._properties._treeProjects.actualProject
        if actual is None:
            return
        mainFile = actual.mainFile
        if mainFile == "":
            self._properties._treeProjects.open_project_properties()
            self.containerIsVisible = False
            self.container.hide()
            return
        path = manage_files.create_abs_path(actual.path, mainFile)
        self._central.save_project_files(actual.path)
        lang = actual.lang()
        type_ = actual.projectType
        if lang == "html":
            height = self.height() / 3
            self.splitterCentral.setSizes([height, height * 2])
            self.container.render_web_page(path)
        elif lang == "py":
            height = self.height() / 3
            self.splitterCentral.setSizes([height * 2, height])
            self.container.run_application(path)
        else:
            self.execute_program(path, lang, type_)

    def _stop_program(self):
        self.container.kill_application()

    def _hide_all(self):
        if self._properties.isVisible():
            self._properties.hide()
            self.container.hide()
            self._parent._toolbar.hide()
        else:
            if self.containerIsVisible:
                self.container.show()
            self._properties.show()
            self._parent._toolbar.show()

    def show_start_page(self):
        startPage = Browser(resources.start_page_url)
        self.add_tab(startPage, "Start Page")

    def show_report_bugs(self):
        bugsPage = Browser(resources.bugs_page)
        self.add_tab(bugsPage, "Report Bugs!")

    def _show_python_doc(self):
        process = runner.start_pydoc()
        docPage = Browser(process[1], process[0])
        self.add_tab(docPage, "Python Documentation")

    def new_editor(self, lang="py"):
        if not self._reloading:
            editor = factory_editor(lang, self._central.actual_tab())
            self.add_tab(editor, "New Document")

    def add_tab(self, component, title):
        self._central.actual_tab().add_tab(component, title)

    def split_tab(self, option):
        if option:
            self._central.show_split(Qt.Horizontal)
        else:
            self._central.show_split(Qt.Vertical)

    def new_project(self):
        project = WizardNewProject(self)
        project.show()

    def show_preferences(self):
        prefs = PreferencesWindow(self)
        prefs.show()

    def open_document(self, fileName, project=None):
        try:
            if not self._central.actual_tab().is_open(fileName):
                self._central.actual_tab().notOpening = False
                editor = factory_editor(fileName, self._central.actual_tab(), project)
                content = self.read_file_content(fileName)
                editor.setPlainText(content)
                editor.path = fileName
                editor.ask_if_externally_modified = True
                # self.add_tab(editor, self.get_file_name(fileName))
                if not editor.has_write_permission():
                    fileName += " (Read-Only)"
                self.add_tab(editor, self.get_file_name(fileName))
                self.change_window_title(fileName)
            else:
                self._central.actual_tab().move_to_open(fileName)
        except Exception, reason:
            print reason
            QMessageBox.information(self, "Incorrect File", "The file couldn't be open")
        self._central.actual_tab().notOpening = True
Esempio n. 36
0
class PlotWidgetContainer(QWidget):
    def __init__(self, modelRoot, *args, **kwargs):

        super(PlotWidgetContainer, self).__init__(*args)
        self.modelRoot = modelRoot
        if len(moose.wildcardFind(modelRoot + "/##[ISA=ChemCompt]")) == 0:
            self.modelType = ELECTRICAL
        else:
            self.modelType = CHEMICAL

        self.model = moose.element(self.modelRoot)
        if self.modelRoot != "/":
            if moose.exists(modelRoot + "/data"):
                self.data = moose.element(self.modelRoot + "/data")
            else:
                self.data = moose.Neutral(self.modelRoot + "/data")

        else:
            self.data = moose.element("/data")

        self._layout = QVBoxLayout()
        self.graphs = QSplitter()
        self.graphs.setOrientation(PyQt4.QtCore.Qt.Vertical)
        self.graphsArea = QScrollArea()
        # self.graphsLayout   = QGridLayout()
        # self.menubar        = self.createMenuBar()
        self.rowIndex = 0
        # self.setSizePolicy( QtGui.QSizePolicy.Expanding
        #                   , QtGui.QSizePolicy.Expanding
        #                   )

        self.graphs.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                  QtGui.QSizePolicy.Expanding)
        self.setAcceptDrops(True)
        # self._layout.setSizeConstraint( QLayout.SetNoConstraint )
        # self.graphs.setLayout(self.graphsLayout)
        self.graphsArea.setWidget(self.graphs)
        self.graphsArea.setWidgetResizable(True)
        self.graphWidgets = []
        # self._layout.addWidget(self.menubar)
        self._layout.addWidget(self.graphsArea)
        self.setLayout(self._layout)

        for graph in self.data.children:
            self.addPlotWidget(graph=graph)

        if len(self.data.children) == 0:
            self.addPlotWidget()

    def deleteWidget(self, graphWidget):
        # print("Deleted => ", graphWidget)
        self.graphWidgets.remove(graphWidget)
        graphWidget.setParent(None)
        graphWidget.close()

    def createMenuBar(self):
        bar = sidebar.sidebar()
        bar.addAction(
            sidebar.add_graph_action(bar, lambda event: self.addPlotWidget()))
        # bar.addAction(sidebar.delete_graph_action(bar, lambda event: self.addPlotWidget() ))
        # bar.addAction(sidebar.list_action(bar, self.showPlotView))
        return bar

    def addPlotWidget(self, row=None, col=0, graph=None):
        if graph == None:
            graph = moose.Neutral(self.data.path + "/graph_" +
                                  str(self.rowIndex))
        widget = default.PlotWidget(self.model, graph, self.rowIndex, self)

        if self.modelType == ELECTRICAL:
            for axes in widget.canvas.axes.values():
                # axes.autoscale(False, axis='x', tight=True)
                axes.set_ylim(bottom=-0.07, top=0.03)

        if row == None:
            row = self.rowIndex
        self.graphs.addWidget(widget)
        self.rowIndex += 1
        self.graphWidgets.append(widget)
        widget.widgetClosedSignal.connect(self.deleteWidget)
        widget.addGraph.connect(lambda event: self.addPlotWidget())
        # widget.resize(1, 1);
        return widget

    def showPlotView(self):
        pass

    def setModelRoot(self, *args):
        pass

    def getMenus(self, *args):
        return []

    def setDataRoot(self, *args):
        pass

    def updatePlots(self):
        self.apply(lambda obj: obj.updatePlots())

    def rescalePlots(self):
        self.apply(lambda obj: obj.rescalePlots())

    def extendXAxes(self, xlim):
        self.apply(lambda obj: obj.extendXAxes(xlim))

    def plotAllData(self):
        self.apply(lambda obj: obj.plotAllData())

    def apply(self, f):
        for graphWidget in self.graphWidgets:
            f(graphWidget)
Esempio n. 37
0
class DSBrowser(QWidget):
    """browser for datastorage databases
       Nodes are identified by a string, containing fields separated by '|'.
       - first filed is a capital letter:
       'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart
       - second field is the database folder
       - third filed is the path of the node in the database
       - for charts the fourth field is the chart name (third is path of sensorgroup in this case)
    """
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(0)
        self.layout.setMargin(0)

        self.toolBar = QFrame(self)
        self.toolBarLayout = QHBoxLayout(self.toolBar)
        self.toolBarLayout.setMargin(2)
        self.toolBarLayout.setSpacing(2)
        self.layout.addWidget(self.toolBar)

        self.loadButton = QToolButton(self.toolBar)
        self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...'))
        self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen)))
        self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database'))
        self.toolBarLayout.addWidget(self.loadButton)
        self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase)

        self.expandButton = QToolButton(self.toolBar)
        self.expandButton.setText('Expand/Collapse')
        self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col)))
        self.expandButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Expand or collapse the whole tree'))
        self.toolBarLayout.addWidget(self.expandButton)
        self.connect(self.expandButton, SIGNAL('pressed()'), self.expandCollapseAll)

        self.searchInput = QLineEdit(self.toolBar)
        self.searchInput.setText(QCoreApplication.translate('DataStorageBrowser', 'Enter search text here'))
        self.searchInput.setToolTip(QCoreApplication.translate('DataStorageBrowser',
            'Enter search text using wildcards here, press ENTER again to go to next match!'))
        self.toolBarLayout.addWidget(self.searchInput, 100)
        self.connect(self.searchInput, SIGNAL('returnPressed()'), self.searchItem)

        self.helpButton = QToolButton(self.toolBar)
        self.helpButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Help'))
        self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help)))
        self.helpButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Show help for DataStorageBrowser'))
        self.toolBarLayout.addWidget(self.helpButton)
        self.connect(self.helpButton, SIGNAL('pressed()'), self.showHelp)

        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Vertical)
        self.treeView = QTreeView(self.splitter)
        self.treeView.setAlternatingRowColors(True)
        self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeView.setAutoExpandDelay(500)
        self.textBrowser = QTextBrowser(self.splitter)
        self.layout.addWidget(self.splitter)
        self.splitter.setStretchFactor(0, 60)
        self.splitter.setStretchFactor(1, 40)
        self.model = DSModel()
        self.treeView.setModel(self.model)
        self.treeView.setSortingEnabled(True)
        self.treeView.expandAll()
        self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem)
        self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction)
        self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu)
        self.selectedNode = None
        self.selectedMI = None
        self.searchText = ''
        self.searchResults = []
        self.collExpand = SimuVis4.Misc.Switcher()


    def loadDatabase(self, dn=None):
        """load a database"""
        if not dn:
            dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser',
                "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder)
            if not dn.isEmpty():
                dn = unicode(dn)
                SimuVis4.Globals.defaultFolder = dn
            else:
                return
        self.model.addDatabase(dn)
        self.treeView.expandToDepth(1)
        self.treeView.resizeColumnToContents(0)


    def showHelp(self):
        SimuVis4.HelpBrowser.showHelp('/plugin/DataStorageBrowser/index.html')


    def showItem(self, mi, pr):
        """show the item at model index mi"""
        t, n = self.model.dsNode(mi)
        txt = ""
        if t == 'R':
            # FIXME: no metadata?
            txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir,
                projects=len(n)) + formatMetaData(n)
        elif t == 'P':
            txt = projectInfo.substitute(name=n.name, path=escape(n.parent.name),
                title=escape(n.title), groups=len(n)) + formatMetaData(n)
        elif t == 'G':
            txt = groupInfo.substitute(name=n.name,  path='/'.join(n.path.split('/')[:-1]),
                title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n)
        elif t == 'S':
            txt = sensorInfo.substitute(name=n.name,  path='/'.join(n.path.split('/')[:-1]),
                title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop,
                step=n.timegrid.step, length=n.datalen()) + formatMetaData(n)
        elif t == 'C':
            txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path)
        self.textBrowser.setText(txt)


    def searchItem(self):
        """execute the search and highlight the (next) result"""
        txt = str(self.searchInput.text())
        if txt != self.searchText:
            self.searchText = txt
            tmp = self.model.findItems(txt,
                Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive)
            self.searchList = [i.index() for i in tmp]
        if self.searchList:
            mi = self.searchList.pop()
            self.treeView.setCurrentIndex(mi)
            self.treeView.expand(mi)
            self.treeView.scrollTo(mi)
        else:
            QMessageBox.information(self, QCoreApplication.translate('DataStorageBrowser',
                'No (more) matches!'), QCoreApplication.translate('DataStorageBrowser',
                'No (more) matches found! Change you search criteria and try again!'))
            self.searchText = ''


    def expandCollapseAll(self):
        if self.collExpand():
            self.treeView.collapseAll()
        else:
            self.treeView.expandAll()

    def itemAction(self, mi):
        """default action (on doubleclick) for item at model index mi"""
        t, n = self.model.dsNode(mi)
        if t == 'R':
            pass
        elif t == 'P':
            pass
        elif t == 'G':
            pass
        elif t == 'S':
            self.showQwtPlot(n)
        elif t == 'C':
            self.showMplChart(n)


    def showContextMenu(self, pos):
        """show context menu for item at pos"""
        mi = self.treeView.indexAt(pos)
        t, n = self.model.dsNode(mi)
        self.selectedNode = n
        self.selectedMI = mi
        m = QMenu()
        if t == 'R':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Close'), self.closeDatabase)
        elif t == 'P':
            pass
        elif t == 'G':
            nCharts = len(n.charts)
            if nCharts > 0:
                txt = str(QCoreApplication.translate('DataStorageBrowser', 'Show all Charts (%d)')) % nCharts
                m.addAction(txt, self.showAllCharts)
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart)
        elif t == 'S':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot)
        elif t == 'C':
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart)
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem)
        if t in 'RPGS':
            m.addSeparator()
            m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata)
        a = m.exec_(self.treeView.mapToGlobal(pos))


    def showMplChart(self, node=None):
        if node is None:
            node = self.selectedNode
        showChartMplWindow(node, maximized=showChartMaximized)


    def showAllCharts(self, node=None):
        if node is None:
            node = self.selectedNode
        for chart in node.charts.values():
            showChartMplWindow(chart, maximized=showChartMaximized)


    def showQwtPlot(self, node=None):
        if node is None:
            node = self.selectedNode
        showQwtPlotWindow(node, maximized=showChartMaximized)


    def editMetadata(self, node=None):
        if node is None:
            node = self.selectedNode
        editMetadata(node)


    def closeDatabase(self, mi=None):
        if mi is None:
            mi = self.selectedMI
        self.model.closeDatabase(mi)


    def newChart(self, mi=None):
        """add a chart to sensorgroup at mi using the wizard"""
        if mi is None:
            mi = self.selectedMI
        showNewChartWizard(self.model, mi)


    def deleteItem(self, mi=None):
        """delete the item at mi"""
        if mi is None:
            mi = self.selectedMI
        self.model.deleteItem(mi)
Esempio n. 38
0
class PythonConsoleWidget(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        ##------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        #self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        #self.splitterObj.setSizes([0, 0])
        #self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        #self.splitterEditor.addWidget(self.widgetEditor)
        #self.splitterObj.addWidget(self.listClassMethod)
        #self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        ##----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        ##------------------Toolbar Editor-------------------------------------

        ## Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open file")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in external editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        ## Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        ## Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        ## Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCutEditorConsole.png"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        ## Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        ## Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        ## Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        ## Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        ## Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        ## Action for Object browser
        objList = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp",
                                                             False, type=bool))
        self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        ## Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        ##----------------Toolbar Console-------------------------------------

        ## Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        ## Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        ## Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Settings")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        ## Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        ## Import Processing class
        loadProcessingBt = QCoreApplication.translate("PythonConsole", "Import Processing class")
        self.loadProcessingButton = QAction(self)
        self.loadProcessingButton.setCheckable(False)
        self.loadProcessingButton.setEnabled(True)
        self.loadProcessingButton.setIcon(QgsApplication.getThemeIcon("console/iconProcessingConsole.png"))
        self.loadProcessingButton.setMenuRole(QAction.PreferencesRole)
        self.loadProcessingButton.setIconVisibleInMenu(True)
        self.loadProcessingButton.setToolTip(loadProcessingBt)
        self.loadProcessingButton.setText(loadProcessingBt)
        ## Import QtCore class
        loadQtCoreBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore class")
        self.loadQtCoreButton = QAction(self)
        self.loadQtCoreButton.setCheckable(False)
        self.loadQtCoreButton.setEnabled(True)
        self.loadQtCoreButton.setIcon(QgsApplication.getThemeIcon("console/iconQtCoreConsole.png"))
        self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtCoreButton.setIconVisibleInMenu(True)
        self.loadQtCoreButton.setToolTip(loadQtCoreBt)
        self.loadQtCoreButton.setText(loadQtCoreBt)
        ## Import QtGui class
        loadQtGuiBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui class")
        self.loadQtGuiButton = QAction(self)
        self.loadQtGuiButton.setCheckable(False)
        self.loadQtGuiButton.setEnabled(True)
        self.loadQtGuiButton.setIcon(QgsApplication.getThemeIcon("console/iconQtGuiConsole.png"))
        self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtGuiButton.setIconVisibleInMenu(True)
        self.loadQtGuiButton.setToolTip(loadQtGuiBt)
        self.loadQtGuiButton.setText(loadQtGuiBt)
        ## Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        ## Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        ## Menu Import Class
        self.classMenu = QMenu()
        self.classMenu.addAction(self.loadProcessingButton)
        self.classMenu.addAction(self.loadQtCoreButton)
        self.classMenu.addAction(self.loadQtGuiButton)
        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        ##------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        ## Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...")

        if pyqtconfig.Configuration().qt_version >= 0x40700:
            self.lineEditFind.setPlaceholderText(placeHolderTxt)
        else:
            self.lineEditFind.setToolTip(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        ##------------ Add first Tab in Editor -------------------------------

        #self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        ##------------ Signal -------------------------------

        self.findTextButton.toggled.connect(self.findTextEditor)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.loadProcessingButton.triggered.connect(self.processing)
        self.loadQtCoreButton.triggered.connect(self.qtCore)
        self.loadQtGuiButton.triggered.connect(self.qtGui)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.connect(self.listClassMethod, SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
                     self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findText)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

    def _findText(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def processing(self):
        self.shell.commandConsole('processing')

    def qtCore(self):
        self.shell.commandConsole('qtCore')

    def qtGui(self):
        self.shell.commandConsole('qtGui')

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def findTextEditor(self, checked):
        self.widgetFind.show() if checked else self.widgetFind.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate('PythonConsole',
                                                 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                              error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath", QDir.home())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As")
        filename = QFileDialog.getSaveFileName(self,
                                               saveAsFileTr,
                                               pathFileName, "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate('PythonConsole',
                                                     'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                                  error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelp(self):
        QgsContextHelp.run("PythonConsole")

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts",
                               self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
Esempio n. 39
0
class Ui_dev_client(object):
    def setupUi(self, dev_client):
        dev_client.resize(935, 660)
        dev_client.setWindowTitle(QApplication.translate("dev_client", "DevClient"))

        self.centralwidget = QWidget(dev_client)
        dev_client.setCentralWidget(self.centralwidget)

        main_layout = QGridLayout(self.centralwidget)
        main_layout.setContentsMargins(5, 5, 5, 3)
        main_layout.setSpacing(3)
        main_layout.setColumnStretch(0, 1)
        main_layout.setRowStretch(1, 1)

        top_layout = QHBoxLayout()
        top_layout.setContentsMargins(0, 0, 0, 0)
        top_layout.setSpacing(5)

        top_label_conn = QLabel()
        top_label_conn.setText(QApplication.translate("dev_client", "Connection"))
        top_layout.addWidget(top_label_conn)

        self.list_conn = QComboBox()
        self.list_conn.setFixedSize(145, 26)
        self.list_conn.setFocusPolicy(Qt.NoFocus)
        top_layout.addWidget(self.list_conn)

        self.list_account = QComboBox()
        self.list_account.setFixedSize(145, 26)
        self.list_account.setFocusPolicy(Qt.NoFocus)
        top_layout.addWidget(self.list_account)

        top_layout.addItem(QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
        top_label_account = QLabel()
        top_label_account.setText(QApplication.translate("dev_client", "Account"))
        top_layout.addWidget(top_label_account)

        self.button_connect = QPushButton()
        self.button_connect.setFixedSize(105, 26)
        self.button_connect.setFocusPolicy(Qt.NoFocus)
        self.button_connect.setIcon(QIcon(":/images/connect.png"))
        self.button_connect.setIconSize(QSize(16, 16))
        self.button_connect.setText(QApplication.translate("dev_client", "Connect"))
        top_layout.addWidget(self.button_connect)

        self.button_option = QPushButton()
        self.button_option.setFixedSize(105, 26)
        self.button_option.setFocusPolicy(Qt.NoFocus)
        self.button_option.setIcon(QIcon(":/images/option.png"))
        self.button_option.setIconSize(QSize(16, 16))
        self.button_option.setText(QApplication.translate("dev_client", "Option"))
        top_layout.addWidget(self.button_option)
        main_layout.addLayout(top_layout, 0, 0)

        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.addItem(QSpacerItem(40, 29, QSizePolicy.Minimum, QSizePolicy.Fixed))

        self.rightpanel = QWidget()
        self.rightpanel.setMinimumWidth(225)
        right_layout.addWidget(self.rightpanel)
        main_layout.addLayout(right_layout, 0, 1, 3, 1)

        self.output_splitter = QSplitter(self.centralwidget)
        self.output_splitter.setOrientation(Qt.Vertical)
        self.output_splitter.setHandleWidth(3)
        self.output_splitter.setChildrenCollapsible(False)

        self.text_output = QTextEdit(self.output_splitter)
        self.text_output.setMinimumWidth(690)
        self.text_output.setFocusPolicy(Qt.NoFocus)
        self.text_output.setAutoFillBackground(True)
        self.text_output.setUndoRedoEnabled(False)
        self.text_output.setReadOnly(True)

        self.text_output_noscroll = QTextEdit(self.output_splitter)
        self.text_output_noscroll.setMinimumWidth(690)
        self.text_output_noscroll.setFocusPolicy(Qt.NoFocus)
        self.text_output_noscroll.setAutoFillBackground(True)
        self.text_output_noscroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.text_output_noscroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.text_output_noscroll.setUndoRedoEnabled(False)
        self.text_output_noscroll.setReadOnly(True)
        main_layout.addWidget(self.output_splitter, 1, 0)

        bottom_layout = QHBoxLayout()
        bottom_layout.setContentsMargins(0, 0, 0, 0)
        bottom_layout.setSpacing(5)

        self.text_input = QComboBox()
        self.text_input.setMinimumWidth(660)
        self.text_input.setFixedHeight(25)
        self.text_input.setEditable(True)
        self.text_input.addItem("")
        bottom_layout.addWidget(self.text_input)

        self.toggle_splitter = QPushButton()
        self.toggle_splitter.setFixedSize(25, 25)
        self.toggle_splitter.setFocusPolicy(Qt.NoFocus)
        self.toggle_splitter.setIcon(QIcon(":/images/split-window.png"))
        bottom_layout.addWidget(self.toggle_splitter)
        main_layout.addLayout(bottom_layout, 2, 0)