imageFrame.origin.y -= kImageOriginYOffset;
imageFrame.size = imageSize;
- if ([controlView isFlipped])
- imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
- else
- imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
- [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
+ imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
+ [image drawInRect:imageFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
NSRect newFrame = cellFrame;
newFrame.origin.x += kTextOriginXOffset;
ASIPithos *pithos;
ASIPithosAccount *pithosAccount;
- NSMutableArray *containers;
ASIPithosAccountRequest *accountRequest;
ASIPithosAccountRequest *applyMetadataAccountRequest;
} else {
newChildren = nil;
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshNeeded;
if (accountRequest.responseStatusCode == 200) {
self.pithosAccount = [accountRequest account];
+ NSMutableArray *containers = [accountRequest.userInfo objectForKey:@"containers"];
NSArray *someContainers = [accountRequest containers];
if (containers == nil) {
- containers = [[NSMutableArray alloc] initWithArray:someContainers];
+ containers = [NSMutableArray arrayWithArray:someContainers];
} else {
[containers addObjectsFromArray:someContainers];
}
}
// Else cache was used and all results were fetched during this request, so existing children can be reused
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
NSStringFromSelector(@selector(accountRequestFinished:)), @"didFinishSelector",
- NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector",
+ NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector",
+ containers, @"containers",
nil];
[[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
}
} else if (accountRequest.responseStatusCode == 304) {
// Account is not modified, so existing children can be reused
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
NSString *message;
NSUInteger totalBytes;
NSUInteger currentBytes;
- PithosAccount *__unsafe_unretained pithosAccount;
+ PithosAccount *pithosAccount;
}
- (id)initWithType:(PithosActivityType)aType pithosAccount:(PithosAccount *)aPithosAccount;
@property (nonatomic, copy) NSString *message;
@property (nonatomic, assign) NSUInteger totalBytes;
@property (nonatomic, assign) NSUInteger currentBytes;
-@property (nonatomic, unsafe_unretained) PithosAccount *pithosAccount;
+@property (nonatomic, strong) PithosAccount *pithosAccount;
@end
type = aType;
totalBytes = 0;
currentBytes = 0;
- pithosAccount = aPithosAccount;
+ self.pithosAccount = aPithosAccount;
}
return self;
}
NSViewController *sharedPreviewController;
- NSSplitView *__unsafe_unretained verticalSplitView;
- NSSplitView *__unsafe_unretained horizontalSplitView;
- NSView *__unsafe_unretained leftTopView;
- NSView *__unsafe_unretained leftBottomView;
- NSOutlineView *__unsafe_unretained outlineView;
- NSBrowser *__unsafe_unretained browser;
- NSMenu *__unsafe_unretained outlineViewMenu;
- NSMenu *__unsafe_unretained browserMenu;
+ IBOutlet NSSplitView *verticalSplitView;
+ IBOutlet NSSplitView *horizontalSplitView;
+ IBOutlet NSView *leftTopView;
+ IBOutlet NSView *leftBottomView;
+ IBOutlet NSOutlineView *outlineView;
+ IBOutlet NSBrowser *browser;
+ IBOutlet NSMenu *outlineViewMenu;
+ IBOutlet NSMenu *browserMenu;
BOOL editingItem;
PithosNode *clipboardParentNode;
BOOL clipboardCopy;
- NSTextField *__unsafe_unretained activityTextField;
- NSProgressIndicator *__unsafe_unretained activityProgressIndicator;
+ IBOutlet NSTextField *activityTextField;
+ IBOutlet NSProgressIndicator *activityProgressIndicator;
PithosActivityFacility *activityFacility;
NSTimer *refreshTimer;
@property (nonatomic, unsafe_unretained) PithosAccount *pithosAccountManager;
@property (nonatomic, strong) PithosAccountNode *accountNode;
-@property (nonatomic, unsafe_unretained) IBOutlet NSSplitView *verticalSplitView;
-@property (nonatomic, unsafe_unretained) IBOutlet NSSplitView *horizontalSplitView;
-@property (nonatomic, unsafe_unretained) IBOutlet NSView *leftTopView;
-@property (nonatomic, unsafe_unretained) IBOutlet NSView *leftBottomView;
-@property (nonatomic, unsafe_unretained) IBOutlet NSOutlineView *outlineView;
-@property (nonatomic, unsafe_unretained) IBOutlet NSBrowser *browser;
-@property (nonatomic, unsafe_unretained) IBOutlet NSMenu *outlineViewMenu;
-@property (nonatomic, unsafe_unretained) IBOutlet NSMenu *browserMenu;
-
@property (nonatomic, strong) NSArray *draggedNodes;
@property (nonatomic, strong) PithosNode *draggedParentNode;
@property (nonatomic, strong) PithosNode *clipboardParentNode;
@property (nonatomic, assign) BOOL clipboardCopy;
-@property (nonatomic, unsafe_unretained) IBOutlet NSTextField *activityTextField;
-@property (nonatomic, unsafe_unretained) IBOutlet NSProgressIndicator *activityProgressIndicator;
-
- (IBAction)forceRefresh:(id)sender;
- (IBAction)refresh:(id)sender;
- (void)resetBrowser;
@implementation PithosBrowserController
@synthesize pithos;
@synthesize pithosAccountManager, accountNode;
-@synthesize verticalSplitView, horizontalSplitView, leftTopView, leftBottomView, outlineView, browser, outlineViewMenu, browserMenu;
@synthesize draggedNodes, draggedParentNode;
@synthesize clipboardNodes, clipboardParentNode, clipboardCopy;
-@synthesize activityTextField, activityProgressIndicator;
#pragma mark -
#pragma Object Lifecycle
// Request for browser refresh
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosBrowserRefreshNeeded:)
- name:@"PithosBrowserRefreshNeeeded"
+ name:@"PithosBrowserRefreshNeeded"
object:nil];
}
#pragma mark Observers
- (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
+ if (![NSThread isMainThread]) {
+ [self performSelectorOnMainThread:@selector(pithosNodeChildrenUpdated:) withObject:notification waitUntilDone:NO];
+ return;
+ }
PithosNode *node = (PithosNode *)[notification object];
if ((node == accountNode) || ![node.pithos isEqualTo:pithos])
return;
}
- (void)pithosAccountNodeChildrenUpdated:(NSNotification *)notification {
+ if (![NSThread isMainThread]) {
+ [self performSelectorOnMainThread:@selector(pithosAccountNodeChildrenUpdated:) withObject:notification waitUntilDone:NO];
+ return;
+ }
BOOL containerPithosFound = NO;
BOOL containerTrashFound = NO;
NSMutableIndexSet *removedContainersNodeChildren = [NSMutableIndexSet indexSet];
#pragma mark Actions
- (IBAction)forceRefresh:(id)sender {
+ if (![NSThread isMainThread]) {
+ [self performSelectorOnMainThread:@selector(forceRefresh:) withObject:sender waitUntilDone:NO];
+ return;
+ }
if (editingItem)
return;
if (sender)
}
- (IBAction)refresh:(id)sender {
+ if (![NSThread isMainThread]) {
+ [self performSelectorOnMainThread:@selector(refresh:) withObject:sender waitUntilDone:NO];
+ return;
+ }
if (editingItem)
return;
if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) {
ASIPithos *pithos;
ASIPithosContainer *pithosContainer;
- NSMutableArray *objects;
ASIPithosContainerRequest *containerRequest;
NSString *prefix;
} else {
newChildren = nil;
containerRequest = nil;
- objects = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshNeeded;
pithosContainer.blockSize = [containerRequest blockSize];
}
+ NSMutableArray *objects = [containerRequest.userInfo objectForKey:@"objects"];
NSArray *someObjects = [containerRequest objects];
if (objects == nil) {
- objects = [[NSMutableArray alloc] initWithArray:someObjects];
+ objects = [NSMutableArray arrayWithArray:someObjects];
} else {
[objects addObjectsFromArray:someObjects];
}
}
// Else cache was used and all results were fetched during this request, so existing children can be reused
containerRequest = nil;
- objects = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
NSStringFromSelector(@selector(containerRequestFinished:)), @"didFinishSelector",
- NSStringFromSelector(@selector(containerRequestFailed:)), @"didFailSelector",
+ NSStringFromSelector(@selector(containerRequestFailed:)), @"didFailSelector",
+ objects, @"objects",
nil];
[[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
}
} else if (containerRequest.responseStatusCode == 304) {
// Container is not modified, so existing children can be reused
containerRequest = nil;
- objects = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
- (void)refresh {
[self invalidateChildren];
- self.children;
+ [self children];
}
- (void)forceRefresh {
pithosNodeInfoController.node = nil;
[[pithosNodeInfoController window] close];
}
- for (PithosNode *child in children) {
- [child pithosNodeWillBeRemoved];
- }
+ [children makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
}
#pragma mark -
self.isPublic = (pithosObject.publicURI != nil);
// Refresh browser if the object is in my shared and is no longer shared
if (shared && !pithosObject.sharing)
- [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeeded" object:self];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeded" object:self];
}
- (void)setLimitedPithosObject:(ASIPithosObject *)aPithosObject {
@interface PithosSharingAccountsNode : PithosNode {
ASIPithos *pithos;
- NSMutableArray *sharingAccounts;
ASIPithosRequest *sharingAccountsRequest;
BOOL reset;
} else {
newChildren = nil;
sharingAccountsRequest = nil;
- sharingAccounts = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshNeeded;
DLog(@"List sharing accounts finished: %@", [sharingAccountsRequest url]);
DLog(@"Cached: %d", [sharingAccountsRequest didUseCachedResponse]);
if (sharingAccountsRequest.responseStatusCode == 200) {
+ NSMutableArray *sharingAccounts = [sharingAccountsRequest.userInfo objectForKey:@"sharingAccounts"];
NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts];
if (sharingAccounts == nil) {
- sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts];
+ sharingAccounts = [NSMutableArray arrayWithArray:someSharingAccounts];
} else {
[sharingAccounts addObjectsFromArray:someSharingAccounts];
}
DLog(@"using newChildren");
newChildren = [[NSMutableArray alloc] init];
NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
- NSMutableArray *sharingAccountsNames = [NSMutableArray arrayWithCapacity:sharingAccounts.count];
for (ASIPithosAccount *account in sharingAccounts) {
- [sharingAccountsNames addObject:account.name];
if (![account.name isEqualToString:pithos.authUser]) {
PithosAccountNode *node = [[PithosAccountNode alloc] initWithPithos:pithos];
node.parent = self;
[newChildren addObject:node];
}
}
- [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:sharingAccountsNames];
[[children objectsAtIndexes:
[[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
if ([keptNodes containsIndex:idx])
}]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
}
// Else cache was used and all results were fetched during this request, so existing children can be reused
+ // Update user catalog even if cache was used
+ NSMutableArray *sharingAccountsNames = [NSMutableArray arrayWithCapacity:sharingAccounts.count];
+ for (ASIPithosAccount *account in sharingAccounts) {
+ [sharingAccountsNames addObject:account.name];
+ }
+ [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:sharingAccountsNames];
sharingAccountsRequest = nil;
- sharingAccounts = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector",
- NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector",
+ NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector",
+ sharingAccounts, @"sharingAccounts",
nil];
// if (!forcedRefresh)
// sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
self.isPublic = (pithosObject.publicURI != nil);
// Refresh browser if the object is in my shared and is no longer shared
if (shared && !pithosObject.subdir && !pithosObject.sharing) {
- [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeeded" object:self];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeded" object:self];
}
}
#pragma mark Request Helper Methods
+ (ASIPithosRequest *)prepareRequest:(ASIPithosRequest *)request priority:(NSOperationQueuePriority)priority {
- [request setTimeOutSeconds:60];
+ request.timeOutSeconds = 60;
request.numberOfTimesToRetryOnTimeout = 10;
- [request setQueuePriority:priority];
+ request.queuePriority = priority;
return request;
}
[smallImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[sourceImage setSize:NSMakeSize(18, 18)];
- [sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
+ [sourceImage drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
[smallImage unlockFocus];
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];