changeset 8:edd70006d3e4

Started with MDI functions
author windel
date Fri, 21 Oct 2011 17:36:57 +0200
parents 2db4d2b362e6
children 92ace1ca50a8
files ide/ide/codeeditor.py ide/ide/ide.py ide/project.py ide/runtests.py testproject/main.mod testproject/test.lcp testproject/test.mod
diffstat 7 files changed, 174 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/ide/ide/codeeditor.py	Sat Oct 15 10:03:21 2011 +0200
+++ b/ide/ide/codeeditor.py	Fri Oct 21 17:36:57 2011 +0200
@@ -62,10 +62,11 @@
 
    def loadFile(self, filename):
       self.filename = filename
-      f = open(filename, 'r')
-      source = f.read()
-      f.close()
+      with open(filename, 'r') as f:
+         source = f.read()
       self.setPlainText(source)
+      self.setWindowTitle(filename)
+
    def saveFile(self):
       if self.filename:
          source = str(self.toPlainText())
--- a/ide/ide/ide.py	Sat Oct 15 10:03:21 2011 +0200
+++ b/ide/ide/ide.py	Fri Oct 21 17:36:57 2011 +0200
@@ -5,33 +5,7 @@
 from .astviewer import AstViewer
 import base64
 from project import Project
-
-source = """
-module x;
-var 
- a,b,c : integer;
-
-procedure test(x:integer);
- var y,z:integer;
-begin
-  y := x * 3 + 2;
-  z := x + y + a;
-end test;
-
-procedure add(a:integer; b:integer):integer;
- var 
-  tmp : integer;
- begin
-  tmp := a + b;
-  return tmp
- end add;
-
-begin
-  a := 12;
-  b := a * 12 + 33;
-  c := a div b + a * b * 99;
-end x.
-"""
+import os.path
 
 lcfospng = base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A\n/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEhMKBk7B678AAAA/SURBVFjD\n7dbBCQAgDATBi9h/y7EFA4Kf2QLCwH1S6XQu6sqoujublc8BAAAAAAAAAAB8B+zXT6YJAAAAAKYd\nWSgFQNUyijIAAAAASUVORK5CYII=\n')
 
@@ -67,25 +41,48 @@
       self.sigErrorSelected.emit(err)
 
 class ProjectView(QWidget):
+   sigLoadFile = pyqtSignal(str)
    def __init__(self, parent=None):
       super(ProjectView, self).__init__(parent)
       self.treeview = QTreeView(self)
+      self.treeview.setContextMenuPolicy(Qt.CustomContextMenu)
       l = QVBoxLayout(self)
       l.addWidget(self.treeview)
       pm = QPixmap()
       pm.loadFromData(lcfospng)
       self.projectIcon = QIcon(pm)
+      # Connect signals:
+      self.treeview.activated.connect(self.activate)
+      self.treeview.customContextMenuRequested.connect(self.contextMenu)
    def setProject(self, project):
       self.project = project
       model = QStandardItemModel()
       root = model.invisibleRootItem()
       pitem = QStandardItem(self.projectIcon, project.name)
+      pitem.setEditable(False)
+      pitem.setData(project)
       root.appendRow(pitem)
       for f in self.project.files:
          fitem = QStandardItem(f)
          pitem.appendRow(fitem)
+         fitem.setEditable(False)
+         fitem.setData(f)
       self.treeview.setModel(model)
       self.treeview.expandAll()
+   def contextMenu(self, pos):
+      idx = self.treeview.indexAt(pos)
+      if not idx.isValid():
+         return
+      item = self.treeview.model().itemFromIndex(idx)
+      print(item)
+   def activate(self, index):
+      if not index.isValid():
+         return
+      model = self.treeview.model()
+      item = model.itemFromIndex(index)
+      fn = item.data()
+      if type(fn) is str:
+         self.sigLoadFile.emit(fn)
 
 class AboutDialog(QDialog):
    def __init__(self, parent=None):
@@ -106,6 +103,10 @@
       but.clicked.connect(self.close)
       l.addWidget(but)
 
