Example #1
0
 def createToolBar(self, title, name=""):
     """
     Public method to create a custom toolbar.
     
     @param title title to be used for the toolbar (string)
     @param name optional name for the new toolbar (string)
     @return reference to the created toolbar (QToolBar)
     """
     if self.__mainWindow is None:
         return None
     
     toolBar = QToolBar(title, self.__mainWindow)
     toolBar.setToolTip(title)
     if not name:
         index = 1
         customPrefix = "__CustomPrefix__"
         name = "{0}{1:d}".format(customPrefix, index)
         while self.__toolBarByName(name) is not None:
             index += 1
             name = "{0}{1:d}".format(customPrefix, index)
     toolBar.setObjectName(name)
     self.__mainWindow.addToolBar(toolBar)
     
     tbID = id(toolBar)
     self.__customToolBars.append(toolBar)
     self.__allToolBars[tbID] = toolBar
     self.__toolBars[tbID] = []
     self.__toolBarsWithSeparators[tbID] = []
     
     if self.__ui is not None:
         toolBar.setIconSize(self.__ui.getToolBarIconSize())
         self.__ui.registerToolbar(name, title, toolBar)
     
     return toolBar
Example #2
0
    def createToolBar(self, title, name=""):
        """
        Public method to create a custom toolbar.
        
        @param title title to be used for the toolbar (string)
        @param name optional name for the new toolbar (string)
        @return reference to the created toolbar (QToolBar)
        """
        if self.__mainWindow is None:
            return None

        toolBar = QToolBar(title, self.__mainWindow)
        toolBar.setToolTip(title)
        if not name:
            index = 1
            customPrefix = "__CustomPrefix__"
            name = "{0}{1:d}".format(customPrefix, index)
            while self.__toolBarByName(name) is not None:
                index += 1
                name = "{0}{1:d}".format(customPrefix, index)
        toolBar.setObjectName(name)
        self.__mainWindow.addToolBar(toolBar)

        tbID = id(toolBar)
        self.__customToolBars.append(toolBar)
        self.__allToolBars[tbID] = toolBar
        self.__toolBars[tbID] = []
        self.__toolBarsWithSeparators[tbID] = []

        if self.__ui is not None:
            toolBar.setIconSize(self.__ui.getToolBarIconSize())
            self.__ui.registerToolbar(name, title, toolBar)

        return toolBar
class BufferSelectToolbar(object):
    def __init__(self, selectTool):
        super(BufferSelectToolbar, self).__init__()
        # references
        self.selectTool = selectTool
        self.result = None
        self.debug = self.selectTool.debug
        self.id = id
        self.config = self.selectTool.config
        self.info = Info(self)
        try:
            self.gtomain = self.selectTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface
            self.canvas = self.iface.mapCanvas()
            # tool data
            self.toolbar_dock = self.config.get("toolbar_dock", 4)
            self.toolbar_height = self.gtomain.toolbar_height
            # widget
            self.toolbar = None
            # load toolbar
            objName = "gtoTB_" + __name__ + str(id)
            self.toolbar = self.gtomain.helper.findToolbar(self.iface, objName)
            if self.toolbar is None:
                if self.debug: self.info.log("load", objName)
                self.toolbar = QToolBar()
                self.toolbar.setObjectName(objName)
                self.toolbar.setWindowTitle(u'GTO Buffer Selection')
                self.toolbar.setAllowedAreas(Qt.BottomToolBarArea
                                             | Qt.TopToolBarArea)
                self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                # set the iconsize=> changed when self.iface.addToolBar :S
                if self.toolbar_height is not None:
                    self.toolbar.setMaximumHeight(self.gtomain.toolbar_height)
                    self.toolbar.setMinimumHeight(self.gtomain.toolbar_height)
            else:
                self.toolbar.clear()
            self.wid = Widget(self)
            self.toolbar.addWidget(self.wid)
            self.wid.setIconSizes(self.iface.iconSize(False))
            self.wid.geometry_changed.connect(self.getGeometry)
            self.toolbar.setHidden(False)
        except Exception as e:
            self.info.err(e)

    # from mActionbufferselectxy
    def setHidden(self, a0):
        self.toolbar.setHidden(a0)

    def setGeometry(self, geo, isValid, isCircle=False, isRectangle=False):
        self.toolbar.setHidden(False)
        if self.debug:
            self.info.log("setGeometry", geo.isEmpty(), isValid, isCircle,
                          isRectangle)
        self.wid.setOriginalGeometry(geo, isValid, isCircle, isRectangle)

    def getGeometry(self, geo):
        self.selectTool.setGeometryToMapTool(geo)
Example #4
0
    def init_menu(self):
        load_rom = self.create_action('載入Rom', self.load_rom)
        save_rom = self.create_action('保存Rom', self.save_rom)
        save_rom.setEnabled(False)
        save_as = self.create_action('另存為', self.save_as)
        save_as.setEnabled(False)
        close_child = self.create_action('關閉窗口', self.close_child)
        exit_editor = self.create_action('退出', self.close)
        file_menu = self.create_menu(
            '文件(&F)', None,
            [load_rom, save_rom, save_as, close_child, exit_editor])

        value_editors = [
            self.create_action(editor_name, self.open_editor_frame)
            for editor_name in CHILD_MAPPING
        ]

        edit_menu = self.create_menu('編輯(&E)', None, value_editors)
        edit_menu.setEnabled(False)

        self.menuBar().addMenu(file_menu)
        self.menuBar().addMenu(edit_menu)

        tool_bar = QToolBar('顯示標籤')
        tool_bar.setObjectName('工具')
        tool_bar.addActions(value_editors)
        tool_bar.setEnabled(False)
        tool_bar.setMovable(False)
        tool_bar.setVisible(False)
        self.addToolBar(tool_bar)

        action_group = QActionGroup(self)
        [(action_group.addAction(i), i.setCheckable(True))
         for i in value_editors]
        action_group.setExclusive(True)
Example #5
0
class run(QObject):  # gtoAction
    def __init__(self, id, gtoTool, config, debug):
        super(run, self).__init__()
        # references
        self.debug = debug
        self.id = id
        self.config = config
        self.info = gtoTool.info

        try:
            self.action = gtoTool.action
            self.action.setCheckable(True)
            self.gtomain = gtoTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface
            self.canvas = self.iface.mapCanvas()
            if not self.config.get("is_widgetaction", False):
                # tool data
                self.toolbar_dock = self.config.get("toolbar_dock", 4)
                # widget
                self.toolbar = None

                # load toolbar
                self.objName = "gtoTB_" + gtoTool.action.objectName() + str(id)
                self.toolbar = self.gtomain.helper.findToolbar(self.iface, self.objName)
                if self.toolbar is None:
                    if self.debug: self.info.log("load", self.objName)
                    self.toolbar = QToolBar()
                    self.toolbar.setObjectName(self.objName)
                    self.toolbar.setWindowTitle(u'GTO Coordinate')
                    self.toolbar.setAllowedAreas(Qt.BottomToolBarArea | Qt.TopToolBarArea)
                    self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                    self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                else:
                    self.toolbar.clear()
                self.wid = GTOPointWidget(self.gtomain, self.toolbar)
                self.toolbar.addWidget(self.wid)
                if self.config.get("spacer", False):
                    spacer = QWidget()
                    spacer.setObjectName('spacer')
                    spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                    spacer.setStyleSheet("QWidget{background: transparent;}")
                    self.toolbar.addWidget(spacer)
                self.wid.set_parent_widget(self)
                self.wid.isActive.connect(self.set_status)  # not always(?) working?
                self.wid.setConfig(self.config)
                self.wid.added()
                self.wid.setMapTool()
                self.toolbar.show()
        except Exception as e:
            self.info.err(e)

    def set_status(self, isActive):
        try:
            self.action.setChecked(isActive)
            self.toolbar.setHidden(not isActive)
        except Exception as e:
            self.info.err(e)
Example #6
0
    def setupModelBar(self):
        """
        Add a tool bar to the GUI for selecting which model to display 
        """

        leftToolBar = QToolBar()
        leftToolBar.setStyleSheet("background-color: rgb(60, 63, 65);")
        leftToolBar.setObjectName('lefttoolbar')

        leftToolBar.addWidget(self.modelButtonGroup())
        self.addToolBar(Qt.LeftToolBarArea, leftToolBar)
Example #7
0
 def create_button_panel(self, horizontal):
     toolbar = QToolBar()
     if horizontal:
         toolbar.setObjectName("button_panel")
     else:
         toolbar.setObjectName("toolbox")
     if horizontal:
         self.window.addToolBar(Qt.TopToolBarArea, toolbar)
     else:
         self.window.addToolBar(Qt.LeftToolBarArea, toolbar)
     return ButtonPanel(toolbar)
Example #8
0
 def gui(self):
     self.systray = QSystemTrayIcon()
     self.icon = QIcon(':/sansimera.png')
     self.systray.setIcon(self.icon)
     self.systray.setToolTip('Σαν σήμερα...')
     self.menu = QMenu()
     self.exitAction = QAction('&Έξοδος', self)
     self.refreshAction = QAction('&Ανανέωση', self)
     self.aboutAction = QAction('&Σχετικά', self)
     self.notification_interval = QAction('Ει&δοποίηση εορταζόντων', self)
     self.menu.addAction(self.notification_interval)
     self.menu.addAction(self.refreshAction)
     self.menu.addAction(self.aboutAction)
     self.menu.addAction(self.exitAction)
     self.systray.setContextMenu(self.menu)
     self.notification_interval.triggered.connect(self.interval_namedays)
     self.exitAction.triggered.connect(exit)
     self.refreshAction.triggered.connect(self.refresh)
     self.aboutAction.triggered.connect(self.about)
     self.browser = QTextBrowser()
     self.browser.setOpenExternalLinks(True)
     self.setGeometry(600, 500, 400, 300)
     self.setWindowIcon(self.icon)
     self.setWindowTitle('Σαν σήμερα...')
     self.setCentralWidget(self.browser)
     self.systray.show()
     self.systray.activated.connect(self.activate)
     self.browser.append('Λήψη...')
     nicon = QIcon(':/next')
     picon = QIcon(':/previous')
     ricon = QIcon(':/refresh')
     iicon = QIcon(':/info')
     qicon = QIcon(':/exit')
     inicon = QIcon(':/notifications')
     self.nextAction = QAction('Επόμενο', self)
     self.nextAction.setIcon(nicon)
     self.previousAction = QAction('Προηγούμενο', self)
     self.refreshAction.triggered.connect(self.refresh)
     self.nextAction.triggered.connect(self.nextItem)
     self.previousAction.triggered.connect(self.previousItem)
     self.previousAction.setIcon(picon)
     self.refreshAction.setIcon(ricon)
     self.exitAction.setIcon(qicon)
     self.aboutAction.setIcon(iicon)
     self.notification_interval.setIcon(inicon)
     controls = QToolBar()
     self.addToolBar(Qt.BottomToolBarArea, controls)
     controls.setObjectName('Controls')
     controls.addAction(self.previousAction)
     controls.addAction(self.nextAction)
     controls.addAction(self.refreshAction)
     self.restoreState(self.settings.value("MainWindow/State", QByteArray()))
     self.refresh()
class run(object):
    def __init__(self, id, gtoTool, config, debug):
        super(run, self).__init__()
        try:
            # references
            self.result = None
            self.debug = debug
            self.id = id
            self.config = config
            self.info = gtoTool.info
            self.gtomain = gtoTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface

            # tool data widegt
            self.toolbar_dock = self.config.get("toolbar_dock", None)
            # widget
            self.toolbar = None
            self.wid = Widget(self, self.iface.mainWindow())
            if self.toolbar_dock is not None:
                # load toolbar
                objName = "gtoTB_" + gtoTool.action.objectName()
                self.toolbar = self.gtomain.helper.findToolbar(
                    self.iface, objName)
                if self.toolbar is None:
                    if self.debug: self.info.log("load", objName)
                    self.toolbar = QToolBar()
                    self.toolbar.setObjectName(objName)
                    self.toolbar.setWindowTitle(u'GTO Suche')
                    self.toolbar.setAllowedAreas(Qt.BottomToolBarArea
                                                 | Qt.TopToolBarArea)
                    self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                    self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                else:
                    self.toolbar.clear()
                    self.toolbar.setHidden(False)
            else:
                self.toolbar = self.gtomain.gtotb
            self.toolbar.addWidget(self.wid)
            if self.config.get("show_hide_button", False):
                self.helper.addToolbarClose(self.toolbar)
            self.toolbar.visibilityChanged.connect(self.reset)
        except Exception as e:
            self.info.err(e)

    def reset(self, *args):  # from (gto)toolbar hidden/shown
        try:
            if self.debug: self.info.log("gtoAction reset")
            self.wid.reset()
        except Exception as e:
            self.info.err(e)
Example #10
0
    def init_bar(self) -> None:
        """
        Init function bar, set to right side of widget
        :return: 
        """
        toolbar = QToolBar()
        toolbar.setObjectName('MapToolbar')
        self.mainWindow.addToolBar(Qt.RightToolBarArea, toolbar)

        # ------------------------------- Open map ----------------------------------
        self.openMap_action = QAction(QIcon('resources/icons/openMap.png'), TR().tr('Open_map'), self.mainWindow,
                                      triggered=self.open_map_action, enabled=False)
        toolbar.addAction(self.openMap_action)

        # ------------------------------- Zoom in ----------------------------------
        self.zoomIn_action = QAction(QIcon('resources/icons/zoomIn.png'), TR().tr('Zoom_in'), self.mainWindow,
                                     triggered=self.zoom_in_action, shortcut='Ctrl++', enabled=False)
        toolbar.addAction(self.zoomIn_action)

        # ------------------------------- Zoom out ----------------------------------
        self.zoomOut_action = QAction(QIcon('resources/icons/zoomOut.png'), TR().tr('Zoom_out'), self.mainWindow,
                                      triggered=self.zoom_out_action, shortcut='Ctrl++', enabled=False)
        toolbar.addAction(self.zoomOut_action)

        # ------------------------------- Edit info  ----------------------------------
        self.info_action = QAction(QIcon('resources/icons/scroll.png'), TR().tr('Edit_info'), self.mainWindow,
                                   triggered=self.edit_info_action, shortcut='Ctrl+P', enabled=False)
        toolbar.addAction(self.info_action)

        toolbar.addSeparator()

        # ------------------------------- Add monster ----------------------------------
        self.addMonster_action = QAction(QIcon('resources/icons/addMonster.png'), TR().tr('Add_monster'), self.mainWindow,
                                         triggered=self.add_monster_action, shortcut='Ctrl+M', enabled=False)
        toolbar.addAction(self.addMonster_action)

        # ------------------------------- Add item ----------------------------------
        self.addItem_action = QAction(QIcon('resources/icons/addItem.png'), TR().tr('Add_item'), self.mainWindow,
                                      triggered=self.add_item_action, enabled=False)
        toolbar.addAction(self.addItem_action)

        # ------------------------------- Add room ----------------------------------
        self.addRoom_action = QAction(QIcon('resources/icons/addRoom.png'), TR().tr('Add_room'), self.mainWindow,
                                      triggered=self.add_room_action, enabled=False)
        toolbar.addAction(self.addRoom_action)

        # ------------------------------- Add object ----------------------------------
        self.addObject_action = QAction(QIcon('resources/icons/addObject.png'), TR().tr('Add_object_map'), self.mainWindow,
                                        triggered=self.add_object_action, enabled=False)
        toolbar.addAction(self.addObject_action)
Example #11
0
    def setup_toolbar(self):
        toolbar = QToolBar("Main Toolbar")
        toolbar.setObjectName("main-toolbar")

        toolbar.addAction(self.start_listening_action)
        toolbar.addAction(self.stop_listening_action)
        toolbar.addSeparator()
        toolbar.addAction(self.stop_debug_action)
        toolbar.addAction(self.detach_debug_action)
        toolbar.addSeparator()
        toolbar.addAction(self.run_debug_action)
        toolbar.addAction(self.step_over_action)
        toolbar.addAction(self.step_into_action)
        toolbar.addAction(self.step_out_action)

        self.addToolBar(toolbar)
Example #12
0
    def setup_toolbar(self):
        toolbar = QToolBar("Main Toolbar")
        toolbar.setObjectName("main-toolbar")

        toolbar.addAction(self.start_listening_action)
        toolbar.addAction(self.stop_listening_action)
        toolbar.addSeparator()
        toolbar.addAction(self.stop_debug_action)
        toolbar.addAction(self.detach_debug_action)
        toolbar.addSeparator()
        toolbar.addAction(self.run_debug_action)
        toolbar.addAction(self.step_over_action)
        toolbar.addAction(self.step_into_action)
        toolbar.addAction(self.step_out_action)

        self.addToolBar(toolbar)
Example #13
0
class IPythonWorkspaceViewer(QMainWindow):
    """Class for workspace viewer controlled by IPython
    """
    def __init__(self, parent=None):
        """
        initialization including setting up UI
        :param parent:
        """
        super(IPythonWorkspaceViewer, self).__init__(parent)

        # set up
        self.setObjectName(_fromUtf8("MainWindow"))
        self.resize(1600, 1200)
        self.centralwidget = QWidget(self)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.widget = WorkspaceViewWidget(self)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy(sizePolicy)
        self.widget.setObjectName(_fromUtf8("widget"))
        self.gridLayout.addWidget(self.widget, 1, 0, 1, 1)
        self.label = QLabel(self.centralwidget)
        self.label.setObjectName(_fromUtf8("label"))
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1005, 25))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(self)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        self.setStatusBar(self.statusbar)
        self.toolBar = QToolBar(self)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)

        # self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

        return
Example #14
0
    def add_toolbar(self,
                    name: str,
                    toolbar: QToolBar,
                    text: str = 'untitled toolbar'):

        b = self.top_toolbar_tab.add_button(text)
        toolbar.tab_button = b
        b.clicked.connect(lambda: self.switch_toolbar(name))

        self.addToolBarBreak(Qt.TopToolBarArea)
        self.addToolBar(toolbar)
        toolbar.setObjectName(name)
        self.toolbars[name] = toolbar
        toolbar.setMovable(False)
        toolbar.setFloatable(False)

        if self._current_toolbar_name != '':
            self.refresh_toolbar_appearance()
Example #15
0
 def initBasicToolbar(self, ui, toolbarManager):
     """
     Public slot to initialize the basic VCS toolbar.
     
     @param ui reference to the main window (UserInterface)
     @param toolbarManager reference to a toolbar manager object
         (E5ToolBarManager)
     @return the toolbar generated (QToolBar)
     """
     tb = QToolBar(self.tr("VCS"), ui)
     tb.setIconSize(UI.Config.ToolBarIconSize)
     tb.setObjectName("VersionControlToolbar")
     tb.setToolTip(self.tr('VCS'))
     
     tb.addAction(self.vcsNewAct)
     tb.addAction(self.vcsExportAct)
     tb.addSeparator()
     tb.addAction(self.vcsAddAct)
     
     toolbarManager.addToolBar(tb, tb.windowTitle())
     
     return tb
Example #16
0
 def initBasicToolbar(self, ui, toolbarManager):
     """
     Public slot to initialize the basic VCS toolbar.
     
     @param ui reference to the main window (UserInterface)
     @param toolbarManager reference to a toolbar manager object
         (E5ToolBarManager)
     @return the toolbar generated (QToolBar)
     """
     tb = QToolBar(self.tr("VCS"), ui)
     tb.setIconSize(UI.Config.ToolBarIconSize)
     tb.setObjectName("VersionControlToolbar")
     tb.setToolTip(self.tr('VCS'))
     
     tb.addAction(self.vcsNewAct)
     tb.addAction(self.vcsExportAct)
     tb.addSeparator()
     tb.addAction(self.vcsAddAct)
     
     toolbarManager.addToolBar(tb, tb.windowTitle())
     
     return tb
Example #17
0
    def add_toolbar(self, name: str, toolbar: QToolBar,
                    text: str = 'untitled toolbar'):
        """
        添加一个工具栏。
        """
        b = self.top_toolbar_tab.add_button(text)
        toolbar.tab_button = b
        b.clicked.connect(lambda: self.on_toolbar_switch_button_clicked(name))

        if hasattr(self, 'toolbar_path'):
            self.insertToolBar(self.toolbar_path, toolbar)
            self.insertToolBarBreak(self.toolbar_path)
        else:
            self.addToolBarBreak(Qt.TopToolBarArea)
            self.addToolBar(toolbar)
        toolbar.setObjectName(name)
        self.toolbars[name] = toolbar
        toolbar.setMovable(False)
        toolbar.setFloatable(False)

        if self._current_toolbar_name != '':
            self.refresh_toolbar_appearance()
Example #18
0
 def initToolbar(self, toolbarManager):
     """
     Public slot to initialize the multi project toolbar.
     
     @param toolbarManager reference to a toolbar manager object
         (E5ToolBarManager)
     @return the toolbar generated (QToolBar)
     """
     tb = QToolBar(self.tr("Multiproject"), self.ui)
     tb.setIconSize(UI.Config.ToolBarIconSize)
     tb.setObjectName("MultiProjectToolbar")
     tb.setToolTip(self.tr('Multiproject'))
     
     tb.addActions(self.actGrp1.actions())
     tb.addAction(self.closeAct)
     tb.addSeparator()
     tb.addAction(self.saveAct)
     tb.addAction(self.saveasAct)
     
     toolbarManager.addToolBar(tb, tb.windowTitle())
     toolbarManager.addAction(self.addProjectAct, tb.windowTitle())
     toolbarManager.addAction(self.propsAct, tb.windowTitle())
     
     return tb
Example #19
0
class SMLSurveyor(object):
    def __init__(self, iface):
        # save reference to the QGIS interface
        self.iface = iface
        # get plugin directory
        self.plugin_dir = os.path.dirname(os.path.realpath(__file__))
        self.uri = None
        self.connection = None
        self.crs = None
        self.database = None
        self.datetime = datetime.now()
        self.required_layers = []
        # 1. beacons
        # 2. parcels
        self.required_layers.append(
            RequiredLayer('Beacon', 'Beacons', 'beacons', 'gid', 'points'))
        self.required_layers.append(
            RequiredLayer('Parcel', 'Parcels', 'parcels', 'parcel_id',
                          'polygons'))

    def initGui(self):
        """ Initialize gui
        """
        # create plugin toolbar
        self.create_plugin_toolbar()

    def unload(self):
        """ Uninitialize gui
        """
        # remove plugin toolbar
        self.remove_plugin_toolbar()
        # remove layers
        self.refresh_layers()
        for l in self.required_layers:
            if bool(l.layer):
                QgsProject.instance().removeMapLayers([l.layer.id()])

    def create_plugin_toolbar(self):
        """ Create plugin toolbar to house buttons
        """
        # create plugin toolbar

        self.plugin_toolbar = QToolBar('Parcel Plugin')
        self.plugin_toolbar.setObjectName('Parcel Plugin')
        # create Database Selection button
        self.select_database_action = QAction(
            QIcon(os.path.join(self.plugin_dir, "images", "database.png")),
            "Select Database Connection", self.iface.mainWindow())
        self.select_database_action.setWhatsThis("Select database connection")
        self.select_database_action.setStatusTip("Select database connection")
        self.select_database_action.triggered.connect(
            self.manage_database_connection)
        # create Beardist button
        self.bearing_distance_action = QAction(
            QIcon(os.path.join(self.plugin_dir, "images", "beardist.png")),
            "Manage Bearings and Distances", self.iface.mainWindow())
        self.bearing_distance_action.setWhatsThis(
            "Manage bearings and distances")
        self.bearing_distance_action.setStatusTip(
            "Manage bearings and distances")
        self.bearing_distance_action.triggered.connect(
            self.manage_bearing_distance)
        # create Beacons button
        self.beacons_action = QAction(
            QIcon(os.path.join(self.plugin_dir, "images", "beacon.gif")),
            "Manage Beacons", self.iface.mainWindow())
        self.beacons_action.setWhatsThis("Manage beacons")
        self.beacons_action.setStatusTip("Manage beacons")
        self.beacons_action.triggered.connect(self.manage_beacons)
        # create Parcels button
        self.parcels_action = QAction(
            QIcon(os.path.join(self.plugin_dir, "images", "parcel.png")),
            "Manage Parcels", self.iface.mainWindow())
        self.parcels_action.setWhatsThis("Manage parcels")
        self.parcels_action.setStatusTip("Manage parcels")
        self.parcels_action.triggered.connect(self.manage_parcels)
        # populate plugin toolbar
        self.plugin_toolbar.addAction(self.select_database_action)
        self.plugin_toolbar.addAction(self.bearing_distance_action)
        self.plugin_toolbar.addAction(self.beacons_action)
        self.plugin_toolbar.addAction(self.parcels_action)
        # add plugin toolbar to gui
        self.iface.mainWindow().addToolBar(self.plugin_toolbar)

    def remove_plugin_toolbar(self):
        """ Remove plugin toolbar which houses buttons
        """
        # remove app toolbar from gui
        if hasattr(self, "pluginToolBar"):
            self.iface.mainWindow().removeToolBar(self.plugin_toolbar)
            self.plugin_toolbar.hide()

    def set_database_connection(self, connection=None, crs=None):
        """ Create a database connection
        """
        # fetch settings
        settings_plugin = QSettings()
        settings_postgis = QSettings()
        settings_plugin.beginGroup('CoGo Plugin')
        settings_postgis.beginGroup('PostgreSQL/connections')
        self.connection = connection
        if not bool(self.connection):
            # fetch pre-chosen database connection
            self.connection = settings_plugin.value("DatabaseConnection", None)
        # check if still exists
        if bool(self.connection):
            if self.connection not in settings_postgis.childGroups():
                settings_plugin.setValue("DatabaseConnection", "")
                self.connection = None
        # fetch from user if necessary
        if not bool(self.connection):
            dialog = DatabaseConnectionDialog()
            dialog.show()
            if bool(dialog.exec_()):
                self.connection = dialog.get_database_connection()
                if dialog.get_crs():
                    self.crs = QgsCoordinateReferenceSystem(
                        dialog.get_crs().get('auth_id'))
                settings_plugin.setValue("DatabaseConnection", self.connection)
        # validate database connection
        if bool(self.connection):
            db_service = settings_postgis.value(self.connection + '/service')
            db_host = settings_postgis.value(self.connection + '/host')
            db_port = settings_postgis.value(self.connection + '/port')
            db_name = settings_postgis.value(self.connection + '/database')
            db_username = settings_postgis.value(self.connection + '/username')
            db_password = settings_postgis.value(self.connection + '/password')

            max_attempts = 3
            self.uri = QgsDataSourceUri()
            self.uri.setConnection(db_host, db_port, db_name, db_username,
                                   db_password)

            if db_username and db_password:
                for i in range(max_attempts):
                    error_message = self.connect_to_db(db_service, db_host,
                                                       db_port, db_name,
                                                       db_username,
                                                       db_password)
                    if error_message:
                        ok, db_username, db_password = (
                            QgsCredentials.instance().get(
                                self.uri.connectionInfo(), db_username,
                                db_password, error_message))
                        if not ok:
                            break
                    else:
                        break

            else:
                msg = "Please enter the username and password."
                for i in range(max_attempts):
                    ok, db_username, db_password = (
                        QgsCredentials.instance().get(
                            self.uri.connectionInfo(), db_username,
                            db_password, msg))
                    if not ok:
                        break
                    error_message = self.connect_to_db(db_service, db_host,
                                                       db_port, db_name,
                                                       db_username,
                                                       db_password)
                    if not error_message:
                        break

        settings_plugin.endGroup()
        settings_postgis.endGroup()

    def connect_to_db(self, service, host, port, name, username, password):
        username.replace(" ", "")
        password.replace(" ", "")
        try:
            self.database = database.Manager({
                "CONNECTION": self.connection,
                "SERVICE": service,
                "HOST": host,
                "NAME": name,
                "PORT": port,
                "USER": username,
                "PASSWORD": password
            })
            self.uri.setConnection(host, port, name, username, password)
            self.datetime = datetime.now()
            return None
        except Exception as e:
            self.database = None
            msg = "Invalid username and password."
            return msg

    def refresh_layers(self):
        """ Ensure all required layers exist
        """
        if bool(self.database):

            # Comment out below section because connection name is better
            # to be a group name than crs name IMHO.

            # # first, we need to check the layer group for the crs used by
            # # current database
            # query = "SELECT Find_SRID('public', 'beacons', 'the_geom');"
            # self.database.connect(self.database.parameters)
            # cursor = self.database.cursor
            # cursor.execute(query)
            # crs_id = int(cursor.fetchall()[0][0])
            # del cursor
            # group_name = None
            # for key, value in crs_options.iteritems():
            #     if value == crs_id:
            #         group_name = key

            group_name = self.connection

            root = QgsProject.instance().layerTreeRoot()
            target_group = root.findGroup(group_name)
            if not bool(target_group):
                target_group = root.insertGroup(0, group_name)
            target_group.setItemVisibilityChecked(Qt.Checked)

            for required_layer in reversed(self.required_layers):
                for layer_node in target_group.findLayers():
                    layer = layer_node.layer()
                    if required_layer.name_plural.lower() == \
                            layer.name().lower():
                        target_group.removeLayer(layer)

            for required_layer in self.required_layers:
                self.uri.setDataSource(required_layer.schema,
                                       required_layer.table,
                                       required_layer.geometry_column, '',
                                       required_layer.primary_key)
                added_layer = QgsVectorLayer(self.uri.uri(),
                                             required_layer.name_plural,
                                             "postgres")
                QgsProject.instance().addMapLayer(added_layer, False)
                target_group.addLayer(added_layer)
                for layer_node in target_group.findLayers():
                    layer = layer_node.layer()
                    if required_layer.name_plural == layer.name():
                        required_layer.layer = layer
                        layer_node.setItemVisibilityChecked(Qt.Checked)
                        if self.crs:
                            layer.setCrs(self.crs)
                self.iface.zoomToActiveLayer()

    def manage_beacons(self):
        """ Portal which enables the management of beacons
        """
        if self.datetime.date() != datetime.now().date():
            self.database = None
        if self.database is None:
            self.set_database_connection()
            if self.database is None:
                return
        BeaconManager(self.iface, self.database, self.required_layers)
        validate_plugin_actions(self, self.database)
        self.iface.mapCanvas().refresh()

    def manage_parcels(self):
        """ Portal which enables the management of parcels
        """
        if self.datetime.date() != datetime.now().date():
            self.database = None
        if self.database is None:
            self.set_database_connection()
            if self.database is None:
                return
        ParcelManager(self.iface, self.database, self.required_layers)
        validate_plugin_actions(self, self.database)
        self.iface.mapCanvas().refresh()

    def manage_bearing_distance(self):
        """ Portal which enables the management of
        bearings and distances
        """
        if self.datetime.date() != datetime.now().date():
            self.database = None
        if self.database is None:
            self.set_database_connection()
            if self.database is None:
                return

        result = validate_plugin_actions(self, self.database)
        if not result:
            QMessageBox.warning(
                None, "SML Surveyor",
                ("No Beacons available in the table. "
                 "Please use Beacon Manager tool to create a Beacon."))
        else:
            BearDistManager(self.iface, self.database, self.required_layers)

        self.iface.mapCanvas().refresh()

    def manage_database_connection(self):
        """ Action to select the db connection to work with.
        """
        database_manager = DatabaseManager()
        connection = database_manager.get_current_connection()
        crs = database_manager.get_current_crs()
        if connection:
            self.set_database_connection(connection=connection, crs=crs)
            self.refresh_layers()
        if self.database:
            validate_plugin_actions(self, self.database)
Example #20
0
class MainWindow(QMainWindow):
    """This is the main application window class

    it defines the GUI window for the browser
    """
    def parse_config(self, file_config, options):
        self.config = {}
        options = vars(options)
        for key, metadata in CONFIG_OPTIONS.items():
            options_val = options.get(key)
            file_val = file_config.get(key)
            env_val = os.environ.get(metadata.get("env", ''))
            default_val = metadata.get("default")
            vals = metadata.get("values")
            debug("key: {}, default: {}, file: {}, options: {}".format(
                key, default_val, file_val, options_val))
            if vals:
                options_val = (options_val in vals and options_val) or None
                file_val = (file_val in vals and file_val) or None
                env_val = (env_val in vals and env_val) or None
            if metadata.get("is_file"):
                filename = options_val or env_val
                if not filename:
                    self.config[key] = default_val
                else:
                    try:
                        with open(filename, 'r') as fh:
                            self.config[key] = fh.read()
                    except IOError:
                        debug("Could not open file {} for reading.".format(
                            filename))
                        self.config[key] = default_val
            else:
                set_values = [
                    val for val in (options_val, env_val, file_val)
                    if val is not None
                ]
                if len(set_values) > 0:
                    self.config[key] = set_values[0]
                else:
                    self.config[key] = default_val
            if metadata.get("type") and self.config[key]:
                debug("{} cast to {}".format(key, metadata.get("type")))
                self.config[key] = metadata.get("type")(self.config[key])
        debug(repr(self.config))

    def createAction(self,
                     text,
                     slot=None,
                     shortcut=None,
                     icon=None,
                     tip=None,
                     checkable=False,
                     signal="triggered"):
        """Return a QAction given a number of common QAction attributes

        Just a shortcut function Originally borrowed from
        'Rapid GUI Development with PyQT' by Mark Summerset
        """
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(
                QIcon.fromTheme(icon, QIcon(":/{}.png".format(icon))))
        if shortcut is not None and not shortcut.isEmpty():
            action.setShortcut(shortcut)
            tip += " ({})".format(shortcut.toString())
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.__getattr__(signal).connect(slot)
        if checkable:
            action.setCheckable()
        return action

    def __init__(self, options, parent=None):
        """Construct a MainWindow Object."""
        super(MainWindow, self).__init__(parent)
        # Load config file
        self.setWindowTitle("Browser")
        debug("loading configuration from '{}'".format(options.config_file))
        configfile = {}
        if options.config_file:
            configfile = yaml.safe_load(open(options.config_file, 'r'))
        self.parse_config(configfile, options)
        # self.popup will hold a reference to the popup window
        # if it gets opened
        self.popup = None

        # Stylesheet support
        if self.config.get("stylesheet"):
            try:
                with open(self.config.get("stylesheet")) as ss:
                    self.setStyleSheet(ss.read())
            except:
                debug(('Problem loading stylesheet file "{}", '
                       'using default style.').format(
                           self.config.get("stylesheet")))
        self.setObjectName("global")

        # Set proxy server environment variable before creating web views
        if self.config.get("proxy_server"):
            os.environ["http_proxy"] = self.config.get("proxy_server")
            os.environ["https_proxy"] = self.config.get("proxy_server")

        # If the whitelist is activated, add the bookmarks and start_url
        if self.config.get("whitelist"):
            # we can just specify whitelist = True,
            # which should whitelist just the start_url and bookmark urls.
            if type(self.config.get("whitelist")) is not list:
                self.whitelist = []
            self.whitelist.append(
                str(QUrl(self.config.get("start_url")).host()))
            bookmarks = self.config.get("bookmarks")
            if bookmarks:
                self.whitelist += [
                    str(QUrl(b.get("url")).host())
                    for k, b in bookmarks.items()
                ]
                self.whitelist = set(self.whitelist)  # uniquify and optimize
            debug("Generated whitelist: " + str(self.whitelist))

        # create the web engine profile
        self.create_webprofile()

        # Now construct the UI
        self.build_ui()

    # ## END OF CONSTRUCTOR ## #

    def create_webprofile(self):
        """Create a webengineprofile to use in all views."""
        if self.config.get("privacy_mode"):
            webprofile = QWebEngineProfile()
        else:
            webprofile = QWebEngineProfile.defaultProfile()
        debug("Browser session is private: {}".format(
            webprofile.isOffTheRecord()))
        if self.config.get("user_agent"):
            webprofile.setHttpUserAgent(self.config["user_agent"])
            debug('Set user agent to "{}"'.format(webprofile.httpUserAgent()))
        self.webprofile = webprofile

    def build_ui(self):
        """Set up the user interface for the main window.

        Unlike the constructor, this method is re-run
        whenever the browser is "reset" by the user.
        """

        debug("build_ui")
        inactivity_timeout = self.config.get("timeout")
        quit_button_tooltip = ("Click here to quit"
                               if self.config.get('quit_button_mode')
                               == 'close' else "Click here when you are done"
                               "\nIt will clear your browsing history"
                               " and return you to the start page.")
        qb_mode_callbacks = {'close': self.close, 'reset': self.reset_browser}
        to_mode_callbacks = {
            'close': self.close,
            'reset': self.reset_browser,
            'screensaver': self.screensaver
        }
        self.screensaver_active = False

        # ##Start GUI configuration## #
        self.browser_window = AdmWebView(self.config,
                                         webprofile=self.webprofile)
        self.browser_window.setObjectName("web_content")
        self.setCentralWidget(self.browser_window)

        # Icon theme setting
        QIcon.setThemeName(self.config.get("icon_theme"))

        self.setCentralWidget(self.browser_window)
        debug("loading {}".format(self.config.get("start_url")))
        self.browser_window.setUrl(QUrl(self.config.get("start_url")))

        # Window size settings
        window_size = self.config.get("window_size", '').lower()
        if window_size == 'full':
            self.showFullScreen()
        elif window_size == 'max':
            self.showMaximized()
        elif window_size:
            size = re.match(r"(\d+)x(\d+)", window_size)
            if size:
                width, height = size.groups()
                self.setFixedSize(int(width), int(height))
            else:
                debug('Ignoring invalid window size "{}"'.format(window_size))

        # Set up the top navigation bar if it's configured to exist
        if self.config.get("navigation"):
            self.navigation_bar = QToolBar("Navigation")
            self.navigation_bar.setObjectName("navigation")
            self.addToolBar(Qt.TopToolBarArea, self.navigation_bar)
            self.navigation_bar.setMovable(False)
            self.navigation_bar.setFloatable(False)

            #  Standard navigation tools
            self.nav_items = {
                "back":
                self.browser_window.pageAction(AdmWebPage.Back),
                "forward":
                self.browser_window.pageAction(AdmWebPage.Forward),
                "refresh":
                self.browser_window.pageAction(AdmWebPage.Reload),
                "stop":
                self.browser_window.pageAction(AdmWebPage.Stop),
                "quit":
                self.createAction(
                    self.config.get("quit_button_text"),
                    qb_mode_callbacks.get(self.config.get("quit_button_mode"),
                                          self.reset_browser),
                    QKeySequence("Alt+F"), None, quit_button_tooltip),
                "zoom_in":
                self.createAction(
                    "Zoom In", self.zoom_in, QKeySequence("Alt++"), "zoom-in",
                    "Increase the size of the text and images on the page"),
                "zoom_out":
                self.createAction(
                    "Zoom Out", self.zoom_out, QKeySequence("Alt+-"),
                    "zoom-out",
                    "Decrease the size of text and images on the page")
            }
            if self.config.get("allow_printing"):
                self.nav_items["print"] = self.createAction(
                    "Print", self.browser_window.print_webpage,
                    QKeySequence("Ctrl+p"), "document-print",
                    "Print this page")

            # Add all the actions to the navigation bar.
            for item in self.config.get("navigation_layout"):
                if item == "separator":
                    self.navigation_bar.addSeparator()
                elif item == "spacer":
                    # an expanding spacer.
                    spacer = QWidget()
                    spacer.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Preferred)
                    self.navigation_bar.addWidget(spacer)
                elif item == "bookmarks":
                    # Insert bookmarks buttons here.
                    self.bookmark_buttons = []
                    for bookmark in self.config.get("bookmarks", {}).items():
                        debug("Bookmark:\n" + bookmark.__str__())
                        # bookmark name will use the "name" attribute,
                        # if present, or else just the key:
                        bookmark_name = bookmark[1].get("name") or bookmark[0]
                        # Create a button for the bookmark as a QAction,
                        # which we'll add to the toolbar
                        button = self.createAction(
                            bookmark_name, (lambda url=bookmark[1].get(
                                "url"): self.browser_window.load(QUrl(url))),
                            QKeySequence.mnemonic(bookmark_name), None,
                            bookmark[1].get("description"))
                        self.navigation_bar.addAction(button)
                        (self.navigation_bar.widgetForAction(
                            button).setObjectName("navigation_button"))
                else:
                    action = self.nav_items.get(item, None)
                    if action:
                        self.navigation_bar.addAction(action)
                        (self.navigation_bar.widgetForAction(
                            action).setObjectName("navigation_button"))

            # This removes the ability to toggle off the navigation bar:
            self.nav_toggle = self.navigation_bar.toggleViewAction()
            self.nav_toggle.setVisible(False)
            # End "if show_navigation is True" block

        # set hidden quit action
        # For reasons I haven't adequately ascertained,
        # this shortcut fails now and then claiming
        # "Ambiguous shortcut overload".
        # No idea why, as it isn't consistent.
        self.really_quit = self.createAction("", self.close,
                                             QKeySequence("Ctrl+Alt+Q"), None,
                                             "")
        self.addAction(self.really_quit)

        # Call a reset function after timeout
        if inactivity_timeout != 0:
            self.event_filter = InactivityFilter(inactivity_timeout)
            QCoreApplication.instance().installEventFilter(self.event_filter)
            self.browser_window.page().installEventFilter(self.event_filter)
            self.event_filter.timeout.connect(
                to_mode_callbacks.get(self.config.get("timeout_mode"),
                                      self.reset_browser))
        else:
            self.event_filter = None

        # ##END OF UI SETUP## #

    def screensaver(self):
        """Enter "screensaver" mode

        This method puts the browser in screensaver mode, where a URL
        is displayed while the browser is idle.  Activity causes the browser to
        return to the home screen.
        """
        debug("screensaver started")
        self.screensaver_active = True
        if self.popup:
            self.popup.close()
        if self.config.get("navigation"):
            self.navigation_bar.hide()
        self.browser_window.setZoomFactor(self.config.get("zoom_factor"))
        self.browser_window.load(QUrl(self.config.get("screensaver_url")))
        self.event_filter.timeout.disconnect()
        self.event_filter.activity.connect(self.reset_browser)

    def reset_browser(self):
        """Clear the history and reset the UI.

        Called whenever the inactivity filter times out,
        or when the user clicks the "finished" button in
        'reset' mode.
        """
        # Clear out the memory cache
        #QWebEngineSettings.clearMemoryCaches()
        self.browser_window.history().clear()
        # self.navigation_bar.clear() doesn't do its job,
        # so remove the toolbar first, then rebuild the UI.
        debug("RESET BROWSER")
        if self.event_filter:
            self.event_filter.blockSignals(True)
        if self.screensaver_active is True:
            self.screensaver_active = False
            self.event_filter.activity.disconnect()
        if self.event_filter:
            self.event_filter.blockSignals(False)
        if hasattr(self, "navigation_bar"):
            self.removeToolBar(self.navigation_bar)
        self.build_ui()

    def zoom_in(self):
        """Zoom in action callback.

        Note that we cap zooming in at a factor of 3x.
        """
        if self.browser_window.zoomFactor() < 3.0:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() + 0.1)
            self.nav_items["zoom_out"].setEnabled(True)
        else:
            self.nav_items["zoom_in"].setEnabled(False)

    def zoom_out(self):
        """Zoom out action callback.

        Note that we cap zooming out at 0.1x.
        """
        if self.browser_window.zoomFactor() > 0.1:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() - 0.1)
            self.nav_items["zoom_in"].setEnabled(True)
        else:
            self.nav_items["zoom_out"].setEnabled(False)
Example #21
0
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # self.initUI()
        self.init_ui()
        self.generateData()
        self.UI_style()

    def init_ui(self):
        self.setFixedSize(1200, 700)
        self.setWindowTitle('STalking')
        self.setWindowIcon(QIcon("icon/stlogo.ico"))
        self.main_widget = QtWidgets.QWidget()  # 创建窗口主部件
        self.main_widget.setObjectName('main_widget')
        self.main_layout = QtWidgets.QGridLayout()  # 创建主部件的网格布局
        self.main_widget.setLayout(self.main_layout)  # 设置窗口主部件布局为网格布局

        self.left_widget = QtWidgets.QWidget()  # 创建左侧部件 左侧为功能按钮
        self.left_widget.setObjectName('left_widget')
        self.left_layout = QtWidgets.QGridLayout()  # 创建左侧部件的网格布局层
        self.left_widget.setLayout(self.left_layout)  # 设置左侧部件布局为网格

        self.center_Splitter = QSplitter(Qt.Horizontal)
        self.center_Splitter.setObjectName('center_Splitter')
        self.center_layout = QtWidgets.QGridLayout()
        self.center_Splitter.setLayout(self.center_layout)  # 设置右侧部件布局为网格

        self.main_layout.addWidget(self.left_widget, 0, 0, 16,
                                   3)  # 左侧部件在第0行第0列,占8行3列
        # self.main_layout.addWidget(self.center_QWidget, 0, 3, 16, 17)  # 左侧部件在第0行第3列,占8行3列
        self.main_layout.addWidget(self.center_Splitter, 0, 3, 16,
                                   17)  # 左侧部件在第0行第3列,占8行3列
        self.setCentralWidget(self.main_widget)  # 设置窗口主部件

        self.icon_button = QtWidgets.QToolButton()
        self.icon_button.setIcon(QtGui.QIcon('icon/stlogo.ico'))  # 设置按钮图标
        self.icon_button.setIconSize(QtCore.QSize(150, 100))  # 设置图标大小

        self.left_label_1 = QtWidgets.QPushButton("模型选择")
        self.left_label_1.setObjectName('left_label')
        self.left_label_2 = QtWidgets.QPushButton("保存与设置")
        self.left_label_2.setObjectName('left_label')
        self.left_label_3 = QtWidgets.QPushButton("其他")
        self.left_label_3.setObjectName('left_label')

        self.left_button_1 = QtWidgets.QPushButton(
            qtawesome.icon('fa.database', color='gray'), "选择GMM")
        self.left_button_1.setObjectName('left_button')
        self.left_button_2 = QtWidgets.QPushButton(
            qtawesome.icon('fa.file', color='gray'), "选择UBM")
        self.left_button_2.setObjectName('left_button')
        self.left_button_3 = QtWidgets.QPushButton(
            qtawesome.icon('fa.plus-circle', color='gray'), "选择视频")
        self.left_button_3.setObjectName('left_button')
        self.left_button_4 = QtWidgets.QPushButton(
            qtawesome.icon('fa.save', color='gray'), "保存模型")
        self.left_button_4.setObjectName('left_button')
        self.left_button_5 = QtWidgets.QPushButton(
            qtawesome.icon('fa.file', color='gray'), "模型路径")
        self.left_button_5.setObjectName('left_button')
        self.left_button_6 = QtWidgets.QPushButton(
            qtawesome.icon('fa.folder-open', color='gray'), "文件路径")
        self.left_button_6.setObjectName('left_button')
        self.left_button_7 = QtWidgets.QPushButton(
            qtawesome.icon('fa.comment', color='gray'), "使用向导")
        self.left_button_7.setObjectName('left_button')
        self.left_button_8 = QtWidgets.QPushButton(
            qtawesome.icon('fa.star', color='gray'), "版权说明")
        self.left_button_8.setObjectName('left_button')
        self.left_button_9 = QtWidgets.QPushButton(
            qtawesome.icon('fa.question', color='gray'), "关于我们")
        self.left_button_9.setObjectName('left_button')
        self.left_xxx = QtWidgets.QPushButton(" ")

        self.left_layout.addWidget(self.icon_button, 0, 0.5, 1, 3)
        self.left_layout.addWidget(self.left_label_1, 1, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_1, 2, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_2, 3, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_3, 4, 0, 1, 3)
        self.left_layout.addWidget(self.left_label_2, 5, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_4, 6, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_5, 7, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_6, 8, 0, 1, 3)
        self.left_layout.addWidget(self.left_label_3, 9, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_7, 10, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_8, 11, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_9, 12, 0, 1, 3)

        self.model_list_widget = QtWidgets.QWidget()
        self.model_list_widget.setObjectName('model_widget')
        self.model_list_layout = QtWidgets.QGridLayout()  # 创建左侧部件的网格布局层
        self.model_list_widget.setLayout(self.model_list_layout)  # 设置左侧部件布局为网格

        self.model_list_label = QtWidgets.QLabel("模型列表")
        self.model_list_label.setObjectName('my_lable')

        self.model_view_list = QListWidget()  # 文件列表
        self.model_view_list.setObjectName('my_list')
        # self.model_view_list.setFixedWidth(200)
        self.right_Splitter = QSplitter(Qt.Vertical)
        self.right_Splitter.setObjectName('right_Splitter')

        self.model_list_layout.addWidget(self.model_list_label, 0, 0, 1, 1)
        self.model_list_layout.addWidget(self.model_view_list, 1, 0, 9, 1)

        self.center_Splitter.addWidget(self.model_list_widget)
        self.center_Splitter.addWidget(self.right_Splitter)
        self.center_Splitter.setStretchFactor(0, 2)
        self.center_Splitter.setStretchFactor(1, 8)

        self.result_label = QtWidgets.QLabel("数据分析")
        self.result_label.setFixedHeight(80)
        self.result_label.setObjectName('my_lable')

        self.right_html_page_TabWidget = QtWidgets.QTabWidget()
        self.right_html_page_TabWidget.setObjectName(
            'right_html_page_TabWidget')
        self.right_log_widget = QtWidgets.QWidget()  # log 框 = button + log
        self.right_log_widget.setObjectName('right_log_widget')
        self.right_log_layout = QtWidgets.QGridLayout()
        self.right_log_widget.setLayout(self.right_log_layout)  # 设置右侧部件布局为网格

        self.right_Splitter.addWidget(self.result_label)
        self.right_Splitter.addWidget(self.right_html_page_TabWidget)
        self.right_Splitter.addWidget(self.right_log_widget)
        self.right_Splitter.setStretchFactor(0, 1)
        self.right_Splitter.setStretchFactor(1, 9)
        self.right_Splitter.setStretchFactor(2, 1)

        self.right_log_toolbar = QToolBar()
        self.right_log_toolbar.setObjectName('right_log_toolbar')
        self.right_log_toolbar.setOrientation(Qt.Vertical)
        # self.right_button_layout.addWidget(self.toolbarGmm)
        delete_action = QAction(QIcon('icon/delete-gray.png'), '清空日志', self)
        self.right_log_toolbar.addAction(delete_action)
        export_action = QAction(QIcon('icon/save_m.png'), '导出日志', self)
        self.right_log_toolbar.addAction(export_action)
        # self.right_log_layout.setSpacing(0)
        self.right_log_contend = QListWidget()
        # self.right_log_contend.setFixedHeight(100)
        self.right_log_contend.setObjectName('my_list')
        self.right_log_layout.addWidget(self.right_log_toolbar, 0, 0, 1, 3)
        self.right_log_layout.addWidget(self.right_log_contend, 0, 1, 1, 18)

    # 定义 css
    def UI_style(self):
        self.main_widget.setStyleSheet('''
            QWidget#main_widget{
                background:#EBEBEB;
                border-top:1px solid #EBEBEB;
                border-bottom:1px solid #EBEBEB;
                border-left:1px solid #EBEBEB;
                border-top-left-radius:10px;
                border-bottom-left-radius:10px;
            }

        ''')
        self.result_label.setStyleSheet('''
            QLabel{
                border:none;
                background:#EBEBEB;
                font-size:20px;
                font-weight:900;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
        ''')
        self.model_list_label.setStyleSheet('''
                    QLabel{
                        border:none;
                        background:#EBEBEB;
                        font-size:20px;
                        font-weight:900;
                        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                    }

                ''')
        self.icon_button.setStyleSheet('''
            QToolButton{
                border:none;
                background:#EBEBEB;
            }
        ''')
        self.main_widget.setStyleSheet('''
            QWidget#center_QWidget{
                color:#232C51;
                background:#EBEBEB;
                border-top:1px solid #EBEBEB;
                border-bottom:1px solid #EBEBEB;
                border-right:1px solid #EBEBEB;
                border-top-right-radius:10px;
                border-bottom-right-radius:10px;
            }
            QWidget#left_widget{
                        background:#EBEBEB;
                        border-top:1px solid #EBEBEB;
                        border-bottom:1px solid #EBEBEB;
                        border-left:1px solid #EBEBEB;
                        border-top-left-radius:10px;
                        border-bottom-left-radius:10px;
                    }
        ''')
        self.model_list_widget.setStyleSheet('''
            QListWidget#my_list{
                background:light white;
                border:none;
                width:300px;
                border-radius:10px;
                padding:2px 4px;
            }
        ''')
        self.left_widget.setStyleSheet('''
            QPushButton{border:none;color:gray;font-size:18px;font-weight:700;}
            QPushButton#left_label{
                    border:none;
                    border-bottom:1px solid dark gray;
                    font-size:20px;
                    font-weight:900;
                    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
            QPushButton#left_button:hover{border-left:4px solid red;font-weight:700;}
        ''')
        self.center_Splitter.setStyleSheet('''
            QSplitter#center_Splitter{
                background:#EBEBEB;
            }
            QSplitter#right_Splitter{
                background:#EBEBEB;
            }
            QTabWidget#right_html_page_TabWidget{
                width:300px;
                border-radius:10px;
                padding:2px 4px;
                border:none;
                font-size:16px;
                font-weight:700;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
            }
            QLabel#my_lable{
                background-color:#EBEBEB;
                border:none;
                font-size:20px;
                font-weight:bold;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
             QToolBar#right_log_toolbar{
                border:none;
                background-color: #EBEBEB;
            }
            QListWidget#my_list{
                background:light white;
                border:none;
                width:300px;
                border-radius:10px;
                padding:2px 4px;
            }

        ''')
        self.model_list_label.setAlignment(Qt.AlignCenter)
        self.result_label.setAlignment(Qt.AlignCenter)
        self.model_list_label.setStyleSheet('''
            QLabel{
                background-color:light gray;
                border:none;
                font-size:20px;
                font-weight:bold;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
        ''')

        self.right_log_widget.setStyleSheet('''
            QListWidget#right_log_widget{
                width:300px;
                border-radius:10px;
                padding:2px 4px;
            }
            QToolBar#right_log_toolbar{
                border:none;
                background-color: light gray;
            }
            QListWidget#right_log_contend{
                background:#EBEBEB;
                border:none;
                border:1px solid gray;
                width:300px;
                border-radius:10px;
                padding:2px 4px;
            }
        ''')

        # self.setWindowOpacity(1)  # 设置窗口透明度
        # self.setAttribute(QtCore.Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        # self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # 隐藏边框
        # self.main_layout.setSpacing(0)

    def generateData(self):
        for group in range(1, 100):
            self.model_view_list.addItem("model_{0}".format(group))
        for group in range(1, 100):
            self.right_log_contend.addItem(
                (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') +
                 " : operation_{0}").format(group))
        for group in range(1, 4):
            self.tabItem = QTextBrowser()
            self.right_html_page_TabWidget.addTab(self.tabItem,
                                                  "page_{0}".format(group))
            self.tabItem.setHtml("""<table bgcolor=yellow>
        <tr><td>Groups:</td><td>comp.lang.python.announce</td></tr>
        <tr><td>From:</td><td>"Fuzzyman" &lt;[email protected]&gt;</td></tr>
        <tr><td>Subject:</td><td><b>[ANN] Movable Python 2.0.0 Final
        Available</b></td></tr>
        </table>

        <h3>Movable Python 2.0.0 Final</h3>
        <p>
        <a href="http://www.voidspace.org.uk/python/movpy/">
        http://www.voidspace.org.uk/python/movpy/</a>
        is now available.

        <p>
        The new binaries are available for download from the groups page :

        <p>Movable Python Groups Page
        <a href="http://voidspace.tradebit.com/groups.php">
        http://voidspace.tradebit.com/groups.php</a>
        <p>
        Binaries are uploaded for Python 2.2.3, 2.3.5, 2.4.4, 2.5 and the
        MegaPack
        <a href="http://www.voidspace.org.uk/python/movpy/megapack.html">
        http://www.voidspace.org.uk/python/movpy/megapack.html</a>.
        <p>
        There is also a fresh version of the free demo, based on Python 2.3.5:

        <p>Movable Python Trial Version
        <a href="http://voidspace.tradebit.com/files.php/7007">
        http://voidspace.tradebit.com/files.php/7007</a>

        <h3>What is Movable Python</h3>

        <p>
        <b><i>Movable Python</i></b> is a distribution of Python, for Windows,
        that can run without being installed. It means you can carry a full
        development environment round on a USB stick.

        <p>
        It is also useful for testing programs with a 'clean Python install',
        and testing programs with multiple versions of Python.

        <p>
        The GUI program launcher makes it a useful programmers tool, including
        features like :

        <ul>
        <li>Log the output of all Python scripts run
        <li>Enable Psyco for all scripts
        <li>Quick Launch buttons for commonly used programs
        <li>Configure multiple interpreters for use from a single interface
        </ul>
        <p>
        It comes with the Pythonwin IDE and works fine with other IDEs like
        SPE
        <a href="http://developer.berlios.de/projects/python/">
        http://developer.berlios.de/projects/python/</a>.
        <p>
        Plus many other features and bundled libraries.""")
Example #22
0
class GUI(QMainWindow):
    def __init__(self, config, app, splash):
        super().__init__()

        self.config = config
        self.app = app
        self.splash = splash

        log.set_up(logger, verbose=config.VERBOSE, logfile=config.LOG_FILE)

        self.resize(1024, 680)
        self.setWindowTitle(tr("Zuul GUI"))
        icon = QtGui.QIcon('assets/zuul.icns')
        self.setWindowIcon(icon)
        self.app.setWindowIcon(icon)

        def openPreference():
            if self.config.initialize(openDialog=True):
                self.loadPlugins()

        # Add Preferences menu
        mainMenuBar = QMenuBar()
        newAct = QAction(tr("Preferences..."), self)
        newAct.triggered.connect(openPreference)
        fileMenu = mainMenuBar.addMenu(tr("Zuul GUI"))
        fileMenu.addAction(newAct)
        self.setMenuBar(mainMenuBar)

        self.currentBlock = None
        if self.refreshStatus():
            self.loadPlugins()

            timer = QtCore.QTimer(self)
            timer.timeout.connect(self.refreshStatus)
            timer.start(self.config.POLL_INTERVAL)

            self.show()

    # init clientapi
    def initXcpApi(self):
        if hasattr(self, 'zulApi') and isinstance(self.zulApi, ZuuldAPI):
            return True
        else:
            try:
                self.zulApi = ZuuldAPI(self.config)
                return True
            except ConfigurationError as e:
                self.show()
                msgBox = QMessageBox(self)
                msgBox.setText(str(e))
                msgBox.setModal(True)
                msgBox.show()
                return False

    def refreshStatus(self):
        if not self.initXcpApi():
            return False

        try:
            serverInfo = self.zulApi.call(
                {
                    'method': 'get_running_info',
                    'params': []
                }, return_dict=True)

            zuulLastBlock = serverInfo['last_block']['block_index']
            walletLastBlock = self.zulApi.call(
                {
                    'method': 'wallet_last_block',
                    'params': {}
                },
                return_dict=True)

            message = 'Server Last Block: {} | Wallet Last Block: {}'

            self.statusBar().showMessage(
                message.format(zuulLastBlock, walletLastBlock))

            if self.currentBlock is not None and self.currentBlock != zuulLastBlock:
                self.notifyPlugins('new_block', {'block_index': zuulLastBlock})

            self.currentBlock = zuulLastBlock

            return True
        # TODO
        except Exception as e:
            # if application startup then open preference dialog and exit
            if not hasattr(self, 'plugins'):
                if self.splash:
                    self.splash.hide()
                self.config.initialize(openDialog=True)
                exit()
            # else fails silently, error are already shown by `api.ZuuldRPCError`
            # and refreshStatus is executed each self.config.POLL_INTERVAL second
            return False

    def notifyPlugins(self, messageName, messageData):
        logger.debug('Notify plugins `{}`: {}'.format(messageName,
                                                      messageData))
        if hasattr(self, 'plugins'):
            for plugin in self.plugins:
                if hasattr(plugin, 'onMessage'):
                    plugin.onMessage(messageName, messageData)
            self.refreshToolbar()

    def refreshToolbar(self):
        pluginIndex = self.currentMenuItem.property('pluginIndex')
        actionValue = self.currentMenuItem.property('actionValue')
        self.initToolbar(selectedPluginIndex=pluginIndex,
                         selectedActionValue=actionValue)
        self.currentMenuItem.setProperty('active', 'true')
        self.refreshStyleSheet()

    def initPlugins(self):
        # init QML plugin container
        if hasattr(self, 'stackedWidget'):
            del (self.stackedWidget)

        self.stackedWidget = QStackedWidget(self)
        self.plugins = []

        for pluginName in self.config.PLUGINS:
            view = QQuickView()
            view.setFlags(Qt.SubWindow)

            # add clientapi into the plugin context
            context = view.rootContext()

            context.setContextProperty('zulApi', self.zulApi)
            context.setContextProperty('GUI', self)

            # load plugin translations if i18n subfolder exists
            i18nDir = 'plugins/{}/i18n'.format(pluginName)
            if os.path.exists(i18nDir):
                translator = QtCore.QTranslator()
                fileName = 'send_'.format(QtCore.QLocale.system().name())
                #fileName = 'send_fr'
                translator.load(fileName, i18nDir)
                self.app.installTranslator(translator)

            # load QML file
            plugin_index_path = 'plugins/{}/index.qml'.format(pluginName)
            view.setSource(QUrl(plugin_index_path))

            plugin = view.rootObject()
            self.plugins.append(plugin)

            # call plugin init callback
            plugin.init()

            # add the plugin in the container
            container = QWidget.createWindowContainer(view, self)
            self.stackedWidget.addWidget(container)

    def initToolbar(self, selectedPluginIndex=None, selectedActionValue=None):
        # init toolbar
        if hasattr(self, 'toolbar'):
            self.removeToolBar(self.toolbar)
            del (self.toolbar)

        self.toolbar = QToolBar()
        self.toolbar.setAutoFillBackground(True)
        self.toolbar.setObjectName('menu')
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon
                                        | Qt.AlignLeft)
        self.addToolBar(Qt.LeftToolBarArea, self.toolbar)
        self.currentMenuItem = None

        pluginIndex = 0
        for plugin in self.plugins:
            # generate the left menu
            menu = plugin.property('menu')
            if isinstance(menu, QJSValue):
                menu = menu.toVariant()
            if menu and isinstance(menu,
                                   dict) and 'items' in menu and isinstance(
                                       menu['items'], list):
                # menu title
                if 'groupLabel' in menu:
                    menuGroupLabel = QLabel(menu['groupLabel'])
                    menuGroupLabel.setProperty('isGroupLabel', 'true')
                    self.toolbar.addWidget(menuGroupLabel)
                # menu item
                items = []
                for menuItem in menu['items']:
                    if isinstance(
                            menuItem, dict
                    ) and 'label' in menuItem and 'value' in menuItem:
                        items.append(MenuItem(menuItem['label'], self))
                        items[-1].setProperty('pluginIndex', pluginIndex)
                        items[-1].setProperty('actionValue', menuItem['value'])
                        items[-1].setProperty('isAction', 'true')
                        self.toolbar.addWidget(items[-1])
                        if self.currentMenuItem is None or (
                                selectedPluginIndex == pluginIndex
                                and selectedActionValue == menuItem['value']):
                            self.currentMenuItem = items[-1]

            pluginIndex += 1

        self.currentMenuItem.activate()

    def loadPlugins(self):
        if not self.initXcpApi():
            return

        self.initPlugins()
        self.initToolbar()

        # display the plugin container
        self.refreshStyleSheet()
        self.setCentralWidget(self.stackedWidget)

    def refreshStyleSheet(self):
        self.setStyleSheet('''
            QWidget, QQuickView, QToolBar, QMainWindow { font-size:14pt }
            QToolBar#menu { background-color: #ececec; border: 1px solid #ececec; border-right-color: #000; }
            QToolBar#menu QLabel { width:100%; text-align:left; padding:3px; margin:0; }
            QToolBar#menu QLabel[isAction="true"]:hover { background-color:#CCC; }
            QToolBar#menu QLabel[active="true"] { background-color:#CCC; }
            QToolBar#menu QLabel[isAction="true"] { padding-left: 15px; }
            QToolBar#menu QLabel[isGroupLabel="true"] { color:#888888; text-transform:uppercase; }
        ''')

    # used in QML to display a confirm dialog
    @pyqtSlot(QVariant, QVariant, result=QVariant)
    def confirm(self, title, text):
        result = QMessageBox.question(self, title, text)
        if result == QMessageBox.Yes:
            return True
        else:
            return False

    # used in QML to display a message dialog
    @pyqtSlot(QVariant, QVariant)
    def alert(self, title, text):
        QMessageBox.information(self, title, text)

    @pyqtSlot(QVariant)
    def copyToClipboard(self, text):
        clipboard = QApplication.clipboard()
        clipboard.setText(text)
Example #23
0
class MainWindow(QMainWindow):
    """
    Main UI window

    Class creates window elements, fills main menu with items.

    If you need to access to some existing menu items - check action path
    in the class constructor, than use next code: ::

        core.actionManager().action("mFile/aOpen").setEnabled(True)
        core.actionManager().action("mFile/aOpen").triggered.connect(self.myCoolMethod)

    MainWindow instance is accessible as: ::

        from enki.core.core import core
        core.mainwindow()

    Created by the core
    """

    hideAllWindows = pyqtSignal()
    """
    hideAllWindows()

    **Signal** emitted, when user toggled "Hide all" .
    Dock widgets are closed automatically, but other widgets, i.e. search widget, must catch this signal and close
    themselves.
    """  # pylint: disable=W0105

    directoryDropt = pyqtSignal(str)
    """
    directoryDropt()

    **Signal** emitted, when user drag-n-dropt directory to main windowd.
    FileBrowser shows directory
    """  # pylint: disable=W0105

    _STATE_FILE = os.path.join(enki.core.defines.CONFIG_DIR,
                               "main_window_state.bin")
    _GEOMETRY_FILE = os.path.join(enki.core.defines.CONFIG_DIR,
                                  "main_window_geometry.bin")

    def __init__(self):
        QMainWindow.__init__(self)

        self._queuedMessageToolBar = None
        self._createdMenuPathes = []
        self._createdActions = []

        self._addedDockWidgets = []

        if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'
                   ):  # missing on some PyQt5 versions
            self.setUnifiedTitleAndToolBarOnMac(True)
        self.setIconSize(QSize(16, 16))
        self.setAcceptDrops(True)

        # Set corner settings for dock widgets
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)
        self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)

        self.setWindowTitle(self.defaultTitle(
        ))  # overwriten by workspace when file or it's modified state changes
        self.setWindowIcon(QIcon(':/enkiicons/logo/enki.svg'))

        # Create top tool bar
        self._topToolBar = QToolBar("topToolBar")
        self._topToolBar.setObjectName("topToolBar")
        self._topToolBar.setMovable(False)
        self._topToolBar.setIconSize(QSize(16, 16))
        self._topToolBar.setContextMenuPolicy(
            Qt.PreventContextMenu)  # to avoid possibility to hide the toolbar

        # Create menu bar
        self._menuBar = ActionMenuBar(self, core.actionManager())
        self._initMenubarAndStatusBarLayout()

        # create central layout
        widget = QWidget(self)
        self._centralLayout = QVBoxLayout(widget)
        self._centralLayout.setContentsMargins(0, 0, 0, 0)
        self.setCentralWidget(widget)
        self.setStyleSheet('QMainWindow::separator{width: 4px}')

    def _initActions(self):
        """ Public method for actionManager. """

        self._createMenuStructure()
        core.actionManager().action('mView/aOpenMainMenu').triggered.connect(
            self._openMainMenu)
        core.actionManager().action('mFile/aQuit').triggered.connect(
            self.onQuit)

    def terminate(self):
        """Explicitly called destructor
        """
        if self._queuedMessageToolBar:
            self.removeToolBar(self._queuedMessageToolBar)
            del self._queuedMessageToolBar

        for act in self._createdActions:
            core.actionManager().removeAction(act)
        for menuPath in self._createdMenuPathes[::-1]:
            core.actionManager().removeMenu(menuPath)

    @staticmethod
    def _isMenuEmbeddedToTaskBar():
        """On Unity (Ubuntu) and MacOS menu bar is embedded to task bar
        """
        return 'UBUNTU_MENUPROXY' in os.environ or \
               os.environ.get('XDG_CURRENT_DESKTOP') == 'Unity' or \
               'darwin' == sys.platform

    def _initMenubarAndStatusBarLayout(self):
        """Create top widget and put it on its place
        """
        if not 'darwin' == sys.platform:
            # on Ubuntu toolbar, docs and editor area look as one widget. Ugly
            # Therefore it is separated with line. On Mac seems OK
            # I can't predict, how it will look on other platforms, therefore line is used for all, except Mac
            toolBarStyleSheet = "QToolBar {border: 0; border-bottom-width: 1; border-bottom-style: solid}" ""
            self._topToolBar.setStyleSheet(toolBarStyleSheet)

        area = Qt.BottomToolBarArea if self._isMenuEmbeddedToTaskBar(
        ) else Qt.TopToolBarArea
        self.addToolBar(area, self._topToolBar)

        if self._isMenuEmbeddedToTaskBar():  # separate menu bar
            self.setMenuBar(self._menuBar)
        else:  # menubar, statusbar and editor tool bar on one line
            self._menuBar.setAutoFillBackground(False)
            menuBarStyleSheet = """
            QMenuBar {background-color: transparent;
                      color: %s}
            QMenuBar::item:!selected {background: transparent;}
            """ % self.palette().color(QPalette.WindowText).name()
            self._menuBar.setStyleSheet(menuBarStyleSheet)
            self._menuBar.setSizePolicy(QSizePolicy.MinimumExpanding,
                                        QSizePolicy.Minimum)

            self._topToolBar.addWidget(self._menuBar)

        # Create status bar
        self._statusBar = _StatusBar(self)
        self._topToolBar.addWidget(self._statusBar)

    def _initQueuedMessageToolBar(self):
        from enki.core.queued_msg_tool_bar import QueuedMessageToolBar

        self._queuedMessageToolBar = QueuedMessageToolBar(self)
        area = Qt.TopToolBarArea if self._isMenuEmbeddedToTaskBar(
        ) else Qt.BottomToolBarArea
        self.addToolBar(area, self._queuedMessageToolBar)
        self._queuedMessageToolBar.setVisible(False)

    def _createMenuStructure(self):
        """Fill menu bar with items. The majority of items are not connected to the slots,
        Connections made by module, which implements menu item functionality, but, all items are in one place,
        because it's easier to create clear menu layout
        """

        # create menubar menus and actions

        def menu(path, name, icon, visible=True):
            """Subfunction for create a menu in the main menu"""
            menuObject = core.actionManager().addMenu(path, name)
            if icon:
                menuObject.setIcon(QIcon(':/enkiicons/' + icon))
            self._createdMenuPathes.append(path)
            if not visible:
                menuObject.setVisible(False)

        def action(path,
                   name,
                   icon,
                   shortcut,
                   tooltip,
                   enabled,
                   checkable=False):  # pylint: disable=R0913
            """Subfunction for create an action in the main menu"""
            if icon:  # has icon
                actObject = core.actionManager().addAction(
                    path, name, QIcon(':/enkiicons/' + icon), shortcut)
            else:
                actObject = core.actionManager().addAction(path,
                                                           name,
                                                           shortcut=shortcut)
            if tooltip:
                actObject.setStatusTip(tooltip)
            actObject.setEnabled(enabled)
            actObject.setCheckable(checkable)
            self._createdActions.append(actObject)

        def separator(menu):
            """Subfunction for insert separator to the menu"""
            core.actionManager().action(menu).menu().addSeparator()

        # pylint: disable=C0301
        # enable long lines for menu items
        # Menu or action path                          Name                     Icon            Shortcut        Hint                     enabled  checkable
        menu("mFile", "File", "")
        action("mFile/aOpenProject", "Open Pro&ject...", "open.png",
               "Shift+Ctrl+O", "Open a project", True)
        separator("mFile")
        menu("mFile/mUndoClose", "Undo Close", "recents.png")
        separator("mFile")
        action("mFile/aNew", "&New file...", "new.png", 'Ctrl+N', "New file",
               True)
        action("mFile/aOpen", "&Open...", "open.png", "Ctrl+O", "Open a file",
               True)
        menu("mFile/mSave", "&Save", "save.png")
        action("mFile/mSave/aCurrent", "&Save", "save.png", "Ctrl+S",
               "Save the current file", False)
        action("mFile/mSave/aSaveAs", "Save As...", "save.png", "Ctrl+Alt+S",
               "", False)
        action("mFile/mSave/aAll", "Save &All", "saveall.png", 'Shift+Ctrl+S',
               "Save all files", False)
        menu("mFile/mReload", "&Reload", "reload.png")
        action("mFile/mReload/aCurrent", "Reload", "reload.png", 'F5',
               "Reload the current file", False)
        action("mFile/mReload/aAll", "Reload All", "reload.png", 'Shift+F5',
               "Reload all files", True)
        menu("mFile/mClose", "&Close", "close.png")
        action("mFile/mClose/aCurrent", "&Close", "close.png", "Ctrl+W",
               "Close the current file", False)
        action("mFile/mClose/aAll", "Close &All", "closeall.png",
               'Shift+Ctrl+W', "Close all files", False)
        menu("mFile/mFileSystem", "File System", "filesystem.png")
        action("mFile/mFileSystem/aRename", "Rename", "edit.png", '',
               "Rename current file", False)
        if platform.system() != 'Windows':
            action("mFile/mFileSystem/aToggleExecutable", "Make executable",
                   "", '', "Toggle executable mode", False)
        separator("mFile")
        action("mFile/aQuit", "Quit", "quit.png", 'Ctrl+Q', "Quit", True)
        separator("mFile")

        menu("mView", "View", "")
        action("mView/aShowIncorrectIndentation", "Show incorrect indentation",
               "", "", "", False, True)
        action("mView/aShowAnyWhitespaces", "Show any whitespace", "", "", "",
               False, True)
        separator("mView")
        action("mView/aHideAll", "Hide all / Restore", "", "Shift+Esc",
               "Hide all widgets", True)
        action("mView/aOpenMainMenu", "Open main menu", "", "F10", "", True)
        separator("mView")

        menu("mEdit", "Edit", "")
        action("mEdit/aStripTrailingWhitespace",
               "Strip trailing whitespace when saving", "", "", "", True, True)
        separator("mEdit")
        menu("mEdit/mCopyPasteLines", "Copy-paste lines", "")
        menu("mEdit/mIndentation", "Indentation", "")
        separator("mEdit")
        action("mEdit/aEnableVimMode", "Enable Vim mode", "", "", "", False,
               True)

        menu("mNavigation", "Navigation", "")
        action("mNavigation/aFocusCurrentDocument", "Focus to editor",
               "text.png", "Ctrl+Return", "Focus current document", False)

        menu("mNavigation/mSearchReplace", "&Search && Replace",
             "search-replace-directory.png")
        menu("mNavigation/mBookmarks", "&Bookmarks", "bookmark.png")

        separator("mNavigation"),
        action("mNavigation/aNext", "&Next file", "next.png", "Ctrl+PgDown",
               "Next file", False)
        action("mNavigation/aPrevious", "&Previous file", "previous.png",
               "Ctrl+PgUp", "Previous file", False)
        separator("mNavigation")
        action("mNavigation/aGoto", "Go go line...", "goto.png", "Ctrl+G",
               "Go to line...", False)
        menu("mNavigation/mFileBrowser",
             "File browser",
             ':/enkiicons/open.png',
             visible=False)
        menu("mNavigation/mScroll", "Scroll file", '')

        menu("mSettings", "Settings", "")

        menu("mTools", "Tools", "")
        menu("mHelp", "Help", "")

    @pyqtSlot()
    def _openMainMenu(self):
        fileMenu = core.actionManager().menu('mFile')
        self._menuBar.setActiveAction(fileMenu.menuAction())

    def menuBar(self):
        """Reference to menuBar
        """
        return self._menuBar

    def topToolBar(self):
        """Top tool bar. Contains main menu, position indicator, etc
        """
        return self._topToolBar

    def statusBar(self):
        """Return main window status bar.
        It is located on the top tool bar
        """
        return self._statusBar

    def setWorkspace(self, workspace):
        """Set central widget of the main window.
        Normally called only by core when initializing system
        """
        self._centralLayout.addWidget(workspace)
        self.setFocusProxy(workspace)

    def defaultTitle(self):
        """Default title. Contains  name and version
        """
        return "%s v.%s" % (enki.core.defines.PACKAGE_NAME,
                            enki.core.defines.PACKAGE_VERSION)

    def centralLayout(self):
        """Layout of the central widget. Contains Workspace and search widget
        """
        return self._centralLayout

    def appendMessage(self, text, timeoutMs=10000):
        """Append message to the queue. It will be shown as non-modal at the bottom of the window.
        Use such notifications, which are too long or too important for status bar
        but, not so important, to interrupt an user with QMessageBox
        """
        if self._queuedMessageToolBar is None:
            self._initQueuedMessageToolBar()

        self._queuedMessageToolBar.appendMessage(text, timeoutMs)

    def closeEvent(self, event):
        """NOT A PUBLIC API
        Close event handler.
        Shows save files dialog. Cancels close, if dialog was rejected
        """

        # saving geometry BEFORE closing widgets, because state might be changed, when docks are closed
        self._saveState()
        self._saveGeometry()

        # request close all documents
        if not core.workspace().askToCloseAll():
            event.ignore()
            return

        core.aboutToTerminate.emit()
        self.hide()

        core.workspace().forceCloseAllDocuments()

        return QMainWindow.closeEvent(self, event)

    def onQuit(self):
        # saving geometry BEFORE closing widgets, because state might be changed, when docks are closed
        self._saveState()
        self._saveGeometry()

        # request close all documents
        if not core.workspace().askToCloseAll():
            return

        core.aboutToTerminate.emit()
        self.hide()

        core.workspace().forceCloseAllDocuments()

        return QApplication.quit()

    def _saveByteArray(self, path, title, data):
        """Load data, show error and return None if failed"""
        try:
            with open(path, 'wb') as f:
                f.write(data)
        except (OSError, IOError) as ex:
            error = str(ex)
            QMessageBox.critical(
                None, self.tr("Cannot save {}".format(title)),
                self.tr("Cannot create file '%s'\nError: %s" % (path, error)))
            return

    def _loadByteArray(self, path, title):
        """Load data, show error and return None if failed"""
        if os.path.exists(path):
            try:
                with open(path, 'rb') as f:
                    return f.read()
            except (OSError, IOError) as ex:
                error = str(ex)
                QMessageBox.critical(
                    None, self.tr("Cannot restore {}".format(title)),
                    self.tr("Cannot read file '%s'\nError: %s" %
                            (path, error)))

        return None

    def _saveState(self):
        """Save window state to main_window_state.bin file in the config directory
        """
        self._saveByteArray(self._STATE_FILE, "main window state",
                            self.saveState())

    def loadState(self):
        """Restore window state from main_window_state.bin and config.
        Called by the core after all plugins had been initialized
        """
        self._restoreGeometry()

        state = self._loadByteArray(self._STATE_FILE, "main window state")

        if state is not None:
            self.restoreState(state)
        else:  # no state, first start
            self.showMaximized()
            for dock in self.findChildren(DockWidget):
                dock.show()

    def _saveGeometry(self):
        """Save window geometry to the config file
        """
        self._saveByteArray(self._GEOMETRY_FILE, "main window geometry",
                            self.saveGeometry())

    def _restoreGeometry(self):
        """Restore window geometry to the config file
        """
        geometry = self._loadByteArray(self._GEOMETRY_FILE,
                                       "main window geometry")
        if geometry is not None:
            self.restoreGeometry(geometry)

    def sizeHint(self):
        return QSize(900, 560)

    def dragEnterEvent(self, event):
        """QMainWindow method reimplementation.
        Say, that we are ready to accept dragged urls
        """
        if event.mimeData().hasUrls():
            # accept drag
            event.acceptProposedAction()

        # default handler
        QMainWindow.dragEnterEvent(self, event)

    def dropEvent(self, event):
        """QMainWindow method reimplementation.
        Open dropt files
        """
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                localFile = url.toLocalFile()
                if os.path.isfile(localFile):
                    core.workspace().openFile(localFile)
                elif os.path.isdir(localFile):
                    self.directoryDropt.emit(localFile)

        # default handler
        QMainWindow.dropEvent(self, event)

    def addDockWidget(self, area, dock):
        pass  # not a plugin API method
        """Add dock widget to previous position, if known.
        Otherwise add to specified area
        """
        assert not dock in self._addedDockWidgets
        self._addedDockWidgets.append(dock)

        if not self.restoreDockWidget(dock):
            QMainWindow.addDockWidget(self, area, dock)
        """ Scroll view to make the cursor visible.
        Otherwise cursor can disappear from the viewport.
        QTimer is used because ensureCursorVisible works only after the dock has been drawn.
        A bad fix for #319
        """
        QTimer.singleShot(0, self._ensureCursorVisible)

    def _ensureCursorVisible(self):
        # When the timer fires, first check that there's still a workspace/document.
        if core.workspace() is not None:
            document = core.workspace().currentDocument()
            if document is not None:
                document.qutepart.ensureCursorVisible

    def removeDockWidget(self, dock):
        pass  # not a plugin API method
        """Remove dock widget"""
        assert dock in self._addedDockWidgets
        self._addedDockWidgets.remove(dock)
        QMainWindow.removeDockWidget(self, dock)

    def restoreState(self, state):
        pass  # not a plugin API method
        """Restore state shows widgets, which exist
        but shall not be installed on main window
        """
        QMainWindow.restoreState(self, state)
        for dock in self.findChildren(DockWidget):
            if not dock in self._addedDockWidgets:
                dock.hide()
Example #24
0
class UIController(object):
    documentModifiedText = ""
    documentStatusBarText = "untitled"

    def __init__(self):
        self.mainWidget = scripterdialog.ScripterDialog(self)
        self.actionToolbar = QToolBar('toolBar', self.mainWidget)
        self.menu_bar = QMenuBar(self.mainWidget)

        self.actionToolbar.setObjectName('toolBar')
        self.menu_bar.setObjectName('menuBar')

        self.actions = []

        self.mainWidget.setWindowModality(Qt.NonModal)

    def initialize(self, scripter):
        self.editor = pythoneditor.CodeEditor(scripter)
        self.tabWidget = QTabWidget()
        self.statusBar = Elided_Text_Label()
        self.statusBar.setMainText('untitled')
        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)
        self.highlight = syntax.PythonHighlighter(
            self.editor.document(), syntaxstyles.DefaultSyntaxStyle())
        p = self.editor.palette()
        p.setColor(
            QPalette.Base,
            syntaxstyles.DefaultSyntaxStyle()
            ['background'].foreground().color())
        p.setColor(
            QPalette.Text,
            syntaxstyles.DefaultSyntaxStyle()
            ['foreground'].foreground().color())
        self.editor.setPalette(p)

        self.scripter = scripter

        self.loadMenus()
        self.loadWidgets()
        self.loadActions()
        self._readSettings()  # sets window size

        vbox = QVBoxLayout(self.mainWidget)
        vbox.addWidget(self.menu_bar)
        vbox.addWidget(self.actionToolbar)
        self.splitter.addWidget(self.editor)
        self.splitter.addWidget(self.tabWidget)
        vbox.addWidget(self.splitter)
        vbox.addWidget(self.statusBar)

        self.mainWidget.setWindowTitle(i18n("Scripter"))
        self.mainWidget.setSizeGripEnabled(True)
        self.mainWidget.show()
        self.mainWidget.activateWindow()

        self.editor.undoAvailable.connect(self.setStatusModified)

    def loadMenus(self):
        self.addMenu(i18n('File'), i18n('File'))

    def addMenu(self, menuName, parentName):
        parent = self.menu_bar.findChild(QObject, parentName)
        self.newMenu = None

        if parent:
            self.newMenu = parent.addMenu(menuName)
        else:
            self.newMenu = self.menu_bar.addMenu(menuName)

        self.newMenu.setObjectName(menuName)

        return self.newMenu

    def loadActions(self):
        module_path = 'scripter.ui_scripter.actions'
        actions_module = importlib.import_module(module_path)
        modules = []

        for class_path in actions_module.action_classes:
            _module = class_path[:class_path.rfind(".")]
            _klass = class_path[class_path.rfind(".") + 1:]
            modules.append(
                dict(module='{0}.{1}'.format(module_path, _module),
                     klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            action_class = getattr(m, module['klass'])
            obj = action_class(self.scripter)
            obj_parent = obj.parent
            for name in obj_parent:
                parent = self.mainWidget.findChild(QObject, i18n(name))
                self.actions.append(dict(action=obj, parent=parent))

        for action in self.actions:
            action['parent'].addAction(action['action'])

    def loadWidgets(self):
        modulePath = 'scripter.ui_scripter.tabwidgets'
        widgetsModule = importlib.import_module(modulePath)
        modules = []

        for class_path in widgetsModule.widgetClasses:
            _module = class_path[:class_path.rfind(".")]
            _klass = class_path[class_path.rfind(".") + 1:]
            modules.append(
                dict(module='{0}.{1}'.format(modulePath, _module),
                     klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            widgetClass = getattr(m, module['klass'])
            obj = widgetClass(self.scripter)
            self.tabWidget.addTab(obj, obj.objectName())

    def invokeAction(self, actionName):
        for action in self.actions:
            if action['action'].objectName() == actionName:
                method = getattr(action['action'], actionName)
                if method:
                    return method()

    def findTabWidget(self, widgetName, childName=''):
        for index in range(self.tabWidget.count()):
            widget = self.tabWidget.widget(index)
            if widget.objectName() == widgetName:
                if childName:
                    widget = widget.findChild(QObject, childName)
                return widget

    def showException(self, exception):
        QMessageBox.critical(self.editor, i18n("Error Running Script"),
                             str(exception))

    def setDocumentEditor(self, document):
        self.editor.clear()
        self.editor.moveCursor(QTextCursor.Start)
        self.editor._documentModified = False
        self.editor.setPlainText(document.data)
        self.editor.moveCursor(QTextCursor.End)

    def setStatusBar(self, value='untitled'):
        self.documentStatusBarText = value
        self.statusBar.setMainText(self.documentStatusBarText +
                                   self.documentModifiedText)

    def setStatusModified(self):
        self.documentModifiedText = ""
        if (self.editor._documentModified is True):
            self.documentModifiedText = " [Modified]"
        self.statusBar.setMainText(self.documentStatusBarText +
                                   self.documentModifiedText)

    def setActiveWidget(self, widgetName):
        widget = self.findTabWidget(widgetName)

        if widget:
            self.tabWidget.setCurrentWidget(widget)

    def setStepped(self, status):
        self.editor.setStepped(status)

    def clearEditor(self):
        self.editor.clear()

    def repaintDebugArea(self):
        self.editor.repaintDebugArea()

    def closeScripter(self):
        self.mainWidget.close()

    def _writeSettings(self):
        """ _writeSettings is a method invoked when the scripter starts, making
            control inversion. Actions can implement a writeSettings method to
            save your own settings without this method to know about it. """

        self.scripter.settings.beginGroup('scripter')

        document = self.scripter.documentcontroller.activeDocument
        if document:
            self.scripter.settings.setValue('activeDocumentPath',
                                            document.filePath)
        else:
            self.scripter.settings.setValue('activeDocumentPath', '')

        self.scripter.settings.setValue('editorFontSize',
                                        self.editor.fontInfo().pointSize())

        for action in self.actions:
            writeSettings = getattr(action['action'], "writeSettings", None)
            if callable(writeSettings):
                writeSettings()

        #  Window Geometry
        rect = self.mainWidget.geometry()
        self.scripter.settings.setValue(KEY_GEOMETRY, rect)

        self.scripter.settings.endGroup()

    def _readSettings(self):
        """ It's similar to _writeSettings, but reading the settings when the ScripterDialog is closed. """

        self.scripter.settings.beginGroup('scripter')

        activeDocumentPath = self.scripter.settings.value(
            'activeDocumentPath', '')

        if activeDocumentPath:
            if QFileInfo(activeDocumentPath).exists():
                document = self.scripter.documentcontroller.openDocument(
                    activeDocumentPath)
                self.setStatusBar(document.filePath)
                self.setDocumentEditor(document)

        for action in self.actions:
            readSettings = getattr(action['action'], "readSettings", None)
            if callable(readSettings):
                readSettings()

        pointSize = self.scripter.settings.value(
            'editorFontSize', str(self.editor.fontInfo().pointSize()))
        self.editor.setFontSize(int(pointSize))

        # Window Geometry
        rect = self.scripter.settings.value(KEY_GEOMETRY, DEFAULT_GEOMETRY)
        self.mainWidget.setGeometry(rect)

        self.scripter.settings.endGroup()

    def _saveSettings(self):
        self.scripter.settings.sync()
Example #25
0
class MainWindow(QMainWindow):
    """
    Main UI window

    Class creates window elements, fills main menu with items.

    If you need to access to some existing menu items - check action path
    in the class constructor, than use next code: ::

        core.actionManager().action("mFile/aOpen").setEnabled(True)
        core.actionManager().action("mFile/aOpen").triggered.connect(self.myCoolMethod)

    MainWindow instance is accessible as: ::

        from enki.core.core import core
        core.mainwindow()

    Created by the core
    """

    hideAllWindows = pyqtSignal()
    """
    hideAllWindows()

    **Signal** emitted, when user toggled "Hide all" .
    Dock widgets are closed automatically, but other widgets, i.e. search widget, must catch this signal and close
    themselves.
    """  # pylint: disable=W0105

    directoryDropt = pyqtSignal(str)
    """
    directoryDropt()

    **Signal** emitted, when user drag-n-dropt directory to main windowd.
    FileBrowser shows directory
    """  # pylint: disable=W0105

    _STATE_FILE = os.path.join(enki.core.defines.CONFIG_DIR, "main_window_state.bin")
    _GEOMETRY_FILE = os.path.join(enki.core.defines.CONFIG_DIR, "main_window_geometry.bin")

    def __init__(self):
        QMainWindow.__init__(self)

        self._queuedMessageToolBar = None
        self._createdMenuPathes = []
        self._createdActions = []

        self._addedDockWidgets = []

        if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):  # missing on some PyQt5 versions
            self.setUnifiedTitleAndToolBarOnMac(True)
        self.setIconSize(QSize(16, 16))
        self.setAcceptDrops(True)

        # Set corner settings for dock widgets
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)
        self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)

        self.setWindowTitle(self.defaultTitle())  # overwriten by workspace when file or it's modified state changes
        self.setWindowIcon(QIcon(':/enkiicons/logo/enki.svg'))

        # Create top tool bar
        self._topToolBar = QToolBar("topToolBar")
        self._topToolBar.setObjectName("topToolBar")
        self._topToolBar.setMovable(False)
        self._topToolBar.setIconSize(QSize(16, 16))
        self._topToolBar.setContextMenuPolicy(Qt.PreventContextMenu)  # to avoid possibility to hide the toolbar

        # Create menu bar
        self._menuBar = ActionMenuBar(self, core.actionManager())
        self._initMenubarAndStatusBarLayout()

        # create central layout
        widget = QWidget(self)
        self._centralLayout = QVBoxLayout(widget)
        self._centralLayout.setContentsMargins(0, 0, 0, 0)
        self.setCentralWidget(widget)
        self.setStyleSheet('QMainWindow::separator{width: 4px}')

    def _initActions(self):
        """ Public method for actionManager. """

        self._createMenuStructure()
        core.actionManager().action('mView/aOpenMainMenu').triggered.connect(self._openMainMenu)
        core.actionManager().action('mFile/aQuit').triggered.connect(self.onQuit)

    def terminate(self):
        """Explicitly called destructor
        """
        if self._queuedMessageToolBar:
            self.removeToolBar(self._queuedMessageToolBar)
            del self._queuedMessageToolBar

        for act in self._createdActions:
            core.actionManager().removeAction(act)
        for menuPath in self._createdMenuPathes[::-1]:
            core.actionManager().removeMenu(menuPath)

    @staticmethod
    def _isMenuEmbeddedToTaskBar():
        """On Unity (Ubuntu) and MacOS menu bar is embedded to task bar
        """
        return 'UBUNTU_MENUPROXY' in os.environ or \
               os.environ.get('XDG_CURRENT_DESKTOP') == 'Unity' or \
               'darwin' == sys.platform

    def _initMenubarAndStatusBarLayout(self):
        """Create top widget and put it on its place
        """
        if not 'darwin' == sys.platform:
            # on Ubuntu toolbar, docs and editor area look as one widget. Ugly
            # Therefore it is separated with line. On Mac seems OK
            # I can't predict, how it will look on other platforms, therefore line is used for all, except Mac
            toolBarStyleSheet = "QToolBar {border: 0; border-bottom-width: 1; border-bottom-style: solid}"""
            self._topToolBar.setStyleSheet(toolBarStyleSheet)

        area = Qt.BottomToolBarArea if self._isMenuEmbeddedToTaskBar() else Qt.TopToolBarArea
        self.addToolBar(area, self._topToolBar)

        if self._isMenuEmbeddedToTaskBar():  # separate menu bar
            self.setMenuBar(self._menuBar)
        else:  # menubar, statusbar and editor tool bar on one line
            self._menuBar.setAutoFillBackground(False)
            menuBarStyleSheet = """
            QMenuBar {background-color: transparent;
                      color: %s}
            QMenuBar::item:!selected {background: transparent;}
            """ % self.palette().color(QPalette.WindowText).name()
            self._menuBar.setStyleSheet(menuBarStyleSheet)
            self._menuBar.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)

            self._topToolBar.addWidget(self._menuBar)

        # Create status bar
        self._statusBar = _StatusBar(self)
        self._topToolBar.addWidget(self._statusBar)

    def _initQueuedMessageToolBar(self):
        from enki.core.queued_msg_tool_bar import QueuedMessageToolBar

        self._queuedMessageToolBar = QueuedMessageToolBar(self)
        area = Qt.TopToolBarArea if self._isMenuEmbeddedToTaskBar() else Qt.BottomToolBarArea
        self.addToolBar(area, self._queuedMessageToolBar)
        self._queuedMessageToolBar.setVisible(False)

    def _createMenuStructure(self):
        """Fill menu bar with items. The majority of items are not connected to the slots,
        Connections made by module, which implements menu item functionality, but, all items are in one place,
        because it's easier to create clear menu layout
        """
        # create menubar menus and actions

        def menu(path, name, icon, visible=True):
            """Subfunction for create a menu in the main menu"""
            menuObject = core.actionManager().addMenu(path, name)
            if icon:
                menuObject.setIcon(QIcon(':/enkiicons/' + icon))
            self._createdMenuPathes.append(path)
            if not visible:
                menuObject.setVisible(False)

        def action(path, name, icon, shortcut, tooltip, enabled, checkable=False):  # pylint: disable=R0913
            """Subfunction for create an action in the main menu"""
            if icon:  # has icon
                actObject = core.actionManager().addAction(path, name, QIcon(':/enkiicons/' + icon), shortcut)
            else:
                actObject = core.actionManager().addAction(path, name, shortcut=shortcut)
            if tooltip:
                actObject.setStatusTip(tooltip)
            actObject.setEnabled(enabled)
            actObject.setCheckable(checkable)
            self._createdActions.append(actObject)

        def separator(menu):
            """Subfunction for insert separator to the menu"""
            core.actionManager().action(menu).menu().addSeparator()

        # pylint: disable=C0301
        # enable long lines for menu items
        # Menu or action path                          Name                     Icon            Shortcut        Hint                     enabled  checkable
        menu  ("mFile",                               "File"                  , ""           )
        action("mFile/aOpenProject",                  "Open Pro&ject..."      , "open.png",     "Shift+Ctrl+O" ,"Open a project"         , True)
        separator("mFile")
        menu  ("mFile/mUndoClose",                    "Undo Close"            , "recents.png")
        separator("mFile")
        action("mFile/aNew",                          "&New file..."          , "new.png",      'Ctrl+N',       "New file"               , True)
        action("mFile/aOpen",                         "&Open..."              , "open.png",     "Ctrl+O" ,      "Open a file"            , True)
        menu  ("mFile/mSave",                         "&Save"                 , "save.png"   )
        action("mFile/mSave/aCurrent",                "&Save"                 , "save.png" ,    "Ctrl+S" ,      "Save the current file"  , False)
        action("mFile/mSave/aSaveAs",                 "Save As..."            , "save.png" ,    "Ctrl+Alt+S" ,  ""                           , False)
        action("mFile/mSave/aAll",                    "Save &All"             , "saveall.png",  'Shift+Ctrl+S', "Save all files"         , False)
        menu  ("mFile/mReload",                       "&Reload"               , "reload.png"   )
        action("mFile/mReload/aCurrent",              "Reload"                , "reload.png"  , 'F5',           "Reload the current file", False)
        action("mFile/mReload/aAll",                  "Reload All"            , "reload.png"  , 'Shift+F5',     "Reload all files"       , True)
        menu  ("mFile/mClose",                        "&Close"                , "close.png"  )
        action("mFile/mClose/aCurrent",               "&Close"                , "close.png",    "Ctrl+W",       "Close the current file" , False)
        action("mFile/mClose/aAll",                   "Close &All"            , "closeall.png", 'Shift+Ctrl+W', "Close all files"        , False)
        menu  ("mFile/mFileSystem",                   "File System"           , "filesystem.png")
        action("mFile/mFileSystem/aRename",           "Rename"                , "edit.png",     '',             "Rename current file"    , False)
        if platform.system() != 'Windows':
            action("mFile/mFileSystem/aToggleExecutable", "Make executable"   , "",            '',             "Toggle executable mode" , False)
        separator("mFile")
        action("mFile/aQuit",                         "Quit"                  , "quit.png",     'Ctrl+Q',       "Quit"                  , True)
        separator("mFile")

        menu  ("mView",                               "View"                  , ""           )
        action("mView/aShowIncorrectIndentation",      "Show incorrect indentation", "",       "",              ""                       , False, True)
        action("mView/aShowAnyWhitespaces",     "Show any whitespace",        "",              "",              ""                       , False, True)
        separator("mView")
        action("mView/aHideAll",                      "Hide all / Restore"   , "",             "Shift+Esc",   "Hide all widgets"          , True)
        action("mView/aOpenMainMenu",                 "Open main menu"       , "",             "F10",         ""                          , True)
        separator("mView")

        menu  ("mEdit",                               "Edit"                  , ""           )
        action("mEdit/aStripTrailingWhitespace",      "Strip trailing whitespace when saving", "", "",            ""                   , True, True)
        separator("mEdit")
        menu  ("mEdit/mCopyPasteLines",               "Copy-paste lines"      , ""           )
        menu  ("mEdit/mIndentation",                  "Indentation"           , ""           )
        separator("mEdit")
        action("mEdit/aEnableVimMode",                "Enable Vim mode"       , "",             "",             ""                      , False, True)

        menu  ("mNavigation",                          "Navigation"            , ""          )
        action("mNavigation/aFocusCurrentDocument",   "Focus to editor"       , "text.png",     "Ctrl+Return",  "Focus current document" , False)

        menu  ("mNavigation/mSearchReplace",           "&Search && Replace"    , "search-replace-directory.png")
        menu  ("mNavigation/mBookmarks",               "&Bookmarks"            , "bookmark.png")

        separator("mNavigation"),
        action("mNavigation/aNext",                   "&Next file"            , "next.png",     "Ctrl+PgDown",    "Next file"              , False)
        action("mNavigation/aPrevious",               "&Previous file"        , "previous.png", "Ctrl+PgUp",     "Previous file"          , False)
        separator("mNavigation")
        action("mNavigation/aGoto",                   "Go go line..."         , "goto.png",     "Ctrl+G",       "Go to line..."          , False)
        menu  ("mNavigation/mFileBrowser",            "File browser"          , ':/enkiicons/open.png', visible=False)
        menu  ("mNavigation/mScroll",                 "Scroll file"           , '')

        menu  ("mSettings",                           "Settings"              , ""           )

        menu  ("mTools",                              "Tools"                 , ""           )
        menu  ("mHelp",                               "Help"                  , ""           )

    @pyqtSlot()
    def _openMainMenu(self):
        fileMenu = core.actionManager().menu('mFile')
        self._menuBar.setActiveAction(fileMenu.menuAction())

    def menuBar(self):
        """Reference to menuBar
        """
        return self._menuBar

    def topToolBar(self):
        """Top tool bar. Contains main menu, position indicator, etc
        """
        return self._topToolBar

    def statusBar(self):
        """Return main window status bar.
        It is located on the top tool bar
        """
        return self._statusBar

    def setWorkspace(self, workspace):
        """Set central widget of the main window.
        Normally called only by core when initializing system
        """
        self._centralLayout.addWidget(workspace)
        self.setFocusProxy(workspace)

    def defaultTitle(self):
        """Default title. Contains  name and version
        """
        return "%s v.%s" % (enki.core.defines.PACKAGE_NAME, enki.core.defines.PACKAGE_VERSION)

    def centralLayout(self):
        """Layout of the central widget. Contains Workspace and search widget
        """
        return self._centralLayout

    def appendMessage(self, text, timeoutMs=10000):
        """Append message to the queue. It will be shown as non-modal at the bottom of the window.
        Use such notifications, which are too long or too important for status bar
        but, not so important, to interrupt an user with QMessageBox
        """
        if self._queuedMessageToolBar is None:
            self._initQueuedMessageToolBar()

        self._queuedMessageToolBar.appendMessage(text, timeoutMs)

    def closeEvent(self, event):
        """NOT A PUBLIC API
        Close event handler.
        Shows save files dialog. Cancels close, if dialog was rejected
        """

        # saving geometry BEFORE closing widgets, because state might be changed, when docks are closed
        self._saveState()
        self._saveGeometry()

        # request close all documents
        if not core.workspace().askToCloseAll():
            event.ignore()
            return

        core.aboutToTerminate.emit()
        self.hide()

        core.workspace().forceCloseAllDocuments()

        return QMainWindow.closeEvent(self, event)

    def onQuit(self):
        # saving geometry BEFORE closing widgets, because state might be changed, when docks are closed
        self._saveState()
        self._saveGeometry()

        # request close all documents
        if not core.workspace().askToCloseAll():
            return

        core.aboutToTerminate.emit()
        self.hide()

        core.workspace().forceCloseAllDocuments()

        return QApplication.quit()

    def _saveByteArray(self, path, title, data):
        """Load data, show error and return None if failed"""
        try:
            with open(path, 'wb') as f:
                f.write(data)
        except (OSError, IOError) as ex:
            error = str(ex)
            QMessageBox.critical(None,
                                 self.tr("Cannot save {}".format(title)),
                                 self.tr("Cannot create file '%s'\nError: %s" % (path, error)))
            return

    def _loadByteArray(self, path, title):
        """Load data, show error and return None if failed"""
        if os.path.exists(path):
            try:
                with open(path, 'rb') as f:
                    return f.read()
            except (OSError, IOError) as ex:
                error = str(ex)
                QMessageBox.critical(None,
                                     self.tr("Cannot restore {}".format(title)),
                                     self.tr("Cannot read file '%s'\nError: %s" % (path, error)))

        return None

    def _saveState(self):
        """Save window state to main_window_state.bin file in the config directory
        """
        self._saveByteArray(self._STATE_FILE, "main window state", self.saveState())

    def loadState(self):
        """Restore window state from main_window_state.bin and config.
        Called by the core after all plugins had been initialized
        """
        self._restoreGeometry()

        state = self._loadByteArray(self._STATE_FILE, "main window state")

        if state is not None:
            self.restoreState(state)
        else:  # no state, first start
            self.showMaximized()
            for dock in self.findChildren(DockWidget):
                dock.show()

    def _saveGeometry(self):
        """Save window geometry to the config file
        """
        self._saveByteArray(self._GEOMETRY_FILE, "main window geometry", self.saveGeometry())

    def _restoreGeometry(self):
        """Restore window geometry to the config file
        """
        geometry = self._loadByteArray(self._GEOMETRY_FILE, "main window geometry")
        if geometry is not None:
            self.restoreGeometry(geometry)

    def sizeHint(self):
        return QSize(900, 560)

    def dragEnterEvent(self, event):
        """QMainWindow method reimplementation.
        Say, that we are ready to accept dragged urls
        """
        if event.mimeData().hasUrls():
            # accept drag
            event.acceptProposedAction()

        # default handler
        QMainWindow.dragEnterEvent(self, event)

    def dropEvent(self, event):
        """QMainWindow method reimplementation.
        Open dropt files
        """
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                localFile = url.toLocalFile()
                if os.path.isfile(localFile):
                    core.workspace().openFile(localFile)
                elif os.path.isdir(localFile):
                    self.directoryDropt.emit(localFile)

        # default handler
        QMainWindow.dropEvent(self, event)

    def addDockWidget(self, area, dock):
        pass  # not a plugin API method
        """Add dock widget to previous position, if known.
        Otherwise add to specified area
        """
        assert not dock in self._addedDockWidgets
        self._addedDockWidgets.append(dock)

        if not self.restoreDockWidget(dock):
            QMainWindow.addDockWidget(self, area, dock)

        """ Scroll view to make the cursor visible.
        Otherwise cursor can disappear from the viewport.
        QTimer is used because ensureCursorVisible works only after the dock has been drawn.
        A bad fix for #319
        """
        QTimer.singleShot(0, self._ensureCursorVisible)

    def _ensureCursorVisible(self):
        # When the timer fires, first check that there's still a workspace/document.
        if core.workspace() is not None:
            document = core.workspace().currentDocument()
            if document is not None:
                document.qutepart.ensureCursorVisible

    def removeDockWidget(self, dock):
        pass  # not a plugin API method
        """Remove dock widget"""
        assert dock in self._addedDockWidgets
        self._addedDockWidgets.remove(dock)
        QMainWindow.removeDockWidget(self, dock)

    def restoreState(self, state):
        pass  # not a plugin API method
        """Restore state shows widgets, which exist
        but shall not be installed on main window
        """
        QMainWindow.restoreState(self, state)
        for dock in self.findChildren(DockWidget):
            if not dock in self._addedDockWidgets:
                dock.hide()
class _ToolsDock(QWidget):
    """Former Miscellaneous, contains all the widgets in the bottom area."""

    findStarted = pyqtSignal()
    splitEditor = pyqtSignal(QWidget, QWidget, bool)
    closeSplit = pyqtSignal(QWidget)

    def __init__(self, parent=None):
        super(_ToolsDock, self).__init__(parent)
        #Register signals connections
        connections = (
            {
                'target': 'main_container',
                'signal_name': "findOcurrences",  #(QString)
                'slot': self.show_find_occurrences
            },
            {
                'target': 'main_container',
                'signal_name': "runFile",  #(QString)
                'slot': self.execute_file
            },
        )
        IDE.register_signals('tools_dock', connections)
        IDE.register_service("tools_dock", self)

    def setup_ui(self):
        """Load all the components of the ui during the install process."""
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        self.__toolbar = QToolBar()
        self.__toolbar.setObjectName('custom')
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.stack = StackedWidget()
        vbox.addWidget(self.stack)

        self._console = console_widget.ConsoleWidget()
        self._runWidget = run_widget.RunWidget()
        self._web = web_render.WebRender()
        self._findInFilesWidget = find_in_files.FindInFilesWidget(
            self.parent())

        # Not Configurable Shortcuts
        shortEscMisc = QShortcut(QKeySequence(Qt.Key_Escape), self)

        shortEscMisc.activated.connect(self.hide)

        #Toolbar
        hbox.addWidget(self.__toolbar)
        self.add_to_stack(self._console, ":img/console",
                          translations.TR_CONSOLE)
        self.add_to_stack(self._runWidget, ":img/play", translations.TR_OUTPUT)
        self.add_to_stack(self._web, ":img/web", translations.TR_WEB_PREVIEW)
        self.add_to_stack(self._findInFilesWidget, ":img/find",
                          translations.TR_FIND_IN_FILES)
        #Last Element in the Stacked widget
        self._results = results.Results(self)
        self.stack.addWidget(self._results)
        # self.__toolbar.addSeparator()

        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        btn_close.setIconSize(QSize(24, 24))
        btn_close.setObjectName('navigation_button')
        btn_close.setToolTip('F4: ' + translations.TR_ALL_VISIBILITY)
        hbox.addWidget(btn_close)
        btn_close.clicked['bool'].connect(self.hide)

    def install(self):
        """Install triggered by the ide."""
        self.setup_ui()
        ninjaide = IDE.getInstance()
        ninjaide.place_me_on("tools_dock", self, "central")
        ui_tools.install_shortcuts(self, actions.ACTIONS, ninjaide)

        ninjaide.goingDown.connect(self.save_configuration)

        qsettings = IDE.ninja_settings()
        value = qsettings.value("tools_dock/visible", True, type=bool)
        self.setVisible(value)
        print("\ninstall")

    def save_configuration(self):
        qsettings = IDE.ninja_settings()
        qsettings.setValue("tools_dock/visible", self.isVisible())

    def change_visibility(self):
        """Change tools dock visibility."""
        print("change_visibility22", self.isVisible())
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def add_project_to_console(self, projectFolder):
        """Add the namespace of the project received into the ninja-console."""
        self._console.load_project_into_console(projectFolder)

    def remove_project_from_console(self, projectFolder):
        """Remove the namespace of the project received from the console."""
        self._console.unload_project_from_console(projectFolder)

    def _item_changed(self, val):
        """Change the current item."""
        print("_item_changed", val)
        if not self.isVisible():
            self.show()
        self.stack.show_display(val)

    def show_find_in_files_widget(self):
        """Show the Find In Files widget."""
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.open()
        self._findInFilesWidget.setFocus()

    def show_find_occurrences(self, word):
        """Show Find In Files widget in find occurrences mode."""
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.find_occurrences(word)
        self._findInFilesWidget.setFocus()

    def execute_file(self):
        """Execute the current file."""
        main_container = IDE.get_service('main_container')
        if not main_container:
            return
        editorWidget = main_container.get_current_editor()
        if editorWidget:
            #emit a signal for plugin!
            self.fileExecuted.emit(editorWidget.file_path)
            main_container.save_file(editorWidget)
            ext = file_manager.get_file_extension(editorWidget.file_path)
            #TODO: Remove the IF statment and use Handlers
            if ext == 'py':
                self._run_application(editorWidget.file_path)
            elif ext == 'html':
                self.render_web_page(editorWidget.file_path)

    def execute_project(self):
        """Execute the project marked as Main Project."""
        projects_explorer = IDE.get_service('projects_explorer')
        if projects_explorer is None:
            return
        nproject = projects_explorer.current_project
        if nproject:
            main_file = nproject.main_file
            if not main_file and projects_explorer.current_tree:
                projects_explorer.current_tree.open_project_properties()
            elif main_file:
                projects_explorer.save_project()
                #emit a signal for plugin!
                self.projectExecuted.emit(nproject.path)

                main_file = file_manager.create_path(nproject.path,
                                                     nproject.main_file)
                self._run_application(main_file,
                                      pythonExec=nproject.python_exec_command,
                                      PYTHONPATH=nproject.python_path,
                                      programParams=nproject.program_params,
                                      preExec=nproject.pre_exec_script,
                                      postExec=nproject.post_exec_script)
        else:
            QMessageBox.information(
                self, translations.TR_INFO_TITLE_PROJECT_PROPERTIES,
                translations.TR_INFO_MESSAGE_PROJECT_PROPERTIES)

    def _run_application(self,
                         fileName,
                         pythonExec=False,
                         PYTHONPATH=None,
                         programParams='',
                         preExec='',
                         postExec=''):
        """Execute the process to run the application."""
        self._item_changed(1)
        self.show()
        self._runWidget.start_process(fileName, pythonExec, PYTHONPATH,
                                      programParams, preExec, postExec)
        self._runWidget.input.setFocus()

    def show_results(self, items):
        """Show Results of Navigate to for several occurrences."""
        index_of = self.stack.indexOf(self._results)
        self._item_changed(index_of)
        self.show()
        self._results.update_result(items)
        self._results._tree.setFocus()
        self._results.setFocus()

    def kill_application(self):
        """Kill the process of the application being executed."""
        self._runWidget.kill_process()

    def render_web_page(self, url):
        """Render a webpage from the url path."""
        index_of = self.stack.indexOf(self._web)
        self._item_changed(index_of)
        self.show()
        self._web.render_page(url)
        if settings.SHOW_WEB_INSPECTOR:
            web_inspector = IDE.get_service('web_inspector')
            if web_inspector:
                web_inspector.set_inspection_page(self._web.webFrame.page())
                self._web.webFrame.triggerPageAction(QWebPage.InspectElement,
                                                     True)
                web_inspector.refresh_inspector()
        self._web.setFocus()

    def add_to_stack(self, widget, icon_path, description):
        """
        Add a widget to the container and an button(with icon))to the toolbar
        to show the widget
        """
        #add the widget
        self.stack.addWidget(widget)
        #create a button in the toolbar to show the widget
        button = QPushButton(QIcon(icon_path), '')
        button.setIconSize(QSize(16, 16))
        button.setToolTip(description)
        index = self.stack.count() - 1
        button.clicked['bool'].connect(
            lambda s, i=index: self._item_changed(i))
        self.__toolbar.addWidget(button)

    def showEvent(self, event):
        super(_ToolsDock, self).showEvent(event)
        widget = self.stack.currentWidget()
        if widget:
            widget.setFocus()
