X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/92c79e8d525db2e8a768790e1256ac0f6ab80c1e..1b9ba5964135b35d5fc2357d05e1754f0b97d479:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index b955c08a..b7050fc6 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -1355,6 +1355,8 @@ typedef std::map< unsigned long, _H > SourceMap; int cydiafd_; int statusfd_; FILE *input_; + + std::map > sections_; } + (Database *) sharedInstance; @@ -1388,6 +1390,9 @@ typedef std::map< unsigned long, _H > SourceMap; - (void) setDelegate:(id)delegate; - (Source *) getSource:(pkgCache::PkgFileIterator)file; + +- (NSString *) mappedSectionForPointer:(const char *)pointer; + @end /* }}} */ /* Delegate Helpers {{{ */ @@ -1825,7 +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; @@ -1844,7 +1850,7 @@ struct ParsedPackage { CYString latest_; CYString installed_; - CYString section_; + const char *section_; _transient NSString *section$_; Source *source_; @@ -1853,7 +1859,6 @@ struct ParsedPackage { ParsedPackage *parsed_; NSMutableArray *tags_; - NSString *role_; } - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database; @@ -1915,7 +1920,6 @@ struct ParsedPackage { - (NSArray *) applications; - (Source *) source; -- (NSString *) role; - (BOOL) matches:(NSString *)text; @@ -2076,15 +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]; } @@ -2218,8 +2217,18 @@ struct PackageNameOrdering : 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) @@ -2267,7 +2276,7 @@ struct PackageNameOrdering : _end _profile(Package$initWithVersion$Section) - section_.set(NULL, iterator.Section()); + section_ = iterator.Section(); _end _profile(Package$initWithVersion$Flags) @@ -2315,13 +2324,11 @@ struct PackageNameOrdering : - (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$_; } @@ -2471,12 +2478,12 @@ struct PackageNameOrdering : - (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 @@ -2487,7 +2494,11 @@ struct PackageNameOrdering : 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)) @@ -2710,10 +2721,6 @@ struct PackageNameOrdering : return source_ == (Source *) [NSNull null] ? nil : source_; } -- (NSString *) role { - return role_; -} - - (BOOL) matches:(NSString *)text { if (text == nil) return NO; @@ -2736,17 +2743,17 @@ struct PackageNameOrdering : } - (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; @@ -2868,7 +2875,7 @@ struct PackageNameOrdering : } - (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 { @@ -3677,6 +3684,37 @@ static NSString *Warning_; return i == sources_.end() ? nil : i->second; } +- (NSString *) mappedSectionForPointer:(const char *)section { + _H *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 /* }}} */ @@ -3933,6 +3971,71 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ +/* @ Loading... Indicator {{{ */ +@interface CYLoadingIndicator : UIView { + UIActivityIndicatorView *spinner_; + UILabel *label_; + UIView *container_; +} + +@property (readonly, nonatomic) UILabel *label; +@property (readonly, nonatomic) UIActivityIndicatorView *activityIndicatorView; + +@end + +@implementation CYLoadingIndicator + +- (id)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + container_ = [[[UIView alloc] init] autorelease]; + [container_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin]; + + spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; + [spinner_ startAnimating]; + [container_ addSubview:spinner_]; + + label_ = [[[UILabel alloc] init] autorelease]; + [label_ setFont:[UIFont boldSystemFontOfSize:15.0f]]; + [label_ setBackgroundColor:[UIColor clearColor]]; + [label_ setTextColor:[UIColor blackColor]]; + [label_ setShadowColor:[UIColor whiteColor]]; + [label_ setShadowOffset:CGSizeMake(0, 1)]; + [label_ setText:[NSString stringWithFormat:Elision_, UCLocalize("LOADING"), nil]]; + [container_ addSubview:label_]; + + CGSize viewsize = frame.size; + CGSize spinnersize = [spinner_ bounds].size; + CGSize textsize = [[label_ text] sizeWithFont:[label_ font]]; + float bothwidth = spinnersize.width + textsize.width + 5.0f; + + CGRect containrect = { + CGPointMake(floorf((viewsize.width / 2) - (bothwidth / 2)), floorf((viewsize.height / 2) - (spinnersize.height / 2))), + CGSizeMake(bothwidth, spinnersize.height) + }; + CGRect textrect = { + CGPointMake(spinnersize.width + 5.0f, floorf((spinnersize.height / 2) - (textsize.height / 2))), + textsize + }; + CGRect spinrect = { + CGPointZero, + spinnersize + }; + + [container_ setFrame:containrect]; + [spinner_ setFrame:spinrect]; + [label_ setFrame:textrect]; + [self addSubview:container_]; + } + + return self; +} + +- (UILabel *)label { return label_; } +- (UIActivityIndicatorView *)activityIndicatorView { return spinner_; } + +@end +/* }}} */ + /* Cydia Browser Controller {{{ */ @interface CYBrowserController : BrowserController { CydiaObject *cydia_; @@ -5079,7 +5182,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) drawContentRect:(CGRect)rect { - bool highlighted(highlighted_); + bool highlighted(highlighted_ && !editing_); [icon_ drawInRect:CGRectMake(8, 7, 32, 32)]; @@ -5341,7 +5444,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadButtonClicked { - // Don't reload a package view by clicking the button. + // Don't reload a commerical package by tapping the loading button, + // but if it's not an Install button, we should forward it on. + if (![package_ uninstalled]) + [self _customButtonClicked]; } - (void) applyLoadingTitle { @@ -5470,13 +5576,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super dealloc]; } ++ (BOOL) hasIndexedCollation { + return NO; // XXX: objc_getClass("UILocalizedIndexedCollation") != nil; +} + - (NSInteger) numberOfSectionsInTableView:(UITableView *)list { NSInteger count([sections_ count]); return count == 0 ? 1 : count; } - (NSString *) tableView:(UITableView *)list titleForHeaderInSection:(NSInteger)section { - if ([sections_ count] == 0) + if ([sections_ count] == 0 || [[sections_ objectAtIndex:section] count] == 0) return nil; return [[sections_ objectAtIndex:section] name]; } @@ -5522,10 +5632,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView { + // XXX: is 20 the most optimal number here? return [packages_ count] > 20 ? index_ : nil; } -- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { +- (NSInteger) tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { + if ([[self class] hasIndexedCollation]) { + return [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionForSectionIndexTitleAtIndex:index]; + } + return index; } @@ -5536,7 +5651,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { target_ = target; action_ = action; - index_ = [[NSMutableArray alloc] initWithCapacity:32]; + index_ = [[self class] hasIndexedCollation] + ? [[[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles] retain] + : [[NSMutableArray alloc] initWithCapacity:32]; indices_ = [[NSMutableDictionary alloc] initWithCapacity:32]; packages_ = [[NSMutableArray arrayWithCapacity:16] retain]; @@ -5573,37 +5690,70 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [packages_ addObject:package]; _end - [index_ removeAllObjects]; [indices_ removeAllObjects]; Section *section = nil; - _profile(PackageTable$reloadData$Section) - for (size_t offset(0), end([packages_ count]); offset != end; ++offset) { - Package *package; - unichar index; + if ([[self class] hasIndexedCollation]) { + id collation = [objc_getClass("UILocalizedIndexedCollation") currentCollation]; + NSArray *titles = [collation sectionIndexTitles]; + int secidx = -1; - _profile(PackageTable$reloadData$Section$Package) - package = [packages_ objectAtIndex:offset]; - index = [package index]; - _end + _profile(PackageTable$reloadData$Section) + for (size_t offset(0), end([packages_ count]); offset != end; ++offset) { + Package *package; + int index; - if (section == nil || [section index] != index) { - _profile(PackageTable$reloadData$Section$Allocate) - section = [[[Section alloc] initWithIndex:index row:offset] autorelease]; + _profile(PackageTable$reloadData$Section$Package) + package = [packages_ objectAtIndex:offset]; + index = [collation sectionForObject:package collationStringSelector:@selector(name)]; _end - [index_ addObject:[section name]]; - //[indices_ setObject:[NSNumber numberForInt:[sections_ count]] forKey:index]; + while (secidx < index) { + secidx += 1; - _profile(PackageTable$reloadData$Section$Add) - [sections_ addObject:section]; - _end + _profile(PackageTable$reloadData$Section$Allocate) + section = [[[Section alloc] initWithName:[titles objectAtIndex:secidx] row:offset localize:NO] autorelease]; + _end + + _profile(PackageTable$reloadData$Section$Add) + [sections_ addObject:section]; + _end + } + + [section addToCount]; } + _end + } else { + [index_ removeAllObjects]; - [section addToCount]; - } - _end + _profile(PackageTable$reloadData$Section) + for (size_t offset(0), end([packages_ count]); offset != end; ++offset) { + Package *package; + unichar index; + + _profile(PackageTable$reloadData$Section$Package) + package = [packages_ objectAtIndex:offset]; + index = [package index]; + _end + + if (section == nil || [section index] != index) { + _profile(PackageTable$reloadData$Section$Allocate) + section = [[[Section alloc] initWithIndex:index row:offset] autorelease]; + _end + + [index_ addObject:[section name]]; + //[indices_ setObject:[NSNumber numberForInt:[sections_ count]] forKey:index]; + + _profile(PackageTable$reloadData$Section$Add) + [sections_ addObject:section]; + _end + } + + [section addToCount]; + } + _end + } _profile(PackageTable$reloadData$List) [list_ reloadData]; @@ -6389,6 +6539,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation HomeController ++ (BOOL)shouldHideNavigationBar { + return NO; +} + - (void) _setMoreHeaders:(NSMutableURLRequest *)request { [super _setMoreHeaders:request]; @@ -6419,12 +6573,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - //[[self navigationController] setNavigationBarHidden:YES animated:animated]; + + if ([[self class] shouldHideNavigationBar]) + [[self navigationController] setNavigationBarHidden:YES animated:animated]; } - (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - //[[self navigationController] setNavigationBarHidden:NO animated:animated]; + + if ([[self class] shouldHideNavigationBar]) + [[self navigationController] setNavigationBarHidden:NO animated:animated]; } - (id) init { @@ -6912,6 +7070,8 @@ freeing the view controllers on tab change */ // Inherit autorotation settings for modal parents. if ([self parentViewController] && [[self parentViewController] modalViewController] == self) { return [[self parentViewController] shouldAutorotateToInterfaceOrientation:orientation]; + } else if ([self parentViewController]) { + return [[self parentViewController] shouldAutorotateToInterfaceOrientation:orientation]; } else { return [super shouldAutorotateToInterfaceOrientation:orientation]; } @@ -8039,10 +8199,6 @@ static _finline void _setHomePage(Cydia *self) { return [tabbar_ updating]; } -- (UIView *) rotatingContentViewForWindow:(UIWindow *)window { - return window_; -} - - (void) _loaded { if ([broken_ count] != 0) { int count = [broken_ count]; @@ -8289,10 +8445,6 @@ static _finline void _setHomePage(Cydia *self) { _error->Discard(); } -- (CGRect) popUpBounds { - return [[tabbar_ view] bounds]; -} - - (bool) perform { if (![database_ prepare]) return false; @@ -8702,8 +8854,6 @@ static _finline void _setHomePage(Cydia *self) { CYViewController *page = nil; int tag = 0; - NSLog(@"open url: %@", url); - if ((page = [self pageForURL:url hasTag:&tag])) { [self setPage:page]; tag_ = tag; @@ -8715,7 +8865,7 @@ static _finline void _setHomePage(Cydia *self) { - (void) applicationOpenURL:(NSURL *)url { [super applicationOpenURL:url]; - NSLog(@"first: %@", url); + if (!loaded_) starturl_ = [url retain]; else [self openCydiaURL:url]; } @@ -8790,6 +8940,20 @@ static _finline void _setHomePage(Cydia *self) { [tabbar_ setViewControllers:controllers]; } +- (void)showFakeTabBarInView:(UIView *)view { + static UITabBar *fake = [[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 49.0f)]; + 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]; + } else { + [fake removeFromSuperview]; + } +} + - (void) applicationDidFinishLaunching:(id)unused { _trace(); CydiaApp = self; @@ -8815,9 +8979,7 @@ _trace(); essential_ = [[NSMutableArray alloc] initWithCapacity:4]; broken_ = [[NSMutableArray alloc] initWithCapacity:4]; - UIScreen *screen([UIScreen mainScreen]); - - window_ = [[UIWindow alloc] initWithFrame:[screen bounds]]; + window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [window_ orderFront:self]; [window_ makeKey:self]; [window_ setHidden:NO]; @@ -8850,6 +9012,7 @@ _trace(); // Show pinstripes while loading data. [[tabbar_ view] setBackgroundColor:[UIColor pinStripeColor]]; + [self showFakeTabBarInView:[tabbar_ tabBar]]; [self performSelector:@selector(loadData) withObject:nil afterDelay:0]; _trace(); @@ -8862,47 +9025,14 @@ _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]; - UIView *container = [[[UIView alloc] init] autorelease]; - [container setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin]; - - UIActivityIndicatorView *spinner = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; - [spinner startAnimating]; - [container addSubview:spinner]; - - UILabel *label = [[[UILabel alloc] init] autorelease]; - [label setFont:[UIFont boldSystemFontOfSize:15.0f]]; - [label setBackgroundColor:[UIColor clearColor]]; - [label setTextColor:[UIColor blackColor]]; - [label setShadowColor:[UIColor whiteColor]]; - [label setShadowOffset:CGSizeMake(0, 1)]; - [label setText:[NSString stringWithFormat:Elision_, UCLocalize("LOADING"), nil]]; - [container addSubview:label]; - - CGSize viewsize = [[tabbar_ view] frame].size; - CGSize spinnersize = [spinner bounds].size; - CGSize textsize = [[label text] sizeWithFont:[label font]]; - float bothwidth = spinnersize.width + textsize.width + 5.0f; - - CGRect containrect = { - CGPointMake(floorf((viewsize.width / 2) - (bothwidth / 2)), floorf((viewsize.height / 2) - (spinnersize.height / 2))), - CGSizeMake(bothwidth, spinnersize.height) - }; - CGRect textrect = { - CGPointMake(spinnersize.width + 5.0f, floorf((spinnersize.height / 2) - (textsize.height / 2))), - textsize - }; - CGRect spinrect = { - CGPointZero, - spinnersize - }; - - [container setFrame:containrect]; - [spinner setFrame:spinrect]; - [label setFrame:textrect]; - [[tabbar_ view] addSubview:container]; - [self reloadData]; PrintTimes(); @@ -8912,6 +9042,8 @@ _trace(); _setHomePage(self); } + [self showFakeTabBarInView:nil]; + [starturl_ release]; starturl_ = nil; @@ -8919,7 +9051,7 @@ _trace(); // XXX: does this actually slow anything down? [[tabbar_ view] setBackgroundColor:[UIColor clearColor]]; - [container removeFromSuperview]; + [loading removeFromSuperview]; } - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item {