]> git.saurik.com Git - cydia.git/commitdiff
Merge branch 'master' of saurik.com:cydia into url-tabbar
authorGrant Paul <chpwn@chpwn.com>
Wed, 5 Jan 2011 07:31:15 +0000 (23:31 -0800)
committerGrant Paul <chpwn@chpwn.com>
Wed, 5 Jan 2011 07:31:15 +0000 (23:31 -0800)
1  2 
MobileCydia.mm
UICaboodle/BrowserView.mm

diff --combined MobileCydia.mm
index 57643ee08d653ba8bcfbe0fd404ab8d856d5a7e3,79b34952eb62af12b217a9af715cd42140df5336..71f000643fdc2243e4c9c88fc16a8f0bc82c5d1c
@@@ -1179,12 -1179,12 +1179,12 @@@ bool isSectionVisible(NSString *section
  - (void) setConfigurationData:(NSString *)data;
  @end
  
 -@class PackageController;
 +@class CYPackageController;
  
  @protocol CydiaDelegate
  - (void) retainNetworkActivityIndicator;
  - (void) releaseNetworkActivityIndicator;
 -- (void) setPackageController:(PackageController *)view;
 +- (void) setPackageController:(CYPackageController *)view;
  - (void) clearPackage:(Package *)package;
  - (void) installPackage:(Package *)package;
  - (void) installPackages:(NSArray *)packages;
  - (UIProgressHUD *) addProgressHUD;
  - (void) removeProgressHUD:(UIProgressHUD *)hud;
  - (CYViewController *) pageForPackage:(NSString *)name;
 -- (PackageController *) packageController;
  - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
  @end
  
@@@ -1345,6 -1346,7 +1345,7 @@@ typedef std::map< unsigned long, _H<Sou
      pkgSourceList *list_;
  
      SourceMap sources_;
+     CFMutableArrayRef deadSources_;
      CFMutableArrayRef packages_;
  
      _transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
      int cydiafd_;
      int statusfd_;
      FILE *input_;
+     std::map<const char *, _H<NSString> > sections_;
  }
  
  + (Database *) sharedInstance;
  
  - (void) setDelegate:(id)delegate;
  - (Source *) getSource:(pkgCache::PkgFileIterator)file;
+ - (NSString *) mappedSectionForPointer:(const char *)pointer;
  @end
  /* }}} */
  /* Delegate Helpers {{{ */
@@@ -1824,7 -1831,8 +1830,8 @@@ struct ParsedPackage 
  };
  
  @interface Package : NSObject {
-     uint32_t era_ : 29;
+     uint32_t era_ : 26;
+     uint32_t role_ : 3;
      uint32_t essential_ : 1;
      uint32_t obsolete_ : 1;
      uint32_t ignored_ : 1;
      CYString latest_;
      CYString installed_;
  
-     CYString section_;
+     const char *section_;
      _transient NSString *section$_;
  
      Source *source_;
      ParsedPackage *parsed_;
  
      NSMutableArray *tags_;
-     NSString *role_;
  }
  
  - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
  - (NSArray *) applications;
  
  - (Source *) source;
- - (NSString *) role;
  
  - (BOOL) matches:(NSString *)text;
  
@@@ -2075,15 -2081,10 +2080,10 @@@ struct PackageNameOrdering 
  - (void) dealloc {
      if (parsed_ != NULL)
          delete parsed_;
      if (source_ != nil)
          [source_ release];
      if (tags_ != nil)
          [tags_ release];
-     if (role_ != nil)
-         [role_ release];
      [super dealloc];
  }
  
                      const char *name(tag.Name());
                      [tags_ addObject:[(NSString *)CYStringCreate(name) autorelease]];
  
