Skip default save dialog when closing the editor

Post here questions and problems related to oXygen frameworks/document types.
Thorsten
Posts: 3
Joined: Tue Jan 24, 2023 4:50 pm

Skip default save dialog when closing the editor

Post by Thorsten »

We use the Oxygen XML Author (Version 23) and add all our project specific logic as plugin.
As new requirement the user should get more project specific options when the editor is closed. The new requirements entail that the default opening dialog when the editor contains modified and not saved content should also be handled by the new project specific dialog.
How is it possible to skip or deactivate the default "Save" dialog?
Because the user shouldn’t be asked twice if the modified content should be saved. Nevertheless it should be possible to close without saving and it should be only displayed the project specific dialog.

Additional we are not sure what’s the best place to add the logic of the project specific dialog. Currently we have implemented a WSEditorChangeListener, which opens the dialog when the editorAboutToBeClosed(URL url) method is called.
Is that a suitable position or would you recommend a different way?

Code: Select all

pluginWorkspace.addEditorChangeListener(new WSEditorChangeListener() {
		
		@Override
		public boolean editorAboutToBeClosed(URL url) {

			boolean isClosable = true;

			StandalonePluginWorkspace pluginWorkspace = getPluginWorkspace();

			Object parent = pluginWorkspace.getParentFrame();

			if (parent instanceof JFrame) {
				//project specific dialog which provides "save", "skip save" "cancel" and additional operations
				SaveDialog saveDlg = new SaveDialog((JFrame) parent, Collections.singleton(url));
				saveDlg.setVisible(true);
				isClosable = !saveDlg.isCancel();
			}

			return isClosable;
		}

	}, PluginWorkspace.MAIN_EDITING_AREA);
Thanks and regards,
Thorsten
Radu
Posts: 9055
Joined: Fri Jul 09, 2004 5:18 pm

Re: Skip default save dialog when closing the editor

Post by Radu »

Hi Thorsten,

Maybe we can take a small example, so you have Oxygen opened with files "document1.xml" and "document2.xml" inside it. The files are not yet saved.
And you use for example the main menu File->Exit action to close the entire Oxygen application, right?
After that you should receive this callback:
https://www.oxygenxml.com/InstData/Edit ... net.URL:A-

You iterate through all the URLs of the opened document, obtain for each of them the corresponding WSEditor, and if the corresponding WSEditor is modified, you gather that URL to present in your own dialog. You can use our APIs to save a modified editor or to close it without save.
Something like this:

Code: Select all

      pluginWorkspaceAccess.addEditorChangeListener(new WSEditorChangeListener() {
        @Override
        public boolean editorsAboutToBeClosed(URL[] editorLocations) {
          
          List<WSEditor> modifiedDocuments = new ArrayList<WSEditor>();
          for (int i = 0; i < editorLocations.length; i++) {
            WSEditor ed = pluginWorkspaceAccess.getEditorAccess(editorLocations[i], pluginWorkspaceAccess.MAIN_EDITING_AREA);
            if(ed.isModified()) {
              modifiedDocuments.add(ed);
            }
          }
          
          if(!modifiedDocuments.isEmpty()) {
            boolean proceed = showYourOwnDialog(modifiedDocuments);
            if(proceedWithSave) {
              //Now save each of the modified documents.
              for (Iterator iterator = modifiedDocuments.iterator(); iterator.hasNext();) {
                WSEditor wsEditor = (WSEditor) iterator.next();
                wsEditor.save();
              }
            } else {
              //Force close each modified document without saving it
              for (Iterator iterator = modifiedDocuments.iterator(); iterator.hasNext();) {
                WSEditor wsEditor = (WSEditor) iterator.next();
                wsEditor.close(false);
              }
            }
          }
          //Always proceed with closing, Oxygen's dialog will no longer appear as all the files are now saved
          return true;
        };
      }, pluginWorkspaceAccess.MAIN_EDITING_AREA);
    }
If you are editing DITA XML documents, the DITA Maps Manager view has a similar mechanism and you can use a similar API to add a similar listener for documents closed on it.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Thorsten
Posts: 3
Joined: Tue Jan 24, 2023 4:50 pm

Re: Skip default save dialog when closing the editor

Post by Thorsten »

Hi Radu,
Thanks for your quick response and the included sample.
I have already tried and implemented a similar solution and it worked. But the solution works only when all opened editor tabs (multiple xml documents are opened) or the complete Oxygen is closed. But when I close for example just one of 3 opened XML documents, then I close it by the main menu File -> Close or by the cross at the editor tab. This way of closing doesn’t execute the mentioned callback ‘editorsAboutToBeClosed(URL[] editorLocations)’ with the URL array as argument. It executes just the callback editorAboutToBeClosed(URL editorLocation) with a single URL as argument.
And as soon as I add the logic to this method with a single URL, the editor.close(false) method call causes an endless loop, because it executes the callback a second time.

Code: Select all

pluginWorkspaceAccess.addEditorChangeListener(new WSEditorChangeListener() {
        @Override
        public boolean editorAboutToBeClosed(URL editorLocation) {
	//Handle the closing of one editor tab
         .....
         //Causes a loop, because the callback is executed a second time
          wsEditor.close(false);
          ......
          }
Do you have any idea, how I could solve it?
Let me know, if you need more details or something is unclear in my problem description.
Best regards,
Thorsten
Radu
Posts: 9055
Joined: Fri Jul 09, 2004 5:18 pm

Re: Skip default save dialog when closing the editor

Post by Radu »

Hi Thorsten,
Now I understand, so by "closing the editor" you meant closing a single tab in the application, not closing the entire application.
Indeed when closing tabs one by one that callback I exemplified is not received.
Maybe you can try to avoid the double callback by doing something like this:

Code: Select all

      pluginWorkspaceAccess.addEditorChangeListener(new WSEditorChangeListener() {
        
        private URL aboutToClose = null;
        
        public boolean editorAboutToBeClosed(URL editorLocation) {
          if(aboutToClose != null && editorLocation.toString().equals(aboutToClose.toString())) {
            //Avoid recursivity
            return true;
          } else {
            aboutToClose = editorLocation;
            WSEditor ed = pluginWorkspaceAccess.getEditorAccess(editorLocation, PluginWorkspace.MAIN_EDITING_AREA);
            ed.close(false);
            aboutToClose = null;
            return false;
          }
        };
      }, PluginWorkspace.MAIN_EDITING_AREA);
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Thorsten
Posts: 3
Joined: Tue Jan 24, 2023 4:50 pm

Re: Skip default save dialog when closing the editor

Post by Thorsten »

Hi Radu,
Thanks again!
I tried your recommended solution, but unfortunately the Oxygen “Save” dialog is displayed, even when the close(false) method is called.
It might be a side effect of the duplicate close method calls, one performed by the user and the second in the editorAboutToBeClosed
method programmatically.

I detected a way to avoid the “Save” dialog:
Instead of calling the close(false) method I called the editor.setModified(false) method, when the user want to discard the changes.
But I m not sure, if that method call could cause side effects.
What do you think?

Best regards,
Thorsten
Radu
Posts: 9055
Joined: Fri Jul 09, 2004 5:18 pm

Re: Skip default save dialog when closing the editor

Post by Radu »

Hi Thorsten,

What you ended up doing sounds like a good idea to me.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply