Skip to content

Commit

Permalink
SessionMainWindow Base class for saving and loading sessions (#67)
Browse files Browse the repository at this point in the history
* Add SessionDialogs and SessionMainWindow, and example, and start work on tests

* Add unit tests for saving and reloading sessions

* Add docstrings and qdarkstyle requirement

* tidy up io

* Add Settings Dialog

* No longer chdir in SessionsMainwindow

* check we arent in current session folder before closing

* Add organisation name param

* addToMenu method and dont use spanning widget

* update session folder path and add example menu to example

* Add example with error in process

* autoformatting

* update signature of ErrorDialog
  • Loading branch information
lauramurgatroyd authored Apr 3, 2023
1 parent a40af04 commit e344b3d
Show file tree
Hide file tree
Showing 12 changed files with 2,303 additions and 366 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
- Adds unit tests to cover: `saveAllWidgetStates`, `restoreAllSavedWidgetStates`, `getAllWidgetStates`, `getWidgetState`, `applyWidgetState`, `applyWidgetStates`
- setup.py:
- Always normalise the version from git describe to pep440
- Adds `SessionsMainWindow.py` - which is a base class for our apps which create a session folder where any files generated in the app are saved, and provides the ability to permanently save and reload sessions.
- Adds `SessionsMainWindow_example.py` - an example of using the SessionsMainWindow - you can run this example, change the state of widgets in the form, save the session, reload the session and see the state of the widgets be restored.
- Adds `SessionsDialogs.py` - the dialogs used by the SessionsMainWindow.py
- Adds `io.py` - contains method for zipping a directory, used by SessionsMainWindow.py
- Adds unit tests to cover `SessionsDialogs.py`, `io.py`, and a large proportion of `SessionsMainWindow.py`

## v0.5.0
* Add getWidgets method to FormWidget, FormDockWidget and FormDialog
Expand Down
1 change: 1 addition & 0 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ requirements:
run:
- python
- pyside2
- qdarkstyle

about:
home: https://github.com/paskino/qt-elements
Expand Down
30 changes: 30 additions & 0 deletions eqt/io.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import os
import zipfile



def zip_directory(directory, compress=True, **kwargs):
'''
Zips a directory, optionally compressing it.
Parameters
----------
directory : str
The directory to be zipped.
compress : bool
Whether to compress the directory.
'''

zipper = zipfile.ZipFile(directory + '.zip', 'a')

if compress:
compress_type = zipfile.ZIP_DEFLATED
else:
compress_type = zipfile.ZIP_STORED

for r, _, f in os.walk(directory):
for _file in f:
filepath = os.path.join(r, _file)
arcname = os.path.relpath(filepath, directory)
zipper.write(filepath, arcname, compress_type=compress_type)
zipper.close()
2 changes: 2 additions & 0 deletions eqt/ui/ProgressTimerDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,7 @@ def close(self):
# running then it continues forever,
# even after the progress window closes.
self.run_cancelled = True
# need to wait for the thread to finish:
self.threadpool.waitForDone()
QProgressDialog.close(self)

180 changes: 180 additions & 0 deletions eqt/ui/SessionDialogs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
from eqt.ui import FormDialog
from PySide2.QtWidgets import (
QCheckBox, QComboBox, QFileDialog, QLabel, QLineEdit, QPushButton, QMessageBox)
from PySide2 import QtWidgets
import os


class SaveSessionDialog(FormDialog):
def __init__(self, parent=None, title="Save Session"):
'''
A dialog to save a session. Prompts the user for a name for the session, and whether to compress the files.
Parameters
----------
parent : QWidget
The parent widget.
title : str
The title of the dialog.
'''

FormDialog.__init__(self, parent, title)
self.parent = parent

qlabel = QLabel(self.groupBox)
qlabel.setText("Save session as:")
qwidget = QLineEdit(self.groupBox)
qwidget.setClearButtonEnabled(True)
# finally add to the form widget
self.addWidget(qwidget, qlabel, 'session_name')

qwidget = QCheckBox(self.groupBox)
qwidget.setText("Compress Files")
qwidget.setEnabled(True)
qwidget.setChecked(False)
self.addSpanningWidget(qwidget, 'compress')

self.Ok.setText('Save')


class SessionDirectorySelectionDialog(FormDialog):
def __init__(self, parent=None, app_name=None):
'''
A dialog to select a directory in which to save and retrieve sessions.
Parameters
----------
parent : QWidget
The parent widget.
app_name : str
The name of the application.
Attributes
----------
selected_dir : str
The selected directory, to be used as the directory in which all sessions are saved.
'''
FormDialog.__init__(self, parent, "Select Session Directory")
self.parent = parent

self.app_name = app_name

if app_name is None:
label_text = 'Select a session directory to save and retrieve all Sessions:'

else:
label_text = f'Select a session directory to save and retrieve all {app_name} Sessions:'

self.addSpanningWidget(QLabel(label_text), 'select_session_directory')

browse_button = QPushButton('Browse')
browse_button.clicked.connect(self.browse_for_dir)
self.addWidget(browse_button, QLabel(
'No directory selected'), 'selected_dir')

self.selected_dir = None

self.Ok.setText('OK')
self.Cancel.setEnabled(False)

def browse_for_dir(self):
dialog = QFileDialog(self.groupBox)
directory = dialog.getExistingDirectory(
self, "Select a Directory to Save the Session to")
self.getWidget('selected_dir', 'label').setText(
os.path.basename(directory))
self.selected_dir = directory


class LoadSessionDialog(FormDialog):
def __init__(self, parent=None, title="Load a Session", location_of_session_files="."):
'''
A dialog to load a session. Prompts the user to select a session from a list of available sessions.
Parameters
----------
parent : QWidget
The parent widget.
title : str
The title of the dialog.
location_of_session_files : str
The directory in which to look for session files.
'''
FormDialog.__init__(self, parent, title)
self.parent = parent

select_dir_button = QPushButton(
'Select Directory for Loading Sessions')
self.buttonBox.addButton(
select_dir_button, QtWidgets.QDialogButtonBox.ActionRole)
self.Select = select_dir_button

self.addSpanningWidget(QLabel('Load a Session'), 'load_title')

location_of_session_files = os.path.abspath(location_of_session_files)

self.addSpanningWidget(QLabel(
f'Currently loading sessions from: {location_of_session_files}'), 'sessions_directory')

combo = QComboBox(self.groupBox)
self.addWidget(combo, 'Select a session:', 'select_session')

self.Ok.setText('Load')
self.Cancel.setText('New Session')


class WarningDialog(QMessageBox):
def __init__(self, parent=None, window_title=None, message=None, detailed_text=None):
'''
A dialog to display a warning message.
Parameters
----------
parent : QWidget
The parent widget.
window_title : str
The title of the dialog.
message : str
The message to display.
detailed_text : str
The detailed text to display.
'''
QMessageBox.__init__(self, parent)
self.setIcon(QMessageBox.Information)
self.setText(message)
self.setWindowTitle(window_title)
self.setDetailedText(detailed_text)


class ErrorDialog(QMessageBox):
def __init__(self, parent=None, window_title=None, message=None, detailed_text=None):
'''
A dialog to display an error message.
The icon is a red circle with a white X.
Parameters
----------
parent : QWidget
The parent widget.
window_title : str
The title of the dialog.
message : str
The message to display.
detailed_text : str
The detailed text to display.
'''
QMessageBox.__init__(self, parent)
self.setIcon(QMessageBox.Critical)
self.setText(message)
self.setWindowTitle(window_title)
self.setDetailedText(detailed_text)


class AppSettingsDialog(FormDialog):

def __init__(self, parent=None):
super(AppSettingsDialog, self).__init__(parent)
self.setWindowTitle("App Settings")
dark_checkbox = QCheckBox("Dark Mode")
self.addSpanningWidget(dark_checkbox, 'dark_checkbox')
self.Ok.setText("Save")
Loading

0 comments on commit e344b3d

Please sign in to comment.