libs-base/Source/NSFileCoordinator.m

310 lines
8.8 KiB
Mathematica
Raw Permalink Normal View History

/** Definition of class NSFileCoordinator
2019-09-20 09:07:41 +00:00
Copyright (C) 2019 Free Software Foundation, Inc.
Implemented by: Gregory Casamento <greg.casamento@gmail.com>
Date: Sep 2019
Original File by: Daniel Ferreira
This file is part of the GNUstep Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
2019-09-20 09:07:41 +00:00
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA.
2019-09-20 09:07:41 +00:00
*/
#import <Foundation/NSFileCoordinator.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
2019-09-23 03:26:30 +00:00
#import <Foundation/NSFilePresenter.h>
#import <Foundation/NSOperation.h>
2019-09-27 08:49:29 +00:00
#import <Foundation/NSString.h>
2019-09-23 03:26:30 +00:00
static NSMutableArray *__presenters = nil;
static NSMutableDictionary *__presenterMap = nil;
2019-09-27 08:49:29 +00:00
static unsigned int __pid = 0;
static NSMutableDictionary *__presenterIdDict = nil;
@implementation NSFileAccessIntent
2019-09-21 00:00:45 +00:00
- (instancetype) init
{
self = [super init];
2022-09-26 15:15:47 +00:00
if (self != nil)
2019-09-21 00:00:45 +00:00
{
_url = nil;
_isRead = NO;
_options = 0L;
}
return self;
}
+ (instancetype) readingIntentWithURL: (NSURL *)url
options: (NSFileCoordinatorReadingOptions)options
{
2019-09-21 00:00:45 +00:00
NSFileAccessIntent *result = [[self alloc] init];
2022-09-26 15:15:47 +00:00
2019-09-21 00:00:45 +00:00
ASSIGNCOPY(result->_url, url);
result->_options = options;
2019-09-21 00:38:17 +00:00
result->_isRead = YES;
2022-09-26 15:15:47 +00:00
return AUTORELEASE(result);
}
+ (instancetype) writingIntentWithURL: (NSURL *)url
options: (NSFileCoordinatorWritingOptions)options
{
2019-09-21 00:38:17 +00:00
NSFileAccessIntent *result = [[self alloc] init];
2022-09-26 15:15:47 +00:00
2019-09-21 00:38:17 +00:00
ASSIGNCOPY(result->_url, url);
result->_options = options;
result->_isRead = NO;
2022-09-26 15:15:47 +00:00
return AUTORELEASE(result);
}
- (NSURL *) URL
{
2019-09-21 00:38:17 +00:00
return _url;
}
@end
@implementation NSFileCoordinator
2019-09-21 00:00:45 +00:00
+ (void) initialize
{
2022-09-26 15:15:47 +00:00
if (self == [NSFileCoordinator class])
2019-09-21 00:35:50 +00:00
{
__presenters = [[NSMutableArray alloc] init];
__presenterMap = [[NSMutableDictionary alloc] init];
2019-09-27 08:49:29 +00:00
__presenterIdDict = [[NSMutableDictionary alloc] init];
2019-09-21 00:35:50 +00:00
}
2019-09-21 00:00:45 +00:00
}
+ (NSArray *) filePresenters
{
2019-09-23 03:26:30 +00:00
return __presenters;
}
+ (void) addFilePresenter: (id)presenter
{
[__presenters addObject: presenter];
[__presenterMap setObject: presenter forKey: [presenter presentedItemURL]];
2019-09-27 08:49:29 +00:00
[__presenterIdDict setObject: presenter forKey: [presenter purposeIdentifier]];
2019-09-23 03:26:30 +00:00
}
+ (void) removeFilePresenter: (id)presenter
{
[__presenters removeObject: presenter];
2019-09-27 05:56:08 +00:00
[__presenterMap removeObjectForKey: [presenter presentedItemURL]];
2019-09-27 08:49:29 +00:00
[__presenterIdDict removeObjectForKey: [presenter purposeIdentifier]];
}
- (instancetype) init
{
self = [super init];
2022-09-26 15:15:47 +00:00
if (self != nil)
2019-09-27 08:49:29 +00:00
{
NSString *p = nil;
__pid++;
p = [NSString stringWithFormat: @"%d",__pid];
_purposeIdentifier = RETAIN(p);
_isCancelled = NO;
}
return self;
}
- (NSString *) purposeIdentifier
{
2019-09-23 03:26:30 +00:00
return _purposeIdentifier;
}
- (void) setPurposeIdentifier: (NSString *)ident // copy
{
2019-09-23 03:26:30 +00:00
ASSIGNCOPY(_purposeIdentifier, ident);
}
- (void)cancel
{
2019-09-23 03:26:30 +00:00
NSEnumerator *en = [__presenters objectEnumerator];
id obj = nil;
2022-09-26 15:15:47 +00:00
while ((obj = [en nextObject]) != nil)
2019-09-23 03:26:30 +00:00
{
id<NSFilePresenter> o = (id<NSFilePresenter>)obj;
NSOperationQueue *q = [o presentedItemOperationQueue];
[q cancelAllOperations];
}
2019-09-27 08:49:29 +00:00
_isCancelled = YES;
}
- (void)coordinateAccessWithIntents: (NSArray *)intents
queue: (NSOperationQueue *)queue
byAccessor: (GSAccessorCallbackHandler)accessor
{
NSEnumerator *en = [intents objectEnumerator];
id obj = nil;
2022-09-26 15:15:47 +00:00
while ((obj = [en nextObject]) != nil)
{
NSBlockOperation *op;
op = [NSBlockOperation
blockOperationWithBlock: (GSBlockOperationBlock)accessor];
[queue addOperation: op];
}
}
2022-09-26 15:15:47 +00:00
- (void) coordinateReadingItemAtURL: (NSURL *)readingURL
options: (NSFileCoordinatorReadingOptions)readingOptions
writingItemAtURL: (NSURL *)writingURL
options: (NSFileCoordinatorWritingOptions)writingOptions
error: (NSError **)outError
byAccessor: (GSNoEscapeReadWriteHandler)readerWriter
{
2022-09-26 15:15:47 +00:00
if (readingOptions == 0L)
2019-09-25 09:12:33 +00:00
{
id<NSFilePresenter> p = [__presenterMap objectForKey: readingURL];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
2019-09-25 09:12:33 +00:00
{
2022-09-26 15:15:47 +00:00
[p savePresentedItemChangesWithCompletionHandler: NULL];
2019-09-25 09:12:33 +00:00
}
}
2022-09-26 15:15:47 +00:00
if (writingOptions == 0L)
2019-09-25 09:12:33 +00:00
{
id<NSFilePresenter> p = [__presenterMap objectForKey: writingURL];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
2019-09-25 09:12:33 +00:00
{
2022-09-26 15:15:47 +00:00
[p savePresentedItemChangesWithCompletionHandler: NULL];
2019-09-25 09:12:33 +00:00
}
}
CALL_BLOCK(readerWriter, readingURL, writingURL);
}
2022-09-26 15:15:47 +00:00
- (void) coordinateReadingItemAtURL: (NSURL *)url
options: (NSFileCoordinatorReadingOptions)options
error: (NSError **)outError
byAccessor: (GSNoEscapeNewURLHandler)reader
{
2022-09-26 15:15:47 +00:00
if (options == 0L)
{
id<NSFilePresenter> p = [__presenterMap objectForKey: url];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
2019-09-23 06:51:41 +00:00
{
2022-09-26 15:15:47 +00:00
[p savePresentedItemChangesWithCompletionHandler: NULL];
2019-09-23 06:51:41 +00:00
}
}
CALL_BLOCK(reader, url);
}
2022-09-26 15:15:47 +00:00
- (void) coordinateWritingItemAtURL: (NSURL *)url
options: (NSFileCoordinatorWritingOptions)options
error: (NSError **)outError
byAccessor: (GSNoEscapeNewURLHandler)writer
{
2022-09-26 15:15:47 +00:00
if (options == 0L)
{
id<NSFilePresenter> p = [__presenterMap objectForKey: url];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
{
[p savePresentedItemChangesWithCompletionHandler: NULL];
}
}
CALL_BLOCK(writer, url);
}
2022-09-26 15:15:47 +00:00
- (void) coordinateWritingItemAtURL: (NSURL *)url1
options: (NSFileCoordinatorWritingOptions)options1
writingItemAtURL: (NSURL *)url2
options: (NSFileCoordinatorWritingOptions)options2
error: (NSError **)outError
byAccessor: (GSDualWriteURLCallbackHandler)writer
{
2022-09-26 15:15:47 +00:00
if (options1 == 0L)
2019-09-25 09:12:33 +00:00
{
id<NSFilePresenter> p = [__presenterMap objectForKey: url1];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
{
[p savePresentedItemChangesWithCompletionHandler: NULL];
}
2019-09-25 09:12:33 +00:00
}
2022-09-26 15:15:47 +00:00
if (options2 == 0L)
2019-09-25 09:12:33 +00:00
{
id<NSFilePresenter> p = [__presenterMap objectForKey: url2];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
{
[p savePresentedItemChangesWithCompletionHandler: NULL];
}
2019-09-25 09:12:33 +00:00
}
CALL_BLOCK(writer, url1, url2);
}
2022-09-26 15:15:47 +00:00
- (void) itemAtURL: (NSURL *)oldURL didMoveToURL: (NSURL *)newURL
{
2019-09-27 06:51:41 +00:00
id<NSFilePresenter> presenter = [__presenterMap objectForKey: oldURL];
2022-09-26 15:15:47 +00:00
2019-09-27 06:51:41 +00:00
[presenter presentedItemDidMoveToURL: newURL];
}
2022-09-26 15:15:47 +00:00
- (void) itemAtURL: (NSURL *)oldURL willMoveToURL: (NSURL *)newURL
{
2019-09-27 06:51:41 +00:00
id<NSFilePresenter> presenter = [__presenterMap objectForKey: oldURL];
2022-09-26 15:15:47 +00:00
[presenter presentedItemDidChange]; // there is no "Will" method for this, so I am a bit perplexed.
}
2022-09-26 15:15:47 +00:00
- (void) itemAtURL: (NSURL *)url
didChangeUbiquityAttributes: (NSSet *)attributes
{
2019-09-27 06:51:41 +00:00
id<NSFilePresenter> presenter = [__presenterMap objectForKey: url];
2022-09-26 15:15:47 +00:00
2019-09-27 06:51:41 +00:00
[presenter presentedItemDidChangeUbiquityAttributes: attributes];
}
2022-09-26 15:15:47 +00:00
- (void) prepareForReadingItemsAtURLs: (NSArray *)readingURLs
options: (NSFileCoordinatorReadingOptions)readingOptions
writingItemsAtURLs: (NSArray *)writingURLs
options: (NSFileCoordinatorWritingOptions)writingOptions
error: (NSError **)outError
byAccessor: (GSBatchAccessorCompositeBlock)batchAccessor
{
2022-09-26 15:15:47 +00:00
if (readingOptions == 0L)
{
2022-09-26 15:15:47 +00:00
NSEnumerator *en = [readingURLs objectEnumerator];
NSURL *aurl = nil;
while ((aurl = [en nextObject]) != nil)
{
id<NSFilePresenter> p = [__presenterMap objectForKey: aurl];
2022-09-26 15:15:47 +00:00
if ([p respondsToSelector:
@selector(savePresentedItemChangesWithCompletionHandler:)])
{
2022-09-26 15:15:47 +00:00
[p savePresentedItemChangesWithCompletionHandler: NULL];
}
}
}
// CALL_BLOCK(batchAccessor, batchAccessor.argTys[0]); // NOT SURE HOW TO CALL COMPOSITE BLOCK
}
@end