+class ProjectOptions(QDialog):
+   pass
+   # TODO: project options in here
+
 class Ide(QMainWindow):
   def __init__(self, parent=None):
     super(Ide, self).__init__(parent)
@@ -115,13 +116,18 @@
     self.setWindowIcon(QIcon(icon))
 
     # Create menus:
+    self.fileMenu = self.menuBar().addMenu('File')
     self.viewMenu = self.menuBar().addMenu('View')
     self.projectMenu = self.menuBar().addMenu('Project')
     self.helpMenu = self.menuBar().addMenu('Help')
 
+    # Create mdi area:
+    self.mdiArea = QMdiArea()
+    self.setCentralWidget(self.mdiArea)
+
     # Create components:
     self.codeedit = CodeEdit()
-    self.setCentralWidget(self.codeedit)
+    self.mdiArea.addSubWindow(self.codeedit)
 
     self.buildOutput = BuildOutput()
     self.addComponent('Build output', self.buildOutput)
@@ -136,6 +142,7 @@
 
     self.projectview = ProjectView()
     self.addComponent('Project', self.projectview)
+    self.projectview.sigLoadFile.connect(self.loadFile)
 
     # About dialog:
     self.aboutDialog = AboutDialog()
@@ -155,15 +162,27 @@
     self.helpMenu.addAction(self.aboutAction)
     self.aboutAction.triggered.connect(self.aboutDialog.open)
 
-    # END of UI construction
+    self.newFileAction = QAction("New File", self)
+    self.fileMenu.addAction(self.newFileAction)
+    self.newFileAction.triggered.connect(self.newFile)
+    self.saveFileAction = QAction("Save File", self)
+    self.fileMenu.addAction(self.saveFileAction)
+    self.saveFileAction.triggered.connect(self.saveFile)
+    self.closeFileAction = QAction("Close File", self)
+    self.fileMenu.addAction(self.closeFileAction)
+    self.closeFileAction.triggered.connect(self.closeFile)
+
+    cascadeAction = QAction("Cascade windows", self)
+    cascadeAction.triggered.connect(self.mdiArea.cascadeSubWindows)
+    self.viewMenu.addAction(cascadeAction)
+    tileAction = QAction('Tile windows', self)
+    tileAction.triggered.connect(self.mdiArea.tileSubWindows)
+    self.viewMenu.addAction(tileAction)
 
     # Load settings:
     self.settings = QSettings('windelsoft', 'lcfoside')
     self.loadSettings()
 
-    # Load example source:
-    self.codeedit.setPlainText(source)
-
   def addComponent(self, name, widget):
      dw = QDockWidget(name)
      dw.setWidget(widget)
@@ -171,6 +190,60 @@
      self.addDockWidget(Qt.RightDockWidgetArea, dw)
      self.viewMenu.addAction(dw.toggleViewAction())
 
+  # File handling:
+  def newFile(self):
+     ce = CodeEdit()
+     w = self.mdiArea.addSubWindow(ce)
+     ce.show()
+
+  def saveFile(self):
+     ac = self.activeMdiChild()
+     if ac:
+        print(ac)
+        ac.saveFile()
+
+  def openFile(self):
+     # TODO
+     pass
+
+  def closeFile(self):
+     ac = self.activeMdiChild()
+     if ac:
+        self.mdiArea.removeSubWindow(ac)
+  
+  def loadFile(self, filename):
+     # Find existing mdi widget:
+     wid = self.findMdiChild(filename)
+     if wid:
+        wid.setActiveSubWindow(wid)
+
+     # Create a new one:
+     basedir = os.path.dirname(self.project.filename)
+     filename = os.path.join(basedir, filename)
+
+     ce = CodeEdit()
+     ce.loadFile(filename)
+     self.mdiArea.addSubWindow(ce)
+     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():
+        print(window, window.widget())
+        wid = window.widget()
+        if wid.filename == filename:
+           return wid
+     return None
+        
+  # Settings:
   def loadSettings(self):
      if self.settings.contains('mainwindowstate'):
         self.restoreState(self.settings.value('mainwindowstate'))
