- (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
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 {{{ */
};
@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;
- (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 {
- (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 = §ions_[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
/* }}} */
@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();
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 {