Example #27
0
class SvnProjectHelper(VcsProjectHelper):
    """
    Class implementing the VCS project helper for Subversion.
    """
    def __init__(self, vcsObject, projectObject, parent=None, name=None):
        """
        Constructor
        
        @param vcsObject reference to the vcs object
        @param projectObject reference to the project object
        @param parent parent widget (QWidget)
        @param name name of this object (string)
        """
        VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name)

    def getActions(self):
        """
        Public method to get a list of all actions.
        
        @return list of all actions (list of E5Action)
        """
        return self.actions[:]

    def initActions(self):
        """
        Public method to generate the action objects.
        """
        self.vcsNewAct = E5Action(self.tr('New from repository'),
                                  UI.PixmapCache.getIcon("vcsCheckout.png"),
                                  self.tr('&New from repository...'), 0, 0,
                                  self, 'subversion_new')
        self.vcsNewAct.setStatusTip(
            self.tr('Create a new project from the VCS repository'))
        self.vcsNewAct.setWhatsThis(
            self.tr("""<b>New from repository</b>"""
                    """<p>This creates a new local project from the VCS"""
                    """ repository.</p>"""))
        self.vcsNewAct.triggered.connect(self._vcsCheckout)
        self.actions.append(self.vcsNewAct)

        self.vcsUpdateAct = E5Action(self.tr('Update from repository'),
                                     UI.PixmapCache.getIcon("vcsUpdate.png"),
                                     self.tr('&Update from repository'), 0, 0,
                                     self, 'subversion_update')
        self.vcsUpdateAct.setStatusTip(
            self.tr('Update the local project from the VCS repository'))
        self.vcsUpdateAct.setWhatsThis(
            self.tr("""<b>Update from repository</b>"""
                    """<p>This updates the local project from the VCS"""
                    """ repository.</p>"""))
        self.vcsUpdateAct.triggered.connect(self._vcsUpdate)
        self.actions.append(self.vcsUpdateAct)

        self.vcsCommitAct = E5Action(
            self.tr('Commit changes to repository'),
            UI.PixmapCache.getIcon("vcsCommit.png"),
            self.tr('&Commit changes to repository...'), 0, 0, self,
            'subversion_commit')
        self.vcsCommitAct.setStatusTip(
            self.tr(
                'Commit changes to the local project to the VCS repository'))
        self.vcsCommitAct.setWhatsThis(
            self.tr(
                """<b>Commit changes to repository</b>"""
                """<p>This commits changes to the local project to the VCS"""
                """ repository.</p>"""))
        self.vcsCommitAct.triggered.connect(self._vcsCommit)
        self.actions.append(self.vcsCommitAct)

        self.svnLogBrowserAct = E5Action(self.tr('Show log browser'),
                                         UI.PixmapCache.getIcon("vcsLog.png"),
                                         self.tr('Show log browser'), 0, 0,
                                         self, 'subversion_log_browser')
        self.svnLogBrowserAct.setStatusTip(
            self.tr('Show a dialog to browse the log of the local project'))
        self.svnLogBrowserAct.setWhatsThis(
            self.
            tr("""<b>Show log browser</b>"""
               """<p>This shows a dialog to browse the log of the local"""
               """ project. A limited number of entries is shown first. More"""
               """ can be retrieved later on.</p>"""))
        self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser)
        self.actions.append(self.svnLogBrowserAct)

        self.vcsDiffAct = E5Action(self.tr('Show differences'),
                                   UI.PixmapCache.getIcon("vcsDiff.png"),
                                   self.tr('Show &difference'), 0, 0, self,
                                   'subversion_diff')
        self.vcsDiffAct.setStatusTip(
            self.tr(
                'Show the difference of the local project to the repository'))
        self.vcsDiffAct.setWhatsThis(
            self.tr("""<b>Show differences</b>"""
                    """<p>This shows differences of the local project to the"""
                    """ repository.</p>"""))
        self.vcsDiffAct.triggered.connect(self._vcsDiff)
        self.actions.append(self.vcsDiffAct)

        self.svnExtDiffAct = E5Action(self.tr('Show differences (extended)'),
                                      UI.PixmapCache.getIcon("vcsDiff.png"),
                                      self.tr('Show differences (extended)'),
                                      0, 0, self, 'subversion_extendeddiff')
        self.svnExtDiffAct.setStatusTip(
            self.
            tr('Show the difference of revisions of the project to the repository'
               ))
        self.svnExtDiffAct.setWhatsThis(
            self.tr("""<b>Show differences (extended)</b>"""
                    """<p>This shows differences of selectable revisions of"""
                    """ the project.</p>"""))
        self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff)
        self.actions.append(self.svnExtDiffAct)

        self.svnUrlDiffAct = E5Action(self.tr('Show differences (URLs)'),
                                      UI.PixmapCache.getIcon("vcsDiff.png"),
                                      self.tr('Show differences (URLs)'), 0, 0,
                                      self, 'subversion_urldiff')
        self.svnUrlDiffAct.setStatusTip(
            self.
            tr('Show the difference of the project between two repository URLs'
               ))
        self.svnUrlDiffAct.setWhatsThis(
            self.tr("""<b>Show differences (URLs)</b>"""
                    """<p>This shows differences of the project between"""
                    """ two repository URLs.</p>"""))
        self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff)
        self.actions.append(self.svnUrlDiffAct)

        self.vcsStatusAct = E5Action(self.tr('Show status'),
                                     UI.PixmapCache.getIcon("vcsStatus.png"),
                                     self.tr('Show &status'), 0, 0, self,
                                     'subversion_status')
        self.vcsStatusAct.setStatusTip(
            self.tr('Show the status of the local project'))
        self.vcsStatusAct.setWhatsThis(
            self.tr("""<b>Show status</b>"""
                    """<p>This shows the status of the local project.</p>"""))
        self.vcsStatusAct.triggered.connect(self._vcsStatus)
        self.actions.append(self.vcsStatusAct)

        self.svnChangeListsAct = E5Action(
            self.tr('Show change lists'),
            UI.PixmapCache.getIcon("vcsChangeLists.png"),
            self.tr('Show change lists'), 0, 0, self, 'subversion_changelists')
        self.svnChangeListsAct.setStatusTip(
            self.
            tr('Show the change lists and associated files of the local project'
               ))
        self.svnChangeListsAct.setWhatsThis(
            self.
            tr("""<b>Show change lists</b>"""
               """<p>This shows the change lists and associated files of the"""
               """ local project.</p>"""))
        self.svnChangeListsAct.triggered.connect(self.__svnChangeLists)
        self.actions.append(self.svnChangeListsAct)

        self.vcsTagAct = E5Action(self.tr('Tag in repository'),
                                  UI.PixmapCache.getIcon("vcsTag.png"),
                                  self.tr('&Tag in repository...'), 0, 0, self,
                                  'subversion_tag')
        self.vcsTagAct.setStatusTip(
            self.tr('Tag the local project in the repository'))
        self.vcsTagAct.setWhatsThis(
            self.tr(
                """<b>Tag in repository</b>"""
                """<p>This tags the local project in the repository.</p>"""))
        self.vcsTagAct.triggered.connect(self._vcsTag)
        self.actions.append(self.vcsTagAct)

        self.vcsExportAct = E5Action(self.tr('Export from repository'),
                                     UI.PixmapCache.getIcon("vcsExport.png"),
                                     self.tr('&Export from repository...'), 0,
                                     0, self, 'subversion_export')
        self.vcsExportAct.setStatusTip(
            self.tr('Export a project from the repository'))
        self.vcsExportAct.setWhatsThis(
            self.tr("""<b>Export from repository</b>"""
                    """<p>This exports a project from the repository.</p>"""))
        self.vcsExportAct.triggered.connect(self._vcsExport)
        self.actions.append(self.vcsExportAct)

        self.vcsPropsAct = E5Action(self.tr('Command options'),
                                    self.tr('Command &options...'), 0, 0, self,
                                    'subversion_options')
        self.vcsPropsAct.setStatusTip(self.tr('Show the VCS command options'))
        self.vcsPropsAct.setWhatsThis(
            self.
            tr("""<b>Command options...</b>"""
               """<p>This shows a dialog to edit the VCS command options.</p>"""
               ))
        self.vcsPropsAct.triggered.connect(self._vcsCommandOptions)
        self.actions.append(self.vcsPropsAct)

        self.vcsRevertAct = E5Action(self.tr('Revert changes'),
                                     UI.PixmapCache.getIcon("vcsRevert.png"),
                                     self.tr('Re&vert changes'), 0, 0, self,
                                     'subversion_revert')
        self.vcsRevertAct.setStatusTip(
            self.tr('Revert all changes made to the local project'))
        self.vcsRevertAct.setWhatsThis(
            self.
            tr("""<b>Revert changes</b>"""
               """<p>This reverts all changes made to the local project.</p>"""
               ))
        self.vcsRevertAct.triggered.connect(self._vcsRevert)
        self.actions.append(self.vcsRevertAct)

        self.vcsMergeAct = E5Action(self.tr('Merge'),
                                    UI.PixmapCache.getIcon("vcsMerge.png"),
                                    self.tr('Mer&ge changes...'), 0, 0, self,
                                    'subversion_merge')
        self.vcsMergeAct.setStatusTip(
            self.tr('Merge changes of a tag/revision into the local project'))
        self.vcsMergeAct.setWhatsThis(
            self.tr(
                """<b>Merge</b>"""
                """<p>This merges changes of a tag/revision into the local"""
                """ project.</p>"""))
        self.vcsMergeAct.triggered.connect(self._vcsMerge)
        self.actions.append(self.vcsMergeAct)

        self.vcsSwitchAct = E5Action(self.tr('Switch'),
                                     UI.PixmapCache.getIcon("vcsSwitch.png"),
                                     self.tr('S&witch...'), 0, 0, self,
                                     'subversion_switch')
        self.vcsSwitchAct.setStatusTip(
            self.tr('Switch the local copy to another tag/branch'))
        self.vcsSwitchAct.setWhatsThis(
            self.
            tr("""<b>Switch</b>"""
               """<p>This switches the local copy to another tag/branch.</p>"""
               ))
        self.vcsSwitchAct.triggered.connect(self._vcsSwitch)
        self.actions.append(self.vcsSwitchAct)

        self.vcsResolveAct = E5Action(self.tr('Conflicts resolved'),
                                      self.tr('Con&flicts resolved'), 0, 0,
                                      self, 'subversion_resolve')
        self.vcsResolveAct.setStatusTip(
            self.tr('Mark all conflicts of the local project as resolved'))
        self.vcsResolveAct.setWhatsThis(
            self.tr("""<b>Conflicts resolved</b>"""
                    """<p>This marks all conflicts of the local project as"""
                    """ resolved.</p>"""))
        self.vcsResolveAct.triggered.connect(self.__svnResolve)
        self.actions.append(self.vcsResolveAct)

        self.vcsCleanupAct = E5Action(self.tr('Cleanup'), self.tr('Cleanu&p'),
                                      0, 0, self, 'subversion_cleanup')
        self.vcsCleanupAct.setStatusTip(self.tr('Cleanup the local project'))
        self.vcsCleanupAct.setWhatsThis(
            self.tr(
                """<b>Cleanup</b>"""
                """<p>This performs a cleanup of the local project.</p>"""))
        self.vcsCleanupAct.triggered.connect(self._vcsCleanup)
        self.actions.append(self.vcsCleanupAct)

        self.vcsCommandAct = E5Action(self.tr('Execute command'),
                                      self.tr('E&xecute command...'), 0, 0,
                                      self, 'subversion_command')
        self.vcsCommandAct.setStatusTip(
            self.tr('Execute an arbitrary VCS command'))
        self.vcsCommandAct.setWhatsThis(
            self.
            tr("""<b>Execute command</b>"""
               """<p>This opens a dialog to enter an arbitrary VCS command.</p>"""
               ))
        self.vcsCommandAct.triggered.connect(self._vcsCommand)
        self.actions.append(self.vcsCommandAct)

        self.svnTagListAct = E5Action(self.tr('List tags'),
                                      self.tr('List tags...'), 0, 0, self,
                                      'subversion_list_tags')
        self.svnTagListAct.setStatusTip(self.tr('List tags of the project'))
        self.svnTagListAct.setWhatsThis(
            self.tr("""<b>List tags</b>"""
                    """<p>This lists the tags of the project.</p>"""))
        self.svnTagListAct.triggered.connect(self.__svnTagList)
        self.actions.append(self.svnTagListAct)

        self.svnBranchListAct = E5Action(self.tr('List branches'),
                                         self.tr('List branches...'), 0, 0,
                                         self, 'subversion_list_branches')
        self.svnBranchListAct.setStatusTip(
            self.tr('List branches of the project'))
        self.svnBranchListAct.setWhatsThis(
            self.tr("""<b>List branches</b>"""
                    """<p>This lists the branches of the project.</p>"""))
        self.svnBranchListAct.triggered.connect(self.__svnBranchList)
        self.actions.append(self.svnBranchListAct)

        self.svnListAct = E5Action(self.tr('List repository contents'),
                                   self.tr('List repository contents...'), 0,
                                   0, self, 'subversion_contents')
        self.svnListAct.setStatusTip(
            self.tr('Lists the contents of the repository'))
        self.svnListAct.setWhatsThis(
            self.tr("""<b>List repository contents</b>"""
                    """<p>This lists the contents of the repository.</p>"""))
        self.svnListAct.triggered.connect(self.__svnTagList)
        self.actions.append(self.svnListAct)

        self.svnPropSetAct = E5Action(self.tr('Set Property'),
                                      self.tr('Set Property...'), 0, 0, self,
                                      'subversion_property_set')
        self.svnPropSetAct.setStatusTip(
            self.tr('Set a property for the project files'))
        self.svnPropSetAct.setWhatsThis(
            self.tr("""<b>Set Property</b>"""
                    """<p>This sets a property for the project files.</p>"""))
        self.svnPropSetAct.triggered.connect(self.__svnPropSet)
        self.actions.append(self.svnPropSetAct)

        self.svnPropListAct = E5Action(self.tr('List Properties'),
                                       self.tr('List Properties...'), 0, 0,
                                       self, 'subversion_property_list')
        self.svnPropListAct.setStatusTip(
            self.tr('List properties of the project files'))
        self.svnPropListAct.setWhatsThis(
            self.tr(
                """<b>List Properties</b>"""
                """<p>This lists the properties of the project files.</p>"""))
        self.svnPropListAct.triggered.connect(self.__svnPropList)
        self.actions.append(self.svnPropListAct)

        self.svnPropDelAct = E5Action(self.tr('Delete Property'),
                                      self.tr('Delete Property...'), 0, 0,
                                      self, 'subversion_property_delete')
        self.svnPropDelAct.setStatusTip(
            self.tr('Delete a property for the project files'))
        self.svnPropDelAct.setWhatsThis(
            self.tr(
                """<b>Delete Property</b>"""
                """<p>This deletes a property for the project files.</p>"""))
        self.svnPropDelAct.triggered.connect(self.__svnPropDel)
        self.actions.append(self.svnPropDelAct)

        self.svnRelocateAct = E5Action(self.tr('Relocate'),
                                       UI.PixmapCache.getIcon("vcsSwitch.png"),
                                       self.tr('Relocate...'), 0, 0, self,
                                       'subversion_relocate')
        self.svnRelocateAct.setStatusTip(
            self.tr('Relocate the working copy to a new repository URL'))
        self.svnRelocateAct.setWhatsThis(
            self.tr(
                """<b>Relocate</b>"""
                """<p>This relocates the working copy to a new repository"""
                """ URL.</p>"""))
        self.svnRelocateAct.triggered.connect(self.__svnRelocate)
        self.actions.append(self.svnRelocateAct)

        self.svnRepoBrowserAct = E5Action(
            self.tr('Repository Browser'),
            UI.PixmapCache.getIcon("vcsRepoBrowser.png"),
            self.tr('Repository Browser...'), 0, 0, self,
            'subversion_repo_browser')
        self.svnRepoBrowserAct.setStatusTip(
            self.tr('Show the Repository Browser dialog'))
        self.svnRepoBrowserAct.setWhatsThis(
            self.tr("""<b>Repository Browser</b>"""
                    """<p>This shows the Repository Browser dialog.</p>"""))
        self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser)
        self.actions.append(self.svnRepoBrowserAct)

        self.svnConfigAct = E5Action(self.tr('Configure'),
                                     self.tr('Configure...'), 0, 0, self,
                                     'subversion_configure')
        self.svnConfigAct.setStatusTip(
            self.
            tr('Show the configuration dialog with the Subversion page selected'
               ))
        self.svnConfigAct.setWhatsThis(
            self.tr(
                """<b>Configure</b>"""
                """<p>Show the configuration dialog with the Subversion page"""
                """ selected.</p>"""))
        self.svnConfigAct.triggered.connect(self.__svnConfigure)
        self.actions.append(self.svnConfigAct)

        self.svnUpgradeAct = E5Action(self.tr('Upgrade'),
                                      self.tr('Upgrade...'), 0, 0, self,
                                      'subversion_upgrade')
        self.svnUpgradeAct.setStatusTip(
            self.tr('Upgrade the working copy to the current format'))
        self.svnUpgradeAct.setWhatsThis(
            self.tr(
                """<b>Upgrade</b>"""
                """<p>Upgrades the working copy to the current format.</p>"""))
        self.svnUpgradeAct.triggered.connect(self.__svnUpgrade)
        self.actions.append(self.svnUpgradeAct)

    def initMenu(self, menu):
        """
        Public method to generate the VCS menu.
        
        @param menu reference to the menu to be populated (QMenu)
        """
        menu.clear()

        act = menu.addAction(
            UI.PixmapCache.getIcon(
                os.path.join("VcsPlugins",
                             "vcsSubversion", "icons", "subversion.png")),
            self.vcs.vcsName(), self._vcsInfoDisplay)
        font = act.font()
        font.setBold(True)
        act.setFont(font)
        menu.addSeparator()

        menu.addAction(self.vcsUpdateAct)
        menu.addAction(self.vcsCommitAct)
        menu.addSeparator()
        menu.addAction(self.vcsTagAct)
        if self.vcs.otherData["standardLayout"]:
            menu.addAction(self.svnTagListAct)
            menu.addAction(self.svnBranchListAct)
        else:
            menu.addAction(self.svnListAct)
        menu.addSeparator()
        menu.addAction(self.svnLogBrowserAct)
        menu.addSeparator()
        menu.addAction(self.vcsStatusAct)
        menu.addAction(self.svnChangeListsAct)
        menu.addSeparator()
        menu.addAction(self.vcsDiffAct)
        menu.addAction(self.svnExtDiffAct)
        menu.addAction(self.svnUrlDiffAct)
        menu.addSeparator()
        menu.addAction(self.vcsRevertAct)
        menu.addAction(self.vcsMergeAct)
        menu.addAction(self.vcsResolveAct)
        menu.addSeparator()
        menu.addAction(self.svnRelocateAct)
        menu.addAction(self.vcsSwitchAct)
        menu.addSeparator()
        menu.addAction(self.svnPropSetAct)
        menu.addAction(self.svnPropListAct)
        menu.addAction(self.svnPropDelAct)
        menu.addSeparator()
        menu.addAction(self.vcsCleanupAct)
        menu.addSeparator()
        menu.addAction(self.vcsCommandAct)
        menu.addAction(self.svnRepoBrowserAct)
        menu.addAction(self.svnUpgradeAct)
        menu.addSeparator()
        menu.addAction(self.vcsPropsAct)
        menu.addSeparator()
        menu.addAction(self.svnConfigAct)
        menu.addSeparator()
        menu.addAction(self.vcsNewAct)
        menu.addAction(self.vcsExportAct)

    def initToolbar(self, ui, toolbarManager):
        """
        Public slot to initialize the VCS toolbar.
        
        @param ui reference to the main window (UserInterface)
        @param toolbarManager reference to a toolbar manager object
            (E5ToolBarManager)
        """
        self.__toolbar = QToolBar(self.tr("Subversion (svn)"), ui)
        self.__toolbar.setIconSize(UI.Config.ToolBarIconSize)
        self.__toolbar.setObjectName("SubversionToolbar")
        self.__toolbar.setToolTip(self.tr('Subversion (svn)'))

        self.__toolbar.addAction(self.svnLogBrowserAct)
        self.__toolbar.addAction(self.vcsStatusAct)
        self.__toolbar.addSeparator()
        self.__toolbar.addAction(self.vcsDiffAct)
        self.__toolbar.addSeparator()
        self.__toolbar.addAction(self.svnRepoBrowserAct)
        self.__toolbar.addAction(self.vcsNewAct)
        self.__toolbar.addAction(self.vcsExportAct)
        self.__toolbar.addSeparator()

        title = self.__toolbar.windowTitle()
        toolbarManager.addToolBar(self.__toolbar, title)
        toolbarManager.addAction(self.vcsUpdateAct, title)
        toolbarManager.addAction(self.vcsCommitAct, title)
        toolbarManager.addAction(self.svnExtDiffAct, title)
        toolbarManager.addAction(self.svnUrlDiffAct, title)
        toolbarManager.addAction(self.svnChangeListsAct, title)
        toolbarManager.addAction(self.vcsTagAct, title)
        toolbarManager.addAction(self.vcsRevertAct, title)
        toolbarManager.addAction(self.vcsMergeAct, title)
        toolbarManager.addAction(self.vcsSwitchAct, title)
        toolbarManager.addAction(self.svnRelocateAct, title)

        self.__toolbar.setEnabled(False)
        self.__toolbar.setVisible(False)

        ui.registerToolbar("subversion", self.__toolbar.windowTitle(),
                           self.__toolbar)
        ui.addToolBar(self.__toolbar)

    def removeToolbar(self, ui, toolbarManager):
        """
        Public method to remove a toolbar created by initToolbar().
        
        @param ui reference to the main window (UserInterface)
        @param toolbarManager reference to a toolbar manager object
            (E5ToolBarManager)
        """
        ui.removeToolBar(self.__toolbar)
        ui.unregisterToolbar("subversion")

        title = self.__toolbar.windowTitle()
        toolbarManager.removeCategoryActions(title)
        toolbarManager.removeToolBar(self.__toolbar)

        self.__toolbar.deleteLater()
        self.__toolbar = None

    def __svnResolve(self):
        """
        Private slot used to resolve conflicts of the local project.
        """
        self.vcs.svnResolve(self.project.ppath)

    def __svnPropList(self):
        """
        Private slot used to list the properties of the project files.
        """
        self.vcs.svnListProps(self.project.ppath, True)

    def __svnPropSet(self):
        """
        Private slot used to set a property for the project files.
        """
        self.vcs.svnSetProp(self.project.ppath, True)

    def __svnPropDel(self):
        """
        Private slot used to delete a property for the project files.
        """
        self.vcs.svnDelProp(self.project.ppath, True)

    def __svnTagList(self):
        """
        Private slot used to list the tags of the project.
        """
        self.vcs.svnListTagBranch(self.project.ppath, True)

    def __svnBranchList(self):
        """
        Private slot used to list the branches of the project.
        """
        self.vcs.svnListTagBranch(self.project.ppath, False)

    def __svnExtendedDiff(self):
        """
        Private slot used to perform a svn diff with the selection of
        revisions.
        """
        self.vcs.svnExtendedDiff(self.project.ppath)

    def __svnUrlDiff(self):
        """
        Private slot used to perform a svn diff with the selection of
        repository URLs.
        """
        self.vcs.svnUrlDiff(self.project.ppath)

    def __svnRelocate(self):
        """
        Private slot used to relocate the working copy to a new repository URL.
        """
        self.vcs.svnRelocate(self.project.ppath)

    def __svnRepoBrowser(self):
        """
        Private slot to open the repository browser.
        """
        self.vcs.svnRepoBrowser(projectPath=self.project.ppath)

    def __svnConfigure(self):
        """
        Private slot to open the configuration dialog.
        """
        e5App().getObject("UserInterface").showPreferences(
            "zzz_subversionPage")

    def __svnChangeLists(self):
        """
        Private slot used to show a list of change lists.
        """
        self.vcs.svnShowChangelists(self.project.ppath)

    def __svnUpgrade(self):
        """
        Private slot used to upgrade the working copy format.
        """
        self.vcs.svnUpgrade(self.project.ppath)