@@ -178,11 +251,9 @@
         self.restoreGeometry(self.settings.value('mainwindowgeometry'))
      if self.settings.contains('openedproject'):
         self.projectfile = self.settings.value('openedproject')
-        print(self.projectfile, type(self.projectfile))
         self.loadProject()
      else:
         self.projectfile = ""
-
   
   def closeEvent(self, ev):
      self.settings.setValue('mainwindowstate', self.saveState())
@@ -191,6 +262,7 @@
      self.codeedit.saveFile()
      ev.accept()
 
+  # Error handling:
   def nodeSelected(self, node):
       if node.location:
          row, col = node.location
@@ -202,6 +274,7 @@
      row, col, msg = err
      self.codeedit.highlightErrorLocation(row, col)
 
+  # Project loading:
   def loadProject(self):
      if self.projectfile:
         self.project = Project()
@@ -212,6 +285,7 @@
      self.projectfile = QFileDialog.getOpenFileName(self, "Choose project file", "", "lcfos Project files (*.lcp)")
      self.loadProject()
 
+  # Build recepy:
   def buildFile(self):
      self.buildOutput.clear()
      self.codeedit.clearErrors()
@@ -225,4 +299,3 @@
      else:
         self.buildOutput.append("Done!")
 
-
--- a/ide/project.py	Sat Oct 15 10:03:21 2011 +0200
+++ b/ide/project.py	Fri Oct 21 17:36:57 2011 +0200
@@ -26,6 +26,7 @@
       self.name = ""
       self.files = []
       self.settings = {}
+      self.filename = ""
 
    def save(self, filename):
       """ Save the project in XML format """
@@ -53,6 +54,8 @@
       """ Load the project from the XML file """
       if not os.path.exists(filename):
          return
+      self.filename = filename
+      print(self.filename)
       parser = make_parser()
       handler = ProjectContentHandler(self)
       parser.setContentHandler(handler)
--- a/ide/runtests.py	Sat Oct 15 10:03:21 2011 +0200
+++ b/ide/runtests.py	Fri Oct 21 17:36:57 2011 +0200
@@ -1,4 +1,5 @@
 import unittest
+import os
 
 from compiler.compiler import Compiler
 from compiler.errors import CompilerException, printError
@@ -265,6 +266,7 @@
       assert(p.name == q.name)
       assert(p.files == q.files)
       # TODO: remove test.xml test file
+      os.remove('test.xml')
 
 if __name__ == '__main__':
    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testproject/main.mod	Fri Oct 21 17:36:57 2011 +0200
@@ -0,0 +1,25 @@
+module main;
+var 
+ a,b,c : integer;
+
+procedure test(x:integer);
+ var y,z:integer;
+begin
+  y := x * 3 + 2;
+  z := x + y + a;
+end test;
+
+procedure add(a:integer; b:integer):integer;
+ var 
+  tmp : integer;
+ begin
+  tmp := a + b;
+  return tmp
+ end add;
+
+begin
+  a := 12;
+  b := a * 12 + 33;
+  c := a div b + a * b * 99;
+end main.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testproject/test.lcp	Fri Oct 21 17:36:57 2011 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0" ?>
+<Project name="Test project">
+	<Files>
+		<File Filename="main.mod"/>
+		<File Filename="test.mod"/>
+	</Files>
+</Project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testproject/test.mod	Fri Oct 21 17:36:57 2011 +0200
@@ -0,0 +1,25 @@
+module test;
+var 
+ a,b,c : integer;
+
+procedure test(x:integer);
+ var y,z:integer;
+begin
+  y := x * 3 + 2;
+  z := x + y + a;
+end test;
+
+procedure add(a:integer; b:integer):integer;
+ var 
+  tmp : integer;
+ begin
+  tmp := a + b;
+  return tmp
+ end add;
+
+begin
+  a := 12;
+  b := a * 12 + 33;
+  c := a div b + a * b * 99;
+end test.
+