Revision df003f06

b/pithos-macos.xcodeproj/project.pbxproj
49 49
		6152D08C143200CC00803874 /* PithosSharingAccountsNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 6152D08B143200CC00803874 /* PithosSharingAccountsNode.m */; };
50 50
		6152D092143334CC00803874 /* AllowedToBoolTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6152D091143334CC00803874 /* AllowedToBoolTransformer.m */; };
51 51
		6152D095143334E000803874 /* SharingAccountBoolTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6152D094143334E000803874 /* SharingAccountBoolTransformer.m */; };
52
		6154BF4B145554D600EE353A /* pithos-logo-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 6154BF4A145554D600EE353A /* pithos-logo-small.png */; };
53
		6154BF4D145558E300EE353A /* pithos.icns in Resources */ = {isa = PBXBuildFile; fileRef = 6154BF4C145558E300EE353A /* pithos.icns */; };
52 54
		615615DD140CECDB00017BD4 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 615615DC140CECDB00017BD4 /* libz.dylib */; };
53 55
		615A444E140F8A5700308614 /* MetadataKeyTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 615A444D140F8A5700308614 /* MetadataKeyTransformer.m */; };
54 56
		615A4451140F8A7F00308614 /* MetadataKeyFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 615A4450140F8A7F00308614 /* MetadataKeyFormatter.m */; };
......
160 162
		6152D091143334CC00803874 /* AllowedToBoolTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AllowedToBoolTransformer.m; path = "pithos-macos/AllowedToBoolTransformer.m"; sourceTree = "<group>"; };
161 163
		6152D093143334E000803874 /* SharingAccountBoolTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharingAccountBoolTransformer.h; path = "pithos-macos/SharingAccountBoolTransformer.h"; sourceTree = "<group>"; };
162 164
		6152D094143334E000803874 /* SharingAccountBoolTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SharingAccountBoolTransformer.m; path = "pithos-macos/SharingAccountBoolTransformer.m"; sourceTree = "<group>"; };
165
		6154BF4A145554D600EE353A /* pithos-logo-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pithos-logo-small.png"; sourceTree = "<group>"; };
166
		6154BF4C145558E300EE353A /* pithos.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = pithos.icns; path = ../pithos.icns; sourceTree = "<group>"; };
163 167
		615615DC140CECDB00017BD4 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
164 168
		615A444C140F8A5700308614 /* MetadataKeyTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MetadataKeyTransformer.h; path = "pithos-macos/MetadataKeyTransformer.h"; sourceTree = "<group>"; };
165 169
		615A444D140F8A5700308614 /* MetadataKeyTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MetadataKeyTransformer.m; path = "pithos-macos/MetadataKeyTransformer.m"; sourceTree = "<group>"; };
......
345 349
		610DD46113E950E500ED982F /* Icons */ = {
346 350
			isa = PBXGroup;
347 351
			children = (
352
				6154BF4C145558E300EE353A /* pithos.icns */,
348 353
				610DD46213E950E600ED982F /* 01-refresh.png */,
349 354
				61E99D9313EC348500E48DA5 /* 145-persondot.png */,
355
				6154BF4A145554D600EE353A /* pithos-logo-small.png */,
350 356
			);
351 357
			path = Icons;
352 358
			sourceTree = SOURCE_ROOT;
......
560 566
				619B85D613F8077800C9371F /* PithosPreferencesController.xib in Resources */,
561 567
				616FC0AF13F91BA400140A33 /* PithosObjectNodeInfoController.xib in Resources */,
562 568
				611405D11428BEC000637170 /* PithosContainerNodeInfoController.xib in Resources */,
569
				6154BF4B145554D600EE353A /* pithos-logo-small.png in Resources */,
570
				6154BF4D145558E300EE353A /* pithos.icns in Resources */,
563 571
			);
564 572
			runOnlyForDeploymentPostprocessing = 0;
565 573
		};
b/pithos-macos/PithosBrowserController.xib
342 342
																			<int key="NSvFlags">4352</int>
343 343
																			<string key="NSFrameSize">{180, 292}</string>
344 344
																			<reference key="NSSuperview" ref="843429105"/>
345
																			<reference key="NSWindow"/>
345 346
																			<reference key="NSNextKeyView" ref="624286523"/>
346 347
																			<bool key="NSEnabled">YES</bool>
347 348
																			<object class="_NSCornerView" key="NSCornerView">
......
440 441
																	</object>
441 442
																	<string key="NSFrameSize">{180, 292}</string>
442 443
																	<reference key="NSSuperview" ref="197496877"/>
444
																	<reference key="NSWindow"/>
443 445
																	<reference key="NSNextKeyView" ref="392693553"/>
444 446
																	<reference key="NSDocView" ref="392693553"/>
445 447
																	<reference key="NSBGColor" ref="592883226"/>
......
450 452
																	<int key="NSvFlags">-2147483392</int>
451 453
																	<string key="NSFrame">{{224, 17}, {15, 102}}</string>
452 454
																	<reference key="NSSuperview" ref="197496877"/>
455
																	<reference key="NSWindow"/>
453 456
																	<reference key="NSNextKeyView" ref="1047973191"/>
454 457
																	<reference key="NSTarget" ref="197496877"/>
455 458
																	<string key="NSAction">_doScroller:</string>
......
460 463
																	<int key="NSvFlags">-2147483392</int>
461 464
																	<string key="NSFrame">{{-100, -100}, {144, 15}}</string>
462 465
																	<reference key="NSSuperview" ref="197496877"/>
466
																	<reference key="NSWindow"/>
463 467
																	<reference key="NSNextKeyView" ref="843429105"/>
464 468
																	<int key="NSsFlags">1</int>
465 469
																	<reference key="NSTarget" ref="197496877"/>
......
469 473
															</object>
470 474
															<string key="NSFrameSize">{180, 292}</string>
471 475
															<reference key="NSSuperview" ref="414504914"/>
476
															<reference key="NSWindow"/>
472 477
															<reference key="NSNextKeyView" ref="205521010"/>
473 478
															<int key="NSsFlags">528</int>
474 479
															<reference key="NSVScroller" ref="624286523"/>
......
479 484
													</object>
480 485
													<string key="NSFrameSize">{180, 292}</string>
481 486
													<reference key="NSSuperview" ref="462572416"/>
487
													<reference key="NSWindow"/>
482 488
													<reference key="NSNextKeyView" ref="197496877"/>
483 489
													<string key="NSClassName">NSView</string>
484 490
												</object>
......
493 499
															<object class="NSPSMatrix" key="NSDrawMatrix"/>
494 500
															<string key="NSFrame">{{7, 49}, {166, 12}}</string>
495 501
															<reference key="NSSuperview" ref="1047973191"/>
496
															<reference key="NSNextKeyView" ref="987905504"/>
502
															<reference key="NSWindow"/>
503
															<reference key="NSNextKeyView" ref="620067477"/>
497 504
															<int key="NSpiFlags">16648</int>
498 505
															<double key="NSMaxValue">100</double>
499 506
														</object>
......
502 509
															<int key="NSvFlags">266</int>
503 510
															<string key="NSFrame">{{5, 13}, {170, 35}}</string>
504 511
															<reference key="NSSuperview" ref="1047973191"/>
505
															<reference key="NSNextKeyView" ref="744849637"/>
512
															<reference key="NSWindow"/>
513
															<reference key="NSNextKeyView" ref="987905504"/>
506 514
															<bool key="NSEnabled">YES</bool>
507 515
															<object class="NSTextFieldCell" key="NSCell" id="667098628">
508 516
																<int key="NSCellFlags">67239424</int>
......
547 555
																	<string>NeXT TIFF v4.0 pasteboard type</string>
548 556
																</object>
549 557
															</object>
550
															<string key="NSFrame">{{69, 66}, {42, 42}}</string>
558
															<string key="NSFrame">{{50, 66}, {76, 40}}</string>
551 559
															<reference key="NSSuperview" ref="1047973191"/>
552
															<reference key="NSNextKeyView" ref="620067477"/>
560
															<reference key="NSWindow"/>
561
															<reference key="NSNextKeyView" ref="744849637"/>
553 562
															<bool key="NSEnabled">YES</bool>
554 563
															<object class="NSImageCell" key="NSCell" id="280822281">
555 564
																<int key="NSCellFlags">130560</int>
556 565
																<int key="NSCellFlags2">33554432</int>
557 566
																<object class="NSCustomResource" key="NSContents">
558 567
																	<string key="NSClassName">NSImage</string>
559
																	<string key="NSResourceName">NSFolderBurnable</string>
568
																	<string key="NSResourceName">pithos-logo-small</string>
560 569
																</object>
561 570
																<int key="NSAlign">0</int>
562
																<int key="NSScale">3</int>
571
																<int key="NSScale">2</int>
563 572
																<int key="NSStyle">0</int>
564 573
																<bool key="NSAnimates">NO</bool>
565 574
															</object>
......
568 577
													</object>
569 578
													<string key="NSFrame">{{0, 293}, {180, 107}}</string>
570 579
													<reference key="NSSuperview" ref="462572416"/>
580
													<reference key="NSWindow"/>
571 581
													<reference key="NSNextKeyView" ref="805035077"/>
572 582
													<string key="NSClassName">NSView</string>
573 583
												</object>
574 584
											</object>
575 585
											<string key="NSFrameSize">{180, 400}</string>
576 586
											<reference key="NSSuperview" ref="581795577"/>
587
											<reference key="NSWindow"/>
577 588
											<reference key="NSNextKeyView" ref="414504914"/>
578 589
											<int key="NSDividerStyle">2</int>
579 590
										</object>
580 591
									</object>
581 592
									<string key="NSFrameSize">{180, 400}</string>
582 593
									<reference key="NSSuperview" ref="374340452"/>
594
									<reference key="NSWindow"/>
583 595
									<reference key="NSNextKeyView" ref="462572416"/>
584 596
									<string key="NSClassName">NSView</string>
585 597
								</object>
......
593 605
											<int key="NSvFlags">4370</int>
594 606
											<string key="NSFrame">{{-1, -1}, {511, 402}}</string>
595 607
											<reference key="NSSuperview" ref="987905504"/>
608
											<reference key="NSWindow"/>
596 609
											<reference key="NSNextKeyView"/>
597 610
											<bool key="NSEnabled">YES</bool>
598 611
											<object class="NSBrowserCell" key="NSCellPrototype">
......
617 630
									</object>
618 631
									<string key="NSFrame">{{181, 0}, {509, 400}}</string>
619 632
									<reference key="NSSuperview" ref="374340452"/>
633
									<reference key="NSWindow"/>
620 634
									<reference key="NSNextKeyView" ref="259981942"/>
621 635
									<string key="NSClassName">NSView</string>
622 636
								</object>
623 637
							</object>
624 638
							<string key="NSFrameSize">{690, 400}</string>
625 639
							<reference key="NSSuperview" ref="1006"/>
640
							<reference key="NSWindow"/>
626 641
							<reference key="NSNextKeyView" ref="581795577"/>
627 642
							<bool key="NSIsVertical">YES</bool>
628 643
							<int key="NSDividerStyle">2</int>
......
630 645
					</object>
631 646
					<string key="NSFrame">{{7, 11}, {690, 400}}</string>
632 647
					<reference key="NSSuperview"/>
648
					<reference key="NSWindow"/>
633 649
					<reference key="NSNextKeyView" ref="374340452"/>
634 650
				</object>
635 651
				<string key="NSScreenRect">{{0, 0}, {1280, 778}}</string>
......
1218 1234
			<nil key="sourceID"/>
1219 1235
			<int key="maxID">193</int>
1220 1236
		</object>
1221
		<object class="IBClassDescriber" key="IBDocument.Classes"/>
1237
		<object class="IBClassDescriber" key="IBDocument.Classes">
1238
			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
1239
				<bool key="EncodedWithXMLCoder">YES</bool>
1240
				<object class="IBPartialClassDescription">
1241
					<string key="className">PithosBrowserController</string>
1242
					<string key="superclassName">NSWindowController</string>
1243
					<object class="NSMutableDictionary" key="actions">
1244
						<bool key="EncodedWithXMLCoder">YES</bool>
1245
						<object class="NSArray" key="dict.sortedKeys">
1246
							<bool key="EncodedWithXMLCoder">YES</bool>
1247
							<string>forceRefresh:</string>
1248
							<string>refresh:</string>
1249
						</object>
1250
						<object class="NSMutableArray" key="dict.values">
1251
							<bool key="EncodedWithXMLCoder">YES</bool>
1252
							<string>id</string>
1253
							<string>id</string>
1254
						</object>
1255
					</object>
1256
					<object class="NSMutableDictionary" key="actionInfosByName">
1257
						<bool key="EncodedWithXMLCoder">YES</bool>
1258
						<object class="NSArray" key="dict.sortedKeys">
1259
							<bool key="EncodedWithXMLCoder">YES</bool>
1260
							<string>forceRefresh:</string>
1261
							<string>refresh:</string>
1262
						</object>
1263
						<object class="NSMutableArray" key="dict.values">
1264
							<bool key="EncodedWithXMLCoder">YES</bool>
1265
							<object class="IBActionInfo">
1266
								<string key="name">forceRefresh:</string>
1267
								<string key="candidateClassName">id</string>
1268
							</object>
1269
							<object class="IBActionInfo">
1270
								<string key="name">refresh:</string>
1271
								<string key="candidateClassName">id</string>
1272
							</object>
1273
						</object>
1274
					</object>
1275
					<object class="NSMutableDictionary" key="outlets">
1276
						<bool key="EncodedWithXMLCoder">YES</bool>
1277
						<object class="NSArray" key="dict.sortedKeys">
1278
							<bool key="EncodedWithXMLCoder">YES</bool>
1279
							<string>activityProgressIndicator</string>
1280
							<string>activityTextField</string>
1281
							<string>browser</string>
1282
							<string>browserMenu</string>
1283
							<string>horizontalSplitView</string>
1284
							<string>leftBottomView</string>
1285
							<string>leftTopView</string>
1286
							<string>outlineView</string>
1287
							<string>outlineViewMenu</string>
1288
							<string>verticalSplitView</string>
1289
						</object>
1290
						<object class="NSMutableArray" key="dict.values">
1291
							<bool key="EncodedWithXMLCoder">YES</bool>
1292
							<string>NSProgressIndicator</string>
1293
							<string>NSTextField</string>
1294
							<string>NSBrowser</string>
1295
							<string>NSMenu</string>
1296
							<string>NSSplitView</string>
1297
							<string>NSView</string>
1298
							<string>NSView</string>
1299
							<string>NSOutlineView</string>
1300
							<string>NSMenu</string>
1301
							<string>NSSplitView</string>
1302
						</object>
1303
					</object>
1304
					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
1305
						<bool key="EncodedWithXMLCoder">YES</bool>
1306
						<object class="NSArray" key="dict.sortedKeys">
1307
							<bool key="EncodedWithXMLCoder">YES</bool>
1308
							<string>activityProgressIndicator</string>
1309
							<string>activityTextField</string>
1310
							<string>browser</string>
1311
							<string>browserMenu</string>
1312
							<string>horizontalSplitView</string>
1313
							<string>leftBottomView</string>
1314
							<string>leftTopView</string>
1315
							<string>outlineView</string>
1316
							<string>outlineViewMenu</string>
1317
							<string>verticalSplitView</string>
1318
						</object>
1319
						<object class="NSMutableArray" key="dict.values">
1320
							<bool key="EncodedWithXMLCoder">YES</bool>
1321
							<object class="IBToOneOutletInfo">
1322
								<string key="name">activityProgressIndicator</string>
1323
								<string key="candidateClassName">NSProgressIndicator</string>
1324
							</object>
1325
							<object class="IBToOneOutletInfo">
1326
								<string key="name">activityTextField</string>
1327
								<string key="candidateClassName">NSTextField</string>
1328
							</object>
1329
							<object class="IBToOneOutletInfo">
1330
								<string key="name">browser</string>
1331
								<string key="candidateClassName">NSBrowser</string>
1332
							</object>
1333
							<object class="IBToOneOutletInfo">
1334
								<string key="name">browserMenu</string>
1335
								<string key="candidateClassName">NSMenu</string>
1336
							</object>
1337
							<object class="IBToOneOutletInfo">
1338
								<string key="name">horizontalSplitView</string>
1339
								<string key="candidateClassName">NSSplitView</string>
1340
							</object>
1341
							<object class="IBToOneOutletInfo">
1342
								<string key="name">leftBottomView</string>
1343
								<string key="candidateClassName">NSView</string>
1344
							</object>
1345
							<object class="IBToOneOutletInfo">
1346
								<string key="name">leftTopView</string>
1347
								<string key="candidateClassName">NSView</string>
1348
							</object>
1349
							<object class="IBToOneOutletInfo">
1350
								<string key="name">outlineView</string>
1351
								<string key="candidateClassName">NSOutlineView</string>
1352
							</object>
1353
							<object class="IBToOneOutletInfo">
1354
								<string key="name">outlineViewMenu</string>
1355
								<string key="candidateClassName">NSMenu</string>
1356
							</object>
1357
							<object class="IBToOneOutletInfo">
1358
								<string key="name">verticalSplitView</string>
1359
								<string key="candidateClassName">NSSplitView</string>
1360
							</object>
1361
						</object>
1362
					</object>
1363
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
1364
						<string key="majorKey">IBProjectSource</string>
1365
						<string key="minorKey">./Classes/PithosBrowserController.h</string>
1366
					</object>
1367
				</object>
1368
			</object>
1369
		</object>
1222 1370
		<int key="IBDocument.localizationMode">0</int>
1223 1371
		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
1224 1372
		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
......
1233 1381
				<bool key="EncodedWithXMLCoder">YES</bool>
1234 1382
				<string>01-refresh</string>
1235 1383
				<string>145-persondot</string>
1236
				<string>NSFolderBurnable</string>
1237 1384
				<string>NSMenuCheckmark</string>
1238 1385
				<string>NSMenuMixedState</string>
1239 1386
				<string>NSToolbarCustomizeToolbarItemImage</string>
1387
				<string>pithos-logo-small</string>
1240 1388
			</object>
1241 1389
			<object class="NSMutableArray" key="dict.values">
1242 1390
				<bool key="EncodedWithXMLCoder">YES</bool>
1243 1391
				<string>{24, 26}</string>
1244 1392
				<string>{24, 26}</string>
1245
				<string>{32, 32}</string>
1246 1393
				<string>{9, 8}</string>
1247 1394
				<string>{7, 2}</string>
1248 1395
				<string>{32, 32}</string>
1396
				<string>{75, 19}</string>
1249 1397
			</object>
1250 1398
		</object>
1251 1399
	</data>
b/pithos-macos/PithosLocalObjectState.h
40 40
@interface PithosLocalObjectState : NSObject <NSCoding> {
41 41
    NSString *md5;
42 42
    NSString *hashMapHash;
43
    NSString *tmpDownloadFile;
43
    NSString *filePath;
44 44
    BOOL isDirectory;
45 45
}
46 46

  
47
- (id)initWithFile:(NSString *)filePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize;
47
- (id)initWithFile:(NSString *)aFilePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize;
48 48
- (id)initWithHash:(NSString *)aHash directory:(BOOL)anIsDirectory;
49 49
+ (id)localObjectState;
50
+ (id)localObjectStateWithFile:(NSString *)filePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize;
50
+ (id)localObjectStateWithFile:(NSString *)aFilePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize;
51 51
+ (id)localObjectStateWithHash:(NSString *)aHash directory:(BOOL)anIsDirectory;
52 52
- (BOOL)isEqualToState:(PithosLocalObjectState *)aState;
53 53

  
54 54
@property (nonatomic, retain) NSString *md5;
55 55
@property (nonatomic, retain) NSString *hashMapHash;
56
@property (nonatomic, retain) NSString *tmpDownloadFile;
56
@property (nonatomic, retain) NSString *filePath;
57 57
@property (nonatomic, assign) BOOL isDirectory;
58 58

  
59 59
@property (nonatomic, readonly) BOOL exists;
b/pithos-macos/PithosLocalObjectState.m
41 41
#import "HashMapHash.h"
42 42

  
43 43
@implementation PithosLocalObjectState
44
@synthesize md5, hashMapHash, tmpDownloadFile, isDirectory, exists, hash;
44
@synthesize md5, hashMapHash, filePath, isDirectory, exists, hash;
45 45

  
46 46
#pragma mark -
47 47
#pragma mark Object Lifecycle
48 48

  
49
- (id)initWithFile:(NSString *)filePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize {
49
- (id)initWithFile:(NSString *)aFilePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize {
50 50
    if ((self = [self init])) {
51
        self.filePath = aFilePath;
51 52
        if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory] && !isDirectory) {
52
            self.md5 = (NSString *)FileMD5HashCreateWithPath((CFStringRef)filePath, 
53
            self.md5 = (NSString *)FileMD5HashCreateWithPath((CFStringRef)aFilePath, 
53 54
                                                             FileHashDefaultChunkSizeForReadingData);
54 55
            self.hashMapHash = [HashMapHash calculateHashMapHash:[HashMapHash calculateObjectHashMap:filePath 
55 56
                                                                                       withBlockHash:blockHash 
......
75 76
    return [[[self alloc] init] autorelease];
76 77
}
77 78

  
78
+ (id)localObjectStateWithFile:(NSString *)filePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize {
79
    return [[[self alloc] initWithFile:filePath blockHash:blockHash blockSize:blockSize] autorelease];
79
+ (id)localObjectStateWithFile:(NSString *)aFilePath blockHash:(NSString *)blockHash blockSize:(NSUInteger)blockSize {
80
    return [[[self alloc] initWithFile:aFilePath blockHash:blockHash blockSize:blockSize] autorelease];
80 81
}
81 82

  
82 83
+ (id)localObjectStateWithHash:(NSString *)aHash directory:(BOOL)anIsDirectory {
......
84 85
}
85 86

  
86 87
- (void)dealloc {
87
    self.tmpDownloadFile = nil;
88
    self.filePath = nil;
88 89
    [hashMapHash release];
89 90
    [md5 release];
90 91
    [super dealloc];    
91 92
}
92 93

  
93 94
- (NSString *)description {
94
    return [NSString stringWithFormat:@"md5: %@, hashMapHash: %@, tmpDownloadFile: %@, isDirectory: %d", 
95
            md5, hashMapHash, tmpDownloadFile, isDirectory];
95
    return [NSString stringWithFormat:@"md5: %@, hashMapHash: %@, filePath: %@, isDirectory: %d", 
96
            md5, hashMapHash, filePath, isDirectory];
96 97
}
97 98

  
98 99
- (BOOL)isEqualToState:(PithosLocalObjectState *)aState {
......
121 122
    if (isDirectory) {
122 123
        self.md5 = nil;
123 124
        self.hashMapHash = nil;
124
        self.tmpDownloadFile = nil;
125
        self.filePath = nil;
125 126
    }
126 127
}
127 128

  
128
- (void)setTmpDownloadFile:(NSString *)aTmpDownloadFile {
129
    if (![tmpDownloadFile isEqualToString:aTmpDownloadFile]) {
130
        if (!aTmpDownloadFile) {
129
- (void)setTmpDownloadFile:(NSString *)aFilePath {
130
    if (![filePath isEqualToString:aFilePath]) {
131
        if (!aFilePath) {
131 132
            NSFileManager *fileManager = [NSFileManager defaultManager];
132
            if ([fileManager fileExistsAtPath:tmpDownloadFile]) {
133
            if ([fileManager fileExistsAtPath:filePath]) {
133 134
                NSError *error = nil;
134
                if (![fileManager removeItemAtPath:tmpDownloadFile error:&error] || error)
135
                if (![fileManager removeItemAtPath:filePath error:&error] || error)
135 136
                    [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
136
                                                            message:[NSString stringWithFormat:@"Cannot remove file at '%@'", tmpDownloadFile] 
137
                                                            message:[NSString stringWithFormat:@"Cannot remove file at '%@'", filePath] 
137 138
                                                              error:error];
138 139
            }
139 140
        }
140
        [tmpDownloadFile release];
141
        tmpDownloadFile = [aTmpDownloadFile retain];
141
        [filePath release];
142
        filePath = [aFilePath retain];
142 143
    }
143 144
}
144 145

  
......
170 171
    if ((self = [super init])) {
171 172
        self.md5 = [decoder decodeObjectForKey:@"md5"];
172 173
        self.hashMapHash = [decoder decodeObjectForKey:@"hashMapHash"];
173
        self.tmpDownloadFile = [decoder decodeObjectForKey:@"tmpDownloadFile"];
174
        self.filePath = [decoder decodeObjectForKey:@"filePath"];
174 175
        self.isDirectory = [decoder decodeBoolForKey:@"isDirectory"];
175 176
    }
176 177
    return self;
......
179 180
- (void)encodeWithCoder:(NSCoder *)encoder {
180 181
    [encoder encodeObject:md5 forKey:@"md5"];
181 182
    [encoder encodeObject:hashMapHash forKey:@"hashMapHash"];
182
    [encoder encodeObject:tmpDownloadFile forKey:@"tmpDownloadFile"];
183
    [encoder encodeObject:filePath forKey:@"filePath"];
183 184
    [encoder encodeBool:isDirectory forKey:@"isDirectory"];
184 185
}
185 186

  
b/pithos-macos/PithosSyncDaemon.h
50 50
    NSMutableArray *objects;
51 51
    NSMutableDictionary *remoteObjects;
52 52
    NSMutableDictionary *storedLocalObjectStates;
53
    NSMutableDictionary *currentLocalObjectStates;
53 54
    
55
    NSString *containerDirectoryPath;
54 56
    NSString *pithosStateFilePath;
55 57
    NSString *tempDownloadsDirPath;
58
    NSString *tempTrashDirPath;
56 59
    
57 60
    NSUInteger syncOperationCount;
58 61
    BOOL newSyncRequested;
......
70 73
@property (nonatomic, retain) NSDate *lastModified;
71 74
@property (nonatomic, retain) NSMutableDictionary *remoteObjects;
72 75
@property (nonatomic, retain) NSMutableDictionary *storedLocalObjectStates;
76
@property (nonatomic, retain) NSMutableDictionary *currentLocalObjectStates;
73 77

  
78
@property (nonatomic, readonly) NSString *containerDirectoryPath;
74 79
@property (nonatomic, readonly) NSString *pithosStateFilePath;
75 80
@property (nonatomic, readonly) NSString *tempDownloadsDirPath;
81
@property (nonatomic, readonly) NSString *tempTrashDirPath;
76 82

  
77 83
@property (nonatomic, retain) NSDate *lastCompletedSync;
78 84

  
b/pithos-macos/PithosSyncDaemon.m
51 51
@interface PithosSyncDaemon (Private)
52 52
- (NSString *)pithosStateFilePath;
53 53
- (void)saveLocalState;
54
- (BOOL)moveToTempTrashFile:(NSString *)filePath;
54 55
- (void)updateLocalStateWithObject:(ASIPithosObject *)object localFilePath:(NSString *)filePath;
55 56
- (void)updateServerStateWithCurrentState:(PithosLocalObjectState *)currentState 
56 57
                                   object:(ASIPithosObject *)object 
......
63 64
@end
64 65

  
65 66
@implementation PithosSyncDaemon
66
@synthesize blockHash, blockSize, lastModified, lastCompletedSync, remoteObjects, storedLocalObjectStates;
67
@synthesize pithosStateFilePath, tempDownloadsDirPath;
67
@synthesize blockHash, blockSize, lastModified, lastCompletedSync, remoteObjects, storedLocalObjectStates, currentLocalObjectStates;
68
@synthesize containerDirectoryPath, pithosStateFilePath, tempDownloadsDirPath, tempTrashDirPath;
68 69

  
69 70
#pragma mark -
70 71
#pragma Object Lifecycle
......
79 80
        
80 81
        syncOperationCount = 0;
81 82
        newSyncRequested = NO;
83
        containerDirectoryPath = [[directoryPath stringByAppendingPathComponent:containerName] copy];
82 84
        
83 85
        activityFacility = [PithosActivityFacility defaultPithosActivityFacility];
84 86
        
......
113 115
    [queue release];
114 116
    [timer invalidate];
115 117
    [timer release];
118
    [tempTrashDirPath release];
116 119
    [tempDownloadsDirPath release];
117 120
    [pithosStateFilePath release];
121
    [containerDirectoryPath release];
122
    [currentLocalObjectStates release];
118 123
    [storedLocalObjectStates release];
119 124
    [remoteObjects release];
120 125
    [objects release];
......
177 182
    return [tempDownloadsDirPath copy];
178 183
}
179 184

  
185
- (NSString *)tempTrashDirPath {
186
    NSFileManager *fileManager = [NSFileManager defaultManager];
187
    if (!tempTrashDirPath || ![fileManager fileExistsAtPath:tempTrashDirPath]) {
188
        // Get the path from user defaults
189
        tempTrashDirPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"PithosTempTrashDirPath"];
190
        if (tempTrashDirPath) {
191
            // Check if the path exists
192
            BOOL isDirectory;
193
            BOOL fileExists = [fileManager fileExistsAtPath:tempTrashDirPath isDirectory:&isDirectory];
194
            NSError *error = nil;
195
            if (fileExists && !isDirectory)
196
                [fileManager removeItemAtPath:tempTrashDirPath error:&error];
197
            if (!error & !fileExists)
198
                [fileManager createDirectoryAtPath:tempTrashDirPath withIntermediateDirectories:YES attributes:nil error:&error];
199
            if (error)
200
                tempTrashDirPath = nil;
201
        }
202
        if (!tempTrashDirPath) {
203
            NSString *tempDirTemplate = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Temp Trash XXXXXX"];
204
            const char *tempDirTemplateCString = [tempDirTemplate fileSystemRepresentation];
205
            char *tempDirNameCString = (char *)malloc(strlen(tempDirTemplateCString) + 1);
206
            strcpy(tempDirNameCString, tempDirTemplateCString);
207
            tempDirNameCString = mkdtemp(tempDirNameCString);
208
            if (tempDirNameCString != NULL)
209
                tempTrashDirPath = [fileManager stringWithFileSystemRepresentation:tempDirNameCString length:strlen(tempDirNameCString)];
210
            free(tempDirNameCString);
211
        }
212
        if (!tempTrashDirPath)
213
            [[NSUserDefaults standardUserDefaults] setObject:tempTrashDirPath forKey:@"PithosTempTrashDirPath"];
214
        [tempTrashDirPath retain];
215
    }
216
    return [tempTrashDirPath copy];
217
}
218

  
180 219
#pragma mark -
181 220
#pragma mark Sync
182 221

  
......
201 240
            self.lastCompletedSync = [NSDate date];
202 241
            [activityFacility startAndEndActivityWithType:PithosActivityOther 
203 242
                                                  message:[NSString stringWithFormat:@"Sync: Completed %@", lastCompletedSync]];
243
            // The sync cycle is completed and the final operation is to move the Trash Folder the contents of the Temp Trash
244
            NSString *trashDirPath = self.tempTrashDirPath;
245
            if (tempTrashDirPath) {
246
                NSError *error = nil;
247
                NSArray *subPaths = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:trashDirPath error:&error];
248
                if (error) {
249
                    [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
250
                                                            message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", containerDirectoryPath] 
251
                                                              error:error];
252
                    return;
253
                }
254
                if ([subPaths count]) {
255
                    NSMutableArray *subURLs = [NSMutableArray arrayWithCapacity:[subPaths count]];
256
                    for (NSString *subPath in subPaths) {
257
                        [subURLs addObject:[NSURL fileURLWithPath:[trashDirPath stringByAppendingPathComponent:subPath]]];
258
                    }
259
                    syncOperationCount = 1;
260
                    [[NSWorkspace sharedWorkspace] recycleURLs:subURLs completionHandler:^(NSDictionary *newURLs, NSError *error) {
261
                        if (error) {
262
                            [PithosUtilities fileActionFailedAlertWithTitle:@"Move to Trash Error" 
263
                                                                    message:@"Cannot move files to Trash" 
264
                                                                      error:error];
265
                        }
266
                        syncOperationCount = 0;
267
                    }];
268
                }
269
            }
204 270
        }
205 271
    }
206 272
}
......
219 285
        }
220 286
    }
221 287

  
222
    NSString *containerDirectoryPath = [directoryPath stringByAppendingPathComponent:containerName];
223 288
    NSFileManager *fileManager = [NSFileManager defaultManager];
224 289
    BOOL isDirectory;
225 290
    NSError *error = nil;
......
270 335
    [queue addOperation:[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh]];
271 336
}
272 337

  
338
- (BOOL)moveToTempTrashFile:(NSString *)filePath {
339
    NSString *trashDirPath = self.tempTrashDirPath;
340
    if (!tempTrashDirPath)
341
        return NO;
342
    NSFileManager *fileManager = [NSFileManager defaultManager];
343
    BOOL isDirectory;
344
    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
345
    NSError *error = nil;
346
    NSString *newFilePath = [filePath stringByReplacingOccurrencesOfString:containerDirectoryPath 
347
                                                                withString:trashDirPath];
348
    NSString *newDirPath = [newFilePath stringByDeletingLastPathComponent];
349
    if (fileExists && isDirectory) {
350
        NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:filePath error:&error];
351
        if (error) {
352
            [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
353
                                                    message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", containerDirectoryPath] 
354
                                                      error:error];
355
            return NO;
356
        }
357
        if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
358
            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
359
                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
360
                                                      error:error];
361
            return NO;
362
        }
363
        if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
364
            [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
365
                                                    message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
366
                                                             filePath, newFilePath] 
367
                                                      error:error];
368
            return NO;
369
        }
370
        PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
371
        if (currentState) {
372
            currentState.filePath = newFilePath;
373
            [currentLocalObjectStates setObject:currentState forKey:newFilePath];
374
            [currentLocalObjectStates removeObjectForKey:filePath];        
375
        } else {
376
            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
377
                                                                                       blockHash:blockHash 
378
                                                                                       blockSize:blockSize] 
379
                                         forKey:newFilePath];
380
        }
381
        for (NSString *subPath in subPaths) {
382
            NSString *subFilePath = [filePath stringByAppendingPathComponent:subPath];
383
            NSString *newSubFilePath = [subFilePath stringByReplacingOccurrencesOfString:containerDirectoryPath 
384
                                                                              withString:trashDirPath];
385
            currentState = [currentLocalObjectStates objectForKey:subFilePath];
386
            if (currentState) {
387
                currentState.filePath = newSubFilePath;
388
                [currentLocalObjectStates setObject:currentState forKey:newSubFilePath];
389
                [currentLocalObjectStates removeObjectForKey:subFilePath];
390
            } else {
391
                [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newSubFilePath 
392
                                                                                           blockHash:blockHash 
393
                                                                                           blockSize:blockSize] 
394
                                             forKey:newSubFilePath];
395
            }        
396
        }
397
    } else if (fileExists && !isDirectory) {
398
        if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
399
            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
400
                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
401
                                                      error:error];
402
            return NO;
403
        }
404
        if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
405
            [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
406
                                                    message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
407
                                                             filePath, newFilePath] 
408
                                                      error:error];
409
            return NO;
410
        }
411
        PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
412
        if (currentState) {
413
            currentState.filePath = newFilePath;
414
            [currentLocalObjectStates setObject:currentState forKey:newFilePath];
415
            [currentLocalObjectStates removeObjectForKey:filePath];        
416
        } else {
417
            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
418
                                                                                       blockHash:blockHash 
419
                                                                                       blockSize:blockSize] 
420
                                         forKey:newFilePath];
421
        }
422
    }
423
    return YES;
424
}
425

  
273 426
- (void)updateLocalStateWithObject:(ASIPithosObject *)object
274 427
                     localFilePath:(NSString *)filePath {
275 428
    NSFileManager *fileManager = [NSFileManager defaultManager];
......
277 430
    BOOL isDirectory;
278 431
    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
279 432
    PithosLocalObjectState *storedState = [storedLocalObjectStates objectForKey:object.name];
280
    if (!object.hash) {
433
    if (!object || !object.hash) {
281 434
        // Delete local object
282 435
        // XXX move to local trash instead
283 436
        NSLog(@"Sync::delete local object: %@", filePath);
284
        BOOL deleteFailed = NO;
285
        if (fileExists) {
286
            error = nil;
287
            if (![fileManager removeItemAtPath:filePath error:&error] || error) {
288
                [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
289
                                                        message:[NSString stringWithFormat:@"Cannot remove file at '%@'", filePath] 
290
                                                          error:error];
291
                deleteFailed = YES;
292
            }
293
        }
294
        if (!deleteFailed) {
437
        if (!fileExists || [self moveToTempTrashFile:filePath]) {
295 438
            [activityFacility startAndEndActivityWithType:PithosActivityOther 
296 439
                                                  message:[NSString stringWithFormat:@"Sync: Deleting '%@' locally (finished)", object.name]];
297 440
            [storedLocalObjectStates removeObjectForKey:object.name];
......
301 444
        // Create local directory object
302 445
        NSLog(@"Sync::create local directory object: %@", filePath);
303 446
        BOOL directoryCreated = NO;
304
        if (fileExists && !isDirectory) {
305
            NSLog(@"Sync::delete local file object: %@", filePath);
306
            error = nil;
307
            if (![fileManager removeItemAtPath:filePath error:&error] || error) {
308
                [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
309
                                                        message:[NSString stringWithFormat:@"Cannot remove file at '%@'", filePath] 
310
                                                          error:error];
311
            }
312
        }
313
        if (![fileManager fileExistsAtPath:filePath]) {
447
        if (!fileExists || (!isDirectory && [self moveToTempTrashFile:filePath])) {
314 448
            NSLog(@"Sync::local directory object doesn't exist: %@", filePath);
315 449
            error = nil;
316 450
            if (![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
......
322 456
                storedState.isDirectory = YES;
323 457
                [self saveLocalState];
324 458
            }
325
        } else if (isDirectory) {
459
        } else {
326 460
            NSLog(@"Sync::local directory object exists: %@", filePath);
327 461
            directoryCreated = YES;
328 462
        }
......
333 467
        // Create local object with zero length
334 468
        NSLog(@"Sync::create local zero length object: %@", filePath);
335 469
        BOOL fileCreated = NO;
336
        if (fileExists && (isDirectory || [PithosUtilities bytesOfFile:filePath])) {
337
            NSLog(@"Sync::delete local object: %@", filePath);
338
            error = nil;
339
            if (![fileManager removeItemAtPath:filePath error:&error] || error) {
340
                [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
341
                                                        message:[NSString stringWithFormat:@"Cannot remove file at '%@'", filePath] 
342
                                                          error:error];
343
            }
344
        }
345
        if (![fileManager fileExistsAtPath:filePath]) {
470
        if (!fileExists || ((isDirectory || [PithosUtilities bytesOfFile:filePath]) && [self moveToTempTrashFile:filePath])) {
346 471
            NSLog(@"Sync::local zero length object doesn't exist: %@", filePath);
347 472
            error = nil;
348 473
            if (![fileManager createFileAtPath:filePath contents:nil attributes:nil]) {
......
352 477
            } else {
353 478
                fileCreated = YES;
354 479
                storedState.hash = object.hash;
355
                storedState.tmpDownloadFile = nil;
480
                storedState.filePath = nil;
356 481
                [self saveLocalState];
357 482
            }
358
        } else if (!isDirectory && ![PithosUtilities bytesOfFile:filePath]) {
483
        } else {
359 484
            NSLog(@"Sync::local zero length object exists: %@", filePath);
360 485
            fileCreated = YES;
361 486
        }
362 487
        if (fileCreated)
363 488
            [activityFacility startAndEndActivityWithType:PithosActivityOther 
364 489
                                                  message:[NSString stringWithFormat:@"Sync: Downloading '%@' (100%%)", object.name]];
365
    } else if (storedState.tmpDownloadFile == nil) {
490
    } else if (storedState.filePath == nil) {
366 491
        // Create new local object
367 492
        [self increaseSyncOperationCount];
368 493
        __block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectBlockDataRequestWithContainerName:containerName 
......
585 710
        [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
586 711
                          withMessage:[containerRequest.userInfo objectForKey:@"finishedActivityMessage"]];
587 712
        NSFileManager *fileManager = [NSFileManager defaultManager];
588
        NSString *containerDirectoryPath = [directoryPath stringByAppendingPathComponent:containerName];
589 713
        NSError *error = nil;
590 714
        NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:containerDirectoryPath error:&error];
591 715
        if (error) {
......
601 725
            }
602 726
            return;
603 727
        }
728
        self.currentLocalObjectStates = [NSMutableDictionary dictionaryWithCapacity:[subPaths count]];
604 729
        for (NSString *objectName in subPaths) {
605 730
            if (![storedLocalObjectStates objectForKey:objectName]) {
606 731
                [storedLocalObjectStates setObject:[PithosLocalObjectState localObjectState] forKey:objectName];
607 732
            }
733
            NSString *filePath = [containerDirectoryPath stringByAppendingPathComponent:objectName];
734
            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:filePath 
735
                                                                                       blockHash:blockHash 
736
                                                                                       blockSize:blockSize] 
737
                                         forKey:filePath];
608 738
        }
609 739
        [self saveLocalState];
610 740

  
......
622 752
            NSLog(@"Sync::object name: %@", objectName);
623 753
            
624 754
            PithosLocalObjectState *storedLocalObjectState = [storedLocalObjectStates objectForKey:object.name];
625
            PithosLocalObjectState *currentLocalObjectState = [PithosLocalObjectState localObjectStateWithFile:filePath 
626
                                                                                                     blockHash:blockHash 
627
                                                                                                     blockSize:blockSize];
755
            PithosLocalObjectState *currentLocalObjectState = [currentLocalObjectStates objectForKey:filePath];
756
            if (!currentLocalObjectState)
757
                currentLocalObjectState = [PithosLocalObjectState localObjectStateWithFile:filePath 
758
                                                                                 blockHash:blockHash 
759
                                                                                 blockSize:blockSize];
628 760
            if (currentLocalObjectState.isDirectory)
629 761
                object.contentType = @"application/directory";
630 762
            
......
798 930
        }
799 931
        
800 932
        PithosLocalObjectState *storedState = [storedLocalObjectStates objectForKey:object.name];
801
        if ((storedState.tmpDownloadFile == nil) || ![fileManager fileExistsAtPath:storedState.tmpDownloadFile]) {
933
        if ((storedState.filePath == nil) || ![fileManager fileExistsAtPath:storedState.filePath]) {
802 934
            NSString *tempFileTemplate = [downloadsDirPath stringByAppendingPathComponent:@"download.XXXXXX"];
803 935
            const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation];
804 936
            char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1);
......
808 940
            free(tempFileNameCString);
809 941
            if (fileDescriptor == -1) {
810 942
                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Temporary File Error" 
811
                                                        message:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", storedState.tmpDownloadFile] 
943
                                                        message:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", storedState.filePath] 
812 944
                                                          error:nil];
813 945
                [activityFacility endActivity:activity 
814 946
                                  withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
......
821 953
                return;
822 954
            }
823 955
            close(fileDescriptor);
824
            storedState.tmpDownloadFile = tempFilePath;
956
            storedState.filePath = tempFilePath;
825 957
            [self saveLocalState];
826 958
        }
827 959
        
828 960

  
829 961
        NSUInteger missingBlockIndex = [[objectRequest.userInfo objectForKey:@"missingBlockIndex"] unsignedIntegerValue];
830
        NSFileHandle *tempFileHandle = [NSFileHandle fileHandleForWritingAtPath:storedState.tmpDownloadFile];
962
        NSFileHandle *tempFileHandle = [NSFileHandle fileHandleForWritingAtPath:storedState.filePath];
831 963
        [tempFileHandle seekToFileOffset:missingBlockIndex*blockSize];
832 964
        [tempFileHandle writeData:[objectRequest responseData]];
833 965
        [tempFileHandle closeFile];
......
837 969
        if (missingBlockIndex == NSNotFound) {
838 970
            NSString *filePath = [objectRequest.userInfo objectForKey:@"filePath"];
839 971
            NSString *dirPath = [filePath stringByDeletingLastPathComponent];
840
            if ([fileManager fileExistsAtPath:filePath]) {
841
                error = nil;
842
                // XXX don't delete but move to local trash instead
843
                [fileManager removeItemAtPath:filePath error:&error];
844
                if (error != nil) {
845
                    [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
846
                                                            message:[NSString stringWithFormat:@"Cannot remove file at '%@'", filePath] 
847
                                                              error:error];
848
                    [activityFacility endActivity:activity 
849
                                      withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
850
                    @synchronized(self) {
851
                        syncIncomplete = YES;
852
                        [self decreaseSyncOperationCount];
853
                        if (newSyncRequested && !syncOperationCount)
854
                            [self sync];
855
                    }
856
                    return;
972
            if ([fileManager fileExistsAtPath:filePath] && ![self moveToTempTrashFile:filePath]) {
973
                [activityFacility endActivity:activity 
974
                                  withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
975
                @synchronized(self) {
976
                    syncIncomplete = YES;
977
                    [self decreaseSyncOperationCount];
978
                    if (newSyncRequested && !syncOperationCount)
979
                        [self sync];
857 980
                }
981
                return;
858 982
            } else if (![fileManager fileExistsAtPath:dirPath]) {
859 983
                // File doesn't exist but also the containing directory doesn't exist
860 984
                // In most cases this should have been resolved as an update of the corresponding local object,
......
878 1002
            }
879 1003
            // Move file from tmp download
880 1004
            error = nil;
881
            [fileManager moveItemAtPath:storedState.tmpDownloadFile toPath:filePath error:&error];
1005
            [fileManager moveItemAtPath:storedState.filePath toPath:filePath error:&error];
882 1006
            if (error != nil) {
883 1007
                [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
884
                                                        message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", storedState.tmpDownloadFile, filePath] 
1008
                                                        message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", storedState.filePath, filePath] 
885 1009
                                                          error:error];
886 1010
                [activityFacility endActivity:activity 
887 1011
                                  withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
......
899 1023
                             currentBytes:activity.totalBytes];
900 1024

  
901 1025
            storedState.hash = object.hash;
902
            storedState.tmpDownloadFile = nil;
1026
            storedState.filePath = nil;
903 1027
            [self saveLocalState];
904 1028
            
905 1029
            @synchronized(self) {
......
972 1096
        } else {
973 1097
            ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
974 1098
            PithosLocalObjectState *storedState = [storedLocalObjectStates objectForKey:object.name];
975
            if ([PithosUtilities bytesOfFile:storedState.tmpDownloadFile] > object.bytes)
976
                [[NSFileHandle fileHandleForWritingAtPath:storedState.tmpDownloadFile] truncateFileAtOffset:object.bytes];
1099
            if ([PithosUtilities bytesOfFile:storedState.filePath] > object.bytes)
1100
                [[NSFileHandle fileHandleForWritingAtPath:storedState.filePath] truncateFileAtOffset:object.bytes];
977 1101
            PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
978
            NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForFile:storedState.tmpDownloadFile 
1102
            NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForFile:storedState.filePath 
979 1103
                                                                    blockSize:blockSize 
980 1104
                                                                    blockHash:blockHash 
981 1105
                                                                   withHashes:[objectRequest hashes]];
b/pithos-macos/pithos-macos-Info.plist
7 7
	<key>CFBundleExecutable</key>
8 8
	<string>${EXECUTABLE_NAME}</string>
9 9
	<key>CFBundleIconFile</key>
10
	<string></string>
10
	<string>pithos.icns</string>
11 11
	<key>CFBundleIdentifier</key>
12 12
	<string>gr.grnet.${PRODUCT_NAME:rfc1034identifier}</string>
13 13
	<key>CFBundleInfoDictionaryVersion</key>
......
24 24
	<array>
25 25
		<dict>
26 26
			<key>CFBundleURLName</key>
27
			<string>Pithos&apos; URL</string>
27
			<string>Pithos' URL</string>
28 28
			<key>CFBundleURLSchemes</key>
29 29
			<array>
30 30
				<string>pithos</string>
......
47 47
	<string>https://pithos.dev.grnet.gr</string>
48 48
	<key>PithosStorageURLPrefix</key>
49 49
	<string>https://pithos.dev.grnet.gr/v1</string>
50
	<key>PithosSyncDirectoryPath</key>
51
	<string></string>
52 50
	<key>PithosSyncContainerName</key>
53 51
	<string>pithos</string>
52
	<key>PithosSyncDirectoryPath</key>
53
	<string></string>
54 54
	<key>PithosSyncTimeInterval</key>
55 55
	<real>180</real>
56 56
</dict>

Also available in: Unified diff