diff -r 704593d042fe -r 4b99609f6a87 Graphics/UMLDialog.py --- a/Graphics/UMLDialog.py Sun Sep 09 17:46:32 2012 +0200 +++ b/Graphics/UMLDialog.py Sun Sep 09 19:38:07 2012 +0200 @@ -7,9 +7,11 @@ Module implementing a dialog showing UML like diagrams. """ -from PyQt4.QtCore import Qt +from PyQt4.QtCore import Qt, QFileInfo from PyQt4.QtGui import QMainWindow, QAction, QToolBar, QGraphicsScene +from E5Gui import E5MessageBox, E5FileDialog + from .UMLGraphicsView import UMLGraphicsView import UI.Config @@ -25,7 +27,8 @@ ImportsDiagram = 2 ApplicationDiagram = 3 - def __init__(self, diagramType, project, path, parent=None, **kwargs): + def __init__(self, diagramType, project, path="", parent=None, initBuilder=True, + **kwargs): """ Constructor @@ -33,33 +36,86 @@ (one of ApplicationDiagram, ClassDiagram, ImportsDiagram, PackageDiagram) @param project reference to the project object (Project) @param path file or directory path to build the diagram from (string) - @param parent parent widget of the view (QWidget) + @param parent parent widget of the dialog (QWidget) + @keyparam initBuilder flag indicating to initialize the diagram builder (boolean) @param kwargs diagram specific data """ super().__init__(parent) self.setObjectName("UMLDialog") + self.__diagramType = diagramType + self.scene = QGraphicsScene(0.0, 0.0, 800.0, 600.0) - self.umlView = UMLGraphicsView(self.scene, diagramType, parent=self) - self.builder = self.__diagramBuilder(diagramType, project, path, **kwargs) + self.umlView = UMLGraphicsView(self.scene, parent=self) + self.builder = self.__diagramBuilder(self.__diagramType, project, path, **kwargs) + if initBuilder: + self.builder.initialize() + + self.__fileName = "" + self.__initActions() + self.__initToolBars() + + self.setCentralWidget(self.umlView) + + self.umlView.relayout.connect(self.__relayout) + + def __initActions(self): + """ + Private slot to initialize the actions. + """ self.closeAct = \ QAction(UI.PixmapCache.getIcon("close.png"), self.trUtf8("Close"), self) self.closeAct.triggered[()].connect(self.close) + self.saveAct = \ + QAction(UI.PixmapCache.getIcon("fileSave.png"), + self.trUtf8("Save"), self) + self.saveAct.triggered[()].connect(self.__save) + + self.saveAsAct = \ + QAction(UI.PixmapCache.getIcon("fileSaveAs.png"), + self.trUtf8("Save As..."), self) + self.saveAsAct.triggered[()].connect(self.__saveAs) + + self.saveImageAct = \ + QAction(UI.PixmapCache.getIcon("fileSavePixmap.png"), + self.trUtf8("Save as PNG"), self) + self.saveImageAct.triggered[()].connect(self.umlView.saveImage) + + self.printAct = \ + QAction(UI.PixmapCache.getIcon("print.png"), + self.trUtf8("Print"), self) + self.printAct.triggered[()].connect(self.umlView.printDiagram) + + self.printPreviewAct = \ + QAction(UI.PixmapCache.getIcon("printPreview.png"), + self.trUtf8("Print Preview"), self) + self.printPreviewAct.triggered[()].connect(self.umlView.printPreviewDiagram) + + def __initToolBars(self): + """ + Private slot to initialize the toolbars. + """ self.windowToolBar = QToolBar(self.trUtf8("Window"), self) self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) self.windowToolBar.addAction(self.closeAct) + self.fileToolBar = QToolBar(self.trUtf8("File"), self) + self.fileToolBar.setIconSize(UI.Config.ToolBarIconSize) + self.fileToolBar.addAction(self.saveAct) + self.fileToolBar.addAction(self.saveAsAct) + self.fileToolBar.addAction(self.saveImageAct) + self.fileToolBar.addSeparator() + self.fileToolBar.addAction(self.printPreviewAct) + self.fileToolBar.addAction(self.printAct) + self.umlToolBar = self.umlView.initToolBar() + self.addToolBar(Qt.TopToolBarArea, self.fileToolBar) self.addToolBar(Qt.TopToolBarArea, self.windowToolBar) self.addToolBar(Qt.TopToolBarArea, self.umlToolBar) - - self.setCentralWidget(self.umlView) - - self.umlView.relayout.connect(self.__relayout) def show(self): """ @@ -100,21 +156,91 @@ raise ValueError( self.trUtf8("Illegal diagram type '{0}' given.").format(diagramType)) - def diagramTypeToString(self, diagramType): + def __diagramTypeString(self): """ - Public method to convert the diagram type to a readable string. + Private method to generate a readable string for the diagram type. - @param diagramType type of the diagram - (one of ApplicationDiagram, ClassDiagram, ImportsDiagram, PackageDiagram) @return readable type string (string) """ - if diagramType == UMLDialog.ClassDiagram: + if self.__diagramType == UMLDialog.ClassDiagram: return "Class Diagram" - elif diagramType == UMLDialog.PackageDiagram: + elif self.__diagramType == UMLDialog.PackageDiagram: return "Package Diagram" - elif diagramType == UMLDialog.ImportsDiagram: + elif self.__diagramType == UMLDialog.ImportsDiagram: return "Imports Diagram" - elif diagramType == UMLDialog.ApplicationDiagram: + elif self.__diagramType == UMLDialog.ApplicationDiagram: return "Application Diagram" else: return "Illegal Diagram Type" + + def __save(self): + """ + Private slot to save the diagram with the current name. + """ + self.__saveAs(self.__fileName) + + def __saveAs(self, filename=""): + """ + Private slot to save the diagram. + + @param filename name of the file to write to (string) + """ + if not filename: + fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( + self, + self.trUtf8("Save Diagram"), + "", + self.trUtf8("Eric5 Graphics File (*.e5g);;All Files (*)"), + "", + E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) + if not fname: + return + ext = QFileInfo(fname).suffix() + if not ext: + ex = selectedFilter.split("(*")[1].split(")")[0] + if ex: + fname += ex + if QFileInfo(fname).exists(): + res = E5MessageBox.yesNo(self, + self.trUtf8("Save Diagram"), + self.trUtf8("<p>The file <b>{0}</b> already exists." + " Overwrite it?</p>").format(fname), + icon=E5MessageBox.Warning) + if not res: + return + filename = fname + + lines = [ + "version: 1.0", + "diagram_type: {0} ({1})".format(self.__diagramType, + self.__diagramTypeString()), + "scene_size: {0};{1}".format(self.scene.width(), self.scene.height()), + ] + persistenceData = self.builder.getPersistenceData() + if persistenceData: + lines.append("builder_data: {0}".format(persistenceData)) + lines.extend(self.umlView.getPersistenceData()) + + try: + f = open(filename, "w", encoding="utf-8") + f.write("\n".join(lines)) + f.close() + except (IOError, OSError) as err: + E5MessageBox.critical(self, + self.trUtf8("Save Diagram"), + self.trUtf8("""<p>The file <b>{0}</b> could not be saved.</p>""" + """<p>Reason: {1}</p>""").format(fname, str(err))) + + self.__fileName = filename + + @classmethod + def generateDialogFromFile(cls, project, parent=None): + """ + Class method to generate a dialog reading data from a file. + + @param project reference to the project object (Project) + @param parent parent widget of the dialog (QWidget) + @return generated dialog (UMLDialog) + """ + # TODO: implement this + return None