Example #28
0
class SvnProjectHelper(VcsProjectHelper):
    """
    Class implementing the VCS project helper for Subversion.
    """
    def __init__(self, vcsObject, projectObject, parent=None, name=None):
        """
        Constructor
        
        @param vcsObject reference to the vcs object
        @param projectObject reference to the project object
        @param parent parent widget (QWidget)
        @param name name of this object (string)
        """
        VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name)
        
    def getActions(self):
        """
        Public method to get a list of all actions.
        
        @return list of all actions (list of E5Action)
        """
        return self.actions[:]
        
    def initActions(self):
        """
        Public method to generate the action objects.
        """
        self.vcsNewAct = E5Action(
            self.tr('New from repository'),
            UI.PixmapCache.getIcon("vcsCheckout.png"),
            self.tr('&New from repository...'), 0, 0, self,
            'subversion_new')
        self.vcsNewAct.setStatusTip(self.tr(
            'Create a new project from the VCS repository'
        ))
        self.vcsNewAct.setWhatsThis(self.tr(
            """<b>New from repository</b>"""
            """<p>This creates a new local project from the VCS"""
            """ repository.</p>"""
        ))
        self.vcsNewAct.triggered.connect(self._vcsCheckout)
        self.actions.append(self.vcsNewAct)
        
        self.vcsUpdateAct = E5Action(
            self.tr('Update from repository'),
            UI.PixmapCache.getIcon("vcsUpdate.png"),
            self.tr('&Update from repository'), 0, 0, self,
            'subversion_update')
        self.vcsUpdateAct.setStatusTip(self.tr(
            'Update the local project from the VCS repository'
        ))
        self.vcsUpdateAct.setWhatsThis(self.tr(
            """<b>Update from repository</b>"""
            """<p>This updates the local project from the VCS"""
            """ repository.</p>"""
        ))
        self.vcsUpdateAct.triggered.connect(self._vcsUpdate)
        self.actions.append(self.vcsUpdateAct)
        
        self.vcsCommitAct = E5Action(
            self.tr('Commit changes to repository'),
            UI.PixmapCache.getIcon("vcsCommit.png"),
            self.tr('&Commit changes to repository...'), 0, 0, self,
            'subversion_commit')
        self.vcsCommitAct.setStatusTip(self.tr(
            'Commit changes to the local project to the VCS repository'
        ))
        self.vcsCommitAct.setWhatsThis(self.tr(
            """<b>Commit changes to repository</b>"""
            """<p>This commits changes to the local project to the VCS"""
            """ repository.</p>"""
        ))
        self.vcsCommitAct.triggered.connect(self._vcsCommit)
        self.actions.append(self.vcsCommitAct)
        
        self.vcsLogAct = E5Action(
            self.tr('Show log'),
            UI.PixmapCache.getIcon("vcsLog.png"),
            self.tr('Show &log'),
            0, 0, self, 'subversion_log')
        self.vcsLogAct.setStatusTip(self.tr(
            'Show the log of the local project'
        ))
        self.vcsLogAct.setWhatsThis(self.tr(
            """<b>Show log</b>"""
            """<p>This shows the log of the local project.</p>"""
        ))
        self.vcsLogAct.triggered.connect(self._vcsLog)
        self.actions.append(self.vcsLogAct)
        
        self.svnLogBrowserAct = E5Action(
            self.tr('Show log browser'),
            UI.PixmapCache.getIcon("vcsLog.png"),
            self.tr('Show log browser'),
            0, 0, self, 'subversion_log_browser')
        self.svnLogBrowserAct.setStatusTip(self.tr(
            'Show a dialog to browse the log of the local project'
        ))
        self.svnLogBrowserAct.setWhatsThis(self.tr(
            """<b>Show log browser</b>"""
            """<p>This shows a dialog to browse the log of the local"""
            """ project. A limited number of entries is shown first. More"""
            """ can be retrieved later on.</p>"""
        ))
        self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser)
        self.actions.append(self.svnLogBrowserAct)
        
        self.vcsDiffAct = E5Action(
            self.tr('Show differences'),
            UI.PixmapCache.getIcon("vcsDiff.png"),
            self.tr('Show &difference'),
            0, 0, self, 'subversion_diff')
        self.vcsDiffAct.setStatusTip(self.tr(
            'Show the difference of the local project to the repository'
        ))
        self.vcsDiffAct.setWhatsThis(self.tr(
            """<b>Show differences</b>"""
            """<p>This shows differences of the local project to the"""
            """ repository.</p>"""
        ))
        self.vcsDiffAct.triggered.connect(self._vcsDiff)
        self.actions.append(self.vcsDiffAct)
        
        self.svnExtDiffAct = E5Action(
            self.tr('Show differences (extended)'),
            UI.PixmapCache.getIcon("vcsDiff.png"),
            self.tr('Show differences (extended)'),
            0, 0, self, 'subversion_extendeddiff')
        self.svnExtDiffAct.setStatusTip(self.tr(
            'Show the difference of revisions of the project to the repository'
        ))
        self.svnExtDiffAct.setWhatsThis(self.tr(
            """<b>Show differences (extended)</b>"""
            """<p>This shows differences of selectable revisions of"""
            """ the project.</p>"""
        ))
        self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff)
        self.actions.append(self.svnExtDiffAct)
        
        self.svnUrlDiffAct = E5Action(
            self.tr('Show differences (URLs)'),
            UI.PixmapCache.getIcon("vcsDiff.png"),
            self.tr('Show differences (URLs)'),
            0, 0, self, 'subversion_urldiff')
        self.svnUrlDiffAct.setStatusTip(self.tr(
            'Show the difference of the project between two repository URLs'
        ))
        self.svnUrlDiffAct.setWhatsThis(self.tr(
            """<b>Show differences (URLs)</b>"""
            """<p>This shows differences of the project between"""
            """ two repository URLs.</p>"""
        ))
        self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff)
        self.actions.append(self.svnUrlDiffAct)
        
        self.vcsStatusAct = E5Action(
            self.tr('Show status'),
            UI.PixmapCache.getIcon("vcsStatus.png"),
            self.tr('Show &status'),
            0, 0, self, 'subversion_status')
        self.vcsStatusAct.setStatusTip(self.tr(
            'Show the status of the local project'
        ))
        self.vcsStatusAct.setWhatsThis(self.tr(
            """<b>Show status</b>"""
            """<p>This shows the status of the local project.</p>"""
        ))
        self.vcsStatusAct.triggered.connect(self._vcsStatus)
        self.actions.append(self.vcsStatusAct)
        
        self.svnChangeListsAct = E5Action(
            self.tr('Show change lists'),
            UI.PixmapCache.getIcon("vcsChangeLists.png"),
            self.tr('Show change lists'),
            0, 0, self, 'subversion_changelists')
        self.svnChangeListsAct.setStatusTip(self.tr(
            'Show the change lists and associated files of the local project'
        ))
        self.svnChangeListsAct.setWhatsThis(self.tr(
            """<b>Show change lists</b>"""
            """<p>This shows the change lists and associated files of the"""
            """ local project.</p>"""
        ))
        self.svnChangeListsAct.triggered.connect(self.__svnChangeLists)
        self.actions.append(self.svnChangeListsAct)
        
        self.vcsTagAct = E5Action(
            self.tr('Tag in repository'),
            UI.PixmapCache.getIcon("vcsTag.png"),
            self.tr('&Tag in repository...'),
            0, 0, self, 'subversion_tag')
        self.vcsTagAct.setStatusTip(self.tr(
            'Tag the local project in the repository'
        ))
        self.vcsTagAct.setWhatsThis(self.tr(
            """<b>Tag in repository</b>"""
            """<p>This tags the local project in the repository.</p>"""
        ))
        self.vcsTagAct.triggered.connect(self._vcsTag)
        self.actions.append(self.vcsTagAct)
        
        self.vcsExportAct = E5Action(
            self.tr('Export from repository'),
            UI.PixmapCache.getIcon("vcsExport.png"),
            self.tr('&Export from repository...'),
            0, 0, self, 'subversion_export')
        self.vcsExportAct.setStatusTip(self.tr(
            'Export a project from the repository'
        ))
        self.vcsExportAct.setWhatsThis(self.tr(
            """<b>Export from repository</b>"""
            """<p>This exports a project from the repository.</p>"""
        ))
        self.vcsExportAct.triggered.connect(self._vcsExport)
        self.actions.append(self.vcsExportAct)
        
        self.vcsPropsAct = E5Action(
            self.tr('Command options'),
            self.tr('Command &options...'), 0, 0, self,
            'subversion_options')
        self.vcsPropsAct.setStatusTip(self.tr(
            'Show the VCS command options'))
        self.vcsPropsAct.setWhatsThis(self.tr(
            """<b>Command options...</b>"""
            """<p>This shows a dialog to edit the VCS command options.</p>"""
        ))
        self.vcsPropsAct.triggered.connect(self._vcsCommandOptions)
        self.actions.append(self.vcsPropsAct)
        
        self.vcsRevertAct = E5Action(
            self.tr('Revert changes'),
            UI.PixmapCache.getIcon("vcsRevert.png"),
            self.tr('Re&vert changes'),
            0, 0, self, 'subversion_revert')
        self.vcsRevertAct.setStatusTip(self.tr(
            'Revert all changes made to the local project'
        ))
        self.vcsRevertAct.setWhatsThis(self.tr(
            """<b>Revert changes</b>"""
            """<p>This reverts all changes made to the local project.</p>"""
        ))
        self.vcsRevertAct.triggered.connect(self._vcsRevert)
        self.actions.append(self.vcsRevertAct)
        
        self.vcsMergeAct = E5Action(
            self.tr('Merge'),
            UI.PixmapCache.getIcon("vcsMerge.png"),
            self.tr('Mer&ge changes...'),
            0, 0, self, 'subversion_merge')
        self.vcsMergeAct.setStatusTip(self.tr(
            'Merge changes of a tag/revision into the local project'
        ))
        self.vcsMergeAct.setWhatsThis(self.tr(
            """<b>Merge</b>"""
            """<p>This merges changes of a tag/revision into the local"""
            """ project.</p>"""
        ))
        self.vcsMergeAct.triggered.connect(self._vcsMerge)
        self.actions.append(self.vcsMergeAct)
        
        self.vcsSwitchAct = E5Action(
            self.tr('Switch'),
            UI.PixmapCache.getIcon("vcsSwitch.png"),
            self.tr('S&witch...'),
            0, 0, self, 'subversion_switch')
        self.vcsSwitchAct.setStatusTip(self.tr(
            'Switch the local copy to another tag/branch'
        ))
        self.vcsSwitchAct.setWhatsThis(self.tr(
            """<b>Switch</b>"""
            """<p>This switches the local copy to another tag/branch.</p>"""
        ))
        self.vcsSwitchAct.triggered.connect(self._vcsSwitch)
        self.actions.append(self.vcsSwitchAct)
        
        self.vcsResolveAct = E5Action(
            self.tr('Conflicts resolved'),
            self.tr('Con&flicts resolved'),
            0, 0, self, 'subversion_resolve')
        self.vcsResolveAct.setStatusTip(self.tr(
            'Mark all conflicts of the local project as resolved'
        ))
        self.vcsResolveAct.setWhatsThis(self.tr(
            """<b>Conflicts resolved</b>"""
            """<p>This marks all conflicts of the local project as"""
            """ resolved.</p>"""
        ))
        self.vcsResolveAct.triggered.connect(self.__svnResolve)
        self.actions.append(self.vcsResolveAct)
        
        self.vcsCleanupAct = E5Action(
            self.tr('Cleanup'),
            self.tr('Cleanu&p'),
            0, 0, self, 'subversion_cleanup')
        self.vcsCleanupAct.setStatusTip(self.tr(
            'Cleanup the local project'
        ))
        self.vcsCleanupAct.setWhatsThis(self.tr(
            """<b>Cleanup</b>"""
            """<p>This performs a cleanup of the local project.</p>"""
        ))
        self.vcsCleanupAct.triggered.connect(self._vcsCleanup)
        self.actions.append(self.vcsCleanupAct)
        
        self.vcsCommandAct = E5Action(
            self.tr('Execute command'),
            self.tr('E&xecute command...'),
            0, 0, self, 'subversion_command')
        self.vcsCommandAct.setStatusTip(self.tr(
            'Execute an arbitrary VCS command'
        ))
        self.vcsCommandAct.setWhatsThis(self.tr(
            """<b>Execute command</b>"""
            """<p>This opens a dialog to enter an arbitrary VCS command.</p>"""
        ))
        self.vcsCommandAct.triggered.connect(self._vcsCommand)
        self.actions.append(self.vcsCommandAct)
        
        self.svnTagListAct = E5Action(
            self.tr('List tags'),
            self.tr('List tags...'),
            0, 0, self, 'subversion_list_tags')
        self.svnTagListAct.setStatusTip(self.tr(
            'List tags of the project'
        ))
        self.svnTagListAct.setWhatsThis(self.tr(
            """<b>List tags</b>"""
            """<p>This lists the tags of the project.</p>"""
        ))
        self.svnTagListAct.triggered.connect(self.__svnTagList)
        self.actions.append(self.svnTagListAct)
        
        self.svnBranchListAct = E5Action(
            self.tr('List branches'),
            self.tr('List branches...'),
            0, 0, self, 'subversion_list_branches')
        self.svnBranchListAct.setStatusTip(self.tr(
            'List branches of the project'
        ))
        self.svnBranchListAct.setWhatsThis(self.tr(
            """<b>List branches</b>"""
            """<p>This lists the branches of the project.</p>"""
        ))
        self.svnBranchListAct.triggered.connect(self.__svnBranchList)
        self.actions.append(self.svnBranchListAct)
        
        self.svnListAct = E5Action(
            self.tr('List repository contents'),
            self.tr('List repository contents...'),
            0, 0, self, 'subversion_contents')
        self.svnListAct.setStatusTip(self.tr(
            'Lists the contents of the repository'
        ))
        self.svnListAct.setWhatsThis(self.tr(
            """<b>List repository contents</b>"""
            """<p>This lists the contents of the repository.</p>"""
        ))
        self.svnListAct.triggered.connect(self.__svnTagList)
        self.actions.append(self.svnListAct)
        
        self.svnPropSetAct = E5Action(
            self.tr('Set Property'),
            self.tr('Set Property...'),
            0, 0, self, 'subversion_property_set')
        self.svnPropSetAct.setStatusTip(self.tr(
            'Set a property for the project files'
        ))
        self.svnPropSetAct.setWhatsThis(self.tr(
            """<b>Set Property</b>"""
            """<p>This sets a property for the project files.</p>"""
        ))
        self.svnPropSetAct.triggered.connect(self.__svnPropSet)
        self.actions.append(self.svnPropSetAct)
        
        self.svnPropListAct = E5Action(
            self.tr('List Properties'),
            self.tr('List Properties...'),
            0, 0, self, 'subversion_property_list')
        self.svnPropListAct.setStatusTip(self.tr(
            'List properties of the project files'
        ))
        self.svnPropListAct.setWhatsThis(self.tr(
            """<b>List Properties</b>"""
            """<p>This lists the properties of the project files.</p>"""
        ))
        self.svnPropListAct.triggered.connect(self.__svnPropList)
        self.actions.append(self.svnPropListAct)
        
        self.svnPropDelAct = E5Action(
            self.tr('Delete Property'),
            self.tr('Delete Property...'),
            0, 0, self, 'subversion_property_delete')
        self.svnPropDelAct.setStatusTip(self.tr(
            'Delete a property for the project files'
        ))
        self.svnPropDelAct.setWhatsThis(self.tr(
            """<b>Delete Property</b>"""
            """<p>This deletes a property for the project files.</p>"""
        ))
        self.svnPropDelAct.triggered.connect(self.__svnPropDel)
        self.actions.append(self.svnPropDelAct)
        
        self.svnRelocateAct = E5Action(
            self.tr('Relocate'),
            UI.PixmapCache.getIcon("vcsSwitch.png"),
            self.tr('Relocate...'),
            0, 0, self, 'subversion_relocate')
        self.svnRelocateAct.setStatusTip(self.tr(
            'Relocate the working copy to a new repository URL'
        ))
        self.svnRelocateAct.setWhatsThis(self.tr(
            """<b>Relocate</b>"""
            """<p>This relocates the working copy to a new repository"""
            """ URL.</p>"""
        ))
        self.svnRelocateAct.triggered.connect(self.__svnRelocate)
        self.actions.append(self.svnRelocateAct)
        
        self.svnRepoBrowserAct = E5Action(
            self.tr('Repository Browser'),
            UI.PixmapCache.getIcon("vcsRepoBrowser.png"),
            self.tr('Repository Browser...'),
            0, 0, self, 'subversion_repo_browser')
        self.svnRepoBrowserAct.setStatusTip(self.tr(
            'Show the Repository Browser dialog'
        ))
        self.svnRepoBrowserAct.setWhatsThis(self.tr(
            """<b>Repository Browser</b>"""
            """<p>This shows the Repository Browser dialog.</p>"""
        ))
        self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser)
        self.actions.append(self.svnRepoBrowserAct)
        
        self.svnConfigAct = E5Action(
            self.tr('Configure'),
            self.tr('Configure...'),
            0, 0, self, 'subversion_configure')
        self.svnConfigAct.setStatusTip(self.tr(
            'Show the configuration dialog with the Subversion page selected'
        ))
        self.svnConfigAct.setWhatsThis(self.tr(
            """<b>Configure</b>"""
            """<p>Show the configuration dialog with the Subversion page"""
            """ selected.</p>"""
        ))
        self.svnConfigAct.triggered.connect(self.__svnConfigure)
        self.actions.append(self.svnConfigAct)
        
        self.svnUpgradeAct = E5Action(
            self.tr('Upgrade'),
            self.tr('Upgrade...'),
            0, 0, self, 'subversion_upgrade')
        self.svnUpgradeAct.setStatusTip(self.tr(
            'Upgrade the working copy to the current format'
        ))
        self.svnUpgradeAct.setWhatsThis(self.tr(
            """<b>Upgrade</b>"""
            """<p>Upgrades the working copy to the current format.</p>"""
        ))
        self.svnUpgradeAct.triggered.connect(self.__svnUpgrade)
        self.actions.append(self.svnUpgradeAct)
    
    def initMenu(self, menu):
        """
        Public method to generate the VCS menu.
        
        @param menu reference to the menu to be populated (QMenu)
        """
        menu.clear()
        
        act = menu.addAction(
            UI.PixmapCache.getIcon(
                os.path.join("VcsPlugins", "vcsSubversion", "icons",
                             "subversion.png")),
            self.vcs.vcsName(), self._vcsInfoDisplay)
        font = act.font()
        font.setBold(True)
        act.setFont(font)
        menu.addSeparator()
        
        menu.addAction(self.vcsUpdateAct)
        menu.addAction(self.vcsCommitAct)
        menu.addSeparator()
        menu.addAction(self.vcsTagAct)
        if self.vcs.otherData["standardLayout"]:
            menu.addAction(self.svnTagListAct)
            menu.addAction(self.svnBranchListAct)
        else:
            menu.addAction(self.svnListAct)
        menu.addSeparator()
        menu.addAction(self.vcsLogAct)
        menu.addAction(self.svnLogBrowserAct)
        menu.addSeparator()
        menu.addAction(self.vcsStatusAct)
        menu.addAction(self.svnChangeListsAct)
        menu.addSeparator()
        menu.addAction(self.vcsDiffAct)
        menu.addAction(self.svnExtDiffAct)
        menu.addAction(self.svnUrlDiffAct)
        menu.addSeparator()
        menu.addAction(self.vcsRevertAct)
        menu.addAction(self.vcsMergeAct)
        menu.addAction(self.vcsResolveAct)
        menu.addSeparator()
        menu.addAction(self.svnRelocateAct)
        menu.addAction(self.vcsSwitchAct)
        menu.addSeparator()
        menu.addAction(self.svnPropSetAct)
        menu.addAction(self.svnPropListAct)
        menu.addAction(self.svnPropDelAct)
        menu.addSeparator()
        menu.addAction(self.vcsCleanupAct)
        menu.addSeparator()
        menu.addAction(self.vcsCommandAct)
        menu.addAction(self.svnRepoBrowserAct)
        menu.addAction(self.svnUpgradeAct)
        menu.addSeparator()
        menu.addAction(self.vcsPropsAct)
        menu.addSeparator()
        menu.addAction(self.svnConfigAct)
        menu.addSeparator()
        menu.addAction(self.vcsNewAct)
        menu.addAction(self.vcsExportAct)
    
    def initToolbar(self, ui, toolbarManager):
        """
        Public slot to initialize the VCS toolbar.
        
        @param ui reference to the main window (UserInterface)
        @param toolbarManager reference to a toolbar manager object
            (E5ToolBarManager)
        """
        self.__toolbar = QToolBar(self.tr("Subversion (svn)"), ui)
        self.__toolbar.setIconSize(UI.Config.ToolBarIconSize)
        self.__toolbar.setObjectName("SubversionToolbar")
        self.__toolbar.setToolTip(self.tr('Subversion (svn)'))
        
        self.__toolbar.addAction(self.svnLogBrowserAct)
        self.__toolbar.addAction(self.vcsStatusAct)
        self.__toolbar.addSeparator()
        self.__toolbar.addAction(self.vcsDiffAct)
        self.__toolbar.addSeparator()
        self.__toolbar.addAction(self.svnRepoBrowserAct)
        self.__toolbar.addAction(self.vcsNewAct)
        self.__toolbar.addAction(self.vcsExportAct)
        self.__toolbar.addSeparator()
        
        title = self.__toolbar.windowTitle()
        toolbarManager.addToolBar(self.__toolbar, title)
        toolbarManager.addAction(self.vcsUpdateAct, title)
        toolbarManager.addAction(self.vcsCommitAct, title)
        toolbarManager.addAction(self.vcsLogAct, title)
        toolbarManager.addAction(self.svnExtDiffAct, title)
        toolbarManager.addAction(self.svnUrlDiffAct, title)
        toolbarManager.addAction(self.svnChangeListsAct, title)
        toolbarManager.addAction(self.vcsTagAct, title)
        toolbarManager.addAction(self.vcsRevertAct, title)
        toolbarManager.addAction(self.vcsMergeAct, title)
        toolbarManager.addAction(self.vcsSwitchAct, title)
        toolbarManager.addAction(self.svnRelocateAct, title)
        
        self.__toolbar.setEnabled(False)
        self.__toolbar.setVisible(False)
        
        ui.registerToolbar("subversion", self.__toolbar.windowTitle(),
                           self.__toolbar)
        ui.addToolBar(self.__toolbar)
    
    def removeToolbar(self, ui, toolbarManager):
        """
        Public method to remove a toolbar created by initToolbar().
        
        @param ui reference to the main window (UserInterface)
        @param toolbarManager reference to a toolbar manager object
            (E5ToolBarManager)
        """
        ui.removeToolBar(self.__toolbar)
        ui.unregisterToolbar("subversion")
        
        title = self.__toolbar.windowTitle()
        toolbarManager.removeCategoryActions(title)
        toolbarManager.removeToolBar(self.__toolbar)
        
        self.__toolbar.deleteLater()
        self.__toolbar = None
    
    def __svnResolve(self):
        """
        Private slot used to resolve conflicts of the local project.
        """
        self.vcs.svnResolve(self.project.ppath)
        
    def __svnPropList(self):
        """
        Private slot used to list the properties of the project files.
        """
        self.vcs.svnListProps(self.project.ppath, True)
        
    def __svnPropSet(self):
        """
        Private slot used to set a property for the project files.
        """
        self.vcs.svnSetProp(self.project.ppath, True)
        
    def __svnPropDel(self):
        """
        Private slot used to delete a property for the project files.
        """
        self.vcs.svnDelProp(self.project.ppath, True)
        
    def __svnTagList(self):
        """
        Private slot used to list the tags of the project.
        """
        self.vcs.svnListTagBranch(self.project.ppath, True)
        
    def __svnBranchList(self):
        """
        Private slot used to list the branches of the project.
        """
        self.vcs.svnListTagBranch(self.project.ppath, False)
        
    def __svnExtendedDiff(self):
        """
        Private slot used to perform a svn diff with the selection of
        revisions.
        """
        self.vcs.svnExtendedDiff(self.project.ppath)
        
    def __svnUrlDiff(self):
        """
        Private slot used to perform a svn diff with the selection of
        repository URLs.
        """
        self.vcs.svnUrlDiff(self.project.ppath)
        
    def __svnRelocate(self):
        """
        Private slot used to relocate the working copy to a new repository URL.
        """
        self.vcs.svnRelocate(self.project.ppath)
        
    def __svnRepoBrowser(self):
        """
        Private slot to open the repository browser.
        """
        self.vcs.svnRepoBrowser(projectPath=self.project.ppath)
        
    def __svnConfigure(self):
        """
        Private slot to open the configuration dialog.
        """
        e5App().getObject("UserInterface")\
            .showPreferences("zzz_subversionPage")
    
    def __svnChangeLists(self):
        """
        Private slot used to show a list of change lists.
        """
        self.vcs.svnShowChangelists(self.project.ppath)
    
    def __svnUpgrade(self):
        """
        Private slot used to upgrade the working copy format.
        """
        self.vcs.svnUpgrade(self.project.ppath)
Example #29
0
class _s_MiscContainer(QWidget):
    """From Miscellaneous, contains all the widgets in the bottom area."""
    #Miscellaneous was to long and dificult to write :P

    def __init__(self, parent=None):
        super(_s_MiscContainer, self).__init__(parent)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        self.__toolbar = QToolBar()
        self.__toolbar.setObjectName('custom')
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.stack = StackedWidget()
        vbox.addWidget(self.stack)

        self._console = console_widget.ConsoleWidget()
        self.stack.addWidget(self._console)

        self._runWidget = run_widget.RunWidget()
        self.stack.addWidget(self._runWidget)

        self._web = web_render.WebRender()
        self.stack.addWidget(self._web)

        self._findInFilesWidget = find_in_files.FindInFilesWidget(
            self.parent())
        self.stack.addWidget(self._findInFilesWidget)

        #Last Element in the Stacked widget
        self._results = results.Results(self)
        self.stack.addWidget(self._results)

        self._btnConsole = QPushButton(QIcon(resources.IMAGES['console']), '')
        self._btnConsole.setToolTip(_translate("_s_MiscContainer", "Console"))
        self._btnRun = QPushButton(QIcon(resources.IMAGES['play']), '')
        self._btnRun.setToolTip(_translate("_s_MiscContainer", "Output"))
        self._btnWeb = QPushButton(QIcon(resources.IMAGES['web']), '')
        self._btnWeb.setToolTip(_translate("_s_MiscContainer", "Web Preview"))
        self._btnFind = QPushButton(QIcon(resources.IMAGES['find']), '')
        self._btnFind.setToolTip(_translate("_s_MiscContainer", "Find in Files"))
        #Toolbar
        hbox.addWidget(self.__toolbar)
        self.__toolbar.addWidget(self._btnConsole)
        self.__toolbar.addWidget(self._btnRun)
        self.__toolbar.addWidget(self._btnWeb)
        self.__toolbar.addWidget(self._btnFind)
        self.__toolbar.addSeparator()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        btn_close.setObjectName('navigation_button')
        btn_close.setToolTip(_translate("_s_MiscContainer", 'F4: Show/Hide'))
        hbox.addWidget(btn_close)

        self._btnConsole.clicked['bool'].connect(lambda: self._item_changed(0))
        self._btnRun.clicked['bool'].connect(lambda: self._item_changed(1))
        self._btnWeb.clicked['bool'].connect(lambda: self._item_changed(2))
        self._btnFind.clicked['bool'].connect(lambda: self._item_changed(3))
        btn_close.clicked['bool'].connect(self.hide)

    def gain_focus(self):
        self._console.setFocus()

    def _item_changed(self, val):
        if not self.isVisible():
            self.show()
        self.stack.show_display(val)

    def show_find_in_files_widget(self):
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.open()

    def show_find_occurrences(self, word):
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.find_occurrences(word)

    def load_toolbar(self, toolbar):
        toolbar.addWidget(self._combo)
        toolbar.addSeparator()

    def run_application(self, fileName, pythonPath=False, PYTHONPATH=None,
            programParams='', preExec='', postExec=''):
        self._item_changed(1)
        self.show()
        self._runWidget.start_process(fileName, pythonPath, PYTHONPATH,
            programParams, preExec, postExec)
        self._runWidget.input.setFocus()

    def show_results(self, items):
        self._item_changed(4)
        self.show()
        self._results.update_result(items)
        self._results._tree.setFocus()

    def kill_application(self):
        self._runWidget.kill_process()

    def render_web_page(self, url):
        self._item_changed(2)
        self.show()
        self._web.render_page(url)
        if settings.SHOW_WEB_INSPECTOR:
            explorer_container.ExplorerContainer().set_inspection_page(
            self._web.webFrame.page())
            self._web.webFrame.triggerPageAction(
                QWebPage.InspectElement, True)
            explorer_container.ExplorerContainer().refresh_inspector()

    def add_to_stack(self, widget, icon_path, description):
        """
        Add a widget to the container and an button(with icon))to the toolbar
        to show the widget
        """
        #add the widget
        self.stack.addWidget(widget)
        #create a button in the toolbar to show the widget
        button = QPushButton(QIcon(icon_path), '')
        button.setToolTip(description)
        #index = self.stack.count() - 1
        #func = lambda: self._item_changed(index)
        button.clicked['bool'].connect(lambda: self._item_changed(self.stack.count() - 1))#func
        self.__toolbar.addWidget(button)
Example #30
0
class ToolbarController:
    def __init__(self, parent_window, app):
        self.parent = parent_window
        self.toolbar = QToolBar()
        self.app = app
        self.populating_tools = True

    def __get_combo_box(self, action_name) -> QComboBox:
        toolbar_actions = self.toolbar.actions()
        tags_list_action = next(act for act in toolbar_actions
                                if act.text() == action_name)
        return tags_list_action.defaultWidget()

    def init(self):
        tools_combo = self.__get_combo_box(DEVTOOLS_COMBO_NAME)
        tools_combo.clear()
        for ek, ev in tool_plugins.items():
            tools_combo.addItem(ev.tool.name, ek)

        # To avoid creating any view while we are populating tools in the combo box
        self.populating_tools = False

        selected_tool = self.app.data.get_selected_tool()
        found = tools_combo.findData(selected_tool)
        tools_combo.setCurrentIndex(found if found > 0 else 0)
        # Manually triggering to render the view as the index is not changing
        if found <= 0:
            self.on_toolbar_tool_changed(selected_tool)

    def on_toolbar_tool_changed(self, _):
        if self.populating_tools:
            return

        tools_combo = self.__get_combo_box("DevTools")
        current_tool = tools_combo.currentData()
        self.app.data.update_selected_tool(current_tool)

    def focus_on_devtools_combo_box(self):
        tools_combo = self.__get_combo_box("DevTools")
        tools_combo.setFocus(True)
        tools_combo.showPopup()

    def init_items(self):
        self.toolbar.setObjectName("maintoolbar")
        self.parent.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.setMovable(False)

        self.toolbar.addSeparator()

        toolbar_ctx_list = QComboBox(self.parent)
        toolbar_ctx_list.setDuplicatesEnabled(False)
        toolbar_ctx_list.setEditable(True)
        toolbar_ctx_list.currentIndexChanged[str].connect(
            lambda new_tool: self.on_toolbar_tool_changed(new_tool))
        toolbar_ctx_list_action = QWidgetAction(self.parent)
        toolbar_ctx_list_action.setText(DEVTOOLS_COMBO_NAME)
        toolbar_ctx_list_action.setDefaultWidget(toolbar_ctx_list)
        self.toolbar.addAction(toolbar_ctx_list_action)

        spacer = QWidget(self.parent)
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolbar.addWidget(spacer)

        toolbar_configure_action = QAction(QIcon(":/images/configure-48.png"),
                                           "Settings", self.parent)
        toolbar_configure_action.triggered.connect(
            self.parent.config_controller.show_dialog)
        self.toolbar.addAction(toolbar_configure_action)
Example #31
0
class Window(QMainWindow):
    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)

        # TODO: save state in settings file on exit
        self.setMinimumSize(1000, 600)
        # self.resize(QDesktopWidget().availableGeometry(self).size() * 0.7)
        self.set_title()

        self.main_grid = GridEditor(INIT_ROWS, INIT_COLS, self)
        self.setCentralWidget(self.main_grid)

        self.text_editor = CodeEditor()
        self.text_editor_dock = QDockWidget("Code Editor", self)
        self.text_editor_dock.setObjectName("CodeEditor")
        self.text_editor_dock.setAllowedAreas(Qt.RightDockWidgetArea)
        self.text_editor_dock.setWidget(self.text_editor)
        self.addDockWidget(Qt.RightDockWidgetArea, self.text_editor_dock)

        self.console_panel = ConsolePanel()
        self.console_panel_dock = QDockWidget("Console", self)
        self.console_panel_dock.setObjectName("Console")
        self.console_panel_dock.setAllowedAreas(Qt.RightDockWidgetArea)
        self.console_panel_dock.setWidget(self.console_panel)
        self.addDockWidget(Qt.RightDockWidgetArea, self.console_panel_dock)

        self.stdout_queue = Queue()
        sys.stdout = QueueWriteStream(self.stdout_queue)
        self.stdout_broadcaster = QueueBroadcaster(self.stdout_queue)
        self.stdout_broadcaster.new_queue_item.connect(
            partial(self.console_panel.append_to_log, "black"))
        self.stdout_queue_thread = QThread()
        self.stdout_broadcaster.moveToThread(self.stdout_queue_thread)
        self.stdout_queue_thread.started.connect(self.stdout_broadcaster.loop)
        self.stdout_queue_thread.start()

        self.stderr_queue = Queue()
        sys.stderr = QueueWriteStream(self.stderr_queue)
        self.stderr_broadcaster = QueueBroadcaster(self.stderr_queue)
        self.stderr_broadcaster.new_queue_item.connect(
            partial(self.console_panel.append_to_log, "red"))
        self.stderr_queue_thread = QThread()
        self.stderr_broadcaster.moveToThread(self.stderr_queue_thread)
        self.stderr_queue_thread.started.connect(self.stderr_broadcaster.loop)
        self.stderr_queue_thread.start()

        self.toolbar = QToolBar("Main toolbar")
        self.toolbar.setObjectName("MainToolbar")
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        self.toolbar_controls = dict()

        # standard icons from https://joekuan.wordpress.com/2015/09/23/list-of-qt-icons/
        # theme icons from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
        for tb_config in [
                # fmt: off
            [
                "button", "open", "Open", "document-open", "Click to open.",
                self.open_file_dialog, False
            ],
            [
                "button", "save", "Save As", "document-save-as",
                "Click to save.", self.save_file_dialog, False
            ],
            [
                "button", "new", "New", "document-new",
                "Click to clear and start new sheet.", self.new_sheet, False
            ],
            ["separator"],
            [
                "button", "calculate", "Calculate", "media-playback-start",
                "Click to calculate sheet.", self.calculate, False
            ],
            [
                "button", "resize_all", "Resize", "zoom-fit-best",
                "Click to resize columns and rows to fit.",
                self.main_grid.resize_all, False
            ],
            ["separator"],
            ["label", "Cell: "],
            [
                "button", "invalidate", "Invalidate", QStyle.SP_TrashIcon,
                "Click to invalidate selected cells.",
                self.main_grid.invalidate_cell, False
            ],
            [
                "button", "copy_values", "Copy Values", "edit-copy",
                "Click to copy selected cell values.",
                partial(self.main_grid.copy_cell, "value"), False
            ],
            [
                "button", "paste", "Paste", "edit-paste", "Click to paste.",
                self.main_grid.paste_cell, False
            ],
            [
                "button", "clear", "Clear", "edit-clear",
                "Click to clear selected cells.", self.main_grid.clear_cell,
                False
            ],
            [
                "textfield", "format", "Format Spec..", 100,
                self.main_grid.format_cell
            ],
            ["separator"],
            [
                "button", "show_editor", "Editor", "accessories-text-editor",
                "Click to show editor.", self.text_editor_dock.show, False
            ],
            [
                "button", "show_console", "Console", "utilities-terminal",
                "Click to show console.", self.console_panel_dock.show, False
            ],
            ["separator"],
            [
                "button", "exit", "Exit", "application-exit", "Click to exit.",
                self.close, False
            ],
            ["separator"],
            [
                "button", "help", "Help", "help-about",
                "Click for help and about.", self.show_help_dialog, False
            ],
                # fmt: on
        ]:
            if tb_config[0] == "button":
                name, label, icon, status, func, checkable = tb_config[1:]
                if isinstance(icon, QStyle.StandardPixmap):
                    icon = QIcon(QApplication.style().standardIcon(icon))
                else:
                    icon = QIcon.fromTheme(icon)
                button = QAction(
                    icon,
                    label,
                    self,
                )
                button.setStatusTip(status)
                button.triggered.connect(func)
                button.setCheckable(checkable)
                self.toolbar_controls[f"button_{name}"] = button
                self.toolbar.addAction(button)
            elif tb_config[0] == "separator":
                self.toolbar.addSeparator()
            elif tb_config[0] == "textfield":
                name, placeholder, max_width, func = tb_config[1:]
                line_edit = QLineEdit(self)
                line_edit.setPlaceholderText(placeholder)
                line_edit.setMaximumWidth(max_width)
                line_edit.returnPressed.connect(func)
                self.toolbar_controls[f"textfield_{name}"] = line_edit
                self.toolbar.addWidget(line_edit)
            elif tb_config[0] == "label":
                (label, ) = tb_config[1:]
                self.toolbar.addWidget(QLabel(label))

        self.addToolBar(self.toolbar)

        self.status_bar = QStatusBar(self)
        self.setStatusBar(self.status_bar)

        self.read_settings()

        # event filter needs to be in top level thread
        self.main_grid.installEventFilter(self.main_grid)

        # clear all sets up namespace
        self.clear_all()

    def set_title(self, label=None):
        self.setWindowTitle("Simple Spreadsheet" +
                            (f" - {label}" if label else ""))

    def calculate(self, s):
        self.main_grid.calculate()
        self.text_editor.execute_code()

    def new_sheet(self, s):
        self.clear_all()

    def clear_all(self):
        self.main_grid.clear()
        self.text_editor.clear()
        NAME_SPACE.clear()
        NAME_SPACE.update(new_name_space())
        NAME_SPACE["WINDOW"] = self
        NAME_SPACE["GRID"] = self.main_grid

    def show_help_dialog(self, s):
        detail = dedent("""\
            Keyboard shortcuts:

            CTRL + D: Fill down.
            CTRL + R: Fill right.
            CTRL + C: Copy cell formulas.
            CTRL + X: Cut cell formulas.
            CTRL + V: Paste cell formulas.

            For license information please see LICENSE text file included with this distribution.
        """)
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Information)
        msg.setText(
            f"Copyright © {datetime.date.today().year} Blair Azzopardi.")
        msg.setWindowTitle("About Simple Spreadsheet")
        msg.setDetailedText(detail)
        msg.setStandardButtons(QMessageBox.Ok)
        msg.exec_()

    def save_file_dialog(self, s):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            "Save sheet data",
            "",
            "All Files (*);;Text Files (*.json)",
            options=options,
        )
        if file_name:
            self.save_file(file_name)

    def save_file(self, file):
        try:
            file = Path(file)
            file_data = {
                "data": self.main_grid.export_data(),
                "code": self.text_editor.export_code(),
                "grid_state": self.main_grid.state,
            }
            file.write_text(json.dumps(file_data, cls=JSONEncoder))
            self.set_title(file.name)
        except Exception as exc:
            show_exception(exc, self)

    def open_file_dialog(self, s):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_name, _ = QFileDialog.getOpenFileName(
            self,
            "Load sheet data",
            "",
            "All Files (*);;Text Files (*.json)",
            options=options,
        )
        if file_name:
            self.open_file(file_name)

    def open_file(self, file):
        self.clear_all()
        file = Path(file)
        file_data = json.loads(file.read_text(), cls=JSONDecoder)
        # load & exec code, useful to load json importers
        self.text_editor.import_code(file_data["code"])
        self.text_editor.execute_code()
        # load grid data - do not calc
        self.main_grid.import_data(file_data["data"])
        self.set_title(file.name)
        # load grid state
        if "grid_state" in file_data:
            self.main_grid.state = file_data["grid_state"]

    def closeEvent(self, event):
        settings = QSettings("BlairAzzopardi", "SimpleSpreadSheet")
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("windowState", self.saveState())
        super().closeEvent(event)

    def read_settings(self):
        settings = QSettings("BlairAzzopardi", "SimpleSpreadSheet")
        if settings.value("geometry"):
            self.restoreGeometry(settings.value("geometry"))
        if settings.value("windowState"):
            self.restoreState(settings.value("windowState"))
