Esempio n. 1
0
class EditorWindow(QtGui.QWidget):

    def __init__(self, pathDict, library, busyWidget,
                 colorScheme, useData, app, parent):
        QtGui.QWidget.__init__(self, parent)

        self.pathDict = pathDict
        self.app = app
        self.useData = useData
        self.library = library
        self.projects = parent
        self.colorScheme = colorScheme

        self.loadProjectData()

        self.busyWidget = busyWidget
        self.buildStatusWidget = BuildStatusWidget(self.app, self.useData)

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.setMargin(0)
        mainLayout.setSpacing(0)
        self.setLayout(mainLayout)

        self.standardToolbar = QtGui.QToolBar("Standard")
        self.standardToolbar.setMovable(False)
        self.standardToolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
        self.standardToolbar.setMaximumHeight(26)
        self.standardToolbar.setObjectName("StandardToolBar")
        mainLayout.addWidget(self.standardToolbar)

        widget = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout()
        vbox.setMargin(0)
        vbox.setSpacing(0)
        widget.setLayout(vbox)

        self.vSplitter = VerticalSplitter()
        mainLayout.addWidget(self.vSplitter)

        self.hSplitter = QtGui.QSplitter()
        self.hSplitter.setObjectName("hSplitter")

        self.vSplitter.addWidget(self.hSplitter)

        self.bottomStack = QtGui.QStackedWidget()
        self.vSplitter.addWidget(self.bottomStack)

        self.sideBar = QtGui.QSplitter()
        self.sideBar.setStyleSheet(StyleSheet.sidebarStyle)
        self.hSplitter.addWidget(widget)

        self.bottomStackSwitcher = StackSwitcher(self.bottomStack)
        self.bottomStackSwitcher.setStyleSheet(StyleSheet.bottomSwitcherStyle)

        self.messagesWidget = MessagesWidget(
            self.bottomStackSwitcher, self.vSplitter)

        self.createActions()

        self.manageFavourites = Favourites(

            self.PROJECT_DATA['favourites'], self.messagesWidget, self)

        self.externalLauncher = ExternalLauncher(
            self.PROJECT_DATA["launchers"], self)

        self.writePad = WritePad(self.pathDict[
                                 "notes"], self.pathDict["name"], self)

        self.bookmarkToolbar = QtGui.QToolBar("Bookmarks")
        self.bookmarkToolbar.setMovable(False)
        self.bookmarkToolbar.setFloatable(False)
        self.bookmarkToolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
        self.bookmarkToolbar.setMaximumHeight(26)
        self.bookmarkToolbar.setObjectName("Bookmarks")
        self.bookmarkToolbar.addSeparator()

        self.editorTabWidget = EditorTabWidget(
            self.useData, self.pathDict, self.PROJECT_DATA["settings"],
            self.colorScheme, self.busyWidget, self.bookmarkToolbar, self.app, self.manageFavourites,
            self.externalLauncher)
        vbox.addWidget(self.editorTabWidget)

        self.manageFavourites.openFile.connect(self.editorTabWidget.loadfile)

        self.editorTabWidget.updateRecentFilesList.connect(
            self.updateRecentFiles)
        self.editorTabWidget.updateLinesCount.connect(self.updateLineCount)
        self.editorTabWidget.updateEncodingLabel.connect(
            self.updateEncodingLabel)
        self.editorTabWidget.cursorPositionChanged.connect(
            self.showCursorPosition)

        self.searchWidget = SearchWidget(
            self.useData, self.editorTabWidget)
        vbox.addWidget(self.searchWidget)

        self.findInFiles = FindInFiles(
            self.useData, self.editorTabWidget, pathDict, self.bottomStackSwitcher)
        vbox.addWidget(self.findInFiles.dashboard)
        self.findInFiles.dashboard.hide()

        self.projectManager = ProjectManager(
            self.editorTabWidget, self.messagesWidget, pathDict, self.PROJECT_DATA[
                "settings"], self.useData, app,
            self.busyWidget, self.buildStatusWidget, self.projects)
        self.projectManager.projectViewer.fileActivated.connect(
            self.editorTabWidget.loadfile)

        self.outline = Outline(
            self.useData, self.editorTabWidget)

        self.sideSplitter = QtGui.QSplitter()
        self.sideSplitter.setObjectName("sideSplitter")
        self.sideSplitter.setOrientation(0)
        self.sideSplitter.setStyleSheet(StyleSheet.sidebarStyle)
        self.hSplitter.addWidget(self.sideSplitter)

        self.sideSplitter.addWidget(self.outline)

        self.sideBottomTab = QtGui.QTabWidget()
        self.sideSplitter.addWidget(self.sideBottomTab)

        self.sideBottomTab.addTab(self.projectManager.projectViewer, QtGui.QIcon(
            os.path.join("Resources", "images", "tree")), "Project")

        self.fileExplorer = FileExplorer(
            self.useData, self.PROJECT_DATA['shortcuts'], self.messagesWidget, self.editorTabWidget)
        self.fileExplorer.fileActivated.connect(self.editorTabWidget.loadfile)
        self.sideBottomTab.addTab(self.fileExplorer, QtGui.QIcon(
            os.path.join("Resources", "images", "tree")), "File System")

        # create menus
        self.mainMenu = QtGui.QMenu()
        self.mainMenu.addMenu(self.editorTabWidget.newFileMenu)
        self.mainMenu.addAction(self.editorTabWidget.openFileAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAllAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAsAct)
        self.mainMenu.addAction(self.editorTabWidget.saveCopyAsAct)
        self.mainMenu.addAction(self.editorTabWidget.printAct)

        self.projectMenu = QtGui.QMenu("Project")
        if pathDict["type"] == "Desktop Application":
            self.projectMenu.addAction(self.buildAct)
            self.projectMenu.addAction(self.openBuildAct)
        self.projectMenu.addAction(self.configureAct)
        self.projectMenu.addSeparator()
        self.projectMenu.addAction(self.exportProjectAct)
        self.projectMenu.addAction(self.closeProjectAct)
        self.mainMenu.addMenu(self.projectMenu)

        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.gotoLineAct)
        self.mainMenu.addAction(self.viewSwitcherAct)
        helpMenu = self.mainMenu.addMenu("Help")
        helpMenu.addAction(self.userGuideAct)
        helpMenu.addAction(self.pythonManualsAct)
        helpMenu.addSeparator()
        helpMenu.addAction(self.feedbackAct)
        helpMenu.addAction(self.checkUpdatesAct)
        self.mainMenu.addSeparator()
        self.mainMenu.addMenu(self.manageFavourites.favouritesMenu)
        self.recentFilesMenu = self.mainMenu.addMenu("Recent Files")
        self.recentFilesMenu.setIcon(
            QtGui.QIcon(os.path.join("Resources", "images", "history")))
        self.loadRecentFiles()
        self.mainMenu.addMenu(self.externalLauncher.launcherMenu)
        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.exitAct)

        self.createToolbars()

        # create StatusBar
        self.statusbar = QtGui.QStatusBar()

        self.statusbar.addPermanentWidget(self.buildStatusWidget)

        #*** Position
        self.cursorPositionButton = QtGui.QToolButton()
        self.cursorPositionButton.setAutoRaise(True)
        self.cursorPositionButton.clicked.connect(
            self.editorTabWidget.goToCursorPosition)
        self.statusbar.addPermanentWidget(self.cursorPositionButton)
        #*** lines
        self.linesLabel = QtGui.QLabel("Lines: 0")
        self.linesLabel.setMinimumWidth(50)
        self.statusbar.addPermanentWidget(self.linesLabel)
        #*** encoding
        self.encodingLabel = QtGui.QLabel("Coding: utf-8")
        self.statusbar.addPermanentWidget(self.encodingLabel)
        #*** uptime
        self.uptimeLabel = QtGui.QLabel()
        self.uptimeLabel.setText("Uptime: 0min")
        self.statusbar.addPermanentWidget(self.uptimeLabel)

        self.runWidget = RunWidget(
            self.bottomStackSwitcher, self.PROJECT_DATA[
                "settings"], self.useData,
            self.editorTabWidget, self.vSplitter,
            self.runProjectAct, self.stopRunAct, self.runFileAct)
        self.addBottomWidget(self.runWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "graphic-design")),  "Output")

        self.assistantWidget = Assistant(
            self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(self.assistantWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "flag")), "Alerts")

        bookmarkWidget = BookmarkWidget(
            self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(bookmarkWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "tag")), "Bookmarks")

        tasksWidget = Tasks(self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(tasksWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "issue")), "Tasks")

        self.addBottomWidget(self.messagesWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "speech_bubble")), "Messages")

        self.profiler = Profiler(self.useData, self.bottomStackSwitcher)
        self.addBottomWidget(self.profiler,
                             QtGui.QIcon(os.path.join("Resources", "images", "settings")), "Profiler")
        self.runWidget.loadProfile.connect(
            self.profiler.viewProfile)

        self.addBottomWidget(self.findInFiles,
                             QtGui.QIcon(os.path.join("Resources", "images", "attibutes")), "Find-in-Files")

        self.bottomStackSwitcher.setDefault()

        hbox = QtGui.QHBoxLayout()
        hbox.setMargin(0)
        hbox.setSpacing(0)
        hbox.addWidget(self.bottomStackSwitcher)
        hbox.addStretch(1)
        hbox.addWidget(self.statusbar)
        mainLayout.addLayout(hbox)

        self.uptime = 0
        self.uptimeTimer = QtCore.QTimer()
        self.uptimeTimer.setInterval(60000)
        self.uptimeTimer.timeout.connect(self.updateUptime)
        self.uptimeTimer.start()

        # remember layout
        if pathDict['root'] in self.useData.OPENED_PROJECTS:
            settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
            settings.beginGroup(pathDict['root'])
            self.hSplitter.restoreState(settings.value('hsplitter'))
            self.vSplitter.restoreState(settings.value('vsplitter'))
            self.sideSplitter.restoreState(
                settings.value('sidesplitter'))
            self.vSplitter.updateStatus()
            self.writePad.setGeometry(settings.value('writepad'))
            settings.endGroup()

        self.install_shortcuts()

    def createActions(self):
        self.gotoLineAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "mail_check")),
                "Goto Line", self,
                statusTip="Goto Line", triggered=self.showGotoLineWidget)

        self.viewSwitcherAct = QtGui.QAction(
            "Switch Views", self, statusTip="Switch Views",
            triggered=self.showSnapShotSwitcher)

        self.exitAct = \
            QtGui.QAction("Exit", self, statusTip="Exit",
                          triggered=self.projects.closeProgram)

        # Menubar Actions ----------------------------------------------------

        self.userGuideAct = QtGui.QAction(
            "User Guide", self, statusTip="User Guide",
                                         triggered=self.launchHelp)

        self.pythonManualsAct = QtGui.QAction("Python Manuals", self,
                                              statusTip="Python Manuals",
                                              triggered=self.launchPythonHelp)

        self.checkUpdatesAct = QtGui.QAction("Check For Updates", self,
                                             statusTip="Check For Updates",
                                             triggered=self.visitHomepage)

        self.feedbackAct = QtGui.QAction("Send Feedback", self,
                                         statusTip="Send Feedback",
                                        triggered=self.openFeedbackLink)
        #----------------------------------------------------------------------
        self.runFileAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "rerun")),
            "Run File", self,
            statusTip="Run current file", triggered=self.runFile)

        self.runProjectAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "run")),
            "Run Project", self,
            statusTip="Run Project", triggered=self.runProject)

        self.stopRunAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "stop")),
            "Stop", self,
            statusTip="Stop execution",
            triggered=self.stopProcess)

        self.runParamAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "shell")),
            "Set Run Parameters", self,
            statusTip="Set Run Parameters",
            triggered=self.setRunParameters)

        #---------------------------------------------------------------------

        self.finderAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "scope")),
            "Find", self,
            statusTip="Find", triggered=self.showFinderWidget)

        self.replaceAct = \
            QtGui.QAction(
                QtGui.QIcon(
                    os.path.join("Resources", "images", "edit-replace")),
                "Replace", self,
                statusTip="Replace",
                          triggered=self.showReplaceWidget)

        self.findInFilesAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "find_in_files")),
            "Find-in-Files", self,
            statusTip="Find-in-Files", triggered=self.showFindInFilesWidget)

        self.addToLibraryAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "add")),
                "Add To Library", self,
                statusTip="Add current module to Library",
                          triggered=self.addToLibrary)

        self.clearRecentFilesAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "clear")),
                "Clear History", self, statusTip="Clear History",
                triggered=self.clearRecentFiles)

        self.writePadAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "pencil")),
                "Writepad", self, statusTip="Writepad",
                triggered=self.showWritePad)

        self.buildAct = \
            QtGui.QAction(
                "Build", self,
                statusTip="Build",
                triggered=self.buildProject)

        self.openBuildAct = \
            QtGui.QAction(
                "Open Build", self, statusTip="Open Build",
                triggered=self.openBuild)

        self.configureAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "settings")),
                "Configuration", self, statusTip="Configuration",
                triggered=self.showProjectConfiguration)

        self.exportProjectAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "archive")),
                "Export as Zip...", self, statusTip="Export as Zip",
                triggered=self.exportProject)

        self.closeProjectAct = \
            QtGui.QAction(
                QtGui.QIcon(
                    os.path.join("Resources", "images", "inbox--minus")),
                "Close Project", self, statusTip="Close Project",
                triggered=self.closeProject)

    def visitHomepage(self):
        QtGui.QDesktopServices().openUrl(QtCore.QUrl(
            """https://github.com/fortharris/Pcode"""))

    def showProjectConfiguration(self):
        self.editorTabWidget.showProjectConfiguration()

    def buildProject(self):
        self.projectManager.buildProject()

    def openBuild(self):
        self.projectManager.openBuild()

    def exportProject(self):
        self.projectManager.exportProject()

    def closeProject(self):
        self.projects.closeProject()

    def updateEncodingLabel(self, text):
        self.encodingLabel.setText(text)

    def showGotoLineWidget(self):
        self.editorTabWidget.showGotoLineWidget()

    def showSnapShotSwitcher(self):
        self.editorTabWidget.showSnapShotSwitcher()

    def addBottomWidget(self, widget, icon, name):
        self.bottomStack.addWidget(widget)
        self.bottomStackSwitcher.addButton(toolTip=name, icon=icon)

    def showWritePad(self):
        self.writePad.show()

    def showFinderWidget(self):
        self.findInFiles.dashboard.hide()
        self.searchWidget.showFinder()

    def showReplaceWidget(self):
        self.findInFiles.dashboard.hide()
        self.searchWidget.showReplaceWidget()

    def showFindInFilesWidget(self):
        self.searchWidget.hide()
        self.findInFiles.dashboard.show()

    def createToolbars(self):

        self.editorMenuButton = QtGui.QToolButton()
        self.editorMenuButton.setText("Menu")
        self.editorMenuButton.setToolButtonStyle(2)
        self.editorMenuButton.setAutoRaise(True)
        self.editorMenuButton.setPopupMode(2)
        self.editorMenuButton.setIcon(QtGui.QIcon(
            os.path.join("Resources", "images", "Dashboard")))
        self.editorMenuButton.setMenu(self.mainMenu)

        self.standardToolbar.addWidget(self.editorMenuButton)
        self.standardToolbar.addAction(self.editorTabWidget.openFileAct)
        self.standardToolbar.addAction(self.editorTabWidget.newPythonFileAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.saveAct)
        self.standardToolbar.addAction(self.editorTabWidget.saveAllAct)
        self.standardToolbar.addAction(self.editorTabWidget.undoAct)
        self.editorTabWidget.undoAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.redoAct)
        self.editorTabWidget.redoAct.setDisabled(True)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.cutAct)
        self.editorTabWidget.cutAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.copyAct)
        self.editorTabWidget.copyAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.pasteAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.dedentAct)
        self.standardToolbar.addAction(self.editorTabWidget.indentAct)

        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.runFileAct)
        self.standardToolbar.addAction(self.runProjectAct)
        self.standardToolbar.addAction(self.stopRunAct)
        self.stopRunAct.setVisible(False)
        self.standardToolbar.addAction(self.runParamAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.finderAct)
        self.standardToolbar.addAction(self.replaceAct)
        self.standardToolbar.addAction(self.findInFilesAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.addToLibraryAct)
        self.standardToolbar.addAction(self.writePadAct)

        self.bookmarkToolbar.addAction(
            self.editorTabWidget.findNextBookmarkAct)
        self.bookmarkToolbar.addAction(
            self.editorTabWidget.findPrevBookmarkAct)
        self.bookmarkToolbar.addAction(self.editorTabWidget.removeBookmarksAct)
        self.standardToolbar.addWidget(self.bookmarkToolbar)

    def recentFileActivated(self, action):
        path = action.text().split('  ', 1)[1]
        if os.path.exists(path):
            self.editorTabWidget.loadfile(path)
        else:
            message = QtGui.QMessageBox.warning(self, "Open",
                                                "File is unavailable!")

    def loadRecentFiles(self):
        if len(self.PROJECT_DATA['recentfiles']) > 0:
            self.recentFile_actionGroup = QtGui.QActionGroup(self)
            self.recentFile_actionGroup.triggered.connect(
                self.recentFileActivated)
            self.recentFilesMenu.clear()
            c = 1
            for i in self.PROJECT_DATA['recentfiles']:
                action = QtGui.QAction(str(c) + '  ' + i, self)
                self.recentFile_actionGroup.addAction(action)
                self.recentFilesMenu.addAction(action)
                c += 1
            self.recentFilesMenu.addSeparator()
            self.recentFilesMenu.addAction(self.clearRecentFilesAct)
        else:
            self.recentFilesMenu.addAction("No Recent Files")

    def updateRecentFiles(self, filePath):
        if filePath in self.PROJECT_DATA['recentfiles']:
            self.PROJECT_DATA['recentfiles'].remove(filePath)
            self.PROJECT_DATA['recentfiles'].insert(0, filePath)
        else:
            if len(self.PROJECT_DATA['recentfiles']) < 15:
                self.PROJECT_DATA['recentfiles'].insert(0, filePath)
            else:
                del self.PROJECT_DATA['recentfiles'][-1]
                self.PROJECT_DATA['recentfiles'].insert(0, filePath)
        self.loadRecentFiles()

    def clearRecentFiles(self):
        self.PROJECT_DATA['recentfiles'] = []
        self.recentFilesMenu.clear()
        self.loadRecentFiles()
        self.messagesWidget.addMessage(0, 'Recent Files:',
                                       ["Recent files history has been cleared!"])

    def addToLibrary(self):
        self.library.addToLibrary(self.editorTabWidget)

    def openFeedbackLink(self):
        QtGui.QDesktopServices().openUrl(QtCore.QUrl(
            """https://twitter.com/PcodeIDE"""))

    def updateUptime(self):
        self.uptime += 1
        if self.uptime == 60:
            new_time = "1hr"
        elif self.uptime > 60:
            t = int(str(self.uptime / 60).split('.')[0])
            h = str(t) + "hr"
            m = str(self.uptime - (t * 60)) + "min"
            new_time = h + m
        else:
            new_time = str(self.uptime) + "min"
        self.uptimeLabel.setText("Uptime: " + new_time)

    def saveAll(self):
        self.editorTabWidget.saveAll()

    def fileUrl(self, fname):
        """Select the right file uri scheme according to the operating system"""
        if os.name == 'nt':
            # Local file
            if re.search(r'^[a-zA-Z]:', fname):
                return 'file:///' + fname
            # UNC based path
            else:
                return 'file://' + fname
        else:
            return 'file://' + fname

    def getPythonDocPath(self):
        """
        Return Python documentation path
        (Windows: return the PythonXX.chm path if available)
        """
        if os.name == 'nt':
            version = self.editorTabWidget.setRunParameters.getVesionFromVenv()
            version_ = version.split('.')
            folderName = 'Python' + version_[0] + version_[1]
            path = os.path.join("c:\\", folderName)
            doc_path = os.path.join(path, "Doc")
            if not os.path.isdir(doc_path):
                return
            python_chm = [path for path in os.listdir(doc_path)
                          if re.match(r"(?i)Python[0-9]{3}.chm", path)]
            if python_chm:
                return self.fileUrl(os.path.join(doc_path, python_chm[0]))
        else:
            vinf = sys.version_info
            doc_path = '/usr/share/doc/python%d.%d/html' % (vinf[0], vinf[1])
        python_doc = os.path.join(doc_path, "index.html")
        if os.path.isfile(python_doc):
            return self.fileUrl(python_doc)

    def launchHelp(self):
        message = QtGui.QMessageBox.warning(
            self, "User Guide", "Will be available when i am out of beta.")

    def launchPythonHelp(self):
        try:
            doc_path = self.getPythonDocPath()
            os.startfile(doc_path)
        except Exception as err:
            message = QtGui.QMessageBox.critical(self, "Python Manuals",
                                                 ("Failed to launch the Python Manuals!\n\n"
                                                  "It is either not available for the current python "
                                                  "version or Python is not installed in your system."))

    def setRunParameters(self):
        self.editorTabWidget.showSetRunParameters()

    def runFile(self):
        self.runWidget.runFile()

    def runProject(self):
        self.runWidget.runProject()

    def stopProcess(self):
        self.runWidget.stopProcess()

    def showPythonInterpreter(self):
        process = QtCore.QProcess()
        process.startDetached(self.useData.SETTINGS["DefaultInterpreter"])

    def showCommandPrompt(self):
        prompt = os.environ["COMSPEC"]
        process = QtCore.QProcess()
        process.startDetached(prompt, [], QtCore.QDir().rootPath())

    def showCursorPosition(self):
        line, index = self.editorTabWidget.currentEditor.getCursorPosition()
        self.cursorPositionButton.setText(
            "Line {0} : Column {1}".format(line + 1, index + 1))

    def updateLineCount(self, lines):
        self.linesLabel.setText("Lines: " + str(lines))

    def saveUiState(self):
        name = self.pathDict["root"]
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup(name)
        settings.setValue('hsplitter', self.hSplitter.saveState())
        settings.setValue('vsplitter', self.vSplitter.saveState())
        settings.setValue('sidesplitter', self.sideSplitter.saveState())
        settings.setValue('writepad', self.writePad.geometry())
        settings.endGroup()

    def restoreSession(self):
        self.editorTabWidget.restoreSession()

    def makeLogEntry(self, entry):
        file = open(self.pathDict["log"], 'a')
        file.write(
            "\n[ {0} :: {1} ]".format(QtCore.QDate().currentDate().toString(),
                                      QtCore.QTime().currentTime().toString()))
        file.write('\n' + entry)
        file.close()

    def closeWindow(self):
        if self.runWidget.currentProcess is not None:
            mess = "Close running program?"
            reply = QtGui.QMessageBox.warning(self, "Close",
                                              mess, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
            if reply == QtGui.QMessageBox.Yes:
                self.runWidget.stopProcess()
            else:
                return False
        modified = []
        for i in range(self.editorTabWidget.count()):
            if self.editorTabWidget.getEditor(i).isModified():
                modified.append(i)
        if len(modified) == 0:
            pass
        else:
            for i in range(len(modified)):
                v = modified.pop(-1)
                self.editorTabWidget.setCurrentIndex(v)
                mess = 'Save changes to "{0}"?'.format(
                    self.editorTabWidget.tabText(v))
                reply = QtGui.QMessageBox.warning(self, "Close", mess,
                                                  QtGui.QMessageBox.Yes | QtGui.QMessageBox.No |
                                                  QtGui.QMessageBox.Cancel)
                if reply == QtGui.QMessageBox.No:
                    if len(modified) == 0:
                        pass
                elif reply == QtGui.QMessageBox.Yes:
                    saved = self.editorTabWidget.save()
                    if saved:
                        pass
                    else:
                        return False
                elif reply == QtGui.QMessageBox.Cancel:
                    return False
        self.saveUiState()
        self.editorTabWidget.saveSession()
        self.PROJECT_DATA["settings"]["Closed"] = "True"
        self.saveProjectData()
        self.editorTabWidget.refactor.close()
        self.makeLogEntry(self.uptimeLabel.text())

        return True

    def loadProjectData(self):
        dom_document = QtXml.QDomDocument()
        file = open(os.path.join(self.pathDict[
                    "root"], "Data", "projectdata.xml"), "r")
        x = dom_document.setContent(file.read())
        file.close()

        elements = dom_document.documentElement()
        node = elements.firstChild()

        shortcuts = []
        recentfiles = []
        favourites = []
        launchers = {}

        settingsList = []
        while node.isNull() is False:
            property = node.toElement()
            sub_node = property.firstChild()
            while sub_node.isNull() is False:
                sub_prop = sub_node.toElement()
                if node.nodeName() == "shortcuts":
                    shortcuts.append(sub_prop.text())
                elif node.nodeName() == "recentfiles":
                    if os.path.exists(sub_prop.text()):
                        recentfiles.append(sub_prop.text())
                    else:
                        pass
                elif node.nodeName() == "favourites":
                    favourites.append(sub_prop.text())
                elif node.nodeName() == "settings":
                    settingsList.append((tuple(sub_prop.text().split('=', 1))))
                elif node.nodeName() == "launchers":
                    tag = sub_prop.toElement()
                    path = tag.attribute("path")
                    param = tag.attribute("param")
                    launchers[path] = param
                sub_node = sub_node.nextSibling()
            node = node.nextSibling()
        settingsDict = dict(settingsList)

        settingsDict['LastCloseSuccessful'] = settingsDict['Closed']
        settingsDict['Closed'] = "False"
        settingsDict['venvdir'] = self.useData.appPathDict['venvdir']

        self.PROJECT_DATA = {}
        self.PROJECT_DATA["shortcuts"] = shortcuts
        self.PROJECT_DATA["favourites"] = favourites
        self.PROJECT_DATA["recentfiles"] = recentfiles
        self.PROJECT_DATA["settings"] = settingsDict
        self.PROJECT_DATA["launchers"] = launchers
        self.pathDict["DefaultVenv"] = settingsDict["DefaultVenv"]

        # in order that a crash can be reported
        self.saveProjectData()

    def saveProjectData(self):
        domDocument = QtXml.QDomDocument("projectdata")

        projectdata = domDocument.createElement("projectdata")
        domDocument.appendChild(projectdata)

        root = domDocument.createElement("shortcuts")
        projectdata.appendChild(root)

        for i in self.PROJECT_DATA['shortcuts']:
            tag = domDocument.createElement("shortcut")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("recentfiles")
        projectdata.appendChild(root)

        for i in self.PROJECT_DATA['recentfiles']:
            tag = domDocument.createElement("recent")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("favourites")
        projectdata.appendChild(root)

        for i in self.PROJECT_DATA['favourites']:
            tag = domDocument.createElement("fav")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("launchers")
        projectdata.appendChild(root)

        for path, param in self.PROJECT_DATA['launchers'].items():
            tag = domDocument.createElement("item")
            tag.setAttribute("path", path)
            tag.setAttribute("param", param)
            root.appendChild(tag)

        root = domDocument.createElement("settings")
        projectdata.appendChild(root)

        s = 0
        for key, value in self.PROJECT_DATA['settings'].items():
            tag = domDocument.createElement("key")
            root.appendChild(tag)

            t = domDocument.createTextNode(key + '=' + value)
            tag.appendChild(t)
            s += 1

        path = os.path.join(self.pathDict["root"], "Data", "projectdata.xml")
        file = open(path, "w")
        file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
        file.write(domDocument.toString())
        file.close()

    def install_shortcuts(self):
        shortcuts = self.useData.CUSTOM_DEFAULT_SHORTCUTS

        self.shortGotoLine = QtGui.QShortcut(
            shortcuts["Ide"]["Go-to-Line"][0], self)
        self.shortGotoLine.activatedAmbiguously.connect(
            self.showGotoLineWidget)
        self.gotoLineAct.setShortcut(shortcuts["Ide"]["Go-to-Line"][0])

        self.shortBuild = QtGui.QShortcut(shortcuts["Ide"]["Build"][0], self)
        self.shortBuild.activatedAmbiguously.connect(self.buildProject)
        self.buildAct.setShortcut(shortcuts["Ide"]["Build"][0])

        self.shortFind = QtGui.QShortcut(shortcuts["Ide"]["Find"][0], self)
        self.shortFind.activated.connect(self.showFinderWidget)

        self.shortReplace = QtGui.QShortcut(
            shortcuts["Ide"]["Replace"][0], self)
        self.shortReplace.activated.connect(self.showReplaceWidget)

        self.shortRunFile = QtGui.QShortcut(
            shortcuts["Ide"]["Run-File"][0], self)
        self.shortRunFile.activated.connect(self.runFile)

        self.shortRunProject = QtGui.QShortcut(
            shortcuts["Ide"]["Run-Project"][0], self)
        self.shortRunProject.activated.connect(self.runProject)

        self.shortStopRun = QtGui.QShortcut(
            shortcuts["Ide"]["Stop-Execution"][0], self)
        self.shortStopRun.activated.connect(self.stopProcess)

        self.shortPythonManuals = QtGui.QShortcut(
            shortcuts["Ide"]["Python-Manuals"][0], self)
        self.shortPythonManuals.activatedAmbiguously.connect(
            self.launchPythonHelp)
        self.pythonManualsAct.setShortcut(
            shortcuts["Ide"]["Python-Manuals"][0])
Esempio n. 2
0
class Pcode(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowIcon(
            QtGui.QIcon(os.path.join("Resources", "images", "Icon")))
        self.setWindowTitle("Pcode - Loading...")

        screen = QtGui.QDesktopWidget().screenGeometry()
        self.resize(screen.width() - 200, screen.height() - 200)
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)
        self.lastWindowGeometry = self.geometry()

        self.setBaseColor()

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.setSpacing(0)
        mainLayout.setMargin(0)
        self.setLayout(mainLayout)

        self.useData = UseData()
        self.library = Library(self.useData)
        self.busyWidget = BusyWidget(app, self.useData, self)

        self.projectWindowStack = QtGui.QStackedWidget()

        self.projectTitleBox = QtGui.QComboBox()
        self.projectTitleBox.setMinimumWidth(180)
        self.projectTitleBox.setStyleSheet(StyleSheet.projectTitleBoxStyle)
        self.projectTitleBox.setItemDelegate(QtGui.QStyledItemDelegate())
        self.projectTitleBox.currentIndexChanged.connect(self.projectChanged)
        self.projectTitleBox.activated.connect(self.projectChanged)

        self.settingsWidget = SettingsWidget(self.useData,
                                             self.projectWindowStack,
                                             self.library.codeViewer, self)
        self.settingsWidget.colorScheme.styleEditor(self.library.codeViewer)

        startWindow = Start(self.useData, self)
        self.addProject(startWindow, "Start", "Start",
                        os.path.join("Resources", "images", "flag-green"))

        self.projects = Projects(self.useData, self.busyWidget, self.library,
                                 self.settingsWidget, app,
                                 self.projectWindowStack, self.projectTitleBox,
                                 self)

        self.createActions()

        hbox = QtGui.QHBoxLayout()
        hbox.setContentsMargins(5, 3, 5, 3)
        mainLayout.addLayout(hbox)

        hbox.addStretch(1)

        self.pagesStack = QtGui.QStackedWidget()
        mainLayout.addWidget(self.pagesStack)

        self.projectSwitcher = StackSwitcher(self.pagesStack)
        self.projectSwitcher.setStyleSheet(StyleSheet.mainMenuStyle)
        hbox.addWidget(self.projectSwitcher)

        self.addPage(
            self.projectWindowStack, "EDITOR",
            QtGui.QIcon(os.path.join("Resources", "images", "hire-me")))

        self.addPage(
            self.library, "LIBRARY",
            QtGui.QIcon(os.path.join("Resources", "images", "library")))
        self.projectSwitcher.setDefault()

        hbox.addWidget(self.projectTitleBox)
        hbox.setSpacing(5)

        self.settingsButton = QtGui.QToolButton()
        self.settingsButton.setAutoRaise(True)
        self.settingsButton.setDefaultAction(self.settingsAct)
        hbox.addWidget(self.settingsButton)

        self.fullScreenButton = QtGui.QToolButton()
        self.fullScreenButton.setAutoRaise(True)
        self.fullScreenButton.setDefaultAction(self.showFullScreenAct)
        hbox.addWidget(self.fullScreenButton)

        self.aboutButton = QtGui.QToolButton()
        self.aboutButton.setAutoRaise(True)
        self.aboutButton.setDefaultAction(self.aboutAct)
        hbox.addWidget(self.aboutButton)

        self.install_shortcuts()

        if self.useData.settings["firstRun"] == 'True':
            self.showMaximized()
        else:
            self.restoreUiState()

        self.useData.settings["running"] = 'True'
        self.useData.settings["firstRun"] = 'False'
        self.useData.saveSettings()

    def createActions(self):
        self.aboutAct = QtGui.QAction(QtGui.QIcon(
            os.path.join("Resources", "images", "properties")),
                                      "About Pcode",
                                      self,
                                      statusTip="About Pcode",
                                      triggered=self.showAbout)

        self.showFullScreenAct = \
            QtGui.QAction(QtGui.QIcon(os.path.join("Resources", "images", "fullscreen")),
                          "Fullscreen", self,
                          statusTip="Fullscreen",
                          triggered=self.showFullScreenMode)

        self.settingsAct = QtGui.QAction(QtGui.QIcon(
            os.path.join("Resources", "images", "config")),
                                         "Settings",
                                         self,
                                         statusTip="Settings",
                                         triggered=self.showSettings)

    def addPage(self, pageWidget, name, iconPath):
        self.projectSwitcher.addButton(name=name, icon=iconPath)
        self.pagesStack.addWidget(pageWidget)

    def loadProject(self, path, show=False, new=False):
        self.projects.loadProject(path, show, new)

    def newProject(self):
        self.projects.newProjectDialog.exec_()

    def showProject(self, path):
        if not os.path.exists(path):
            message = QtGui.QMessageBox.warning(self, "Open Project",
                                                "Project cannot be be found!")
        else:
            if path in self.useData.OPENED_PROJECTS:
                for i in range(self.projectWindowStack.count() - 1):
                    window = self.projectWindowStack.widget(i)
                    p_path = window.pathDict["root"]
                    if os.path.samefile(path, p_path):
                        self.projectTitleBox.setCurrentIndex(i)
                        return True
        return False

    def addProject(self, window, name, type='Project', iconPath=None):
        self.projectWindowStack.insertWidget(0, window)
        if type == 'Project':
            self.projectTitleBox.insertItem(
                0, QtGui.QIcon(os.path.join("Resources", "images", "project")),
                name, [window, type])
        else:
            self.projectTitleBox.insertItem(0, QtGui.QIcon(iconPath), name,
                                            [window, type])

    def projectChanged(self, index):
        data = self.projectTitleBox.itemData(index)
        window = data[0]
        windowType = data[1]
        if windowType == "Start":
            self.setWindowTitle("Pcode - Start")
        elif windowType == "Project":
            title = window.editorTabWidget.getEditorData("filePath")
            self.updateWindowTitle(title)
        self.projectWindowStack.setCurrentWidget(window)

    def removeProject(self, window):
        for index in range(self.projectTitleBox.count() - 1):
            data = self.projectTitleBox.itemData(index)
            windowWidget = data[0]
            if windowWidget == window:
                self.projectWindowStack.removeWidget(window)
                self.projectTitleBox.removeItem(index)

    def updateWindowTitle(self, title):
        if title is None:
            title = "Pcode - " + "Unsaved"
        else:
            window = self.projectTitleBox.itemData(
                self.projectTitleBox.currentIndex())[0]
            if title.startswith(window.pathDict["sourcedir"]):
                src_dir = window.pathDict["sourcedir"]
                n = title.partition(src_dir)[-1]
                title = 'Pcode - ' + n
            else:
                title = "Pcode - " + title
        self.setWindowTitle(title)

    def showAbout(self):
        aboutPane = About(self)
        aboutPane.exec_()

    def showSettings(self):
        self.settingsWidget.show()

    def showFullScreenMode(self):
        if self.isFullScreen():
            self.showNormal()
            self.setGeometry(self.lastWindowGeometry)
        else:
            # get current size ahd show Fullscreen
            # so we can later restore to proper position
            self.lastWindowGeometry = self.geometry()
            self.showFullScreen()

    def saveUiState(self):
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup("MainWindow")
        settings.setValue("geometry", self.geometry())
        settings.setValue("lsplitter", self.library.mainSplitter.saveState())
        settings.setValue(
            "snippetsMainsplitter",
            self.settingsWidget.snippetEditor.mainSplitter.saveState())
        settings.setValue("windowMaximized", self.isMaximized())
        settings.endGroup()

    def restoreUiState(self):
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup("MainWindow")
        if settings.value("windowMaximized", True, type=bool):
            self.showMaximized()
        else:
            self.setGeometry(settings.value("geometry"))
            self.show()
        self.library.mainSplitter.restoreState(settings.value("lsplitter"))
        self.settingsWidget.snippetEditor.mainSplitter.restoreState(
            settings.value("snippetsMainsplitter"))
        settings.endGroup()

    def closeEvent(self, event):
        for i in range(self.projectWindowStack.count() - 1):
            window = self.projectWindowStack.widget(i)
            closed = window.closeWindow()
            if not closed:
                self.projectTitleBox.setCurrentIndex(i)
                event.ignore()
                return
            else:
                pass
        self.saveUiState()
        self.useData.saveUseData()
        app.closeAllWindows()

        event.accept()

    def setBaseColor(self):
        baseColor = "#EFEFF2"

        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(baseColor))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(baseColor))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(baseColor))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(baseColor))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(baseColor))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
        self.setPalette(palette)

    def install_shortcuts(self):
        shortcuts = self.useData.CUSTOM_DEFAULT_SHORTCUTS

        self.shortFullscreen = QtGui.QShortcut(
            shortcuts["Ide"]["Fullscreen"][0], self)
        self.shortFullscreen.activated.connect(self.showFullScreenMode)
