Skip to content

Commit

Permalink
pcorlessGH-252 Adds Undo/Redo
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume Tâche committed Jul 27, 2023
1 parent 675d33e commit 7eb90b7
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 26 deletions.
31 changes: 31 additions & 0 deletions core/core-awt/src/main/java/org/icepdf/core/CombinedMemento.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.icepdf.core;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* A memento composed of several mementos
*/
public class CombinedMemento implements Memento {
private final List<Memento> mementos;

public CombinedMemento(final Memento... mementos) {
this(Arrays.asList(mementos));
}

public CombinedMemento(final List<Memento> mementos) {
this.mementos = new ArrayList<>(mementos);
Collections.reverse(this.mementos);
}

public List<Memento> getMementos() {
return List.copyOf(mementos);
}

@Override
public void restore() {
mementos.forEach(Memento::restore);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1245,9 +1245,9 @@ public void setDeleteAllButton(final JButton btn) {
documentViewController.getDocumentViewModel().getPageComponents().forEach(pvc -> {
final List<AbstractAnnotationComponent> comps = ((PageViewComponentImpl) pvc).getAnnotationComponents();
if (comps != null) {
final Set<AbstractAnnotationComponent> toDelete = comps.stream().filter(comp -> comp instanceof MarkupAnnotationComponent
final Collection<AnnotationComponent> toDelete = comps.stream().filter(comp -> comp instanceof MarkupAnnotationComponent
&& ((MarkupAnnotation) comp.getAnnotation()).isCurrentUserOwner()).collect(Collectors.toSet());
toDelete.forEach(documentViewController::deleteAnnotation);
documentViewController.deleteAnnotations(toDelete);
}
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.icepdf.ri.common.views;

import org.icepdf.core.CombinedMemento;
import org.icepdf.core.Memento;
import org.icepdf.core.pobjects.Document;
import org.icepdf.core.pobjects.Page;
Expand All @@ -27,11 +28,10 @@

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.*;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
* <p>The AbstractDocumentViewModel is responsible for keeping the state of the
Expand Down Expand Up @@ -389,11 +389,27 @@ public UndoCaretaker getAnnotationCareTaker() {
}

public void addMemento(Memento oldMementoState, Memento newMementoState) {
final AnnotationState newState = (AnnotationState) newMementoState;
//Don't register add/remove for popups, will be managed by the parent annotation
if (newState.getOperation() == AnnotationState.Operation.MOVE ||
!(newState.getAnnotationComponent() instanceof PopupAnnotationComponent)) {
undoCaretaker.addState(oldMementoState, newMementoState);
final Memento filteredOld = filterMemento(oldMementoState);
final Memento filteredNew = filterMemento(newMementoState);
if (filteredOld != null && filteredNew != null){
undoCaretaker.addState(filteredOld, filteredNew);
}
}

private Memento filterMemento(final Memento memento){
if (memento instanceof AnnotationState){
final AnnotationState state = (AnnotationState) memento;
if(state.getOperation() == AnnotationState.Operation.MOVE ||
!(state.getAnnotationComponent() instanceof PopupAnnotationComponent)){
return memento;
} else {
return null;
}
} else if (memento instanceof CombinedMemento){
return new CombinedMemento(((CombinedMemento) memento).getMementos().stream().map(this::filterMemento)
.filter(Objects::nonNull).collect(Collectors.toList()));
} else {
return memento;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
import org.icepdf.core.SecurityCallback;
import org.icepdf.core.pobjects.Destination;
import org.icepdf.core.pobjects.Document;
import org.icepdf.ri.common.views.annotations.AbstractAnnotationComponent;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyListener;
import java.util.Collection;
import java.util.Set;


/**
Expand Down Expand Up @@ -230,4 +233,6 @@ public interface DocumentViewController {
void firePropertyChange(String event, int oldValue, int newValue);

void firePropertyChange(String event, Object oldValue, Object newValue);

void deleteAnnotations(Collection<AnnotationComponent> annotations);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.icepdf.ri.common.views;

import org.icepdf.core.CombinedMemento;
import org.icepdf.core.Memento;
import org.icepdf.core.SecurityCallback;
import org.icepdf.core.pobjects.*;
import org.icepdf.core.search.DocumentSearchController;
Expand All @@ -35,6 +37,7 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -1393,6 +1396,35 @@ public void deleteAnnotation(AnnotationComponent annotationComponent) {
}
}

@Override
public void deleteAnnotations(final Collection<AnnotationComponent> annotations) {
if (documentViewModel != null) {
final List<Memento> addMementos = new ArrayList<>(annotations.size());
final List<Memento> deleteMementos = new ArrayList<>(annotations.size());
annotations.forEach(ac -> {
// parent component
final PageViewComponent pageComponent =
ac.getPageViewComponent();

if (annotationCallback != null) {
annotationCallback.removeAnnotation(pageComponent, ac);
}
addMementos.add(new AnnotationState(ac, AnnotationState.Operation.ADD));
deleteMementos.add(new AnnotationState(ac, AnnotationState.Operation.DELETE));

// fire event notification
firePropertyChange(PropertyConstants.ANNOTATION_DELETED, ac, null);
});
documentViewModel.addMemento(new CombinedMemento(addMementos), new CombinedMemento(deleteMementos));

// clear previously selected annotation and fire event.
assignSelectedAnnotation(null);

// repaint the view.
documentView.repaint();
}
}

public void addNewDestination(Destination destination) {
if (documentViewModel != null && destination != null) {
Library library = document.getCatalog().getLibrary();
Expand Down Expand Up @@ -1471,32 +1503,38 @@ public void deleteDestination(Destination destination) {


public void undo() {
final AnnotationState state = (AnnotationState) documentViewModel.getAnnotationCareTaker().undo();
fireEvent(state);
final Memento memento = documentViewModel.getAnnotationCareTaker().undo();
fireEvent(memento);
// repaint the view.
documentView.repaint();
}

public void redo() {
final AnnotationState state = (AnnotationState) documentViewModel.getAnnotationCareTaker().redo();
fireEvent(state);
final Memento memento = documentViewModel.getAnnotationCareTaker().redo();
fireEvent(memento);
// repaint the view.
documentView.repaint();
}

private void fireEvent(Memento memento) {
if (memento instanceof AnnotationState) {
fireEvent((AnnotationState) memento);
} else if (memento instanceof CombinedMemento) {
((CombinedMemento) memento).getMementos().forEach(this::fireEvent);
}
}

private void fireEvent(AnnotationState state) {
if (state != null) {
switch (state.getOperation()) {
case ADD:
firePropertyChange(PropertyConstants.ANNOTATION_ADDED, null, state.getAnnotationComponent());
break;
case DELETE:
firePropertyChange(PropertyConstants.ANNOTATION_DELETED, state.getAnnotationComponent(), null);
break;
case MOVE:
firePropertyChange(PropertyConstants.ANNOTATION_BOUNDS, state.getAnnotationComponent(), state.getAnnotationComponent());
break;
}
switch (state.getOperation()) {
case ADD:
firePropertyChange(PropertyConstants.ANNOTATION_ADDED, null, state.getAnnotationComponent());
break;
case DELETE:
firePropertyChange(PropertyConstants.ANNOTATION_DELETED, state.getAnnotationComponent(), null);
break;
case MOVE:
firePropertyChange(PropertyConstants.ANNOTATION_BOUNDS, state.getAnnotationComponent(), state.getAnnotationComponent());
break;
}
}

Expand Down

0 comments on commit 7eb90b7

Please sign in to comment.