Example #32
0
class PluginLiteUI(QObject):
    def __init__(self, ui):
        super(PluginLiteUI, self).__init__(ui)

        self.__ui = ui
        self.__toolbars = e5App().getObject("ToolbarManager")
        self.__sourcesBrowser = e5App().getObject(
            "ProjectBrowser").getProjectBrowser("sources")

        # override window loaded event
        self.__oldShowEvent = self.__ui.showEvent
        self.__ui.showEvent = self.__windowLoaded

        self.__ui._UserInterface__populateToolbarsMenu = self.__populateToolbarsMenu

        # override source browser createPythonPopupMenus
        self.__oldCreatePythonPopupMenus = self.__sourcesBrowser._ProjectSourcesBrowser__createPythonPopupMenus
        self.__sourcesBrowser._ProjectSourcesBrowser__createPythonPopupMenus = self.__createPythonPopupMenus

    def activate(self):
        """
        Public method to activate this plugin.

        @return tuple of None and activation status (boolean)
        """

        return None, True

    def deactivate(self):
        """
        Public method to deactivate this plugin.
        """
        pass

    def __windowLoaded(self, event):
        """
        Private method that gets called when the main window gets visible.
        """
        # remove preferences items
        self.__simplifyPreferences()
        self.__setupMenus()

        self.__oldShowEvent(event)

        self.__setupSidebars()
        self.__hideStatusBar()
        self.__setupToolbars()
        e5App().getObject("ViewManager").editorOpenedEd.connect(
            self.__on_new_editor)

        # I must run only once
        self.__ui.showEvent = self.__oldShowEvent
        self.__showInitialTip()

    def __setupMenus(self):
        """
        Private method that hides engineer-level menus and makes the others
        non-detachable.
        """
        # hide unused menus
        for menu in ["view", "extras", "window", "bookmarks", "plugins"]:
            UiHelper.hideUnusedMenu(self.__ui, menu)

        toRemove = {
            "file": [
                "Open &Bookmarked Files", "Search &File...", "Save &Copy...",
                "Export as", "Print Preview", "&Print"
            ],
            "edit": [
                "Re&vert to last saved state", "&Indent", "U&nindent",
                "Toggle Comment", "Convert selection to upper case",
                "Convert selection to lower case", "Sort", "Complete",
                "&Calltip", "&Goto Line...", "Goto &Brace",
                "Goto Last &Edit Location", "Goto Previous Method or Class",
                "Goto Next Method or Class", "Select to &brace",
                "&Deselect all", "Shorten empty lines",
                "Convert &Line End Characters"
            ],
            "project": [
                "Session", "Add &translation...", "&Diagrams", "Chec&k",
                "Sho&w", "Source &Documentation", "Pac&kagers",
                "&Properties...", "&User Properties...",
                "Filetype Associations...", "Lexer Associations..."
            ],
            "settings": [
                "E&xport Preferences...", "I&mport Preferences...",
                "Tool&bars...", "Keyboard &Shortcuts...",
                "&Export Keyboard Shortcuts...",
                "&Import Keyboard Shortcuts...", "Show external &tools"
            ],
            "help": [
                "Show &Versions", "Show &downloadable versions...",
                "Show Error &Log..."
            ]
        }

        for menu, items in toRemove.iteritems():
            UiHelper.removeWidgetActions(self.__ui.getMenu(menu), items)

        removeFromSearch = [
            "&Quicksearch", "Quicksearch &backwards",
            "Search current word forward", "Search current word backward",
            "Clear search markers", "Search in &Files...",
            "Replace in F&iles...", "Search in Open Files...",
            "Replace in Open Files..."
        ]

        for el in self.__ui.getMenu("edit").actions():
            if el.text() == self.__ui.tr("&Search"):
                UiHelper.removeWidgetActions(el.menu(), removeFromSearch)
                break

    def __initLiteToolbar(self, ui, toolbarManager):
        # find first toolbar
        firstToolbar = None

        for toolbar in ui.findChildren(QToolBar):
            if toolbar.isVisible():
                firstToolbar = toolbar
                break

        toCopy = [
            ['file', ["&Save", "&Open...", "&New"]],
            ['project', ["&Save", "&Open...", "&New..."]],
        ]

        self.__toolbar = QToolBar(self.tr("Lite tools"), ui)
        self.__toolbar.setIconSize(UI.Config.ToolBarIconSize)
        self.__toolbar.setObjectName("LiteUI")
        self.__toolbar.setToolTip(self.tr('Pymakr lite tools'))

        title = self.__toolbar.windowTitle()
        toolbarManager.addToolBar(self.__toolbar, title)

        # load new toolbar actions
        for bar in toCopy:
            if self.__ui.getToolbar(bar[0]) != None and self.__ui.getToolbar(
                    bar[0])[1] != None:
                for el in self.__ui.getToolbar(bar[0])[1].actions():
                    if el.text() in bar[1]:
                        self.__toolbar.addAction(el)
                        toolbarManager.addAction(el, title)

        try:
            ui.registerToolbar("lite", title, self.__toolbar)

            if firstToolbar:
                ui.insertToolBar(firstToolbar, self.__toolbar)
            else:
                ui.addToolBar(self.__toolbar)
        except KeyError:
            pass  # happens when toolbar is already registered
        self.__toolbar.setIconSize(QSize(32, 32))

    def __setupToolbars(self):
        self.__initLiteToolbar(self.__ui, self.__toolbars)

        for toolbar in [
                "project", "edit", "file", "quicksearch", "search", "spelling"
        ]:
            UiHelper.hideToolbar(self.__ui, toolbar)

        self.__fixToolbars()

    def __setupSidebars(self):
        """
        Private method that hides the pro-level sidebars
        """
        allLeftTabs = {
            "File-Browser", "Project-Viewer", "Multiproject-Viewer",
            "Template-Viewer", "Symbols", "File-Browser"
        }

        allBottomTabs = {
            "Pycom Console", "Shell", "Task-Viewer", "Numbers", "Translator",
            "Local Shell", "Log-Viewer"
        }

        toHideBottom = list(allBottomTabs - bottomTabsToShow)
        toHideLeft = list(allLeftTabs - leftTabsToShow)
        try:
            UiHelper.hideItemsSidebar(self.__ui.leftSidebar, toHideLeft)
        except AttributeError:
            # most likely the leftSidebar is not initialized, which can happen on windows sometimes
            pass

        UiHelper.hideItemsSidebar(self.__ui.bottomSidebar, toHideBottom)

    def __fixToolbars(self):
        self.__toolbars._fixedToolbars = True  # ask future toolbars to be fixed
        for toolbar in self.__ui.findChildren(QToolBar):
            toolbar.setMovable(False)

    def __hideStatusBar(self):
        self.__ui.statusBar().hide()

    def __populateToolbarsMenu(self, menu):
        menu.clear()

    def __on_new_editor(self, editor):
        itemstoHide = [
            "Autosave enabled", "Typing aids enabled",
            "Automatic Completion enabled", "Complete", "Calltip", "Check",
            "Show", "Diagrams", "Tools", "New Document View",
            "New Document View (with new split)", "Close",
            "Re-Open With Encoding", "Save", "Save As...", "Save Copy..."
        ]

        UiHelper.hideWidgetActions(editor.menu, itemstoHide)

    def __createPythonPopupMenus(self):
        itemsToRemove = [
            "Run unittest...", "Diagrams", "Check", "Show", "Configure..."
        ]

        self.__oldCreatePythonPopupMenus()
        UiHelper.removeWidgetActions(self.__sourcesBrowser.sourceMenu,
                                     itemsToRemove)

    def __simplifyPreferences(self):
        toDeleteTxt = [
            'Shell', 'Tasks', 'Interface', 'Editor/Autocompletion',
            'Editor/Calltips', 'Editor/Code Checkers', 'Editor/Exporters',
            'Editor/Filehandling', 'Editor/Highlighters/Properties',
            'Editor/Searching', 'Editor/Spell checking', 'Editor/Typing'
        ]
        FullUI.PreferencesDialog.SimplifyPreferences.toDeleteExtend(
            toDeleteTxt)

    def __showInitialTip(self):
        if Preferences.Prefs.settings.value("UI/AdvancedInterfaceTipShown",
                                            False) != "true":
            E5MessageBox.information(
                self.__ui, self.__ui.tr("Pymakr hint"),
                self.__ui.
                tr("<b>Hint</b><br><br>If you're an expert, you can always switch to the full interface by selecting<i>Settings > Switch to expert interface</i> in the main menu."
                   ))
            Preferences.Prefs.settings.setValue("UI/AdvancedInterfaceTipShown",
                                                "true")
Example #33
0
class MainWindow(QMainWindow):

    """This is the main application window class

    it defines the GUI window for the browser
    """

    def parse_config(self, file_config, options):
        self.config = {}
        options = vars(options)
        for key, metadata in CONFIG_OPTIONS.items():
            options_val = options.get(key)
            file_val = file_config.get(key)
            env_val = os.environ.get(metadata.get("env", ''))
            default_val = metadata.get("default")
            vals = metadata.get("values")
            debug("key: {}, default: {}, file: {}, options: {}".format(
                key, default_val, file_val, options_val
            ))
            if vals:
                options_val = (options_val in vals and options_val) or None
                file_val = (file_val in vals and file_val) or None
                env_val = (env_val in vals and env_val) or None
            if metadata.get("is_file"):
                filename = options_val or env_val
                if not filename:
                    self.config[key] = default_val
                else:
                    try:
                        with open(filename, 'r') as fh:
                            self.config[key] = fh.read()
                    except IOError:
                        debug("Could not open file {} for reading.".format(
                            filename)
                        )
                        self.config[key] = default_val
            else:
                set_values = [
                    val for val in (options_val, env_val, file_val)
                    if val is not None
                ]
                if len(set_values) > 0:
                    self.config[key] = set_values[0]
                else:
                    self.config[key] = default_val
            if metadata.get("type") and self.config[key]:
                debug("{} cast to {}".format(key, metadata.get("type")))
                self.config[key] = metadata.get("type")(self.config[key])
        debug(repr(self.config))

    def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None,
                     checkable=False, signal="triggered"):
        """Return a QAction given a number of common QAction attributes

        Just a shortcut function Originally borrowed from
        'Rapid GUI Development with PyQT' by Mark Summerset
        """
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon.fromTheme(
                icon, QIcon(":/{}.png".format(icon))
            ))
        if shortcut is not None and not shortcut.isEmpty():
            action.setShortcut(shortcut)
            tip += " ({})".format(shortcut.toString())
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.__getattr__(signal).connect(slot)
        if checkable:
            action.setCheckable()
        return action

    def __init__(self, options, parent=None):
        """Construct a MainWindow Object."""
        super(MainWindow, self).__init__(parent)
        # Load config file
        self.setWindowTitle("Browser")
        debug("loading configuration from '{}'".format(options.config_file))
        configfile = {}
        if options.config_file:
            configfile = yaml.safe_load(open(options.config_file, 'r'))
        self.parse_config(configfile, options)
        # self.popup will hold a reference to the popup window
        # if it gets opened
        self.popup = None

        # Stylesheet support
        if self.config.get("stylesheet"):
            try:
                with open(self.config.get("stylesheet")) as ss:
                    self.setStyleSheet(ss.read())
            except:
                debug(
                    """Problem loading stylesheet file "{}", """
                    """using default style."""
                    .format(self.config.get("stylesheet"))
                )
        self.setObjectName("global")

        # If the whitelist is activated, add the bookmarks and start_url
        if self.config.get("whitelist"):
            # we can just specify whitelist = True,
            # which should whitelist just the start_url and bookmark urls.
            whitelist = self.config.get("whitelist")
            if type(whitelist) is not list:
                whitelist = []
            whitelist.append(str(QUrl(
                self.config.get("start_url")
            ).host()))
            bookmarks = self.config.get("bookmarks")
            if bookmarks:
                whitelist += [
                    str(QUrl(b.get("url")).host())
                    for k, b in bookmarks.items()
                ]
                self.config["whitelist"] = set(whitelist)  # uniquify and optimize
            debug("Generated whitelist: " + str(whitelist))

        # If diagnostic is enabled, connect CTRL+ALT+? to show some diagnistic info
        if (self.config.get("enable_diagnostic")):
            self.diagnostic_action = self.createAction(
                "Show Diagnostic",
                self.show_diagnostic,
                QKeySequence("Ctrl+Alt+/"),
                tip=''
            )
            self.addAction(self.diagnostic_action)

        self.build_ui()

    # ## END OF CONSTRUCTOR ## #

    def build_ui(self):
        """Set up the user interface for the main window.

        Unlike the constructor, this method is re-run
        whenever the browser is "reset" by the user.
        """

        debug("build_ui")
        inactivity_timeout = self.config.get("timeout")
        quit_button_tooltip = (
            self.config.get("quit_button_mode") == 'close'
            and "Click here to quit the browser."
            or """Click here when you are done.
            It will clear your browsing history"""
            """ and return you to the start page.""")
        qb_mode_callbacks = {'close': self.close, 'reset': self.reset_browser}
        to_mode_callbacks = {'close': self.close,
                             'reset': self.reset_browser,
                             'screensaver': self.screensaver}
        self.screensaver_active = False

        # ##Start GUI configuration## #
        self.browser_window = WcgWebView(self.config)
        self.browser_window.setObjectName("web_content")

        if (
            self.config.get("icon_theme") is not None
            and QT_VERSION_STR > '4.6'
        ):
            QIcon.setThemeName(self.config.get("icon_theme"))
        self.setCentralWidget(self.browser_window)
        debug("loading {}".format(self.config.get("start_url")))
        self.browser_window.setUrl(QUrl(self.config.get("start_url")))
        if self.config.get("fullscreen"):
            self.showFullScreen()
        elif (
            self.config.get("window_size") and
            self.config.get("window_size").lower() == 'max'
        ):
            self.showMaximized()
        elif self.config.get("window_size"):
            size = re.match(r"(\d+)x(\d+)", self.config.get("window_size"))
            if size:
                width, height = size.groups()
                self.setFixedSize(int(width), int(height))
            else:
                debug('Ignoring invalid window size "{}"'.format(
                    self.config.get("window_size")
                ))

        # Set up the top navigation bar if it's configured to exist
        if self.config.get("navigation"):
            self.navigation_bar = QToolBar("Navigation")
            self.navigation_bar.setObjectName("navigation")
            self.addToolBar(Qt.TopToolBarArea, self.navigation_bar)
            self.navigation_bar.setMovable(False)
            self.navigation_bar.setFloatable(False)

            #  Standard navigation tools
            self.nav_items = {}
            self.nav_items["back"] = self.browser_window.pageAction(QWebPage.Back)
            self.nav_items["forward"] = self.browser_window.pageAction(QWebPage.Forward)
            self.nav_items["refresh"] = self.browser_window.pageAction(QWebPage.Reload)
            self.nav_items["stop"] = self.browser_window.pageAction(QWebPage.Stop)
            # The "I'm finished" button.
            self.nav_items["quit"] = self.createAction(
                self.config.get("quit_button_text"),
                qb_mode_callbacks.get(self.config.get("quit_button_mode"), self.reset_browser),
                QKeySequence("Alt+F"),
                None,
                quit_button_tooltip)
            # Zoom buttons
            self.nav_items["zoom_in"] = self.createAction(
                "Zoom In",
                self.zoom_in,
                QKeySequence("Alt++"),
                "zoom-in",
                "Increase the size of the text and images on the page")
            self.nav_items["zoom_out"] = self.createAction(
                "Zoom Out",
                self.zoom_out,
                QKeySequence("Alt+-"),
                "zoom-out",
                "Decrease the size of text and images on the page")
            if self.config.get("allow_printing"):
                self.nav_items["print"] = self.createAction(
                    "Print",
                    self.browser_window.print_webpage,
                    QKeySequence("Ctrl+p"),
                    "document-print",
                    "Print this page")

            # Add all the actions to the navigation bar.
            for item in self.config.get("navigation_layout"):
                if item == "separator":
                    self.navigation_bar.addSeparator()
                elif item == "spacer":
                    # an expanding spacer.
                    spacer = QWidget()
                    spacer.setSizePolicy(
                        QSizePolicy.Expanding, QSizePolicy.Preferred)
                    self.navigation_bar.addWidget(spacer)
                elif item == "bookmarks":
                    # Insert bookmarks buttons here.
                    self.bookmark_buttons = []
                    for bookmark in self.config.get("bookmarks", {}).items():
                        debug("Bookmark:\n" + bookmark.__str__())
                        # bookmark name will use the "name" attribute, if present
                        # or else just the key:
                        bookmark_name = bookmark[1].get("name") or bookmark[0]
                        # Create a button for the bookmark as a QAction,
                        # which we'll add to the toolbar
                        button = self.createAction(
                            bookmark_name,
                            lambda url=bookmark[1].get("url"): self.browser_window.load(QUrl(url)),
                            QKeySequence.mnemonic(bookmark_name),
                            None,
                            bookmark[1].get("description")
                            )
                        self.navigation_bar.addAction(button)
                        self.navigation_bar.widgetForAction(button).setObjectName("navigation_button")
                else:
                    action = self.nav_items.get(item, None)
                    if action:
                        self.navigation_bar.addAction(action)
                        self.navigation_bar.widgetForAction(action).setObjectName("navigation_button")

            # This removes the ability to toggle off the navigation bar:
            self.nav_toggle = self.navigation_bar.toggleViewAction()
            self.nav_toggle.setVisible(False)
            # End "if show_navigation is True" block

        # set hidden quit action
        # For reasons I haven't adequately ascertained,
        # this shortcut fails now and then claiming
        # "Ambiguous shortcut overload".
        # No idea why, as it isn't consistent.
        self.really_quit = self.createAction(
            "", self.close, QKeySequence("Ctrl+Alt+Q"), None, ""
        )
        self.addAction(self.really_quit)

        # Call a reset function after timeout
        if inactivity_timeout != 0:
            self.event_filter = InactivityFilter(inactivity_timeout)
            QCoreApplication.instance().installEventFilter(self.event_filter)
            self.browser_window.page().installEventFilter(self.event_filter)
            self.event_filter.timeout.connect(
                to_mode_callbacks.get(self.config.get("timeout_mode"),
                                      self.reset_browser))
        else:
            self.event_filter = None

        # ##END OF UI SETUP## #

    def screensaver(self):
        """Enter "screensaver" mode

        This method puts the browser in screensaver mode, where a URL
        is displayed while the browser is idle.  Activity causes the browser to
        return to the home screen.
        """
        debug("screensaver started")
        self.screensaver_active = True
        if self.popup:
            self.popup.close()
        if self.config.get("navigation"):
            self.navigation_bar.hide()
        self.browser_window.setZoomFactor(self.config.get("zoom_factor"))
        self.browser_window.load(QUrl(self.config.get("screensaver_url")))
        self.event_filter.timeout.disconnect()
        self.event_filter.activity.connect(self.reset_browser)

    def reset_browser(self):
        """Clear the history and reset the UI.

        Called whenever the inactivity filter times out,
        or when the user clicks the "finished" button in
        'reset' mode.
        """
        # Clear out the memory cache
        QWebSettings.clearMemoryCaches()
        self.browser_window.history().clear()
        # self.navigation_bar.clear() doesn't do its job,
        # so remove the toolbar first, then rebuild the UI.
        debug("RESET BROWSER")
        if self.event_filter:
            self.event_filter.blockSignals(True)
        if self.screensaver_active is True:
            self.screensaver_active = False
            self.event_filter.activity.disconnect()
        if self.event_filter:
            self.event_filter.blockSignals(False)
        if hasattr(self, "navigation_bar"):
            self.removeToolBar(self.navigation_bar)
        self.build_ui()

    def zoom_in(self):
        """Zoom in action callback.

        Note that we cap zooming in at a factor of 3x.
        """
        if self.browser_window.zoomFactor() < 3.0:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() + 0.1
            )
            self.nav_items["zoom_out"].setEnabled(True)
        else:
            self.nav_items["zoom_in"].setEnabled(False)

    def zoom_out(self):
        """Zoom out action callback.

        Note that we cap zooming out at 0.1x.
        """
        if self.browser_window.zoomFactor() > 0.1:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() - 0.1
            )
            self.nav_items["zoom_in"].setEnabled(True)
        else:
            self.nav_items["zoom_out"].setEnabled(False)

    def show_diagnostic(self):
        "Display a dialog box with some diagnostic info"
        data = {
            "OS": os.uname(),
            "USER": (os.environ.get("USER")
                     or os.environ.get("USERNAME")),
            "Python": sys.version,
            "Qt": QT_VERSION_STR,
            "Script Date": (
                datetime.datetime.fromtimestamp(
                    os.stat(__file__).st_mtime).isoformat()
            )
        }
        html = "\n".join([
            "<h1>System Information</h1>",
            "<h2>Please click &quot;",
            self.config.get("quit_button_text").replace("&", ''),
            "&quot; when you are finished.</h2>",
            "<ul>",
            "\n".join([
                "<li><b>{}</b>: {}</li>".format(k, v)
                for k, v in data.items()
            ]),
            "</ul>"
        ])
        self.browser_window.setHtml(html)
Example #34
0
class MainWindowUI(object):

    title = "Synspy Launcher"

    def __init__(self, MainWin):
        super(MainWindow).__init__()

        # Main Window
        MainWin.setObjectName("MainWindow")
        MainWin.setWindowTitle(
            MainWin.tr("%s %s" % (self.title, synspy_version)))
        MainWin.resize(800, 600)
        self.centralWidget = QWidget(MainWin)
        self.centralWidget.setObjectName("centralWidget")
        MainWin.setCentralWidget(self.centralWidget)
        self.verticalLayout = QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        # Splitter for Worklist/Log
        self.splitter = QSplitter(Qt.Vertical)

        # Table View (Work list)
        self.workList = TableWidget(self.centralWidget)
        self.workList.setObjectName("tableWidget")
        self.workList.setStyleSheet("""
            QTableWidget {
                    border: 2px solid grey;
                    border-radius: 5px;
            }
            """)
        self.workList.setEditTriggers(
            QAbstractItemView.NoEditTriggers
        )  # use NoEditTriggers to disable editing
        self.workList.setAlternatingRowColors(True)
        self.workList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.workList.setSelectionMode(QAbstractItemView.SingleSelection)
        self.workList.verticalHeader().setDefaultSectionSize(
            18)  # tighten up the row size
        self.workList.horizontalHeader().setStretchLastSection(True)
        # self.workList.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.workList.setSortingEnabled(True)  # allow sorting
        self.workList.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.workList.doubleClicked.connect(MainWin.on_actionLaunch_triggered)
        self.splitter.addWidget(self.workList)

        # Log Widget
        self.logTextBrowser = QPlainTextEditLogger(self.centralWidget)
        self.logTextBrowser.widget.setObjectName("logTextBrowser")
        self.logTextBrowser.widget.setStyleSheet("""
            QPlainTextEdit {
                    border: 2px solid grey;
                    border-radius: 5px;
                    background-color: lightgray;
            }
            """)
        self.splitter.addWidget(self.logTextBrowser.widget)

        # add splitter
        self.splitter.setSizes([600, 100])
        self.verticalLayout.addWidget(self.splitter)

        # Actions

        # Launch
        self.actionLaunch = QAction(MainWin)
        self.actionLaunch.setObjectName("actionLaunch")
        self.actionLaunch.setText(MainWin.tr("Launch Analysis"))
        self.actionLaunch.setToolTip(
            MainWin.tr("Launch the synspy-viewer process"))
        self.actionLaunch.setShortcut(MainWin.tr("Ctrl+L"))

        # Refresh
        self.actionRefresh = QAction(MainWin)
        self.actionRefresh.setObjectName("actionRefresh")
        self.actionRefresh.setText(MainWin.tr("Refresh Work List"))
        self.actionRefresh.setToolTip(MainWin.tr("Refresh the work list"))
        self.actionRefresh.setShortcut(MainWin.tr("Ctrl+R"))

        # Options
        self.actionOptions = QAction(MainWin)
        self.actionOptions.setObjectName("actionOptions")
        self.actionOptions.setText(MainWin.tr("Options"))
        self.actionOptions.setToolTip(MainWin.tr("Configuration Options"))
        self.actionOptions.setShortcut(MainWin.tr("Ctrl+P"))

        # Login
        self.actionLogin = QAction(MainWin)
        self.actionLogin.setObjectName("actionLogin")
        self.actionLogin.setText(MainWin.tr("Login"))
        self.actionLogin.setToolTip(MainWin.tr("Login to the server"))
        self.actionLogin.setShortcut(MainWin.tr("Ctrl+G"))

        # Logout
        self.actionLogout = QAction(MainWin)
        self.actionLogout.setObjectName("actionLogout")
        self.actionLogout.setText(MainWin.tr("Logout"))
        self.actionLogout.setToolTip(MainWin.tr("Logout of the server"))
        self.actionLogout.setShortcut(MainWin.tr("Ctrl+O"))

        # Exit
        self.actionExit = QAction(MainWin)
        self.actionExit.setObjectName("actionExit")
        self.actionExit.setText(MainWin.tr("Exit"))
        self.actionExit.setToolTip(MainWin.tr("Exit the application"))
        self.actionExit.setShortcut(MainWin.tr("Ctrl+Z"))

        # Help
        self.actionHelp = QAction(MainWin)
        self.actionHelp.setObjectName("actionHelp")
        self.actionHelp.setText(MainWin.tr("Help"))
        self.actionHelp.setToolTip(MainWin.tr("Help"))
        self.actionHelp.setShortcut(MainWin.tr("Ctrl+H"))

        # Mark Incomplete
        self.markIncompleteAction = QAction('Mark Incomplete', self.workList)
        self.markIncompleteAction.triggered.connect(MainWin.markIncomplete)

        # Tool Bar

        self.mainToolBar = QToolBar(MainWin)
        self.mainToolBar.setObjectName("mainToolBar")
        self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        MainWin.addToolBar(Qt.TopToolBarArea, self.mainToolBar)

        # Launch
        self.mainToolBar.addAction(self.actionLaunch)
        self.actionLaunch.setIcon(qApp.style().standardIcon(
            QStyle.SP_MediaPlay))

        # Reload
        self.mainToolBar.addAction(self.actionRefresh)
        self.actionRefresh.setIcon(qApp.style().standardIcon(
            QStyle.SP_BrowserReload))

        # Options
        self.mainToolBar.addAction(self.actionOptions)
        self.actionOptions.setIcon(qApp.style().standardIcon(
            QStyle.SP_FileDialogDetailedView))

        # this spacer right justifies everything that comes after it
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainToolBar.addWidget(spacer)

        # Login
        self.mainToolBar.addAction(self.actionLogin)
        self.actionLogin.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogApplyButton))

        # Logout
        self.mainToolBar.addAction(self.actionLogout)
        self.actionLogout.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogOkButton))

        # Help
        #self.mainToolBar.addAction(self.actionHelp)
        self.actionHelp.setIcon(qApp.style().standardIcon(
            QStyle.SP_MessageBoxQuestion))

        # Exit
        self.mainToolBar.addAction(self.actionExit)
        self.actionExit.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogCancelButton))

        # Status Bar

        self.statusBar = QStatusBar(MainWin)
        self.statusBar.setToolTip("")
        self.statusBar.setStatusTip("")
        self.statusBar.setObjectName("statusBar")
        MainWin.setStatusBar(self.statusBar)

        # finalize UI setup
        QMetaObject.connectSlotsByName(MainWin)
Example #35
0
class ToolbarUI(object):
    def __init__(self, main_window: QMainWindow):
        """
        工具导航
        外观模式
        :param main_window:
        """
        self.main_window = main_window
        self.toolbar = QToolBar(self.main_window)

        # 子类
        self.ui_list = []
        self.server_start_ui = ServerStartUI(self.toolbar)  # 服务器开关
        self.file_manager_ui = FileManagerUI(self.toolbar)  # 文件管理
        self.terminal_ui = TerminalUI(self.toolbar)  # 远程终端
        self.remote_control_ui = RemoteControlUI(self.toolbar)  # 远程控制
        self.video_monitor_ui = VideoMonitorUI(self.toolbar)  # 视频监控
        self.voice_monitor_ui = VoiceMonitorUI(self.toolbar)  # 语音监控
        self.keyboard_ui = KeyboardUI(self.toolbar)  # 键盘记录
        self.make_client_ui = MakeClientUI(self.toolbar)  # 创建客户端
        self.service_manager_ui = ServiceManagerUI(self.toolbar)  # 服务管理
        self.exit_ui = ExitUI(self.toolbar, self.main_window)  # 退出程序

        # 子类信号
        self.connect_list = []
        self.server_start_connect = ServerStartConnect(self.server_start_ui)

    def options(self) -> None:
        """
        参数设置
        :return:
        """
        self.toolbar.setObjectName("toolBar")

        # 设置是否可以移动
        self.toolbar.setMovable(True)

        # 设置是否可以悬浮在主窗口
        self.toolbar.setFloatable(True)

        # 设置图标尺寸
        self.toolbar.setIconSize(QSize(25, 25))

        # 字体在右边
        # self.tools_main.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        # 字体在下面
        if settings.LOAD_EFFECT_ON:
            self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            load_animation.load_animation(self.toolbar)

        # 窗口添加工具导航栏
        self.main_window.addToolBar(Qt.TopToolBarArea, self.toolbar)

    def setup_ui(self) -> None:
        self.options()

        if not settings.TOOLBAR_SHOW:
            self.toolbar.hide()

        self.load_ui()
        self.load_connect()
        self.show_ui()

        # QDockWidget 位置发生变动
        self.toolbar.orientationChanged.connect(self.orientation_changed)

    def orientation_changed(self, event) -> None:
        """
        位置变动事件
        :param event:
        :return:
        """
        if event:
            pass
        if settings.LOAD_EFFECT_ON:
            load_animation.load_animation(self.toolbar)

    # noinspection PyArgumentList
    def retranslate_ui(self) -> None:
        self.toolbar.setWindowTitle(_translate("ToolbarUI", "工具导航"))

    def load_ui(self) -> None:
        """
        加载模块
        :return:
        """
        self.ui_list.append(self.server_start_ui)
        self.ui_list.append(self.file_manager_ui)
        self.ui_list.append(self.terminal_ui)
        self.ui_list.append(self.remote_control_ui)
        self.ui_list.append(self.video_monitor_ui)
        self.ui_list.append(self.voice_monitor_ui)
        self.ui_list.append(self.keyboard_ui)
        self.ui_list.append(self.make_client_ui)
        self.ui_list.append(self.service_manager_ui)
        self.ui_list.append(self.exit_ui)

    def load_connect(self) -> None:
        """
        加载 链接信号
        :return:
        """
        self.connect_list.append(self.server_start_connect)

    def show_ui(self) -> None:
        """
        显示数据
        :return:
        """
        all_list = self.ui_list + self.connect_list
        for item in all_list:
            item.setup_ui()
            item.retranslate_ui()