Esempio n. 3
0
class EditorWindow(QtGui.QWidget):

    def __init__(self, projectPathDict, library, busyWidget,
                 colorScheme, useData, app, parent):
        QtGui.QWidget.__init__(self, parent)

        self.app = app
        self.useData = useData
        self.library = library
        self.projects = parent
        self.colorScheme = colorScheme

        self.projectPathDict = projectPathDict
        self.loadProjectData()

        self.busyWidget = busyWidget
        self.buildStatusWidget = BuildStatusWidget(self.app, self.useData)

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.setMargin(0)
        mainLayout.setSpacing(0)
        self.setLayout(mainLayout)

        self.standardToolbar = QtGui.QToolBar("Standard")
        self.standardToolbar.setMovable(False)
        self.standardToolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
        self.standardToolbar.setMaximumHeight(26)
        self.standardToolbar.setObjectName("StandardToolBar")
        mainLayout.addWidget(self.standardToolbar)

        widget = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout()
        vbox.setMargin(0)
        vbox.setSpacing(0)
        widget.setLayout(vbox)

        self.vSplitter = VerticalSplitter()
        mainLayout.addWidget(self.vSplitter)

        self.hSplitter = QtGui.QSplitter()
        self.hSplitter.setObjectName("hSplitter")

        self.vSplitter.addWidget(self.hSplitter)

        self.bottomStack = QtGui.QStackedWidget()
        self.vSplitter.addWidget(self.bottomStack)

        self.hSplitter.addWidget(widget)

        self.bottomStackSwitcher = StackSwitcher(self.bottomStack)
        self.bottomStackSwitcher.setStyleSheet(StyleSheet.bottomSwitcherStyle)

        self.messagesWidget = MessagesWidget(
            self.bottomStackSwitcher, self.vSplitter)

        self.createActions()

        self.manageFavourites = Favourites(

            self.projectData['favourites'], self.messagesWidget, self)

        self.externalLauncher = ExternalLauncher(
            self.projectData["launchers"], self)

        self.writePad = WritePad(self.projectPathDict[
                                 "notes"], self.projectPathDict["name"], self)

        self.bookmarkToolbar = QtGui.QToolBar("Bookmarks")
        self.bookmarkToolbar.setMovable(False)
        self.bookmarkToolbar.setFloatable(False)
        self.bookmarkToolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
        self.bookmarkToolbar.setObjectName("Bookmarks")
        self.bookmarkToolbar.addSeparator()

        self.editorTabWidget = EditorTabWidget(
            self.useData, self.projectPathDict, self.projectData[
                "settings"], self.messagesWidget,
            self.colorScheme, self.busyWidget, self.bookmarkToolbar, self.app, self.manageFavourites,
            self.externalLauncher, self)
        vbox.addWidget(self.editorTabWidget)

        self.manageFavourites.openFile.connect(self.editorTabWidget.loadfile)

        self.editorTabWidget.updateRecentFilesList.connect(
            self.updateRecentFiles)
        self.editorTabWidget.updateLinesCount.connect(self.updateLineCount)
        self.editorTabWidget.updateEncodingLabel.connect(
            self.updateEncodingLabel)
        self.editorTabWidget.cursorPositionChanged.connect(
            self.showCursorPosition)

        self.searchWidget = SearchWidget(
            self.useData, self.editorTabWidget)
        vbox.addWidget(self.searchWidget)

        self.findInFiles = FindInFiles(
            self.useData, self.editorTabWidget, projectPathDict, self.bottomStackSwitcher)
        vbox.addWidget(self.findInFiles.dashboard)
        self.findInFiles.dashboard.hide()

        self.projectManager = ProjectManager(
            self.editorTabWidget, self.messagesWidget, projectPathDict, self.projectData[
                "settings"], self.useData, app,
            self.busyWidget, self.buildStatusWidget, self.projects)
        self.projectManager.projectView.fileActivated.connect(
            self.editorTabWidget.loadfile)

        self.outline = Outline(
            self.useData, self.editorTabWidget)

        self.sideSplitter = QtGui.QSplitter()
        self.sideSplitter.setObjectName("sidebarItem")
        self.sideSplitter.setOrientation(0)
        self.hSplitter.addWidget(self.sideSplitter)

        self.sideSplitter.addWidget(self.outline)

        self.sideBottomTab = QtGui.QTabWidget()
        self.sideBottomTab.setObjectName("sideBottomTab")
        self.sideSplitter.addWidget(self.sideBottomTab)

        self.sideBottomTab.addTab(self.projectManager.projectView, QtGui.QIcon(
            os.path.join("Resources", "images", "tree")), "Project")

        self.fileExplorer = FileExplorer(
            self.useData, self.projectData['shortcuts'], self.messagesWidget, self.editorTabWidget)
        self.fileExplorer.fileActivated.connect(self.editorTabWidget.loadfile)
        self.sideBottomTab.addTab(self.fileExplorer, QtGui.QIcon(
            os.path.join("Resources", "images", "tree")), "File System")

        # create menus
        self.mainMenu = QtGui.QMenu()
        self.mainMenu.addMenu(self.editorTabWidget.newFileMenu)
        self.mainMenu.addAction(self.editorTabWidget.openFileAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAllAct)
        self.mainMenu.addAction(self.editorTabWidget.saveAsAct)
        self.mainMenu.addAction(self.editorTabWidget.saveCopyAsAct)
        self.mainMenu.addAction(self.editorTabWidget.printAct)

        self.projectMenu = QtGui.QMenu("Project")
        if projectPathDict["type"] == "Desktop Application":
            self.projectMenu.addAction(self.buildAct)
            self.projectMenu.addAction(self.openBuildAct)
        self.projectMenu.addAction(self.configureAct)
        self.projectMenu.addSeparator()
        self.projectMenu.addAction(self.exportProjectAct)
        self.projectMenu.addAction(self.closeProjectAct)
        self.mainMenu.addMenu(self.projectMenu)

        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.gotoLineAct)
        self.mainMenu.addAction(self.viewSwitcherAct)
        helpMenu = self.mainMenu.addMenu("Help")
        helpMenu.addAction(self.userGuideAct)
        helpMenu.addAction(self.pythonManualsAct)
        helpMenu.addSeparator()
        helpMenu.addAction(self.checkUpdatesAct)
        self.mainMenu.addSeparator()
        self.mainMenu.addMenu(self.manageFavourites.favouritesMenu)
        self.recentFilesMenu = self.mainMenu.addMenu("Recent Files")
        self.recentFilesMenu.setIcon(
            QtGui.QIcon(os.path.join("Resources", "images", "history")))
        self.loadRecentFiles()
        self.mainMenu.addMenu(self.externalLauncher.launcherMenu)
        self.mainMenu.addSeparator()
        self.mainMenu.addAction(self.exitAct)

        self.createToolbars()

        # create StatusBar
        self.statusbar = QtGui.QStatusBar()

        self.statusbar.addPermanentWidget(self.buildStatusWidget)

        #*** Position
        self.cursorPositionButton = QtGui.QToolButton()
        self.cursorPositionButton.setAutoRaise(True)
        self.cursorPositionButton.clicked.connect(
            self.editorTabWidget.goToCursorPosition)
        self.statusbar.addPermanentWidget(self.cursorPositionButton)
        #*** lines
        self.linesLabel = QtGui.QLabel("Lines: 0")
        self.linesLabel.setMinimumWidth(50)
        self.statusbar.addPermanentWidget(self.linesLabel)
        #*** encoding
        self.encodingLabel = QtGui.QLabel("Coding: utf-8")
        self.statusbar.addPermanentWidget(self.encodingLabel)
        #*** uptime
        self.uptimeLabel = QtGui.QLabel()
        self.uptimeLabel.setText("Uptime: 0min")
        self.statusbar.addPermanentWidget(self.uptimeLabel)

        self.runWidget = RunWidget(
            self.bottomStackSwitcher, self.projectData[
                "settings"], self.useData,
            self.editorTabWidget, self.vSplitter,
            self.runProjectAct, self.stopRunAct, self.runFileAct)
        self.addBottomWidget(self.runWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "graphic-design")),  "Output")

        self.assistantWidget = Assistant(
            self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(self.assistantWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "flag")), "Alerts")

        bookmarkWidget = BookmarkWidget(
            self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(bookmarkWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "tag")), "Bookmarks")

        tasksWidget = Tasks(self.editorTabWidget, self.bottomStackSwitcher)
        self.addBottomWidget(tasksWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "issue")), "Tasks")

        self.addBottomWidget(self.messagesWidget,
                             QtGui.QIcon(os.path.join("Resources", "images", "speech_bubble")), "Messages")

        self.profiler = Profiler(self.useData, self.bottomStackSwitcher)
        self.addBottomWidget(self.profiler,
                             QtGui.QIcon(os.path.join("Resources", "images", "settings")), "Profiler")
        self.runWidget.loadProfile.connect(
            self.profiler.viewProfile)

        self.addBottomWidget(self.findInFiles,
                             QtGui.QIcon(os.path.join("Resources", "images", "attibutes")), "Find-in-Files")

        self.bottomStackSwitcher.setDefault()

        hbox = QtGui.QHBoxLayout()
        hbox.setMargin(0)
        hbox.setSpacing(0)
        hbox.addWidget(self.bottomStackSwitcher)
        hbox.addStretch(1)
        hbox.addWidget(self.statusbar)
        mainLayout.addLayout(hbox)

        self.uptime = 0
        self.uptimeTimer = QtCore.QTimer()
        self.uptimeTimer.setInterval(60000)
        self.uptimeTimer.timeout.connect(self.updateUptime)
        self.uptimeTimer.start()

        # remember layout
        if projectPathDict['root'] in self.useData.OPENED_PROJECTS:
            settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
            settings.beginGroup(projectPathDict['root'])
            self.hSplitter.restoreState(settings.value('hsplitter'))
            self.vSplitter.restoreState(settings.value('vsplitter'))
            self.sideSplitter.restoreState(
                settings.value('sidesplitter'))
            self.vSplitter.updateStatus()
            self.writePad.setGeometry(settings.value('writepad'))
            settings.endGroup()

        self.setKeymap()

    def resizeView(self, hview, vview):
        hSizes = self.hSplitter.sizes()
        vSizes = self.vSplitter.sizes()
        if hview == 1:
            self.hSplitter.setSizes([hSizes[0] + 2, hSizes[1] - 2])
        elif hview == -1:
            self.hSplitter.setSizes([hSizes[0] - 2, hSizes[1] + 2])

        if vview == 1:
            self.vSplitter.setSizes([vSizes[0] + 2, vSizes[1] - 2])
        elif vview == -1:
            self.vSplitter.setSizes([vSizes[0] - 2, vSizes[1] + 2])

    def createActions(self):
        self.gotoLineAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "mail_check")),
                "Goto Line", self,
                statusTip="Goto Line", triggered=self.showGotoLineWidget)

        self.viewSwitcherAct = QtGui.QAction(
            "Switch Views", self, statusTip="Switch Views",
            triggered=self.showSnapShotSwitcher)

        self.exitAct = \
            QtGui.QAction("Exit", self, statusTip="Exit",
                          triggered=self.projects.closeProgram)

        # Menubar Actions ----------------------------------------------------

        self.userGuideAct = QtGui.QAction(
            "User Guide", self, statusTip="User Guide",
                                         triggered=self.launchHelp)

        self.pythonManualsAct = QtGui.QAction("Python Manuals", self,
                                              statusTip="Python Manuals",
                                              triggered=self.launchPythonHelp)

        self.checkUpdatesAct = QtGui.QAction("Check For Updates", self,
                                             statusTip="Check For Updates",
                                             triggered=self.visitHomepage)

        #----------------------------------------------------------------------
        self.runFileAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "rerun")),
            "Run File", self,
            statusTip="Run current file", triggered=self.runFile)

        self.runProjectAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "run")),
            "Run Project", self,
            statusTip="Run Project", triggered=self.runProject)

        self.stopRunAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "stop")),
            "Stop", self,
            statusTip="Stop execution",
            triggered=self.stopProcess)

        self.runParamAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "shell")),
            "Set Run Parameters", self,
            statusTip="Set Run Parameters",
            triggered=self.setRunParameters)

        #---------------------------------------------------------------------

        self.finderAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "scope")),
            "Find", self,
            statusTip="Find", triggered=self.showFinderWidget)

        self.replaceAct = \
            QtGui.QAction(
                QtGui.QIcon(
                    os.path.join("Resources", "images", "edit-replace")),
                "Replace", self,
                statusTip="Replace",
                          triggered=self.showReplaceWidget)

        self.findInFilesAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "find_in_files")),
            "Find-in-Files", self,
            statusTip="Find-in-Files", triggered=self.showFindInFilesWidget)

        self.addToLibraryAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "add")),
                "Add To Library", self,
                statusTip="Add current module to Library",
                          triggered=self.addToLibrary)

        self.clearRecentFilesAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "clear")),
                "Clear History", self, statusTip="Clear History",
                triggered=self.clearRecentFiles)

        self.writePadAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "pencil")),
                "Writepad", self, statusTip="Writepad",
                triggered=self.showWritePad)

        self.buildAct = \
            QtGui.QAction(
                "Build", self,
                statusTip="Build",
                triggered=self.buildProject)

        self.openBuildAct = \
            QtGui.QAction(
                "Open Build", self, statusTip="Open Build",
                triggered=self.openBuild)

        self.configureAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "settings")),
                "Configuration", self, statusTip="Configuration",
                triggered=self.showProjectConfiguration)

        self.exportProjectAct = \
            QtGui.QAction(
                QtGui.QIcon(os.path.join("Resources", "images", "archive")),
                "Export as Zip...", self, statusTip="Export as Zip",
                triggered=self.exportProject)

        self.closeProjectAct = \
            QtGui.QAction(
                QtGui.QIcon(
                    os.path.join("Resources", "images", "inbox--minus")),
                "Close Project", self, statusTip="Close Project",
                triggered=self.closeProject)

    def visitHomepage(self):
        QtGui.QDesktopServices().openUrl(QtCore.QUrl(
            """https://github.com/fortharris/Pcode"""))

    def showProjectConfiguration(self):
        self.editorTabWidget.showProjectConfiguration()

    def buildProject(self):
        self.projectManager.buildProject()

    def openBuild(self):
        self.projectManager.openBuild()

    def exportProject(self):
        self.projectManager.exportProject()

    def closeProject(self):
        self.projects.closeProject()

    def updateEncodingLabel(self, text):
        self.encodingLabel.setText(text)

    def showGotoLineWidget(self):
        self.editorTabWidget.showGotoLineWidget()

    def showSnapShotSwitcher(self):
        self.editorTabWidget.showSnapShotSwitcher()

    def addBottomWidget(self, widget, icon, name):
        self.bottomStack.addWidget(widget)
        self.bottomStackSwitcher.addButton(toolTip=name, icon=icon)

    def showWritePad(self):
        self.writePad.show()

    def showFinderWidget(self):
        self.findInFiles.dashboard.hide()
        self.searchWidget.showFinder()

    def showReplaceWidget(self):
        self.findInFiles.dashboard.hide()
        self.searchWidget.showReplaceWidget()

    def showFindInFilesWidget(self):
        self.searchWidget.hide()
        self.findInFiles.dashboard.show()

    def createToolbars(self):

        self.editorMenuButton = QtGui.QToolButton()
        self.editorMenuButton.setText("Menu")
        self.editorMenuButton.setToolButtonStyle(2)
        self.editorMenuButton.setAutoRaise(True)
        self.editorMenuButton.setPopupMode(2)
        self.editorMenuButton.setIcon(QtGui.QIcon(
            os.path.join("Resources", "images", "Dashboard")))
        self.editorMenuButton.setMenu(self.mainMenu)

        self.standardToolbar.addWidget(self.editorMenuButton)
        self.standardToolbar.addAction(self.editorTabWidget.openFileAct)
        self.standardToolbar.addAction(self.editorTabWidget.newPythonFileAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.saveAct)
        self.standardToolbar.addAction(self.editorTabWidget.saveAllAct)
        self.standardToolbar.addAction(self.editorTabWidget.undoAct)
        self.editorTabWidget.undoAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.redoAct)
        self.editorTabWidget.redoAct.setDisabled(True)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.cutAct)
        self.editorTabWidget.cutAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.copyAct)
        self.editorTabWidget.copyAct.setDisabled(True)
        self.standardToolbar.addAction(self.editorTabWidget.pasteAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.editorTabWidget.dedentAct)
        self.standardToolbar.addAction(self.editorTabWidget.indentAct)

        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.runFileAct)
        self.standardToolbar.addAction(self.runProjectAct)
        self.standardToolbar.addAction(self.stopRunAct)
        self.stopRunAct.setVisible(False)
        self.standardToolbar.addAction(self.runParamAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.finderAct)
        self.standardToolbar.addAction(self.replaceAct)
        self.standardToolbar.addAction(self.findInFilesAct)
        self.standardToolbar.addSeparator()
        self.standardToolbar.addAction(self.addToLibraryAct)
        self.standardToolbar.addAction(self.writePadAct)

        self.bookmarkToolbar.addAction(
            self.editorTabWidget.findNextBookmarkAct)
        self.bookmarkToolbar.addAction(
            self.editorTabWidget.findPrevBookmarkAct)
        self.bookmarkToolbar.addAction(self.editorTabWidget.removeBookmarksAct)
        self.standardToolbar.addWidget(self.bookmarkToolbar)

    def recentFileActivated(self, action):
        path = action.text().split('  ', 1)[1]
        if os.path.exists(path):
            self.editorTabWidget.loadfile(path)
        else:
            message = QtGui.QMessageBox.warning(self, "Open",
                                                "File is unavailable!")

    def loadRecentFiles(self):
        if len(self.projectData['recentfiles']) > 0:
            self.recentFile_actionGroup = QtGui.QActionGroup(self)
            self.recentFile_actionGroup.triggered.connect(
                self.recentFileActivated)
            self.recentFilesMenu.clear()
            c = 1
            for i in self.projectData['recentfiles']:
                action = QtGui.QAction(str(c) + '  ' + i, self)
                self.recentFile_actionGroup.addAction(action)
                self.recentFilesMenu.addAction(action)
                c += 1
            self.recentFilesMenu.addSeparator()
            self.recentFilesMenu.addAction(self.clearRecentFilesAct)
        else:
            self.recentFilesMenu.addAction("No Recent Files")

    def updateRecentFiles(self, filePath):
        if filePath in self.projectData['recentfiles']:
            self.projectData['recentfiles'].remove(filePath)
            self.projectData['recentfiles'].insert(0, filePath)
        else:
            if len(self.projectData['recentfiles']) < 15:
                self.projectData['recentfiles'].insert(0, filePath)
            else:
                del self.projectData['recentfiles'][-1]
                self.projectData['recentfiles'].insert(0, filePath)
        self.loadRecentFiles()

    def clearRecentFiles(self):
        self.projectData['recentfiles'] = []
        self.recentFilesMenu.clear()
        self.loadRecentFiles()
        self.messagesWidget.addMessage(0, 'Recent Files:',
                                       ["Recent files history has been cleared!"])

    def addToLibrary(self):
        self.library.addToLibrary(self.editorTabWidget)

    def updateUptime(self):
        self.uptime += 1
        if self.uptime == 60:
            new_time = "1hr"
        elif self.uptime > 60:
            t = int(str(self.uptime / 60).split('.')[0])
            h = str(t) + "hr"
            m = str(self.uptime - (t * 60)) + "min"
            new_time = h + m
        else:
            new_time = str(self.uptime) + "min"
        self.uptimeLabel.setText("Uptime: " + new_time)

    def saveAll(self):
        self.editorTabWidget.saveAll()

    def fileUrl(self, fname):
        """Select the right file url scheme according to the operating system"""
        if os.name == 'nt':
            # Local file
            if re.search(r'^[a-zA-Z]:', fname):
                return 'file:///' + fname
            # UNC based path
            else:
                return 'file://' + fname
        else:
            return 'file://' + fname

    def getPythonDocPath(self):
        """
        Return Python documentation path
        (Windows: return the PythonXX.chm path if available)
        """
        if os.name == 'nt':
            path = os.path.dirname(
                self.projectData['settings']["DefaultInterpreter"])
            doc_path = os.path.join(path, "Doc")
            if not os.path.isdir(doc_path):
                return
            python_chm = [path for path in os.listdir(doc_path)
                          if re.match(r"(?i)Python[0-9]{3}.chm", path)]
            if python_chm:
                return self.fileUrl(os.path.join(doc_path, python_chm[0]))
        else:
            vinf = sys.version_info
            doc_path = '/usr/share/doc/python%d.%d/html' % (vinf[0], vinf[1])
        python_doc = os.path.join(doc_path, "index.html")
        if os.path.isfile(python_doc):
            return self.fileUrl(python_doc)

    def launchHelp(self):
        message = QtGui.QMessageBox.warning(
            self, "User Guide", "Not available at the moment")

    def launchPythonHelp(self):
        try:
            doc_path = self.getPythonDocPath()
            os.startfile(doc_path)
        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            logging.error(repr(traceback.format_exception(exc_type, exc_value,
                         exc_traceback)))
            message = QtGui.QMessageBox.critical(self, "Python Manuals",
                                                 ("Failed to launch the Python Manuals!\n\n"
                                                  "It is either not available for the current python "
                                                  "version or Python is not installed in your system."))

    def setRunParameters(self):
        self.editorTabWidget.showSetRunParameters()

    def runFile(self):
        self.runWidget.runFile()

    def runProject(self):
        self.runWidget.runProject()

    def stopProcess(self):
        self.runWidget.stopProcess()

    def showPythonInterpreter(self):
        process = QtCore.QProcess()
        process.startDetached(self.useData.SETTINGS["DefaultInterpreter"])

    def showCommandPrompt(self):
        prompt = os.environ["COMSPEC"]
        process = QtCore.QProcess()
        process.startDetached(prompt, [], QtCore.QDir().rootPath())

    def showCursorPosition(self):
        line, index = self.editorTabWidget.currentEditor.getCursorPosition()
        self.cursorPositionButton.setText(
            "Line {0} : Column {1}".format(line + 1, index + 1))

    def updateLineCount(self, lines):
        self.linesLabel.setText("Lines: " + str(lines))

    def saveUiState(self):
        name = self.projectPathDict["root"]
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup(name)
        settings.setValue('hsplitter', self.hSplitter.saveState())
        settings.setValue('vsplitter', self.vSplitter.saveState())
        settings.setValue('sidesplitter', self.sideSplitter.saveState())
        settings.setValue('writepad', self.writePad.geometry())
        settings.endGroup()

    def restoreSession(self):
        self.editorTabWidget.restoreSession()

    def closeWindow(self):
        if self.runWidget.currentProcess is not None:
            mess = "Close running program?"
            reply = QtGui.QMessageBox.warning(self, "Close",
                                              mess, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
            if reply == QtGui.QMessageBox.Yes:
                self.runWidget.stopProcess()
            else:
                return False
        modified = []
        for i in range(self.editorTabWidget.count()):
            if self.editorTabWidget.getEditor(i).isModified():
                modified.append(i)
        if len(modified) == 0:
            pass
        else:
            for i in range(len(modified)):
                v = modified.pop(-1)
                self.editorTabWidget.setCurrentIndex(v)
                mess = 'Save changes to "{0}"?'.format(
                    self.editorTabWidget.tabText(v))
                reply = QtGui.QMessageBox.warning(self, "Close", mess,
                                                  QtGui.QMessageBox.Yes | QtGui.QMessageBox.No |
                                                  QtGui.QMessageBox.Cancel)
                if reply == QtGui.QMessageBox.No:
                    if len(modified) == 0:
                        pass
                elif reply == QtGui.QMessageBox.Yes:
                    saved = self.editorTabWidget.save()
                    if saved:
                        pass
                    else:
                        return False
                elif reply == QtGui.QMessageBox.Cancel:
                    return False
        self.saveUiState()
        self.editorTabWidget.saveSession()
        self.projectData["settings"]["Closed"] = "True"
        self.saveProjectData()
        self.editorTabWidget.refactor.closeRope()

        return True

    def loadProjectData(self):
        dom_document = QtXml.QDomDocument()
        file = open(os.path.join(self.projectPathDict[
                    "root"], "Data", "projectdata.xml"), "r")
        x = dom_document.setContent(file.read())
        file.close()

        elements = dom_document.documentElement()
        node = elements.firstChild()

        shortcuts = []
        recentfiles = []
        favourites = []
        launchers = {}

        settingsList = []
        while node.isNull() is False:
            property = node.toElement()
            sub_node = property.firstChild()
            while sub_node.isNull() is False:
                sub_prop = sub_node.toElement()
                if node.nodeName() == "shortcuts":
                    shortcuts.append(sub_prop.text())
                elif node.nodeName() == "recentfiles":
                    if os.path.exists(sub_prop.text()):
                        recentfiles.append(sub_prop.text())
                    else:
                        pass
                elif node.nodeName() == "favourites":
                    favourites.append(sub_prop.text())
                elif node.nodeName() == "settings":
                    settingsList.append((tuple(sub_prop.text().split('=', 1))))
                elif node.nodeName() == "launchers":
                    tag = sub_prop.toElement()
                    path = tag.attribute("path")
                    param = tag.attribute("param")
                    launchers[path] = param
                sub_node = sub_node.nextSibling()
            node = node.nextSibling()
        settingsDict = dict(settingsList)

        settingsDict['LastCloseSuccessful'] = settingsDict['Closed']
        settingsDict['Closed'] = "False"

        self.projectData = {}
        self.projectData["shortcuts"] = shortcuts
        self.projectData["favourites"] = favourites
        self.projectData["recentfiles"] = recentfiles
        self.projectData["settings"] = settingsDict
        self.projectData["launchers"] = launchers

        # in order that a crash can be reported
        self.saveProjectData()

    def saveProjectData(self):
        domDocument = QtXml.QDomDocument("projectdata")

        projectdata = domDocument.createElement("projectdata")
        domDocument.appendChild(projectdata)

        root = domDocument.createElement("shortcuts")
        projectdata.appendChild(root)

        for i in self.projectData['shortcuts']:
            tag = domDocument.createElement("shortcut")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("recentfiles")
        projectdata.appendChild(root)

        for i in self.projectData['recentfiles']:
            tag = domDocument.createElement("recent")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("favourites")
        projectdata.appendChild(root)

        for i in self.projectData['favourites']:
            tag = domDocument.createElement("fav")
            root.appendChild(tag)

            t = domDocument.createTextNode(i)
            tag.appendChild(t)

        root = domDocument.createElement("launchers")
        projectdata.appendChild(root)

        for path, param in self.projectData['launchers'].items():
            tag = domDocument.createElement("item")
            tag.setAttribute("path", path)
            tag.setAttribute("param", param)
            root.appendChild(tag)

        root = domDocument.createElement("settings")
        projectdata.appendChild(root)

        s = 0
        for key, value in self.projectData['settings'].items():
            tag = domDocument.createElement("key")
            root.appendChild(tag)

            t = domDocument.createTextNode(key + '=' + value)
            tag.appendChild(t)
            s += 1

        path = os.path.join(
            self.projectPathDict["root"], "Data", "projectdata.xml")
        file = open(path, "w")
        file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
        file.write(domDocument.toString())
        file.close()

    def setKeymap(self):
        shortcuts = self.useData.CUSTOM_SHORTCUTS

        self.shortGotoLine = QtGui.QShortcut(
            shortcuts["Ide"]["Go-to-Line"], self)
        self.shortGotoLine.activatedAmbiguously.connect(
            self.showGotoLineWidget)
        self.gotoLineAct.setShortcut(shortcuts["Ide"]["Go-to-Line"])

        self.shortBuild = QtGui.QShortcut(shortcuts["Ide"]["Build"], self)
        self.shortBuild.activatedAmbiguously.connect(self.buildProject)
        self.buildAct.setShortcut(shortcuts["Ide"]["Build"])

        self.shortFind = QtGui.QShortcut(shortcuts["Ide"]["Find"], self)
        self.shortFind.activated.connect(self.showFinderWidget)

        self.shortReplace = QtGui.QShortcut(
            shortcuts["Ide"]["Replace"], self)
        self.shortReplace.activated.connect(self.showReplaceWidget)

        self.shortRunFile = QtGui.QShortcut(
            shortcuts["Ide"]["Run-File"], self)
        self.shortRunFile.activated.connect(self.runFile)

        self.shortRunProject = QtGui.QShortcut(
            shortcuts["Ide"]["Run-Project"], self)
        self.shortRunProject.activated.connect(self.runProject)

        self.shortStopRun = QtGui.QShortcut(
            shortcuts["Ide"]["Stop-Execution"], self)
        self.shortStopRun.activated.connect(self.stopProcess)

        self.shortPythonManuals = QtGui.QShortcut(
            shortcuts["Ide"]["Python-Manuals"], self)
        self.shortPythonManuals.activatedAmbiguously.connect(
            self.launchPythonHelp)
        self.pythonManualsAct.setShortcut(
            shortcuts["Ide"]["Python-Manuals"])
Esempio n. 4
0
File: Pcode.py Progetto: ntoll/Pcode
class Pcode(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowIcon(QtGui.QIcon(os.path.join("Resources", "images", "Icon")))
        self.setWindowTitle("Pcode - Loading...")

        screen = QtGui.QDesktopWidget().screenGeometry()
        self.resize(screen.width() - 200, screen.height() - 200)
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2, (
            screen.height() - size.height()) / 2)
        self.lastWindowGeometry = self.geometry()

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.setSpacing(0)
        mainLayout.setMargin(0)
        self.setLayout(mainLayout)

        self.useData = UseData()

        logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s',
                            filename=self.useData.appPathDict["logfile"], level=logging.DEBUG)
        if sys.version_info.major < 3:
            logging.error("This application requires Python 3")
            sys.exit(1)

        self.library = Library(self.useData)
        self.busyWidget = BusyWidget(app, self.useData, self)

        if self.useData.SETTINGS["UI"] == "Custom":
            app.setStyleSheet(StyleSheet.globalStyle)

        self.projectWindowStack = QtGui.QStackedWidget()

        self.projectTitleBox = QtGui.QComboBox()
        self.projectTitleBox.setMinimumWidth(180)
        self.projectTitleBox.setStyleSheet(StyleSheet.projectTitleBoxStyle)
        self.projectTitleBox.setItemDelegate(QtGui.QStyledItemDelegate())
        self.projectTitleBox.currentIndexChanged.connect(self.projectChanged)
        self.projectTitleBox.activated.connect(self.projectChanged)

        self.settingsWidget = SettingsWidget(self.useData, app,
                                             self.projectWindowStack, self.library.codeViewer, self)
        self.settingsWidget.colorScheme.styleEditor(self.library.codeViewer)

        startWindow = Start(self.useData, self)
        self.addProject(startWindow, "Start",
                        "Start", os.path.join("Resources", "images", "flag-green"))

        self.projects = Projects(self.useData, self.busyWidget,
                                 self.library, self.settingsWidget, app,
                                 self.projectWindowStack, self.projectTitleBox, self)

        self.createActions()

        hbox = QtGui.QHBoxLayout()
        hbox.setContentsMargins(5, 3, 5, 3)
        mainLayout.addLayout(hbox)

        hbox.addStretch(1)

        self.pagesStack = QtGui.QStackedWidget()
        mainLayout.addWidget(self.pagesStack)

        self.projectSwitcher = StackSwitcher(self.pagesStack)
        self.projectSwitcher.setStyleSheet(StyleSheet.mainMenuStyle)
        hbox.addWidget(self.projectSwitcher)

        self.pagesStack.addWidget(self.projectWindowStack)
