Version 1.1
This commit is contained in:
@@ -8,52 +8,191 @@
|
||||
|
||||
#import "LFDocument.h"
|
||||
|
||||
@implementation LFDocument
|
||||
void *const FolderNameChangedContext = @"FolderNameChangedContext";
|
||||
void *const TranslationsChangedContext = @"TranslationsChangedContext";
|
||||
|
||||
|
||||
@implementation LFDocument {
|
||||
NSString *_lastSavePanelEnteredFilename;
|
||||
NSString *_lastFolderName;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
// Add your subclass-specific initialization here.
|
||||
self.folder = [[LFFolder alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setFolder:(LFFolder *)f
|
||||
{
|
||||
[_folder removeObserver:self forKeyPath:@"translations"];
|
||||
[_folder removeObserver:self forKeyPath:@"folderName"];
|
||||
_folder = f;
|
||||
[_folder addObserver:self forKeyPath:@"translations" options:NSKeyValueObservingOptionOld context:TranslationsChangedContext];
|
||||
[_folder addObserver:self forKeyPath:@"folderName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:FolderNameChangedContext];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_folder removeObserver:self forKeyPath:@"translations"];
|
||||
[_folder removeObserver:self forKeyPath:@"folderName"];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
if (context == TranslationsChangedContext) {
|
||||
NSMutableDictionary *oldValue = change[NSKeyValueChangeOldKey];
|
||||
[self.undoManager registerUndoWithTarget:self.folder selector:@selector(setTranslations:) object:oldValue];
|
||||
} else if (context == FolderNameChangedContext) {
|
||||
NSString *oldName = change[NSKeyValueChangeOldKey];
|
||||
NSString *newName = change[NSKeyValueChangeNewKey];
|
||||
[self renameFolderFrom:oldName to:newName];
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renameFolderFrom:(id)oldName to:(id)newName
|
||||
{
|
||||
if (oldName == [NSNull null] || !oldName) {
|
||||
// Ignore initial change
|
||||
return;
|
||||
}
|
||||
if ([oldName isEqual:newName]) {
|
||||
return;
|
||||
}
|
||||
if ([newName isEqual:self.fileURL.lastPathComponent.stringByDeletingPathExtension]) {
|
||||
return;
|
||||
}
|
||||
NSString *actualNewName = [newName stringByAppendingPathExtension:LFLocalizedFolderExtension];
|
||||
NSURL *newURL = [self.fileURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:actualNewName isDirectory:YES];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:newURL.path]) {
|
||||
_lastFolderName = oldName;
|
||||
NSBeginAlertSheet(NSLocalizedString(@"The folder could not be renamed", nil), @"OK", nil, nil, self.windowForSheet, self, NULL, @selector(renameFolderSheetDidDismiss:returnCode:contextInfo:), NULL, NSLocalizedString(@"Another folder with the same name already exists at that location. Rename the existing folder or choose another name.", nil));
|
||||
return;
|
||||
}
|
||||
[self moveToURL:newURL completionHandler:^(NSError *error) {
|
||||
if (error) {
|
||||
[self presentError:error];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)renameFolderSheetDidDismiss:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
self.folder.folderName = _lastFolderName;
|
||||
}
|
||||
|
||||
- (NSString *)windowNibName
|
||||
{
|
||||
// Override returning the nib file name of the document
|
||||
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
|
||||
return @"LFDocument";
|
||||
}
|
||||
|
||||
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
|
||||
- (NSString *)autosavingFileType
|
||||
{
|
||||
[super windowControllerDidLoadNib:aController];
|
||||
// Add any code here that needs to be executed once the windowController has loaded the document's window.
|
||||
}
|
||||
|
||||
+ (BOOL)autosavesInPlace
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
|
||||
{
|
||||
// Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning nil.
|
||||
// You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
|
||||
NSException *exception = [NSException exceptionWithName:@"UnimplementedMethod" reason:[NSString stringWithFormat:@"%@ is unimplemented", NSStringFromSelector(_cmd)] userInfo:nil];
|
||||
@throw exception;
|
||||
// Autosave is disabled
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
|
||||
- (void)saveDocumentWithDelegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(void *)contextInfo
|
||||
{
|
||||
// Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO.
|
||||
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
|
||||
// If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.
|
||||
NSException *exception = [NSException exceptionWithName:@"UnimplementedMethod" reason:[NSString stringWithFormat:@"%@ is unimplemented", NSStringFromSelector(_cmd)] userInfo:nil];
|
||||
@throw exception;
|
||||
if (!self.fileURL) {
|
||||
[super saveDocumentWithDelegate:delegate didSaveSelector:didSaveSelector contextInfo:contextInfo];
|
||||
} else {
|
||||
NSString *title = NSLocalizedString(@"Do you want do delete the contents of the folder?", nil);
|
||||
NSString *deleteButton = NSLocalizedString(@"Delete Folder's Contents", nil);
|
||||
NSString *cancelButton = NSLocalizedString(@"Cancel", nil);
|
||||
NSString *applyButton = NSLocalizedString(@"Apply to...", nil);
|
||||
NSString *msgFormat = NSLocalizedString(@"If you save this document the contents of the folder will be deleted. If you want to keep the folder's contents select \"Apply to...\" and select the folder. In either way, this operation can not be undone.", nil);
|
||||
NSBeginCriticalAlertSheet(title, applyButton, cancelButton, deleteButton, self.windowForSheet, self, NULL, @selector(saveWarningSheetDidDismiss:returnCode:contextInfo:), NULL, @"%@", msgFormat);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)saveWarningSheetDidDismiss:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
if (returnCode == NSAlertDefaultReturn) {
|
||||
[self applyTo:self];
|
||||
} else if (returnCode == NSAlertOtherReturn) {
|
||||
[super saveDocumentWithDelegate:nil didSaveSelector:NULL contextInfo:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)applyTo:(id)sender
|
||||
{
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
openPanel.canChooseDirectories = YES;
|
||||
openPanel.canChooseFiles = NO;
|
||||
openPanel.allowsMultipleSelection = NO;
|
||||
openPanel.canCreateDirectories = YES;
|
||||
openPanel.message = NSLocalizedString(@"Select a directory you want to apply the current translations to", nil);
|
||||
openPanel.prompt = NSLocalizedString(@"Select", nil);
|
||||
[openPanel beginSheetModalForWindow:self.windowForSheet completionHandler:^(NSInteger result) {
|
||||
if (result == NSFileHandlingPanelOKButton) {
|
||||
[self applyToURL:openPanel.URL];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)applyToURL:(NSURL *)url
|
||||
{
|
||||
NSError *error;
|
||||
NSURL *actualURL = url;
|
||||
if (![actualURL.lastPathComponent hasSuffix:LFLocalizedFolderExtensionWithPeriod]) {
|
||||
actualURL = [actualURL URLByAppendingPathExtension:LFLocalizedFolderExtension];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:actualURL.path]) {
|
||||
NSRunAlertPanel(NSLocalizedString(@"The folder could not be localized", nil), NSLocalizedString(@"Another folder with the name \"%@\" already exists", nil), NSLocalizedString(@"OK", nil), nil, nil, actualURL.lastPathComponent);
|
||||
return;
|
||||
}
|
||||
[[NSFileManager defaultManager] moveItemAtURL:url toURL:actualURL error:&error];
|
||||
if (error) {
|
||||
[self presentError:error];
|
||||
return;
|
||||
}
|
||||
}
|
||||
LFFolder *folder = [[LFFolder alloc] initWithURL:actualURL error:&error];
|
||||
if (error) {
|
||||
[self presentError:error];
|
||||
return;
|
||||
}
|
||||
folder.translations = self.folder.translations.copy;
|
||||
[folder saveTranslationsToURL:actualURL error:&error];
|
||||
if (error) {
|
||||
[self presentError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)prepareSavePanel:(NSSavePanel *)savePanel
|
||||
{
|
||||
savePanel.directoryURL = self.fileURL.URLByDeletingLastPathComponent;
|
||||
savePanel.delegate = self;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag
|
||||
{
|
||||
NSString *newName = filename;
|
||||
if (![newName hasSuffix:LFLocalizedFolderExtensionWithPeriod]) {
|
||||
newName = [newName stringByAppendingPathExtension:LFLocalizedFolderExtension];
|
||||
}
|
||||
_lastSavePanelEnteredFilename = newName;
|
||||
return newName;
|
||||
}
|
||||
|
||||
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
|
||||
{
|
||||
if (!self.folder.folderName) {
|
||||
self.folder.folderName = _lastSavePanelEnteredFilename.stringByDeletingPathExtension;
|
||||
}
|
||||
return [self.folder saveTranslationsToURL:url error:outError];
|
||||
}
|
||||
|
||||
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
|
||||
{
|
||||
self.folder = [[LFFolder alloc] init];
|
||||
return [self.folder loadTranslationsFromURL:url error:outError];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user