X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/fe8e721fbeeaa802b0a3c3092d6d3e6d758cf583..c65611b940099e8762aa18bd34d75799898e77bd:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 8b47cc22..fe48f969 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -1,5 +1,5 @@ /* Cydia - iPhone UIKit Front-End for Debian APT - * Copyright (C) 2008-2010 Jay Freeman (saurik) + * Copyright (C) 2008-2011 Jay Freeman (saurik) */ /* Modified BSD License {{{ */ @@ -217,14 +217,6 @@ union SplitHash { static const NSUInteger UIViewAutoresizingFlexibleBoth(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); -void NSLogPoint(const char *fix, const CGPoint &point) { - NSLog(@"%s(%g,%g)", fix, point.x, point.y); -} - -void NSLogRect(const char *fix, const CGRect &rect) { - NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - static _finline NSString *CydiaURL(NSString *path) { char page[25]; page[0] = 'h'; page[1] = 't'; page[2] = 't'; page[3] = 'p'; page[4] = ':'; @@ -309,15 +301,15 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) { @end /* }}} */ -/* Cydia Action Sheet {{{ */ -@interface CYActionSheet : UIAlertView { +/* Cydia Alert View {{{ */ +@interface CYAlertView : UIAlertView { unsigned button_; } - (int) yieldToPopupAlertAnimated:(BOOL)animated; @end -@implementation CYActionSheet +@implementation CYAlertView - (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index { if ((self = [super init])) { @@ -363,32 +355,6 @@ static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSC static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch; static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; -/* Information Dictionaries {{{ */ -@interface NSMutableArray (Cydia) -- (void) addInfoDictionary:(NSDictionary *)info; -@end - -@implementation NSMutableArray (Cydia) - -- (void) addInfoDictionary:(NSDictionary *)info { - [self addObject:info]; -} - -@end - -@interface NSMutableDictionary (Cydia) -- (void) addInfoDictionary:(NSDictionary *)info; -@end - -@implementation NSMutableDictionary (Cydia) - -- (void) addInfoDictionary:(NSDictionary *)info { - [self setObject:info forKey:[info objectForKey:@"CFBundleIdentifier"]]; -} - -@end -/* }}} */ - #define lprintf(args...) fprintf(stderr, args) #define ForRelease 1 @@ -402,6 +368,7 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | #define ShowInternals (0 && !ForRelease) #define IgnoreInstall (0 && !ForRelease) #define AlwaysReload (0 && !ForRelease) +#define TryIndexedCollation (0 && !ForRelease) #if !TraceLogging #undef _trace @@ -1071,7 +1038,7 @@ static _transient NSMutableDictionary *Sources_; static bool Changed_; static time_t now_; -static bool IsWildcat_; +bool IsWildcat_; /* }}} */ /* Display Helpers {{{ */ @@ -1184,7 +1151,6 @@ bool isSectionVisible(NSString *section) { @protocol CydiaDelegate - (void) retainNetworkActivityIndicator; - (void) releaseNetworkActivityIndicator; -- (void) setPackageController:(CYPackageController *)view; - (void) clearPackage:(Package *)package; - (void) installPackage:(Package *)package; - (void) installPackages:(NSArray *)packages; @@ -1461,7 +1427,7 @@ struct MetaValue : static Cytore::File MetaFile_; // }}} // Cytore Helper Functions {{{ -static PackageValue *PackageFind(const char *name, size_t length) { +static PackageValue *PackageFind(const char *name, size_t length, bool *fail = NULL) { SplitHash nhash = { hashlittle(name, length) }; PackageValue *metadata; @@ -1471,6 +1437,14 @@ static PackageValue *PackageFind(const char *name, size_t length) { *offset = MetaFile_.New(length + 1); metadata = &MetaFile_.Get(*offset); + if (metadata == NULL) { + if (fail != NULL) + *fail = true; + + metadata = new PackageValue(); + memset(metadata, 0, sizeof(*metadata)); + } + memcpy(metadata->name_, name, length + 1); metadata->nhash_ = nhash.u16[1]; } else { @@ -1486,13 +1460,15 @@ static PackageValue *PackageFind(const char *name, size_t length) { } static void PackageImport(const void *key, const void *value, void *context) { + bool &fail(*reinterpret_cast(context)); + char buffer[1024]; if (!CFStringGetCString((CFStringRef) key, buffer, sizeof(buffer), kCFStringEncodingUTF8)) { NSLog(@"failed to import package %@", key); return; } - PackageValue *metadata(PackageFind(buffer, strlen(buffer))); + PackageValue *metadata(PackageFind(buffer, strlen(buffer), &fail)); NSDictionary *package((NSDictionary *) value); if (NSNumber *subscribed = [package objectForKey:@"IsSubscribed"]) @@ -2735,6 +2711,8 @@ struct PackageNameOrdering : if (range.location != NSNotFound) return YES; + [self parse]; + range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_]; if (range.location != NSNotFound) return YES; @@ -4104,18 +4082,16 @@ static NSString *Warning_; WebDataSource *source([frame dataSource]); NSURLResponse *response([source response]); + NSURL *url([response URL]); NSString *scheme([url scheme]); - - NSHTTPURLResponse *http; - if (scheme != nil && ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"])) - http = (NSHTTPURLResponse *) response; - else - http = nil; - - NSDictionary *headers([http allHeaderFields]); NSString *host([url host]); - [self setHeaders:headers forHost:host]; + + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *http((NSHTTPURLResponse *) response); + NSDictionary *headers([http allHeaderFields]); + [self setHeaders:headers forHost:host]; + } if ( [host isEqualToString:@"cydia.saurik.com"] || @@ -4349,7 +4325,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:UCLocalize("CANCEL") - // OLD: [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")] style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonClicked) @@ -4362,7 +4337,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (issues_ == nil && ![self isLoading]) [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:UCLocalize("CONFIRM") - style:UIBarButtonItemStylePlain + style:UIBarButtonItemStyleDone target:self action:@selector(confirmButtonClicked) ] autorelease]]; @@ -4498,7 +4473,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { //[status_ setFont:font]; output_ = [[UITextView alloc] init]; - [output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; //[output_ setTextFont:@"Courier New"]; [output_ setFont:[[output_ font] fontWithSize:12]]; @@ -4544,7 +4518,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { 10, 20, bounds.size.width - 20, - bounds.size.height - 62 + bounds.size.height - 96 )]; [close_ setFrame:CGRectMake( (bounds.size.width - closewidth) / 2, @@ -4754,7 +4728,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) setProgressError:(NSString *)error withTitle:(NSString *)title { - CYActionSheet *sheet([[[CYActionSheet alloc] + CYAlertView *sheet([[[CYAlertView alloc] initWithTitle:title buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil] defaultButtonIndex:0 @@ -5010,6 +4984,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self setNeedsDisplay]; } +- (NSString *) accessibilityLabel { + return [NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), name_, description_]; +} + - (void) setPackage:(Package *)package { [self clearPackage]; [package parse]; @@ -5238,6 +5216,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [switch_ setFrame:CGRectMake(frame.size.width - 102, 9, rect.size.width, rect.size.height)]; } +- (NSString *) accessibilityLabel { + return name_; +} + - (void) drawContentRect:(CGRect)rect { bool highlighted(highlighted_ && !editing_); @@ -5434,8 +5416,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) release { - if ([self retainCount] == 1) - [delegate_ setPackageController:self]; [super release]; } @@ -5536,11 +5516,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } #endif +- (void) viewWillAppear:(BOOL)animated { + if (![self hasLoaded]) + [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/package/")]]; + [super viewWillAppear:animated]; +} + - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; buttons_ = [[NSMutableArray alloc] initWithCapacity:4]; - [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]]; } return self; } @@ -5602,14 +5587,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { + [super reloadData]; + [self setPackage:[database_ packageWithName:name_]]; } @end /* }}} */ -/* Package Table {{{ */ -@interface PackageTable : UIView < +/* Package List Controller {{{ */ +@interface PackageListController : CYViewController < UITableViewDataSource, UITableViewDelegate > { @@ -5620,29 +5607,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UITableView *list_; NSMutableArray *index_; NSMutableDictionary *indices_; - // XXX: this target_ seems to be delegate_. :( - _transient id target_; - SEL action_; - // XXX: why do we even have this delegate_? - _transient id delegate_; + NSString *title_; } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action; - +- (id) initWithDatabase:(Database *)database title:(NSString *)title; - (void) setDelegate:(id)delegate; - -- (void) reloadData; - (void) resetCursor; -- (UITableView *) list; - -- (void) setShouldHideHeaderInShortLists:(BOOL)hide; - -- (void) deselectWithAnimation:(BOOL)animated; - @end -@implementation PackageTable +@implementation PackageListController - (void) dealloc { [packages_ release]; @@ -5650,13 +5624,98 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ release]; [index_ release]; [indices_ release]; + [title_ release]; [super dealloc]; } +- (void) deselectWithAnimation:(BOOL)animated { + [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds duration:(NSTimeInterval)duration curve:(UIViewAnimationCurve)curve { + CGRect base = [[self view] bounds]; + base.size.height -= bounds.size.height; + base.origin = [list_ frame].origin; + + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationBeginsFromCurrentState:YES]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationDuration:duration]; + [list_ setFrame:base]; + [UIView commitAnimations]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds duration:(NSTimeInterval)duration { + [self resizeForKeyboardBounds:bounds duration:duration curve:UIViewAnimationCurveLinear]; +} + +- (void) resizeForKeyboardBounds:(CGRect)bounds { + [self resizeForKeyboardBounds:bounds duration:0]; +} + +- (void) keyboardWillShow:(NSNotification *)notification { + CGRect bounds; + CGPoint center; + NSTimeInterval duration; + UIViewAnimationCurve curve; + [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&bounds]; + [[[notification userInfo] objectForKey:UIKeyboardCenterEndUserInfoKey] getValue:¢er]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration]; + + CGRect kbframe = CGRectMake(round(center.x - bounds.size.width / 2.0), round(center.y - bounds.size.height / 2.0), bounds.size.width, bounds.size.height); + UIViewController *base = self; + while ([base parentViewController] != nil) + base = [base parentViewController]; + CGRect viewframe = [[base view] convertRect:[list_ frame] fromView:[list_ superview]]; + CGRect intersection = CGRectIntersection(viewframe, kbframe); + + [self resizeForKeyboardBounds:intersection duration:duration curve:curve]; +} + +- (void) keyboardWillHide:(NSNotification *)notification { + NSTimeInterval duration; + UIViewAnimationCurve curve; + [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve]; + [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration]; + + [self resizeForKeyboardBounds:CGRectZero duration:duration curve:curve]; +} + +- (void) viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [self resizeForKeyboardBounds:CGRectZero]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; +} + +- (void) viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [self resizeForKeyboardBounds:CGRectZero]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; +} + +- (void) viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self deselectWithAnimation:animated]; +} + +- (void) didSelectPackage:(Package *)package { + CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]); + [view setPackage:package]; + [view setDelegate:delegate_]; + [[self navigationController] pushViewController:view animated:YES]; +} + +#if TryIndexedCollation + (BOOL) hasIndexedCollation { return NO; // XXX: objc_getClass("UILocalizedIndexedCollation") != nil; } +#endif - (NSInteger) numberOfSectionsInTableView:(UITableView *)list { NSInteger count([sections_ count]); @@ -5694,15 +5753,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return cell; } -- (void) deselectWithAnimation:(BOOL)animated { - [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; -} - -- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path { +- (void) tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)path { Package *package([self packageAtIndexPath:path]); package = [database_ packageWithName:[package id]]; - [target_ performSelector:action_ withObject:package]; - return path; + [self didSelectPackage:package]; } - (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView { @@ -5711,32 +5765,37 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSInteger) tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { +#if TryIndexedCollation if ([[self class] hasIndexedCollation]) { return [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionForSectionIndexTitleAtIndex:index]; } +#endif return index; } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action { - if ((self = [super initWithFrame:frame]) != nil) { +- (id) initWithDatabase:(Database *)database title:(NSString *)title { + if ((self = [super init]) != nil) { database_ = database; + title_ = [title copy]; + [[self navigationItem] setTitle:title_]; - target_ = target; - action_ = action; +#if TryIndexedCollation + if ([[self class] hasIndexedCollation]) + index_ = [[[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles] retain] + else +#endif + index_ = [[NSMutableArray alloc] initWithCapacity:32]; - index_ = [[self class] hasIndexedCollation] - ? [[[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles] retain] - : [[NSMutableArray alloc] initWithCapacity:32]; indices_ = [[NSMutableDictionary alloc] initWithCapacity:32]; packages_ = [[NSMutableArray arrayWithCapacity:16] retain]; sections_ = [[NSMutableArray arrayWithCapacity:16] retain]; - list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain]; + list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [list_ setRowHeight:73]; - [self addSubview:list_]; + [[self view] addSubview:list_]; [list_ setDataSource:self]; [list_ setDelegate:self]; @@ -5752,6 +5811,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { + [super reloadData]; + era_ = [database_ era]; NSArray *packages = [database_ packages]; @@ -5768,6 +5829,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Section *section = nil; +#if TryIndexedCollation if ([[self class] hasIndexedCollation]) { id collation = [objc_getClass("UILocalizedIndexedCollation") currentCollation]; NSArray *titles = [collation sectionIndexTitles]; @@ -5798,7 +5860,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [section addToCount]; } _end - } else { + } else +#endif + { [index_ removeAllObjects]; _profile(PackageTable$reloadData$Section) @@ -5838,18 +5902,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:NO]; } -- (UITableView *) list { - return list_; -} - -- (void) setShouldHideHeaderInShortLists:(BOOL)hide { - //XXX:[list_ setShouldHideHeaderInShortLists:hide]; -} - @end /* }}} */ -/* Filtered Package Table {{{ */ -@interface FilteredPackageTable : PackageTable { +/* Filtered Package List Controller {{{ */ +@interface FilteredPackageListController : PackageListController { SEL filter_; IMP imp_; id object_; @@ -5858,11 +5914,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) setObject:(id)object; - (void) setObject:(id)object forFilter:(SEL)filter; -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object; +- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object; @end -@implementation FilteredPackageTable +@implementation FilteredPackageListController - (void) dealloc { if (object_ != nil) @@ -5900,94 +5956,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _end } -- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object { - if ((self = [super initWithFrame:frame database:database target:target action:action]) != nil) { +- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { + if ((self = [super initWithDatabase:database title:title]) != nil) { [self setFilter:filter]; - object_ = [object retain]; + [self setObject:object]; [self reloadData]; } return self; } @end -/* }}} */ -/* Filtered Package Controller {{{ */ -@interface FilteredPackageController : CYViewController { - _transient Database *database_; - FilteredPackageTable *packages_; - NSString *title_; - SEL filter_; - id object_; -} - -- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object; - -@end - -@implementation FilteredPackageController - -- (void) dealloc { - [self releaseSubviews]; - [title_ release]; - - [super dealloc]; -} - -- (void) viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [packages_ deselectWithAnimation:animated]; -} - -- (void) didSelectPackage:(Package *)package { - CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_] autorelease]); - [view setPackage:package]; - [view setDelegate:delegate_]; - [[self navigationController] pushViewController:view animated:YES]; -} - -- (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - packages_ = [[FilteredPackageTable alloc] - initWithFrame:[[self view] bounds] - database:database_ - target:self - action:@selector(didSelectPackage:) - filter:filter_ - with:object_ - ]; - [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:packages_]; -} - -- (void) viewDidLoad { - [[self navigationItem] setTitle:title_]; -} - -- (void) releaseSubviews { - [packages_ release]; -} - -- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { - if ((self = [super init]) != nil) { - database_ = database; - title_ = [title copy]; - filter_ = filter; - object_ = object; - } return self; -} - -- (void) reloadData { - [super reloadData]; - [packages_ reloadData]; -} - -- (void) setDelegate:(id)delegate { - [super setDelegate:delegate]; - [packages_ setDelegate:delegate]; -} - -@end - /* }}} */ /* Home Controller {{{ */ @@ -5997,7 +5974,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation HomeController -+ (BOOL)shouldHideNavigationBar { ++ (BOOL) shouldHideNavigationBar { return NO; } @@ -6024,7 +6001,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert setCancelButtonIndex:0]; [alert setMessage: - @"Copyright (C) 2008-2010\n" + @"Copyright (C) 2008-2011\n" "Jay Freeman (saurik)\n" "saurik@saurik.com\n" "http://www.saurik.com/" @@ -6033,13 +6010,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert show]; } -- (void) viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - if ([[self class] shouldHideNavigationBar]) - [[self navigationController] setNavigationBarHidden:YES animated:animated]; -} - - (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; @@ -6047,17 +6017,23 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [[self navigationController] setNavigationBarHidden:NO animated:animated]; } -- (id) init { - if ((self = [super init]) != nil) { - [self loadURL:[NSURL URLWithString:CydiaURL(@"")]]; +- (void) viewWillAppear:(BOOL)animated { + if (![self hasLoaded]) + [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/home/")]]; - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("ABOUT") - style:UIBarButtonItemStylePlain - target:self - action:@selector(aboutButtonClicked) - ] autorelease]]; - } return self; + [super viewWillAppear:animated]; + + if ([[self class] shouldHideNavigationBar]) + [[self navigationController] setNavigationBarHidden:YES animated:animated]; +} + +- (void) viewDidLoad { + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("ABOUT") + style:UIBarButtonItemStylePlain + target:self + action:@selector(aboutButtonClicked) + ] autorelease]]; } @end @@ -6075,21 +6051,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [NSURL URLWithString:@"cydia://manage"]; } -- (id) init { - if ((self = [super init]) != nil) { - [[self navigationItem] setTitle:UCLocalize("MANAGE")]; +- (void) viewWillAppear:(BOOL)animated { + if (![self hasLoaded]) + [self loadURL:[NSURL URLWithString:CydiaURL(@"ui/manage/")]]; - [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]]; + [super viewWillAppear:animated]; +} - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("SETTINGS") - style:UIBarButtonItemStylePlain - target:self - action:@selector(settingsButtonClicked) - ] autorelease]]; +- (void) viewDidLoad { + [[self navigationItem] setTitle:UCLocalize("MANAGE")]; - [self queueStatusDidChange]; - } return self; + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("SETTINGS") + style:UIBarButtonItemStylePlain + target:self + action:@selector(settingsButtonClicked) + ] autorelease]]; + + [self queueStatusDidChange]; } - (void) settingsButtonClicked { @@ -6102,11 +6081,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) applyLoadingTitle { - // No "Loading" title. + // Disable "Loading" title. } - (void) applyRightButton { - // No right button. + // Disable right button. } #endif @@ -6126,6 +6105,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (bool) isLoading { + // Never show as loading. return false; } @@ -6265,7 +6245,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { id root_; } -- (NSArray *) navigationURLItems; +- (NSArray *) navigationURLCollection; - (void) dropBar:(BOOL)animated; - (void) beginUpdate; - (void) raiseBar:(BOOL)animated; @@ -6275,12 +6255,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation CYTabBarController -- (NSArray *) navigationURLItems { +- (NSArray *) navigationURLCollection { NSMutableArray *items([NSMutableArray array]); - // XXX:Deal with transient view controllers. + // XXX: Should this deal with transient view controllers? for (id navigation in [self viewControllers]) { - NSArray *stack = [navigation performSelector:@selector(navigationURLStack)]; + NSArray *stack = [navigation performSelector:@selector(navigationURLCollection)]; if (stack != nil) [items addObject:stack]; } @@ -6289,15 +6269,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { - size_t count([[self viewControllers] count]); - for (size_t i(0); i != count; ++i) { - CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); - [page reloadData]; - } + for (CYViewController *controller in [self viewControllers]) + [controller reloadData]; [(CYNavigationController *)[self transientViewController] reloadData]; } +- (void) dealloc { + [refreshbar_ release]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; @@ -6522,12 +6506,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } -- (void) dealloc { - [refreshbar_ release]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; -} - @end /* }}} */ /* Cydia Navigation Controller {{{ */ @@ -6536,7 +6514,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _transient id delegate_; } -- (NSArray *) navigationURLStack; +- (NSArray *) navigationURLCollection; - (id) initWithDatabase:(Database *)database; - (void) reloadData; @@ -6549,7 +6527,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super dealloc]; } -- (NSArray *) navigationURLStack { +- (NSArray *) navigationURLCollection { NSMutableArray *stack([NSMutableArray array]); for (CYViewController *controller in [self viewControllers]) { @@ -6562,10 +6540,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { - size_t count([[self viewControllers] count]); - for (size_t i(0); i != count; ++i) { - CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); - [page reloadData]; + for (CYViewController *page in [self viewControllers]) { + if ([page hasLoaded]) + [page reloadData]; } } @@ -6684,7 +6661,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* }}} */ /* Section Controller {{{ */ -@interface SectionController : FilteredPackageController { +@interface SectionController : FilteredPackageListController { NSString *section_; } @@ -6765,6 +6742,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } +- (BOOL) isEditing { + return editing_; +} + - (void) setEditing:(BOOL)editing { if ((editing_ = editing)) [list_ reloadData]; @@ -6800,7 +6781,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *reuseIdentifier = @"SectionCell"; - SectionCell *cell = (SectionCell *) [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; + SectionCell *cell = (SectionCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if (cell == nil) cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease]; @@ -6949,6 +6930,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [NSURL URLWithString:@"cydia://changes"]; } +- (void) viewWillAppear:(BOOL)animated { + // Loads after it appears, so don't load beforehand. + loaded_ = YES; + [super viewWillAppear:animated]; +} + - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; @@ -7044,9 +7031,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ((self = [super init]) != nil) { database_ = database; - // We load after the view is visible, so don't "magically" load beforehand. - loaded_ = YES; - packages_ = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); sections_ = [[NSMutableArray arrayWithCapacity:16] retain]; } return self; @@ -7170,7 +7154,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Search Controller {{{ */ -@interface SearchController : FilteredPackageController < +@interface SearchController : FilteredPackageListController < UISearchBarDelegate > { UISearchBar *search_; @@ -7191,7 +7175,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://search/%@", [search_ text]]]; + if ([search_ text] == nil || [[search_ text] isEqualToString:@""]) + return [NSURL URLWithString:@"cydia://search"]; + else + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://search/%@", [search_ text]]]; } - (void) setSearchTerm:(NSString *)searchTerm { @@ -7200,13 +7187,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar { - [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; + [self setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; [search_ resignFirstResponder]; [self reloadData]; } - (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text { - [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSelectedForBy:)]; + [self setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)]; [self reloadData]; } @@ -7239,9 +7226,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadData { - [packages_ setObject:[search_ text]]; + [self setObject:[search_ text]]; [super reloadData]; - [packages_ resetCursor]; + [self resetCursor]; } - (void) didSelectPackage:(Package *)package { @@ -7407,51 +7394,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [table_ reloadData]; } -@end -/* }}} */ -/* Signature Controller {{{ */ -@interface SignatureController : CYBrowserController { - _transient Database *database_; - NSString *package_; -} - -- (id) initWithDatabase:(Database *)database package:(NSString *)package; - -@end - -@implementation SignatureController - -- (void) dealloc { - [package_ release]; - [super dealloc]; -} - -- (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/signature", package_]]; -} - -- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { - // XXX: dude! - [super webView:view didClearWindowObject:window forFrame:frame]; -} - -- (id) initWithDatabase:(Database *)database package:(NSString *)package { - if ((self = [super init]) != nil) { - database_ = database; - package_ = [package retain]; - [self reloadData]; - } return self; -} - -- (void) reloadData { - [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]]; -} - @end /* }}} */ /* Installed Controller {{{ */ -@interface InstalledController : FilteredPackageController { +@interface InstalledController : FilteredPackageListController { BOOL expert_; } @@ -7502,10 +7449,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #endif } -- (void) reloadData { - [packages_ reloadData]; -} - - (void) updateRoleButton { if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] @@ -7517,18 +7460,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) roleButtonClicked { - [packages_ setObject:[NSNumber numberWithBool:expert_]]; - [packages_ reloadData]; + [self setObject:[NSNumber numberWithBool:expert_]]; + [self reloadData]; expert_ = !expert_; [self updateRoleButton]; } -- (void) setDelegate:(id)delegate { - [super setDelegate:delegate]; - [packages_ setDelegate:delegate]; -} - @end /* }}} */ @@ -7592,6 +7530,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } return self; } +- (NSString *) accessibilityLabel { + return label_; +} + - (void) drawContentRect:(CGRect)rect { bool highlighted(highlighted_); float width(rect.size.width); @@ -7614,7 +7556,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Source Controller {{{ */ -@interface SourceController : FilteredPackageController { +@interface SourceController : FilteredPackageListController { Source *source_; } @@ -8497,8 +8439,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (recently || loaded_ || ManualRefresh) { [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO]; - // If we are cancelling due to ManualRefresh or a recent refresh - // we need to make sure it knows it's already loaded. + // If we are cancelling, we need to make sure it knows it's already loaded. loaded_ = true; return; } else { @@ -8751,12 +8692,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self setNetworkActivityIndicatorVisible:NO]; } -- (void) setPackageController:(CYPackageController *)view { - WebThreadLock(); - [view setPackage:nil]; - WebThreadUnlock(); -} - - (void) cancelAndClear:(bool)clear { @synchronized (self) { if (clear) { @@ -8989,8 +8924,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ([base isEqualToString:@"package"]) { if ([arg2 isEqualToString:@"settings"]) { controller = [[[PackageSettingsController alloc] initWithDatabase:database_ package:arg1] autorelease]; - } else if ([arg2 isEqualToString:@"signature"]) { - controller = [[[SignatureController alloc] initWithDatabase:database_ package:arg1] autorelease]; } else if ([arg2 isEqualToString:@"files"]) { if (Package *package = [database_ packageWithName:arg1]) { controller = [[[FileTable alloc] initWithDatabase:database_] autorelease]; @@ -9033,7 +8966,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) applicationWillTerminate:(UIApplication *)application { - [Metadata_ setObject:[tabbar_ navigationURLItems] forKey:@"InterfaceState"]; + Changed_ = true; + [Metadata_ setObject:[tabbar_ navigationURLCollection] forKey:@"InterfaceState"]; [Metadata_ setObject:[NSDate date] forKey:@"LastClosed"]; [Metadata_ setObject:[NSNumber numberWithInt:[tabbar_ selectedIndex]] forKey:@"InterfaceIndex"]; @@ -9305,6 +9239,33 @@ MSHook(void, UIHardware$_playSystemSound$, Class self, SEL _cmd, int sound) { } } +Class $UIApplication; + +MSHook(void, UIApplication$_updateApplicationAccessibility, UIApplication *self, SEL _cmd) { + static BOOL initialized = NO; + static BOOL started = NO; + + NSDictionary *dict([[[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.apple.Accessibility.plist"] autorelease]); + BOOL enabled = [[dict objectForKey:@"VoiceOverTouchEnabled"] boolValue] || [[dict objectForKey:@"VoiceOverTouchEnabledByiTunes"] boolValue]; + + if ([self respondsToSelector:@selector(_accessibilityBundlePrincipalClass)]) { + id bundle = [self performSelector:@selector(_accessibilityBundlePrincipalClass)]; + if (![bundle respondsToSelector:@selector(_accessibilityStopServer)]) return; + if (![bundle respondsToSelector:@selector(_accessibilityStartServer)]) return; + + if (initialized && !enabled) { + initialized = NO; + [bundle performSelector:@selector(_accessibilityStopServer)]; + } else if (enabled) { + initialized = YES; + if (!started) { + started = YES; + [bundle performSelector:@selector(_accessibilityStartServer)]; + } + } + } +} + int main(int argc, char *argv[]) { _pooled _trace(); @@ -9332,6 +9293,13 @@ int main(int argc, char *argv[]) { _pooled _UIHardware$_playSystemSound$ = reinterpret_cast(method_getImplementation(UIHardware$_playSystemSound$)); method_setImplementation(UIHardware$_playSystemSound$, reinterpret_cast(&$UIHardware$_playSystemSound$)); } + + $UIApplication = objc_getClass("UIApplication"); + Method UIApplication$_updateApplicationAccessibility(class_getInstanceMethod($UIApplication, @selector(_updateApplicationAccessibility))); + if (UIApplication$_updateApplicationAccessibility != NULL) { + _UIApplication$_updateApplicationAccessibility = reinterpret_cast(method_getImplementation(UIApplication$_updateApplicationAccessibility)); + method_setImplementation(UIApplication$_updateApplicationAccessibility, reinterpret_cast(&$UIApplication$_updateApplicationAccessibility)); + } /* }}} */ /* Set Locale {{{ */ Locale_ = CFLocaleCopyCurrent(); @@ -9505,11 +9473,15 @@ int main(int argc, char *argv[]) { _pooled _trace(); if (Packages_ != nil) { - CFDictionaryApplyFunction((CFDictionaryRef) Packages_, &PackageImport, NULL); + bool fail(false); + CFDictionaryApplyFunction((CFDictionaryRef) Packages_, &PackageImport, &fail); _trace(); - [Metadata_ removeObjectForKey:@"Packages"]; - Packages_ = nil; - Changed_ = true; + + if (!fail) { + [Metadata_ removeObjectForKey:@"Packages"]; + Packages_ = nil; + Changed_ = true; + } } Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];