def __init__(self): ''' Constructor ''' super(AppMainWindow, self).__init__() print "STM32 GCC-ARM IDE started..." print SPLASH_NOTICE if False: # todo: set to True if building stand-alone package (cx_Freeze) setpath = os.path.dirname(os.path.realpath(__file__)) if os.name == 'nt': os.chdir(setpath[:setpath.rfind('\\')]) else: os.chdir(setpath[:setpath.rfind('/')]) self.aboutDlg = AboutDialog(self) self.aboutDlg.show() self.setWindowTitle("STM32 GCC-ARM IDE") self.setWindowIcon(QtGui.QIcon('images/app.png')) self.setMinimumSize(300, 400) self.Editor = MultipleCppEditor(self) self.setCentralWidget(self.Editor) self.OutLineView = self.Editor.getOutLineView() self.OutLineView.setObjectName("OutLineView") self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.OutLineView) self.Compiler = GccCompilerThread(self) self.pollCompilerTimerID = None self.serialPortName = None self.serialPortLabel = QtGui.QLabel( '<font color=red><i>(select port)</i></font>') self.SerialPortMonitorDialog = SerialPortMonitor(self) self.flashLoader = FlashLoaderThread(self) self.pollLoaderTimerID = None self.Configs = IdeConfig(self) self.createLogWindow() self.createActions() self.createToolBars() self.createStatusBar() self.Configs.restoreIdeSettings() self.createMenus() self.aboutDlg.finish(self) print "IDE ready."
def __init__(self): ''' Constructor ''' super(AppMainWindow, self).__init__() print "LM4F GCC-ARM IDE started..." print SPLASH_NOTICE if False: # todo: set to True if building stand-alone package (cx_Freeze) setpath = os.path.dirname( os.path.realpath( __file__ ) ) if os.name == 'nt': os.chdir( setpath[:setpath.rfind('\\')] ) else: os.chdir( setpath[:setpath.rfind('/')] ) self.aboutDlg = AboutDialog(self) self.aboutDlg.show() self.setWindowTitle("LM4F GCC-ARM IDE") self.setWindowIcon(QtGui.QIcon('images/app.png')) self.setMinimumSize(300, 400) self.Editor = MultipleCppEditor(self) self.setCentralWidget(self.Editor) self.OutLineView = self.Editor.getOutLineView() self.OutLineView.setObjectName("OutLineView") self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.OutLineView) self.Compiler = GccCompilerThread(self) self.pollCompilerTimerID = None self.serialPortName = None self.serialPortLabel = QtGui.QLabel('<font color=red><i>(select port)</i></font>') self.SerialPortMonitorDialog = SerialPortMonitor(self) self.flashLoader = LM4FlashThread(self) self.pollLoaderTimerID = None self.Configs = IdeConfig(self) self.createLogWindow() self.createActions() self.createToolBars() self.createStatusBar() self.Configs.restoreIdeSettings() self.createMenus() self.aboutDlg.finish(self) print "IDE ready."
def __init__(self): ''' Constructor ''' super(AppMainWindow, self).__init__() print "PhilRoboKit IDE started..." print SPLASH_NOTICE if False: # todo: set to True if building stand-alone package (cx_Freeze) setpath = os.path.dirname( os.path.realpath( __file__ ) ) if os.name == 'nt': os.chdir( setpath[:setpath.rfind('\\')] ) else: os.chdir( setpath[:setpath.rfind('/')] ) self.aboutDlg = AboutDialog(self) self.aboutDlg.show() self.setWindowTitle("PhilRobokit IDE") self.setWindowIcon(QtGui.QIcon('images/app.png')) self.setMinimumSize(300, 400) self.Configs = IdeConfig(self) self.Editor = MultipleCppEditor(self) self.setCentralWidget(self.Editor) self.Compiler = PicCompilerThread(self) self.pollCompilerTimerID = None self.boardName = '' self.serialPortName = '' self.serialPortLabel = QtGui.QLabel('<font color=red><i>(select port)</i></font>') self.SerialPortMonitorDialog = SerialPortMonitor(self) self.PK2Programmer = PICkit2ProgrammerThread(self) self.pollPK2TimerID = None self.tinyBootloader = TinyPICBootloaderThread(self) self.pollTblTimerID = None self.createLogWindow() self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.aboutDlg.finish(self) print "IDE ready."
class AppMainWindow(QtGui.QMainWindow): ''' classdocs ''' def __init__(self): ''' Constructor ''' super(AppMainWindow, self).__init__() print "LM4F GCC-ARM IDE started..." print SPLASH_NOTICE if False: # todo: set to True if building stand-alone package (cx_Freeze) setpath = os.path.dirname( os.path.realpath( __file__ ) ) if os.name == 'nt': os.chdir( setpath[:setpath.rfind('\\')] ) else: os.chdir( setpath[:setpath.rfind('/')] ) self.aboutDlg = AboutDialog(self) self.aboutDlg.show() self.setWindowTitle("LM4F GCC-ARM IDE") self.setWindowIcon(QtGui.QIcon('images/app.png')) self.setMinimumSize(300, 400) self.Editor = MultipleCppEditor(self) self.setCentralWidget(self.Editor) self.OutLineView = self.Editor.getOutLineView() self.OutLineView.setObjectName("OutLineView") self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.OutLineView) self.Compiler = GccCompilerThread(self) self.pollCompilerTimerID = None self.serialPortName = None self.serialPortLabel = QtGui.QLabel('<font color=red><i>(select port)</i></font>') self.SerialPortMonitorDialog = SerialPortMonitor(self) self.flashLoader = LM4FlashThread(self) self.pollLoaderTimerID = None self.Configs = IdeConfig(self) self.createLogWindow() self.createActions() self.createToolBars() self.createStatusBar() self.Configs.restoreIdeSettings() self.createMenus() self.aboutDlg.finish(self) print "IDE ready." def about(self): self.aboutDlg.show() kdbMod = QtGui.QApplication.keyboardModifiers() if kdbMod == QtCore.Qt.ShiftModifier: self.aboutDlg.showMessage('[developer mode] update firmware library...', QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtGui.QColor("#eecc77")) self.aboutDlg.showUpdateDialog() return # todo: other informations self.aboutDlg.showMessage("LM4F GCC-ARM IDE [ %s ]" % self.aboutDlg.getVersions(), QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtGui.QColor("#eecc77")); def openProjectProtoSite(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl("http://projectproto.blogspot.com") ) def openPhilRoboticsSite(self): # todo: change to .ORG QtGui.QDesktopServices.openUrl( QtCore.QUrl("http://www.philrobotics.com") ) def aboutCompiler(self): info = self.Compiler.getCompilerInfo() #self.log.append(info) if info: QtGui.QMessageBox.about( self, "Compiler Information", info ) else: QtGui.QMessageBox.about( self, "Compiler Information", "no compiler found!" ) def startBuild(self): if self.Compiler.isRunning(): self.insertLog('compiler busy..') return kdbMod = QtGui.QApplication.keyboardModifiers() ret = self.Editor.saveFile() # save the file first before starting the build. if ret == False: self.insertLog("<font color=red>unable to save project!</font>") return elif ret == None: self.insertLog("nothing to build.") return self.insertLog("<font color=green>------- Start Project Build. -------</font>", True) fn = self.Editor.getCurrentFile() cleanBuild = False if kdbMod == QtCore.Qt.ShiftModifier: #print 'Shift-Click PushButton' cleanBuild = True ret, msg = self.Compiler.buildProject(fn, cleanBuild) if not ret: self.insertLog( "<font color=red>%s</font>"%msg ) if msg == "file not found": QtGui.QMessageBox.warning( self, "Build Error", "File not found (may be unsaved yet). " + \ "Create or save first the file." ) elif msg == "busy": QtGui.QMessageBox.warning( self, "Busy", "Previous build process still running!" ) elif msg == "abort": QtGui.QMessageBox.warning( self, "Error", "Unable to start build process!" ) else: self.insertLog( "<font color=lightblue><i> %s </i></font>"%msg ) self.pollCompilerTimerID = self.startTimer(50) if not self.pollCompilerTimerID: self.insertLog("<font color=red>Unable to start Timer.</font>") def stopBuild(self): if self.pollCompilerTimerID: self.killTimer(self.pollCompilerTimerID) self.pollCompilerTimerID = None self.Compiler.pollBuildProcess(True) self.insertLog("<font color=red>----- Stopped. -----</font>") else: self.insertLog("nothing to stop.") def programChip(self): if self.Editor.isCurrentFileModified(): self.insertLog('<font color=orange>Project was modified. Please re-build the project.</font>') return if self.Compiler.isRunning(): self.insertLog('compiler busy... please wait...') return if self.flashLoader.isRunning(): self.insertLog('serial bootloader busy.') return binfile = self.Compiler.getExpectedBinFileName( self.Editor.getCurrentFile() ) ret, msg = self.flashLoader.programDevice( binfile ) if ret: self.insertLog("<font color=green>Bootload/Program Device:</font>", True) self.insertLog("<font color=lightblue><i> %s </i></font>"%msg) self.pollLoaderTimerID = self.startTimer(0.5) # relatively fast! if not self.pollLoaderTimerID: self.insertLog("<font color=red>Unable to start Timer.</font>") else: self.insertLog("<font color=red>%s</font>"%msg) def selectSerialPort(self): act = self.serialPortGroup.checkedAction() if act: portname = str( act.text() ) if portname != self.serialPortName: self.serialPortName = portname self.Configs.saveIdeSettings( self.serialPortName ) self.insertLog( 'selected port: <b><font color=green>%s</font></b>' % self.serialPortName ) self.serialPortLabel.setText('<font color=green>%s</font>'%self.serialPortName) if self.SerialPortMonitorDialog.isPortOpen(): if not self.SerialPortMonitorDialog.openPort(self.serialPortName): self.SerialPortMonitorDialog.close() self.insertLog( "<font color=red>unable to open %s</font>"%self.serialPortName) def updateSerialPortList(self): # clear previous actions list self.serialPortMenu.clear() for act in self.serialPortGroup.actions(): self.serialPortGroup.removeAction(act) del act # scan existing ports portList = scan_serialports() # serialport.py previousPortName = self.Configs.getSerialPortName() # create new actions & update serial port menu if len(portList): for i in range(len(portList)): act = QtGui.QAction(portList[i], self, checkable=True, statusTip="select " + portList[i] + " serial port", triggered=self.selectSerialPort) self.serialPortGroup.addAction( act ) self.serialPortMenu.addAction( act ) if portList[i] == previousPortName: act.setChecked(True) act.trigger() if not self.serialPortGroup.checkedAction(): self.serialPortName = '' #self.insertLog( '<i><font color=gray>( please select a serial port. )</font></i>' ) def importFirmwareLib(self, action=None): if action: libname = str( action.text() ) self.Editor.importFirmwareLib(libname) def openSerialPortMonitorDialog(self): if self.serialPortName == None: self.insertLog( "<font color=red>no serial port selected!</font>" ) return if self.SerialPortMonitorDialog.openPort(self.serialPortName): self.SerialPortMonitorDialog.show() # non-modal open else: self.insertLog( "<font color=red>unable to open serial port!</font>" ) def createActions(self): # file menu self.newAct = QtGui.QAction( QtGui.QIcon("./images/new.png"), "&New", self, shortcut=QtGui.QKeySequence("Ctrl+N"), statusTip="Create a new file", triggered=self.Editor.newFile) self.openAct = QtGui.QAction(QtGui.QIcon("./images/open.png"), "&Open...", self, shortcut=QtGui.QKeySequence("Ctrl+O"), statusTip="Open an existing file") self.openAct.triggered.connect( functools.partial(self.Editor.openFile, None) ) self.closeAct = QtGui.QAction("&Close", self, shortcut=QtGui.QKeySequence("Ctrl+W"), statusTip="Close the current window", triggered=self.Editor.closeCurrentFile) self.saveAct = QtGui.QAction(QtGui.QIcon("./images/save.png"), "&Save", self, shortcut=QtGui.QKeySequence("Ctrl+S"), statusTip="Save the current file", triggered=self.Editor.saveFile) self.saveAsAct = QtGui.QAction("Save &As...", self, shortcut=QtGui.QKeySequence("Ctrl+Shift+S"), statusTip="Save to another file", triggered=self.Editor.saveFileAs) self.exitAct = QtGui.QAction("E&xit", self, shortcut=QtGui.QKeySequence("Alt+F4"), statusTip="Exit the application", triggered=QtGui.qApp.closeAllWindows) # edit menu self.editUndoAct = QtGui.QAction("&Undo", self, shortcut=QtGui.QKeySequence("Ctrl+Z"), triggered=self.Editor.editUndo) self.editRedoAct = QtGui.QAction("&Redo", self, shortcut=QtGui.QKeySequence("Ctrl+Y"), triggered=self.Editor.editRedo) self.editCutAct = QtGui.QAction("Cu&t", self, shortcut=QtGui.QKeySequence("Ctrl+X"), triggered=self.Editor.editCut) self.editCopyAct = QtGui.QAction("&Copy", self, shortcut=QtGui.QKeySequence("Ctrl+C"), triggered=self.Editor.editCopy) self.editPasteAct = QtGui.QAction("&Paste", self, shortcut=QtGui.QKeySequence("Ctrl+V"), triggered=self.Editor.editPaste) self.editSelectAllAct = QtGui.QAction("Select &All", self, shortcut=QtGui.QKeySequence("Ctrl+A"), triggered=self.Editor.editSelectAll) self.editClearAct = QtGui.QAction("Clear", self, triggered=self.Editor.editClear) # find/replace self.findAct = QtGui.QAction("&Find/Replace...", self, shortcut=QtGui.QKeySequence("Ctrl+F"), statusTip="Find/Replace texts", triggered=self.Editor.showFindDialog) # project menu self.compileAct = QtGui.QAction(QtGui.QIcon("./images/build.png"), "&Compile", self, shortcut=QtGui.QKeySequence("Ctrl+B"), statusTip="Build the current project", triggered=self.startBuild) self.stopAct = QtGui.QAction(QtGui.QIcon("./images/stop.png"), "S&top", self, statusTip="Cancel the build process", triggered=self.stopBuild) self.programAct = QtGui.QAction(QtGui.QIcon("./images/load.png"), "&Load", self, shortcut=QtGui.QKeySequence("Ctrl+R"), statusTip="Download program to the board using bootloader", triggered=self.programChip) self.firmwareLibList = scanFirmwareLibs() self.firmwareLibActs = [] if len(self.firmwareLibList): for i in range(len(self.firmwareLibList)): self.firmwareLibActs.append( QtGui.QAction(self.firmwareLibList[i], self, statusTip="include " + self.firmwareLibList[i] + " library" ) ) self.exampleProjects = getExampleProjects(self.firmwareLibList) self.exampleFolderMenus = [] self.openExampleActs = [] for group in self.exampleProjects: folder, files = group[0], group[1] self.exampleFolderMenus.append(QtGui.QMenu(str(folder), self)) for fname in files: baseName = os.path.basename(fname) self.openExampleActs.append(QtGui.QAction(os.path.splitext(baseName)[0], self, statusTip = 'Open "' + str(fname).replace('\\', '/') + '"') ) # serial monitor/terminal window self.serialMonitorAct = QtGui.QAction(QtGui.QIcon("./images/serial.png"), "Serial &Monitor", self, shortcut=QtGui.QKeySequence("Ctrl+Shift+M"), statusTip="Launch Serial Monitor Dialog", triggered=self.openSerialPortMonitorDialog) self.serialPortGroup = QtGui.QActionGroup(self) self.serialPortList = scan_serialports() self.serialPortActs = [] if len(self.serialPortList): for i in range(len(self.serialPortList)): self.serialPortActs.append( QtGui.QAction(self.serialPortList[i], self, checkable=True, statusTip="select " + self.serialPortList[i] + " serial port", triggered=self.selectSerialPort) ) self.serialPortGroup.addAction( self.serialPortActs[i] ) # todo: board names?? #self.boardAnitoAct = QtGui.QAction("PhilRobokit &Anito", self, # checkable=True, statusTip="Select PhilRobokit Anito board" ) self.boardStellarisAct = QtGui.QAction("EK-&LM4F120XL", self, checkable=True, statusTip="Select TI Stellaris LM4F120 LaunchPad" ) self.boardGroup = QtGui.QActionGroup(self) #self.boardGroup.addAction(self.boardAnitoAct) self.boardGroup.addAction(self.boardStellarisAct) self.boardStellarisAct.setChecked(True) self.restoreDefaultsAct = QtGui.QAction("Restore Defaults", self, statusTip="Clear configuration files", triggered=self.Configs.setDefaults) # help menu self.aboutAct = QtGui.QAction("&About", self, shortcut=QtGui.QKeySequence("F1"), statusTip="About the IDE", triggered=self.about) self.aboutCompilerAct = QtGui.QAction("About &Compiler", self, statusTip="About GNU tools for ARM Embedded", triggered=self.aboutCompiler) self.aboutQtAct = QtGui.QAction("About &Qt", self, statusTip="Show the Qt library's About box", triggered=QtGui.qApp.aboutQt) self.visitProjectprotoSiteAct = QtGui.QAction("Visit &ProjectProto", self, statusTip="Open ProjectProto blog site (yus' projects)", triggered=self.openProjectProtoSite) self.visitPhilroboticsSiteAct = QtGui.QAction("Visit Phil&Robotics", self, statusTip="Open PhilRobotics website", triggered=self.openPhilRoboticsSite) def createMenus(self): ### File Menu ### self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.newAct) self.fileMenu.addAction(self.openAct) self.fileMenu.addSeparator() self.examplesMenu = QtGui.QMenu('Examples', self) fileCount = 0 for dirCount in range( len(self.exampleFolderMenus) ): examples = self.exampleProjects[dirCount][1] for fname in examples: pathname = str( os.getcwd() + '/' + fname ) # complete path pathname = pathname.replace('\\', '/') # for consistency self.openExampleActs[fileCount].triggered.connect( functools.partial(self.Editor.openFile, pathname) ) self.exampleFolderMenus[dirCount].addAction(self.openExampleActs[fileCount]) fileCount += 1 self.examplesMenu.addMenu(self.exampleFolderMenus[dirCount]) self.fileMenu.addMenu(self.examplesMenu) self.fileMenu.addSeparator() self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.closeAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) ### Edit Menu ### self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.editUndoAct) self.editMenu.addAction(self.editRedoAct) self.editMenu.addSeparator() self.editMenu.addAction(self.editCutAct) self.editMenu.addAction(self.editCopyAct) self.editMenu.addAction(self.editPasteAct) self.editMenu.addAction(self.editSelectAllAct) self.editMenu.addAction(self.editClearAct) self.editMenu.addSeparator() self.editMenu.addAction(self.findAct) ### Project Menu ### self.projectMenu = self.menuBar().addMenu("&Project") self.projectMenu.addAction(self.compileAct) self.projectMenu.addAction(self.stopAct) self.programMenu = self.projectMenu.addMenu("Program Board...") self.programMenu.addAction(self.programAct) self.projectMenu.addSeparator() self.firmwareLibMenu = self.projectMenu.addMenu("Import &Library...") if len(self.firmwareLibActs): for i in range(len(self.firmwareLibActs)): self.firmwareLibMenu.addAction(self.firmwareLibActs[i]) self.connect(self.firmwareLibMenu, QtCore.SIGNAL("triggered (QAction *)"), self.importFirmwareLib) ### Tools Menu ### self.toolsMenu = self.menuBar().addMenu("&Tools") self.toolsMenu.addAction(self.serialMonitorAct) self.toolsMenu.addSeparator() self.boardMenu = self.toolsMenu.addMenu("&Board") #self.boardMenu.addAction(self.boardAnitoAct) self.boardMenu.addAction(self.boardStellarisAct) self.serialPortMenu = self.toolsMenu.addMenu("&Serial Port") self.serialPortGroup = QtGui.QActionGroup(self) self.connect(self.serialPortMenu, QtCore.SIGNAL("aboutToShow ()"), self.updateSerialPortList ) self.updateSerialPortList() self.toolsMenu.addSeparator() self.toolsMenu.addAction(self.restoreDefaultsAct) # todo: create settings dialog #self.bootloaderMenu = self.toolsMenu.addMenu("&Booloader") ### Help Menu ### self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.visitProjectprotoSiteAct) self.helpMenu.addAction(self.visitPhilroboticsSiteAct) self.helpMenu.addAction(self.aboutCompilerAct) self.helpMenu.addAction(self.aboutQtAct) self.helpMenu.addAction(self.aboutAct) def createToolBars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.setObjectName("FileToolBar") self.fileToolBar.addAction(self.newAct) self.fileToolBar.addAction(self.openAct) self.fileToolBar.addAction(self.saveAct) self.projectToolBar = self.addToolBar("Project") self.projectToolBar.setObjectName("ProjectToolBar") self.projectToolBar.addAction(self.compileAct) self.projectToolBar.addAction(self.stopAct) self.projectToolBar.addAction(self.programAct) self.serialToolBar = self.addToolBar("Serial Port") self.serialToolBar.setObjectName("SerialPortToolBar") self.serialToolBar.addAction(self.serialMonitorAct) self.serialToolBar.addWidget(self.serialPortLabel) def createStatusBar(self): self.statusBar().showMessage("Ready") def createLogWindow(self): self.log = QtGui.QTextEdit(self) self.log.setReadOnly(True) self.log.resize(self.width(), 100 ) self.log.setText("Ready") palette = QtGui.QPalette(QtGui.QColor(0, 0, 0)) palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Base, QtGui.QColor(25, 10, 0)) self.log.setPalette(palette) logWindow = QtGui.QDockWidget("Log", self) logWindow.setObjectName("LogView") logWindow.setWidget(self.log) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, logWindow) def insertLog(self, log='', resetWindow=False): if resetWindow: self.log.setText('') self.log.append(log) def timerEvent(self, *args, **kwargs): timerID = args[0].timerId() if timerID == self.pollCompilerTimerID: ret, msg = self.Compiler.pollBuildProcess() if ret: if len( msg ): self.insertLog( msg ) else: self.killTimer(timerID) self.pollCompilerTimerID = None if timerID == self.pollLoaderTimerID: ret, msg = self.flashLoader.pollBootLoadProcess() if ret: if len(msg): self.insertLog( msg ) else: self.killTimer(timerID) self.pollLoaderTimerID = None return QtGui.QMainWindow.timerEvent(self, *args, **kwargs) def closeEvent(self, event): if not self.Editor.closeAllTabs(): # check for unsaved changes in the project(s) event.ignore() return self.Configs.saveIdeSettings(self.serialPortName) return QtGui.QMainWindow.closeEvent(self, event)
class AppMainWindow(QtGui.QMainWindow): ''' classdocs ''' def __init__(self): ''' Constructor ''' super(AppMainWindow, self).__init__() print "STM32 GCC-ARM IDE started..." print SPLASH_NOTICE if False: # todo: set to True if building stand-alone package (cx_Freeze) setpath = os.path.dirname(os.path.realpath(__file__)) if os.name == 'nt': os.chdir(setpath[:setpath.rfind('\\')]) else: os.chdir(setpath[:setpath.rfind('/')]) self.aboutDlg = AboutDialog(self) self.aboutDlg.show() self.setWindowTitle("STM32 GCC-ARM IDE") self.setWindowIcon(QtGui.QIcon('images/app.png')) self.setMinimumSize(300, 400) self.Editor = MultipleCppEditor(self) self.setCentralWidget(self.Editor) self.OutLineView = self.Editor.getOutLineView() self.OutLineView.setObjectName("OutLineView") self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.OutLineView) self.Compiler = GccCompilerThread(self) self.pollCompilerTimerID = None self.serialPortName = None self.serialPortLabel = QtGui.QLabel( '<font color=red><i>(select port)</i></font>') self.SerialPortMonitorDialog = SerialPortMonitor(self) self.flashLoader = FlashLoaderThread(self) self.pollLoaderTimerID = None self.Configs = IdeConfig(self) self.createLogWindow() self.createActions() self.createToolBars() self.createStatusBar() self.Configs.restoreIdeSettings() self.createMenus() self.aboutDlg.finish(self) print "IDE ready." def about(self): self.aboutDlg.show() kdbMod = QtGui.QApplication.keyboardModifiers() if kdbMod == QtCore.Qt.ShiftModifier: self.aboutDlg.showMessage( '[developer mode] update firmware library...', QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtGui.QColor("#eecc77")) self.aboutDlg.showUpdateDialog() return # todo: other informations self.aboutDlg.showMessage( "STM32 GCC-ARM IDE [ %s ]" % self.aboutDlg.getVersions(), QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom, QtGui.QColor("#eecc77")) def openProjectProtoSite(self): QtGui.QDesktopServices.openUrl( QtCore.QUrl("http://projectproto.blogspot.com")) def openPhilRoboticsSite(self): # todo: change to .ORG QtGui.QDesktopServices.openUrl( QtCore.QUrl("http://www.philrobotics.com")) def aboutCompiler(self): info = self.Compiler.getCompilerInfo() #self.log.append(info) if info: QtGui.QMessageBox.about(self, "Compiler Information", info) else: QtGui.QMessageBox.about(self, "Compiler Information", "no compiler found!") def startBuild(self): if self.Compiler.isRunning(): self.insertLog('compiler busy..') return kdbMod = QtGui.QApplication.keyboardModifiers() ret = self.Editor.saveFile( ) # save the file first before starting the build. if ret == False: self.insertLog("<font color=red>unable to save project!</font>") return elif ret == None: self.insertLog("nothing to build.") return self.insertLog( "<font color=green>------- Start Project Build. -------</font>", True) fn = self.Editor.getCurrentFile() cleanBuild = False if kdbMod == QtCore.Qt.ShiftModifier: #print 'Shift-Click PushButton' cleanBuild = True ret, msg = self.Compiler.buildProject(fn, cleanBuild) if not ret: self.insertLog("<font color=red>%s</font>" % msg) if msg == "file not found": QtGui.QMessageBox.warning( self, "Build Error", "File not found (may be unsaved yet). " + \ "Create or save first the file." ) elif msg == "busy": QtGui.QMessageBox.warning( self, "Busy", "Previous build process still running!") elif msg == "abort": QtGui.QMessageBox.warning(self, "Error", "Unable to start build process!") else: self.insertLog("<font color=lightblue><i> %s </i></font>" % msg) self.pollCompilerTimerID = self.startTimer(50) if not self.pollCompilerTimerID: self.insertLog("<font color=red>Unable to start Timer.</font>") def stopBuild(self): if self.pollCompilerTimerID: self.killTimer(self.pollCompilerTimerID) self.pollCompilerTimerID = None self.Compiler.pollBuildProcess(True) self.insertLog("<font color=red>----- Stopped. -----</font>") else: self.insertLog("nothing to stop.") def programChip(self): if self.Editor.isCurrentFileModified(): self.insertLog( '<font color=orange>Project was modified. Please re-build the project.</font>' ) return if not self.serialPortName: self.insertLog( '<font color=orange>Please select first a Serial Port.</font>') return if self.Compiler.isRunning(): self.insertLog('compiler busy... please wait...') return if self.SerialPortMonitorDialog.isPortOpen(): self.SerialPortMonitorDialog.close( ) # close first serial port monitor if self.flashLoader.isRunning(): self.insertLog('serial bootloader busy.') return binfile = self.Compiler.getExpectedBinFileName( self.Editor.getCurrentFile()) ret, msg = self.flashLoader.programDevice(binfile, self.serialPortName) if ret: self.insertLog("<font color=green>Bootload/Program Device:</font>", True) self.insertLog("<font color=lightblue><i> %s </i></font>" % msg) self.pollLoaderTimerID = self.startTimer(0.5) # relatively fast! if not self.pollLoaderTimerID: self.insertLog("<font color=red>Unable to start Timer.</font>") else: self.insertLog("<font color=red>%s</font>" % msg) def selectSerialPort(self): act = self.serialPortGroup.checkedAction() if act: portname = str(act.text()) if portname != self.serialPortName: self.serialPortName = portname self.Configs.saveIdeSettings(self.serialPortName) self.insertLog( 'selected port: <b><font color=green>%s</font></b>' % self.serialPortName) self.serialPortLabel.setText('<font color=green>%s</font>' % self.serialPortName) if self.SerialPortMonitorDialog.isPortOpen(): if not self.SerialPortMonitorDialog.openPort( self.serialPortName): self.SerialPortMonitorDialog.close() self.insertLog( "<font color=red>unable to open %s</font>" % self.serialPortName) def updateSerialPortList(self): # clear previous actions list self.serialPortMenu.clear() for act in self.serialPortGroup.actions(): self.serialPortGroup.removeAction(act) del act # scan existing ports portList = scan_serialports() # serialport.py previousPortName = self.Configs.getSerialPortName() # create new actions & update serial port menu if len(portList): for i in range(len(portList)): act = QtGui.QAction(portList[i], self, checkable=True, statusTip="select " + portList[i] + " serial port", triggered=self.selectSerialPort) self.serialPortGroup.addAction(act) self.serialPortMenu.addAction(act) if portList[i] == previousPortName: act.setChecked(True) act.trigger() if not self.serialPortGroup.checkedAction(): self.serialPortName = '' self.insertLog( '<i><font color=gray>( please select a serial port. )</font></i>' ) def importFirmwareLib(self, action=None): if action: libname = str(action.text()) self.Editor.importFirmwareLib(libname) def openSerialPortMonitorDialog(self): if self.serialPortName == None: self.insertLog("<font color=red>no serial port selected!</font>") return if self.SerialPortMonitorDialog.openPort(self.serialPortName): self.SerialPortMonitorDialog.show() # non-modal open else: self.insertLog( "<font color=red>unable to open serial port!</font>") def createActions(self): # file menu self.newAct = QtGui.QAction(QtGui.QIcon("./images/new.png"), "&New", self, shortcut=QtGui.QKeySequence("Ctrl+N"), statusTip="Create a new file", triggered=self.Editor.newFile) self.openAct = QtGui.QAction(QtGui.QIcon("./images/open.png"), "&Open...", self, shortcut=QtGui.QKeySequence("Ctrl+O"), statusTip="Open an existing file") self.openAct.triggered.connect( functools.partial(self.Editor.openFile, None)) self.closeAct = QtGui.QAction("&Close", self, shortcut=QtGui.QKeySequence("Ctrl+W"), statusTip="Close the current window", triggered=self.Editor.closeCurrentFile) self.saveAct = QtGui.QAction(QtGui.QIcon("./images/save.png"), "&Save", self, shortcut=QtGui.QKeySequence("Ctrl+S"), statusTip="Save the current file", triggered=self.Editor.saveFile) self.saveAsAct = QtGui.QAction( "Save &As...", self, shortcut=QtGui.QKeySequence("Ctrl+Shift+S"), statusTip="Save to another file", triggered=self.Editor.saveFileAs) self.exitAct = QtGui.QAction("E&xit", self, shortcut=QtGui.QKeySequence("Alt+F4"), statusTip="Exit the application", triggered=QtGui.qApp.closeAllWindows) # edit menu self.editUndoAct = QtGui.QAction("&Undo", self, shortcut=QtGui.QKeySequence("Ctrl+Z"), triggered=self.Editor.editUndo) self.editRedoAct = QtGui.QAction("&Redo", self, shortcut=QtGui.QKeySequence("Ctrl+Y"), triggered=self.Editor.editRedo) self.editCutAct = QtGui.QAction("Cu&t", self, shortcut=QtGui.QKeySequence("Ctrl+X"), triggered=self.Editor.editCut) self.editCopyAct = QtGui.QAction("&Copy", self, shortcut=QtGui.QKeySequence("Ctrl+C"), triggered=self.Editor.editCopy) self.editPasteAct = QtGui.QAction( "&Paste", self, shortcut=QtGui.QKeySequence("Ctrl+V"), triggered=self.Editor.editPaste) self.editSelectAllAct = QtGui.QAction( "Select &All", self, shortcut=QtGui.QKeySequence("Ctrl+A"), triggered=self.Editor.editSelectAll) self.editClearAct = QtGui.QAction("Clear", self, triggered=self.Editor.editClear) # find/replace self.findAct = QtGui.QAction("&Find/Replace...", self, shortcut=QtGui.QKeySequence("Ctrl+F"), statusTip="Find/Replace texts", triggered=self.Editor.showFindDialog) # project menu self.compileAct = QtGui.QAction(QtGui.QIcon("./images/build.png"), "&Compile", self, shortcut=QtGui.QKeySequence("Ctrl+B"), statusTip="Build the current project", triggered=self.startBuild) self.stopAct = QtGui.QAction(QtGui.QIcon("./images/stop.png"), "S&top", self, statusTip="Cancel the build process", triggered=self.stopBuild) self.programAct = QtGui.QAction( QtGui.QIcon("./images/load.png"), "&Load", self, shortcut=QtGui.QKeySequence("Ctrl+R"), statusTip="Download program to the board using bootloader", triggered=self.programChip) self.firmwareLibList = scanFirmwareLibs() self.firmwareLibActs = [] if len(self.firmwareLibList): for i in range(len(self.firmwareLibList)): self.firmwareLibActs.append( QtGui.QAction(self.firmwareLibList[i], self, statusTip="include " + self.firmwareLibList[i] + " library")) self.exampleProjects = getExampleProjects(self.firmwareLibList) self.exampleFolderMenus = [] self.openExampleActs = [] for group in self.exampleProjects: folder, files = group[0], group[1] self.exampleFolderMenus.append(QtGui.QMenu(str(folder), self)) for fname in files: baseName = os.path.basename(fname) self.openExampleActs.append( QtGui.QAction(os.path.splitext(baseName)[0], self, statusTip='Open "' + str(fname).replace('\\', '/') + '"')) # serial monitor/terminal window self.serialMonitorAct = QtGui.QAction( QtGui.QIcon("./images/serial.png"), "Serial &Monitor", self, shortcut=QtGui.QKeySequence("Ctrl+Shift+M"), statusTip="Launch Serial Monitor Dialog", triggered=self.openSerialPortMonitorDialog) self.serialPortGroup = QtGui.QActionGroup(self) self.serialPortList = scan_serialports() self.serialPortActs = [] if len(self.serialPortList): for i in range(len(self.serialPortList)): self.serialPortActs.append( QtGui.QAction(self.serialPortList[i], self, checkable=True, statusTip="select " + self.serialPortList[i] + " serial port", triggered=self.selectSerialPort)) self.serialPortGroup.addAction(self.serialPortActs[i]) # todo: board names?? #self.boardAnitoAct = QtGui.QAction("PhilRobokit &Anito", self, # checkable=True, statusTip="Select PhilRobokit Anito board" ) self.boardEgizmoStm32Act = QtGui.QAction( "e&Gizmo STM32", self, checkable=True, statusTip="Select eGizmo STM32F100C8 MCU board") self.boardGroup = QtGui.QActionGroup(self) #self.boardGroup.addAction(self.boardAnitoAct) self.boardGroup.addAction(self.boardEgizmoStm32Act) self.boardEgizmoStm32Act.setChecked(True) self.restoreDefaultsAct = QtGui.QAction( "Restore Defaults", self, statusTip="Clear configuration files", triggered=self.Configs.setDefaults) # help menu self.aboutAct = QtGui.QAction("&About", self, shortcut=QtGui.QKeySequence("F1"), statusTip="About the IDE", triggered=self.about) self.aboutCompilerAct = QtGui.QAction( "About &Compiler", self, statusTip="About GNU tools for ARM Embedded", triggered=self.aboutCompiler) self.aboutQtAct = QtGui.QAction( "About &Qt", self, statusTip="Show the Qt library's About box", triggered=QtGui.qApp.aboutQt) self.visitProjectprotoSiteAct = QtGui.QAction( "Visit &ProjectProto", self, statusTip="Open ProjectProto blog site (yus' projects)", triggered=self.openProjectProtoSite) self.visitPhilroboticsSiteAct = QtGui.QAction( "Visit Phil&Robotics", self, statusTip="Open PhilRobotics website", triggered=self.openPhilRoboticsSite) def createMenus(self): ### File Menu ### self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.newAct) self.fileMenu.addAction(self.openAct) self.fileMenu.addSeparator() self.examplesMenu = QtGui.QMenu('Examples', self) fileCount = 0 for dirCount in range(len(self.exampleFolderMenus)): examples = self.exampleProjects[dirCount][1] for fname in examples: pathname = str(os.getcwd() + '/' + fname) # complete path pathname = pathname.replace('\\', '/') # for consistency self.openExampleActs[fileCount].triggered.connect( functools.partial(self.Editor.openFile, pathname)) self.exampleFolderMenus[dirCount].addAction( self.openExampleActs[fileCount]) fileCount += 1 self.examplesMenu.addMenu(self.exampleFolderMenus[dirCount]) self.fileMenu.addMenu(self.examplesMenu) self.fileMenu.addSeparator() self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.closeAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) ### Edit Menu ### self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.editUndoAct) self.editMenu.addAction(self.editRedoAct) self.editMenu.addSeparator() self.editMenu.addAction(self.editCutAct) self.editMenu.addAction(self.editCopyAct) self.editMenu.addAction(self.editPasteAct) self.editMenu.addAction(self.editSelectAllAct) self.editMenu.addAction(self.editClearAct) self.editMenu.addSeparator() self.editMenu.addAction(self.findAct) ### Project Menu ### self.projectMenu = self.menuBar().addMenu("&Project") self.projectMenu.addAction(self.compileAct) self.projectMenu.addAction(self.stopAct) self.programMenu = self.projectMenu.addMenu("Program Board...") self.programMenu.addAction(self.programAct) self.projectMenu.addSeparator() self.firmwareLibMenu = self.projectMenu.addMenu("Import &Library...") if len(self.firmwareLibActs): for i in range(len(self.firmwareLibActs)): self.firmwareLibMenu.addAction(self.firmwareLibActs[i]) self.connect(self.firmwareLibMenu, QtCore.SIGNAL("triggered (QAction *)"), self.importFirmwareLib) ### Tools Menu ### self.toolsMenu = self.menuBar().addMenu("&Tools") self.toolsMenu.addAction(self.serialMonitorAct) self.toolsMenu.addSeparator() self.boardMenu = self.toolsMenu.addMenu("&Board") #self.boardMenu.addAction(self.boardAnitoAct) self.boardMenu.addAction(self.boardEgizmoStm32Act) self.serialPortMenu = self.toolsMenu.addMenu("&Serial Port") self.serialPortGroup = QtGui.QActionGroup(self) self.connect(self.serialPortMenu, QtCore.SIGNAL("aboutToShow ()"), self.updateSerialPortList) self.updateSerialPortList() self.toolsMenu.addSeparator() self.toolsMenu.addAction( self.restoreDefaultsAct) # todo: create settings dialog #self.bootloaderMenu = self.toolsMenu.addMenu("&Booloader") ### Help Menu ### self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.visitPhilroboticsSiteAct) self.helpMenu.addAction(self.visitProjectprotoSiteAct) self.helpMenu.addAction(self.aboutCompilerAct) self.helpMenu.addAction(self.aboutQtAct) self.helpMenu.addAction(self.aboutAct) def createToolBars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.setObjectName("FileToolBar") self.fileToolBar.addAction(self.newAct) self.fileToolBar.addAction(self.openAct) self.fileToolBar.addAction(self.saveAct) self.projectToolBar = self.addToolBar("Project") self.projectToolBar.setObjectName("ProjectToolBar") self.projectToolBar.addAction(self.compileAct) self.projectToolBar.addAction(self.stopAct) self.projectToolBar.addAction(self.programAct) self.serialToolBar = self.addToolBar("Serial Port") self.serialToolBar.setObjectName("SerialPortToolBar") self.serialToolBar.addAction(self.serialMonitorAct) self.serialToolBar.addWidget(self.serialPortLabel) def createStatusBar(self): self.statusBar().showMessage("Ready") def createLogWindow(self): self.log = QtGui.QTextEdit(self) self.log.setReadOnly(True) self.log.resize(self.width(), 100) self.log.setText("Ready") palette = QtGui.QPalette(QtGui.QColor(0, 0, 0)) palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Base, QtGui.QColor(25, 10, 0)) self.log.setPalette(palette) logWindow = QtGui.QDockWidget("Log", self) logWindow.setObjectName("LogView") logWindow.setWidget(self.log) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, logWindow) def insertLog(self, log='', resetWindow=False): if resetWindow: self.log.setText('') self.log.append(log) def timerEvent(self, *args, **kwargs): timerID = args[0].timerId() if timerID == self.pollCompilerTimerID: ret, msg = self.Compiler.pollBuildProcess() if ret: if len(msg): self.insertLog(msg) else: self.killTimer(timerID) self.pollCompilerTimerID = None if timerID == self.pollLoaderTimerID: ret, msg = self.flashLoader.pollBootLoadProcess() if ret: if len(msg): self.insertLog("<font color=lightgreen>%s</font>" % msg) else: self.killTimer(timerID) self.pollLoaderTimerID = None return QtGui.QMainWindow.timerEvent(self, *args, **kwargs) def closeEvent(self, event): if not self.Editor.closeAllTabs( ): # check for unsaved changes in the project(s) event.ignore() return self.Configs.saveIdeSettings(self.serialPortName) return QtGui.QMainWindow.closeEvent(self, event)