diff --git a/Frameworks/DocumentWindow/src/DocumentSaveHelper.h b/Frameworks/DocumentWindow/src/DocumentSaveHelper.h deleted file mode 100644 index 8292d3b0..00000000 --- a/Frameworks/DocumentWindow/src/DocumentSaveHelper.h +++ /dev/null @@ -1,8 +0,0 @@ -#import - -@interface DocumentSaveHelper : NSObject -+ (void)trySaveDocuments:(std::vector const&)someDocuments forWindow:(NSWindow*)aWindow defaultDirectory:(NSString*)aFolder completionHandler:(void(^)(BOOL success))callback; -+ (void)trySaveDocument:(document::document_ptr const&)aDocument forWindow:(NSWindow*)aWindow defaultDirectory:(NSString*)aFolder completionHandler:(void(^)(BOOL success))callback; -@end - -NSString* DefaultSaveNameForDocument (document::document_ptr const& aDocument); diff --git a/Frameworks/DocumentWindow/src/DocumentSaveHelper.mm b/Frameworks/DocumentWindow/src/DocumentSaveHelper.mm deleted file mode 100644 index 08919ccb..00000000 --- a/Frameworks/DocumentWindow/src/DocumentSaveHelper.mm +++ /dev/null @@ -1,232 +0,0 @@ -#import "DocumentSaveHelper.h" -#import "DocumentCommand.h" -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -OAK_DEBUG_VAR(DocumentController_SaveHelper); - -NSString* DefaultSaveNameForDocument (document::document_ptr const& aDocument) -{ - for(auto const& item : bundles::query(bundles::kFieldGrammarScope, aDocument->file_type())) - { - std::string const& ext = item->value_for_field(bundles::kFieldGrammarExtension); - if(ext != NULL_STR) - return [NSString stringWithCxxString:aDocument->display_name() + "." + ext]; - } - return [NSString stringWithCxxString:aDocument->display_name()]; -} - -@interface DocumentSaveHelper () -{ - std::vector documents; - file::save_context_ptr context; -} -- (void)didSaveDocument:(document::document_ptr const&)aDocument success:(BOOL)flag error:(std::string const&)aMessage usingFilter:(oak::uuid_t const&)aFilter; -- (file::save_context_ptr const&)context; -- (void)setContext:(file::save_context_ptr const&)newContext; -@property (nonatomic) NSWindow* window; -@property (nonatomic) NSString* saveFolder; -@property (nonatomic) BOOL userAbort; -@property (nonatomic) BOOL failed; -@property (nonatomic, copy) void (^callback)(BOOL); -@end - -namespace -{ - struct save_callback_t : document::save_callback_t - { - save_callback_t (document::document_ptr document, DocumentSaveHelper* self, NSWindow* window) : _document(document), _self(self), _window(window) { } - - void select_path (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) - { - D(DBF_DocumentController_SaveHelper, bug("\n");); - init(context); - - [OakSavePanel showWithPath:DefaultSaveNameForDocument(_document) directory:_self.saveFolder fowWindow:_window encoding:_document->disk_encoding() completionHandler:^(NSString* path, encoding::type const& encoding){ - D(DBF_DocumentController_SaveHelper, bug("%s\n", to_s(path).c_str());); - if(path) - { - _document->set_path(to_s(path)); - _document->set_disk_encoding(encoding); - context->set_path(to_s(path)); - } - else - { - _self.userAbort = YES; - } - [_self setContext:file::save_context_ptr()]; - }]; - } - - void select_make_writable (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) - { - D(DBF_DocumentController_SaveHelper, bug("\n");); - init(context); - - // TODO “unlock file” checkbox (presently implied) - NSAlert* alert = [NSAlert tmAlertWithMessageText:[NSString stringWithCxxString:text::format("The file “%s” is locked.", _document->display_name().c_str())] informativeText:@"Do you want to overwrite it anyway?" buttons:@"Overwrite", @"Cancel", nil]; - OakShowAlertForWindow(alert, _window, ^(NSInteger returnCode){ - if(returnCode == NSAlertFirstButtonReturn) - context->set_make_writable(true); - else _self.userAbort = YES; - [_self setContext:file::save_context_ptr()]; - }); - } - - void select_create_parent (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) - { - D(DBF_DocumentController_SaveHelper, bug("\n");); - init(context); - - NSAlert* alert = [NSAlert tmAlertWithMessageText:[NSString stringWithCxxString:text::format("No parent folder for “%s”.", _document->display_name().c_str())] informativeText:[NSString stringWithFormat:@"Do you wish to create a folder at “%@”?", [NSString stringWithCxxString:path::with_tilde(path::parent(path))]] buttons:@"Create Folder", @"Cancel", nil]; - OakShowAlertForWindow(alert, _window, ^(NSInteger returnCode){ - if(returnCode == NSAlertFirstButtonReturn) - context->set_create_parent(true); - else _self.userAbort = YES; - [_self setContext:file::save_context_ptr()]; - }); - } - - void obtain_authorization (std::string const& path, io::bytes_ptr content, osx::authorization_t auth, file::save_context_ptr context) - { - D(DBF_DocumentController_SaveHelper, bug("\n");); - if(auth.obtain_right(kAuthRightName)) - context->set_authorization(auth); - else _self.userAbort = YES; - } - - void select_charset (std::string const& path, io::bytes_ptr content, std::string const& charset, file::save_context_ptr context) - { - D(DBF_DocumentController_SaveHelper, bug("\n");); - init(context); - - if(charset != kCharsetNoEncoding) - { - NSAlert* alert = [NSAlert tmAlertWithMessageText:[NSString stringWithCxxString:text::format("Unable to save document using “%s” as encoding.", charset.c_str())] informativeText:@"Please choose another encoding:" buttons:@"Retry", @"Cancel", nil]; - OakEncodingPopUpButton* encodingPopUp = [OakEncodingPopUpButton new]; - [alert setAccessoryView:encodingPopUp]; - OakShowAlertForWindow(alert, _window, ^(NSInteger returnCode){ - if(returnCode == NSAlertFirstButtonReturn) - context->set_charset(to_s(encodingPopUp.encoding)); - else _self.userAbort = YES; - [_self setContext:file::save_context_ptr()]; - }); - [[alert window] recalculateKeyViewLoop]; - } - else - { - context->set_charset(kCharsetUTF8); - } - } - - void did_save_document (document::document_ptr document, std::string const& path, bool success, std::string const& message, oak::uuid_t const& filter) - { - D(DBF_DocumentController_SaveHelper, bug("%s, %s\n", path.c_str(), BSTR(success));); - [_self didSaveDocument:document success:success error:message usingFilter:filter]; - } - - private: - void init (file::save_context_ptr context) - { - document::show(_document); - for(NSWindow* window in [NSApp orderedWindows]) - { - id delegate = [window delegate]; - if(![window isMiniaturized] && [delegate isKindOfClass:[[_window delegate] class]]) - { - _window = [delegate window]; - break; - } - } - - [_window.attachedSheet orderOut:_self]; - [_self setContext:context]; - } - - document::document_ptr _document; - DocumentSaveHelper* _self; - NSWindow* _window; - }; -} - -@implementation DocumentSaveHelper -- (id)init -{ - D(DBF_DocumentController_SaveHelper, bug("\n");); - if(self = [super init]) - { - } - return self; -} - -+ (void)trySaveDocuments:(std::vector const&)someDocuments forWindow:(NSWindow*)aWindow defaultDirectory:(NSString*)aFolder completionHandler:(void(^)(BOOL success))callback -{ - [[[DocumentSaveHelper alloc] init] trySaveDocuments:someDocuments forWindow:aWindow defaultDirectory:aFolder completionHandler:callback]; -} - -+ (void)trySaveDocument:(document::document_ptr const&)aDocument forWindow:(NSWindow*)aWindow defaultDirectory:(NSString*)aFolder completionHandler:(void(^)(BOOL success))callback -{ - [DocumentSaveHelper trySaveDocuments:std::vector(1, aDocument) forWindow:aWindow defaultDirectory:aFolder completionHandler:callback]; -} - -- (void)dealloc -{ - D(DBF_DocumentController_SaveHelper, bug("\n");); -} - -- (file::save_context_ptr const&)context { return context; } -- (void)setContext:(file::save_context_ptr const&)newContext { context = newContext; } - -- (void)saveNextDocument:(id)sender -{ - if(documents.empty() || self.failed) - { - if(self.callback) - self.callback(!self.failed); - documents.clear(); - return; - } - - document::document_ptr document = documents.back(); - D(DBF_DocumentController_SaveHelper, bug("%s (%zu total)\n", document->display_name().c_str(), documents.size());); - document->try_save(std::make_shared(document, self, self.window)); -} - -- (void)trySaveDocuments:(std::vector const&)someDocuments forWindow:(NSWindow*)aWindow defaultDirectory:(NSString*)aFolder completionHandler:(void(^)(BOOL success))callback -{ - documents = someDocuments; - self.window = aWindow; - self.saveFolder = aFolder; - self.callback = callback; - - std::reverse(documents.begin(), documents.end()); - [self saveNextDocument:self]; -} - -- (void)didSaveDocument:(document::document_ptr const&)aDocument success:(BOOL)flag error:(std::string const&)aMessage usingFilter:(oak::uuid_t const&)aFilter -{ - D(DBF_DocumentController_SaveHelper, bug("‘%s’, success %s, user abort %s\n", aDocument->path().c_str(), BSTR(flag), BSTR(self.userAbort));); - if(!flag && !self.userAbort) - { - [self.window.attachedSheet orderOut:self]; - if(aFilter) - show_command_error(aMessage, aFilter, self.window); - else [[NSAlert tmAlertWithMessageText:[NSString stringWithCxxString:text::format("The document “%s” could not be saved.", aDocument->display_name().c_str())] informativeText:([NSString stringWithCxxString:aMessage] ?: @"Please check Console output for reason.") buttons:@"OK", nil] beginSheetModalForWindow:self.window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; - } - - documents.pop_back(); - self.failed = self.failed || !flag || self.userAbort; - [self performSelector:@selector(saveNextDocument:) withObject:self afterDelay:0]; -} -@end diff --git a/Frameworks/document/src/OakDocument Private.h b/Frameworks/document/src/OakDocument Private.h index 158664e6..67085185 100644 --- a/Frameworks/document/src/OakDocument Private.h +++ b/Frameworks/document/src/OakDocument Private.h @@ -2,10 +2,7 @@ namespace document { - struct save_callback_t; struct document_t; - - typedef std::shared_ptr save_callback_ptr; typedef std::shared_ptr document_ptr; } /* document */ @@ -23,6 +20,4 @@ namespace document - (BOOL)saveBackup:(id)sender; - (BOOL)performReplacements:(std::multimap, std::string> const&)someReplacements checksum:(uint32_t)crc32; - -- (void)trySaveUsingCallback:(document::save_callback_ptr)callback forDocument:(document::document_ptr)document; @end diff --git a/Frameworks/document/src/OakDocument.mm b/Frameworks/document/src/OakDocument.mm index 6c318248..3ca210d8 100644 --- a/Frameworks/document/src/OakDocument.mm +++ b/Frameworks/document/src/OakDocument.mm @@ -3,7 +3,7 @@ #import "Printing.h" #import "watch.h" #import "merge.h" -#import "document.h" // {open,save}_callback_ptr + kBookmarkIdentifier +#import "document.h" // kBookmarkIdentifier #import #import #import @@ -791,67 +791,6 @@ private: self.observeFileSystem = self.isOpen; } -- (void)trySaveUsingCallback:(document::save_callback_ptr)callback forDocument:(document::document_ptr)document -{ - if(_buffer && _path) - { - [[NSNotificationCenter defaultCenter] postNotificationName:OakDocumentWillSaveNotification object:self]; - self.observeFileSystem = NO; - - io::bytes_ptr content = std::make_shared(_buffer->size()); - _buffer->visit_data([&](char const* bytes, size_t offset, size_t len, bool*){ - memcpy(content->get() + offset, bytes, len); - }); - - std::map attributes; - if(volume::settings(to_s(_path)).extended_attributes()) - attributes = [self extendedAttributeds]; - - encoding::type encoding = encoding::type(to_s(_diskNewlines), to_s(_diskEncoding)); - - settings_t const settings = settings_for_path(to_s(_virtualPath ?: _path), to_s(_fileType), to_s(_directory ?: [_path stringByDeletingLastPathComponent])); - if(encoding.charset() == kCharsetNoEncoding) - encoding.set_charset(settings.get(kSettingsEncodingKey, kCharsetUTF8)); - if(encoding.newlines() == NULL_STR) - encoding.set_newlines(settings.get(kSettingsLineEndingsKey, kLF)); - - struct callback_t : file::save_callback_t - { - callback_t (OakDocument* document, document::document_ptr cppdocument, document::save_callback_ptr callback, bool closeDocument) : _document(document), _cppDocument(cppdocument), _callback(callback), _close_document(closeDocument) - { - } - - void select_path (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) { _callback->select_path(path, content, context); } - void select_make_writable (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) { _callback->select_make_writable(path, content, context); } - void select_create_parent (std::string const& path, io::bytes_ptr content, file::save_context_ptr context) { _callback->select_create_parent(path, content, context); } - void obtain_authorization (std::string const& path, io::bytes_ptr content, osx::authorization_t auth, file::save_context_ptr context) { _callback->obtain_authorization(path, content, auth, context); } - void select_charset (std::string const& path, io::bytes_ptr content, std::string const& charset, file::save_context_ptr context) { _callback->select_charset(path, content, charset, context); } - - void did_save (std::string const& path, io::bytes_ptr content, encoding::type const& encoding, bool success, std::string const& message, oak::uuid_t const& filter) - { - if(_close_document) - [_document didSaveAtPath:to_ns(path) withEncoding:encoding success:success]; - _callback->did_save_document(_cppDocument, path, success, message, filter); - if(_close_document) - [_document close]; - } - - private: - OakDocument* _document; - document::document_ptr _cppDocument; - document::save_callback_ptr _callback; - bool _close_document; - }; - - BOOL closeDocument = self.isOpen; - if(closeDocument) - ++self.openCount; - - auto cb = std::make_shared(self, document, callback, closeDocument); - file::save(to_s(_path), cb, _authorization, content, attributes, encoding, std::vector() /* binary import filters */, std::vector() /* text import filters */); - } -} - - (void)saveModalForWindow:(NSWindow*)aWindow completionHandler:(void(^)(OakDocumentIOResult result, NSString* errorMessage, oak::uuid_t const& filterUUID))block { if(!self.isOpen && self.isDocumentEdited && _backupPath) diff --git a/Frameworks/document/src/document.h b/Frameworks/document/src/document.h index 426560f9..2c2239e0 100644 --- a/Frameworks/document/src/document.h +++ b/Frameworks/document/src/document.h @@ -32,15 +32,6 @@ namespace document typedef std::shared_ptr document_ptr; typedef std::weak_ptr document_weak_ptr; - struct PUBLIC save_callback_t : file::save_callback_t - { - virtual ~save_callback_t () { } - virtual void did_save_document (document_ptr document, std::string const& path, bool success, std::string const& message, oak::uuid_t const& filter) = 0; - virtual void did_save (std::string const& path, io::bytes_ptr content, encoding::type const& encoding, bool success, std::string const& message, oak::uuid_t const& filter) { } - }; - - typedef std::shared_ptr save_callback_ptr; - struct inode_t { inode_t () { } @@ -134,7 +125,6 @@ namespace document void enumerate_bytes_using_block (void(^block)(char const* bytes, size_t len, bool* stop)); bool replace (std::multimap, std::string> const& replacements, uint32_t crc32); - void try_save (document::save_callback_ptr callback); void close (); // =================== diff --git a/Frameworks/document/src/document.mm b/Frameworks/document/src/document.mm index 15286c88..6c51cfac 100644 --- a/Frameworks/document/src/document.mm +++ b/Frameworks/document/src/document.mm @@ -572,11 +572,6 @@ namespace document }]; } - void document_t::try_save (document::save_callback_ptr callback) - { - [_document trySaveUsingCallback:callback forDocument:shared_from_this()]; - } - void document_t::close () { [_document close];