]> git.saurik.com Git - cydia.git/commitdiff
Added session persistence; moved -init to -loadView, -viewDidLoad, etc; added releasi...
authorGrant Paul <chpwn@chpwn.com>
Wed, 2 Feb 2011 08:11:55 +0000 (00:11 -0800)
committerGrant Paul <chpwn@chpwn.com>
Wed, 2 Feb 2011 08:11:55 +0000 (00:11 -0800)
MobileCydia.mm
UICaboodle/RVPage.h
UICaboodle/RVPage.mm

index 0c9634b56db878eb5a4a4f52abc08d3a5d693b04..27d9bd3fdc23344649e8e07ccf718a4be9110064 100644 (file)
@@ -4039,27 +4039,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
@@ -4079,6 +4092,10 @@ static NSString *Warning_;
     [super dealloc];
 }
 
+- (NSURL *) navigationURL {
+    return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[[webview_ request] URL] absoluteString]]];
+}
+
 - (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host {
 }
 
@@ -5267,12 +5284,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @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];
 }
 
@@ -5298,21 +5315,35 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     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;
 }
 
@@ -5362,6 +5393,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) reloadData {
+    [super reloadData];
+
     [self setPackage:[database_ packageWithName:name_]];
 }
 
@@ -5406,6 +5439,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [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")])
@@ -5878,6 +5915,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _transient Database *database_;
     FilteredPackageTable *packages_;
     NSString *title_;
+    SEL filter_;
+    id object_;
 }
 
 - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
@@ -5887,7 +5926,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @implementation FilteredPackageController
 
 - (void) dealloc {
-    [packages_ release];
+    [self releaseSubviews];
     [title_ release];
 
     [super dealloc];
@@ -5905,29 +5944,40 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [[self navigationController] pushViewController:view animated:YES];
 }
 
-- (NSString *) title { return title_; }
+- (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];
-        [[self navigationItem] setTitle:title_];
-
-        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_];
+        filter_ = filter;
+        object_ = object;
     } return self;
 }
 
 - (void) reloadData {
+    [super reloadData];
     [packages_ reloadData];
 }
 
@@ -5951,6 +6001,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return NO;
 }
 
