Page 1 of 1

RefreshReference without making doc dirty

Posted: Tue Jan 12, 2021 11:52 am
by Patrik
Hi,

I'm using an AuthorReferenceResolver to display some status information to the author.
And I have an AuthorOperationWithResult that changes this information so I'm calling AuthorDocumentController.refreshNodeReferences().

This works fine, except that this will cause to document to be marked as modified.
So I tried this:

Code: Select all

final boolean isModified = authorAccess.getEditorAccess().isModified();
authorAccess.getDocumentController().refreshNodeReferences(statusNode);
if (!isModified) {
    authorAccess.getEditorAccess().setModified(false);
}
But it doesn't work and I get a warning in the log:

Code: Select all

ro.sync.ecss.webapp.access.j - Calling isModified() is not supported while a "compound edit" is in progress. Note that a "compound edit" is created automatically when invoking an AuthorOperation that does not extend AuthorOperationWithCustomUndoBehavior
I might as well trigger the refresh from javascript but could not find a way to do it from there.

Any ideas?

Thanks and regards,
Patrik

Re: RefreshReference without making doc dirty

Posted: Tue Jan 12, 2021 2:56 pm
by mihai_coanda
Hello Patrik,

As mentioned in the warning you received if an AuthorOperation is invoked it will automatically mark the document as dirty by creating a "compound edit".
If you want to prevent this behavior, your operation should implement the AuthorOperationWithCustomUndoBehavior marker interface.

Regards,
Michael

Re: RefreshReference without making doc dirty

Posted: Tue Jan 12, 2021 6:58 pm
by Patrik
I already tried that and failed bacause I thought i would nee to implement AuthorOperationWithCustomUndoBehavior instead of AuthorOperationWithResult.
But now I realized I just had to add this interface and it works fine.

Thanks a lot - once again! :)
Patrik

Re: RefreshReference without making doc dirty

Posted: Wed Jan 13, 2021 12:32 pm
by Patrik
Hi again.
I just noticed that the log entry

Code: Select all

1212098 WARN [ http-nio-8080-exec-8 ] ro.sync.ecss.webapp.access.j - Calling setModified() is not supported while a "compound edit" is in progress. Note that a "compound edit" is created automatically when invoking an AuthorOperation that does not extend AuthorOperationWithCustomUndoBehavior
also occurs when doing a git-commit without modifications.

Took me some time to realize this was not my fault (at least I'm pretty sure)... ;)

You might want to take a look on it.

Regards,
Patrik

Re: RefreshReference without making doc dirty

Posted: Wed Jan 13, 2021 3:35 pm
by Patrik
I still have a problem with the refreshreference:
I added the call of an AuthorOperation after the git-commit to rfresh the reference. But the setModified(false) doesn't work there - and I get no warning in the log.

Here is my minimized code for this issue:

Code: Select all

@WebappCompatible
@WebappRestSafe
public class CommitRefreshTest extends AuthorOperationWithResult implements AuthorOperationWithCustomUndoBehavior {

	public String doOperation(AuthorDocumentModel model, ArgumentsMap args) throws AuthorOperationException {
		try {
			final AuthorAccess	authorAccess	= model.getAuthorAccess();
			final AuthorNode 	node 			= authorAccess.getDocumentController().getNodeAtOffset(0);
			System.out.println("CommitRefreshTest: " + node.getDisplayName());
			authorAccess.getDocumentController().refreshNodeReferences(node);
			authorAccess.getEditorAccess().setModified(false);
		} catch (BadLocationException e) {
			final AuthorOperationException ex = new AuthorOperationException(e.getMessage(), e);
			ex.setOperationRejectedOnPurpose(true);
		}
		return null;
	}
}

Code: Select all

goog.events.listenOnce(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
	var editor = e.editor;
	
	goog.events.listenOnce(e.editor, sync.api.Editor.EventTypes.ACTIONS_LOADED, function(e) {
		var commitAction = editor.getActionsManager().getActionById('Git/Commit');
		var oldActionPerformed = commitAction.actionPerformed;
		
		commitAction.actionPerformed = function(callback) {
			oldActionPerformed.call(commitAction, function(callback) {
				if (!editor.isDirty()) {
					console.log('Git/Commit - Done and doc not dirty so it was successful.');
					editor.getActionsManager().invokeOperation(
						'com.gdvdl.TgicServiceCatalog.operations.CommitRefreshTest', 
						{}, // no parameters
						null, // no callback
						null,
						true // This is a background operation - it does not update the document
					);
				} else {
					console.log('Git/Commit - Done but doc is still dirty so it was not successful.');			
				}
			})
		};
	});
});
I was also looking into the documentation for setModified and found this:
For Web Author, can be used to mark the document as clean and to make sure that the clean state is properly identified after a series of undo/redo operations. This method has some limitations:
  • It does not automatically update the client-side editor dirty status.
  • [...]
  • it does nothing if invoked with false
.
This also confuses me. How should I use this method to mark a document as clean other than by invoking it with false?
And in all other cases it was working fine!?

Still the most important question for me remains: How can I refresh the references after a commit without making the document dirty.

Thanks and regards,
Patrik

Re: RefreshReference without making doc dirty

Posted: Wed Jan 13, 2021 5:56 pm
by Gabriel Titerlea
You can call

Code: Select all

this.editor.setDirty(false);
after you invoke the CommitRefreshTest operation. See this forum post [1].

Best,
Gabriel

[1] topic13562.html#p40382

Re: RefreshReference without making doc dirty

Posted: Wed Jan 13, 2021 6:21 pm
by Patrik
Great, that works for me as well! :)

Thanks!
Patrik