From d89e2bff5815896a1dfbdc22625ebff6c9974bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20T=C3=A2che?= Date: Tue, 25 Jul 2023 12:46:03 +0200 Subject: [PATCH 1/2] GH-254 Sets tighter permissions --- .../annotations/MarkupAnnotation.java | 8 ++++++ .../org/icepdf/ri/common/SwingController.java | 21 ++++++++++++++++ .../icepdf/ri/common/SwingViewBuilder.java | 20 ++++++++++++--- .../AnnotationPropertiesDialog.java | 5 +++- .../annotation/properties/FlagsPanel.java | 6 ++--- .../views/DocumentViewControllerImpl.java | 5 +++- .../MarkupAnnotationPopupMenu.java | 23 +++++++++--------- .../annotations/PopupAnnotationComponent.java | 3 +++ .../ri/util/ViewerPropertiesManager.java | 1 + .../ri/images/delete_all_annotations_a_24.png | Bin 0 -> 1311 bytes .../ri/images/delete_all_annotations_a_32.png | Bin 0 -> 1083 bytes .../ri/images/delete_all_annotations_i_24.png | Bin 0 -> 731 bytes .../ri/images/delete_all_annotations_i_32.png | Bin 0 -> 651 bytes .../ri/images/delete_all_annotations_r_24.png | Bin 0 -> 1311 bytes .../ri/images/delete_all_annotations_r_32.png | Bin 0 -> 1083 bytes .../ri/resources/MessageBundle.properties | 2 ++ .../ri/resources/MessageBundle_de.properties | 4 ++- .../ri/resources/MessageBundle_fr.properties | 4 ++- 18 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_a_24.png create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_a_32.png create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_24.png create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_32.png create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_r_24.png create mode 100644 viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_r_32.png diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/annotations/MarkupAnnotation.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/annotations/MarkupAnnotation.java index d013ace65..803c578f0 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/annotations/MarkupAnnotation.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/annotations/MarkupAnnotation.java @@ -18,6 +18,7 @@ import org.icepdf.core.pobjects.*; import org.icepdf.core.pobjects.graphics.GraphicsState; import org.icepdf.core.util.Library; +import org.icepdf.core.util.SystemProperties; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -25,6 +26,7 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; +import java.util.regex.Pattern; /** * As mentioned in 12.5.2, "Annotation Dictionaries," the meaning of an @@ -161,6 +163,8 @@ public abstract class MarkupAnnotation extends Annotation { */ public static final Name EXT_GSTATE_NAME = new Name("ip1"); + private static final Pattern REPLY_PATTERN = Pattern.compile("(?:Re: ?)+"); + protected String titleText; protected PopupAnnotation popupAnnotation; protected float opacity = 1.0f; @@ -406,4 +410,8 @@ public void setSubject(String subject) { public String toString() { return getPObjectReference() + " - " + getTitleText() + " - " + getContents(); } + + public boolean isCurrentUserOwner() { + return REPLY_PATTERN.matcher(getTitleText()).replaceAll("").equals(SystemProperties.USER_NAME); + } } diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingController.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingController.java index 566e175c6..95ee015b2 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingController.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingController.java @@ -224,6 +224,7 @@ public class SwingController extends ComponentAdapter private JToggleButton zoomDynamicToolButton; private JToggleButton selectToolButton; // main annotation toolbar + private JButton deleteAllAnnotationsButton; private AnnotationColorToggleButton highlightAnnotationToolButton; private JToggleButton linkAnnotationToolButton; private AnnotationColorToggleButton strikeOutAnnotationToolButton; @@ -1233,6 +1234,25 @@ public void setAnnotationEditingModeToolButton(JToggleButton btn) { btn.addActionListener(this); } + /** + * Called by SwingViewerBuilder, so that Controller can setup event handling + * + * @param btn button to assign + */ + public void setDeleteAllButton(final JButton btn) { + deleteAllAnnotationsButton = btn; + btn.addActionListener(e -> { + documentViewController.getDocumentViewModel().getPageComponents().forEach(pvc -> { + final List comps = ((PageViewComponentImpl) pvc).getAnnotationComponents(); + if (comps != null) { + final Set toDelete = comps.stream().filter(comp -> comp instanceof MarkupAnnotationComponent + && ((MarkupAnnotation) comp.getAnnotation()).isCurrentUserOwner()).collect(Collectors.toSet()); + toDelete.forEach(documentViewController::deleteAnnotation); + } + }); + }); + } + /** * Called by SwingViewerBuilder, so that Controller can setup event handling * @@ -1698,6 +1718,7 @@ protected void reflectStateInComponents() { setEnabled(zoomDynamicToolButton, opened && !pdfCollection); setEnabled(textSelectToolButton, opened && canExtract && !pdfCollection); setEnabled(selectToolButton, opened && canModify && !pdfCollection); + setEnabled(deleteAllAnnotationsButton, opened && canModify && !pdfCollection && !IS_READONLY); setEnabled(highlightAnnotationToolButton, opened && canModify && !pdfCollection && !IS_READONLY); setEnabled(strikeOutAnnotationToolButton, opened && canModify && !pdfCollection && !IS_READONLY); setEnabled(underlineAnnotationToolButton, opened && canModify && !pdfCollection && !IS_READONLY); diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingViewBuilder.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingViewBuilder.java index 6b0ac2b02..497e8647f 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingViewBuilder.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/SwingViewBuilder.java @@ -1224,7 +1224,7 @@ public JToolBar buildCompleteToolBar(boolean embeddableComponent) { if (propertiesManager.checkAndStoreBooleanProperty(ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_TOOL)) addToToolBar(toolbar, buildToolToolBar()); if (propertiesManager.checkAndStoreBooleanProperty(ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION)) - addToToolBar(toolbar, buildAnnotationlToolBar()); + addToToolBar(toolbar, buildAnnotationToolBar()); if (propertiesManager.checkAndStoreBooleanProperty(ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_FORMS)) addToToolBar(toolbar, buildFormsToolBar()); if (propertiesManager.checkAndStoreBooleanProperty(ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_SEARCH)) @@ -1587,7 +1587,7 @@ public JToolBar buildToolToolBar() { return toolbar; } - public JToolBar buildAnnotationlToolBar() { + public JToolBar buildAnnotationToolBar() { JToolBar toolbar = new JToolBar(); commonToolBarSetup(toolbar, false); if (propertiesManager.checkAndStoreBooleanProperty( @@ -1638,6 +1638,10 @@ public JToolBar buildAnnotationlToolBar() { ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION_TEXT)) { addToToolBar(toolbar, buildTextAnnotationToolButton(iconSize)); } + if (propertiesManager.checkAndStoreBooleanProperty( + ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION_DELETE)) { + addToToolBar(toolbar, buildDeleteAllAnnotationsButton(iconSize)); + } if (SystemProperties.PRIVATE_PROPERTY_ENABLED && propertiesManager.checkAndStoreBooleanProperty( ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION_PERMISSION)) { addToToolBar(toolbar, buildAnnotationPermissionCombBox()); @@ -1654,7 +1658,6 @@ public JToolBar buildAnnotationlToolBar() { ViewerPropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION_PREVIEW)) { addToToolBar(toolbar, buildAnnotationPreviewButton(iconSize)); } - return toolbar; } @@ -1768,6 +1771,17 @@ public JToggleButton buildSelectToolButton(final String imageSize) { return btn; } + public JButton buildDeleteAllAnnotationsButton(final String imageSize) { + final JButton btn = makeToolbarButton( + messageBundle.getString("viewer.toolbar.tool.delete.all.label"), + messageBundle.getString("viewer.toolbar.tool.delete.all.tooltip"), + "delete_all_annotations", imageSize, buttonFont); + if (viewerController != null && btn != null) { + viewerController.setDeleteAllButton(btn); + } + return btn; + } + public AbstractButton buildHighlightAnnotationToolButton(final String imageSize) { AnnotationColorToggleButton btn = makeAnnotationToggleButton( messageBundle.getString("viewer.toolbar.tool.highlight.label"), diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/AnnotationPropertiesDialog.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/AnnotationPropertiesDialog.java index 071e55156..bf506ab5b 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/AnnotationPropertiesDialog.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/AnnotationPropertiesDialog.java @@ -15,6 +15,7 @@ */ package org.icepdf.ri.common.utility.annotation.properties; +import org.icepdf.core.pobjects.annotations.MarkupAnnotation; import org.icepdf.ri.common.EscapeJDialog; import org.icepdf.ri.common.SwingController; import org.icepdf.ri.common.views.AnnotationComponent; @@ -131,7 +132,9 @@ public void setAnnotationComponent(AnnotationComponent annotation) { } // disable the component if the annotation is readonly. - if (annotation.getAnnotation().getFlagReadOnly()) { + if (annotation.getAnnotation().getFlagReadOnly() || + (annotation.getAnnotation() instanceof MarkupAnnotation && + !((MarkupAnnotation) annotation.getAnnotation()).isCurrentUserOwner())) { if (annotationPropertyPanel != null) annotationPropertyPanel.setEnabled(false); actionsPanel.setEnabled(false); borderPanel.setEnabled(false); diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/FlagsPanel.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/FlagsPanel.java index 9e8a909eb..0bc77aabd 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/FlagsPanel.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/utility/annotation/properties/FlagsPanel.java @@ -17,6 +17,7 @@ package org.icepdf.ri.common.utility.annotation.properties; import org.icepdf.core.pobjects.annotations.Annotation; +import org.icepdf.core.pobjects.annotations.MarkupAnnotation; import org.icepdf.ri.common.views.AnnotationComponent; import org.icepdf.ri.common.views.Controller; @@ -101,9 +102,8 @@ public void setEnabled(boolean enabled) { super.setEnabled(enabled); noRotateComboBox.setEnabled(enabled); noZoomComboBox.setEnabled(enabled); - // leaving this always enabled just so users can change it back in editor mode. - // does this make sense? not sure could argue either way. - readOnlyComboBox.setEnabled(true); + boolean canModify = ((MarkupAnnotation) currentAnnotationComponent.getAnnotation()).isCurrentUserOwner(); + readOnlyComboBox.setEnabled(canModify); printableComboBox.setEnabled(enabled); } diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/DocumentViewControllerImpl.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/DocumentViewControllerImpl.java index 2f0a65f65..d991a3e4d 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/DocumentViewControllerImpl.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/DocumentViewControllerImpl.java @@ -17,6 +17,7 @@ import org.icepdf.core.SecurityCallback; import org.icepdf.core.pobjects.*; +import org.icepdf.core.pobjects.annotations.MarkupAnnotation; import org.icepdf.core.search.DocumentSearchController; import org.icepdf.core.util.Library; import org.icepdf.core.util.PropertyConstants; @@ -1305,7 +1306,9 @@ public void addPropertyChangeListener(PropertyChangeListener l) { public void deleteCurrentAnnotation() { AbstractAnnotationComponent annotationComponent = (AbstractAnnotationComponent) documentViewModel.getCurrentAnnotation(); - if (annotationComponent != null && !(annotationComponent instanceof PopupAnnotationComponent)) { + if (annotationComponent != null && !(annotationComponent instanceof PopupAnnotationComponent) && + (!(annotationComponent.getAnnotation() instanceof MarkupAnnotation) || + ((MarkupAnnotation) annotationComponent.getAnnotation()).isCurrentUserOwner())) { deleteAnnotation(annotationComponent); } } diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java index 6403f1dbc..b18bde98f 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java @@ -92,23 +92,24 @@ public MarkupAnnotationPopupMenu(MarkupAnnotationComponent markupAnnotationCompo public void buildGui() { ViewerPropertiesManager propertiesManager = ViewerPropertiesManager.getInstance(); boolean modifyDocument = controller.havePermissionToModifyDocument(); - + boolean hasEditRights = ((MarkupAnnotation) annotationComponent.getAnnotation()).isCurrentUserOwner(); + boolean canModify = modifyDocument && hasEditRights; // status change commands. statusNoneMenuItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.status.none.label")); - statusNoneMenuItem.setEnabled(modifyDocument); + statusNoneMenuItem.setEnabled(canModify); statusAcceptedItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.status.accepted.label")); - statusAcceptedItem.setEnabled(modifyDocument); + statusAcceptedItem.setEnabled(canModify); statusCancelledMenuItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.status.cancelled.label")); - statusCancelledMenuItem.setEnabled(modifyDocument); + statusCancelledMenuItem.setEnabled(canModify); statusCompletedMenuItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.status.completed.label")); - statusCompletedMenuItem.setEnabled(modifyDocument); + statusCompletedMenuItem.setEnabled(canModify); statusRejectedMenuItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.status.rejected.label")); - statusRejectedMenuItem.setEnabled(modifyDocument); + statusRejectedMenuItem.setEnabled(canModify); // generic commands, open/minimize all openAllMenuItem = new JMenuItem( messageBundle.getString("viewer.annotation.popup.openAll.label")); @@ -122,23 +123,23 @@ public void buildGui() { // annotation creation menus. addDestinationMenuItem = new JMenuItem( messageBundle.getString("viewer.utilityPane.view.selectionTool.contextMenu.addDestination.label")); - addDestinationMenuItem.setEnabled(modifyDocument); + addDestinationMenuItem.setEnabled(canModify); addDestinationMenuItem.addActionListener(this); addDestinationMenuItem.setIcon(new ImageIcon(Images.get("destination_20.png"))); addFreeTextMenuItem1 = new JMenuItem( messageBundle.getString("viewer.annotation.popup.addAnnotation.freeText.label")); - addFreeTextMenuItem1.setEnabled(modifyDocument); + addFreeTextMenuItem1.setEnabled(canModify); addFreeTextMenuItem1.setIcon(new ImageIcon(Images.get("freetext_annot_a_20.png"))); addFreeTextMenuItem1.addActionListener(this); addFreeTextMenuItem2 = new JMenuItem( messageBundle.getString("viewer.annotation.popup.addAnnotation.freeText.label")); - addFreeTextMenuItem2.setEnabled(modifyDocument); + addFreeTextMenuItem2.setEnabled(canModify); addFreeTextMenuItem2.setIcon(new ImageIcon(Images.get("freetext_annot_a_20.png"))); addFreeTextMenuItem2.addActionListener(this); // addition of set status menu JMenu submenu = new JMenu( messageBundle.getString("viewer.annotation.popup.addAnnotation.label")); - addDestinationMenuItem.setEnabled(modifyDocument); + addDestinationMenuItem.setEnabled(canModify); submenu.add(addDestinationMenuItem); submenu.addSeparator(); submenu.add(addFreeTextMenuItem2); @@ -195,7 +196,7 @@ public void buildGui() { submenu.add(setAllPublicMenuItem); add(submenu); addSeparator(); - submenu.setEnabled(modifyDocument); + submenu.setEnabled(canModify); } // generic commands, open/minimize all diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/PopupAnnotationComponent.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/PopupAnnotationComponent.java index 9aa484bb1..e30edbc76 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/PopupAnnotationComponent.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/PopupAnnotationComponent.java @@ -377,6 +377,7 @@ private void buildGUI() { textArea.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(PopupAnnotation.BORDER_COLOR), BorderFactory.createEmptyBorder(2, 2, 2, 2))); + textArea.setEditable(selectedMarkupAnnotation.isCurrentUserOwner()); textArea.setLineWrap(true); textArea.getDocument().addDocumentListener(this); if (!disableSpellCheck) { @@ -763,6 +764,7 @@ public void valueChanged(TreeSelectionEvent e) { public void refreshPopupState() { if (textArea != null) { // update the private/public button. + privateToggleButton.setVisible(selectedMarkupAnnotation.isCurrentUserOwner()); if (privateToggleButton.isVisible()) { privateToggleButton.setSelected(selectedMarkupAnnotation.getFlagPrivateContents()); } @@ -770,6 +772,7 @@ public void refreshPopupState() { textArea.getDocument().removeDocumentListener(this); textArea.setText(selectedMarkupAnnotation.getContents()); textArea.getDocument().addDocumentListener(this); + textArea.setEditable(selectedMarkupAnnotation.isCurrentUserOwner()); } refreshCreationLabel(); } diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/util/ViewerPropertiesManager.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/util/ViewerPropertiesManager.java index 42124ea77..2912eb666 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/util/ViewerPropertiesManager.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/util/ViewerPropertiesManager.java @@ -186,6 +186,7 @@ public final class ViewerPropertiesManager { public static final String PROPERTY_ANNOTATION_EDITING_MODE_ENABLED = "application.annotation.editing.mode.enabled"; // Individual controls for the annotation toolbar button commands public static final String PROPERTY_SHOW_TOOLBAR_ANNOTATION_SELECTION = "application.toolbar.annotation.selection.enabled"; + public static final String PROPERTY_SHOW_TOOLBAR_ANNOTATION_DELETE = "application.toolbar.annotation.delete.enabled"; public static final String PROPERTY_SHOW_TOOLBAR_ANNOTATION_HIGHLIGHT = "application.toolbar.annotation.highlight.enabled"; public static final String PROPERTY_SHOW_TOOLBAR_ANNOTATION_UNDERLINE = "application.toolbar.annotation.underline.enabled"; public static final String PROPERTY_SHOW_TOOLBAR_ANNOTATION_STRIKE_OUT = "application.toolbar.annotation.strikeout.enabled"; diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_a_24.png b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_a_24.png new file mode 100644 index 0000000000000000000000000000000000000000..c0695e7062559e7fffa858593a597e1599d94700 GIT binary patch literal 1311 zcmV+)1>pLLP)(9!fw_^jboREhMQevdAkNs>$eA{L9Ws;Zz|q}8ieW6hd1bm78<7m~^3=L;7u zd~4^U_H8ls;a1~tD~bwk1iP> zAO9g5jlSI6+&rDC5P1Vgk^}(g?CiwY*cjT|+rO@@tvyIY2_n(~*fIc=m6cITOAGt` z{@#X$hH#D?0Ej5B=d7}_5-V4(gkc!r{{H^k!C-Ji2=M@brDRLQ)z#HI0)arJxw#pw zt*y9t@#3Ql^BFV4SPbpa?v0)fHqR}V-psA_p zKRvcwA`J}<=C-v zmzS4+P+D4=$u%#pasVKe0@v0;ibP;3O6J76b^8*2|BxUW1E2wzZbWuC*|IEW48xf8 zdc7i7j>g7DB$LS*gLs+Ib?FiVAlbGHYp-4{`8g69ackN=01p5N#rbH8ii&K*Fsda< z@@krfW5dcD^bMHv)A3;`GgFaaP9;J(YUGA~U`WC)dI(Kj%~s1SdzJ3+O`$^h-wc32eTT)+3Gp53R?nbtNMD0G5E< z+}uo7DwVk~49_T~=AvhX5Vxh2-+P{yo0*we2O2;NXj^0s5fMj#OTb-UUw@(1YQ3$L zx*$Z~C3DAdoa+-46W3Cy)L%diXlg>CO+xelceb{+Qsr_v04@OJa=E?>HJi=;6L+QV zd!F|}CX@LX*aNCST}MR)LGUjD8+>D9<6OO7|3V0n7zDT%5!ZE>XJ=>M1IoaC9g#Mm zWTYNsp-_0X(P(^kTyPV$TrNke)q15+D0~P!0mOmFOd-pN_im%nxH@Ra`ytY7HqRG} z#g~925CdF5xVHECeExMI#2Ev=xVT8MSR4v8oldi`u+Xu#v$OL)@QtpA8qk*7djP4F zdihbcT;o)!RC*2=H)(L~|6M6Hx3aQwa471*N!Z@r-YoDnFk%SUMVPQZK28dHr9ued zXmIzS2raw)sHdOfI5oSKyODOfksJ-#@3l-?gVL8oV;(6YR z=XpQY>-E!0snFJbj^k9v#>Vb0-@N&*<@t+CLGY#Z9=E{54n1HOV?LjMM=AA@y%&$i zKbxMOUe+E|bfh{+ECs<=7T8(f0Z?5Ef|9lF81N27WJYqKP?%~qn^&ZikB^Lul*Y%$ zi<6U+8yfJQ78SdevN7O4TOd#B?+?3w002ovPDHLkV1n&( B162S3 literal 0 HcmV?d00001 diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_24.png b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_24.png new file mode 100644 index 0000000000000000000000000000000000000000..cd92289a05cad3202b78a1d775bfcda2a8a45356 GIT binary patch literal 731 zcmV<10wn#3P)J#GyVOeu3a|oOYl$<*cqO zGN6&Ehx=~~p0(Kk=c|W!_`IZ@o-R5oH7<2U_<#WoCCuDz(wVX>^FC4tsi(_z*3k&K zk{Aq=P1JN{WbAx@H`m!F-ASqtE(1BRIU2cewJI9j&eEsq(qn2qK1=8GC3 zJ5^)B0@&z)?v#yxQC`zRL1P-n_)x6@iz08f?3(zh_&~wimgE^9qp5LDw&rStF-knHnx@Brc4?gX;L1#D3da>=Q zx7d77HhhXs#q(7opDJeL8#9EVTO)_l!?Byw3H=bhbiGP#Vw!>lPq0K;g<+NqIRX@I zl=JSI8B>5WY}Q^$D2oGx!D3NDLL9m@Y@el5z2K4uf}ns>GV;YM;1^`90VJs(0+9d! N002ovPDHLkV1kPHMDzdv literal 0 HcmV?d00001 diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_32.png b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_i_32.png new file mode 100644 index 0000000000000000000000000000000000000000..eed17aab7caae5f02587cf3031522ea37d100125 GIT binary patch literal 651 zcmV;60(AX}P)kdg00002VoOIv0RM-N z%)bBt010qNS#tmY3ljhU3ljkVnw%H_000McNliru z_{lcsM9j&sqnw}&_Zyp*lj!@5IU^>+N|%Ui0|y@;P+z#iZ8nhz>Ee5B;L8NnC;Ig8 z5T1)4=Z>%i*jb-*Vlo*3$g7R74;<}ri%p~m1cI)L{3}s}fZpMN-`?spge~I((8WW@ ze^^9`Ag_KN+i&PYSn<4lH2^LM?BywxDMH}oYyAid5{t#?K@-?tA$QaGggGfzKp^OF zZM^;BbJHk=j>^IJ`Nmg%GL>%A7yTdacG~_zKjVaBPKhxRMqo*awhr61Pw#WYcTSkH zz<7n)B+RO-TW9LMe#kMC(l(9&4C&=?{TM)fbZ|2&1f?V=0Qxx-rX-lW#p(lqe!z@K z9RlbMrck5+gfa#ADG8^HnJ^~rUC))8-DEs6Sxq?JxM0+vs?h>p%bi002ovPDHLkV1mV18=L?D literal 0 HcmV?d00001 diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_r_24.png b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/images/delete_all_annotations_r_24.png new file mode 100644 index 0000000000000000000000000000000000000000..0929ba419a9427680b1225b0fdf4e3c457901e14 GIT binary patch literal 1311 zcmV+)1>pLLP)(9!fw_^jboREhMQevdAkNs>$eA{L9Ws;Zz|q}8ieW6hd1bm78<7m~^3=L;7u zd~4^U_H8ls;a1~tD~bwk1iP> zAO9g5jlSI6+&rDC5P1Vgk^}(g?CiwY*cjT|+rO@@tvyIY2_n(~*fIc=m6cITOAGt` z{@#X$hH#D?0Ej5B=d7}_5-V4(gkc!r{{H^k!C-Ji2=M@brDRLQ)z#HI0)arJxw#pw zt*y9t@#3Ql^BFV4SPbpa?v0)fHqR}V-psA_p zKRvcwA`J}<=C-v zmzS4+P+D4=$u%#pasVKe0@v0;ibP;3O6J76b^8*2|BxUW1E2wzZbWuC*|IEW48xf8 zdc7i7j>g7DB$LS*gLs+Ib?FiVAlbGHYp-4{`8g69ackN=01p5N#rbH8ii&K*Fsda< z@@krfW5dcD^bMHv)A3;`GgFaaP9;J(YUGA~U`WC)dI(Kj%~s1SdzJ3+O`$^h-wc32eTT)+3Gp53R?nbtNMD0G5E< z+}uo7DwVk~49_T~=AvhX5Vxh2-+P{yo0*we2O2;NXj^0s5fMj#OTb-UUw@(1YQ3$L zx*$Z~C3DAdoa+-46W3Cy)L%diXlg>CO+xelceb{+Qsr_v04@OJa=E?>HJi=;6L+QV zd!F|}CX@LX*aNCST}MR)LGUjD8+>D9<6OO7|3V0n7zDT%5!ZE>XJ=>M1IoaC9g#Mm zWTYNsp-_0X(P(^kTyPV$TrNke)q15+D0~P!0mOmFOd-pN_im%nxH@Ra`ytY7HqRG} z#g~925CdF5xVHECeExMI#2Ev=xVT8MSR4v8oldi`u+Xu#v$OL)@QtpA8qk*7djP4F zdihbcT;o)!RC*2=H)(L~|6M6Hx3aQwa471*N!Z@r-YoDnFk%SUMVPQZK28dHr9ued zXmIzS2raw)sHdOfI5oSKyODOfksJ-#@3l-?gVL8oV;(6YR z=XpQY>-E!0snFJbj^k9v#>Vb0-@N&*<@t+CLGY#Z9=E{54n1HOV?LjMM=AA@y%&$i zKbxMOUe+E|bfh{+ECs<=7T8(f0Z?5Ef|9lF81N27WJYqKP?%~qn^&ZikB^Lul*Y%$ zi<6U+8yfJQ78SdevN7O4TOd#B?+?3w002ovPDHLkV1f?> B0+;{* literal 0 HcmV?d00001 diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle.properties b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle.properties index a78244083..00f26e92b 100644 --- a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle.properties +++ b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle.properties @@ -109,6 +109,8 @@ viewer.toolbar.tool.text.label= viewer.toolbar.tool.text.tooltip=Text Select Tool viewer.toolbar.tool.select.label= viewer.toolbar.tool.select.tooltip=Select Tool +viewer.toolbar.tool.delete.all.label=Delete +viewer.toolbar.tool.delete.all.tooltip=Delete all annotations viewer.toolbar.tool.link.label= viewer.toolbar.tool.link.tooltip=Link Annotation Tool viewer.toolbar.tool.highlight.label=Highlight diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_de.properties b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_de.properties index 5959be0ff..bf00d15d0 100644 --- a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_de.properties +++ b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_de.properties @@ -517,4 +517,6 @@ viewer.annotation.signature.properties.dialog.revocation.failure=- Revokations\u viewer.annotation.signature.properties.dialog.certificateExpired.failure=- Signaturzertifikat ist abgelaufen. viewer.annotation.signature.properties.dialog.showCertificates.label=Signaturzertifikat... viewer.annotation.signature.properties.dialog.validity.title=G\u00FCltigkeitszusammenfassung -viewer.annotation.signature.properties.dialog.signerInfo.title=Unterzeichnerinformationen \ No newline at end of file +viewer.annotation.signature.properties.dialog.signerInfo.title=Unterzeichnerinformationen +viewer.toolbar.tool.delete.all.label=L\u00F6schen +viewer.toolbar.tool.delete.all.tooltip=Alle Notizen l\u00F6schen \ No newline at end of file diff --git a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_fr.properties b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_fr.properties index 024636356..33ff67735 100644 --- a/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_fr.properties +++ b/viewer/viewer-awt/src/main/resources/org/icepdf/ri/resources/MessageBundle_fr.properties @@ -508,4 +508,6 @@ viewer.annotation.signature.properties.dialog.revocation.failure=- Aucune v\u00E viewer.annotation.signature.properties.dialog.certificateExpired.failure=- Le certificat du signataire est \u00E9chu. viewer.annotation.signature.properties.dialog.showCertificates.label=Certificat du signataire... viewer.annotation.signature.properties.dialog.validity.title=R\u00E9sum\u00E9 de la validation -viewer.annotation.signature.properties.dialog.signerInfo.title=Informations sur le signataire \ No newline at end of file +viewer.annotation.signature.properties.dialog.signerInfo.title=Informations sur le signataire +viewer.toolbar.tool.delete.all.label=Supprimer +viewer.toolbar.tool.delete.all.tooltip=Supprimer toutes les annotations \ No newline at end of file From 1a25b00044e9bf326ed96dc008f58f7ff258ddcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20T=C3=A2che?= Date: Fri, 27 Oct 2023 16:06:01 +0200 Subject: [PATCH 2/2] GH-254 Fixes NPE when annotationComponent is null in MarkupAnnotationPopupMenu --- .../ri/common/views/annotations/MarkupAnnotationPopupMenu.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java index b18bde98f..d155bfdef 100644 --- a/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java +++ b/viewer/viewer-awt/src/main/java/org/icepdf/ri/common/views/annotations/MarkupAnnotationPopupMenu.java @@ -92,7 +92,7 @@ public MarkupAnnotationPopupMenu(MarkupAnnotationComponent markupAnnotationCompo public void buildGui() { ViewerPropertiesManager propertiesManager = ViewerPropertiesManager.getInstance(); boolean modifyDocument = controller.havePermissionToModifyDocument(); - boolean hasEditRights = ((MarkupAnnotation) annotationComponent.getAnnotation()).isCurrentUserOwner(); + boolean hasEditRights = annotationComponent != null && ((MarkupAnnotation) annotationComponent.getAnnotation()).isCurrentUserOwner(); boolean canModify = modifyDocument && hasEditRights; // status change commands. statusNoneMenuItem = new JMenuItem(