-
Notifications
You must be signed in to change notification settings - Fork 49
Undo project #3995
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
Open
rozyczko
wants to merge
459
commits into
main
Choose a base branch
from
undo_project
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Undo project #3995
Changes from 250 commits
Commits
Show all changes
459 commits
Select commit
Hold shift + click to select a range
baf4bd5
Remvoed shabang.
ac75e4c
Fixed casing.
8dff30d
Unsplit line.
e62d67e
Split import into two lines.
e127495
Looks like a few names didn't change automatically
521d164
Double clicking a unit selects it.
e139150
Added an unload button.
00e6578
Use a horizontal layout.
18c384b
Handle case where there are no more files.
9cd1ac3
Disable table when there's no data.
b21d2de
Handle a unicode decode error.
4c9e490
Set filename label on update.
5f5958d
Reset the label back to original after unload.
03d34ab
For now, ignore the horizontal size hint.
409b4f6
Fixed error that sometimes happens when selecting.
f8e9f52
Disable the button when there's none to unload.
314de06
Set current filename to none when there is none.
d1f222b
Give a window title.
b355f0e
Added a done button.
4a5bfa8
Get the column tuple.
a028ad6
Make this a property.
a7ab5e8
Added exclude lines to match param in dataclass.
def0a6e
Fixed logic error.
43c22b7
Hook up the done button to an event.
c57d86b
Fixed slot connection.
13ab6d3
Ascii dialog is now a dialog not a widget.
ece282f
I don't think these comments are needed anymore.
cbca3af
Changed how the current unit is found.
a05c8fa
Include the selected unit in the options.
c308ee0
Accept when clicking the done button.
fcc9ae1
Need to call items in order to destructure.
bded22a
Just hard code the value.
4758ce5
Fix excluded_lines.
aaf1df4
Keep track of the full path.
a8fb897
Fix the params.
505e143
Load the data instead of printing params only.
a456692
Return the unit not the symbol.
d66f839
Send in an empty dict of metadata for now.
99ea5d4
Added an edit metadata button.
e79f2cc
Bring in the files for the metadata filename gui.
5510c05
Renamed file, and ade it a dialog.
6b4a19d
Forgot to commit new file.
5a5d6ce
Added save button.
8245d65
Hook up the save button to an event.
641e871
Print out the component metadata on success.
0ec32a8
Fixed imports.
c01413b
Add edit metadata button.
b3585b0
Fixed import.
f6d151b
Get filename from self.
598d96d
Created a property for the separator text.
2e174b4
Added a dict for separators.
daa8a1c
Take in initial values for these.
8b999dd
Set the separator field.
1329566
Pass in previous metadata, using defaults.
6917bc5
Selected components should persist.
2764215
Use the actual metadata.
972085c
Add widget for custom metadata entry.
be754d2
Changed name to be more consistent.
dbe0a04
Add a custom entry button to the layout.
1f1a2ee
Use a signal for when the custom button is pressed
a5de73e
Started with the selector widget.
de086fb
Hook up event handlers properly.
4706dfb
Use the generic selector widget.
91ced7b
Init the base class.
162ee2a
Forgot to pass self into layout.
fffac57
Handle when there is no new widget.
8f379b9
Use isinstance.
2763af0
Fixed event handling.
88e2985
Layout not inited properly.
6a59019
Need to delete, and reassign selector widget.
621b330
This line shouldn't be here.
3c509be
Set the title of the metadata dialog.
2d37744
Use separate functions for creating these widgets.
494040d
Use the new function.
84ca5c9
Removed comment that doesn't make sense anymore.
c2a4481
Handle value changes.
60f6c3f
Pass in the new args.
9740063
Fixed typos in comments.
5d7c340
Choose default widget based on current option.
ca46946
Set the field from the already set metadata.
be5de49
Wrong control.
24b9a41
Pass raw_metadata into params.
a95c46d
This should be a TODO comment.
9a19d02
Updated this map with a todo warning.
9ff4d5a
Gonna try a different approach.
09e0759
Fixed bug where not editing metadata wouldn't work
9f4d0de
Strip all of the lines.
f6e4214
First step towards a master metadata dictionary.
256d124
Pass along the master metadata dict.
4cc3a55
Pass in the master metadata.
ff2a170
Changed round a bunch of type hints.
1568867
Master metadata should be the same for all files.
13d82b7
Give the master metadata a default value.
17826bd
This should be type hinted.
3d0d9d2
Remove the metadata dict param.
2dd581e
I think these are the wrong way round.
67be830
Give the master metadata to metadata filename.
a8d6670
Create some classes for metadata.
9acab29
Remove unneeded import.
f67e460
Implemented get_metadata function.
0214d8f
Update metadata function.
a1eb9f4
Add defaults.
1a98295
Implemented add file function.
2b58b9f
Make default_categories not a method.
dc7ed0a
Changed the signature of get metadata.
2a8dea3
Start using the new internal metadata class.
51de209
Need to use factory for defaults.
7e48111
Add a separator field.
663b6ae
Don't need the separator argument anymore.
44e6a4f
Type hint to keep pyright happy.
559c4de
Some more argument fixes.
312e74d
Don't need the separator param.
6d5c3ad
Implemented clear_metadata function.
f9da54e
Component selector uses the new metadata class.
0843a99
Get the filename components in the class itself.
7a704ce
Replicate the behaviour of the old system.
f74aa3d
Updated the clear metadata function.
a7d6664
Update for internal metadata.
e7cbe2c
Use new params.
5fa54f6
Make sure a separator is initialised.
abf84e1
Use the name load file.
fc07e31
Need to add file to metadata when loaded.
a4496b6
Forgot to add these :P
5da7cef
Remove old draw options call.
9b8e4fb
Missing else.
3b55c2a
Pull out the new internal metadata.
5870223
Don't need this comment.
350e813
Take into account this is now a list.
4d8fd9a
Use the replaced class from sasdata.
d505517
Whoops forgot to save these files.
51dda75
Forgot to remove old import.
723e886
Use the new params.
bf25ae3
Send the full file path.
ea6765a
Should only split in metadata class.
d00cb5a
Default separator should be set in dialog.py
58b60b7
Load multiple files at the same time.
033d69f
Updated name to avoid conflict with QT function.
a0a9784
Added type hints.
0014226
Add unparasable lines to warning label.
83f30e5
Take into account the startpos.
3239f18
Update warning label is a function.
65e3e4a
Call new function when its needed.
2086a44
Forgot to save :P
5766718
Fixed how lines are counted.
1319bf0
Try an orange font for this.
cee9027
Type hint to stop pyright from complaining.
fd3953e
Don't pass the CSV if there isn't one.
a3870e2
Separate this into another file.
f74f96d
Fixed a crash when we have > 1000 rows.
5ff7533
Started implementing default units.
20516e8
Use the new preferred units.
76e378b
Add some radios for choosing what to separate on.
133ffb0
Default to using the character.
6fcfdee
Use a separate propety for the expression.
bbeb2da
Split on casing as well.
255cbc9
Use new constant for casing regex.
7cc1530
Try hooking up to this event.
8cd3b91
We should probably use our internal split function.
378e791
Fixed regex.
e6d713b
Was using the wrong event.
268ae43
Changed where options is generated.
c36b2fe
Need to set this earlier to stop the event firing
91dbcb5
This shouldn't be here anymore.
4f49df2
These functions aren't needed anymore.
dfbe18c
Update the separator before updating stuff.
e78c89d
Call purge unreachable on separator update.
3b50828
Disable the separator box if casing is enabled.
308fd0e
Return unformatted if we're using casing separation.
3450780
Fixed error when there are no capital letters.
8cb16c5
Use a property for starting pos.
f9857c4
Update warning on selection/deselection.
650b05f
Add a setter for the current unit.
f8fa870
Make sure units match on uncertanties.
b620a27
Trigger column changed when the unit changes.
6ff1421
Stop event triggering when unit is empty.
333ca8f
Make sure ALL the columns are numbers.
0eee5bf
Use the new init separator method for the metadata.
c4e3ee6
Add dev menu
lucas-wilkins cce2198
Make menu show when config setting made
lucas-wilkins f739db1
Should just be using split line from the reader.
d104f2c
Shouldn't be calling items here.
521c076
Convert to list to make the interpreter happy.
a527bbe
This isn't true anymore.
620e01f
Type hinting to stop linting from complaining.
91a2b42
Changed the params for the new order.
d8beb42
Updated order again.
4f1c916
Changed order yet again.
fade71b
Add logic from starting the ascii reader from dev.
jamescrake-merani 5d34467
Don't use relative module paths.
jamescrake-merani df4ce6f
Got rid of filename label, and move edit metadata.
jamescrake-merani 5a1506c
Rename load file to select file.
jamescrake-merani 603ad77
Add a cancel button.
jamescrake-merani 67a7c1d
Disbale units when column is ignored.
jamescrake-merani 9765f47
Centre the checkbox and remove label.
jamescrake-merani af0a3ef
Try this for clearer.
jamescrake-merani 4c528f6
Maybe lets just empty the message.
jamescrake-merani 79c8b22
Implement set checked method as well.
jamescrake-merani 29a8d3b
Didn't call method properly.
jamescrake-merani c1346ff
Add type hinting here.
jamescrake-merani f1189ea
Try this for resetting the foreground color.
jamescrake-merani dec8dc7
Fixed import.
jamescrake-merani 7e2bfa4
Use Lucas' mode idea for the column count.
jamescrake-merani 557dc00
Put unload, and the filename on same line.
jamescrake-merani b32509b
Changed the bottom row.
jamescrake-merani 8e14c28
Fixed indentation mistake in guess.
jamescrake-merani 1fc3d3c
Changed how symbols are ignored.
jamescrake-merani 0c9fdc3
Add pluses to the symbols.
jamescrake-merani 6507aab
SasData should keep the metadata categories.
jamescrake-merani b37f8bb
Updated units.
d4c4386
Remove this comment.
2e8e9b6
Remove fixme comment.
2be801f
Try this?
8474a58
Making casing consistent.
9ec2cce
Remove guess from the SasView repository.
f184ebc
Update import.
135ad2b
Init should probably be at the top.
c02e482
Move this logic into SasData.
f5dae93
Removed the old import.
68b3b95
Import the right function.
5504112
Handle ignored columns.
323fa23
Fixed crashes when a filename just using casing.
0e7379f
Removed unneeded emit call.
9e1d09c
Use the bidrectional pairings.
9fbcd3e
Fixes linting errors
DrPaulSharp 20592d5
Fixes build
DrPaulSharp 0ec38a1
initial commit
rozyczko e2e5f91
integration into FittingWidget
rozyczko cdf76de
added test for integration
rozyczko 1963078
connect ui to the operations in the fitting tabs
rozyczko 8aadce3
added tab to the preferences for undo depth parameter
rozyczko 765b52e
ruff
rozyczko 1879104
more ruff
rozyczko 961143a
fixed for unnecessary undo firing on model load
rozyczko 6dbabb1
Merge branch 'refactor_24' into undo_project
rozyczko 791b08a
Merge branch 'main' into undo_project
rozyczko 1f32c1a
added other perspectives
rozyczko fe5cd36
ruff
rozyczko b407d6f
minor fixes
rozyczko 64c9878
more fixes
rozyczko 6b6c0b3
fixed unit tests
rozyczko 84a80fc
fixed another test
rozyczko a8322b0
minor fixes
rozyczko 42dbc22
Merge branch 'main' into undo_project
rozyczko 8dac130
added docs on undo/redo
rozyczko a0cd45a
PR review
rozyczko 72f5aa7
fixes for corfunc and batch fitting
rozyczko 9f48b31
reparent with main branch of sasdata
rozyczko 25dec3e
added undo of the fitting, as implemented in undo_redo_24
rozyczko 2374401
fixed PR comments
rozyczko b940a9f
fixes broken Undo contract for ParameterValueCommand and ParameterMin…
rozyczko File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| from typing import cast | ||
|
|
||
| from PySide6.QtCore import Signal, Slot | ||
| from PySide6.QtWidgets import QHBoxLayout, QWidget | ||
|
|
||
| from sasdata.ascii_reader_metadata import bidirectional_pairings | ||
| from sasdata.quantities.units import NamedUnit | ||
|
|
||
| from ascii_dialog.column_unit import ColumnUnit | ||
|
|
||
|
|
||
| class ColEditor(QWidget): | ||
| """An editor widget which allows the user to specify the columns of the data | ||
| from a set of options based on which dataset type has been selected.""" | ||
| column_changed = Signal() | ||
|
|
||
| def __init__(self, cols: int, options: list[str]): | ||
| super().__init__() | ||
|
|
||
| self.cols = cols | ||
| self.options = options | ||
| self.layout = QHBoxLayout(self) | ||
| self.option_widgets: list[ColumnUnit] = [] | ||
| for _ in range(cols): | ||
| new_widget = ColumnUnit(self.options) | ||
| new_widget.column_changed.connect(self.onColumnUpdate) | ||
| self.layout.addWidget(new_widget) | ||
| self.option_widgets.append(new_widget) | ||
|
|
||
| @Slot() | ||
| def onColumnUpdate(self): | ||
| column_changed = cast(ColumnUnit, self.sender()) | ||
| pairing = bidirectional_pairings.get(column_changed.currentColumn) | ||
| if pairing is not None: | ||
| for col_unit in self.option_widgets: | ||
| # Second condition is important because otherwise, this event will keep being called, and the GUI will | ||
| # go into an infinite loop. | ||
| if col_unit.currentColumn == pairing and col_unit.currentUnit != column_changed.currentUnit: | ||
| col_unit.currentUnit = column_changed.currentUnit | ||
|
|
||
| def setCols(self, new_cols: int): | ||
| """Set the amount of columns for the user to edit.""" | ||
|
|
||
| # Decides whether we need to extend the current set of combo boxes, or | ||
| # remove some. | ||
| if self.cols < new_cols: | ||
| for _ in range(new_cols - self.cols): | ||
| new_widget = ColumnUnit(self.options) | ||
| new_widget.column_changed.connect(self.onColumnUpdate) | ||
| self.layout.addWidget(new_widget) | ||
| self.option_widgets.append(new_widget) | ||
|
|
||
| self.cols = new_cols | ||
| if self.cols > new_cols: | ||
| excess_cols = self.cols - new_cols | ||
| length = len(self.option_widgets) | ||
| excess_combo_boxes = self.option_widgets[length - excess_cols:length] | ||
| for box in excess_combo_boxes: | ||
| self.layout.removeWidget(box) | ||
| box.setParent(None) | ||
| self.option_widgets = self.option_widgets[0:length - excess_cols] | ||
| self.cols = new_cols | ||
| self.column_changed.emit() | ||
|
|
||
| def setColOrder(self, cols: list[str]): | ||
| """Sets the series of currently selected columns to be cols, in that | ||
| order. If there are not enough column widgets include as many of the | ||
| columns in cols as possible. | ||
|
|
||
| """ | ||
| try: | ||
| for i, col_name in enumerate(cols): | ||
| self.option_widgets[i].setCurrentColumn(col_name) | ||
| except IndexError: | ||
| pass # Can ignore because it means we've run out of widgets. | ||
|
|
||
| def colNames(self) -> list[str]: | ||
| """Get a list of all of the currently selected columns.""" | ||
| return [widget.currentColumn for widget in self.option_widgets] | ||
|
|
||
| @property | ||
| def columns(self) -> list[tuple[str, NamedUnit | None]]: | ||
| return [(widget.currentColumn, widget.currentUnit if widget.currentColumn != "<ignore>" else None) for widget in self.option_widgets] | ||
|
|
||
| def replaceOptions(self, new_options: list[str]) -> None: | ||
| """Replace options from which the user can choose for each column.""" | ||
| self.options = new_options | ||
| for widget in self.option_widgets: | ||
| widget.replaceOptions(new_options) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
| from PySide6.QtCore import Signal, Slot | ||
| from PySide6.QtGui import QRegularExpressionValidator | ||
| from PySide6.QtWidgets import QComboBox, QHBoxLayout, QSizePolicy, QWidget | ||
|
|
||
| from sasdata.dataset_types import unit_kinds | ||
| from sasdata.default_units import defaults_or_fallback | ||
| from sasdata.quantities.units import NamedUnit | ||
|
|
||
| from ascii_dialog.unit_selector import UnitSelector | ||
|
|
||
|
|
||
| def configure_size_policy(combo_box: QComboBox) -> None: | ||
| policy = combo_box.sizePolicy() | ||
| policy.setHorizontalPolicy(QSizePolicy.Policy.Ignored) | ||
| combo_box.setSizePolicy(policy) | ||
|
|
||
| class ColumnUnit(QWidget): | ||
| """Widget with 2 combo boxes: one allowing the user to pick a column, and | ||
| another to specify the units for that column.""" | ||
| def __init__(self, options) -> None: | ||
| super().__init__() | ||
| self.col_widget = self.createColComboBox(options) | ||
| self.unit_widget = self.createUnitComboBox(self.col_widget.currentText()) | ||
| self.layout = QHBoxLayout(self) | ||
| self.layout.addWidget(self.col_widget) | ||
| self.layout.addWidget(self.unit_widget) | ||
| self.current_option: str | ||
|
|
||
| column_changed = Signal() | ||
|
|
||
| def createColComboBox(self, options: list[str]) -> QComboBox: | ||
| """Create the combo box for specifying the column based on the given | ||
| options.""" | ||
| new_combo_box = QComboBox() | ||
| configure_size_policy(new_combo_box) | ||
| for option in options: | ||
| new_combo_box.addItem(option) | ||
| new_combo_box.setEditable(True) | ||
| validator = QRegularExpressionValidator(r"[a-zA-Z0-9]+") | ||
| new_combo_box.setValidator(validator) | ||
| new_combo_box.currentTextChanged.connect(self.onOptionChange) | ||
| return new_combo_box | ||
|
|
||
| def createUnitComboBox(self, selected_option: str) -> QComboBox: | ||
| """Create the combo box for specifying the unit for selected_option""" | ||
| new_combo_box = QComboBox() | ||
| configure_size_policy(new_combo_box) | ||
| new_combo_box.setEditable(True) | ||
| self.updateUnits(new_combo_box, selected_option) | ||
| new_combo_box.currentTextChanged.connect(self.onUnitChange) | ||
| return new_combo_box | ||
|
|
||
| def updateUnits(self, unit_box: QComboBox, selected_option: str): | ||
| unit_box.clear() | ||
| self.current_option = selected_option | ||
| # Use the list of preferred units but fallback to the first 5 if there aren't any for this particular column. | ||
| if self.current_option == '<ignore>': | ||
| unit_box.setDisabled(True) | ||
| else: | ||
| unit_box.setDisabled(False) | ||
| unit_options = defaults_or_fallback(self.current_option) | ||
| option_symbols = [unit.symbol for unit in unit_options] | ||
| for option in option_symbols[:5]: | ||
| unit_box.addItem(option) | ||
| unit_box.addItem('Select More') | ||
|
|
||
|
|
||
| def replaceOptions(self, new_options) -> None: | ||
| """Replace the old options for the column with new_options""" | ||
| self.col_widget.clear() | ||
| self.col_widget.addItems(new_options) | ||
|
|
||
| def setCurrentColumn(self, new_column_value: str) -> None: | ||
| """Change the current selected column to new_column_value""" | ||
| self.col_widget.setCurrentText(new_column_value) | ||
| self.updateUnits(self.unit_widget, new_column_value) | ||
|
|
||
|
|
||
| @Slot() | ||
| def onOptionChange(self): | ||
| # If the new option is empty string, its probably because the current | ||
| # options have been removed. Can safely ignore this. | ||
| self.column_changed.emit() | ||
| new_option = self.col_widget.currentText() | ||
| if new_option == '': | ||
| return | ||
| try: | ||
| self.updateUnits(self.unit_widget, new_option) | ||
| except KeyError: | ||
| # Means the units for this column aren't known. This shouldn't be | ||
| # the case in the real version so for now we'll just clear the unit | ||
| # widget. | ||
| self.unit_widget.clear() | ||
|
|
||
| @Slot() | ||
| def onUnitChange(self): | ||
| new_text = self.unit_widget.currentText() | ||
| if new_text == 'Select More': | ||
| selector = UnitSelector(unit_kinds[self.col_widget.currentText()].name, False) | ||
| selector.exec() | ||
| # We need the selection unit in the list of options, or else QT has some dodgy behaviour. | ||
| self.unit_widget.insertItem(-1, selector.selected_unit.symbol) | ||
| self.unit_widget.setCurrentText(selector.selected_unit.symbol) | ||
| # This event could get triggered when the units have just been cleared, and not actually updated. We don't want | ||
| # to trigger it in this case. | ||
| elif not new_text == '': | ||
| self.column_changed.emit() | ||
|
|
||
| @property | ||
| def currentColumn(self): | ||
| """The currently selected column.""" | ||
| return self.col_widget.currentText() | ||
|
|
||
| @property | ||
| def currentUnit(self) -> NamedUnit: | ||
| """The currently selected unit.""" | ||
| current_unit_symbol = self.unit_widget.currentText() | ||
| for unit in unit_kinds[self.current_option].units: | ||
| if current_unit_symbol == unit.symbol: | ||
| return unit | ||
| # This error shouldn't really happen so if it does, it indicates there is a bug in the code. | ||
| raise ValueError("Current unit doesn't seem to exist") | ||
|
|
||
| @currentUnit.setter | ||
| def currentUnit(self, new_value: NamedUnit): | ||
| self.unit_widget.setCurrentText(new_value.symbol) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| #!/usr/bin/env python | ||
|
|
||
|
|
||
| TABLE_MAX_ROWS = 1000 | ||
| NOFILE_TEXT = "Click the button below to load a file." |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.