Example #36
0
class UMC(QMainWindow):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
#TODO: Move actions somewhere else? Seems like this could get cluttered quickly
        ### ACTIONS ###
        menuHelpAboutAct = QAction('&About UMC', self)
        menuHelpAboutAct.triggered.connect(self.showDialogAbout)
        menuFileExitAct = QAction('&Exit', self) #QIcon('img/icon.png'), 
        menuFileExitAct.setShortcut('Ctrl+Q')
        menuFileExitAct.setStatusTip('Exit application')
        menuFileExitAct.triggered.connect(qApp.quit)
        menuViewThemeLightAct = QAction('Light', self, checkable=True)
        menuViewThemeLightAct.setChecked(True)
        menuViewThemeLightAct.triggered.connect(self.toggleTheme)
        menuViewThemeDarkAct = QAction('Dark', self, checkable=True)
        menuViewThemeDarkAct.triggered.connect(self.toggleTheme)

        tabMarketAct = QAction(QIcon('img/tab-bitcoin.png'), 'Loot', self)
        tabMarketAct.triggered.connect(self.switchAppTab)
        tabManualAct = QAction(QIcon('img/tab-muscle.png'), 'John Henry Mode', self)
        tabManualAct.triggered.connect(self.switchAppTab)
        tabNetworkAct = QAction(QIcon('img/tab-network.png'), 'Network', self)
        tabNetworkAct.triggered.connect(self.switchAppTab)
        tabOverviewAct = QAction(QIcon('img/tab-home.png'), 'Overview', self)
        tabOverviewAct.triggered.connect(self.switchAppTab)
        tabSettingsAct = QAction(QIcon('img/tab-settings.png'), 'Settings', self)
        tabSettingsAct.triggered.connect(self.switchAppTab)
        tabStatsAct = QAction(QIcon('img/tab-graph.png'), 'Statistics', self)
        tabStatsAct.triggered.connect(self.switchAppTab)
        tabStatusAct = QAction(QIcon('img/tab-status-ok.png'), 'Status', self)
        tabStatusAct.triggered.connect(self.switchAppTab)

        ### MENU BAR ###
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(menuFileExitAct)
        themesMenu = QMenu('Theme', self)
        ag = QActionGroup(self, exclusive=True)
        themesMenu.addAction(ag.addAction(menuViewThemeLightAct))
        themesMenu.addAction(ag.addAction(menuViewThemeDarkAct))
        viewMenu = menubar.addMenu('&View')
        viewMenu.addMenu(themesMenu)
        helpMenu = menubar.addMenu('&Help')
        helpMenu.addAction(menuHelpAboutAct)

        ### TOOLBAR ###
        toolbarFont = QFont('Helvetica', 10, QFont.Bold)
        self.toolbar = QToolBar(self)
        self.toolbar.setStyleSheet('QToolBar QToolButton,QToolBar QLabel { padding: 4; color: #555;}')
        self.toolbar.setIconSize(QSize(24, 24))
        self.toolbar.setObjectName("toolBar")
        self.toolbar.setMovable( False )
        self.addToolBar(Qt.ToolBarArea(Qt.TopToolBarArea), self.toolbar)
        self.toolbar.addAction(tabOverviewAct)
        self.toolbar.addAction(tabStatsAct)
        self.toolbar.addAction(tabNetworkAct)
        self.toolbar.addAction(tabMarketAct)
        self.toolbar.addAction(tabSettingsAct)
        self.toolbar.addSeparator()
        self.toolbar.addAction(tabManualAct)
        
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
        self.toolbar.addWidget(spacer)
        self.btcLbl = QLabel("0.003007 BTC ($41.50 USD)/Day")
        self.btcLbl.setFont(toolbarFont)
        self.toolbar.addWidget(self.btcLbl)
        self.hashLbl = QLabel("2763.45 MH/s")
        self.hashLbl.setFont(toolbarFont)
        self.toolbar.addWidget(self.hashLbl)
        self.toolbar.addAction(tabStatusAct)
        
        ### BODY ###
        self.Stack = QStackedWidget (self)
        self.Stack.addWidget(UMCOverview(self))
        self.Stack.addWidget(UMCStats(self))
        self.Stack.addWidget(UMCNetwork(self))
        self.Stack.addWidget(UMCLoot(self))
        self.Stack.addWidget(UMCSettings(self))
        self.Stack.addWidget(UMCManual(self))
        self.setCentralWidget(self.Stack)

        ### MAIN WINDOW ###
        self.setWindowTitle('Univeral Mining Control')
        self.setStyleSheet("QMainWindow {background: '#FFF';}")
        self.setWindowIcon(QIcon('img/icon.png'))         
        self.resize(800, 600)
        self.center()
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

# TODO this keypress is pretty handy for testing, probably needs to go away though
    def keyPressEvent(self, e): 
        if e.key() == Qt.Key_Escape:
            self.close()

    def showDialogAbout(self):
        msgBox = QMessageBox()
        msgBox.setText("Look! I made this!")
        msgBox.setWindowIcon(QIcon('img/qmessagebox-info.png'))
        msgBox.setWindowTitle("About Universal Mining Control")
        msgBox.exec_()

    def switchAppTab(self):
#TODO attach index to widget so the order can change without breaking things..
        if self.sender().text() == "Overview":
            self.Stack.setCurrentIndex(0)
        elif self.sender().text() == "Statistics":
            self.Stack.setCurrentIndex(1)
        elif self.sender().text() == "Network":
            self.Stack.setCurrentIndex(2)
        elif self.sender().text() == "Loot":
            self.Stack.setCurrentIndex(3)
        elif self.sender().text() == "Settings":
            self.Stack.setCurrentIndex(4)
        elif self.sender().text() == "John Henry Mode":
            self.Stack.setCurrentIndex(5)

    def toggleTheme(self):
        # I know I know, this isn't pretty, just throwing some ideas around...
        if self.sender().text() == "Dark":
            self.setStyleSheet("QMainWindow {background: '#666';}")
        else:
            self.setStyleSheet("QMainWindow {background: '#FFF';}")
Example #37
0
    def __init__(self):
        super().__init__()
        # settings file
        self.settings = QSettings('martinopilia', 'wikied')
        # label for the permanent message in the status bar
        self.permanentMessage = QLabel('Disconnected')
        # window for the regex sandbox
        self.regexSandbox = RegexSandbox()
        # object for the connection to the site
        self.connection = Connection(self.settings)
        self.connection.statusMessage.connect(self.statusBar().showMessage)
        self.connection.permanentMessage.connect(self.permanentMessage.setText)
        # window for the account settings
        self.accountDialog = AccountDialog(self.settings)

        # add permanent widget to the status bar
        self.statusBar().addPermanentWidget(self.permanentMessage)

        # actions
        # quit
        exitAction = QAction(
                QIcon('icons/window-close'),
                'Exit', self)
        exitAction.setStatusTip('Quit the application (Ctrl+Q)')
        exitAction.setShortcut('Ctrl+Q')
        exitAction.triggered.connect(self.close)
        # open RegexSandbox
        sandboxAction = QAction(
                QIcon('icons/code-context'),
                'Regex sandbox', self)
        sandboxAction.setStatusTip(
                'Open the regex test environment (Ctrl+Shif+S)')
        sandboxAction.setShortcut('Ctrl+Shift+S')
        sandboxAction.triggered.connect(self.regexSandbox.show)
        # connect
        connectAction = QAction(
                QIcon('icons/network-connect'),
                'Connect', self)
        connectAction.setStatusTip('Connect to the project')
        connectAction.triggered.connect(self.connection.connect)
        # disconnect
        disconnectAction = QAction(
                QIcon('icons/network-disconnect'),
                'Disconnect', self)
        disconnectAction.setStatusTip('Disconnect from the project')
        disconnectAction.triggered.connect(self.connection.disconnect)
        # set account
        setAccountAction = QAction(
                QIcon('icons/user-identity'),
                'Set account', self)
        setAccountAction.setStatusTip('Manage the account settings')
        setAccountAction.triggered.connect(self.accountDialog.exec_)

        # central widget and docks
        diff = Diff()
        diff.setObjectName('Diff')
        diff.setVisible(False)
        self.addDockWidget(Qt.TopDockWidgetArea, diff)

        editorWidget = VoiceEditor(self.connection, diff)
        self.setCentralWidget(editorWidget)

        substWidget = FindAndReplace(editorWidget.pageContent)
        substWidget.setObjectName('Find and replace')
        substWidget.statusMessage.connect(self.statusBar().showMessage)
        self.addDockWidget(Qt.BottomDockWidgetArea, substWidget)

        voiceSelector = VoiceSelector(self.connection, editorWidget)
        voiceSelector.setObjectName('Select voices')
        voiceSelector.statusMessage.connect(self.statusBar().showMessage)
        self.addDockWidget(Qt.LeftDockWidgetArea, voiceSelector)

        # toolbars
        # Connection
        connectionToolbar = QToolBar('Connection')
        connectionToolbar.setObjectName('connectionToolbar')
        connectionToolbar.addActions(
                [connectAction, disconnectAction, setAccountAction])
        self.addToolBar(connectionToolbar)

        # menu bar
        # File
        fileMenu = self.menuBar().addMenu('File')
        fileMenu.addAction(connectAction)
        fileMenu.addAction(disconnectAction)
        fileMenu.addAction(setAccountAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)
        # Tools
        toolsMenu = self.menuBar().addMenu('Tools')
        toolsMenu.addAction(sandboxAction)
        # View
        viewMenu = self.menuBar().addMenu('View')
        viewMenu.addAction(voiceSelector.toggleViewAction())
        viewMenu.addAction(substWidget.toggleViewAction())
        viewMenu.addAction(connectionToolbar.toggleViewAction())
        viewMenu.addAction(editorWidget.actionsToolbar.toggleViewAction())
        viewMenu.addAction(diff.toggleViewAction())
        viewMenu.addAction(editorWidget.editToolbar.toggleViewAction())

        # view details
        self.setGeometry(200, 200, 1000, 800)
        self.setWindowTitle('WikiEd')
        self.setWindowIcon(QIcon(''))
        editorWidget.pageContent.setFocus()

        # restore state and geometry (lazy initialization)
        if (not self.settings.value('window/geometry') or
            not self.settings.value('window/state')):
            self.saveWindow()
        self.restoreGeometry(self.settings.value('window/geometry'))
        self.restoreState(self.settings.value('window/state'))

        self.show()
class AuthWindowUI(object):
    def __init__(self, MainWin):
        # Main Window
        MainWin.setObjectName("AuthWindow")
        MainWin.setWindowIcon(MainWin.window_icon)
        MainWin.setWindowTitle(MainWin.tr(MainWin.window_title))
        MainWin.resize(1024, 860)
        self.config = MainWin.config
        self.centralWidget = QWidget(MainWin)
        self.centralWidget.setObjectName("centralWidget")
        MainWin.setCentralWidget(self.centralWidget)
        self.verticalLayout = QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        self.tabWidget = QTabWidget(MainWin)
        self.tabWidget.currentChanged.connect(MainWin.onTabChanged)
        self.tabWidget.tabCloseRequested.connect(MainWin.onTabClosed)
        self.tabWidget.setTabsClosable(True)
        # workaround for https://bugreports.qt.io/browse/QTBUG-58267
        if "darwin" in sys.platform:
            self.tabWidget.setDocumentMode(True)

        # Splitter for log
        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.addWidget(self.tabWidget)

        # Log Widget
        self.logTextBrowser = QPlainTextEditLogger(self.centralWidget)
        self.logTextBrowser.widget.setObjectName("logTextBrowser")
        self.logTextBrowser.widget.setStyleSheet("""
            QPlainTextEdit {
                    border: 2px solid grey;
                    border-radius: 5px;
                    background-color: lightgray;
            }
            """)
        self.splitter.addWidget(self.logTextBrowser.widget)

        # add splitter
        self.splitter.setSizes([800, 100])
        self.verticalLayout.addWidget(self.splitter)

        # Tool Bar
        self.mainToolBar = QToolBar(MainWin)
        self.mainToolBar.setObjectName("mainToolBar")
        self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.mainToolBar.setContextMenuPolicy(Qt.PreventContextMenu)
        MainWin.addToolBar(Qt.TopToolBarArea, self.mainToolBar)

        # Servers
        self.serverWidget = QWidget(MainWin)
        self.serverLayout = QHBoxLayout()
        self.serverLabel = QLabel("Server:")
        self.serverLayout.addWidget(self.serverLabel)
        self.serverComboBox = QComboBox()
        self.serverComboBox.setEditable(True)
        self.serverComboBox.setDuplicatesEnabled(False)
        self.serverComboBox.setMinimumContentsLength(50)
        self.serverComboBox.currentIndexChanged.connect(
            MainWin.onServerListChanged)
        lineEdit = self.serverComboBox.lineEdit()
        lineEdit.returnPressed.connect(MainWin.on_actionAdd_triggered)
        self.serverLayout.addWidget(self.serverComboBox)
        self.serverWidget.setLayout(self.serverLayout)
        self.mainToolBar.addWidget(self.serverWidget)

        # Add
        self.actionAdd = QAction(MainWin)
        self.actionAdd.setObjectName("actionAdd")
        self.actionAdd.setText(MainWin.tr("Add"))
        self.actionAdd.setToolTip(MainWin.tr("Add to server list"))
        self.actionAdd.setShortcut(MainWin.tr("Ctrl+A"))

        # Remove
        self.actionRemove = QAction(MainWin)
        self.actionRemove.setObjectName("actionRemove")
        self.actionRemove.setText(MainWin.tr("Remove"))
        self.actionRemove.setToolTip(MainWin.tr("Remove from server list"))
        self.actionRemove.setShortcut(MainWin.tr("Ctrl+X"))

        # Show Token
        self.actionShowToken = QAction(MainWin)
        self.actionShowToken.setEnabled(False)
        self.actionShowToken.setObjectName("actionShowToken")
        self.actionShowToken.setText(MainWin.tr("Show Token"))
        self.actionShowToken.setToolTip(
            MainWin.tr("Display the current authentication token"))
        self.actionShowToken.setShortcut(MainWin.tr("Ctrl+S"))

        # Login
        self.actionLogin = QAction(MainWin)
        self.actionLogin.setObjectName("actionLogin")
        self.actionLogin.setText(MainWin.tr("Login"))
        self.actionLogin.setToolTip(
            MainWin.tr("Login to the currently selected server"))
        self.actionLogin.setShortcut(MainWin.tr("Ctrl+L"))

        # Logout
        self.actionLogout = QAction(MainWin)
        self.actionLogout.setObjectName("actionLogout")
        self.actionLogout.setText(MainWin.tr("Logout"))
        self.actionLogout.setToolTip(
            MainWin.tr("Logout of the currently selected server"))
        self.actionLogout.setShortcut(MainWin.tr("Ctrl+O"))

        # Add
        self.mainToolBar.addAction(self.actionAdd)
        self.actionAdd.setIcon(qApp.style().standardIcon(
            QStyle.SP_FileDialogNewFolder))

        # Remove
        self.mainToolBar.addAction(self.actionRemove)
        self.actionRemove.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogDiscardButton))

        # Show Token
        self.mainToolBar.addAction(self.actionShowToken)
        self.actionShowToken.setIcon(qApp.style().standardIcon(
            QStyle.SP_FileDialogInfoView))
        self.mainToolBar.addSeparator()

        # this spacer right justifies everything that comes after it
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainToolBar.addWidget(spacer)

        # Login
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actionLogin)
        self.actionLogin.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogApplyButton))

        # Logout
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actionLogout)
        self.actionLogout.setIcon(qApp.style().standardIcon(
            QStyle.SP_DialogOkButton))

        # Status Bar
        self.statusBar = QStatusBar(MainWin)
        self.statusBar.setToolTip("")
        self.statusBar.setStatusTip("")
        self.statusBar.setObjectName("statusBar")
        MainWin.setStatusBar(self.statusBar)

        # configure logging
        self.logTextBrowser.widget.log_update_signal.connect(MainWin.updateLog)
        self.logTextBrowser.setFormatter(
            logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
        logging.getLogger().addHandler(self.logTextBrowser)
        logging.getLogger().setLevel(logging.INFO)

        # finalize UI setup
        QMetaObject.connectSlotsByName(MainWin)
Example #39
0
class UIController(object):
    def __init__(self):
        self.mainWidget = scripterdialog.ScripterDialog(self)
        self.actionToolbar = QToolBar('toolBar', self.mainWidget)
        self.menu_bar = QMenuBar(self.mainWidget)

        self.actionToolbar.setObjectName('toolBar')
        self.menu_bar.setObjectName('menuBar')

        self.actions = []

        self.mainWidget.setWindowModality(Qt.NonModal)

    def initialize(self, scripter):
        self.editor = pythoneditor.CodeEditor(scripter)
        self.tabWidget = QTabWidget()
        self.statusBar = QLabel('untitled')
        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)
        self.highlight = syntax.PythonHighlighter(
            self.editor.document(), syntaxstyles.DefaultSyntaxStyle())

        self.scripter = scripter

        self.loadMenus()
        self.loadWidgets()
        self.loadActions()
        self._readSettings()

        vbox = QVBoxLayout(self.mainWidget)
        vbox.addWidget(self.menu_bar)
        vbox.addWidget(self.actionToolbar)
        self.splitter.addWidget(self.editor)
        self.splitter.addWidget(self.tabWidget)
        vbox.addWidget(self.splitter)
        vbox.addWidget(self.statusBar)

        self.mainWidget.resize(400, 500)
        self.mainWidget.setWindowTitle("Scripter")
        self.mainWidget.setSizeGripEnabled(True)
        self.mainWidget.show()
        self.mainWidget.activateWindow()

    def loadMenus(self):
        self.addMenu('File', 'File')

    def addMenu(self, menuName, parentName):
        parent = self.menu_bar.findChild(QObject, parentName)
        self.newMenu = None

        if parent:
            self.newMenu = parent.addMenu(menuName)
        else:
            self.newMenu = self.menu_bar.addMenu(menuName)

        self.newMenu.setObjectName(menuName)

        return self.newMenu

    def loadActions(self):
        module_path = 'scripter.ui_scripter.actions'
        actions_module = importlib.import_module(module_path)
        modules = []

        for class_path in actions_module.action_classes:
            _module, _klass = class_path.rsplit('.', maxsplit=1)
            modules.append(
                dict(module='{0}.{1}'.format(module_path, _module),
                     klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            action_class = getattr(m, module['klass'])
            obj = action_class(self.scripter)
            parent = self.mainWidget.findChild(QObject, obj.parent)
            self.actions.append(dict(action=obj, parent=parent))

        for action in self.actions:
            action['parent'].addAction(action['action'])

    def loadWidgets(self):
        modulePath = 'scripter.ui_scripter.tabwidgets'
        widgetsModule = importlib.import_module(modulePath)
        modules = []

        for classPath in widgetsModule.widgetClasses:
            _module, _klass = classPath.rsplit('.', maxsplit=1)
            modules.append(
                dict(module='{0}.{1}'.format(modulePath, _module),
                     klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            widgetClass = getattr(m, module['klass'])
            obj = widgetClass(self.scripter)
            self.tabWidget.addTab(obj, obj.objectName())

    def invokeAction(self, actionName):
        for action in self.actions:
            if action['action'].objectName() == actionName:
                method = getattr(action['action'], actionName)
                if method:
                    return method()

    def findTabWidget(self, widgetName, childName=''):
        for index in range(self.tabWidget.count()):
            widget = self.tabWidget.widget(index)
            if widget.objectName() == widgetName:
                if childName:
                    widget = widget.findChild(QObject, childName)
                return widget

    def showException(self, exception):
        QMessageBox.critical(self.editor, "Error running script",
                             str(exception))

    def setDocumentEditor(self, document):
        self.editor.clear()
        self.editor.moveCursor(QTextCursor.Start)
        self.editor.insertPlainText(document.data)
        self.editor.moveCursor(QTextCursor.End)

    def setStatusBar(self, value='untitled'):
        self.statusBar.setText(value)

    def setActiveWidget(self, widgetName):
        widget = self.findTabWidget(widgetName)

        if widget:
            self.tabWidget.setCurrentWidget(widget)

    def setStepped(self, status):
        self.editor.setStepped(status)

    def clearEditor(self):
        self.editor.clear()

    def repaintDebugArea(self):
        self.editor.repaintDebugArea()

    def closeScripter(self):
        self.mainWidget.close()

    def _writeSettings(self):
        """ _writeSettings is a method invoked when the scripter starts, making
            control inversion. Actions can implement a writeSettings method to
            save your own settings without this method to know about it. """

        self.scripter.settings.beginGroup('scripter')

        document = self.scripter.documentcontroller.activeDocument
        if document:
            self.scripter.settings.setValue('activeDocumentPath',
                                            document.filePath)

        for action in self.actions:
            writeSettings = getattr(action['action'], "writeSettings", None)
            if callable(writeSettings):
                writeSettings()

        self.scripter.settings.endGroup()

    def _readSettings(self):
        """ It's similar to _writeSettings, but reading the settings when the ScripterDialog is closed. """

        self.scripter.settings.beginGroup('scripter')

        activeDocumentPath = self.scripter.settings.value(
            'activeDocumentPath', '')

        if activeDocumentPath:
            document = self.scripter.documentcontroller.openDocument(
                activeDocumentPath)
            self.setStatusBar(document.filePath)
            self.setDocumentEditor(document)

        for action in self.actions:
            readSettings = getattr(action['action'], "readSettings", None)
            if callable(readSettings):
                readSettings()

        self.scripter.settings.endGroup()

    def _saveSettings(self):
        self.scripter.settings.sync()
Example #40
0
class _ToolsDock(QWidget):
    """Former Miscellaneous, contains all the widgets in the bottom area."""

    findStarted = pyqtSignal()
    splitEditor = pyqtSignal(QWidget, QWidget, bool)
    closeSplit = pyqtSignal(QWidget)
    
    def __init__(self, parent=None):
        super(_ToolsDock, self).__init__(parent)
        #Register signals connections
        connections = (
            {'target': 'main_container',
             'signal_name': "findOcurrences",#(QString)
             'slot': self.show_find_occurrences},
            {'target': 'main_container',
             'signal_name': "runFile",#(QString)
             'slot': self.execute_file},
        )
        IDE.register_signals('tools_dock', connections)
        IDE.register_service("tools_dock", self)

    def setup_ui(self):
        """Load all the components of the ui during the install process."""
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        self.__toolbar = QToolBar()
        self.__toolbar.setObjectName('custom')
        hbox = QHBoxLayout()
        vbox.addLayout(hbox)

        self.stack = StackedWidget()
        vbox.addWidget(self.stack)

        self._console = console_widget.ConsoleWidget()
        self._runWidget = run_widget.RunWidget()
        self._web = web_render.WebRender()
        self._findInFilesWidget = find_in_files.FindInFilesWidget(
            self.parent())

        # Not Configurable Shortcuts
        shortEscMisc = QShortcut(QKeySequence(Qt.Key_Escape), self)

        shortEscMisc.activated.connect(self.hide)

        #Toolbar
        hbox.addWidget(self.__toolbar)
        self.add_to_stack(self._console, ":img/console",
                          translations.TR_CONSOLE)
        self.add_to_stack(self._runWidget, ":img/play",
                          translations.TR_OUTPUT)
        self.add_to_stack(self._web, ":img/web",
                          translations.TR_WEB_PREVIEW)
        self.add_to_stack(self._findInFilesWidget, ":img/find",
                          translations.TR_FIND_IN_FILES)
        #Last Element in the Stacked widget
        self._results = results.Results(self)
        self.stack.addWidget(self._results)
        self.__toolbar.addSeparator()

        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        btn_close.setIconSize(QSize(24, 24))
        btn_close.setObjectName('navigation_button')
        btn_close.setToolTip('F4: ' + translations.TR_ALL_VISIBILITY)
        hbox.addWidget(btn_close)
        btn_close.clicked['bool'].connect(self.hide)

    def install(self):
        """Install triggered by the ide."""
        self.setup_ui()
        ninjaide = IDE.getInstance()
        ninjaide.place_me_on("tools_dock", self, "central")
        ui_tools.install_shortcuts(self, actions.ACTIONS, ninjaide)

        ninjaide.goingDown.connect(self.save_configuration)

        qsettings = IDE.ninja_settings()
        value = qsettings.value("tools_dock/visible", True, type=bool)
        self.setVisible(value)
        print("\ninstall")

    def save_configuration(self):
        qsettings = IDE.ninja_settings()
        qsettings.setValue("tools_dock/visible", self.isVisible())

    def change_visibility(self):
        """Change tools dock visibility."""
        print("change_visibility22",self.isVisible())
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def add_project_to_console(self, projectFolder):
        """Add the namespace of the project received into the ninja-console."""
        self._console.load_project_into_console(projectFolder)

    def remove_project_from_console(self, projectFolder):
        """Remove the namespace of the project received from the console."""
        self._console.unload_project_from_console(projectFolder)

    def _item_changed(self, val):
        """Change the current item."""
        print("_item_changed", val)
        if not self.isVisible():
            self.show()
        self.stack.show_display(val)

    def show_find_in_files_widget(self):
        """Show the Find In Files widget."""
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.open()
        self._findInFilesWidget.setFocus()

    def show_find_occurrences(self, word):
        """Show Find In Files widget in find occurrences mode."""
        index_of = self.stack.indexOf(self._findInFilesWidget)
        self._item_changed(index_of)
        self._findInFilesWidget.find_occurrences(word)
        self._findInFilesWidget.setFocus()

    def execute_file(self):
        """Execute the current file."""
        main_container = IDE.get_service('main_container')
        if not main_container:
            return
        editorWidget = main_container.get_current_editor()
        if editorWidget:
            #emit a signal for plugin!
            self.fileExecuted.emit(editorWidget.file_path)
            main_container.save_file(editorWidget)
            ext = file_manager.get_file_extension(editorWidget.file_path)
            #TODO: Remove the IF statment and use Handlers
            if ext == 'py':
                self._run_application(editorWidget.file_path)
            elif ext == 'html':
                self.render_web_page(editorWidget.file_path)

    def execute_project(self):
        """Execute the project marked as Main Project."""
        projects_explorer = IDE.get_service('projects_explorer')
        if projects_explorer is None:
            return
        nproject = projects_explorer.current_project
        if nproject:
            main_file = nproject.main_file
            if not main_file and projects_explorer.current_tree:
                projects_explorer.current_tree.open_project_properties()
            elif main_file:
                projects_explorer.save_project()
                #emit a signal for plugin!
                self.projectExecuted.emit(nproject.path)

                main_file = file_manager.create_path(nproject.path,
                                                     nproject.main_file)
                self._run_application(
                    main_file,
                    pythonExec=nproject.python_exec_command,
                    PYTHONPATH=nproject.python_path,
                    programParams=nproject.program_params,
                    preExec=nproject.pre_exec_script,
                    postExec=nproject.post_exec_script)
        else:
            QMessageBox.information(self, translations.TR_INFO_TITLE_PROJECT_PROPERTIES,
                translations.TR_INFO_MESSAGE_PROJECT_PROPERTIES)

    def _run_application(self, fileName, pythonExec=False, PYTHONPATH=None,
                         programParams='', preExec='', postExec=''):
        """Execute the process to run the application."""
        self._item_changed(1)
        self.show()
        self._runWidget.start_process(fileName, pythonExec, PYTHONPATH,
                                      programParams, preExec, postExec)
        self._runWidget.input.setFocus()

    def show_results(self, items):
        """Show Results of Navigate to for several occurrences."""
        index_of = self.stack.indexOf(self._results)
        self._item_changed(index_of)
        self.show()
        self._results.update_result(items)
        self._results._tree.setFocus()
        self._results.setFocus()

    def kill_application(self):
        """Kill the process of the application being executed."""
        self._runWidget.kill_process()

    def render_web_page(self, url):
        """Render a webpage from the url path."""
        index_of = self.stack.indexOf(self._web)
        self._item_changed(index_of)
        self.show()
        self._web.render_page(url)
        if settings.SHOW_WEB_INSPECTOR:
            web_inspector = IDE.get_service('web_inspector')
            if web_inspector:
                web_inspector.set_inspection_page(self._web.webFrame.page())
                self._web.webFrame.triggerPageAction(
                    QWebPage.InspectElement, True)
                web_inspector.refresh_inspector()
        self._web.setFocus()

    def add_to_stack(self, widget, icon_path, description):
        """
        Add a widget to the container and an button(with icon))to the toolbar
        to show the widget
        """
        #add the widget
        self.stack.addWidget(widget)
        #create a button in the toolbar to show the widget
        button = QPushButton(QIcon(icon_path), '')
        button.setIconSize(QSize(16, 16))
        button.setToolTip(description)
        index = self.stack.count() - 1
        button.clicked['bool'].connect(lambda s, i=index: self._item_changed(i))
        self.__toolbar.addWidget(button)

    def showEvent(self, event):
        super(_ToolsDock, self).showEvent(event)
        widget = self.stack.currentWidget()
        if widget:
            widget.setFocus()