-                     if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
-                         role_ = (NSString *) CYStringCreate(name + 6);
+                     if (role_ == 0 && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/) {
+                         if (strcmp(name + 6, "enduser") == 0)
+                             role_ = 1;
+                         else if (strcmp(name + 6, "hacker") == 0)
+                             role_ = 2;
+                         else if (strcmp(name + 6, "developer") == 0)
+                             role_ = 3;
+                         else if (strcmp(name + 6, "cydia") == 0)
+                             role_ = 7;
+                         else
+                             role_ = 4;
+                     }
  
                      if (strncmp(name, "cydia::", 7) == 0) {
                          if (strcmp(name + 7, "essential") == 0)
          _end
  
          _profile(Package$initWithVersion$Section)
-             section_.set(NULL, iterator.Section());
+             section_ = iterator.Section();
          _end
  
          _profile(Package$initWithVersion$Flags)
  
  - (NSString *) section {
      if (section$_ == nil) {
-         if (section_.empty())
+         if (section_ == NULL)
              return nil;
  
-         _profile(Package$section)
-             std::replace(section_.data(), section_.data() + section_.size(), '_', ' ');
-             NSString *name(section_);
-             section$_ = [SectionMap_ objectForKey:name] ?: name;
+         _profile(Package$section$mappedSectionForPointer)
+             section$_ = [database_ mappedSectionForPointer:section_];
          _end
      } return section$_;
  }
  
  - (BOOL) unfiltered {
      _profile(Package$unfiltered$obsolete)
-         if (obsolete_)
+         if (_unlikely(obsolete_))
              return false;
      _end
  
      _profile(Package$unfiltered$hasSupportingRole)
-         if (![self hasSupportingRole])
+         if (_unlikely(![self hasSupportingRole]))
              return false;
      _end
  
      if (![self unfiltered])
          return false;
  
-     NSString *section([self section]);
+     NSString *section;
+     _profile(Package$visible$section)
+         section = [self section];
+     _end
  
      _profile(Package$visible$isSectionVisible)
          if (section != nil && !isSectionVisible(section))
      return source_ == (Source *) [NSNull null] ? nil : source_;
  }
  
- - (NSString *) role {
-     return role_;
- }
  - (BOOL) matches:(NSString *)text {
      if (text == nil)
          return NO;
  }
  
  - (bool) hasSupportingRole {
-     if (role_ == nil)
+     if (role_ == 0)
          return true;
-     if ([role_ isEqualToString:@"enduser"])
+     if (role_ == 1)
          return true;
      if ([Role_ isEqualToString:@"User"])
          return false;
-     if ([role_ isEqualToString:@"hacker"])
+     if (role_ == 2)
          return true;
      if ([Role_ isEqualToString:@"Hacker"])
          return false;
-     if ([role_ isEqualToString:@"developer"])
+     if (role_ == 3)
          return true;
      if ([Role_ isEqualToString:@"Developer"])
          return false;
  }
  
  - (bool) isInstalledAndUnfiltered:(NSNumber *)number {
-     return ![self uninstalled] && (![number boolValue] && ![role_ isEqualToString:@"cydia"] || [self unfiltered]);
+     return ![self uninstalled] && (![number boolValue] && role_ != 7 || [self unfiltered]);
  }
  
  - (bool) isVisibleInSection:(NSString *)name {
@@@ -3032,6 -3041,8 +3040,8 @@@ static NSString *Warning_
  - (void) dealloc {
      // XXX: actually implement this thing
      _assert(false);
+     if (deadSources_)
+           CFRelease(deadSources_);
      [self releasePackages];
      apr_pool_destroy(pool_);
      NSRecycleZone(zone_);
              capacity += 1024;
  
          packages_ = CFArrayCreateMutable(kCFAllocatorDefault, capacity, NULL);
+         deadSources_ = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
  
          int fds[2];
  
      NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
      for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
          [sources addObject:i->second];
+     [sources addObjectsFromArray:(NSArray *)deadSources_];
      return sources;
  }
  
      ++era_;
  
      [self releasePackages];
      sources_.clear();
+     CFArrayRemoveAllValues(deadSources_);
  
      _error->Discard();
  
      }
  
      for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
+         bool found = false;
          std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
          for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
              // XXX: this could be more intelligent
              if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
                  pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
-                 if (!cached.end())
+                 if (!cached.end()) {
                      sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease];
+                     found = true;
+                 }
              }
+         if (!found)
+             CFArrayAppendValue(deadSources_, [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease]);
      }
  
      {
      return i == sources_.end() ? nil : i->second;
  }
  
+ - (NSString *) mappedSectionForPointer:(const char *)section {
+     _H<NSString> *mapped;
+     _profile(Database$mappedSectionForPointer$Cache)
+         mapped = &sections_[section];
+     _end
+     if (*mapped == NULL) {
+         size_t length(strlen(section));
+         char spaced[length + 1];
+         _profile(Database$mappedSectionForPointer$Replace)
+             for (size_t index(0); index != length; ++index)
+                 spaced[index] = section[index] == '_' ? ' ' : section[index];
+             spaced[length] = '\0';
+         _end
+         NSString *string;
+         _profile(Database$mappedSectionForPointer$stringWithUTF8String)
+             string = [NSString stringWithUTF8String:spaced];
+         _end
+         _profile(Database$mappedSectionForPointer$Map)
+             string = [SectionMap_ objectForKey:string] ?: string;
+         _end
+         *mapped = string;
+     } return *mapped;
+ }
  @end
  /* }}} */
  
