Revision: 15397
http://sourceforge.net/p/skim-app/code/15397
Author: hofman
Date: 2025-06-07 16:04:20 +0000 (Sat, 07 Jun 2025)
Log Message:
-----------
Undo adding and removing of notes also in bulk
Modified Paths:
--------------
trunk/SKMainWindowController.h
trunk/SKMainWindowController.m
Modified: trunk/SKMainWindowController.h
===================================================================
--- trunk/SKMainWindowController.h 2025-06-07 15:11:08 UTC (rev 15396)
+++ trunk/SKMainWindowController.h 2025-06-07 16:04:20 UTC (rev 15397)
@@ -242,6 +242,7 @@
- (void)insertObject:(PDFAnnotation *)note inNotesAtIndex:(NSUInteger)theIndex;
- (void)insertNotes:(NSArray *)newNotes atIndexes:(NSIndexSet *)theIndexes;
- (void)removeObjectFromNotesAtIndex:(NSUInteger)theIndex;
+- (void)removeNotesAtIndexes:(NSIndexSet *)theIndexes;
- (void)removeAllObjectsFromNotes;
@property (nonatomic, copy) NSArray<SKThumbnail *> *thumbnails;
Modified: trunk/SKMainWindowController.m
===================================================================
--- trunk/SKMainWindowController.m 2025-06-07 15:11:08 UTC (rev 15396)
+++ trunk/SKMainWindowController.m 2025-06-07 16:04:20 UTC (rev 15397)
@@ -965,20 +965,19 @@
return properties;
}
-- (void)addAnnotations:(NSArray *)notesToAdd removeAnnotations:(NSArray
*)notesToRemove {
+- (void)addAnnotations:(NSArray *)notesAndPagesToAdd
removeAnnotations:(NSArray *)notesToRemove {
PDFDocument *pdfDoc = [pdfView document];
NSMutableIndexSet *pageIndexes = [NSMutableIndexSet indexSet];
- NSMutableArray *added = [NSMutableArray array];
- NSMutableArray *removed = [NSMutableArray array];
- NSMutableArray *addedSkimNotes = [NSMutableArray array];
- NSMutableIndexSet *removedIndexes = [NSMutableIndexSet indexSet];
+ NSMutableArray *addedNotes = [NSMutableArray array];
+ NSMutableArray *removedNotesAndPages = [NSMutableArray array];
+ NSMutableIndexSet *removedIndexes = [[notesToRemove firstObject]
isSkimNote] ? [NSMutableIndexSet indexSet] : nil;
mwcFlags.addOrRemoveNotesInBulk = 1;
if ([notesToRemove count]) {
for (PDFAnnotation *annotation in notesToRemove) {
- [removed addObject:@[annotation, [annotation page]]];
- if ([annotation isSkimNote])
+ [removedNotesAndPages addObject:@[annotation, [annotation page]]];
+ if (removedIndexes)
[removedIndexes addIndex:[notes indexOfObject:annotation]];
[pageIndexes addIndex:[annotation pageIndex]];
[pdfDoc removeAnnotation:annotation];
@@ -985,12 +984,10 @@
}
}
- if ([notesToAdd count]) {
- for (NSArray *annotationAndPage in notesToAdd) {
+ if ([notesAndPagesToAdd count]) {
+ for (NSArray *annotationAndPage in notesAndPagesToAdd) {
PDFAnnotation *annotation = [annotationAndPage firstObject];
- [added addObject:annotation];
- if ([annotation isSkimNote])
- [addedSkimNotes addObject:annotation];
+ [addedNotes addObject:annotation];
[pageIndexes addIndex:[annotation pageIndex]];
[pdfDoc addAnnotation:annotation toPage:[annotationAndPage
lastObject]];
}
@@ -998,12 +995,14 @@
mwcFlags.addOrRemoveNotesInBulk = 0;
- [[[self undoManager] prepareWithInvocationTarget:self]
addAnnotations:removed removeAnnotations:added];
+ [[[self undoManager] prepareWithInvocationTarget:self]
addAnnotations:removedNotesAndPages removeAnnotations:addedNotes];
+ [removedIndexes removeIndex:NSNotFound];
+
if ([removedIndexes count])
- [[self mutableArrayValueForKey:NOTES_KEY]
removeObjectsAtIndexes:removedIndexes];
- if ([addedSkimNotes count])
- [self insertNotes:addedSkimNotes atIndexes:[NSIndexSet
indexSetWithIndexesInRange:NSMakeRange([notes count], [addedSkimNotes count])]];
+ [self removeNotesAtIndexes:removedIndexes];
+ if ([[addedNotes firstObject] isSkimNote])
+ [self insertNotes:addedNotes atIndexes:[NSIndexSet
indexSetWithIndexesInRange:NSMakeRange([addedNotes count], [addedNotes
count])]];
// make sure we clear the undo handling
undoGroupOldPropertiesPerNote = nil;
@@ -1017,18 +1016,16 @@
[pdfView resetPDFToolTipRects];
}
-- (void)addAnnotationsFromDictionaries:(NSArray *)noteDicts
toDocument:(PDFDocument *)pdfDoc pageIndexes:(NSMutableIndexSet *)pageIndexes
autoUpdate:(BOOL)autoUpdate {
- NSMutableArray *notesToAdd = [NSMutableArray array];
+- (NSArray *)annotationsAndPagesFromDictionaries:(NSArray *)noteDicts
forDocument:(PDFDocument *)pdfDoc autoUpdate:(BOOL)autoUpdate
widgetDictionaries:(NSMutableArray *)widgetDicts {
+ NSMutableArray *notesAndPagesToAdd = [NSMutableArray array];
BOOL shouldDisplay = [pdfView hideNotes] == NO;
- // disable automatic add/remove from the notification handlers
- // we want to do this in bulk as binding can be very slow and there are
potentially many notes
- mwcFlags.addOrRemoveNotesInBulk = 1;
-
- // create new annotations from the dictionary and add them to their page
and to the document
+ // create new annotations from the dictionary and get the page to add to
for (NSDictionary *dict in noteDicts) {
- if ([[dict objectForKey:SKNPDFAnnotationTypeKey]
isEqualToString:SKNWidgetString])
+ if ([[dict objectForKey:SKNPDFAnnotationTypeKey]
isEqualToString:SKNWidgetString]) {
+ [widgetDicts addObject:dict];
continue;
+ }
@autoreleasepool{
PDFAnnotation *annotation = [PDFAnnotation
newSkimNoteWithProperties:dict];
if (annotation) {
@@ -1037,59 +1034,43 @@
pageIndex = 0;
else if (pageIndex >= [pdfDoc pageCount])
pageIndex = [pdfDoc pageCount] - 1;
- [pageIndexes addIndex:pageIndex];
[annotation setShouldDisplay:shouldDisplay];
[annotation setShouldPrint:shouldDisplay];
PDFPage *page = [pdfDoc pageAtIndex:pageIndex];
if (autoUpdate && [[annotation contents] length] == 0)
[annotation autoUpdateStringWithPage:page];
- [pdfDoc addAnnotation:annotation toPage:page];
- [notesToAdd addObject:annotation];
+ [notesAndPagesToAdd addObject:@[annotation, page]];
}
}
}
- mwcFlags.addOrRemoveNotesInBulk = 0;
-
- if ([notesToAdd count] > 0)
- [self insertNotes:notesToAdd atIndexes:[NSIndexSet
indexSetWithIndexesInRange:NSMakeRange([notes count], [notesToAdd count])]];
+ return notesAndPagesToAdd;
}
- (void)addAnnotationsFromDictionaries:(NSArray *)noteDicts
removeAnnotations:(NSArray *)notesToRemove {
+ // notesToRemove is either [self notes], nil, or non Skim notes
BOOL isAddOrReplace = [notesToRemove count] == 0 || [[notesToRemove
firstObject] isSkimNote];
PDFDocument *pdfDoc = [pdfView document];
- NSMutableIndexSet *pageIndexes = [NSMutableIndexSet indexSet];
+ NSMutableArray *widgetDicts = [NSMutableArray array];
- if ([notesToRemove count]) {
- // notesToRemove is either [self notes], nil, or non Skim notes
- if (isAddOrReplace) {
- [pdfView removePDFToolTipRects];
- // remove the current annotations
- [pdfView setCurrentAnnotation:nil];
- }
- mwcFlags.addOrRemoveNotesInBulk = 1;
- for (PDFAnnotation *annotation in [notesToRemove copy]) {
- [pageIndexes addIndex:[annotation pageIndex]];
- [pdfDoc removeAnnotation:annotation];
- }
- mwcFlags.addOrRemoveNotesInBulk = 0;
- if (isAddOrReplace)
- [self removeAllObjectsFromNotes];
+ NSArray *notesAndPagesToAdd = [self
annotationsAndPagesFromDictionaries:noteDicts forDocument:pdfDoc
autoUpdate:isAddOrReplace == NO widgetDictionaries:widgetDicts];
+
+ if ([notesToRemove count] && isAddOrReplace) {
+ [pdfView removePDFToolTipRects];
+ // remove the current annotations
+ [pdfView setCurrentAnnotation:nil];
}
- if (notesToRemove && isAddOrReplace && [widgets count]) {
- for (PDFAnnotation *widget in widgets) {
- id origValue = [widgetValues objectForKey:widget];
- if ([([widget objectValue] ?: @"") isEqual:(origValue ?: @"")] ==
NO)
- [widget setObjectValue:origValue];
- }
- }
- [self addAnnotationsFromDictionaries:noteDicts toDocument:pdfDoc
pageIndexes:pageIndexes autoUpdate:isAddOrReplace == NO];
-
if (isAddOrReplace) {
- NSArray *widgetProperties = [noteDicts
filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"type =
\"Widget\""]];
- if ([widgetProperties count])
- [self changeWidgetsFromDictionaries:widgetProperties];
+ if (notesToRemove && [widgets count]) {
+ for (PDFAnnotation *widget in widgets) {
+ id origValue = [widgetValues objectForKey:widget];
+ if ([([widget objectValue] ?: @"") isEqual:(origValue ?: @"")]
== NO)
+ [widget setObjectValue:origValue];
+ }
+ }
+ if ([widgetDicts count])
+ [self changeWidgetsFromDictionaries:widgetDicts];
} else if ([widgets count]) {
NSMapTable *values = [NSMapTable strongToStrongObjectsMapTable];
for (PDFAnnotation *widget in widgets)
@@ -1098,16 +1079,7 @@
[self setWidgetValues:values];
}
- // make sure we clear the undo handling
- undoGroupOldPropertiesPerNote = nil;
- [rightSideController.noteArrayController rearrangeObjects]; // doesn't
seem to be done automatically
- [rightSideController.noteOutlineView reloadData];
- [self updateThumbnailsAtPageIndexes:pageIndexes];
- for (SKSnapshotWindowController *wc in snapshots) {
- if ([wc isPageInIndexesVisible:pageIndexes])
- [self snapshotNeedsUpdate:wc lowPriority:NO];
- }
- [pdfView resetPDFToolTipRects];
+ [self addAnnotations:notesAndPagesToAdd removeAnnotations:notesToRemove];
}
- (void)setPdfDocument:(PDFDocument *)pdfDocument
addAnnotationsFromDictionaries:(NSArray *)noteDicts {
@@ -1185,7 +1157,18 @@
[self applyChangedCropBoxes:cropBoxes inDocument:pdfDocument];
}
- [self addAnnotationsFromDictionaries:noteDicts toDocument:pdfDoc
pageIndexes:nil autoUpdate:NO];
+ if ([noteDicts count]) {
+ NSArray *notesAndPagesToAdd = [self
annotationsAndPagesFromDictionaries:noteDicts forDocument:pdfDoc autoUpdate:NO
widgetDictionaries:nil];
+ NSMutableArray *addedNotes = [NSMutableArray array];
+
+ for (NSArray *annotationAndPage in notesAndPagesToAdd) {
+ PDFAnnotation *annotation = [annotationAndPage firstObject];
+ [pdfDoc addAnnotation:annotation toPage:[annotationAndPage
lastObject]];
+ [addedNotes addObject:annotation];
+ }
+
+ [self insertNotes:addedNotes atIndexes:[NSIndexSet
indexSetWithIndexesInRange:NSMakeRange(0, [addedNotes count])]];
+ }
[pdfView setDocument:pdfDocument];
[pdfDocument setDelegate:self];
@@ -1419,6 +1402,23 @@
[notes removeObjectAtIndex:theIndex];
}
+- (void)removeNotesAtIndexes:(NSIndexSet *)theIndexes {
+ NSArray *removedNotes = [notes objectsAtIndexes:theIndexes];
+
+ for (PDFAnnotation *note in removedNotes) {
+ [[self windowControllerForNote:note] close];
+
+ if ([note hasNoteText])
+ [rightSideController.noteOutlineView setRowHeight:0.0
forItem:[note noteText]];
+ [rightSideController.noteOutlineView setRowHeight:0.0 forItem:note];
+ }
+
+ // Stop observing the removed notes
+ [self stopObservingNotes:removedNotes];
+
+ [notes removeObjectsAtIndexes:theIndexes];
+}
+
- (void)removeAllObjectsFromNotes {
if ([notes count]) {
NSArray *wcs = [[[self document] windowControllers] copy];
@@ -2254,9 +2254,9 @@
[self updateThumbnailAtPageIndex:[page pageIndex]];
[presentationView setNeedsDisplayForPage:page];
} else {
- [[undoManager prepareWithInvocationTarget:[notification object]]
removeAnnotation:annotation];
-
if (mwcFlags.addOrRemoveNotesInBulk == 0) {
+ [[undoManager prepareWithInvocationTarget:[notification object]]
removeAnnotation:annotation];
+
if ([annotation isSkimNote]) {
[annotation setShouldDisplay:[pdfView hideNotes] == NO];
[annotation setShouldPrint:[pdfView hideNotes] == NO];
@@ -2297,9 +2297,9 @@
[self updateThumbnailAtPageIndex:[page pageIndex]];
}
} else {
- [[undoManager prepareWithInvocationTarget:[notification object]]
addAnnotation:annotation toPage:page];
-
if (mwcFlags.addOrRemoveNotesInBulk == 0) {
+ [[undoManager prepareWithInvocationTarget:[notification object]]
addAnnotation:annotation toPage:page];
+
if ([annotation isSkimNote]) {
if ([[self selectedNotes] containsObject:annotation])
[rightSideController.noteOutlineView deselectAll:self];
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit