+ [name_ release];
+ if (package_ != nil)
+ [package_ release];
+ [table_ release];
+ [subscribedSwitch_ release];
+ [ignoredSwitch_ release];
+ [subscribedCell_ release];
+ [ignoredCell_ release];
+
+ [super dealloc];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ if (package_ == nil)
+ return 0;
+
+ return 1;
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (package_ == nil)
+ return 0;
+
+ return 1;
+}
+
+- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
+ return UCLocalize("SHOW_ALL_CHANGES_EX");
+}
+
+- (void) onSomething:(BOOL)value withKey:(NSString *)key {
+ if (package_ == nil)
+ return;
+
+ NSMutableDictionary *metadata([package_ metadata]);
+
+ BOOL before;
+ if (NSNumber *number = [metadata objectForKey:key])
+ before = [number boolValue];
+ else
+ before = NO;
+
+ if (value != before) {
+ [metadata setObject:[NSNumber numberWithBool:value] forKey:key];
+ Changed_ = true;
+ [delegate_ updateData];
+ }
+}
+
+- (void) onSubscribed:(id)control {
+ [self onSomething:(int) [control isOn] withKey:@"IsSubscribed"];
+}
+
+- (void) onIgnored:(id)control {
+ [self onSomething:(int) [control isOn] withKey:@"IsIgnored"];
+}
+
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (package_ == nil)
+ return nil;
+
+ switch ([indexPath row]) {
+ case 0: return subscribedCell_;
+ case 1: return ignoredCell_;
+
+ _nodefault
+ }
+
+ return nil;
+}
+
+- (NSString *) title { return UCLocalize("SETTINGS"); }
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+ if ((self = [super init])) {
+ database_ = database;
+ name_ = [package retain];
+
+ [[self navigationItem] setTitle:UCLocalize("SETTINGS")];
+
+ table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
+ [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [table_ setAllowsSelection:NO];
+ [[self view] addSubview:table_];
+
+ subscribedSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+ [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+ [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged];
+
+ ignoredSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+ [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+ [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged];
+
+ subscribedCell_ = [[UITableViewCell alloc] init];
+ [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
+ [subscribedCell_ setAccessoryView:subscribedSwitch_];
+
+ ignoredCell_ = [[UITableViewCell alloc] init];
+ [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")];
+ [ignoredCell_ setAccessoryView:ignoredSwitch_];
+
+ [table_ setDataSource:self];
+ [table_ setDelegate:self];
+ [self reloadData];
+ } return self;
+}
+
+- (void) reloadData {
+ if (package_ != nil)
+ [package_ autorelease];
+ package_ = [database_ packageWithName:name_];
+ if (package_ != nil) {
+ [package_ retain];
+ [subscribedSwitch_ setOn:([package_ subscribed] ? 1 : 0) animated:NO];
+ [ignoredSwitch_ setOn:([package_ ignored] ? 1 : 0) animated:NO];
+ }
+
+ [table_ reloadData];
+}
+
+@end
+/* }}} */
+
+/* Signature Controller {{{ */
+@interface SignatureController : CYBrowserController {
+ _transient Database *database_;
+ NSString *package_;
+}
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package;
+
+@end
+
+@implementation SignatureController
+
+- (void) dealloc {
+ [package_ release];
+ [super dealloc];
+}
+
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+ // XXX: dude!
+ [super webView:sender didClearWindowObject:window forFrame:frame];
+}
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+ if ((self = [super init]) != nil) {
+ database_ = database;
+ package_ = [package retain];
+ [self reloadData];
+ } return self;
+}
+
+- (void) reloadData {
+ [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]];
+}
+
+@end
+/* }}} */
+/* Role Controller {{{ */
+@interface RoleController : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
+ _transient Database *database_;
+ id roledelegate_;
+ UITableView *table_;
+ UISegmentedControl *segment_;
+ UIView *container_;
+}
+
+- (void) showDoneButton;
+- (void) resizeSegmentedControl;
+
+@end
+
+@implementation RoleController
+- (void) dealloc {
+ [table_ release];
+ [segment_ release];
+ [container_ release];
+
+ [super dealloc];
+}
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+ if ((self = [super init])) {
+ database_ = database;
+ roledelegate_ = delegate;
+
+ [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")];
+
+ NSArray *items = [NSArray arrayWithObjects:
+ UCLocalize("USER"),
+ UCLocalize("HACKER"),
+ UCLocalize("DEVELOPER"),
+ nil];
+ segment_ = [[UISegmentedControl alloc] initWithItems:items];
+ container_ = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)];
+ [container_ addSubview:segment_];
+
+ int index = -1;
+ if ([Role_ isEqualToString:@"User"]) index = 0;
+ if ([Role_ isEqualToString:@"Hacker"]) index = 1;
+ if ([Role_ isEqualToString:@"Developer"]) index = 2;
+ if (index != -1) {
+ [segment_ setSelectedSegmentIndex:index];
+ [self showDoneButton];
+ }
+
+ [segment_ addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];
+ [self resizeSegmentedControl];
+
+ table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
+ [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [table_ setDelegate:self];
+ [table_ setDataSource:self];
+ [[self view] addSubview:table_];
+ [table_ reloadData];
+ } return self;
+}
+
+- (void) resizeSegmentedControl {
+ CGFloat width = [[self view] frame].size.width;
+ [segment_ setFrame:CGRectMake(width / 32.0f, 0, width - (width / 32.0f * 2.0f), 44.0f)];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ [self resizeSegmentedControl];
+}
+
+- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+ [self resizeSegmentedControl];
+}
+
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [self resizeSegmentedControl];
+}
+
+- (void) save {
+ NSString *role(nil);
+
+ switch ([segment_ selectedSegmentIndex]) {
+ case 0: role = @"User"; break;
+ case 1: role = @"Hacker"; break;
+ case 2: role = @"Developer"; break;
+
+ _nodefault
+ }
+
+ if (![role isEqualToString:Role_]) {
+ bool rolling(Role_ == nil);
+ Role_ = role;
+
+ Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ Role_, @"Role",
+ nil];
+
+ [Metadata_ setObject:Settings_ forKey:@"Settings"];
+
+ Changed_ = true;
+
+ if (rolling)
+ [roledelegate_ loadData];
+ else
+ [roledelegate_ updateData];
+ }
+}
+
+- (void) segmentChanged:(UISegmentedControl *)control {
+ [self showDoneButton];
+}
+
+- (void) doneButtonClicked {
+ [self save];
+ [[self navigationController] dismissModalViewControllerAnimated:YES];
+}
+
+- (void) showDoneButton {
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("DONE")
+ style:UIBarButtonItemStyleDone
+ target:self
+ action:@selector(doneButtonClicked)
+ ];
+ [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] == nil];
+ [rightItem release];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ // XXX: For not having a single cell in the table, this sure is a lot of sections.
+ return 6;
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return 0; // :(
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ return nil; // This method is required by the protocol.
+}
+
+- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
+ if (section == 1)
+ return UCLocalize("ROLE_EX");
+ if (section == 4)
+ return [NSString stringWithFormat:
+ @"%@: %@\n%@: %@\n%@: %@",
+ UCLocalize("USER"), UCLocalize("USER_EX"),
+ UCLocalize("HACKER"), UCLocalize("HACKER_EX"),
+ UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX")
+ ];
+ else return nil;
+}
+
+- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+ if (section == 3) return 44.0f;
+ else return 0;
+}
+
+- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
+ if (section == 3) return container_;
+ else return nil;
+}
+
+@end
+/* }}} */
+
+/* Cydia Container {{{ */
+@interface CYContainer : UIViewController <ProgressDelegate> {
+ _transient Database *database_;
+ RefreshBar *refreshbar_;
+
+ bool dropped_;
+ bool updating_;
+ id updatedelegate_;
+ UITabBarController *root_;
+}
+
+- (void) setTabBarController:(UITabBarController *)controller;
+
+- (void) dropBar:(BOOL)animated;
+- (void) beginUpdate;
+- (void) raiseBar:(BOOL)animated;
+- (BOOL) updating;
+
+@end
+
+@implementation CYContainer
+
+- (BOOL) _reallyWantsFullScreenLayout {
+ return YES;
+}
+
+// NOTE: UIWindow only sends the top controller these messages,
+// So we have to forward them on.
+
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [root_ viewDidAppear:animated];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [root_ viewWillAppear:animated];
+}
+
+- (void) viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+ [root_ viewDidDisappear:animated];
+}