Ejemplo n.º 1
0
    def setDefaults(self):
        """
        Setup parts of the application that have some sort of default.
        Intended to be used when creating a new project to reset the application
        to a blank slate.
        """
        
        # Remove or hide any windows
        subWindows = self.ui.workspace.subWindowList()

        for window in subWindows:
            if type(window).__name__ in ["DataTableSubWindow", "FigureSubWindow"]:
                window.setAttribute(Qt.WA_DeleteOnClose)
                window.close()
            else:
                window.setVisible(False)

        # Remove signals
        try:
            self.waves().waveAdded.disconnect(self.model('appWaves').appendRow)
        except:
            pass
        try:
            self.waves().allWavesRemoved.disconnect(self.model('appWaves').removeAllWaves)
        except:
            pass

        # Set variables
        self._waves = Waves()
        self._figures = Figures()
        self._models = {}
        self.projectDir = "" # current project directory
        self.setCurrentProject("")
        self._storedSettings = {}   # this is a dict with widgetName: list pairs
                                    # where each list has [setting-name, setting-value] pairs
                                    # setting-value is a dict with (property-name: Property) pairs

        # Load Preferences
        Util.debug(2, "App", "Loading Preferences from file")
        self.preferences = Preferences("~/.pysciplotrc")

        # Create application-wide models
        self._models['appWaves'] = WavesListModel(self.waves().waveNames())

        # Signals
        self.waves().waveAdded.connect(self.model('appWaves').appendRow)
        self.waves().allWavesRemoved.connect(self.model('appWaves').removeAllWaves)

        # Reload modules
        for module in self._loadedModules.values():
            module.reload()
Ejemplo n.º 2
0
class Pysciplot(QMainWindow):
    """
    This class initializes the PySciPlot program.
    """

    def __init__(self):
        QMainWindow.__init__(self)
        Util.debug(2, "App", "Setting up UI")
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
    
    def setup(self):
        """
        Setup the application.
        """

        # Variables
        Util.debug(2, "App", "Initializing variables")
        self._version = 1
        self._loadedModules = {}

        self.setDefaults()

        # Let the workspace resize when the main window is resized
        self.setCentralWidget(self.ui.workspace)

        # Make signal/slot connections
        Util.debug(2, "App", "Connecting signals and slots")
        self.ui.actionQuit.triggered.connect(self.close)
        self.ui.actionNew_Project.triggered.connect(self.newProjectSlot)
        self.ui.actionLoad_Project.triggered.connect(self.loadProjectSlot)
        self.ui.actionSave_Project.triggered.connect(self.saveProject)
        self.ui.actionSave_Project_As.triggered.connect(self.saveProjectAs)
        self.ui.actionSave_Current_Figure.triggered.connect(self.saveCurrentFigure)
        self.ui.actionPreferences.triggered.connect(self.preferences.showDialog)

        self.ui.actionShow_Waves.triggered.connect(self.printAllWaves)
        self.ui.actionShow_Figures.triggered.connect(self.printAllFigures)

        Util.debug(2, "App", "Loading modules")
        for moduleName in modules.__all__:
            module = eval(moduleName + "." + moduleName + "()")
            module.load()
            self._loadedModules[moduleName] = module

    def setDefaults(self):
        """
        Setup parts of the application that have some sort of default.
        Intended to be used when creating a new project to reset the application
        to a blank slate.
        """
        
        # Remove or hide any windows
        subWindows = self.ui.workspace.subWindowList()

        for window in subWindows:
            if type(window).__name__ in ["DataTableSubWindow", "FigureSubWindow"]:
                window.setAttribute(Qt.WA_DeleteOnClose)
                window.close()
            else:
                window.setVisible(False)

        # Remove signals
        try:
            self.waves().waveAdded.disconnect(self.model('appWaves').appendRow)
        except:
            pass
        try:
            self.waves().allWavesRemoved.disconnect(self.model('appWaves').removeAllWaves)
        except:
            pass

        # Set variables
        self._waves = Waves()
        self._figures = Figures()
        self._models = {}
        self.projectDir = "" # current project directory
        self.setCurrentProject("")
        self._storedSettings = {}   # this is a dict with widgetName: list pairs
                                    # where each list has [setting-name, setting-value] pairs
                                    # setting-value is a dict with (property-name: Property) pairs

        # Load Preferences
        Util.debug(2, "App", "Loading Preferences from file")
        self.preferences = Preferences("~/.pysciplotrc")

        # Create application-wide models
        self._models['appWaves'] = WavesListModel(self.waves().waveNames())

        # Signals
        self.waves().waveAdded.connect(self.model('appWaves').appendRow)
        self.waves().allWavesRemoved.connect(self.model('appWaves').removeAllWaves)

        # Reload modules
        for module in self._loadedModules.values():
            module.reload()

    def waves(self):
        """
        Return the app's Waves object.  NOT A LIST OF WAVES.
        """
        return self._waves

    def figures(self):
        """
        Return the app's Figures object.  NOT A LIST OF FIGURES.
        """
        return self._figures

    def storedSettings(self):
        """
        Return the storedSettings dict.
        """
        return self._storedSettings
    
    def models(self):
        """
        Return the models dict.
        """
        return self._models

    def model(self, name):
        """
        Return a specific model from the models dict.
        """
        return self._models[name]

    def createTable(self, waves=[], tableName="Table"):
        """
        Create a table.
        """

        Util.debug(2, "App.createTable", "Creating a table")
        model = DataTableModel(waves, self)

        # Connect slots
        self.waves().waveRemoved[Wave].connect(model.removeWave)
        self.waves().allWavesRemoved.connect(model.removeAllWaves)

        return self.createDataTableView(model, tableName)

    def createDataTableView(self, tableModel, tableName="Table"):
        """
        Create a table view based on the given model.
        """

        tableViewSubWindow = DataTableSubWindow(self.ui.workspace)
        tableView = QDataTableView(tableModel, tableName, tableViewSubWindow)
        tableViewSubWindow.setWidget(tableView)
        tableViewSubWindow.setAttribute(Qt.WA_DeleteOnClose)
        tableViewSubWindow.resize(600, 300)
        self.ui.workspace.addSubWindow(tableViewSubWindow)

        tableViewSubWindow.setVisible(True)

        return tableViewSubWindow

    def saveProjectAs(self):
        """
        Save the current project to a file which will be selected by the user.
        """

        Util.debug(2, "App.saveProjectAs", "Saving project as")
        
        fileName = str(QFileDialog.getSaveFileName(self.ui.workspace, "Save Project", self.projectDirectory(), "PySciPlot Project (*.psp);;All Files (*)"))

        Save.writeProjectToFile(self, fileName)

    def saveProject(self):
        """
        Save the current project to a file.  If project has previously been saved, use
        that location.
        """

        Util.debug(2, "App.saveProject", "Saving project")
        if self.currentProjectFile != "" and QFile.exists(self.currentProjectFile):
            Save.writeProjectToFile(self, self.currentProjectFile)
        else:
            self.saveProjectAs()

        
    def loadProjectSlot(self):
        """
        Slot to pick up menu selection and run loadProject.  Required because of different parameters.
        """
        self.loadProject()

    def loadProject(self, fileName="", confirmReset=True):
        """
        Load a project from a file which will be selected by the user.
        """

        Util.debug(2, "App.loadProject", "Loading project from file " + str(fileName))
        
        # Reset app to a clean slate
        self.resetToDefaults(confirmReset)
        
        # Now load the project
        if fileName == "":
            fileDialog = QFileDialog(self.ui.workspace, "Load Project")
            fileDialog.setNameFilter("PySciPlot Project (*.psp);;All Files (*)")
            fileDialog.setDefaultSuffix("psp")
            fileDialog.setConfirmOverwrite(False)
            fileDialog.setDirectory(self.projectDirectory())
            fileDialog.setAcceptMode(QFileDialog.AcceptOpen)
            fileDialog.exec_()
            fileName = str(fileDialog.selectedFiles()[0])
    
        Load.loadProjectFromFile(self, fileName)
        
    def newProjectSlot(self):
        """
        Slot to pick up menu selection and create a new project.  Required because of different parameters.
        """
        Util.debug(2, "App.newProject", "Creating new project")        
        self.resetToDefaults(True)

    def resetToDefaults(self, confirm=True):
        """
        Reset the application to the defaults.  At the very least,
        this will delete all waves, tables, and figures.

        Before resetting, this will ask the user if they want to save
        the current project.
        """
        
        Util.debug(2, "App.resetToDefaults", "Resetting application to defaults")
        
        if confirm:
            # Check to see if we want to save the current project
            saveProjectMessage = QMessageBox()
            saveProjectMessage.setText("You are about to load another project.")
            saveProjectMessage.setInformativeText("Do you want to save your current project?")
            saveProjectMessage.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
            saveProjectResponse = saveProjectMessage.exec_()
            if saveProjectResponse == QMessageBox.Save:
                self.saveProject()
            elif saveProjectResponse == QMessageBox.Cancel:
                return

        # Now reset to a clean slate
        self.setDefaults()

    def setCurrentProject(self, fileName):
        Util.debug(3, "App.setCurrentProject", "Setting current project title")
        self.currentProjectFile = fileName
        if fileName != "":
            self.setWindowTitle("PySciPlot - " + fileName)
        else:
            self.setWindowTitle("PySciPlot")

    def projectDirectory(self):
        if os.path.isdir(self.projectDir):
            return self.projectDir
        return self.preferences.getInternal('projectDirectory')

    def saveCurrentFigure(self):
        """
        Save the current figure to a file.

        First we make sure that the active window has a figure in it.
        Then we ask the user for certain options to be set.
        Then we ask for the file to save the figure to.
        Then we save the file.
        """

        Util.debug(2, "App.saveCurrentFigure", "Saving current Figure")

        currentWindow = self.ui.workspace.activeSubWindow()

        # Check if the active window has a figure in it
        if type(currentWindow).__name__ != "FigureSubWindow":
            notFigureMessage = QMessageBox()
            notFigureMessage.setText("The active window is not a figure, so you cannot save it as a figure.")
            notFigureMessage.exec_()
            return False
        
        # Ask user for user-configurable options
        figureOptionsDialog = QDialog()
        figureOptionsUi = Ui_SaveFigureOptionsDialog()
        figureOptionsUi.setupUi(figureOptionsDialog)
        figureOptionsSubWindow = self.ui.workspace.addSubWindow(figureOptionsDialog)
        figureOptionsResult = figureOptionsDialog.exec_()
        figureOptionsSubWindow.close()
        
        dpi = 100
        orientation = "Landscape"

        if figureOptionsResult == QDialog.Accepted:
            dpi = Util.getWidgetValue(figureOptionsUi.dpi)
            orientation = Util.getWidgetValue(figureOptionsUi.orientation)
        else:
            return False
        
        # As user for the filename to save to
        fileName = QFileDialog.getSaveFileName(self.ui.workspace, "Save Figure", self.projectDirectory())

        # Save the figure to the file
        currentWindow.widget().figure.savefig(str(fileName), dpi=dpi, orientation=orientation)


    ######################
    # temporary methods, for testing
    ######################
    def createDefaultTable(self):
        waveNames = self.model('appWaves').orderedWaveNames()
        waves = []
        for waveName in waveNames:
            waves.append(self.waves().wave(waveName))
        return self.createTable(waves)

    def printAllWaves(self):
        print self._waves

    def printAllFigures(self):
        print self._figures

    def setTestData(self):
        self._waves.addWave(Wave("Wave1", "Integer", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
        self._waves.addWave(Wave("Wave2", "Integer", [0, 1, 4, 9, 4, 1, 0, 1, 4, 9]))
        self._waves.addWave(Wave("Wave3", "Integer", [0, 1, 3, 1, 3, 1, 3, 1, 3, 1]))
        self._waves.addWave(Wave("Wave4", "Integer", [4, 3, 2, 1, 0, 1, 2, 3, 4, 5]))