@@@ -3996,43 -4047,6 +4046,43 @@@ bool DepSubstrate(const pkgCache::VerIt
  
  @end
  /* }}} */
 +@interface CYEmulatedLoadingController : UIViewController {
 +    CYLoadingIndicator *indicator_;
 +    UITabBar *tabbar_;
 +    UINavigationBar *navbar_;
 +}
 +@end
 +
 +@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;
 +}
 +
 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
 +    return (IsWildcat_ || orientation == UIInterfaceOrientationPortrait);
 +}
 +
 +@end
  
  /* Cydia Browser Controller {{{ */
  @interface CYBrowserController : BrowserController {
  }
  
  - (void) drawContentRect:(CGRect)rect {
-     bool highlighted(highlighted_);
+     bool highlighted(highlighted_ && !editing_);
  
      [icon_ drawInRect:CGRectMake(8, 7, 32, 32)];
  
  @end
  /* }}} */
  /* Package Controller {{{ */
 -@interface PackageController : CYBrowserController <
 +@interface CYPackageController : CYBrowserController <
      UIActionSheetDelegate
  > {
      _transient Database *database_;
  
  @end
  
 -@implementation PackageController
 +@implementation CYPackageController
  
  - (void) dealloc {
      if (package_ != nil)
  }
  
  - (void) didSelectPackage:(Package *)package {
 -    PackageController *view([delegate_ packageController]);
 +    CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]);
      [view setPackage:package];
      [view setDelegate:delegate_];
      [[self navigationController] pushViewController:view animated:YES];
  @end
  /* }}} */
  /* Source Table {{{ */
 -@interface SourceController : CYViewController <
 +@interface CYSourcesController : CYViewController <
      UITableViewDataSource,
      UITableViewDelegate
  > {
  
  @end
  
 -@implementation SourceController
 +@implementation CYSourcesController
  
  - (void) _releaseConnection:(NSURLConnection *)connection {
      if (connection != nil) {
      [list_ reloadData];
  }
  
 -- (void) addButtonClicked {
 -    /*[book_ pushPage:[[[AddSourceController alloc]
 +- (void) showAddSourcePrompt {
 +    /*[book_ pushPage:[[[AddCYSourcesController alloc]
          initWithBook:book_
          database:database_
      ] autorelease]];*/
      [alert show];
  }
  
 +- (void) addButtonClicked {
 +    [self showAddSourcePrompt];
 +}
 +
  - (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated {
      [[self navigationItem] setLeftBarButtonItem:(editing ? [[[UIBarButtonItem alloc]
          initWithTitle:UCLocalize("ADD")
  /* }}} */
  
  /* Installed Controller {{{ */
 -@interface InstalledController : FilteredPackageController {
 +@interface CYInstalledController : FilteredPackageController {
      BOOL expert_;
  }
  
  
  @end
  
 -@implementation InstalledController
 +@implementation CYInstalledController
  
  - (void) dealloc {
      [super dealloc];
      [packages_ setDelegate:delegate];
  }
  
 +@end
 +/* }}} */
 +/* Section Controller {{{ */
 +@interface CYSectionController : FilteredPackageController {
 +}
 +
 +- (id) initWithDatabase:(Database *)database section:(NSString *)section;
 +
 +@end
 +
 +@implementation CYSectionController
 +
 +- (void) dealloc {
 +    [super dealloc];
 +}
 +
 +- (id) initWithDatabase:(Database *)database section:(NSString *)name {
 +    NSString *title;
 +
 +    if (name == nil) {
 +        title = UCLocalize("ALL_PACKAGES");
 +    } else if (![name isEqual:@""]) {
 +        title = [[NSBundle mainBundle] localizedStringForKey:Simplify(name) value:nil table:@"Sections"];
 +    } else {
 +        title = UCLocalize("NO_SECTION");
 +    }
 +
 +    if ((self = [super initWithDatabase:database title:title filter:@selector(isVisibleInSection:) with:name]) != nil) {
 +    } return self;
 +}
 +
 +- (void) reloadData {
 +    [packages_ reloadData];
 +}
 +
 +- (void) setDelegate:(id)delegate {
 +    [super setDelegate:delegate];
 +    [packages_ setDelegate:delegate];
 +}
 +
  @end
  /* }}} */
  
  /* Home Controller {{{ */
 -@interface HomeController : CYBrowserController {
 +@interface CYHomeController : CYBrowserController {
  }
  
  @end
  
 -@implementation HomeController
 +@implementation CYHomeController
  
  + (BOOL)shouldHideNavigationBar {
      return NO;
  
  - (id) init {
      if ((self = [super init]) != nil) {
 +        [self loadURL:[NSURL URLWithString:CydiaURL(@"")]];
 +
          [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
              initWithTitle:UCLocalize("ABOUT")
              style:UIBarButtonItemStylePlain
  @end
  /* }}} */
  /* Manage Controller {{{ */
 -@interface ManageController : CYBrowserController {
 +@interface CYManageController : CYBrowserController {
  }
  
  - (void) queueStatusDidChange;
  @end
  
 -@implementation ManageController
 +@implementation CYManageController
  
  - (id) init {
      if ((self = [super init]) != nil) {
          [[self navigationItem] setTitle:UCLocalize("MANAGE")];
  
 +        [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]];
 +
          [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
              initWithTitle:UCLocalize("SETTINGS")
              style:UIBarButtonItemStylePlain
  
  @implementation CYTabBarController
  
 -/* XXX: some logic should probably go here related to
 -freeing the view controllers on tab change */
 -
  - (void) reloadData {
      size_t count([[self viewControllers] count]);
      for (size_t i(0); i != count; ++i) {
          return;
  
      Section *section = [self sectionAtIndexPath:indexPath];
 -    NSString *name = [section name];
 -    NSString *title;
  
 -    if ([indexPath row] == 0) {
 -        section = nil;
 -        name = nil;
 -        title = UCLocalize("ALL_PACKAGES");
 -    } else {
 -        if (name != nil) {
 -            name = [NSString stringWithString:name];
 -            title = [[NSBundle mainBundle] localizedStringForKey:Simplify(name) value:nil table:@"Sections"];
 -        } else {
 -            name = @"";
 -            title = UCLocalize("NO_SECTION");
 -        }
 -    }
 -
 -    FilteredPackageController *table = [[[FilteredPackageController alloc]
 +    CYSectionController *controller = [[[CYSectionController alloc]
          initWithDatabase:database_
 -        title:title
 -        filter:@selector(isVisibleInSection:)
 -        with:name
 +        section:[section name]
      ] autorelease];
 +    [controller setDelegate:delegate_];
  
 -    [table setDelegate:delegate_];
 -
 -    [[self navigationController] pushViewController:table animated:YES];
 +    [[self navigationController] pushViewController:controller animated:YES];
  }
  
 -- (NSString *) title { return UCLocalize("SECTIONS"); }
 -
  - (id) initWithDatabase:(Database *)database {
      if ((self = [super init]) != nil) {
          database_ = database;
  @end
  /* }}} */
  /* Changes Controller {{{ */
 -@interface ChangesController : CYViewController <
 +@interface CYChangesController : CYViewController <
      UITableViewDataSource,
      UITableViewDelegate
  > {
  
  @end
  
 -@implementation ChangesController
 +@implementation CYChangesController
  
  - (void) dealloc {
      [list_ setDelegate:nil];
      if ([database_ era] != era_)
          return nil;
  
-     Section *section([sections_ objectAtIndex:[path section]]);
+     NSUInteger sectionIndex([path section]);
+     if (sectionIndex >= [sections_ count])
+         return nil;
+     Section *section([sections_ objectAtIndex:sectionIndex]);
      NSInteger row([path row]);
      return [[[self packageAtIndex:([section row] + row)] retain] autorelease];
  } }
  
  - (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path {
      Package *package([self packageAtIndexPath:path]);
 -    PackageController *view([delegate_ packageController]);
 +    CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]);
      [view setDelegate:delegate_];
      [view setPackage:package];
      [[self navigationController] pushViewController:view animated:YES];
  }
  
  - (void) _reloadPackages:(NSArray *)packages {
-     _trace();
-     for (Package *package in packages)
-         if ([package upgradableAndEssential:YES] || [package visible])
-             CFArrayAppendValue(packages_, package);
+     CFRelease(packages_);
+     packages_ = CFArrayCreateMutable(kCFAllocatorDefault, [packages count], NULL);
  
      _trace();
-     [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
+     _profile(ChangesController$_reloadPackages$Filter)
+         for (Package *package in packages)
+             if ([package upgradableAndEssential:YES] || [package visible])
+                 CFArrayAppendValue(packages_, package);
+     _end
+     _trace();
+     _profile(ChangesController$_reloadPackages$radixSort)
+         [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
+     _end
      _trace();
  }
  
  - (void) reloadData {
+ @synchronized (database_) {
      era_ = [database_ era];
      NSArray *packages = [database_ packages];
  
-     CFArrayRemoveAllValues(packages_);
      [sections_ removeAllObjects];
  
  #if 1
                  name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) [NSDate dateWithTimeIntervalSince1970:seen]);
                  [name autorelease];
  
 -                _profile(ChangesController$reloadData$Allocate)
 +                _profile(CYChangesController$reloadData$Allocate)
                      name = [NSString stringWithFormat:UCLocalize("NEW_AT"), name];
                      section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease];
                      [sections_ addObject:section];
              target:self
              action:@selector(refreshButtonClicked)
          ] autorelease]];
- }
+     PrintTimes();
+ } }
  
  @end
  /* }}} */
  /* Search Controller {{{ */
 -@interface SearchController : FilteredPackageController <
 +@interface CYSearchController : FilteredPackageController <
      UISearchBarDelegate
  > {
      UISearchBar *search_;
  }
  
 +- (void) setSearchTerm:(NSString *)searchTerm;
  - (id) initWithDatabase:(Database *)database;
  - (void) reloadData;
  
  @end
  
 -@implementation SearchController
 +@implementation CYSearchController
  
  - (void) dealloc {
      [search_ release];
      [super dealloc];
  }
  
 +- (void) setSearchTerm:(NSString *)searchTerm {
 +    [search_ setText:searchTerm];
 +}
 +
  - (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
      [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
      [search_ resignFirstResponder];
  }
  
  - (void) reloadData {
 -    _profile(SearchController$reloadData)
 +    _profile(CYSearchController$reloadData)
          [packages_ reloadData];
      _end
      PrintTimes();
      return 2;
  }
  
 +- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 +    return UCLocalize("CHANGE_PACKAGE_SETTINGS");
 +}
 +
  - (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
      return UCLocalize("SHOW_ALL_CHANGES_EX");
  }
          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];
  
          subscribedCell_ = [[UITableViewCell alloc] init];
          [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
          [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")];
          [ignoredCell_ setAccessoryView:ignoredSwitch_];
          [ignoredCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
+         // FIXME: Ignored state is not saved.
+         [ignoredCell_ setUserInteractionEnabled:NO];
  
          [table_ setDataSource:self];
          [table_ setDelegate:self];
  /* }}} */
  
  typedef enum {
 -    kCydiaTag = 0,
 -    kSectionsTag = 1,
 -    kChangesTag = 2,
 -    kManageTag = 3,
 -    kInstalledTag = 4,
 -    kSourcesTag = 5,
 -    kSearchTag = 6
 +    kCydiaTag,
 +    kSectionsTag,
 +    kChangesTag,
 +    kManageTag,
 +    kInstalledTag,
 +    kSourcesTag,
 +    kSearchTag
  } CYTabTag;
  
  @interface Cydia : UIApplication <
      Database *database_;
  
      NSURL *starturl_;
 -    int tag_;
  
      unsigned locked_;
      unsigned activity_;
  
 -    CYSectionsController *sections_;
 -    ChangesController *changes_;
 -    ManageController *manage_;
 -    SearchController *search_;
 -    SourceController *sources_;
 -    InstalledController *installed_;
      id queueDelegate_;
  
      CYStashController *stash_;
      bool loaded_;
  }
  
 -- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class;
  - (void) setPage:(CYViewController *)page;
  - (void) loadData;
  
  
  @end
  
 -static _finline void _setHomePage(Cydia *self) {
 -    [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeController class]]];
 -}
 -
  @implementation Cydia
  
  - (void) beginUpdate {
  - (void) _updateData {
      [self _saveConfig];
  
 -    NSMutableSet *tabs([[[NSMutableSet alloc] initWithCapacity:10] autorelease]);
 -
 -    [tabs addObject:[tabbar_ selectedViewController]];
 -
 -    if (sections_ != nil)
 -        [tabs addObject:sections_];
 -    if (changes_ != nil)
 -        [tabs addObject:changes_];
 -    if (manage_ != nil)
 -        [tabs addObject:manage_];
 -    if (search_ != nil)
 -        [tabs addObject:search_];
 -    if (sources_ != nil)
 -        [tabs addObject:sources_];
 -    if (installed_ != nil)
 -        [tabs addObject:installed_];
 -
 -    for (CYNavigationController *tab in tabs)
 -        [tab reloadData];
 +    [tabbar_ reloadData];
  
      [queueDelegate_ queueStatusDidChange];
      [[[self queueBadgeController] tabBarItem] setBadgeValue:(Queuing_ ? UCLocalize("Q_D") : nil)];
  
      CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController];
      [navController setViewControllers:[NSArray arrayWithObject:page]];
 -    for (CYNavigationController *page in [tabbar_ viewControllers])
 -        if (page != navController)
 -            [page setViewControllers:nil];
 -}
 -
 -- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class {
 -    CYBrowserController *browser = [[[_class alloc] init] autorelease];
 -    [browser loadURL:url];
 -    return browser;
 -}
 -
 -- (CYSectionsController *) sectionsController {
 -    if (sections_ == nil)
 -        sections_ = [[CYSectionsController alloc] initWithDatabase:database_];
 -    return sections_;
 -}
 -
 -- (ChangesController *) changesController {
 -    if (changes_ == nil)
 -        changes_ = [[ChangesController alloc] initWithDatabase:database_ delegate:self];
 -    return changes_;
 -}
 -
 -- (ManageController *) manageController {
 -    if (manage_ == nil) {
 -        manage_ = (ManageController *) [[self
 -            _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]
 -            withClass:[ManageController class]
 -        ] retain];
 -        if (!IsWildcat_)
 -            queueDelegate_ = manage_;
 -    }
 -    return manage_;
 -}
 -
 -- (SearchController *) searchController {
 -    if (search_ == nil)
 -        search_ = [[SearchController alloc] initWithDatabase:database_];
 -    return search_;
 -}
 -
 -- (SourceController *) sourcesController {
 -    if (sources_ == nil)
 -        sources_ = [[SourceController alloc] initWithDatabase:database_];
 -    return sources_;
 -}
 -
 -- (InstalledController *) installedController {
 -    if (installed_ == nil) {
 -        installed_ = [[InstalledController alloc] initWithDatabase:database_];
 -        if (IsWildcat_)
 -            queueDelegate_ = installed_;
 -    }
 -    return installed_;
 -}
 -
 -- (void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
 -    int tag = [[viewController tabBarItem] tag];
 -    if (tag == tag_) {
 -        [(CYNavigationController *)[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES];
 -        return;
 -    } else if (tag_ == 1) {
 -        [[self sectionsController] resetView];
 -    }
 -
 -    switch (tag) {
 -        case kCydiaTag: _setHomePage(self); break;
 -
 -        case kSectionsTag: [self setPage:[self sectionsController]]; break;
 -        case kChangesTag: [self setPage:[self changesController]]; break;
 -        case kManageTag: [self setPage:[self manageController]]; break;
 -        case kInstalledTag: [self setPage:[self installedController]]; break;
 -        case kSourcesTag: [self setPage:[self sourcesController]]; break;
 -        case kSearchTag: [self setPage:[self searchController]]; break;
 -
 -        _nodefault
 -    }
 -
 -    tag_ = tag;
 +    NSLog(@"page: %@ nav: %@", page, navController);
  }
  
  - (void) showSettings {
          [self setNetworkActivityIndicatorVisible:NO];
  }
  
 -- (void) setPackageController:(PackageController *)view {
 +- (void) setPackageController:(CYPackageController *)view {
      WebThreadLock();
      [view setPackage:nil];
      WebThreadUnlock();
  }
  
 -- (PackageController *) _packageController {
 -    return [[[PackageController alloc] initWithDatabase:database_] autorelease];
 -}
 -
 -- (PackageController *) packageController {
 -    return [self _packageController];
 -}
 -
  // Returns the navigation controller for the queuing badge.
  - (id) queueBadgeController {
      int index = [self indexOfTabWithTag:kManageTag];
  
  - (CYViewController *) pageForPackage:(NSString *)name {
      if (Package *package = [database_ packageWithName:name]) {
 -        PackageController *view([self packageController]);
 +        CYPackageController *view = [[[CYPackageController alloc] initWithDatabase:database_] autorelease];
          [view setPackage:package];
          return view;
      } else {
          NSURL *url([NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"unknown" ofType:@"html"]]);
          url = [NSURL URLWithString:[[url absoluteString] stringByAppendingString:[NSString stringWithFormat:@"?%@", name]]];
 -        return [self _pageForURL:url withClass:[CYBrowserController class]];
 +        CYBrowserController *browser = [[[CYBrowserController alloc] init] autorelease];
 +        [browser loadURL:url];
 +        return browser;
      }
  }
  
 -- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
 -    if (tag != NULL)
 -        *tag = -1;
 -
 -    NSString *href([url absoluteString]);
 -    if ([href hasPrefix:@"apptapp://package/"])
 -        return [self pageForPackage:[href substringFromIndex:18]];
 -
 +- (CYViewController *) pageForURL:(NSURL *)url {
      NSString *scheme([[url scheme] lowercaseString]);
 -    if (![scheme isEqualToString:@"cydia"])
 +    if ([[url absoluteString] length] <= [scheme length] + 3)
          return nil;
 -    NSString *path([url absoluteString]);
 -    if ([path length] < 8)
 +    NSString *path([[url absoluteString] substringFromIndex:[scheme length] + 3]);
 +    NSArray *components([path pathComponents]);
 +
 +    if ([scheme isEqualToString:@"apptapp"] && [components count] && [[components objectAtIndex:0] isEqualToString:@"package"])
 +        return [self pageForPackage:[components objectAtIndex:1]];
 +
 +    if ([components count] < 1 || ![scheme isEqualToString:@"cydia"])
          return nil;
 -    path = [path substringFromIndex:8];
 -    if (![path hasPrefix:@"/"])
 -        path = [@"/" stringByAppendingString:path];
 -
 -    if ([path isEqualToString:@"/storage"])
 -        return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[CYBrowserController class]];
 -    /*else if ([path isEqualToString:@"/add-source"])
 -        return [[[AddSourceController alloc] initWithDatabase:database_] autorelease];*/
 -    else if ([path isEqualToString:@"/sources"])
 -        return [[[SourceController alloc] initWithDatabase:database_] autorelease];
 -    else if ([path isEqualToString:@"/packages"])
 -        return [[[InstalledController alloc] initWithDatabase:database_] autorelease];
 -    else if ([path hasPrefix:@"/url/"])
 -        return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[CYBrowserController class]];
 -    else if ([path hasPrefix:@"/launch/"])
 -        [self launchApplicationWithIdentifier:[path substringFromIndex:8] suspended:NO];
 -    else if ([path hasPrefix:@"/package-settings/"])
 -        return [[[CYPackageSettingsController alloc] initWithDatabase:database_ package:[path substringFromIndex:18]] autorelease];
 -    else if ([path hasPrefix:@"/package-signature/"])
 -        return [[[SignatureController alloc] initWithDatabase:database_ package:[path substringFromIndex:19]] autorelease];
 -    else if ([path hasPrefix:@"/package/"])
 -        return [self pageForPackage:[path substringFromIndex:9]];
 -    else if ([path hasPrefix:@"/files/"]) {
 -        NSString *name = [path substringFromIndex:7];
 -
 -        if (Package *package = [database_ packageWithName:name]) {
 -            FileTable *files = [[[FileTable alloc] initWithDatabase:database_] autorelease];
 -            [files setPackage:package];
 -            return files;
 +
 +    NSString *base([components objectAtIndex:0]);
 +
 +    if ([components count] == 1) {
 +        if ([base isEqualToString:@"storage"]) {
 +            CYBrowserController *browser = [[[CYBrowserController alloc] init] autorelease];
 +            [browser loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]]];
 +            return browser;
 +        }
 +
 +        if ([base isEqualToString:@"sources"]) {
 +            CYSourcesController *source = [[[CYSourcesController alloc] initWithDatabase:database_] autorelease];
 +            return source;
 +        }
 +
 +        if ([base isEqualToString:@"home"]) {
 +            CYHomeController *home = [[[CYHomeController alloc] init] autorelease];
 +            return home;
 +        }
 +
 +        if ([base isEqualToString:@"sections"]) {
 +            CYSectionsController *sections = [[[CYSectionsController alloc] initWithDatabase:database_] autorelease];
 +            return sections;
 +        }
 +
 +        if ([base isEqualToString:@"search"]) {
 +            CYSearchController *search = [[[CYSearchController alloc] initWithDatabase:database_] autorelease];
 +            return search;
 +        }
 +
 +        if ([base isEqualToString:@"changes"]) {
 +            CYChangesController *changes = [[[CYChangesController alloc] initWithDatabase:database_ delegate:self] autorelease];
 +            return changes;
 +        }
 +
 +        if ([base isEqualToString:@"installed"]) {
 +            CYInstalledController *installed = [[[CYInstalledController alloc] initWithDatabase:database_] autorelease];
 +            return installed;
 +        }
 +    } else if ([components count] == 2) {
 +        NSString *argument = [components objectAtIndex:1];
 +
 +        if ([base isEqualToString:@"package"]) {
 +            CYViewController *package = [self pageForPackage:argument];
 +            return package;
 +        }
 +
 +        if ([base isEqualToString:@"search"]) {
 +            CYSearchController *search = [[[CYSearchController alloc] initWithDatabase:database_] autorelease];
 +            [search setSearchTerm:argument];
 +            return search;
 +        }
 +
 +        if ([base isEqualToString:@"sections"]) {
 +            if ([argument isEqualToString:@"all"])
 +                argument = nil;
 +            CYSectionController *section = [[[CYSectionController alloc] initWithDatabase:database_ section:argument] autorelease];
 +            [section setDelegate:self];
 +            return section;
 +        }
 +
 +        if ([base isEqualToString:@"sources"]) {
 +            if ([argument isEqualToString:@"add"]) {
 +                CYSourcesController *source = [[[CYSourcesController alloc] initWithDatabase:database_] autorelease];
 +                [source showAddSourcePrompt];
 +                return source;
 +            } else {
 +                // XXX: Create page of the source specfified.
 +            }
 +        }
 +
 +        if ([base isEqualToString:@"url"]) {
 +            CYBrowserController *browser = [[[CYBrowserController alloc] init] autorelease];
 +            [browser loadURL:[NSURL URLWithString:argument]];
 +            return browser;
 +        }
 +
 +        if ([base isEqualToString:@"launch"]) {
 +            [self launchApplicationWithIdentifier:argument suspended:NO];
 +        }
 +    } else if ([components count] == 3) {
 +        NSString *arg1 = [components objectAtIndex:1];
 +        NSString *arg2 = [components objectAtIndex:2];
 +
 +        if ([base isEqualToString:@"package"]) {
 +            if ([arg2 isEqualToString:@"settings"]) {
 +                return [[[CYPackageSettingsController alloc] initWithDatabase:database_ package:arg1] autorelease];
 +            } else if ([arg2 isEqualToString:@"signature"]) {
 +                return [[[SignatureController alloc] initWithDatabase:database_ package:arg1] autorelease];
 +            } else if ([arg2 isEqualToString:@"files"]) {
 +                if (Package *package = [database_ packageWithName:arg1]) {
 +                    FileTable *files = [[[FileTable alloc] initWithDatabase:database_] autorelease];
 +                    [files setPackage:package];
 +                    return files;
 +                }
 +            }
          }
      }
  
  }
  
  - (BOOL) openCydiaURL:(NSURL *)url {
 -    CYViewController *page = nil;
 -    int tag = 0;
 +    CYViewController *page([self pageForURL:url]);
  
 -    if ((page = [self pageForURL:url hasTag:&tag])) {
 +    if (page != nil)
          [self setPage:page];
 -        tag_ = tag;
 -        [tabbar_ setSelectedViewController:(tag_ == -1 ? nil : [[tabbar_ viewControllers] objectAtIndex:tag_])];
 -    }
  
 -    return !!page;
 +    return page != nil;
  }
  
  - (void) applicationOpenURL:(NSURL *)url {
      }
  }
  
 -- (void) setupTabBarController {
 +- (void) setupViewControllers {
      tabbar_ = [[CYTabBarController alloc] initWithDatabase:database_];
      [tabbar_ setDelegate:self];
  
          [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:kSearchTag] autorelease],
      nil]);
  
 +    NSMutableArray *pages([NSMutableArray arrayWithObjects:
 +        [[[CYHomeController alloc] init] autorelease],
 +        [[[CYSectionsController alloc] initWithDatabase:database_] autorelease],
 +        [[[CYChangesController alloc] initWithDatabase:database_ delegate:self] autorelease],
 +        [[[CYSearchController alloc] initWithDatabase:database_] autorelease],
 +    nil]);
 +
      if (IsWildcat_) {
          [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source.png"] tag:kSourcesTag] autorelease] atIndex:3];
          [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:kInstalledTag] autorelease] atIndex:3];
 +        [pages insertObject:[[[CYSourcesController alloc] initWithDatabase:database_] autorelease] atIndex:3];
 +        [pages insertObject:[[[CYInstalledController alloc] initWithDatabase:database_] autorelease] atIndex:3];
 +        queueDelegate_ = [pages objectAtIndex:3];
      } else {
          [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:kManageTag] autorelease] atIndex:3];
 +        [pages insertObject:[[[CYManageController alloc] init] autorelease] atIndex:3];
 +        queueDelegate_ = [pages objectAtIndex:3];
      }
  
      NSMutableArray *controllers([NSMutableArray array]);
  
 -    for (UITabBarItem *item in items) {
 +    for (unsigned int i = 0; i < [pages count]; i++) {
 +        UITabBarItem *item = [items objectAtIndex:i];
 +        CYViewController *page = [pages objectAtIndex:i];
 +        [page setDelegate:self];
 +
          CYNavigationController *controller([[[CYNavigationController alloc] initWithDatabase:database_] autorelease]);
 +        [controller setViewControllers:[NSArray arrayWithObject:page]];
          [controller setTabBarItem:item];
          [controllers addObject:controller];
      }
  
      [tabbar_ setViewControllers:controllers];
 +    [tabbar_ setUpdateDelegate:self];
 +    [window_ addSubview:[tabbar_ view]];
  }
  
 -- (void)showFakeTabBarInView:(UIView *)view {
 -    static UITabBar *fake = [[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 49.0f)];
 +- (void)showEmulatedLoadingControllerInView:(UIView *)view {
 +    static CYEmulatedLoadingController *fake = [[CYEmulatedLoadingController alloc] init];
      if (view != nil) {
 -        CGRect frame = [fake frame];
 -        frame.origin.y = [view frame].size.height - frame.size.height;
 -        frame.size.width = [view frame].size.width;
 -        [fake setFrame:frame];
 -        [fake setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
 -        [view addSubview:fake];
 +        [view addSubview:[fake view]];
      } else {
 -        [fake removeFromSuperview];
 +        [[fake view] removeFromSuperview];
      }
  }
  
  _trace();
      CydiaApp = self;
  
+     if ([self respondsToSelector:@selector(setApplicationSupportsShakeToEdit:)])
+         [self setApplicationSupportsShakeToEdit:NO];
      [NSURLCache setSharedURLCache:[[[SDURLCache alloc]
          initWithMemoryCapacity:524288
          diskCapacity:10485760
      Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
      Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
  
 -    tag_ = 0;
 -
      essential_ = [[NSMutableArray alloc] initWithCapacity:4];
      broken_ = [[NSMutableArray alloc] initWithCapacity:4];
  
  
      database_ = [Database sharedInstance];
  
 -    [self setupTabBarController];
 -    [tabbar_ setUpdateDelegate:self];
 -    [window_ addSubview:[tabbar_ view]];
 -
 -    // Show pinstripes while loading data.
 -    [[tabbar_ view] setBackgroundColor:[UIColor pinStripeColor]];
 -    [self showFakeTabBarInView:[tabbar_ tabBar]];
 +    [self showEmulatedLoadingControllerInView:window_];
  
      [self performSelector:@selector(loadData) withObject:nil afterDelay:0];
  _trace();
@@@ -9011,23 -9052,33 +9076,23 @@@ _trace()
          return;
      }
  
 -    CGRect fixframe = [[tabbar_ view] frame];
 -    if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
 -        fixframe.size = CGSizeMake(fixframe.size.height, fixframe.size.width);
 -    CYLoadingIndicator *loading = [[[CYLoadingIndicator alloc] initWithFrame:fixframe] autorelease];
 -    [loading setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
 -    [[tabbar_ view] addSubview:loading];
      [window_ setUserInteractionEnabled:NO];
 -
      [self reloadData];
      PrintTimes();
 -
 -    // Show the initial page
 -    if (starturl_ == nil || ![self openCydiaURL:starturl_]) {
 -        [tabbar_ setSelectedIndex:0];
 -        _setHomePage(self);
 -    }
 -
 -    [self showFakeTabBarInView:nil];
 -
 -    [starturl_ release];
 -    starturl_ = nil;
 -
      [window_ setUserInteractionEnabled:YES];
  
 +    [self setupViewControllers];
 +    [tabbar_ setSelectedIndex:0];
 +    [self showEmulatedLoadingControllerInView:nil];
      // XXX: does this actually slow anything down?
      [[tabbar_ view] setBackgroundColor:[UIColor clearColor]];
 -    [loading removeFromSuperview];
 +
 +    // Show the initial page
 +    if (starturl_ != nil) {
 +        [self openCydiaURL:starturl_];
 +        [starturl_ release];
 +        starturl_ = nil;
 +    }
  }
  
  - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item {
index 921e6aade8e97aab7b6800b0f19183e7c7db01bd,1017496e4e15a2f6c35b276633f7ef67cad00985..2abc02ecc607b3c968bbf2c656260fb490b10b70
@@@ -638,7 -638,7 +638,7 @@@ static void $UIWebViewWebViewDelegate$w
      if ([scheme isEqualToString:@"mailto"])
          [self _openMailToURL:url];
  
 -    CYViewController *page([delegate_ pageForURL:url hasTag:NULL]);
 +    CYViewController *page([delegate_ pageForURL:url]);
  
      if (page == nil) {
          BrowserController *browser([[[class_ alloc] init] autorelease]);
  
          [[self navigationController] pushViewController:page animated:YES];
      } else {
 -        UCNavigationController *navigation([[[UCNavigationController alloc] init] autorelease]);
 +        UCNavigationController *navigation([[[UCNavigationController alloc] initWithRootViewController:page] autorelease]);
  
          [navigation setHook:indirect_];
          [navigation setDelegate:delegate_];
  
 -        [navigation setViewControllers:[NSArray arrayWithObject:page]];
 -
          [[page navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
              initWithTitle:UCLocalize("CLOSE")
              style:UIBarButtonItemStylePlain
  
          [alert dismissWithClickedButtonIndex:-1 animated:YES];
      } else if ([context isEqualToString:@"submit"]) {
-         switch (button) {
-             case 1:
-             break;
-             case 2:
-                 if (request_ != nil) {
-                     WebThreadLock();
-                     [webview_ loadRequest:request_];
-                     WebThreadUnlock();
-                 }
-             break;
-             _nodefault
+         if (button == [alert cancelButtonIndex]) {
+         } else if (button == [alert firstOtherButtonIndex]) {
+             if (request_ != nil) {
+                 WebThreadLock();
+                 [webview_ loadRequest:request_];
+                 WebThreadUnlock();
+             }
          }
  
          [alert dismissWithClickedButtonIndex:-1 animated:YES];