+- (NSURL *) navigationURL {
+    return [NSURL URLWithString:@"cydia://home"];
+}
+
 - (void) _setMoreHeaders:(NSMutableURLRequest *)request {
     [super _setMoreHeaders:request];
 
@@ -6017,6 +6071,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @implementation ManageController
 
+- (NSURL *) navigationURL {
+    return [NSURL URLWithString:@"cydia://manage"];
+}
+
 - (id) init {
     if ((self = [super init]) != nil) {
         [[self navigationItem] setTitle:UCLocalize("MANAGE")];
@@ -6207,6 +6265,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     id root_;
 }
 
+- (NSArray *) navigationURLItems;
 - (void) dropBar:(BOOL)animated;
 - (void) beginUpdate;
 - (void) raiseBar:(BOOL)animated;
@@ -6216,6 +6275,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @implementation CYTabBarController
 
+- (NSArray *) navigationURLItems {
+    NSMutableArray *items([NSMutableArray array]);
+
+    // XXX:Deal with transient view controllers.
+    for (id navigation in [self viewControllers]) {
+        NSArray *stack = [navigation performSelector:@selector(navigationURLStack)];
+        if (stack != nil)
+            [items addObject:stack];
+    }
+
+    return items;
+}
+
 - (void) reloadData {
     size_t count([[self viewControllers] count]);
     for (size_t i(0); i != count; ++i) {
@@ -6464,6 +6536,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _transient id<UINavigationControllerDelegate> delegate_;
 }
 
+- (NSArray *) navigationURLStack;
 - (id) initWithDatabase:(Database *)database;
 - (void) reloadData;
 
@@ -6476,6 +6549,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
+- (NSArray *) navigationURLStack {
+    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) {
@@ -6600,6 +6685,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 /* Section Controller {{{ */
 @interface SectionController : FilteredPackageController {
+    NSString *section_;
 }
 
 - (id) initWithDatabase:(Database *)database section:(NSString *)section;
@@ -6608,6 +6694,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @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;
 
@@ -6619,6 +6713,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         title = UCLocalize("NO_SECTION");
     }
 
+    section_ = name;
+
     if ((self = [super initWithDatabase:database title:title filter:@selector(isVisibleInSection:) with:name]) != nil) {
     } return self;
 }
@@ -6638,9 +6734,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database;
-- (void) reloadData;
-- (void) resetView;
-
 - (void) editButtonClicked;
 
 @end
@@ -6648,15 +6741,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @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) {
@@ -6729,28 +6824,38 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [[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];
@@ -6805,11 +6910,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _trace();
 }
 
-- (void) resetView {
-    if (editing_)
-        [self editButtonClicked];
-}
-
 - (void)editButtonClicked {
     [self setEditing:!editing_];
 }
@@ -6838,18 +6938,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @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) viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
+
     if (!hasSentFirstLoad_) {
         hasSentFirstLoad_ = YES;
         [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0];
@@ -6918,23 +7020,35 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [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;
 }
 
@@ -7060,6 +7174,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     UISearchBarDelegate
 > {
     UISearchBar *search_;
+    BOOL searchloaded_;
 }
 
 - (id) initWithDatabase:(Database *)database;
@@ -7075,8 +7190,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
+- (NSURL *) navigationURL {
+    return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://search/%@", [search_ text]]];
+}
+
 - (void) setSearchTerm:(NSString *)searchTerm {
     [search_ setText:searchTerm];
+    [self reloadData];
 }
 
 - (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
@@ -7086,18 +7206,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text {
-    [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
+    [packages_ setObject:[search_ 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")];
 
@@ -7114,14 +7238,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (void) _reloadData {
-}
-
 - (void) reloadData {
-    _profile(SearchController$reloadData)
-        [packages_ reloadData];
-    _end
-    PrintTimes();
+    [packages_ setObject:[search_ text]];
+    [super reloadData];
     [packages_ resetCursor];
 }
 
@@ -7154,18 +7273,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @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;
@@ -7214,48 +7332,69 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     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];
+}
 
-        subscribedCell_ = [[UITableViewCell alloc] init];
-        [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
-        [subscribedCell_ setAccessoryView:subscribedSwitch_];
-        [subscribedCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
+- (void) viewDidLoad {
+    [[self navigationItem] setTitle:UCLocalize("SETTINGS")];
+}
 
-        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) releaseSubviews {
+    [ignoredCell_ release];
+    ignoredCell_ = nil;
 
-        [table_ setDataSource:self];
-        [table_ setDelegate:self];
-        [self reloadData];
+    [subscribedCell_ release];
+    subscribedCell_ = nil;
+
+    [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_];
@@ -7287,6 +7426,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [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];
@@ -7325,7 +7468,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [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) {
@@ -7470,6 +7615,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 /* }}} */
 /* Source Controller {{{ */
 @interface SourceController : FilteredPackageController {
+    Source *source_;
 }
 
 - (id) initWithDatabase:(Database *)database source:(Source *)source;
@@ -7478,7 +7624,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @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;
 }
@@ -7509,7 +7661,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database;
-
 - (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated;
 
 @end
@@ -7525,12 +7676,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (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_];
@@ -7539,10 +7689,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     //[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];
@@ -7744,8 +7897,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [self _endConnection:connection];
 }
 
-- (NSString *) title { return UCLocalize("SOURCES"); }
-
 - (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method {
     NSMutableURLRequest *request = [NSMutableURLRequest
         requestWithURL:[NSURL URLWithString:href]
@@ -7823,27 +7974,37 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (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;
@@ -7952,48 +8113,63 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @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;
 }
 
@@ -8108,61 +8284,82 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     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
@@ -8536,41 +8733,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [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];
@@ -8756,6 +8918,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [(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];
         }
@@ -8866,6 +9032,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [super applicationWillResignActive:application];
 }
 
+- (void) applicationWillTerminate:(UIApplication *)application {
+    [Metadata_ setObject:[tabbar_ navigationURLItems] 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];
@@ -9011,9 +9185,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) {
index 1f39428a8d5a6ded7d3502036a788653c9ef1392..68ffb39d6cd6669eeb5eff6817aefb8edcc267cf 100644 (file)
@@ -4,8 +4,11 @@
 
 @interface CYViewController : UIViewController {
     id delegate_;
+    BOOL loaded_;
 }
-- (void)setDelegate:(id)delegate;
+- (NSURL *)navigationURL;
+- (void) setDelegate:(id)delegate;
 - (void) reloadData;
+- (void) releaseSubviews;
 @end
 
index 81c8739c37b145f3aef6f788e5a17d52aa49d907..d3de6d31bbd7ee725108e63414bfc25a546b6f03 100644 (file)
@@ -6,12 +6,39 @@
 #import "RVBook.h"
 
 @implementation CYViewController
+
 - (void) setDelegate:(id)delegate {
     delegate_ = delegate;
 }
+
+- (void) viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+
+    if (!loaded_)
+        [self reloadData];
+}
+
+- (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);
 }
+
 @end