# HG changeset patch # User Windel Bouwman # Date 1374849962 -7200 # Node ID b10d46e5c8ddf4c5e2320cf083d159b20b1e9648 # Parent dd8bbb9634580339a6ee22b5900b8608de6904e6 ide refactor diff -r dd8bbb963458 -r b10d46e5c8dd python/codeedit.py --- a/python/codeedit.py Fri Jul 26 10:44:26 2013 +0200 +++ b/python/codeedit.py Fri Jul 26 16:46:02 2013 +0200 @@ -211,21 +211,33 @@ self.update() class CodeEdit(QScrollArea): - def __init__(self): - super().__init__() - self.ic = InnerCode(self) - self.textChanged = self.ic.textChanged - self.setWidget(self.ic) - self.setWidgetResizable(True) - self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) - self.setFocusPolicy(Qt.NoFocus) - self.showRow = self.ic.showRow - self.setRowCol = self.ic.setRowCol - Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v)) - def setErrors(self, el): - self.ic.setErrors(el) - def setFocus(self): - self.ic.setFocus() + def __init__(self): + super().__init__() + self.ic = InnerCode(self) + self.textChanged = self.ic.textChanged + self.setWidget(self.ic) + self.setWidgetResizable(True) + self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + self.setFocusPolicy(Qt.NoFocus) + self.showRow = self.ic.showRow + self.setRowCol = self.ic.setRowCol + self.FileName = None + Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v)) + def setErrors(self, el): + self.ic.setErrors(el) + + def setFocus(self): + self.ic.setFocus() + + def setFileName(self, fn): + self.filename = fn + if not fn: + fn = 'Untitled' + self.setWindowTitle(fn) + def getFileName(self): + return self.filename + FileName = property(getFileName, setFileName) + if __name__ == '__main__': app = QApplication(sys.argv) diff -r dd8bbb963458 -r b10d46e5c8dd python/ide.py --- a/python/ide.py Fri Jul 26 10:44:26 2013 +0200 +++ b/python/ide.py Fri Jul 26 16:46:02 2013 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/python -import sys, os, base64 -assert sys.version_info.major == 3, "Needs to be run in python version 3.x" +import sys +import os from PyQt4.QtCore import * from PyQt4.QtGui import * @@ -9,32 +9,33 @@ # 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): + """ 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) + 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): + def setErrorList(self, errorlist): c = self.model.rowCount() self.model.removeRows(0, c) for e in errorlist: @@ -45,7 +46,8 @@ icol = QStandardItem(str(e.loc.col)) icol.setData(e) self.model.appendRow([item, irow, icol]) - def itemSelected(self, index): + + def itemSelected(self, index): if not index.isValid(): return item = self.model.itemFromIndex(index) @@ -54,219 +56,200 @@ 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 = """
An all-in-one IDE for OS development.
-https://www.assembla.com/spaces/lcfOS/wiki
-Author: Windel Bouwman
- """ - txt.append(aboutText) - l.addWidget(txt) - but = QPushButton('OK') - but.setDefault(True) - but.clicked.connect(self.close) - l.addWidget(but) + def __init__(self, parent=None): + super(AboutDialog, self).__init__(parent) + self.setWindowTitle('About') + l = QVBoxLayout(self) + txt = QTextEdit(self) + txt.setReadOnly(True) + aboutText = """An all-in-one IDE for OS development.
+https://www.assembla.com/spaces/lcfOS/wiki
+Author: Windel Bouwman
+ """ + 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) + 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 menus: + mb = self.menuBar() + self.fileMenu = mb.addMenu('File') + self.viewMenu = mb.addMenu('View') + self.helpMenu = mb.addMenu('Help') - # 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 + # Create mdi area: + self.mdiArea = QMdiArea() + self.mdiArea.setViewMode(QMdiArea.TabbedView) + self.setCentralWidget(self.mdiArea) - 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) + # 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 - # 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) + 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) - sb = self.statusBar() + # 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) - # Load settings: - self.settings = QSettings('windelsoft', 'lcfoside') - self.loadSettings() - - ce = self.newFile() - self.diag = ppci.DiagnosticsManager() - self.c3front = c3.Builder(self.diag) + 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")) - # 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 + 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() - def openFile(self): - filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3", "C3 source files (*.ks)") - if filename: - self.loadFile(filename) + # Load settings: + self.settings = QSettings('windelsoft', 'lcfoside') + self.loadSettings() + self.diag = ppci.DiagnosticsManager() + self.c3front = c3.Builder(self.diag) + + # File handling: + def newFile(self): + self.newCodeEdit() - 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 + def openFile(self): + filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3", + "C3 source files (*.c3)") + if filename: + self.loadFile(filename) - # Create a new one: - ce = CodeEdit() + def saveFile(self): + ac = self.activeMdiChild() + if ac: + ac.save() - #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 + def loadFile(self, filename): + ce = self.newCodeEdit() + try: + with open(filename) as f: + ce.Source = f.read() + ce.FileName = filename + except Exception as e: + print('exception opening file', e) - # MDI: - def activeMdiChild(self): - aw = self.mdiArea.activeSubWindow() - if aw: - return aw.widget() - else: - return None + # MDI: + def newCodeEdit(self): + ce = CodeEdit() + ce.textChanged.connect(self.buildFile) + w = self.mdiArea.addSubWindow(ce) + ce.show() + return ce + + def activeMdiChild(self): + aw = self.mdiArea.activeSubWindow() + if aw: + return aw.widget() + + def findMdiChild(self, filename): + for wid in self.allChildren(): + if wid.filename == filename: + return wid - 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 + def allChildren(self): + return [w.widget() for w in self.mdiArea.subWindowList()] + + # 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('lastfiles'): + lfs = self.settings.value('lastfiles') + for lf in lfs: + self.loadFile(lf) - # 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) + def closeEvent(self, ev): + self.settings.setValue('mainwindowstate', self.saveState()) + self.settings.setValue('mainwindowgeometry', self.saveGeometry()) + ac = self.activeMdiChild() + lfs = [ce.FileName for ce in self.allChildren() if ce.FileName] + self.settings.setValue('lastfiles', lfs) + ev.accept() + + # Error handling: + def nodeSelected(self, node): + self.showLoc(node.loc) + + def errorSelected(self, err): + self.showLoc(err.loc) + + def showLoc(self, loc): + ce = self.activeMdiChild() + if not ce: + return + if loc: + ce.setRowCol(loc.row, loc.col) + ce.setFocus() else: - self.settings.remove('lastfile') - else: - self.settings.remove('lastfile') - ev.accept() + ce.clearErrors() - # 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): + def pointCode(self, p): print('PC', p) + # Build recepy: + def buildFile(self): + ce = self.activeMdiChild() + if not ce: + return + self.buildOutput.clear() + self.diag.clear() + self.buildOutput.append('Starting build') + ir = self.c3front.build(ce.Source) - # 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) + # Set errors: + for err in self.diag.diags: + self.buildOutput.append(str(err)) + self.builderrors.setErrorList(self.diag.diags) + ce.setErrors(self.diag.diags) ast = self.c3front.pkg self.astViewer.setAst(ast) self.buildOutput.append("Done!") diff -r dd8bbb963458 -r b10d46e5c8dd python/ppci/errors.py --- a/python/ppci/errors.py Fri Jul 26 10:44:26 2013 +0200 +++ b/python/ppci/errors.py Fri Jul 26 16:46:02 2013 +0200 @@ -49,16 +49,16 @@ class DiagnosticsManager: def __init__(self): - self.diags = [] + self.diags = [] def addDiag(self, d): - self.diags.append(d) + self.diags.append(d) def error(self, msg, loc): - self.addDiag(CompilerError(msg, loc)) + self.addDiag(CompilerError(msg, loc)) def clear(self): - del self.diags[:] + del self.diags[:] def printErrors(self, src): if len(self.diags) > 0: