koppor / jabref

Collection of simple for JabRef issues. Please submit PRs to https://github.com/jabRef/jabref/.
https://github.com/jabRef/jabref/
MIT License
8 stars 13 forks source link

Refinement of Mass Field Editor #593

Open koppor opened 2 years ago

koppor commented 2 years ago

Follow-up to https://github.com/JabRef/jabref/issues/8971


javax.swing.undo.CannotUndoException
    at java.desktop/javax.swing.undo.AbstractUndoableEdit.undo(AbstractUndoableEdit.java:111)
    at java.desktop/javax.swing.undo.CompoundEdit.undo(CompoundEdit.java:63)
    at java.desktop/javax.swing.undo.CompoundEdit.undo(CompoundEdit.java:67)
    at org.jabref@100.0.0/org.jabref.gui.edit.automaticfiededitor.AutomaticFieldEditorViewModel.cancelChanges(AutomaticFieldEditorViewModel.java:50)
    at org.jabref@100.0.0/org.jabref.gui.edit.automaticfiededitor.AutomaticFieldEditorDialog.cancelChanges(AutomaticFieldEditorDialog.java:89)
    at org.jabref@100.0.0/org.jabref.gui.edit.automaticfiededitor.AutomaticFieldEditorDialog.lambda$new$0(AutomaticFieldEditorDialog.java:54)
    at javafx.controls@18.0.1/javafx.scene.control.Dialog.setResultAndClose(Dialog.java:1053)
    at javafx.controls@18.0.1/javafx.scene.control.DialogPane.lambda$createButton$3(DialogPane.java:792)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@18.0.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18.0.1/javafx.scene.Node.fireEvent(Node.java:8797)
    at javafx.controls@18.0.1/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls@18.0.1/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
    at javafx.controls@18.0.1/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@18.0.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18.0.1/javafx.scene.Scene$MouseHandler.process(Scene.java:3881)
    at javafx.graphics@18.0.1/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics@18.0.1/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication._enterNestedEventLoopImpl(Native Method)
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication._enterNestedEventLoop(WinApplication.java:211)
    at javafx.graphics@18.0.1/com.sun.glass.ui.Application.enterNestedEventLoop(Application.java:515)
    at javafx.graphics@18.0.1/com.sun.glass.ui.EventLoop.enter(EventLoop.java:107)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:631)
    at javafx.graphics@18.0.1/javafx.stage.Stage.showAndWait(Stage.java:469)
    at javafx.controls@18.0.1/javafx.scene.control.HeavyweightDialog.showAndWait(HeavyweightDialog.java:162)
    at javafx.controls@18.0.1/javafx.scene.control.Dialog.showAndWait(Dialog.java:346)
    at org.jabref@100.0.0/org.jabref.gui.JabRefDialogService.showCustomDialogAndWait(JabRefDialogService.java:270)
    at org.jabref@100.0.0/org.jabref.gui.edit.automaticfiededitor.AutomaticFieldEditorAction.execute(AutomaticFieldEditorAction.java:23)
    at org.jabref@100.0.0/org.jabref.gui.actions.JabRefAction.lambda$new$3(JabRefAction.java:40)
    at org.controlsfx.controls/org.controlsfx.control.action.Action.handle(Action.java:423)
    at org.controlsfx.controls/org.controlsfx.control.action.Action.handle(Action.java:64)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@18.0.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.controls@18.0.1/javafx.scene.control.MenuItem.fire(MenuItem.java:459)
    at javafx.controls@18.0.1/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
    at javafx.controls@18.0.1/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18.0.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18.0.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18.0.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18.0.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base@18.0.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18.0.1/javafx.scene.Scene$MouseHandler.process(Scene.java:3881)
    at javafx.graphics@18.0.1/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics@18.0.1/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@18.0.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@18.0.1/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)

HoussemNasri commented 2 years ago

I think the exception was introduced in https://github.com/JabRef/jabref/pull/8973/commits/96c7ea81725f0d739c5ea7d0330c738c634a4121. Because in that commit dialogEdits.addEdit(setFieldEdit) will be called even when setFieldEdit.end() was not called. The same thing for the clear and append edits.

Snippet from AutomaticFieldEditorDialog.java listening for edits

EasyBind.listen(stateManager.lastAutomaticFieldEditorEditProperty(), (obs, old, lastEdit) -> {
viewModel.getDialogEdits().addEdit(lastEdit.getEdit());
notificationPanes.get(lastEdit.getTabIndex())
.notify(lastEdit.getAffectedEntries(), selectedEntries.size());
});

Snippet from EditFieldContentViewModel sending notification even when setFieldEdit.end() is not called

if (setFieldEdit.hasEdits()) {
setFieldEdit.end();
}
stateManager.setLastAutomaticFieldEditorEdit(new LastAutomaticFieldEditorEdit(
affectedEntriesCount,
TAB_INDEX,
setFieldEdit
));

EDIT It can be fixed by not registering in progress edits

        EasyBind.listen(stateManager.lastAutomaticFieldEditorEditProperty(), (obs, old, lastEdit) -> {
            if (lastEdit.getEdit().hasEdits()) {
                viewModel.getDialogEdits().addEdit(lastEdit.getEdit());
            }
            notificationPanes.get(lastEdit.getTabIndex())
                             .notify(lastEdit.getAffectedEntries(), selectedEntries.size());
        });