Skip to content

Conversation

krystofair
Copy link
Contributor

@krystofair krystofair commented Jul 30, 2025

I catched myself on doing that twice, when rename workflow file and cannot find it because of extension.
This change is about it. Add extension to filename if there is not.

This is one solution among two I think.
The second one is change visibility of files the user can choose from when opening saved workflow.
The first is simpler I guess and it seems more reasonable.

There is possibility about change type of filename when passed as pathlib.Path,
but this operation is safe in this place. Casting will not raise exception when
filename is pathlib.Path type indeed.

I changed it, because in my first commit basename was from original filename, so it can misguide.

Used Orange3 in version: 3.39

@krystofair krystofair force-pushed the krystofair/extension-in-saving-workflow branch from 486d197 to 094a761 Compare July 30, 2025 21:57
@krystofair krystofair changed the title Add ext to filename when user forget it when rename Add ext to filename when user forget it when rename [WIP] Aug 1, 2025
@krystofair
Copy link
Contributor Author

Could be done in that way, but there can happen weird behaviour:

  • Asking about replace file which exists, there is file with the same name without ext
  • click [ok] - saved file, without overriding,
  • user will have two files.

There is another bug:

orange-canvas-core 0.2.6

  1. Open new workflow and writing name of it with file already exists in recent localization
  2. Save when "modified" indicator is visible.
  3. Click "Reject/Cancel"
  4. Workflow is saved, no notification to user! existing file is replaced.

@krystofair krystofair changed the title Add ext to filename when user forget it when rename [WIP] Add ext to filename when user forget it when rename Aug 1, 2025
@krystofair
Copy link
Contributor Author

Second commit fix mentioned bug.

@markotoplak markotoplak changed the title Add ext to filename when user forget it when rename [FIX] Workflow saves only when confirmed, keep ows extension Aug 22, 2025
@markotoplak markotoplak changed the title [FIX] Workflow saves only when confirmed, keep ows extension [FIX] Workflow saving: fix cancel, enforce ows extension Aug 22, 2025
@markotoplak
Copy link
Member

markotoplak commented Aug 22, 2025

Thank you for this PR, and sorry that we took so long to look into it.

I especially appreciate the fix for the correct treatment of clicking on the "Cancel" in the dialog. That was a nasty bug.

I like the idea of keeping the .ows extension, but now this PR introduced a new bug. Let's assume a file "a.ows" already exists. Then, the user saves their workflow into "a". Now, the code silently add ".ows" and this the user is not notified that they are overwriting an existing file. So that silent addition of ".ows" is dangerous.

We did attempt to handle this in the Save widget and the solution in owsavebase.py (from biolab/orange3) was to manually put up an additional dialog if needed. We could do something similar here. So the crux is this:

                if not os.path.exists(filename) or QMessageBox.question(
                        self, "Overwrite file?",
                        f"File {os.path.split(filename)[1]} already exists.\n"
                        "Overwrite?") == QMessageBox.Yes:

owsavebase.py handles different platforms separately, but I think the above "post-processing" of the dialog results should work with all platforms. Could you try a similar patch?

@markotoplak
Copy link
Member

Please also rebase to master. If you perhaps don't have time to work on this PR, please tell us, so that we can add the check ourselves. Thank you!

@krystofair krystofair force-pushed the krystofair/extension-in-saving-workflow branch from 2ab8e77 to 05b88a3 Compare August 22, 2025 15:55
@krystofair
Copy link
Contributor Author

krystofair commented Aug 22, 2025

Yup, I know about that weird behaviour, but in that moment I cannot figure out where is the best place to do this. So what I was thinking, was compromise. 😎
Now that feature is in right place, I understood that thing about assigned 'path' when file was previously saved.

Thanks for this override snippet - added.

Comment on lines 1577 to 1579
# Enforcing ".ows" extension during saving file.
# see .../biolab/orange-canvas-core/pull/330
filename = filename if str(filename).endswith('.ows') else f"{filename}.ows"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is, what is reverted

This is one solution among two I think.
The second one is change visibility of files the user can choose
from when opening saved workflow.
The first is simpler I guess and it seems more reasonable.

Possibility about change type of `filename` when passed as `pathlib.Path`,
but this operation here is safe. Casting will not raise exception when
`filename` is `pathlib.Path` type indeed.
- reverts commit 4f02bf8.
- Add question MessageBox when overriding file
- changed place when `filename` is changed to `filename`.ows in compare
  to reverted commit.
@krystofair krystofair force-pushed the krystofair/extension-in-saving-workflow branch from 05b88a3 to 25a0d32 Compare August 27, 2025 18:59
@krystofair
Copy link
Contributor Author

/rebase

@krystofair
Copy link
Contributor Author

I don't get one thing. When I run tests at my machine I have to still accept manually dialog with "override", even though the settings: AcceptSave and DontConfirmOverwrite are set. 😑

Maybe here will not ask, but if yes - any ideas?

@janezd
Copy link
Contributor

janezd commented Sep 8, 2025

Confirmation comes a few lines later in the code, where it calls QMessageBox. To avoid this, you need to patch the MessageBox.question, like this (the first patch is already there, just add the second line and the necessary imports):

        with patch("AnyQt.QtWidgets.QFileDialog.exec", exec), \
            patch("AnyQt.QtWidgets.QMessageBox.question", new=Mock(return_value=QMessageBox.Yes)):

@krystofair krystofair force-pushed the krystofair/extension-in-saving-workflow branch 2 times, most recently from ed86ee4 to 3f5dd9d Compare September 8, 2025 08:31
- Add suffix to filename for file created by tempfile to be compatible with
enforcing 'ows' extension.

- Mocked `exec` method for QFileDialog now return True, because it was
never reach out branch `if dialog.exec():`.
@krystofair krystofair force-pushed the krystofair/extension-in-saving-workflow branch from 3f5dd9d to feff7b5 Compare September 8, 2025 08:41
@janezd
Copy link
Contributor

janezd commented Sep 8, 2025

@markotoplak, after you approve the PR (please also add a comment so I get an email), I can update the translations and merge.

@codecov-commenter
Copy link

codecov-commenter commented Sep 8, 2025

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.55%. Comparing base (005dc69) to head (feff7b5).

Files with missing lines Patch % Lines
orangecanvas/application/canvasmain.py 71.42% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #330      +/-   ##
==========================================
+ Coverage   76.54%   76.55%   +0.01%     
==========================================
  Files         102      102              
  Lines       21316    21313       -3     
==========================================
  Hits        16317    16317              
+ Misses       4999     4996       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

I haven't seen it when fixing tests... defaultSuffix
Previously solution is bad, because there will pop-up
two MessageBox, second when FileDialog is already closed.
@krystofair
Copy link
Contributor Author

I don't like this mechanism. There is enough to write name as "title.o" to skip this at all and save file which can't be found...
But I think this is the most elegant solution without complicate things further.

Anyway that fix of "saving at cancel" is more important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants