Revision: 29374
          http://sourceforge.net/p/bibdesk/svn/29374
Author:   hofman
Date:     2025-07-28 08:36:23 +0000 (Mon, 28 Jul 2025)
Log Message:
-----------
change order of method implementations

Modified Paths:
--------------
    trunk/bibdesk/BibDocument.m

Modified: trunk/bibdesk/BibDocument.m
===================================================================
--- trunk/bibdesk/BibDocument.m 2025-07-26 22:45:41 UTC (rev 29373)
+++ trunk/bibdesk/BibDocument.m 2025-07-28 08:36:23 UTC (rev 29374)
@@ -994,6 +994,305 @@
 }
 
 #pragma mark -
+#pragma mark Opening and Loading Files
+
+- (BOOL)checkEncoding:(NSStringEncoding *)encodingPtr forURL:(NSURL 
*)absoluteURL error:(NSError **)outError {
+    // make sure we reread the setup from extended attributes from the file, 
in particular on revert
+    mainWindowSetupDictionary = nil;
+    
+    NSStringEncoding encoding = *encodingPtr;
+    
+    // This is only a sanity check; an encoding of 0 is not valid, so is a 
signal we should ignore xattrs; could only check for public.text UTIs, but it 
will be zero if it was never written (and we don't warn in that case).  The 
user can do many things to make the attribute incorrect, so this isn't very 
robust.
+    NSStringEncoding encodingFromFile = [self 
stringEncodingForSetupKey:BDSKDocumentStringEncodingKey 
defaultValue:BDSKNoStringEncoding];
+    
+    if (encodingFromFile == BDSKNoStringEncoding)
+        encodingFromFile = [[NSFileManager defaultManager] 
appleStringEncodingAtURL:absoluteURL error:NULL] ?: BDSKNoStringEncoding;
+    
+    if (encodingFromFile == BDSKNoStringEncoding || encodingFromFile == 
encoding)
+        return YES;
+    
+    if (outError) {
+        NSError *error = [NSError 
mutableLocalErrorWithCode:kBDSKStringEncodingError 
localizedDescription:NSLocalizedString(@"Incorrect encoding", @"Message in 
alert dialog when opening a document with different encoding")];
+        [error setValue:[NSString stringWithFormat:NSLocalizedString(@"BibDesk 
tried to open the document using encoding %@, but it should have been opened 
with encoding %@.", @"Informative text in alert dialog when opening a document 
with different encoding"), [NSString localizedNameOfStringEncoding:encoding], 
[NSString localizedNameOfStringEncoding:encodingFromFile]] 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+        [error setValue:absoluteURL forKey:NSURLErrorKey];
+        [error setValue:[NSNumber numberWithUnsignedInteger:encoding] 
forKey:NSStringEncodingErrorKey];
+        *outError = error;
+    }
+    
+    // If we allow the user to reopen here, NSDocumentController puts up an 
open failure here when we return NO from this instance, and the message appears 
after the successfully opened file is on-screen...which is confusing, to say 
the least.
+    NSAlert *alert = [[NSAlert alloc] init];
+    [alert setMessageText:NSLocalizedString(@"Incorrect encoding", @"error 
title when opening file")];
+    [alert setInformativeText:[NSString 
stringWithFormat:NSLocalizedString(@"The document will be opened with encoding 
%@, but it was previously saved with encoding %@.  You should cancel opening 
and then reopen with the correct encoding.", @"Informative text in alert dialog 
when opening a document with different encoding"), [NSString 
localizedNameOfStringEncoding:encoding], [NSString 
localizedNameOfStringEncoding:encodingFromFile]]];
+    [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Reopen", @"Button title")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Ignore", @"Button title")];
+    
+    NSInteger rv = [alert runModal];
+    
+    if (rv == NSAlertFirstButtonReturn) {
+        // the user said to give up
+        return NO;
+    } else if (rv == NSAlertSecondButtonReturn) {
+        // we just use the encoding which was used for saving
+        *encodingPtr = encodingFromFile;
+        return YES;
+    } else {
+        NSLog(@"User ignored encoding alert");
+        return YES;
+    }
+}
+
+- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)aType 
error:(NSError **)outError
+{
+    BOOL success = NO;
+    NSError *error = nil;
+    
+    // when using the Open panel this should be initialized to the selected 
encoding, otherwise the default encoding from the prefs, or for revert whatever 
it was
+    NSStringEncoding encoding = [[BDSKDocumentController 
sharedDocumentController] lastSelectedEncodingForURL:absoluteURL];
+    if (encoding == BDSKNoStringEncoding)
+        encoding = [self documentStringEncoding];
+    else
+        [self setDocumentStringEncoding:encoding];
+    
+    if (NO == [self checkEncoding:&encoding forURL:absoluteURL error:&error]) {
+        // wrong encoding and the user said to give up
+        if (outError) *outError = error;
+        return NO;
+    }
+    
+    NSData *data = [NSData dataWithContentsOfURL:absoluteURL 
options:NSUncachedRead error:&error];
+    if (data == nil) {
+        if (outError) *outError = error;
+        return NO;
+    }
+    
+    if ([aType isEqualToString:BDSKBibTeXDocumentType]){
+        success = [self readFromBibTeXData:data string:nil fromURL:absoluteURL 
encoding:encoding error:&error];
+    }else{
+        // sniff the string to see what format we got
+        NSString *string = [[NSString alloc] initWithData:data 
encoding:encoding];
+        BDSKStringType type = [string contentStringType];
+        if(string == nil){
+            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
+            [error setValue:[NSString 
stringWithFormat:NSLocalizedString(@"Unable to interpret data as %@.  Try a 
different encoding.", @"Error informative text"), [NSString 
localizedNameOfStringEncoding:encoding]] 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+            [error setValue:[NSNumber numberWithUnsignedInteger:encoding] 
forKey:NSStringEncodingErrorKey];
+        }else if(type == BDSKStringTypeBibTeX){
+            success = [self readFromBibTeXData:data string:string 
fromURL:absoluteURL encoding:encoding error:&error];
+        }else if (type == BDSKStringTypeNoKeyBibTeX){
+            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
+            [error setValue:NSLocalizedString(@"This file appears to contain 
invalid BibTeX because of missing cite keys. Try to open using temporary cite 
keys to fix this.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+        }else if (type == BDSKStringTypeUnknown){
+            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
+            [error setValue:NSLocalizedString(@"This text file does not 
contain a recognized data type.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+        }else{
+            NSArray *newPubs = [BDSKStringParser itemsFromString:string 
ofType:type error:&error];
+            if (newPubs) {
+                [self setPublications:newPubs macros:nil documentInfo:nil 
groups:nil frontMatter:nil encoding:[self documentStringEncoding]];
+                // since we can't save other files in their native format 
(BibTeX is handled separately)
+                [self setFileURL:nil];
+                success = YES;
+            } else {
+                error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
+                [error setValue:NSLocalizedString(@"This text file does not 
contain a recognized data type.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+            }
+        }
+    }
+    
+    if(success == NO && outError) *outError = error;
+    
+    return success;
+}
+
+- (BOOL)readFromBibTeXData:(NSData *)data string:(NSString *)string 
fromURL:(NSURL *)absoluteURL encoding:(NSStringEncoding)encoding error:(NSError 
**)outError {
+    NSURL *fileURL = absoluteURL;
+    NSStringEncoding parserEncoding = encoding;
+    
+    if ([BDSKBibTeXParser isUnparseableEncoding:encoding]) {
+        if (string == nil)
+            string = [[NSString alloc] initWithData:data encoding:encoding];
+        if([string canBeConvertedToEncoding:NSUTF8StringEncoding]){
+            data = [string dataUsingEncoding:NSUTF8StringEncoding];
+            fileURL = [[NSFileManager defaultManager] 
temporaryFileURLWithBasename:[fileURL lastPathComponent]];
+            [data writeToURL:fileURL atomically:YES];
+            parserEncoding = NSUTF8StringEncoding;
+        }else{
+            NSLog(@"Unable to convert data from encoding %@ to UTF-8", 
[NSString localizedNameOfStringEncoding:encoding]);
+        }
+    }
+    
+    NSError *error = nil;
+    NSArray *newPubs;
+    NSMapTable *newMacros = nil;
+    NSDictionary *newGroups = nil;
+    NSMutableDictionary *newDocumentInfo = nil;
+    NSString *newFrontMatter = nil;
+    
+    newPubs = [BDSKBibTeXParser itemsFromData:data macros:&newMacros 
documentInfo:&newDocumentInfo groups:&newGroups frontMatter:&newFrontMatter 
filePath:[fileURL path] owner:self encoding:parserEncoding error:&error];
+    
+    // do not autogenerate the cite key, unless it is empty or a placeholder
+    [newPubs makeObjectsPerformSelector:@selector(markCiteKeyEdited)];
+    
+    // @@ move this to NSDocumentController; need to figure out where to add 
it, though
+    // @@ should we check for kBDSKBibTeXParserFailed instead? The difference 
is whether we ignore warnings for circular macros 
(kBDSKParserIgnoredFrontMatter), which we used to do
+    if (error) {
+        NSError *recoveryError = [NSError mutableLocalErrorWithCode:[error 
code] localizedDescription:[error localizedDescription] ?: 
NSLocalizedString(@"Error reading file!", @"Message in alert dialog when unable 
to read file")];
+        [recoveryError setValue:NSLocalizedString(@"There was a problem 
reading the file.  Do you want to give up, edit the file to correct the errors, 
or keep going with everything that could be analyzed?\n\nIf you choose \"Keep 
Going\" and then save the file, you will probably lose data.", @"Informative 
text in alert dialog") forKey:NSLocalizedRecoverySuggestionErrorKey];
+        [recoveryError setValue:[BDSKErrorObjectController 
sharedErrorObjectController] forKey:NSRecoveryAttempterErrorKey];
+        [recoveryError setValue:@[NSLocalizedString(@"Give Up", @"Button 
title"), NSLocalizedString(@"Keep Going", @"Button title"), 
NSLocalizedString(@"Edit File", @"Button title")] 
forKey:NSLocalizedRecoveryOptionsErrorKey];
+        [recoveryError setValue:error forKey:NSUnderlyingErrorKey];
+        // initial read is before makeWindowControllers, tell the 
recoveryAttempter to remove this document when accepting the error
+        if ([[self windowControllers] count] == 0)
+            [recoveryError setValue:self forKey:BDSKFailedDocumentErrorKey];
+        
+        if ([self presentError:recoveryError])
+            // the user said to keep going, so if they save, they might 
clobber data...
+            // if we don't return YES, NSDocumentController puts up its lame 
alert saying the document could not be opened, and we get no partial data
+            error = nil;
+        else if (outError)
+            // return NSUserCancelledError so NSDocumentController won't show 
another alert
+            *outError = [NSError errorWithDomain:NSCocoaErrorDomain 
code:NSUserCancelledError userInfo:@{NSUnderlyingErrorKey:error}];
+    }
+    
+    if (fileURL != absoluteURL)
+        [[NSFileManager defaultManager] removeItemAtURL:fileURL error:NULL];
+    
+    if (error == nil) {
+        NSMapTable *newDocInfo = [[NSMapTable alloc] 
initWithKeyPointerFunctions:[NSPointerFunctions 
caseInsensitiveStringPointerFunctions] 
valuePointerFunctions:[NSPointerFunctions strongObjectPointerFunctions] 
capacity:0];
+        [newDocumentInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, 
NSString *value, BOOL *stop){
+            [newDocInfo setObject:value forKey:key];
+        }];
+        [self setPublications:newPubs macros:newMacros documentInfo:newDocInfo 
groups:newGroups frontMatter:newFrontMatter encoding:encoding];
+        return YES;
+    } else {
+        return NO;
+    }
+}
+
+- (BOOL)revertToContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName 
error:(NSError **)outError {
+    BOOL success = [super revertToContentsOfURL:absoluteURL ofType:typeName 
error:outError];
+    if (success)
+        [self runScriptHookWithName:BDSKScriptHookNameRevertDocument 
forPublications:nil];
+    return success;
+}
+
+- (void)setPublications:(NSArray *)newPubs macros:(NSMapTable *)newMacros 
documentInfo:(NSMapTable *)newDocumentInfo groups:(NSDictionary *)newGroups 
frontMatter:(NSString *)newFrontMatter encoding:(NSStringEncoding)newEncoding {
+    NSEnumerator *wcEnum = [[self windowControllers] objectEnumerator];
+    BOOL wasLoaded = nil != [wcEnum nextObject]; // initial read is before 
makeWindowControllers
+    
+    if (wasLoaded) {
+        NSArray *oldPubs = [publications copy];
+        NSMapTable *oldMacros = [[[self macroResolver] macroDefinitions] copy];
+        NSMutableDictionary *oldGroups = [NSMutableDictionary dictionary];
+        NSData *groupData;
+        
+        if ((groupData = serializedGroupsData([[self groups] smartGroups])))
+            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKSmartGroupType]];
+        if ((groupData = serializedGroupsData([[self groups] staticGroups])))
+            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKStaticGroupType]];
+        if ((groupData = serializedGroupsData([[self groups] URLGroups])))
+            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKURLGroupType]];
+        if ((groupData = serializedGroupsData([[self groups] scriptGroups])))
+            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKScriptGroupType]];
+        
+        [[[self undoManager] prepareWithInvocationTarget:self] 
setPublications:oldPubs macros:oldMacros documentInfo:[documentInfo copy] 
groups:oldGroups frontMatter:frontMatter encoding:[self 
documentStringEncoding]];
+        
+        // we need to stop the file search controller on revert, as this will 
be invalid after we update our publications
+        if ([self displaysControlView:BDSKControlViewFileSearch])
+            [self setSearchString:@""];
+        [fileSearchController terminateForDocumentURL:[self fileURL]];
+        fileSearchController = nil;
+        
+        // first remove all editor windows, as they will be invalid afterwards
+        NSWindowController *wc;
+        while ((wc = [wcEnum nextObject])) {
+            if ([wc respondsToSelector:@selector(discardEditing)])
+                [wc discardEditing];
+            [wc close];
+        }
+        
+        // make sure we clear all groups that are saved in the file, should 
only have those for revert
+        [groups removeAllUndoableGroups]; // this also removes editor windows 
for external groups
+    }
+    
+    [self setDocumentStringEncoding:newEncoding];
+    [self setPublications:newPubs];
+    documentInfo = [newDocumentInfo copy];
+    [[self macroResolver] setMacroDefinitions:newMacros];
+    // important that groups are loaded after publications, otherwise the 
static groups won't find their publications
+    [newGroups enumerateKeysAndObjectsUsingBlock:^(NSNumber *groupType, NSData 
*data, BOOL *stop){
+        [[self groups] setGroupsOfType:[groupType unsignedIntegerValue] 
fromSerializedData:data];
+    }];
+    frontMatter = newFrontMatter;
+    
+    if (wasLoaded) {
+        [self setSearchString:@""];
+        [self updateFilteringGroups];
+        [self sortGroupsByKey:nil]; // resort
+        [tableView deselectAll:self]; // clear before resorting
+        [self search:nil]; // redo the search
+        [self sortPubsByKey:nil]; // resort
+    }
+}
+
+#pragma mark -
+
+- (void)setDocumentStringEncoding:(NSStringEncoding)encoding{
+    docState.documentStringEncoding = encoding;
+}
+
+- (NSStringEncoding)documentStringEncoding{
+    return docState.documentStringEncoding;
+}
+
+#pragma mark -
+
+- (void)markAsImported {
+    // set date-added for imports
+    NSDate *importDate = [NSDate date];
+    NSString *importDateDescription = [importDate standardDescription];
+    for (BibItem *pub in publications)
+        [pub markNewWithDate:importDate description:importDateDescription];
+}
+
+- (void)generateForTemporaryCiteKey:(NSString *)tmpKey {
+    NSArray *selItems = [self selectedPublications];
+    [self selectPublications:[[self publications] itemsForCiteKey:tmpKey]];
+    [self generateCiteKeysForPublications:[self selectedPublications]];
+    [self selectPublications:selItems];
+}
+
+- (void)reportTemporaryCiteKeysForNewDocument:(BOOL)isNew{
+    if([publications count] == 0)
+        return;
+    
+    NSString *tmpKey = [BibItem placeholderCiteKey];
+    NSArray *tmpKeyItems = [[self publications] itemsForCiteKey:tmpKey];
+    
+    if([tmpKeyItems count] == 0)
+        return;
+    
+    if(isNew)
+        [self selectPublications:tmpKeyItems];
+    
+    NSString *infoFormat = isNew ? NSLocalizedString(@"This document was 
opened using the temporary cite key \"%@\" for the selected publications.  In 
order to use your file with BibTeX, you must generate valid cite keys for all 
of these items.  Do you want me to do this now?", @"Informative text in alert 
dialog")
+                            : NSLocalizedString(@"New items are added using 
the temporary cite key \"%@\".  In order to use your file with BibTeX, you must 
generate valid cite keys for these items.  Do you want me to do this now?", 
@"Informative text in alert dialog");
+    
+    NSAlert *alert = [[NSAlert alloc] init];
+    [alert setMessageText:NSLocalizedString(@"Temporary Cite Keys", @"Message 
in alert dialog when opening a file with temporary cite keys")];
+    [alert setInformativeText:[NSString stringWithFormat:infoFormat, tmpKey]];
+    [alert addButtonWithTitle:NSLocalizedString(@"Generate", @"Button title")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Don't Generate", @"Button 
title")];
+    if ([documentWindow attachedSheet] == nil) {
+        [alert beginSheetModalForWindow:documentWindow 
completionHandler:^(NSInteger returnCode){
+            if (returnCode == NSAlertFirstButtonReturn)
+                [self generateForTemporaryCiteKey:tmpKey];
+        }];
+    } else if ([alert runModal] == NSAlertFirstButtonReturn) {
+        [self generateForTemporaryCiteKey:tmpKey];
+    }
+}
+
+#pragma mark -
 #pragma mark  Document Saving
 
 + (NSArray *)writableTypes {
@@ -1718,305 +2017,6 @@
 }
 
 #pragma mark -
-#pragma mark Opening and Loading Files
-
-- (BOOL)checkEncoding:(NSStringEncoding *)encodingPtr forURL:(NSURL 
*)absoluteURL error:(NSError **)outError {
-    // make sure we reread the setup from extended attributes from the file, 
in particular on revert
-    mainWindowSetupDictionary = nil;
-    
-    NSStringEncoding encoding = *encodingPtr;
-    
-    // This is only a sanity check; an encoding of 0 is not valid, so is a 
signal we should ignore xattrs; could only check for public.text UTIs, but it 
will be zero if it was never written (and we don't warn in that case).  The 
user can do many things to make the attribute incorrect, so this isn't very 
robust.
-    NSStringEncoding encodingFromFile = [self 
stringEncodingForSetupKey:BDSKDocumentStringEncodingKey 
defaultValue:BDSKNoStringEncoding];
-    
-    if (encodingFromFile == BDSKNoStringEncoding)
-        encodingFromFile = [[NSFileManager defaultManager] 
appleStringEncodingAtURL:absoluteURL error:NULL] ?: BDSKNoStringEncoding;
-    
-    if (encodingFromFile == BDSKNoStringEncoding || encodingFromFile == 
encoding)
-        return YES;
-    
-    if (outError) {
-        NSError *error = [NSError 
mutableLocalErrorWithCode:kBDSKStringEncodingError 
localizedDescription:NSLocalizedString(@"Incorrect encoding", @"Message in 
alert dialog when opening a document with different encoding")];
-        [error setValue:[NSString stringWithFormat:NSLocalizedString(@"BibDesk 
tried to open the document using encoding %@, but it should have been opened 
with encoding %@.", @"Informative text in alert dialog when opening a document 
with different encoding"), [NSString localizedNameOfStringEncoding:encoding], 
[NSString localizedNameOfStringEncoding:encodingFromFile]] 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-        [error setValue:absoluteURL forKey:NSURLErrorKey];
-        [error setValue:[NSNumber numberWithUnsignedInteger:encoding] 
forKey:NSStringEncodingErrorKey];
-        *outError = error;
-    }
-    
-    // If we allow the user to reopen here, NSDocumentController puts up an 
open failure here when we return NO from this instance, and the message appears 
after the successfully opened file is on-screen...which is confusing, to say 
the least.
-    NSAlert *alert = [[NSAlert alloc] init];
-    [alert setMessageText:NSLocalizedString(@"Incorrect encoding", @"error 
title when opening file")];
-    [alert setInformativeText:[NSString 
stringWithFormat:NSLocalizedString(@"The document will be opened with encoding 
%@, but it was previously saved with encoding %@.  You should cancel opening 
and then reopen with the correct encoding.", @"Informative text in alert dialog 
when opening a document with different encoding"), [NSString 
localizedNameOfStringEncoding:encoding], [NSString 
localizedNameOfStringEncoding:encodingFromFile]]];
-    [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
-    [alert addButtonWithTitle:NSLocalizedString(@"Reopen", @"Button title")];
-    [alert addButtonWithTitle:NSLocalizedString(@"Ignore", @"Button title")];
-    
-    NSInteger rv = [alert runModal];
-    
-    if (rv == NSAlertFirstButtonReturn) {
-        // the user said to give up
-        return NO;
-    } else if (rv == NSAlertSecondButtonReturn) {
-        // we just use the encoding which was used for saving
-        *encodingPtr = encodingFromFile;
-        return YES;
-    } else {
-        NSLog(@"User ignored encoding alert");
-        return YES;
-    }
-}
-
-- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)aType 
error:(NSError **)outError
-{
-    BOOL success = NO;
-    NSError *error = nil;
-    
-    // when using the Open panel this should be initialized to the selected 
encoding, otherwise the default encoding from the prefs, or for revert whatever 
it was
-    NSStringEncoding encoding = [[BDSKDocumentController 
sharedDocumentController] lastSelectedEncodingForURL:absoluteURL];
-    if (encoding == BDSKNoStringEncoding)
-        encoding = [self documentStringEncoding];
-    else
-        [self setDocumentStringEncoding:encoding];
-    
-    if (NO == [self checkEncoding:&encoding forURL:absoluteURL error:&error]) {
-        // wrong encoding and the user said to give up
-        if (outError) *outError = error;
-        return NO;
-    }
-    
-    NSData *data = [NSData dataWithContentsOfURL:absoluteURL 
options:NSUncachedRead error:&error];
-    if (data == nil) {
-        if (outError) *outError = error;
-        return NO;
-    }
-    
-       if ([aType isEqualToString:BDSKBibTeXDocumentType]){
-        success = [self readFromBibTeXData:data string:nil fromURL:absoluteURL 
encoding:encoding error:&error];
-    }else{
-               // sniff the string to see what format we got
-        NSString *string = [[NSString alloc] initWithData:data 
encoding:encoding];
-        BDSKStringType type = [string contentStringType];
-        if(string == nil){
-            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
-            [error setValue:[NSString 
stringWithFormat:NSLocalizedString(@"Unable to interpret data as %@.  Try a 
different encoding.", @"Error informative text"), [NSString 
localizedNameOfStringEncoding:encoding]] 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-            [error setValue:[NSNumber numberWithUnsignedInteger:encoding] 
forKey:NSStringEncodingErrorKey];
-        }else if(type == BDSKStringTypeBibTeX){
-            success = [self readFromBibTeXData:data string:string 
fromURL:absoluteURL encoding:encoding error:&error];
-               }else if (type == BDSKStringTypeNoKeyBibTeX){
-            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
-            [error setValue:NSLocalizedString(@"This file appears to contain 
invalid BibTeX because of missing cite keys. Try to open using temporary cite 
keys to fix this.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-               }else if (type == BDSKStringTypeUnknown){
-            error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
-            [error setValue:NSLocalizedString(@"This text file does not 
contain a recognized data type.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-        }else{
-            NSArray *newPubs = [BDSKStringParser itemsFromString:string 
ofType:type error:&error];
-            if (newPubs) {
-                [self setPublications:newPubs macros:nil documentInfo:nil 
groups:nil frontMatter:nil encoding:[self documentStringEncoding]];
-                // since we can't save other files in their native format 
(BibTeX is handled separately)
-                [self setFileURL:nil];
-                success = YES;
-            } else {
-                error = [NSError mutableLocalErrorWithCode:kBDSKParserFailed 
localizedDescription:NSLocalizedString(@"Unable To Open Document", @"Error 
description")];
-                [error setValue:NSLocalizedString(@"This text file does not 
contain a recognized data type.", @"Error informative text") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-            }
-        }
-       }
-    
-    if(success == NO && outError) *outError = error;
-    
-    return success;
-}
-
-- (BOOL)readFromBibTeXData:(NSData *)data string:(NSString *)string 
fromURL:(NSURL *)absoluteURL encoding:(NSStringEncoding)encoding error:(NSError 
**)outError {
-    NSURL *fileURL = absoluteURL;
-    NSStringEncoding parserEncoding = encoding;
-    
-    if ([BDSKBibTeXParser isUnparseableEncoding:encoding]) {
-        if (string == nil)
-            string = [[NSString alloc] initWithData:data encoding:encoding];
-        if([string canBeConvertedToEncoding:NSUTF8StringEncoding]){
-            data = [string dataUsingEncoding:NSUTF8StringEncoding];
-            fileURL = [[NSFileManager defaultManager] 
temporaryFileURLWithBasename:[fileURL lastPathComponent]];
-            [data writeToURL:fileURL atomically:YES];
-            parserEncoding = NSUTF8StringEncoding;
-        }else{
-            NSLog(@"Unable to convert data from encoding %@ to UTF-8", 
[NSString localizedNameOfStringEncoding:encoding]);
-        }
-    }
-    
-    NSError *error = nil;
-       NSArray *newPubs;
-       NSMapTable *newMacros = nil;
-       NSDictionary *newGroups = nil;
-       NSMutableDictionary *newDocumentInfo = nil;
-       NSString *newFrontMatter = nil;
-    
-    newPubs = [BDSKBibTeXParser itemsFromData:data macros:&newMacros 
documentInfo:&newDocumentInfo groups:&newGroups frontMatter:&newFrontMatter 
filePath:[fileURL path] owner:self encoding:parserEncoding error:&error];
-    
-    // do not autogenerate the cite key, unless it is empty or a placeholder
-    [newPubs makeObjectsPerformSelector:@selector(markCiteKeyEdited)];
-    
-    // @@ move this to NSDocumentController; need to figure out where to add 
it, though
-    // @@ should we check for kBDSKBibTeXParserFailed instead? The difference 
is whether we ignore warnings for circular macros 
(kBDSKParserIgnoredFrontMatter), which we used to do
-    if (error) {
-        NSError *recoveryError = [NSError mutableLocalErrorWithCode:[error 
code] localizedDescription:[error localizedDescription] ?: 
NSLocalizedString(@"Error reading file!", @"Message in alert dialog when unable 
to read file")];
-        [recoveryError setValue:NSLocalizedString(@"There was a problem 
reading the file.  Do you want to give up, edit the file to correct the errors, 
or keep going with everything that could be analyzed?\n\nIf you choose \"Keep 
Going\" and then save the file, you will probably lose data.", @"Informative 
text in alert dialog") forKey:NSLocalizedRecoverySuggestionErrorKey];
-        [recoveryError setValue:[BDSKErrorObjectController 
sharedErrorObjectController] forKey:NSRecoveryAttempterErrorKey];
-        [recoveryError setValue:@[NSLocalizedString(@"Give Up", @"Button 
title"), NSLocalizedString(@"Keep Going", @"Button title"), 
NSLocalizedString(@"Edit File", @"Button title")] 
forKey:NSLocalizedRecoveryOptionsErrorKey];
-        [recoveryError setValue:error forKey:NSUnderlyingErrorKey];
-        // initial read is before makeWindowControllers, tell the 
recoveryAttempter to remove this document when accepting the error
-        if ([[self windowControllers] count] == 0)
-            [recoveryError setValue:self forKey:BDSKFailedDocumentErrorKey];
-        
-        if ([self presentError:recoveryError])
-            // the user said to keep going, so if they save, they might 
clobber data...
-            // if we don't return YES, NSDocumentController puts up its lame 
alert saying the document could not be opened, and we get no partial data
-            error = nil;
-        else if (outError)
-            // return NSUserCancelledError so NSDocumentController won't show 
another alert
-            *outError = [NSError errorWithDomain:NSCocoaErrorDomain 
code:NSUserCancelledError userInfo:@{NSUnderlyingErrorKey:error}];
-    }
-    
-    if (fileURL != absoluteURL)
-        [[NSFileManager defaultManager] removeItemAtURL:fileURL error:NULL];
-    
-    if (error == nil) {
-        NSMapTable *newDocInfo = [[NSMapTable alloc] 
initWithKeyPointerFunctions:[NSPointerFunctions 
caseInsensitiveStringPointerFunctions] 
valuePointerFunctions:[NSPointerFunctions strongObjectPointerFunctions] 
capacity:0];
-        [newDocumentInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, 
NSString *value, BOOL *stop){
-            [newDocInfo setObject:value forKey:key];
-        }];
-        [self setPublications:newPubs macros:newMacros documentInfo:newDocInfo 
groups:newGroups frontMatter:newFrontMatter encoding:encoding];
-        return YES;
-    } else {
-        return NO;
-    }
-}
-
-- (BOOL)revertToContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName 
error:(NSError **)outError {
-    BOOL success = [super revertToContentsOfURL:absoluteURL ofType:typeName 
error:outError];
-    if (success)
-        [self runScriptHookWithName:BDSKScriptHookNameRevertDocument 
forPublications:nil];
-    return success;
-}
-
-- (void)setPublications:(NSArray *)newPubs macros:(NSMapTable *)newMacros 
documentInfo:(NSMapTable *)newDocumentInfo groups:(NSDictionary *)newGroups 
frontMatter:(NSString *)newFrontMatter encoding:(NSStringEncoding)newEncoding {
-    NSEnumerator *wcEnum = [[self windowControllers] objectEnumerator];
-    BOOL wasLoaded = nil != [wcEnum nextObject]; // initial read is before 
makeWindowControllers
-    
-    if (wasLoaded) {
-        NSArray *oldPubs = [publications copy];
-        NSMapTable *oldMacros = [[[self macroResolver] macroDefinitions] copy];
-        NSMutableDictionary *oldGroups = [NSMutableDictionary dictionary];
-        NSData *groupData;
-        
-        if ((groupData = serializedGroupsData([[self groups] smartGroups])))
-            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKSmartGroupType]];
-        if ((groupData = serializedGroupsData([[self groups] staticGroups])))
-            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKStaticGroupType]];
-        if ((groupData = serializedGroupsData([[self groups] URLGroups])))
-            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKURLGroupType]];
-        if ((groupData = serializedGroupsData([[self groups] scriptGroups])))
-            [oldGroups setObject:groupData forKey:[NSNumber 
numberWithUnsignedInteger:BDSKScriptGroupType]];
-        
-        [[[self undoManager] prepareWithInvocationTarget:self] 
setPublications:oldPubs macros:oldMacros documentInfo:[documentInfo copy] 
groups:oldGroups frontMatter:frontMatter encoding:[self 
documentStringEncoding]];
-        
-        // we need to stop the file search controller on revert, as this will 
be invalid after we update our publications
-        if ([self displaysControlView:BDSKControlViewFileSearch])
-            [self setSearchString:@""];
-        [fileSearchController terminateForDocumentURL:[self fileURL]];
-        fileSearchController = nil;
-        
-        // first remove all editor windows, as they will be invalid afterwards
-        NSWindowController *wc;
-        while ((wc = [wcEnum nextObject])) {
-            if ([wc respondsToSelector:@selector(discardEditing)])
-                [wc discardEditing];
-            [wc close];
-        }
-        
-        // make sure we clear all groups that are saved in the file, should 
only have those for revert
-        [groups removeAllUndoableGroups]; // this also removes editor windows 
for external groups
-    }
-    
-    [self setDocumentStringEncoding:newEncoding];
-    [self setPublications:newPubs];
-    documentInfo = [newDocumentInfo copy];
-    [[self macroResolver] setMacroDefinitions:newMacros];
-    // important that groups are loaded after publications, otherwise the 
static groups won't find their publications
-    [newGroups enumerateKeysAndObjectsUsingBlock:^(NSNumber *groupType, NSData 
*data, BOOL *stop){
-        [[self groups] setGroupsOfType:[groupType unsignedIntegerValue] 
fromSerializedData:data];
-    }];
-    frontMatter = newFrontMatter;
-    
-    if (wasLoaded) {
-        [self setSearchString:@""];
-        [self updateFilteringGroups];
-        [self sortGroupsByKey:nil]; // resort
-        [tableView deselectAll:self]; // clear before resorting
-        [self search:nil]; // redo the search
-        [self sortPubsByKey:nil]; // resort
-    }
-}
-
-#pragma mark -
-
-- (void)setDocumentStringEncoding:(NSStringEncoding)encoding{
-    docState.documentStringEncoding = encoding;
-}
-
-- (NSStringEncoding)documentStringEncoding{
-    return docState.documentStringEncoding;
-}
-
-#pragma mark -
-
-- (void)markAsImported {
-    // set date-added for imports
-    NSDate *importDate = [NSDate date];
-    NSString *importDateDescription = [importDate standardDescription];
-    for (BibItem *pub in publications)
-        [pub markNewWithDate:importDate description:importDateDescription];
-}
-
-- (void)generateForTemporaryCiteKey:(NSString *)tmpKey {
-    NSArray *selItems = [self selectedPublications];
-    [self selectPublications:[[self publications] itemsForCiteKey:tmpKey]];
-    [self generateCiteKeysForPublications:[self selectedPublications]];
-    [self selectPublications:selItems];
-}
-
-- (void)reportTemporaryCiteKeysForNewDocument:(BOOL)isNew{
-    if([publications count] == 0)
-        return;
-    
-    NSString *tmpKey = [BibItem placeholderCiteKey];
-    NSArray *tmpKeyItems = [[self publications] itemsForCiteKey:tmpKey];
-    
-    if([tmpKeyItems count] == 0)
-        return;
-    
-    if(isNew)
-        [self selectPublications:tmpKeyItems];
-    
-    NSString *infoFormat = isNew ? NSLocalizedString(@"This document was 
opened using the temporary cite key \"%@\" for the selected publications.  In 
order to use your file with BibTeX, you must generate valid cite keys for all 
of these items.  Do you want me to do this now?", @"Informative text in alert 
dialog")
-                            : NSLocalizedString(@"New items are added using 
the temporary cite key \"%@\".  In order to use your file with BibTeX, you must 
generate valid cite keys for these items.  Do you want me to do this now?", 
@"Informative text in alert dialog");
-    
-    NSAlert *alert = [[NSAlert alloc] init];
-    [alert setMessageText:NSLocalizedString(@"Temporary Cite Keys", @"Message 
in alert dialog when opening a file with temporary cite keys")];
-    [alert setInformativeText:[NSString stringWithFormat:infoFormat, tmpKey]];
-    [alert addButtonWithTitle:NSLocalizedString(@"Generate", @"Button title")];
-    [alert addButtonWithTitle:NSLocalizedString(@"Don't Generate", @"Button 
title")];
-    if ([documentWindow attachedSheet] == nil) {
-        [alert beginSheetModalForWindow:documentWindow 
completionHandler:^(NSInteger returnCode){
-            if (returnCode == NSAlertFirstButtonReturn)
-                [self generateForTemporaryCiteKey:tmpKey];
-        }];
-    } else if ([alert runModal] == NSAlertFirstButtonReturn) {
-        [self generateForTemporaryCiteKey:tmpKey];
-    }
-}
-
-#pragma mark -
 #pragma mark String representations
 
 - (NSString *)bibTeXStringDroppingInternal:(BOOL)drop forPublications:(NSArray 
*)items{

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to