Pushr (master) :  summary log tree commit diff
path: root/PushrPhotoProperties.m blob: 82d7e9731e8e1dc98640c2b3bb11a0bead1025b3
1/*
2 * PushrPhotoProperties.m
3 * ----------------------
4 *
5 * Author: Chris Lee <clee@mg8.org>
6 * License: GPL v2 <http://www.opensource.org/licenses/gpl-license.php>
7 */
8
9#import <Foundation/Foundation.h>
10#import <UIKit/CDStructures.h>
11#import <UIKit/UIKit.h>
12#import <UIKit/UIView.h>
13#import <UIKit/UIView-Geometry.h>
14#import <UIKit/UINavigationBar.h>
15#import <UIKit/UITransitionView.h>
16#import <UIKit/UIPreferencesTable.h>
17#import <UIKit/UIPreferencesTextTableCell.h>
18#import <UIKit/UIPreferencesControlTableCell.h>
19#import <UIKit/UIPreferencesTableCell.h>
20#import <UIKit/UISegmentedControl.h>
21#import <UIKit/UISwitchControl.h>
22#import <UIKit/UITextLabel.h>
23#import <UIKit/UIAlertSheet.h>
24#import <UIKit/UIWindow.h>
25
26#import "PushrPhotoProperties.h"
27#import "ExtendedAttributes.h"
28#import "Flickr.h"
29#import "MobilePushr.h"
30
31@implementation PushrPhotoTags
32
33- (void)show
34{
35 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
36 settingsRect.origin.x = 0.0f; // */ settingsRect.size.width;
37 settingsRect.origin.y = 0.0f;
38 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
39 Flickr *flickr = [[Flickr alloc] initWithPushr: _pushr];
40
41 _availableTags = [[flickr tags] retain];
42 _tagsView = [[UIView alloc] initWithFrame: settingsRect];
43 _navBar = [[UINavigationBar alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, 44.0f)];
44 [_navBar setBarStyle: 1];
45 [_navBar setDelegate: self];
46 [_navBar showLeftButton: nil withStyle: 0 rightButton: @"Done" withStyle: 0];
47
48 UINavigationItem *title = [[UINavigationItem alloc] initWithTitle: @"Tags"];
49 [_navBar pushNavigationItem: title];
50 [title release];
51
52 [_tagsView addSubview: _navBar];
53
54 _tagsTable = [[UIPreferencesTable alloc] initWithFrame: CGRectMake(0.0f, 44.0f, settingsRect.size.width, settingsRect.size.height - 44.0f)];
55 [_tagsTable setDataSource: self];
56 [_tagsTable setDelegate: self];
57 [_tagsTable reloadData];
58 [_tagsView addSubview: _tagsTable];
59
60 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: settingsRect];
61 [_mainWindow setContentView: transitionView];
62 [transitionView transition: 0 toView: _prefView];
63 [transitionView transition: 1 fromView: _prefView toView: _tagsView];
64 [transitionView release];
65}
66
67- (id)initFromWindow: (UIWindow *)window withPushr: (MobilePushr *)pushr withView: (UIView *)view withTable: (UIPreferencesTable *)table atPath: (NSString *)path
68{
69 if (![super init])
70 return nil;
71
72 _photoPath = [path retain];
73 _pushr = [pushr retain];
74 _mainWindow = window;
75 _prefView = view;
76 _prefTable = table;
77
78 [self show];
79
80 return self;
81}
82
83- (void)dealloc
84{
85 [_photoPath release];
86 [_availableTags release];
87 [_navBar release];
88 [_prefView release];
89 [_prefTable release];
90 [_tagsView release];
91 [_tagsTable release];
92 [_mainWindow release];
93 [_pushr release];
94 [super dealloc];
95}
96
97#pragma mark PushrGlobalTags delegates
98
99- (int)numberOfGroupsInPreferencesTable: (id)preferencesTable
100{
101 return 1;
102}
103
104- (int)preferencesTable: (UIPreferencesTable *)preferencesTable numberOfRowsInGroup: (int)group
105{
106 return [_availableTags count];
107}
108
109- (id)preferencesTable: (UIPreferencesTable *)preferencesTable titleForGroup: (int)group
110{
111 return @"Default tags for photos";
112}
113
114- (float)preferencesTable: (id)preferencesTable heightForRow:(int)row inGroup: (int)group withProposedHeight: (float)proposedHeight
115{
116 return 48.0f;
117}
118
119- (id)preferencesTable: (id)preferencesTable cellForRow: (int)row inGroup: (int)group
120{
121 struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
122 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
123
124 UIPreferencesTableCell *thisCell = [[UIPreferencesTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, rect.size.width, 48.0f)];
125 [thisCell setTitle: [_availableTags objectAtIndex: row]];
126 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: TAGS_ATTRIBUTE])
127 [thisCell setChecked: [[ExtendedAttributes objectForKey: TAGS_ATTRIBUTE atPath: _photoPath] containsObject: [_availableTags objectAtIndex: row]]];
128 else
129 [thisCell setChecked: [[defaults arrayForKey: @"defaultTags"] containsObject: [_availableTags objectAtIndex: row]]];
130
131 return [thisCell autorelease];
132}
133
134- (void)tableRowSelected: (NSNotification *)notification
135{
136 id row = [_tagsTable cellAtRow: [_tagsTable selectedRow] column: 0];
137 [row setChecked: ![row isChecked]];
138}
139
140- (void)navigationBar: (UINavigationBar *)navBar buttonClicked: (int)button
141{
142 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
143 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, settingsRect.size.height)];
144 [_mainWindow setContentView: transitionView];
145 [transitionView transition: 0 toView: _tagsView];
146
147 NSMutableArray *checkedTags = [NSMutableArray array];
148 for (int tagIndex = 0; tagIndex < [_availableTags count]; tagIndex++)
149 if ([[_tagsTable cellAtRow: tagIndex + 1 column: 0] isChecked])
150 [checkedTags addObject: [_availableTags objectAtIndex: tagIndex]];
151
152 [ExtendedAttributes setObject: checkedTags forKey: TAGS_ATTRIBUTE atPath: _photoPath];
153 [transitionView transition: 2 fromView: _tagsView toView: _prefView];
154 [_prefTable reloadData];
155 [_prefTable selectRow: -1 byExtendingSelection: NO];
156
157 [transitionView release];
158}
159
160@end
161
162@implementation PushrPhotoPrivacy
163
164- (void)show
165{
166 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
167 settingsRect.origin.x = 0.0f; // */ settingsRect.size.width;
168 settingsRect.origin.y = 0.0f;
169 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
170
171 _privacyView = [[UIView alloc] initWithFrame: settingsRect];
172 _navBar = [[UINavigationBar alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, 44.0f)];
173 [_navBar setBarStyle: 1];
174 [_navBar setDelegate: self];
175 [_navBar showLeftButton: nil withStyle: 0 rightButton: @"Done" withStyle: 0];
176
177 UINavigationItem *title = [[UINavigationItem alloc] initWithTitle: @"Privacy"];
178 [_navBar pushNavigationItem: title];
179 [title release];
180
181 [_privacyView addSubview: _navBar];
182
183 _privacyTable = [[UIPreferencesTable alloc] initWithFrame: CGRectMake(0.0f, 44.0f, settingsRect.size.width, settingsRect.size.height - 44.0f)];
184 [_privacyTable setDataSource: self];
185 [_privacyTable setDelegate: self];
186 [_privacyTable reloadData];
187 [_privacyView addSubview: _privacyTable];
188
189 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: settingsRect];
190 [_mainWindow setContentView: transitionView];
191 [transitionView transition: 0 toView: _prefView];
192 [transitionView transition: 1 fromView: _prefView toView: _privacyView];
193 [transitionView release];
194}
195
196- (id)initFromWindow: (UIWindow *)window withPushr: (MobilePushr *)pushr withView: (UIView *)view withTable: (UIPreferencesTable *)table atPath: (NSString *)path
197{
198 if (![super init])
199 return nil;
200
201 _photoPath = [path retain];
202 _pushr = [pushr retain];
203 _mainWindow = window;
204 _prefView = view;
205 _prefTable = table;
206 _availablePrivacy = [[NSArray arrayWithObjects: @"Private", @"Friends", @"Family", @"Public", nil] retain];
207
208 [self show];
209
210 return self;
211}
212
213- (void)dealloc
214{
215 [_photoPath release];
216 [_availablePrivacy release];
217 [_navBar release];
218 [_prefView release];
219 [_prefTable release];
220 [_privacyTable release];
221 [_privacyView release];
222 [_mainWindow release];
223 [_pushr release];
224 [super dealloc];
225}
226
227#pragma mark PushrGlobalPrivacy delegates
228
229- (int)numberOfGroupsInPreferencesTable: (id)preferencesTable
230{
231 return 1;
232}
233
234- (int)preferencesTable: (UIPreferencesTable *)preferencesTable numberOfRowsInGroup: (int)group
235{
236 return [_availablePrivacy count];
237}
238
239- (id)preferencesTable: (UIPreferencesTable *)preferencesTable titleForGroup: (int)group
240{
241 return @"Default privacy for photos";
242}
243
244- (float)preferencesTable: (id)preferencesTable heightForRow:(int)row inGroup: (int)group withProposedHeight: (float)proposedHeight
245{
246 return 48.0f;
247}
248
249- (BOOL)table: (id)table shouldIndentRow: (int)row
250{
251 if (row == 1 || row == 2)
252 return YES;
253 return NO;
254}
255
256- (id)preferencesTable: (id)preferencesTable cellForRow: (int)row inGroup: (int)group
257{
258 struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
259 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
260
261 UIPreferencesTableCell *thisCell = [[UIPreferencesTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, rect.size.width, 48.0f)];
262 // Ugly, ugly hack. If shouldIndentRow just worked properly this would be unnecessary.
263 if (row == 1 || row == 2)
264 [thisCell setTitle: [NSString stringWithFormat: @" %@", [_availablePrivacy objectAtIndex: row]]];
265 else
266 [thisCell setTitle: [_availablePrivacy objectAtIndex: row]];
267
268 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: PRIVACY_ATTRIBUTE])
269 [thisCell setChecked: [[ExtendedAttributes objectForKey: PRIVACY_ATTRIBUTE atPath: _photoPath] containsObject: [_availablePrivacy objectAtIndex: row]]];
270 else
271 [thisCell setChecked: [[defaults arrayForKey: PRIVACY_ATTRIBUTE] containsObject: [_availablePrivacy objectAtIndex: row]]];
272
273 return [thisCell autorelease];
274}
275
276/*
277 * This is a little tricky, it turns out! There are invalid combinations of privacy settings -
278 * for example, 'Friends' + 'Public' simply wouldn't make sense.
279 * This code allows the user to toggle friends/family rows, but prevents invalid combinations.
280 */
281- (void)tableRowSelected: (NSNotification *)notification
282{
283 id row = [_privacyTable cellAtRow: [_privacyTable selectedRow] column: 0];
284 switch ([_privacyTable selectedRow]) {
285 case 1:
286 case 2:
287 case 3: {
288 [row setChecked: ![row isChecked]];
289 [[_privacyTable cellAtRow: 1 column: 0] setChecked: YES];
290 [[_privacyTable cellAtRow: 4 column: 0] setChecked: NO];
291 break;
292 }
293 case 4: {
294 for (int currentRow = 1; currentRow < 4; currentRow++) {
295 [[_privacyTable cellAtRow: currentRow column: 0] setChecked: NO];
296 }
297 [row setChecked: YES];
298 }
299 }
300}
301
302- (void)navigationBar: (UINavigationBar *)navBar buttonClicked: (int)button
303{
304 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
305 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, settingsRect.size.height)];
306 [_mainWindow setContentView: transitionView];
307 [transitionView transition: 0 toView: _privacyView];
308
309 NSMutableArray *checkedPrivacySettings = [NSMutableArray array];
310 for (int settingIndex = 0; settingIndex < [_availablePrivacy count]; settingIndex++)
311 if ([[_privacyTable cellAtRow: settingIndex + 1 column: 0] isChecked])
312 [checkedPrivacySettings addObject: [_availablePrivacy objectAtIndex: settingIndex]];
313
314 [ExtendedAttributes setObject: checkedPrivacySettings forKey: PRIVACY_ATTRIBUTE atPath: _photoPath];
315 [transitionView transition: 2 fromView: _privacyView toView: _prefView];
316 [_prefTable reloadData];
317 [_prefTable selectRow: -1 byExtendingSelection: NO];
318
319 [transitionView release];
320}
321
322@end
323
324@implementation PushrPhotoProperties
325
326- (id)initFromWindow: (UIWindow *)window withPushr: (MobilePushr *)pushr forPhoto: (NSString *)photo
327{
328 if (![super init])
329 return nil;
330
331 _photoPath = [photo retain];
332 _pushr = [pushr retain];
333 _mainWindow = window;
334
335 [self show];
336
337 return self;
338}
339
340- (void)dealloc
341{
342 [_photoPath release];
343 [_navBar release];
344 [_prefView release];
345 [_prefTable release];
346 [_photoView release];
347 [_mainWindow release];
348 [_pushr release];
349 [super dealloc];
350}
351
352- (void)show
353{
354 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
355 settingsRect.origin.x = 0.0f; // */ settingsRect.size.width;
356 settingsRect.origin.y = 0.0f;
357 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
358
359 _prefView = [[UIView alloc] initWithFrame: settingsRect];
360 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: settingsRect];
361
362 _navBar = [[UINavigationBar alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, 44.0f)];
363 [_navBar setBarStyle: 1];
364 [_navBar setDelegate: self];
365 [_navBar showLeftButton: nil withStyle: 0 rightButton: @"Done" withStyle: 1];
366
367 UINavigationItem *title = [[UINavigationItem alloc] initWithTitle: @"Properties"];
368 [_navBar pushNavigationItem: title];
369 [title release];
370
371 [_prefView addSubview: _navBar];
372
373 _prefTable = [[UIPreferencesTable alloc] initWithFrame: CGRectMake(0.0f, 44.0f, settingsRect.size.width, settingsRect.size.height - 44.0f)];
374 [_prefTable setDataSource: self];
375 [_prefTable setDelegate: self];
376 [_prefTable reloadData];
377 [_prefView addSubview: _prefTable];
378
379 _photoView = [[_mainWindow contentView] retain];
380
381 // This doesn't seem like the right way to do this but it seems to work...
382 [_mainWindow setContentView: transitionView];
383 [transitionView transition: 0 toView: _photoView];
384 [transitionView transition: 1 fromView: _photoView toView: _prefView];
385 [transitionView release];
386}
387
388#pragma mark PushrSettings delegates
389- (void)navigationBar: (UINavigationBar *)navBar buttonClicked: (int)button
390{
391 struct CGRect settingsRect = [UIHardware fullScreenApplicationContentRect];
392 UITransitionView *transitionView = [[UITransitionView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, settingsRect.size.width, settingsRect.size.height)];
393 [_mainWindow setContentView: transitionView];
394 [transitionView transition: 0 toView: _prefView];
395
396 id cell = [_prefTable cellAtRow: 1 column: 0];
397 if ([[cell value] length] > 0)
398 [ExtendedAttributes setString: [cell value] forKey: NAME_ATTRIBUTE atPath: _photoPath];
399 cell = [_prefTable cellAtRow: 2 column: 0];
400 if ([[cell value] length] > 0)
401 [ExtendedAttributes setString: [cell value] forKey: DESCRIPTION_ATTRIBUTE atPath: _photoPath];
402
403 switch (button) {
404 default: {
405 [transitionView transition: 2 fromView: _prefView toView: _photoView];
406 }
407 }
408
409 [transitionView release];
410}
411
412- (int)numberOfGroupsInPreferencesTable:(id)preferencesTable { return 1; }
413
414- (int)preferencesTable: (UIPreferencesTable *)preferencesTable numberOfRowsInGroup: (int)group
415{
416 switch (group) {
417 default: {
418 return 4;
419 }
420 }
421}
422
423- (id)preferencesTable: (UIPreferencesTable *)preferencesTable cellForRow: (int)row inGroup: (int)group
424{
425 if (group > 0)
426 return nil;
427
428 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
429 struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
430
431 switch (row) {
432 case 0: {
433 id nameCell = [[UIPreferencesTextTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, rect.size.width, 48.0f)];
434 [nameCell setTitle: @"Name"];
435 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: NAME_ATTRIBUTE])
436 [nameCell setValue: [ExtendedAttributes stringForKey: NAME_ATTRIBUTE atPath: _photoPath]];
437 else
438 [nameCell setPlaceHolderValue: [_photoPath lastPathComponent]];
439 return [nameCell autorelease];
440 }
441 case 1: {
442 id descCell = [[UIPreferencesTextTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, rect.size.width, 48.0f)];
443 [descCell setTitle: @"Description"];
444 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: DESCRIPTION_ATTRIBUTE])
445 [descCell setValue: [ExtendedAttributes stringForKey: DESCRIPTION_ATTRIBUTE atPath: _photoPath]];
446 else
447 [descCell setPlaceHolderValue: @"Optional description"];
448 return [descCell autorelease];
449 }
450 case 2: {
451 id tagsCell = [[UIPreferencesTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 48.0f)];
452 [tagsCell setTitle: @"Tags"];
453 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: TAGS_ATTRIBUTE])
454 [tagsCell setValue: [[ExtendedAttributes objectForKey: TAGS_ATTRIBUTE atPath: _photoPath] componentsJoinedByString: @", "]];
455 else
456 [tagsCell setValue: [[defaults arrayForKey: @"defaultTags"] componentsJoinedByString: @", "]];
457 [tagsCell setShowDisclosure: YES];
458 return [tagsCell autorelease];
459 }
460 case 3: {
461 id privacyCell = [[UIPreferencesTableCell alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 48.0f)];
462 [privacyCell setTitle: @"Privacy"];
463 if ([[ExtendedAttributes allKeysAtPath: _photoPath] containsObject: PRIVACY_ATTRIBUTE])
464 [privacyCell setValue: [[ExtendedAttributes objectForKey: PRIVACY_ATTRIBUTE atPath: _photoPath] componentsJoinedByString: @" + "]];
465 else
466 [privacyCell setValue: [[defaults arrayForKey: @"defaultPrivacy"] componentsJoinedByString: @" + "]];
467 [privacyCell setShowDisclosure: YES];
468 return [privacyCell autorelease];
469 }
470 default:
471 return nil;
472 }
473}
474
475- (id)preferencesTable: (UIPreferencesTable *)preferencesTable titleForGroup: (int)group
476{
477 return [NSString stringWithFormat: @"Properties for photo %@", [_photoPath lastPathComponent]];
478}
479
480- (float)preferencesTable: (id)preferencesTable heightForRow:(int)row inGroup: (int)group withProposedHeight: (float)proposedHeight
481{
482 return 48.0f;
483}
484
485- (void)tableRowSelected:(NSNotification *)notification
486{
487 int i = [_prefTable selectedRow];
488 NSLog(@"Selected row %d", i);
489
490 id cell = [_prefTable cellAtRow: 1 column: 0];
491 if ([[cell value] length] > 0)
492 [ExtendedAttributes setString: [cell value] forKey: NAME_ATTRIBUTE atPath: _photoPath];
493 cell = [_prefTable cellAtRow: 2 column: 0];
494 if ([[cell value] length] > 0)
495 [ExtendedAttributes setString: [cell value] forKey: DESCRIPTION_ATTRIBUTE atPath: _photoPath];
496
497 switch (i) {
498 case 3: {
499 [[PushrPhotoTags alloc] initFromWindow: _mainWindow withPushr: _pushr withView: _prefView withTable: _prefTable atPath: _photoPath];
500 break;
501 }
502 case 4: {
503 [[PushrPhotoPrivacy alloc] initFromWindow: _mainWindow withPushr: _pushr withView: _prefView withTable: _prefTable atPath: _photoPath];
504 break;
505 }
506 }
507}
508
509@end