Mercurial > lcfOS
view python/ide.py @ 247:dd8bbb963458
project remove
author | Windel Bouwman |
---|---|
date | Fri, 26 Jul 2013 10:44:26 +0200 |
parents | 6259856841a0 |
children | b10d46e5c8dd |
line wrap: on
line source
#!/usr/bin/python import sys, os, base64 assert sys.version_info.major == 3, "Needs to be run in python version 3.x" from PyQt4.QtCore import * from PyQt4.QtGui import * # Compiler imports: import ppci from astviewer import AstViewer #from codeeditor import CodeEdit from codeedit import CodeEdit stutil = __import__('st-util') import c3 class BuildOutput(QTextEdit): """ Build output component """ def __init__(self, parent=None): super(BuildOutput, self).__init__(parent) self.setCurrentFont(QFont('Courier')) self.setReadOnly(True) self.append('Build output will appear here!') class BuildErrors(QTreeView): sigErrorSelected = pyqtSignal(object) def __init__(self, parent=None): super(BuildErrors, self).__init__(parent) model = QStandardItemModel() self.setModel(model) self.clicked.connect(self.itemSelected) self.errorIcon = QIcon('icons/error.png') self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels(['Message', 'Row', 'Column']) self.setModel(self.model) def setErrorList(self, errorlist): c = self.model.rowCount() self.model.removeRows(0, c) for e in errorlist: item = QStandardItem(self.errorIcon, str(e.msg)) item.setData(e) irow = QStandardItem(str(e.loc.row)) irow.setData(e) icol = QStandardItem(str(e.loc.col)) icol.setData(e) self.model.appendRow([item, irow, icol]) def itemSelected(self, index): if not index.isValid(): return item = self.model.itemFromIndex(index) err = item.data() self.sigErrorSelected.emit(err) class AboutDialog(QDialog): def __init__(self, parent=None): super(AboutDialog, self).__init__(parent) self.setWindowTitle('About') l = QVBoxLayout(self) txt = QTextEdit(self) txt.setReadOnly(True) aboutText = """<h1>lcfOS IDE</h1> <p>An all-in-one IDE for OS development.</p> <p>https://www.assembla.com/spaces/lcfOS/wiki</p> <p>Author: Windel Bouwman</p> """ txt.append(aboutText) l.addWidget(txt) but = QPushButton('OK') but.setDefault(True) but.clicked.connect(self.close) l.addWidget(but) class Ide(QMainWindow): def __init__(self, parent=None): super(Ide, self).__init__(parent) self.setWindowTitle('LCFOS IDE') icon = QIcon('icons/logo.png') self.setWindowIcon(icon) # Create menus: mb = self.menuBar() self.fileMenu = mb.addMenu('File') self.viewMenu = mb.addMenu('View') self.helpMenu = mb.addMenu('Help') # Create mdi area: self.mdiArea = QMdiArea() self.setCentralWidget(self.mdiArea) # Create components: def addComponent(name, widget): dw = QDockWidget(name) dw.setWidget(widget) dw.setObjectName(name) self.addDockWidget(Qt.RightDockWidgetArea, dw) self.viewMenu.addAction(dw.toggleViewAction()) return widget self.buildOutput = addComponent('Build output', BuildOutput()) self.astViewer = addComponent('AST viewer', AstViewer()) self.astViewer.sigNodeSelected.connect(self.nodeSelected) self.builderrors = addComponent('Build errors', BuildErrors()) self.builderrors.sigErrorSelected.connect(self.errorSelected) self.devxplr = addComponent('Device explorer', stutil.DeviceExplorer()) self.regview = addComponent('Registers', stutil.RegisterView()) self.memview = addComponent('Memory', stutil.MemoryView()) self.ctrlToolbar = stutil.DebugToolbar() self.addToolBar(self.ctrlToolbar) self.ctrlToolbar.setObjectName('debugToolbar') self.devxplr.deviceSelected.connect(self.regview.mdl.setDevice) self.ctrlToolbar.statusChange.connect(self.memview.refresh) self.devxplr.deviceSelected.connect(self.memview.setDevice) self.devxplr.deviceSelected.connect(self.ctrlToolbar.setDevice) self.ctrlToolbar.statusChange.connect(self.regview.refresh) self.ctrlToolbar.codePosition.connect(self.pointCode) # About dialog: self.aboutDialog = AboutDialog() self.aboutDialog.setWindowIcon(icon) # Create actions: def addMenuEntry(name, menu, callback, shortcut=None): a = QAction(name, self) menu.addAction(a) a.triggered.connect(callback) if shortcut: a.setShortcut(shortcut) addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QKeySequence(QKeySequence.New)) addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open)) addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save)) addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F7")) self.helpAction = QAction('Help', self) self.helpAction.setShortcut(QKeySequence('F1')) self.helpMenu.addAction(self.helpAction) addMenuEntry('About', self.helpMenu, self.aboutDialog.open) addMenuEntry('Cascade windows', self.viewMenu, self.mdiArea.cascadeSubWindows) addMenuEntry('Tile windows', self.viewMenu, self.mdiArea.tileSubWindows) sb = self.statusBar() # Load settings: self.settings = QSettings('windelsoft', 'lcfoside') self.loadSettings() ce = self.newFile() self.diag = ppci.DiagnosticsManager() self.c3front = c3.Builder(self.diag) # File handling: def newFile(self): ce = CodeEdit() ce.textChanged.connect(self.buildFile) w = self.mdiArea.addSubWindow(ce) ce.show() w.resize(500, 700) return ce def openFile(self): filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3", "C3 source files (*.ks)") if filename: self.loadFile(filename) def saveFile(self): ac = self.activeMdiChild() if ac: ac.save() def loadFile(self, filename): # Find existing mdi widget: wid = self.findMdiChild(filename) if wid: self.mdiArea.setActiveSubWindow(wid.parent()) return wid # Create a new one: ce = CodeEdit() #source = self.project.loadProjectFile(filename) try: with open(filename) as f: source = f.read() ce.setSource(source) except Exception as e: print('exception opening file', e) self.mdiArea.addSubWindow(ce) ce.setFileName(filename) ce.show() return ce # MDI: def activeMdiChild(self): aw = self.mdiArea.activeSubWindow() if aw: return aw.widget() else: return None def findMdiChild(self, filename): for window in self.mdiArea.subWindowList(): wid = window.widget() if wid.filename == filename: return wid return None def allChildren(self): c = [] for window in self.mdiArea.subWindowList(): wid = window.widget() c.append(wid) return c # Settings: def loadSettings(self): if self.settings.contains('mainwindowstate'): self.restoreState(self.settings.value('mainwindowstate')) if self.settings.contains('mainwindowgeometry'): self.restoreGeometry(self.settings.value('mainwindowgeometry')) if self.settings.contains('lastfile'): self.loadFile(self.settings.value('lastfile')) def closeEvent(self, ev): self.settings.setValue('mainwindowstate', self.saveState()) self.settings.setValue('mainwindowgeometry', self.saveGeometry()) # # TODO: ask for save of opened files ac = self.activeMdiChild() if ac: if hasattr(ac, 'filename') and ac.filename: self.settings.setValue('lastfile', ac.filename) else: self.settings.remove('lastfile') else: self.settings.remove('lastfile') ev.accept() # Error handling: def nodeSelected(self, node): ce = self.activeMdiChild() if not ce: return if node.loc: row, col = node.loc.row, node.loc.col ce.setRowCol(row, col) ce.setFocus() else: ce.clearErrors() def errorSelected(self, err): ce = self.activeMdiChild() if not ce: return ce.setRowCol(err.loc.row, err.loc.col) ce.setFocus() def pointCode(self, p): print('PC', p) # Build recepy: def buildFile(self): ce = self.activeMdiChild() if ce: source = ce.Source self.buildOutput.clear() self.buildOutput.append('Starting build') ir = self.c3front.build(source) ast = self.c3front.pkg self.astViewer.setAst(ast) self.buildOutput.append("Done!") if __name__ == '__main__': app = QApplication(sys.argv) ide = Ide() ide.show() app.exec_()