From: Grant Paul Date: Sat, 12 Feb 2011 07:27:43 +0000 (-0800) Subject: Move -init into -loadView -viewDidLoad and friends, as Apple wants. Add -navigationUR... X-Git-Tag: v1.1.0%b1~367 X-Git-Url: https://git.saurik.com/cydia.git/commitdiff_plain/35f0a3b5de5a22872f7fbd96183f510a5ad80aa0?ds=inline;hp=-c Move -init into -loadView -viewDidLoad and friends, as Apple wants. Add -navigationURL and persistance (15 minute timeout) of Cydia sessions, with full lazy-loading of view controllers. Still failed to fix the URL->blackscreen bug, although now it just shows the wrong tab instaed of a black screen (really, WTF, UITabBarController?) --- 35f0a3b5de5a22872f7fbd96183f510a5ad80aa0 diff --combined MobileCydia.mm index 17b17426,ccec42b8..bb01abd5 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@@ -1,5 -1,5 +1,5 @@@ /* Cydia - iPhone UIKit Front-End for Debian APT - * Copyright (C) 2008-2010 Jay Freeman (saurik) + * Copyright (C) 2008-2011 Jay Freeman (saurik) */ /* Modified BSD License {{{ */ @@@ -402,7 -402,6 +402,7 @@@ static const CFStringCompareFlags LaxCo #define ShowInternals (0 && !ForRelease) #define IgnoreInstall (0 && !ForRelease) #define AlwaysReload (0 && !ForRelease) +#define TryIndexedCollation (0 && !ForRelease) #if !TraceLogging #undef _trace @@@ -1072,7 -1071,7 +1072,7 @@@ static _transient NSMutableDictionary * static bool Changed_; static time_t now_; -static bool IsWildcat_; +bool IsWildcat_; /* }}} */ /* Display Helpers {{{ */ @@@ -1185,6 -1184,7 +1185,6 @@@ bool isSectionVisible(NSString *section @protocol CydiaDelegate - (void) retainNetworkActivityIndicator; - (void) releaseNetworkActivityIndicator; -- (void) setPackageController:(CYPackageController *)view; - (void) clearPackage:(Package *)package; - (void) installPackage:(Package *)package; - (void) installPackages:(NSArray *)packages; @@@ -2735,8 -2735,6 +2735,8 @@@ struct PackageNameOrdering if (range.location != NSNotFound) return YES; + [self parse]; + range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_]; if (range.location != NSNotFound) return YES; @@@ -4041,27 -4039,40 +4041,40 @@@ static NSString *Warning_ @implementation CYEmulatedLoadingController - - (CYEmulatedLoadingController *) init { - if ((self = [super init])) { - [[self view] setBackgroundColor:[UIColor pinStripeColor]]; - - indicator_ = [[CYLoadingIndicator alloc] initWithFrame:[[self view] bounds]]; - [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:indicator_]; - [indicator_ release]; - - tabbar_ = [[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 49.0f)]; - [tabbar_ setFrame:CGRectMake(0.0f, [[self view] bounds].size.height - [tabbar_ bounds].size.height, [[self view] bounds].size.width, [tabbar_ bounds].size.height)]; - [tabbar_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth]; - [[self view] addSubview:tabbar_]; - [tabbar_ release]; - - navbar_ = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 0, 44.0f)]; - [navbar_ setFrame:CGRectMake(0.0f, 0.0f, [[self view] bounds].size.width, [navbar_ bounds].size.height)]; - [navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth]; - [[self view] addSubview:navbar_]; - [navbar_ release]; - } return self; + - (void) dealloc { + [self releaseSubviews]; + + [super dealloc]; + } + + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + [[self view] setBackgroundColor:[UIColor pinStripeColor]]; + + indicator_ = [[CYLoadingIndicator alloc] initWithFrame:[[self view] bounds]]; + [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [[self view] addSubview:indicator_]; + + tabbar_ = [[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 49.0f)]; + [tabbar_ setFrame:CGRectMake(0.0f, [[self view] bounds].size.height - [tabbar_ bounds].size.height, [[self view] bounds].size.width, [tabbar_ bounds].size.height)]; + [tabbar_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth]; + [[self view] addSubview:tabbar_]; + + navbar_ = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 0, 44.0f)]; + [navbar_ setFrame:CGRectMake(0.0f, 0.0f, [[self view] bounds].size.width, [navbar_ bounds].size.height)]; + [navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth]; + [[self view] addSubview:navbar_]; + } + + - (void) releaseSubviews { + [indicator_ release]; + indicator_ = nil; + + [tabbar_ release]; + tabbar_ = nil; + + [navbar_ release]; + navbar_ = nil; } @end @@@ -4081,6 -4092,10 +4094,10 @@@ [super dealloc]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[[webview_ request] URL] absoluteString]]]; + } + - (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host { } @@@ -4089,16 -4104,18 +4106,16 @@@ WebDataSource *source([frame dataSource]); NSURLResponse *response([source response]); + NSURL *url([response URL]); NSString *scheme([url scheme]); - - NSHTTPURLResponse *http; - if (scheme != nil && ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"])) - http = (NSHTTPURLResponse *) response; - else - http = nil; - - NSDictionary *headers([http allHeaderFields]); NSString *host([url host]); - [self setHeaders:headers forHost:host]; + + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *http((NSHTTPURLResponse *) response); + NSDictionary *headers([http allHeaderFields]); + [self setHeaders:headers forHost:host]; + } if ( [host isEqualToString:@"cydia.saurik.com"] || @@@ -4481,6 -4498,7 +4498,6 @@@ bool DepSubstrate(const pkgCache::VerIt //[status_ setFont:font]; output_ = [[UITextView alloc] init]; - [output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; //[output_ setTextFont:@"Courier New"]; [output_ setFont:[[output_ font] fontWithSize:12]]; @@@ -4526,7 -4544,7 +4543,7 @@@ 10, 20, bounds.size.width - 20, - bounds.size.height - 62 + bounds.size.height - 96 )]; [close_ setFrame:CGRectMake( (bounds.size.width - closewidth) / 2, @@@ -5274,12 -5292,12 +5291,12 @@@ @implementation FileTable - (void) dealloc { - if (package_ != nil) - [package_ release]; - if (name_ != nil) - [name_ release]; + [self releaseSubviews]; + + [package_ release]; + [name_ release]; [files_ release]; - [list_ release]; + [super dealloc]; } @@@ -5305,21 -5323,35 +5322,35 @@@ return cell; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/files", [package_ id]]]; + } + + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:24.0f]; + [list_ setDataSource:self]; + [list_ setDelegate:self]; + [[self view] addSubview:list_]; + } + + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("INSTALLED_FILES")]; + } + + - (void) releaseSubviews { + [list_ release]; + list_ = nil; + } + - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - [[self navigationItem] setTitle:UCLocalize("INSTALLED_FILES")]; - files_ = [[NSMutableArray arrayWithCapacity:32] retain]; - - list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; - [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:24.0f]; - [[self view] addSubview:list_]; - - [list_ setDataSource:self]; - [list_ setDelegate:self]; } return self; } @@@ -5369,6 -5401,8 +5400,8 @@@ } - (void) reloadData { + [super reloadData]; + [self setPackage:[database_ packageWithName:name_]]; } @@@ -5408,9 -5442,15 +5441,13 @@@ } - (void) release { - if ([self retainCount] == 1) - [delegate_ setPackageController:self]; [super release]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@", [package_ id]]]; + } + /* XXX: this is not safe at all... localization of /fail/ */ - (void) _clickButtonWithName:(NSString *)name { if ([name isEqualToString:UCLocalize("CLEAR")]) @@@ -5504,11 -5544,11 +5541,16 @@@ } #endif ++- (void) viewWillAppear:(BOOL)animated { ++ if (![self hasLoaded]) ++ [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/package/")]]; ++ [super viewWillAppear:animated]; ++} ++ - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; buttons_ = [[NSMutableArray alloc] initWithCapacity:4]; - [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/package/")]]; - [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]]; } return self; } @@@ -5570,14 -5610,14 +5612,16 @@@ } - (void) reloadData { ++ [super reloadData]; ++ [self setPackage:[database_ packageWithName:name_]]; } @end /* }}} */ -/* Package Table {{{ */ -@interface PackageTable : UIView < +/* Package List Controller {{{ */ +@interface PackageListController : CYViewController < UITableViewDataSource, UITableViewDelegate > { @@@ -5588,16 -5628,29 +5632,16 @@@ UITableView *list_; NSMutableArray *index_; NSMutableDictionary *indices_; - // XXX: this target_ seems to be delegate_. :( - _transient id target_; - SEL action_; - // XXX: why do we even have this delegate_? - _transient id delegate_; + NSString *title_; } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action; - +- (id) initWithDatabase:(Database *)database title:(NSString *)title; - (void) setDelegate:(id)delegate; - -- (void) reloadData; - (void) resetCursor; -- (UITableView *) list; - -- (void) setShouldHideHeaderInShortLists:(BOOL)hide; - -- (void) deselectWithAnimation:(BOOL)animated; - @end -@implementation PackageTable +@implementation PackageListController - (void) dealloc { [packages_ release]; @@@ -5605,98 -5658,13 +5649,98 @@@ [list_ release]; [index_ release]; [indices_ release]; + [title_ release]; [super dealloc]; } +- (void) deselectWithAnimation:(BOOL)animated { + [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds duration:(NSTimeInterval)duration curve:(UIViewAnimationCurve)curve { + CGRect base = [[self view] bounds]; + base.size.height -= bounds.size.height; + base.origin = [list_ frame].origin; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationBeginsFromCurrentState:YES]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationDuration:duration]; + [list_ setFrame:base]; + [UIView commitAnimations]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds duration:(NSTimeInterval)duration { + [self resizeForKeyboardBounds:bounds duration:duration curve:UIViewAnimationCurveLinear]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds { + [self resizeForKeyboardBounds:bounds duration:0]; +} + +- (void) keyboardWillShow:(NSNotification *)notification { + CGRect bounds; + CGPoint center; + NSTimeInterval duration; + UIViewAnimationCurve curve; + [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&bounds]; + [[[notification userInfo] objectForKey:UIKeyboardCenterEndUserInfoKey] getValue:¢er]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration]; + + CGRect kbframe = CGRectMake(round(center.x - bounds.size.width / 2.0), round(center.y - bounds.size.height / 2.0), bounds.size.width, bounds.size.height); + UIViewController *base = self; + while ([base parentViewController] != nil) + base = [base parentViewController]; + CGRect viewframe = [[base view] convertRect:[list_ frame] fromView:[list_ superview]]; + CGRect intersection = CGRectIntersection(viewframe, kbframe); + + [self resizeForKeyboardBounds:intersection duration:duration curve:curve]; +} + +- (void) keyboardWillHide:(NSNotification *)notification { + NSTimeInterval duration; + UIViewAnimationCurve curve; + [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration]; + + [self resizeForKeyboardBounds:CGRectZero duration:duration curve:curve]; +} + +- (void) viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [self resizeForKeyboardBounds:CGRectZero]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; +} + +- (void) viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [self resizeForKeyboardBounds:CGRectZero]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; +} + +- (void) viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self deselectWithAnimation:animated]; +} + +- (void) didSelectPackage:(Package *)package { + CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]); + [view setPackage:package]; + [view setDelegate:delegate_]; + [[self navigationController] pushViewController:view animated:YES]; +} + +#if TryIndexedCollation + (BOOL) hasIndexedCollation { return NO; // XXX: objc_getClass("UILocalizedIndexedCollation") != nil; } +#endif - (NSInteger) numberOfSectionsInTableView:(UITableView *)list { NSInteger count([sections_ count]); @@@ -5734,10 -5702,15 +5778,10 @@@ return cell; } -- (void) deselectWithAnimation:(BOOL)animated { - [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; -} - -- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path { +- (void) tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)path { Package *package([self packageAtIndexPath:path]); package = [database_ packageWithName:[package id]]; - [target_ performSelector:action_ withObject:package]; - return path; + [self didSelectPackage:package]; } - (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView { @@@ -5746,37 -5719,32 +5790,37 @@@ } - (NSInteger) tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { +#if TryIndexedCollation if ([[self class] hasIndexedCollation]) { return [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionForSectionIndexTitleAtIndex:index]; } +#endif return index; } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action { - if ((self = [super initWithFrame:frame]) != nil) { +- (id) initWithDatabase:(Database *)database title:(NSString *)title { + if ((self = [super init]) != nil) { database_ = database; + title_ = [title copy]; + [[self navigationItem] setTitle:title_]; - target_ = target; - action_ = action; +#if TryIndexedCollation + if ([[self class] hasIndexedCollation]) + index_ = [[[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles] retain] + else +#endif + index_ = [[NSMutableArray alloc] initWithCapacity:32]; - index_ = [[self class] hasIndexedCollation] - ? [[[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles] retain] - : [[NSMutableArray alloc] initWithCapacity:32]; indices_ = [[NSMutableDictionary alloc] initWithCapacity:32]; packages_ = [[NSMutableArray arrayWithCapacity:16] retain]; sections_ = [[NSMutableArray arrayWithCapacity:16] retain]; - list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain]; + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [list_ setRowHeight:73]; - [self addSubview:list_]; + [[self view] addSubview:list_]; [list_ setDataSource:self]; [list_ setDelegate:self]; @@@ -5792,6 -5760,6 +5836,8 @@@ } - (void) reloadData { ++ [super reloadData]; ++ era_ = [database_ era]; NSArray *packages = [database_ packages]; @@@ -5808,7 -5776,6 +5854,7 @@@ Section *section = nil; +#if TryIndexedCollation if ([[self class] hasIndexedCollation]) { id collation = [objc_getClass("UILocalizedIndexedCollation") currentCollation]; NSArray *titles = [collation sectionIndexTitles]; @@@ -5839,9 -5806,7 +5885,9 @@@ [section addToCount]; } _end - } else { + } else +#endif + { [index_ removeAllObjects]; _profile(PackageTable$reloadData$Section) @@@ -5881,10 -5846,18 +5927,10 @@@ [list_ scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:NO]; } -- (UITableView *) list { - return list_; -} - -- (void) setShouldHideHeaderInShortLists:(BOOL)hide { - //XXX:[list_ setShouldHideHeaderInShortLists:hide]; -} - @end /* }}} */ -/* Filtered Package Table {{{ */ -@interface FilteredPackageTable : PackageTable { +/* Filtered Package List Controller {{{ */ +@interface FilteredPackageListController : PackageListController { SEL filter_; IMP imp_; id object_; @@@ -5893,11 -5866,11 +5939,11 @@@ - (void) setObject:(id)object; - (void) setObject:(id)object forFilter:(SEL)filter; -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object; +- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object; @end -@implementation FilteredPackageTable +@implementation FilteredPackageListController - (void) dealloc { if (object_ != nil) @@@ -5935,15 -5908,94 +5981,15 @@@ _end } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object { - if ((self = [super initWithFrame:frame database:database target:target action:action]) != nil) { +- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { + if ((self = [super initWithDatabase:database title:title]) != nil) { [self setFilter:filter]; - object_ = [object retain]; + [self setObject:object]; [self reloadData]; } return self; } @end -/* }}} */ -/* Filtered Package Controller {{{ */ -@interface FilteredPackageController : CYViewController { - _transient Database *database_; - FilteredPackageTable *packages_; - NSString *title_; - SEL filter_; - id object_; -} - -- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object; - -@end - -@implementation FilteredPackageController - -- (void) dealloc { - [self releaseSubviews]; - [title_ release]; - - [super dealloc]; -} - -- (void) viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [packages_ deselectWithAnimation:animated]; -} - -- (void) didSelectPackage:(Package *)package { - CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]); - [view setPackage:package]; - [view setDelegate:delegate_]; - [[self navigationController] pushViewController:view animated:YES]; -} - -- (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - packages_ = [[FilteredPackageTable alloc] - initWithFrame:[[self view] bounds] - database:database_ - target:self - action:@selector(didSelectPackage:) - filter:filter_ - with:object_ - ]; - [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:packages_]; -} - -- (void) viewDidLoad { - [[self navigationItem] setTitle:title_]; -} - -- (void) releaseSubviews { - [packages_ release]; -} - -- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { - if ((self = [super init]) != nil) { - database_ = database; - title_ = [title copy]; - filter_ = filter; - object_ = object; - } return self; -} - -- (void) reloadData { - [super reloadData]; - [packages_ reloadData]; -} - -- (void) setDelegate:(id)delegate { - [super setDelegate:delegate]; - [packages_ setDelegate:delegate]; -} - -@end - /* }}} */ /* Home Controller {{{ */ @@@ -5953,10 -6005,14 +5999,14 @@@ @implementation HomeController --+ (BOOL)shouldHideNavigationBar { +++ (BOOL) shouldHideNavigationBar { return NO; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://home"]; + } + - (void) _setMoreHeaders:(NSMutableURLRequest *)request { [super _setMoreHeaders:request]; @@@ -5976,7 -6032,7 +6026,7 @@@ [alert setCancelButtonIndex:0]; [alert setMessage: - @"Copyright (C) 2008-2010\n" + @"Copyright (C) 2008-2011\n" "Jay Freeman (saurik)\n" "saurik@saurik.com\n" "http://www.saurik.com/" @@@ -5985,13 -6041,13 +6035,6 @@@ [alert show]; } --- (void) viewWillAppear:(BOOL)animated { -- [super viewWillAppear:animated]; -- -- if ([[self class] shouldHideNavigationBar]) -- [[self navigationController] setNavigationBarHidden:YES animated:animated]; --} -- - (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; @@@ -5999,17 -6055,17 +6042,23 @@@ [[self navigationController] setNavigationBarHidden:NO animated:animated]; } --- (id) init { -- if ((self = [super init]) != nil) { - [self loadURL:[NSURL URLWithString:CydiaURL(@"")]]; ++- (void) viewWillAppear:(BOOL)animated { ++ if (![self hasLoaded]) + [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/home/")]]; -- [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] -- initWithTitle:UCLocalize("ABOUT") -- style:UIBarButtonItemStylePlain -- target:self -- action:@selector(aboutButtonClicked) -- ] autorelease]]; -- } return self; ++ [super viewWillAppear:animated]; ++ ++ if ([[self class] shouldHideNavigationBar]) ++ [[self navigationController] setNavigationBarHidden:YES animated:animated]; ++} ++ ++- (void) viewDidLoad { ++ [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] ++ initWithTitle:UCLocalize("ABOUT") ++ style:UIBarButtonItemStylePlain ++ target:self ++ action:@selector(aboutButtonClicked) ++ ] autorelease]]; } @end @@@ -6023,21 -6079,25 +6072,28 @@@ @implementation ManageController - - (id) init { - if ((self = [super init]) != nil) { - [[self navigationItem] setTitle:UCLocalize("MANAGE")]; + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://manage"]; + } -- (id) init { - if ((self = [super init]) != nil) { - [[self navigationItem] setTitle:UCLocalize("MANAGE")]; ++- (void) viewWillAppear:(BOOL)animated { ++ if (![self hasLoaded]) + [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/manage/")]]; - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("SETTINGS") - style:UIBarButtonItemStylePlain - target:self - action:@selector(settingsButtonClicked) - ] autorelease]]; - [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]]; ++ [super viewWillAppear:animated]; ++} - [self queueStatusDidChange]; - } return self; - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("SETTINGS") - style:UIBarButtonItemStylePlain - target:self - action:@selector(settingsButtonClicked) - ] autorelease]]; ++- (void) viewDidLoad { ++ [[self navigationItem] setTitle:UCLocalize("MANAGE")]; + - [self queueStatusDidChange]; - } return self; ++ [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] ++ initWithTitle:UCLocalize("SETTINGS") ++ style:UIBarButtonItemStylePlain ++ target:self ++ action:@selector(settingsButtonClicked) ++ ] autorelease]]; ++ ++ [self queueStatusDidChange]; } - (void) settingsButtonClicked { @@@ -6050,11 -6110,11 +6106,11 @@@ } - (void) applyLoadingTitle { -- // No "Loading" title. ++ // Disable "Loading" title. } - (void) applyRightButton { -- // No right button. ++ // Disable right button. } #endif @@@ -6074,6 -6134,6 +6130,7 @@@ } - (bool) isLoading { ++ // Never show as loading. return false; } @@@ -6213,6 -6273,7 +6270,7 @@@ id root_; } -- (NSArray *) navigationURLItems; ++- (NSArray *) navigationURLCollection; - (void) dropBar:(BOOL)animated; - (void) beginUpdate; - (void) raiseBar:(BOOL)animated; @@@ -6222,16 -6283,29 +6280,33 @@@ @implementation CYTabBarController - - (void) reloadData { - size_t count([[self viewControllers] count]); - for (size_t i(0); i != count; ++i) { - CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); - [page reloadData]; -- (NSArray *) navigationURLItems { ++- (NSArray *) navigationURLCollection { + NSMutableArray *items([NSMutableArray array]); + - // XXX:Deal with transient view controllers. ++ // XXX: Should this deal with transient view controllers? + for (id navigation in [self viewControllers]) { - NSArray *stack = [navigation performSelector:@selector(navigationURLStack)]; ++ NSArray *stack = [navigation performSelector:@selector(navigationURLCollection)]; + if (stack != nil) + [items addObject:stack]; } + return items; + } + + - (void) reloadData { - size_t count([[self viewControllers] count]); - for (size_t i(0); i != count; ++i) { - CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); - [page reloadData]; - } ++ for (CYViewController *controller in [self viewControllers]) ++ [controller reloadData]; + [(CYNavigationController *)[self transientViewController] reloadData]; } ++- (void) dealloc { ++ [refreshbar_ release]; ++ [[NSNotificationCenter defaultCenter] removeObserver:self]; ++ ++ [super dealloc]; ++} ++ - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; @@@ -6456,12 -6530,12 +6531,6 @@@ } } --- (void) dealloc { -- [refreshbar_ release]; -- [[NSNotificationCenter defaultCenter] removeObserver:self]; -- [super dealloc]; --} -- @end /* }}} */ /* Cydia Navigation Controller {{{ */ @@@ -6470,6 -6544,7 +6539,7 @@@ _transient id delegate_; } -- (NSArray *) navigationURLStack; ++- (NSArray *) navigationURLCollection; - (id) initWithDatabase:(Database *)database; - (void) reloadData; @@@ -6482,11 -6557,23 +6552,22 @@@ [super dealloc]; } -- (NSArray *) navigationURLStack { ++- (NSArray *) navigationURLCollection { + NSMutableArray *stack([NSMutableArray array]); + + for (CYViewController *controller in [self viewControllers]) { + NSString *url = [[controller navigationURL] absoluteString]; + if (url != nil) + [stack addObject:url]; + } + + return stack; + } + - (void) reloadData { -- size_t count([[self viewControllers] count]); -- for (size_t i(0); i != count; ++i) { -- CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); -- [page reloadData]; ++ for (CYViewController *page in [self viewControllers]) { ++ if ([page hasLoaded]) ++ [page reloadData]; } } @@@ -6605,7 -6692,8 +6686,8 @@@ /* }}} */ /* Section Controller {{{ */ -@interface SectionController : FilteredPackageController { +@interface SectionController : FilteredPackageListController { + NSString *section_; } - (id) initWithDatabase:(Database *)database section:(NSString *)section; @@@ -6614,6 -6702,14 +6696,14 @@@ @implementation SectionController + - (NSURL *) navigationURL { + NSString *name = section_; + if (name == nil) + name = @"all"; + + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sections/%@", name]]; + } + - (id) initWithDatabase:(Database *)database section:(NSString *)name { NSString *title; @@@ -6625,6 -6721,8 +6715,8 @@@ title = UCLocalize("NO_SECTION"); } + section_ = name; + if ((self = [super initWithDatabase:database title:title filter:@selector(isVisibleInSection:) with:name]) != nil) { } return self; } @@@ -6644,9 -6742,6 +6736,6 @@@ } - (id) initWithDatabase:(Database *)database; - - (void) reloadData; - - (void) resetView; - - (void) editButtonClicked; @end @@@ -6654,15 -6749,17 +6743,17 @@@ @implementation SectionsController - (void) dealloc { - [list_ setDataSource:nil]; - [list_ setDelegate:nil]; - + [self releaseSubviews]; [sections_ release]; [filtered_ release]; - [list_ release]; + [super dealloc]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://sections"]; + } + - (void) updateNavigationItem { [[self navigationItem] setTitle:editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")]; if ([sections_ count] == 0) { @@@ -6676,6 -6773,6 +6767,10 @@@ } } ++- (BOOL) isEditing { ++ return editing_; ++} ++ - (void) setEditing:(BOOL)editing { if ((editing_ = editing)) [list_ reloadData]; @@@ -6711,7 -6808,7 +6806,7 @@@ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *reuseIdentifier = @"SectionCell"; -- SectionCell *cell = (SectionCell *) [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; ++ SectionCell *cell = (SectionCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if (cell == nil) cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease]; @@@ -6735,28 -6832,38 +6830,38 @@@ [[self navigationController] pushViewController:controller animated:YES]; } + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:45.0f]; + [list_ setDataSource:self]; + [list_ setDelegate:self]; + [[self view] addSubview:list_]; + } + + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("SECTIONS")]; + } + + - (void) releaseSubviews { + [list_ release]; + list_ = nil; + } + - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - [[self navigationItem] setTitle:UCLocalize("SECTIONS")]; - sections_ = [[NSMutableArray arrayWithCapacity:16] retain]; filtered_ = [[NSMutableArray arrayWithCapacity:16] retain]; - - list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; - [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:45.0f]; - [[self view] addSubview:list_]; - - [list_ setDataSource:self]; - [list_ setDelegate:self]; - - [self reloadData]; } return self; } - (void) reloadData { + [super reloadData]; + NSArray *packages = [database_ packages]; [sections_ removeAllObjects]; @@@ -6811,11 -6918,6 +6916,6 @@@ _trace(); } - - (void) resetView { - if (editing_) - [self editButtonClicked]; - } - - (void)editButtonClicked { [self setEditing:!editing_]; } @@@ -6844,18 -6946,20 +6944,26 @@@ @implementation ChangesController - (void) dealloc { - [list_ setDelegate:nil]; - [list_ setDataSource:nil]; - + [self releaseSubviews]; CFRelease(packages_); - [sections_ release]; - [list_ release]; + [super dealloc]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://changes"]; + } + ++- (void) viewWillAppear:(BOOL)animated { ++ // Loads after it appears, so don't load beforehand. ++ loaded_ = YES; ++ [super viewWillAppear:animated]; ++} ++ - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; + if (!hasSentFirstLoad_) { hasSentFirstLoad_ = YES; [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0]; @@@ -6924,23 -7028,35 +7032,32 @@@ [delegate_ distUpgrade]; } - - (NSString *) title { return UCLocalize("CHANGES"); } + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:73]; + [list_ setDataSource:self]; + [list_ setDelegate:self]; + [[self view] addSubview:list_]; + } + + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("CHANGES")]; + } + + - (void) releaseSubviews { + [list_ release]; + list_ = nil; + } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - [[self navigationItem] setTitle:UCLocalize("CHANGES")]; - // We load after the view is visible, so don't "magically" load beforehand. - loaded_ = YES; - packages_ = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); sections_ = [[NSMutableArray arrayWithCapacity:16] retain]; - - list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; - [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:73]; - [[self view] addSubview:list_]; - - [list_ setDataSource:self]; - [list_ setDelegate:self]; } return self; } @@@ -7062,10 -7178,11 +7179,11 @@@ @end /* }}} */ /* Search Controller {{{ */ -@interface SearchController : FilteredPackageController < +@interface SearchController : FilteredPackageListController < UISearchBarDelegate > { UISearchBar *search_; + BOOL searchloaded_; } - (id) initWithDatabase:(Database *)database; @@@ -7081,29 -7198,38 +7199,41 @@@ [super dealloc]; } + - (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://search/%@", [search_ text]]]; ++ if ([search_ text] == nil || [[search_ text] isEqualToString:@""]) ++ return [NSURL URLWithString:@"cydia://search"]; ++ else ++ return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://search/%@", [search_ text]]]; + } + - (void) setSearchTerm:(NSString *)searchTerm { [search_ setText:searchTerm]; + [self reloadData]; } - (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar { - [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; + [self setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; [search_ resignFirstResponder]; [self reloadData]; } - (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text { - [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSelectedForBy:)]; + [self setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)]; [self reloadData]; } - (id) initWithDatabase:(Database *)database { - return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil]; + if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil])) { + search_ = [[UISearchBar alloc] init]; + } return self; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - if (!search_) { - search_ = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, 44.0f)]; + + if (!searchloaded_) { + searchloaded_ = YES; + [search_ setFrame:CGRectMake(0, 0, [[self view] bounds].size.width, 44.0f)]; [search_ layoutSubviews]; [search_ setPlaceholder:UCLocalize("SEARCH_EX")]; @@@ -7120,15 -7246,10 +7250,10 @@@ } } - - (void) _reloadData { - } - - (void) reloadData { - _profile(SearchController$reloadData) - [super reloadData]; - _end - PrintTimes(); - [packages_ setObject:[search_ text]]; ++ [self setObject:[search_ text]]; + [super reloadData]; - [packages_ resetCursor]; + [self resetCursor]; } - (void) didSelectPackage:(Package *)package { @@@ -7160,18 -7281,17 +7285,17 @@@ @implementation PackageSettingsController - (void) dealloc { + [self releaseSubviews]; [name_ release]; - if (package_ != nil) - [package_ release]; - [table_ release]; - [subscribedSwitch_ release]; - [ignoredSwitch_ release]; - [subscribedCell_ release]; - [ignoredCell_ release]; + [package_ release]; [super dealloc]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/settings", [package_ id]]]; + } + - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { if (package_ == nil) return 0; @@@ -7220,48 -7340,69 +7344,69 @@@ return nil; } - - (NSString *) title { return UCLocalize("SETTINGS"); } + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - (id) initWithDatabase:(Database *)database package:(NSString *)package { - if ((self = [super init])) { - database_ = database; - name_ = [package retain]; + table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped]; + [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [table_ setDataSource:self]; + [table_ setDelegate:self]; + [[self view] addSubview:table_]; - [[self navigationItem] setTitle:UCLocalize("SETTINGS")]; + subscribedSwitch_ = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; + [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; + [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged]; - table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped]; - [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:table_]; + ignoredSwitch_ = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; + [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; + [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged]; + // Disable this switch, since it only reflects (not modifies) the ignored state. + [ignoredSwitch_ setUserInteractionEnabled:NO]; - subscribedSwitch_ = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; - [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged]; + subscribedCell_ = [[UITableViewCell alloc] init]; + [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")]; + [subscribedCell_ setAccessoryView:subscribedSwitch_]; + [subscribedCell_ setSelectionStyle:UITableViewCellSelectionStyleNone]; - ignoredSwitch_ = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; - [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged]; - // Disable this switch, since it only reflects (not modifies) the ignored state. - [ignoredSwitch_ setUserInteractionEnabled:NO]; + ignoredCell_ = [[UITableViewCell alloc] init]; + [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")]; + [ignoredCell_ setAccessoryView:ignoredSwitch_]; + [ignoredCell_ setSelectionStyle:UITableViewCellSelectionStyleNone]; + // FIXME: Ignored state is not saved. + [ignoredCell_ setUserInteractionEnabled:NO]; + } + + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("SETTINGS")]; + } - subscribedCell_ = [[UITableViewCell alloc] init]; - [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")]; - [subscribedCell_ setAccessoryView:subscribedSwitch_]; - [subscribedCell_ setSelectionStyle:UITableViewCellSelectionStyleNone]; + - (void) releaseSubviews { + [ignoredCell_ release]; + ignoredCell_ = nil; - ignoredCell_ = [[UITableViewCell alloc] init]; - [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")]; - [ignoredCell_ setAccessoryView:ignoredSwitch_]; - [ignoredCell_ setSelectionStyle:UITableViewCellSelectionStyleNone]; - // FIXME: Ignored state is not saved. - [ignoredCell_ setUserInteractionEnabled:NO]; + [subscribedCell_ release]; + subscribedCell_ = nil; - [table_ setDataSource:self]; - [table_ setDelegate:self]; - [self reloadData]; + [table_ release]; + table_ = nil; + + [ignoredSwitch_ release]; + ignoredSwitch_ = nil; + + [subscribedSwitch_ release]; + subscribedSwitch_ = nil; + } + + - (id) initWithDatabase:(Database *)database package:(NSString *)package { + if ((self = [super init])) { + database_ = database; + name_ = [package retain]; } return self; } - (void) reloadData { + [super reloadData]; + if (package_ != nil) [package_ autorelease]; package_ = [database_ packageWithName:name_]; @@@ -7274,47 -7415,51 +7419,11 @@@ [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]; -} - -- (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/signature", package_]]; --} -- --- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { -- // XXX: dude! -- [super webView:view 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 /* }}} */ /* Installed Controller {{{ */ -@interface InstalledController : FilteredPackageController { +@interface InstalledController : FilteredPackageListController { BOOL expert_; } @@@ -7331,7 -7476,9 +7440,9 @@@ [super dealloc]; } - - (NSString *) title { return UCLocalize("INSTALLED"); } + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://installed"]; + } - (id) initWithDatabase:(Database *)database { if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndUnfiltered:) with:[NSNumber numberWithBool:YES]]) != nil) { @@@ -7363,6 -7510,10 +7474,6 @@@ #endif } -- (void) reloadData { - [packages_ reloadData]; -} - - (void) updateRoleButton { if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] @@@ -7374,13 -7525,18 +7485,13 @@@ } - (void) roleButtonClicked { - [packages_ setObject:[NSNumber numberWithBool:expert_]]; - [packages_ reloadData]; + [self setObject:[NSNumber numberWithBool:expert_]]; + [self reloadData]; expert_ = !expert_; [self updateRoleButton]; } -- (void) setDelegate:(id)delegate { - [super setDelegate:delegate]; - [packages_ setDelegate:delegate]; -} - @end /* }}} */ @@@ -7470,7 -7626,8 +7581,8 @@@ @end /* }}} */ /* Source Controller {{{ */ -@interface SourceController : FilteredPackageController { +@interface SourceController : FilteredPackageListController { + Source *source_; } - (id) initWithDatabase:(Database *)database source:(Source *)source; @@@ -7479,7 -7636,13 +7591,13 @@@ @implementation SourceController + - (NSURL *) navigationURL { + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sources/%@", [source_ name]]]; + } + - (id) initWithDatabase:(Database *)database source:(Source *)source { + source_ = source; + if ((self = [super initWithDatabase:database title:[source label] filter:@selector(isVisibleInSource:) with:source]) != nil) { } return self; } @@@ -7510,7 -7673,6 +7628,6 @@@ } - (id) initWithDatabase:(Database *)database; - - (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated; @end @@@ -7526,12 -7688,11 +7643,11 @@@ } - (void) dealloc { - if (href_ != nil) - [href_ release]; - if (hud_ != nil) - [hud_ release]; - if (error_ != nil) - [error_ release]; + [self releaseSubviews]; + + [href_ release]; + [hud_ release]; + [error_ release]; //[self _releaseConnection:installer_]; [self _releaseConnection:trivial_]; @@@ -7540,10 -7701,13 +7656,13 @@@ //[self _releaseConnection:automatic_]; [sources_ release]; - [list_ release]; [super dealloc]; } + - (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://sources"]; + } + - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; @@@ -7745,8 -7909,6 +7864,6 @@@ [self _endConnection:connection]; } - - (NSString *) title { return UCLocalize("SOURCES"); } - - (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:href] @@@ -7824,27 -7986,37 +7941,37 @@@ } } - - (id) initWithDatabase:(Database *)database { - if ((self = [super init]) != nil) { - [[self navigationItem] setTitle:UCLocalize("SOURCES")]; - [self updateButtonsForEditingStatus:NO animated:NO]; + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - database_ = database; - sources_ = [[NSMutableArray arrayWithCapacity:16] retain]; + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:56]; + [list_ setDataSource:self]; + [list_ setDelegate:self]; + [[self view] addSubview:list_]; + } - list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; - [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:56]; - [[self view] addSubview:list_]; + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("SOURCES")]; + [self updateButtonsForEditingStatus:NO animated:NO]; + } - [list_ setDataSource:self]; - [list_ setDelegate:self]; + - (void) releaseSubviews { + [list_ release]; + list_ = nil; + } - [self reloadData]; + - (id) initWithDatabase:(Database *)database { + if ((self = [super init]) != nil) { + database_ = database; + sources_ = [[NSMutableArray arrayWithCapacity:16] retain]; } return self; } - (void) reloadData { + [super reloadData]; + pkgSourceList list; if (!list.ReadMainList()) return; @@@ -7953,48 -8125,63 +8080,63 @@@ @end @implementation SettingsController + - (void) dealloc { + [self releaseSubviews]; + + [super dealloc]; + } + + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + + table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped]; + [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [table_ setDelegate:self]; + [table_ setDataSource:self]; + [[self view] addSubview:table_]; + + 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_]; + } + + - (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")]; + + 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]; + } + + - (void) releaseSubviews { [table_ release]; + table_ = nil; + [segment_ release]; - [container_ release]; + segment_ = nil; - [super dealloc]; + [container_ release]; + container_ = nil; } - (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; } @@@ -8109,61 -8296,82 +8251,82 @@@ return section == 3 ? container_ : nil; } + - (void) reloadData { + [super reloadData]; + [table_ reloadData]; + } + @end /* }}} */ /* Stash Controller {{{ */ @interface StashController : CYViewController { - // XXX: just delete these things - _transient UIActivityIndicatorView *spinner_; - _transient UILabel *status_; - _transient UILabel *caption_; + UIActivityIndicatorView *spinner_; + UILabel *status_; + UILabel *caption_; } @end @implementation StashController - - (id) init { - if ((self = [super init])) { - [[self view] setBackgroundColor:[UIColor viewFlipsideBackgroundColor]]; - spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; - CGRect spinrect = [spinner_ frame]; - spinrect.origin.x = ([[self view] frame].size.width / 2) - (spinrect.size.width / 2); - spinrect.origin.y = [[self view] frame].size.height - 80.0f; - [spinner_ setFrame:spinrect]; - [spinner_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin]; - [[self view] addSubview:spinner_]; - [spinner_ startAnimating]; + - (void) dealloc { + [self releaseSubviews]; - CGRect captrect; - captrect.size.width = [[self view] frame].size.width; - captrect.size.height = 40.0f; - captrect.origin.x = 0; - captrect.origin.y = ([[self view] frame].size.height / 2) - (captrect.size.height * 2); - caption_ = [[[UILabel alloc] initWithFrame:captrect] autorelease]; - [caption_ setText:UCLocalize("PREPARING_FILESYSTEM")]; - [caption_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; - [caption_ setFont:[UIFont boldSystemFontOfSize:28.0f]]; - [caption_ setTextColor:[UIColor whiteColor]]; - [caption_ setBackgroundColor:[UIColor clearColor]]; - [caption_ setShadowColor:[UIColor blackColor]]; - [caption_ setTextAlignment:UITextAlignmentCenter]; - [[self view] addSubview:caption_]; - - CGRect statusrect; - statusrect.size.width = [[self view] frame].size.width; - statusrect.size.height = 30.0f; - statusrect.origin.x = 0; - statusrect.origin.y = ([[self view] frame].size.height / 2) - statusrect.size.height; - status_ = [[[UILabel alloc] initWithFrame:statusrect] autorelease]; - [status_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; - [status_ setText:UCLocalize("EXIT_WHEN_COMPLETE")]; - [status_ setFont:[UIFont systemFontOfSize:16.0f]]; - [status_ setTextColor:[UIColor whiteColor]]; - [status_ setBackgroundColor:[UIColor clearColor]]; - [status_ setShadowColor:[UIColor blackColor]]; - [status_ setTextAlignment:UITextAlignmentCenter]; - [[self view] addSubview:status_]; - } return self; + [super dealloc]; + } + + - (void) loadView { + [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + [[self view] setBackgroundColor:[UIColor viewFlipsideBackgroundColor]]; + + spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; + CGRect spinrect = [spinner_ frame]; + spinrect.origin.x = ([[self view] frame].size.width / 2) - (spinrect.size.width / 2); + spinrect.origin.y = [[self view] frame].size.height - 80.0f; + [spinner_ setFrame:spinrect]; + [spinner_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin]; + [[self view] addSubview:spinner_]; + [spinner_ startAnimating]; + + CGRect captrect; + captrect.size.width = [[self view] frame].size.width; + captrect.size.height = 40.0f; + captrect.origin.x = 0; + captrect.origin.y = ([[self view] frame].size.height / 2) - (captrect.size.height * 2); + caption_ = [[[UILabel alloc] initWithFrame:captrect] autorelease]; + [caption_ setText:UCLocalize("PREPARING_FILESYSTEM")]; + [caption_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; + [caption_ setFont:[UIFont boldSystemFontOfSize:28.0f]]; + [caption_ setTextColor:[UIColor whiteColor]]; + [caption_ setBackgroundColor:[UIColor clearColor]]; + [caption_ setShadowColor:[UIColor blackColor]]; + [caption_ setTextAlignment:UITextAlignmentCenter]; + [[self view] addSubview:caption_]; + + CGRect statusrect; + statusrect.size.width = [[self view] frame].size.width; + statusrect.size.height = 30.0f; + statusrect.origin.x = 0; + statusrect.origin.y = ([[self view] frame].size.height / 2) - statusrect.size.height; + status_ = [[[UILabel alloc] initWithFrame:statusrect] autorelease]; + [status_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; + [status_ setText:UCLocalize("EXIT_WHEN_COMPLETE")]; + [status_ setFont:[UIFont systemFontOfSize:16.0f]]; + [status_ setTextColor:[UIColor whiteColor]]; + [status_ setBackgroundColor:[UIColor clearColor]]; + [status_ setShadowColor:[UIColor blackColor]]; + [status_ setTextAlignment:UITextAlignmentCenter]; + [[self view] addSubview:status_]; + } + + - (void) releaseSubviews { + [spinner_ release]; + spinner_ = nil; + + [status_ release]; + status_ = nil; + + [caption_ release]; + caption_ = nil; } @end @@@ -8301,8 -8509,8 +8464,7 @@@ if (recently || loaded_ || ManualRefresh) { [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO]; -- // If we are cancelling due to ManualRefresh or a recent refresh -- // we need to make sure it knows it's already loaded. ++ // If we are cancelling, we need to make sure it knows it's already loaded. loaded_ = true; return; } else { @@@ -8537,41 -8745,6 +8699,6 @@@ [self complete]; } - - (void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { - CYNavigationController *controller = (CYNavigationController *) viewController; - - if ([[controller viewControllers] count] == 0) { - int index = [[tabbar_ viewControllers] indexOfObjectIdenticalTo:controller]; - CYViewController *root = nil; - - if (index == 0) - root = [[[HomeController alloc] init] autorelease]; - else if (index == 1) - root = [[[SectionsController alloc] initWithDatabase:database_] autorelease]; - else if (index == 2) - root = [[[ChangesController alloc] initWithDatabase:database_] autorelease]; - - if (IsWildcat_) { - if (index == 3) - root = [[[InstalledController alloc] initWithDatabase:database_] autorelease]; - else if (index == 4) - root = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; - else if (index == 5) - root = [[[SearchController alloc] initWithDatabase:database_] autorelease]; - } else { - if (index == 3) - root = [[[ManageController alloc] init] autorelease]; - else if (index == 4) - root = [[[SearchController alloc] initWithDatabase:database_] autorelease]; - } - - [root setDelegate:self]; - - if (root != nil) - [controller setViewControllers:[NSArray arrayWithObject:root]]; - } - } - - (void) showSettings { SettingsController *role = [[[SettingsController alloc] initWithDatabase:database_ delegate:self] autorelease]; CYNavigationController *nav = [[[CYNavigationController alloc] initWithRootViewController:role] autorelease]; @@@ -8590,6 -8763,12 +8717,6 @@@ [self setNetworkActivityIndicatorVisible:NO]; } -- (void) setPackageController:(CYPackageController *)view { - WebThreadLock(); - [view setPackage:nil]; - WebThreadUnlock(); -} - - (void) cancelAndClear:(bool)clear { @synchronized (self) { if (clear) { @@@ -8746,6 -8925,15 +8873,15 @@@ controller = [[[CYBrowserController alloc] init] autorelease]; [(CYBrowserController *)controller loadURL:[NSURL URLWithString:destination]]; } else if ([components count] == 1) { + if ([base isEqualToString:@"storage"]) { + controller = [[[CYBrowserController alloc] init] autorelease]; + [(CYBrowserController *)controller loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]]]; + } + + if ([base isEqualToString:@"manage"]) { + controller = [[[ManageController alloc] init] autorelease]; + } + if ([base isEqualToString:@"sources"]) { controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; } @@@ -8813,8 -9001,8 +8949,6 @@@ if ([base isEqualToString:@"package"]) { if ([arg2 isEqualToString:@"settings"]) { controller = [[[PackageSettingsController alloc] initWithDatabase:database_ package:arg1] autorelease]; -- } else if ([arg2 isEqualToString:@"signature"]) { -- controller = [[[SignatureController alloc] initWithDatabase:database_ package:arg1] autorelease]; } else if ([arg2 isEqualToString:@"files"]) { if (Package *package = [database_ packageWithName:arg1]) { controller = [[[FileTable alloc] initWithDatabase:database_] autorelease]; @@@ -8856,6 -9044,14 +8990,15 @@@ [super applicationWillResignActive:application]; } + - (void) applicationWillTerminate:(UIApplication *)application { - [Metadata_ setObject:[tabbar_ navigationURLItems] forKey:@"InterfaceState"]; ++ Changed_ = true; ++ [Metadata_ setObject:[tabbar_ navigationURLCollection] forKey:@"InterfaceState"]; + [Metadata_ setObject:[NSDate date] forKey:@"LastClosed"]; + [Metadata_ setObject:[NSNumber numberWithInt:[tabbar_ selectedIndex]] forKey:@"InterfaceIndex"]; + + [self _saveConfig]; + } + - (void) addStashController { ++locked_; stash_ = [[StashController alloc] init]; @@@ -9014,9 -9210,51 +9157,51 @@@ _trace() [self showEmulatedLoadingControllerInView:nil]; [window_ setUserInteractionEnabled:YES]; - // Show the home page. - CYNavigationController *navigation = [[tabbar_ viewControllers] objectAtIndex:0]; - [navigation setViewControllers:[NSArray arrayWithObject:[self pageForURL:[NSURL URLWithString:@"cydia://home"]]]]; + int selectedIndex = 0; + NSMutableArray *items = nil; + + bool recently = false; + NSDate *closed([Metadata_ objectForKey:@"LastClosed"]); + if (closed != nil) { + NSTimeInterval interval([closed timeIntervalSinceNow]); + // XXX: Is 15 minutes the optimal time here? + if (interval <= 0 && interval > -(15*60)) + recently = true; + } + + if (recently && [Metadata_ objectForKey:@"InterfaceState"]) { + items = [[Metadata_ objectForKey:@"InterfaceState"] mutableCopy]; + selectedIndex = [[Metadata_ objectForKey:@"InterfaceIndex"] intValue]; + } else { + items = [NSMutableArray array]; + [items addObject:[NSArray arrayWithObject:@"cydia://home"]]; + [items addObject:[NSArray arrayWithObject:@"cydia://sections"]]; + [items addObject:[NSArray arrayWithObject:@"cydia://changes"]]; + if (!IsWildcat_) { + [items addObject:[NSArray arrayWithObject:@"cydia://manage"]]; + } else { + [items addObject:[NSArray arrayWithObject:@"cydia://installed"]]; + [items addObject:[NSArray arrayWithObject:@"cydia://sources"]]; + } + [items addObject:[NSArray arrayWithObject:@"cydia://search"]]; + } + + [tabbar_ setSelectedIndex:selectedIndex]; + for (unsigned int tab = 0; tab < [[tabbar_ viewControllers] count]; tab++) { + NSArray *stack = [items objectAtIndex:tab]; + CYNavigationController *navigation = [[tabbar_ viewControllers] objectAtIndex:tab]; + NSMutableArray *current = [NSMutableArray array]; + + for (unsigned int nav = 0; nav < [stack count]; nav++) { + NSString *addr = [stack objectAtIndex:nav]; + NSURL *url = [NSURL URLWithString:addr]; + CYViewController *page = [self pageForURL:url]; + if (page != nil) + [current addObject:page]; + } + + [navigation setViewControllers:current]; + } // (Try to) show the startup URL. if (starturl_ != nil) { diff --combined UICaboodle/RVPage.h index 1f39428a,68ffb39d..5d1346e8 --- a/UICaboodle/RVPage.h +++ b/UICaboodle/RVPage.h @@@ -2,10 -2,13 +2,31 @@@ #import ++@interface UIViewController (Cydia) ++- (BOOL) hasLoaded; ++@end ++ @interface CYViewController : UIViewController { id delegate_; + BOOL loaded_; } - - (void)setDelegate:(id)delegate; ++ ++// The default implementation of this method is essentially a no-op, ++// but calling the superclass implementation is *required*. +- (void) reloadData; ++// This URL is used to save the state of the view controller. Return ++// nil if you cannot or should not save the URL for this page. + - (NSURL *)navigationURL; ++// By default, this delegate is unused. However, it's provided here in case ++// you need some kind of delegate in a subclass. + - (void) setDelegate:(id)delegate; -- (void) reloadData; ++- (id)delegate; ++// Override this in subclasses if you manage the "has seen first load" state yourself. ++- (BOOL) hasLoaded; ++// This is called when the view managed by the view controller is released. ++// That is not always when the controller itself is released: it also can ++// happen when more memory is needed by the system or whenever the controller ++// just happens not to be visible. + - (void) releaseSubviews; @end diff --combined UICaboodle/RVPage.mm index 3e6e6927,d3de6d31..05a1e25b --- a/UICaboodle/RVPage.mm +++ b/UICaboodle/RVPage.mm @@@ -5,15 -5,40 +5,58 @@@ #import "RVBook.h" +extern bool IsWildcat_; + ++@implementation UIViewController (Cydia) ++ ++- (BOOL) hasLoaded { ++ return YES; ++} ++ ++@end ++ @implementation CYViewController + - (void) setDelegate:(id)delegate { delegate_ = delegate; } + ++- (id) delegate { ++ return delegate_; ++} ++ + - (void) viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + - if (!loaded_) ++ if (![self hasLoaded]) + [self reloadData]; + } + ++- (BOOL) hasLoaded { ++ return loaded_; ++} ++ + - (void) releaseSubviews { + // Do nothing. + } + + - (void) setView:(UIView *)view { + if (view == nil) + [self releaseSubviews]; + + [super setView:view]; + } + - (void) reloadData { + loaded_ = YES; + } + + - (NSURL *) navigationURL { + return nil; } + - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { - return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad || orientation == UIInterfaceOrientationPortrait); + return IsWildcat_ || orientation == UIInterfaceOrientationPortrait; } + @end