Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added open recent functionality #551

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions trnsysGUI/diagram/Editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def __init__(self, parent, projectFolder, jsonPath, loadValue, logger):
self.projectFolder = projectFolder

self.diagramName = os.path.split(self.projectFolder)[-1] + ".json"
self.diagramPath = os.path.join(self.projectFolder, self.diagramName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this refactoring choice, as it may lead to incremental improvements.

self.saveAsPath = _pl.Path()
self.idGen = IdGenerator()

Expand Down Expand Up @@ -809,9 +810,8 @@ def save(self, showWarning=True):

"""
self.diagramName = os.path.split(self.projectFolder)[-1] + ".json"
diagramPath = os.path.join(self.projectFolder, self.diagramName)

if os.path.isfile(diagramPath) and showWarning:
if os.path.isfile(self.diagramPath) and showWarning:
qmb = _qtw.QMessageBox(self)
qmb.setText("Warning: " + "This diagram name exists already. Do you want to overwrite or cancel?")
qmb.setStandardButtons(_qtw.QMessageBox.Save | _qtw.QMessageBox.Cancel)
Expand All @@ -823,13 +823,13 @@ def save(self, showWarning=True):
return

self.logger.info("Overwriting")
self.encodeDiagram(diagramPath)
self.encodeDiagram(self.diagramPath)

self.encodeDiagram(diagramPath)
self.encodeDiagram(self.diagramPath)
if showWarning:
msgb = _qtw.QMessageBox()
msgb.setWindowTitle("Saved successfully")
msgb.setText("Saved diagram at " + diagramPath)
msgb.setText("Saved diagram at " + self.diagramPath)
msgb.setStandardButtons(_qtw.QMessageBox.Ok)
msgb.setDefaultButton(_qtw.QMessageBox.Ok)
msgb.exec()
Expand Down
26 changes: 26 additions & 0 deletions trnsysGUI/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from trnsysGUI.MassFlowVisualizer import MassFlowVisualizer
from trnsysGUI.ProcessMain import ProcessMain
from trnsysGUI.RunMain import RunMain
from trnsysGUI.userSettings import UserSettings
from trnsysGUI.common import cancelled as _ccl
from trnsysGUI.diagram import Editor as _de
from trnsysGUI.storageTank.widget import StorageTank
Expand Down Expand Up @@ -130,6 +131,10 @@ def __init__(self, logger, project: _prj.Project, parent=None):
fileMenuOpenAction.setShortcut("Ctrl+o")
self.fileMenu.addAction(fileMenuOpenAction)

fileMenuOpenRecentAction = _qtw.QAction("Open Recent", self)
fileMenuOpenRecentAction.triggered.connect(self.openRecentFile)
self.fileMenu.addAction(fileMenuOpenRecentAction)

fileMenuSaveAction = _qtw.QAction("Save", self)
fileMenuSaveAction.triggered.connect(self.saveDia)
fileMenuSaveAction.setShortcut("Ctrl+s")
Expand Down Expand Up @@ -256,6 +261,7 @@ def newDia(self):
createProjectMaybeCancelled = _prj.getCreateProject(startingDirectoryPath)
if _ccl.isCancelled(createProjectMaybeCancelled):
return
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
createProject = _ccl.value(createProjectMaybeCancelled)

self._resetEditor(createProject)
Expand Down Expand Up @@ -466,13 +472,30 @@ def openFile(self):
maybeCancelled = _prj.getLoadOrMigrateProject()
if _ccl.isCancelled(maybeCancelled):
return
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
project = _ccl.value(maybeCancelled)

self._resetEditor(project)

if isinstance(project, _prj.MigrateProject):
self.editor.save()

def openRecentFile(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like duplication of the usual functionality when opening another project.
Can this be integrated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not exactly, we can defintely extract message box

qmb = _qtw.QMessageBox()
qmb.setText("Are you sure you want to open another project? Unsaved progress on the current one will be lost.")
qmb.setStandardButtons(_qtw.QMessageBox.Yes | _qtw.QMessageBox.Cancel)
qmb.setDefaultButton(_qtw.QMessageBox.Cancel)
ret = qmb.exec()

if ret == _qtw.QMessageBox.Cancel:
return
maybeCancelled = _prj.loadRecentProject()
if _ccl.isCancelled(maybeCancelled):
return
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
project = _ccl.value(maybeCancelled)
self._resetEditor(project)

def _resetEditor(self, project):
wasRunning = self.editor and self.editor.isRunning()

Expand Down Expand Up @@ -577,11 +600,14 @@ def closeEvent(self, e):
if ret == _qtw.QMessageBox.Cancel:
e.ignore()
elif ret == _qtw.QMessageBox.Close:
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
e.accept()
elif ret == _qtw.QMessageBox.Save:
self.editor.save()
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
e.accept()
else:
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved
UserSettings.setRecentProjectJsonPath(self.editor.diagramPath)
e.accept()

def ensureSettingsExist(self):
Expand Down
45 changes: 35 additions & 10 deletions trnsysGUI/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import PyQt5.QtWidgets as _qtw

import trnsysGUI.common.cancelled as _ccl
from trnsysGUI.userSettings import UserSettings


@_dc.dataclass
Expand Down Expand Up @@ -56,17 +57,19 @@ def getProject() -> _ccl.MaybeCancelled[Project]:
class _CreateNewOrOpenExisting(_enum.Enum):
CREATE_NEW = _enum.auto()
OPEN_EXISTING = _enum.auto()
OPEN_RECENT = _enum.auto()


def _askUserWhetherToCreateNewProjectOrOpenExisting() -> _ccl.MaybeCancelled[_CreateNewOrOpenExisting]:
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved
messageBox = _qtw.QMessageBox()
messageBox.setWindowTitle("Start a new or open an existing project")
messageBox.setText("Do you want to start a new project or open an existing one?")

recentButton = _qtw.QPushButton("Recent")
createButton = _qtw.QPushButton("New")
openButton = _qtw.QPushButton("Open")
messageBox.addButton(createButton, _qtw.QMessageBox.YesRole)
messageBox.addButton(openButton, _qtw.QMessageBox.NoRole)
messageBox.addButton(recentButton, _qtw.QMessageBox.NoRole)
messageBox.addButton(_qtw.QMessageBox.Cancel)
messageBox.setFocus()
messageBox.exec()
Expand All @@ -83,6 +86,9 @@ def _askUserWhetherToCreateNewProjectOrOpenExisting() -> _ccl.MaybeCancelled[_Cr
if clickedButton is openButton:
return _CreateNewOrOpenExisting.OPEN_EXISTING

if clickedButton is recentButton:
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved
return _CreateNewOrOpenExisting.OPEN_RECENT

raise AssertionError("Unknown button was clicked.")


Expand All @@ -93,6 +99,9 @@ def _getProjectInternal(createOrOpenExisting: "_CreateNewOrOpenExisting") -> _cc
if createOrOpenExisting == _CreateNewOrOpenExisting.CREATE_NEW:
return getCreateProject()

if createOrOpenExisting == _CreateNewOrOpenExisting.OPEN_RECENT:
return loadRecentProject()

raise AssertionError(f"Unknown value for enum {_CreateNewOrOpenExisting}: {createOrOpenExisting}")


Expand Down Expand Up @@ -132,11 +141,8 @@ def getExistingEmptyDirectory(
def _isEmptyDirectory(path: _pl.Path) -> bool:
if not path.is_dir():
return False

containedFilesAndDirectories = list(path.iterdir())

isDirectoryEmpty = len(containedFilesAndDirectories) == 0

return isDirectoryEmpty


Expand All @@ -145,15 +151,37 @@ def getLoadOrMigrateProject() -> _ccl.MaybeCancelled[LoadProject | MigrateProjec
if not projectFolderPathString:
return _ccl.CANCELLED
jsonFilePath = _pl.Path(projectFolderPathString)

projectFolderPath = jsonFilePath.parent
return checkIfProjectEnviromentIsValid(projectFolderPath, jsonFilePath)


def loadRecentProject() -> _ccl.MaybeCancelled[LoadProject | MigrateProject]:
messageBox = _qtw.QMessageBox()
messageBox.setStandardButtons(_qtw.QMessageBox.Ok)
try:
recentProjectJsonPath = _pl.Path(UserSettings.getRecentProjectJsonPath())
if not recentProjectJsonPath.exists():
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved
messageBox.setText("Recent project has moved or was deleted")
result = messageBox.exec()
if result == _qtw.QMessageBox.Ok:
return _ccl.CANCELLED
else:
return checkIfProjectEnviromentIsValid(recentProjectJsonPath.parent, recentProjectJsonPath)
except TypeError:
messageBox.setText("No recent project available")
result = messageBox.exec()
if result == _qtw.QMessageBox.Ok:
return _ccl.CANCELLED
return _ccl.CANCELLED

sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved

def checkIfProjectEnviromentIsValid(
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved
projectFolderPath, jsonFilePath
) -> _ccl.MaybeCancelled[LoadProject | MigrateProject]:
containingFolderIsCalledSameAsJsonFile = projectFolderPath.name == jsonFilePath.stem
ddckFolder = projectFolderPath / "ddck"

if not containingFolderIsCalledSameAsJsonFile or not ddckFolder.is_dir():
oldJsonFilePath = jsonFilePath

messageBox = _qtw.QMessageBox()
messageBox.setText(
"The json you are opening does not have a proper project folder environment. "
Expand All @@ -164,12 +192,9 @@ def getLoadOrMigrateProject() -> _ccl.MaybeCancelled[LoadProject | MigrateProjec
result = messageBox.exec()
if result == _qtw.QMessageBox.Cancel:
return _ccl.CANCELLED

maybeCancelled = getExistingEmptyDirectory(startingDirectoryPath=projectFolderPath.parent)
if _ccl.isCancelled(maybeCancelled):
return _ccl.CANCELLED
newProjectFolderPath = _ccl.value(maybeCancelled)

return MigrateProject(oldJsonFilePath, newProjectFolderPath)

return LoadProject(jsonFilePath)
17 changes: 17 additions & 0 deletions trnsysGUI/userSettings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import pathlib as _pl
from PyQt5.QtCore import QSettings # pylint: disable=invalid-name


class UserSettings:

_SETTINGS = QSettings("SPF", "pytrnsys")
sebastian-swob marked this conversation as resolved.
Show resolved Hide resolved

@staticmethod
def setRecentProjectJsonPath(jsonFilePath: _pl.Path) -> None:
jsonFilePath = _pl.Path(jsonFilePath)
if jsonFilePath.exists():
UserSettings._SETTINGS.setValue("recentProject", jsonFilePath)

@staticmethod
def getRecentProjectJsonPath() -> _pl.Path:
return UserSettings._SETTINGS.value("recentProject")
Loading