#        self.addPage(self.projectWindowStack, "EDITOR", QtGui.QIcon(
#            os.path.join("Resources", "images", "hire-me")))
#
#        self.addPage(self.library, "LIBRARY", QtGui.QIcon(
#            os.path.join("Resources", "images", "library")))
#        self.projectSwitcher.setDefault()

        hbox.addWidget(self.projectTitleBox)
        hbox.setSpacing(5)

        self.settingsButton = QtGui.QToolButton()
        self.settingsButton.setAutoRaise(True)
        self.settingsButton.setDefaultAction(self.settingsAct)
        hbox.addWidget(self.settingsButton)

        self.fullScreenButton = QtGui.QToolButton()
        self.fullScreenButton.setAutoRaise(True)
        self.fullScreenButton.setDefaultAction(self.showFullScreenAct)
        hbox.addWidget(self.fullScreenButton)

        self.aboutButton = QtGui.QToolButton()
        self.aboutButton.setAutoRaise(True)
        self.aboutButton.setDefaultAction(self.aboutAct)
        hbox.addWidget(self.aboutButton)

        self.setShortcuts()

        if self.useData.settings["firstRun"] == 'True':
            self.showMaximized()
        else:
            self.restoreUiState()

        self.useData.settings["running"] = 'True'
        self.useData.settings["firstRun"] = 'False'
        self.useData.saveSettings()

    def createActions(self):
        self.aboutAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "properties")),
            "About Pcode", self, statusTip="About Pcode",
            triggered=self.showAbout)

        self.showFullScreenAct = \
            QtGui.QAction(QtGui.QIcon(os.path.join("Resources", "images", "fullscreen")),
                          "Fullscreen", self,
                          statusTip="Fullscreen",
                          triggered=self.showFullScreenMode)

        self.settingsAct = QtGui.QAction(
            QtGui.QIcon(os.path.join("Resources", "images", "config")),
            "Settings", self,
            statusTip="Settings", triggered=self.showSettings)

    def addPage(self, pageWidget, name, iconPath):
        self.projectSwitcher.addButton(name=name, icon=iconPath)
        self.pagesStack.addWidget(pageWidget)

    def loadProject(self, path, show=False, new=False):
        self.projects.loadProject(path, show, new)

    def newProject(self):
        self.projects.newProjectDialog.exec_()

    def showProject(self, path):
        if not os.path.exists(path):
            message = QtGui.QMessageBox.warning(
                self, "Open Project", "Project cannot be be found!")
        else:
            if path in self.useData.OPENED_PROJECTS:
                for i in range(self.projectWindowStack.count() - 1):
                    window = self.projectWindowStack.widget(i)
                    p_path = window.projectPathDict["root"]
                    if os.path.samefile(path, p_path):
                        self.projectTitleBox.setCurrentIndex(i)
                        return True
        return False

    def addProject(self, window, name, type='Project', iconPath=None):
        self.projectWindowStack.insertWidget(0, window)
        if type == 'Project':
            self.projectTitleBox.insertItem(0, QtGui.QIcon(
                os.path.join("Resources", "images", "project")), name, [window, type])
        else:
            self.projectTitleBox.insertItem(0, QtGui.QIcon(
                iconPath), name, [window, type])

    def projectChanged(self, index):
        data = self.projectTitleBox.itemData(index)
        window = data[0]
        windowType = data[1]
        if windowType == "Start":
            self.setWindowTitle("Pcode - Start")
        elif windowType == "Project":
            title = window.editorTabWidget.getEditorData("filePath")
            self.updateWindowTitle(title)
        self.projectWindowStack.setCurrentWidget(window)

    def removeProject(self, window):
        for index in range(self.projectTitleBox.count() - 1):
            data = self.projectTitleBox.itemData(index)
            windowWidget = data[0]
            if windowWidget == window:
                self.projectWindowStack.removeWidget(window)
                self.projectTitleBox.removeItem(index)

    def updateWindowTitle(self, title):
        if title is None:
            title = "Pcode - " + "Unsaved"
        else:
            window = self.projectTitleBox.itemData(
                self.projectTitleBox.currentIndex())[0]
            if title.startswith(window.projectPathDict["sourcedir"]):
                src_dir = window.projectPathDict["sourcedir"]
                n = title.partition(src_dir)[-1]
                title = 'Pcode - ' + n
            else:
                title = "Pcode - " + title
        self.setWindowTitle(title)

    def showAbout(self):
        aboutPane = About(self)
        aboutPane.exec_()

    def showSettings(self):
        self.settingsWidget.show()

    def showFullScreenMode(self):
        if self.isFullScreen():
            self.showNormal()
            self.setGeometry(self.lastWindowGeometry)
        else:
            # get current size ahd show Fullscreen
            # so we can later restore to proper position
            self.lastWindowGeometry = self.geometry()
            self.showFullScreen()

    def saveUiState(self):
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup("MainWindow")
        settings.setValue("geometry", self.geometry())
        settings.setValue("lsplitter", self.library.mainSplitter.saveState())
        settings.setValue("snippetsMainsplitter",
                          self.settingsWidget.snippetEditor.mainSplitter.saveState())
        settings.setValue("windowMaximized", self.isMaximized())
        settings.endGroup()

    def restoreUiState(self):
        settings = QtCore.QSettings("Clean Code Inc.", "Pcode")
        settings.beginGroup("MainWindow")
        if settings.value("windowMaximized", True, type=bool):
            self.showMaximized()
        else:
            self.setGeometry(settings.value("geometry"))
            self.show()
        self.library.mainSplitter.restoreState(settings.value("lsplitter"))
        self.settingsWidget.snippetEditor.mainSplitter.restoreState(
            settings.value("snippetsMainsplitter"))
        settings.endGroup()

    def closeEvent(self, event):
        for i in range(self.projectWindowStack.count() - 1):
            window = self.projectWindowStack.widget(i)
            closed = window.closeWindow()
            if not closed:
                self.projectTitleBox.setCurrentIndex(i)
                event.ignore()
                return
            else:
                pass
        self.saveUiState()
        self.useData.saveUseData()
        app.closeAllWindows()

        event.accept()

    def setShortcuts(self):
        shortcuts = self.useData.CUSTOM_SHORTCUTS

        self.shortFullscreen = QtGui.QShortcut(
            shortcuts["Ide"]["Fullscreen"], self)
        self.shortFullscreen.activated.connect(self.showFullScreenMode)