X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/d210b85d77ea40a096290d32423b3b607fa86c1e..20b8724d290791e2a939c3baa3d5657eb3f8ebb1:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index fccb591f..e70d9f3b 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -42,48 +42,11 @@ #include #include #include + #include +#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import -#import -#import - -#import +#import // XXX: remove #import @@ -137,13 +100,17 @@ extern "C" { #include #include -#define UIWebView UIWebDocumentView - #import "BrowserView.h" #import "ResetView.h" #import "UICaboodle.h" /* }}} */ +static const NSStringCompareOptions CompareOptions_ = NSCaseInsensitiveSearch | NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch; + +@interface WebView (Cydia) +- (void) _setLayoutInterval:(float)interval; +@end + /* iPhoneOS 2.0 Compatibility {{{ */ #ifdef __OBJC2__ @interface UICGColor : NSObject { @@ -152,14 +119,6 @@ extern "C" { - (id) initWithCGColor:(CGColorRef)color; @end -@interface UIFont { -} - -+ (id)systemFontOfSize:(float)fp8; -+ (id)boldSystemFontOfSize:(float)fp8; -- (UIFont *) fontWithSize:(CGFloat)size; -@end - @interface NSObject (iPhoneOS) - (CGColorRef) cgColor; - (CGColorRef) CGColor; @@ -217,8 +176,10 @@ extern NSString *kUIButtonBarButtonType; typedef enum { kUIProgressIndicatorStyleLargeWhite = 0, kUIProgressIndicatorStyleMediumWhite = 1, + kUIProgressIndicatorStyleMediumBrown = 2, kUIProgressIndicatorStyleSmallWhite = 3, - kUIProgressIndicatorStyleSmallBlack = 4 + kUIProgressIndicatorStyleSmallBlack = 4, + kUIProgressIndicatorStyleTinyWhite = 5, } UIProgressIndicatorStyle; typedef enum { @@ -456,11 +417,12 @@ static const char * const SpringBoard_ = "/System/Library/LaunchDaemons/com.appl static CGColor Blue_; static CGColor Blueish_; static CGColor Black_; -static CGColor Clear_; +static CGColor Off_; static CGColor Red_; static CGColor White_; static CGColor Gray_; +static NSString *App_; static NSString *Home_; static BOOL Sounds_Keyboard_; @@ -500,6 +462,7 @@ static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; static _transient NSMutableDictionary *Sections_; static _transient NSMutableDictionary *Sources_; +static _transient NSMutableArray *Documents_; static bool Changed_; static NSDate *now_; @@ -553,7 +516,7 @@ UITextView *GetTextView(NSString *value, float left, bool html) { [text setText:value]; [text setEnabled:NO]; - [text setBackgroundColor:[UIColor colorWithCGColor:Clear_]]; + [text setBackgroundColor:[UIColor clearColor]]; CGRect frame = [text frame]; [text setFrame:frame]; @@ -612,7 +575,9 @@ bool isSectionVisible(NSString *section) { - (void) setProgressError:(NSString *)error forPackage:(NSString *)id; - (void) setProgressTitle:(NSString *)title; - (void) setProgressPercent:(float)percent; +- (void) startProgress; - (void) addProgressOutput:(NSString *)output; +- (bool) isCancelling:(size_t)received; @end @protocol ConfigurationDelegate @@ -685,10 +650,11 @@ class Status : ); [delegate_ setProgressPercent:percent]; - return value; + return [delegate_ isCancelling:CurrentBytes] ? false : value; } virtual void Start() { + [delegate_ startProgress]; } virtual void Stop() { @@ -914,7 +880,7 @@ class Progress : return NSOrderedDescending; } - return [lhs caseInsensitiveCompare:rhs]; + return [lhs compare:rhs options:CompareOptions_]; } - (NSDictionary *) record { @@ -1052,8 +1018,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { NSString *name_; NSString *tagline_; NSString *icon_; - NSString *homepage_; NSString *depiction_; + NSString *homepage_; Address *sponsor_; Address *author_; NSArray *tags_; @@ -1082,6 +1048,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (BOOL) upgradableAndEssential:(BOOL)essential; - (BOOL) essential; - (BOOL) broken; +- (BOOL) unfiltered; - (BOOL) visible; - (BOOL) half; @@ -1116,7 +1083,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (void) install; - (void) remove; -- (NSNumber *) isVisiblySearchedForBy:(NSString *)search; +- (NSNumber *) isUnfilteredAndSearchedForBy:(NSString *)search; - (NSNumber *) isInstalledAndVisible:(NSNumber *)number; - (NSNumber *) isVisiblyUninstalledInSection:(NSString *)section; - (NSNumber *) isVisibleInSource:(Source *)source; @@ -1139,10 +1106,10 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [tagline_ release]; if (icon_ != nil) [icon_ release]; - if (homepage_ != nil) - [homepage_ release]; if (depiction_ != nil) [depiction_ release]; + if (homepage_ != nil) + [homepage_ release]; if (sponsor_ != nil) [sponsor_ release]; if (author_ != nil) @@ -1203,14 +1170,16 @@ NSString *Scour(const char *field, const char *begin, const char *end) { icon_ = Scour("Icon", begin, end); if (icon_ != nil) icon_ = [icon_ retain]; + depiction_ = Scour("Depiction", begin, end); + if (depiction_ != nil) + depiction_ = [depiction_ retain]; homepage_ = Scour("Homepage", begin, end); if (homepage_ == nil) homepage_ = Scour("Website", begin, end); + if ([homepage_ isEqualToString:depiction_]) + homepage_ = nil; if (homepage_ != nil) homepage_ = [homepage_ retain]; - depiction_ = Scour("Depiction", begin, end); - if (depiction_ != nil) - depiction_ = [depiction_ retain]; NSString *sponsor = Scour("Sponsor", begin, end); if (sponsor != nil) sponsor_ = [[Address addressWithString:sponsor] retain]; @@ -1342,9 +1311,13 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return [database_ cache][iterator_].InstBroken(); } -- (BOOL) visible { +- (BOOL) unfiltered { NSString *section = [self section]; - return [self hasSupportingRole] && (section == nil || isSectionVisible(section)); + return section == nil || isSectionVisible(section); +} + +- (BOOL) visible { + return [self hasSupportingRole] && [self unfiltered]; } - (BOOL) half { @@ -1507,7 +1480,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return NSOrderedDescending; } - return [lhs caseInsensitiveCompare:rhs]; + return [lhs compare:rhs options:CompareOptions_]; } - (NSComparisonResult) compareBySection:(Package *)package { @@ -1519,7 +1492,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { else if (lhs != NULL && rhs == NULL) return NSOrderedDescending; else if (lhs != NULL && rhs != NULL) { - NSComparisonResult result = [lhs caseInsensitiveCompare:rhs]; + NSComparisonResult result = [lhs compare:rhs options:CompareOptions_]; if (result != NSOrderedSame) return result; } @@ -1585,9 +1558,9 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [database_ cache]->MarkDelete(iterator_, true); } -- (NSNumber *) isVisiblySearchedForBy:(NSString *)search { +- (NSNumber *) isUnfilteredAndSearchedForBy:(NSString *)search { return [NSNumber numberWithBool:( - [self valid] && [self visible] && [self matches:search] + [self unfiltered] && [self matches:search] )]; } @@ -1601,7 +1574,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { NSString *section = [self section]; return [NSNumber numberWithBool:( - [self valid] && [self visible] && + [self visible] && [self installed] == nil && ( name == nil || section == nil && [name length] == 0 || @@ -1654,7 +1627,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return NSOrderedDescending; } - return [lhs caseInsensitiveCompare:rhs]; + return [lhs compare:rhs options:CompareOptions_]; } - (Section *) initWithName:(NSString *)name { @@ -2129,6 +2102,21 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [text setTextColor:[UIColor colorWithCGColor:blue]]; } +bool DepSubstrate(const pkgCache::VerIterator &iterator) { + if (!iterator.end()) + for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) { + if (dep->Type != pkgCache::Dep::Depends && dep->Type != pkgCache::Dep::PreDepends) + continue; + pkgCache::PkgIterator package(dep.TargetPkg()); + if (package.end()) + continue; + if (strcmp(package.Name(), "mobilesubstrate") == 0) + return true; + } + + return false; +} + @protocol ConfirmationViewDelegate - (void) cancel; - (void) confirm; @@ -2143,6 +2131,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString UIPreferencesTable *table_; NSMutableDictionary *fields_; UIActionSheet *essential_; + BOOL substrate_; } - (void) cancel; @@ -2183,8 +2172,11 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString case 0: if (essential_ != nil) [essential_ popupAlertAnimated:YES]; - else + else { + if (substrate_) + Finish_ = 2; [delegate_ confirm]; + } break; case 1: @@ -2202,6 +2194,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [self cancel]; break; case 2: + if (substrate_) + Finish_ = 2; [delegate_ confirm]; break; default: @@ -2318,6 +2312,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString bool remove(false); + pkgDepCache::Policy *policy([database_ policy]); + pkgCacheFile &cache([database_ cache]); NSArray *packages = [database_ packages]; for (size_t i(0), e = [packages count]; i != e; ++i) { @@ -2339,7 +2335,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString if ([package essential]) remove = true; [removing addObject:name]; - } + } else continue; + + substrate_ |= DepSubstrate(policy->GetCandidateVer(iterator)); + substrate_ |= DepSubstrate(iterator.CurrentVer()); } if (!remove) @@ -2382,7 +2381,6 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString 0, navsize.height, bounds.size.width, bounds.size.height - navsize.height )]; - [table_ setReusesTableCells:YES]; [table_ setDataSource:self]; [table_ reloadData]; @@ -2458,6 +2456,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString id delegate_; BOOL running_; SHA1SumValue springlist_; + size_t received_; + NSTimeInterval last_; } - (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to; @@ -2513,10 +2513,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]]; if (bootstrap_) - [overlay_ setBackgroundColor:[UIColor colorWithCGColor:Black_]]; + [overlay_ setBackgroundColor:[UIColor blackColor]]; else { background_ = [[UIView alloc] initWithFrame:[self bounds]]; - [background_ setBackgroundColor:[UIColor colorWithCGColor:Black_]]; + [background_ setBackgroundColor:[UIColor blackColor]]; [self addSubview:background_]; } @@ -2552,8 +2552,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString 24 )]; - [status_ setColor:[UIColor colorWithCGColor:White_]]; - [status_ setBackgroundColor:[UIColor colorWithCGColor:Clear_]]; + [status_ setColor:[UIColor whiteColor]]; + [status_ setBackgroundColor:[UIColor clearColor]]; [status_ setCentersHorizontally:YES]; //[status_ setFont:font]; @@ -2568,8 +2568,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString //[output_ setTextFont:@"Courier New"]; [output_ setTextSize:12]; - [output_ setTextColor:[UIColor colorWithCGColor:White_]]; - [output_ setBackgroundColor:[UIColor colorWithCGColor:Clear_]]; + [output_ setTextColor:[UIColor whiteColor]]; + [output_ setBackgroundColor:[UIColor clearColor]]; [output_ setMarginTop:0]; [output_ setAllowsRubberBanding:YES]; @@ -2632,7 +2632,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString switch (Finish_) { case 0: [delegate_ progressViewIsComplete:self]; - [self resetView]; + [self resetView]; break; case 1: @@ -2640,7 +2640,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString break; case 2: - system("killall SpringBoard"); + system("launchctl stop com.apple.SpringBoard"); break; case 3: @@ -2706,6 +2706,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [output_ setText:@""]; [progress_ setProgress:0]; + received_ = 0; + last_ = 0;//[NSDate timeIntervalSinceReferenceDate]; + [close_ removeFromSuperview]; [overlay_ addSubview:progress_]; [overlay_ addSubview:status_]; @@ -2739,7 +2742,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString detachNewThreadSelector:selector toTarget:database_ withObject:nil - title:@"Repairing..." + title:@"Repairing" ]; } @@ -2782,6 +2785,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString ]; } +- (void) startProgress { + last_ = [NSDate timeIntervalSinceReferenceDate]; +} + - (void) addProgressOutput:(NSString *)output { [self performSelectorOnMainThread:@selector(_addProgressOutput:) @@ -2790,6 +2797,19 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString ]; } +- (bool) isCancelling:(size_t)received { + if (last_ != 0) { + NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; + if (received_ != received) { + received_ = received; + last_ = now; + } else if (now - last_ > 30) + return true; + } + + return false; +} + - (void) _setConfigurationData:(NSString *)data { static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$"); @@ -2818,7 +2838,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } - (void) _setProgressTitle:(NSString *)title { - [status_ setText:[title stringByAppendingString:@"..."]]; + [status_ setText:title]; } - (void) _setProgressPercent:(NSNumber *)percent { @@ -2899,7 +2919,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString badge_ = [[UIImageView alloc] initWithFrame:CGRectMake(17, 70, 16, 16)]; status_ = [[UITextLabel alloc] initWithFrame:CGRectMake(48, 68, 280, 20)]; - [status_ setBackgroundColor:Clear_]; + [status_ setBackgroundColor:[UIColor clearColor]]; [status_ setFont:small]; #endif } return self; @@ -2914,7 +2934,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString if (NSString *icon = [package icon]) icon_ = [UIImage imageAtPath:[icon substringFromIndex:6]]; if (icon_ == nil) if (NSString *section = [package section]) - icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sections/%@.png", Simplify(section)]]; + icon_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, Simplify(section)]]; /*if (icon_ == nil) if (NSString *icon = [source defaultIcon]) icon_ = [UIImage imageAtPath:[icon substringFromIndex:6]];*/ if (icon_ == nil) @@ -2958,7 +2978,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } else if ([package half]) { [badge_ setImage:[UIImage applicationImageNamed:@"damaged.png"]]; [status_ setText:@"Package Damaged"]; - [status_ setColor:Red_]; + [status_ setColor:[UIColor redColor]]; } else { [badge_ setImage:nil]; [status_ setText:nil]; @@ -2972,8 +2992,18 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } - (void) drawContentInRect:(CGRect)rect selected:(BOOL)selected { - if (icon_ != nil) - [icon_ drawInRect:CGRectMake(10, 10, 30, 30)]; + if (icon_ != nil) { + CGRect rect; + rect.size = [icon_ size]; + + rect.size.width /= 2; + rect.size.height /= 2; + + rect.origin.x = 25 - rect.size.width / 2; + rect.origin.y = 25 - rect.size.height / 2; + + [icon_ drawInRect:rect]; + } if (selected) UISetColor(White_); @@ -3299,6 +3329,13 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [sheet dismiss]; } +#include "internals.h" + +- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { + [[frame windowObject] evaluateWebScript:@"document.base.target = '_top'"]; + return [super webView:sender didFinishLoadForFrame:frame]; +} + - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { [window setValue:package_ forKey:@"package"]; } @@ -3490,6 +3527,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [self addSubview:list_]; [self reloadData]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -3514,7 +3554,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString for (size_t i(0); i != [packages count]; ++i) { Package *package([packages objectAtIndex:i]); - if ([[package performSelector:filter_ withObject:object_] boolValue]) + if ([package valid] && [[package performSelector:filter_ withObject:object_] boolValue]) [packages_ addObject:package]; } @@ -3931,6 +3971,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [table setDelegate:self]; [self reloadData]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -4003,8 +4046,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString return [[list_ table] isRowDeletionEnabled] ? @"Done" : @"Edit"; } -- (RVUINavBarButtonStyle) rightButtonStyle { - return [[list_ table] isRowDeletionEnabled] ? RVUINavBarButtonStyleHighlighted : RVUINavBarButtonStyleNormal; +- (UINavigationButtonStyle) rightButtonStyle { + return [[list_ table] isRowDeletionEnabled] ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal; } @end @@ -4041,6 +4084,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString ]; [self addSubview:packages_]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -4071,8 +4117,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString return Role_ != nil && [Role_ isEqualToString:@"Developer"] ? nil : expert_ ? @"Expert" : @"Simple"; } -- (RVUINavBarButtonStyle) rightButtonStyle { - return expert_ ? RVUINavBarButtonStyleHighlighted : RVUINavBarButtonStyleNormal; +- (UINavigationButtonStyle) rightButtonStyle { + return expert_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal; } - (void) setDelegate:(id)delegate { @@ -4155,6 +4201,41 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString @end /* }}} */ +/* Indirect Delegate {{{ */ +@interface IndirectDelegate : NSProxy { + _transient id delegate_; +} + +- (void) setDelegate:(id)delegate; +- (id) initWithDelegate:(id)delegate; +@end + +@implementation IndirectDelegate + +- (void) setDelegate:(id)delegate { + delegate_ = delegate; +} + +- (id) initWithDelegate:(id)delegate { + delegate_ = delegate; + return self; +} + +- (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { + if (delegate_ != nil) + if (NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel]) + return sig; + return nil; +} + +- (void) forwardInvocation:(NSInvocation*)inv { + SEL sel = [inv selector]; + if (delegate_ != nil && [delegate_ respondsToSelector:sel]) + [inv invokeWithTarget:delegate_]; +} + +@end +/* }}} */ /* Browser Implementation {{{ */ @implementation BrowserView @@ -4164,11 +4245,22 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [webview setResourceLoadDelegate:nil]; [webview setUIDelegate:nil]; - [scroller_ setDelegate:nil]; [webview_ setDelegate:nil]; + [webview_ setGestureDelegate:nil]; - [scroller_ release]; + /*WebFrame *frame = [webview mainFrame]; + [frame loadHTMLString:@"" baseURL:[NSURL URLWithString:@"http://cydia.saurik.com/"]];*/ + + //[webview_ removeFromSuperview]; + //[Documents_ addObject:[webview_ autorelease]]; [webview_ release]; + + [indirect_ setDelegate:nil]; + [indirect_ release]; + + [scroller_ setDelegate:nil]; + + [scroller_ release]; [urls_ release]; [indicator_ release]; if (title_ != nil) @@ -4230,10 +4322,39 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [book_ pushPage:page]; } -- (void) getSpecial:(NSString *)href { +- (RVPage *) _pageForPackage:(NSString *)name { + if (Package *package = [database_ packageWithName:name]) { + PackageView *view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease]; + [view setPackage:package]; + return view; + } else { + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:@"Cannot Locate Package" + buttons:[NSArray arrayWithObjects:@"Close", nil] + defaultButtonIndex:0 + delegate:self + context:@"missing" + ] autorelease]; + + [sheet setBodyText:[NSString stringWithFormat: + @"The package %@ cannot be found in your current sources. I might recommend installing more sources." + , name]]; + + [sheet popupAlertAnimated:YES]; + return nil; + } +} + +- (BOOL) getSpecial:(NSString *)href { RVPage *page = nil; - if ([href hasPrefix:@"mailto:"]) + if ( + [href hasPrefix:@"http://ax.phobos.apple.com/"] || + [href hasPrefix:@"http://phobos.apple.com/"] || + [href hasPrefix:@"http://www.youtube.com/watch?"] || + [href hasPrefix:@"mailto:"] || + [href hasPrefix:@"tel:"] + ) [delegate_ openURL:[NSURL URLWithString:href]]; else if ([href isEqualToString:@"cydia://add-source"]) page = [[[AddSourceView alloc] initWithBook:book_ database:database_] autorelease]; @@ -4249,32 +4370,16 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [files setPackage:package]; page = files; } - } else if ([href hasPrefix:@"apptapp://package/"]) { - NSString *name = [href substringFromIndex:18]; - - if (Package *package = [database_ packageWithName:name]) { - PackageView *view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease]; - [view setPackage:package]; - page = view; - } else { - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:@"Cannot Locate Package" - buttons:[NSArray arrayWithObjects:@"Close", nil] - defaultButtonIndex:0 - delegate:self - context:@"missing" - ] autorelease]; - - [sheet setBodyText:[NSString stringWithFormat: - @"The package %@ cannot be found in your current sources. I might recommend installing more sources." - , name]]; - - [sheet popupAlertAnimated:YES]; - } - } + } else if ([href hasPrefix:@"apptapp://package/"]) + page = [self _pageForPackage:[href substringFromIndex:18]]; + else if ([href hasPrefix:@"cydia://package/"]) + page = [self _pageForPackage:[href substringFromIndex:16]]; + else if (![href hasPrefix:@"apptapp:"] && ![href hasPrefix:@"cydia:"]) + return false; if (page != nil) [self pushPage:page]; + return true; } - (void) webView:(WebView *)sender willClickElement:(id)element { @@ -4290,19 +4395,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [self getSpecial:href]; } -- (BOOL) isSpecialScheme:(NSString *)scheme { - return - [scheme isEqualToString:@"apptapp"] || - [scheme isEqualToString:@"cydia"] || - [scheme isEqualToString:@"mailto"]; -} - - (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { NSURL *url = [request URL]; - if ([self isSpecialScheme:[url scheme]]) { - [self getSpecial:[url absoluteString]]; + if ([self getSpecial:[url absoluteString]]) return nil; - } if (!pushed_) { pushed_ = true; @@ -4312,10 +4408,25 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString return [self _addHeadersToRequest:request]; } +- (BOOL) isSpecialScheme:(NSString *)scheme { + return + [scheme isEqualToString:@"apptapp"] || + [scheme isEqualToString:@"cydia"] || + [scheme isEqualToString:@"mailto"] || + [scheme isEqualToString:@"tel"]; +} + - (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { if (request != nil) { - NSString *scheme = [[request URL] scheme]; - if ([self isSpecialScheme:scheme]) + NSURL *url = [request URL]; + NSString *scheme = [url scheme]; + NSString *absolute = [url absoluteString]; + if ( + [self isSpecialScheme:scheme] || + [absolute hasPrefix:@"http://ax.phobos.apple.com/"] || + [absolute hasPrefix:@"http://phobos.apple.com/"] || + [absolute hasPrefix:@"http://www.yahoo.com/watch?"] + ) return nil; } @@ -4354,13 +4465,15 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString title_ = nil; } - [self setTitle:@"Loading..."]; + [self setTitle:@"Loading"]; WebView *webview = [webview_ webView]; NSString *href = [webview mainFrameURL]; [urls_ addObject:[NSURL URLWithString:href]]; - CGRect webrect = [scroller_ frame]; + [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; + + CGRect webrect = [scroller_ bounds]; webrect.size.height = 0; [webview_ setFrame:webrect]; } @@ -4373,10 +4486,31 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } } +- (BOOL) webView:(WebView *)sender shouldScrollToPoint:(struct CGPoint)point forFrame:(WebFrame *)frame { + _trace(); + return [webview_ webView:sender shouldScrollToPoint:point forFrame:frame]; +} + +- (void) webView:(WebView *)sender didReceiveViewportArguments:(id)arguments forFrame:(WebFrame *)frame { + return [webview_ webView:sender didReceiveViewportArguments:arguments forFrame:frame]; +} + +- (void) webView:(WebView *)sender needsScrollNotifications:(id)notifications forFrame:(WebFrame *)frame { + return [webview_ webView:sender needsScrollNotifications:notifications forFrame:frame]; +} + +- (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { + return [webview_ webView:sender didCommitLoadForFrame:frame]; +} + +- (void) webView:(WebView *)sender didReceiveDocTypeForFrame:(WebFrame *)frame { + return [webview_ webView:sender didReceiveDocTypeForFrame:frame]; +} + - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - [self _finishLoading]; + if ([frame parentFrame] == nil) + [self _finishLoading]; + return [webview_ webView:sender didFinishLoadForFrame:frame]; } - (void) webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { @@ -4414,17 +4548,40 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString CGRect webrect = [scroller_ bounds]; webrect.size.height = 0; - webview_ = [[UIWebView alloc] initWithFrame:webrect]; - [scroller_ addSubview:webview_]; + webview_ = [Documents_ lastObject]; + if (webview_ != nil) { + webview_ = [webview_ retain]; + [Documents_ removeLastObject]; + [webview_ setFrame:webrect]; + } else { + webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect]; + + [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; + + [webview_ setTilingEnabled:YES]; + [webview_ setTileMinificationFilter:kCAFilterNearest]; + [webview_ setAutoresizes:YES]; + + [webview_ setViewportSize:CGSizeMake(980, -1) forDocumentTypes:0x10]; + [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x2]; + [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x8]; + + [webview_ _setDocumentType:0x4]; + + [webview_ setZoomsFocusedFormControl:YES]; + [webview_ setContentsPosition:7]; + [webview_ setEnabledGestures:0xa]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x4]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x7]; + [webview_ setSmoothsFonts:YES]; + } - [webview_ setTilingEnabled:YES]; - [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; - [webview_ setAutoresizes:YES]; [webview_ setDelegate:self]; - //[webview_ setEnabledGestures:2]; + [webview_ setGestureDelegate:self]; + [scroller_ addSubview:webview_]; CGSize indsize = [UIProgressIndicator defaultSizeForStyle:kUIProgressIndicatorStyleMediumWhite]; - indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 42, indsize.width, indsize.height)]; + indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 12, indsize.width, indsize.height)]; [indicator_ setStyle:kUIProgressIndicatorStyleMediumWhite]; Package *package([database_ packageWithName:@"cydia"]); @@ -4433,16 +4590,28 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [package installed] ]; + indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; + WebView *webview = [webview_ webView]; [webview setApplicationNameForUserAgent:application]; [webview setFrameLoadDelegate:self]; - [webview setResourceLoadDelegate:self]; + [webview setResourceLoadDelegate:indirect_]; [webview setUIDelegate:self]; + //[webview _setLayoutInterval:0.5]; + urls_ = [[NSMutableArray alloc] initWithCapacity:16]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [pinstripe setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } +- (void) didFinishGesturesInView:(UIView *)view forEvent:(id)event { + [webview_ redrawScaledDocument]; +} + - (void) _rightButtonClicked { reloading_ = true; [self reloadURL]; @@ -4465,10 +4634,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } - (void) setPageActive:(BOOL)active { - if (active) - [book_ addSubview:indicator_]; - else + if (!active) [indicator_ removeFromSuperview]; + else + [[book_ navigationBar] addSubview:indicator_]; } - (void) resetViewAnimated:(BOOL)animated { @@ -4485,11 +4654,14 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString ProgressDelegate > { _transient Database *database_; - UIView *overlay_; + UINavigationBar *overlay_; UIProgressIndicator *indicator_; UITextLabel *prompt_; UIProgressBar *progress_; + UINavigationButton *cancel_; bool updating_; + size_t received_; + NSTimeInterval last_; } - (id) initWithFrame:(CGRect)frame database:(Database *)database; @@ -4619,6 +4791,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [list_ setReusesTableCells:YES]; [self reloadData]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -4702,6 +4877,10 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString return [sections_ count] == 0 ? nil : editing_ ? @"Done" : @"Edit"; } +- (UINavigationButtonStyle) rightButtonStyle { + return editing_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal; +} + - (UIView *) accessoryView { return accessory_; } @@ -4812,6 +4991,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [table setReusesTableCells:YES]; [self reloadData]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -5056,7 +5238,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString initWithBook:book database:database title:nil - filter:@selector(isVisiblySearchedForBy:) + filter:@selector(isUnfilteredAndSearchedForBy:) with:nil ]; @@ -5071,7 +5253,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString CGRect area; area.origin.x = /*cnfrect.origin.x + cnfrect.size.width + 4 +*/ 10; - area.origin.y = 30; + area.origin.y = 1; area.size.width = #ifdef __OBJC2__ @@ -5096,7 +5278,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [traits setAutocorrectionType:1]; [traits setReturnKeyType:6]; - CGRect accrect = {{0, 6}, {6 + cnfrect.size.width + 6 + area.size.width + 6, area.size.height + 30}}; + CGRect accrect = {{0, 6}, {6 + cnfrect.size.width + 6 + area.size.width + 6, area.size.height}}; accessory_ = [[UIView alloc] initWithFrame:accrect]; [accessory_ addSubview:field_]; @@ -5106,6 +5288,9 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [configure setImage:[UIImage applicationImageNamed:@"advanced.png"]]; [configure addTarget:self action:@selector(configurePushed) forEvents:1]; [accessory_ addSubview:configure];*/ + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [table_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; } return self; } @@ -5171,6 +5356,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [indicator_ release]; [prompt_ release]; [progress_ release]; + [cancel_ release]; [super dealloc]; } @@ -5183,13 +5369,31 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } - (void) update { - [navbar_ setPrompt:@""]; - [navbar_ addSubview:overlay_]; + [UIView beginAnimations:nil context:NULL]; + + CGRect ovrframe = [overlay_ frame]; + ovrframe.origin.y = 0; + [overlay_ setFrame:ovrframe]; + + CGRect barframe = [navbar_ frame]; + barframe.origin.y += ovrframe.size.height; + [navbar_ setFrame:barframe]; + + CGRect trnframe = [transition_ frame]; + trnframe.origin.y += ovrframe.size.height; + trnframe.size.height -= ovrframe.size.height; + [transition_ setFrame:trnframe]; + + [UIView endAnimations]; + [indicator_ startAnimation]; - [prompt_ setText:@"Updating Database..."]; + [prompt_ setText:@"Updating Database"]; [progress_ setProgress:0]; + received_ = 0; + last_ = [NSDate timeIntervalSinceReferenceDate]; updating_ = true; + [overlay_ addSubview:cancel_]; [NSThread detachNewThreadSelector:@selector(_update) @@ -5201,11 +5405,26 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString - (void) _update_ { updating_ = false; - [overlay_ removeFromSuperview]; [indicator_ stopAnimation]; - [delegate_ reloadData]; - [self setPrompt:[NSString stringWithFormat:@"Last Updated: %@", GetLastUpdate()]]; + [UIView beginAnimations:nil context:NULL]; + + CGRect ovrframe = [overlay_ frame]; + ovrframe.origin.y = -ovrframe.size.height; + [overlay_ setFrame:ovrframe]; + + CGRect barframe = [navbar_ frame]; + barframe.origin.y -= ovrframe.size.height; + [navbar_ setFrame:barframe]; + + CGRect trnframe = [transition_ frame]; + trnframe.origin.y -= ovrframe.size.height; + trnframe.size.height += ovrframe.size.height; + [transition_ setFrame:trnframe]; + + [UIView commitAnimations]; + + [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0]; } - (id) initWithFrame:(CGRect)frame database:(Database *)database { @@ -5213,15 +5432,19 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString database_ = database; CGRect ovrrect = [navbar_ bounds]; - ovrrect.size.height = ([UINavigationBar defaultSizeWithPrompt].height - [UINavigationBar defaultSize].height); + ovrrect.size.height = [UINavigationBar defaultSize].height; + ovrrect.origin.y = -ovrrect.size.height; - overlay_ = [[UIView alloc] initWithFrame:ovrrect]; + overlay_ = [[UINavigationBar alloc] initWithFrame:ovrrect]; + [self addSubview:overlay_]; - bool ugly = [navbar_ _barStyle:NO] == 0; + [overlay_ setBarStyle:1]; + int barstyle = [overlay_ _barStyle:NO]; + bool ugly = barstyle == 0; UIProgressIndicatorStyle style = ugly ? - kUIProgressIndicatorStyleSmallBlack : - kUIProgressIndicatorStyleSmallWhite; + kUIProgressIndicatorStyleMediumBrown : + kUIProgressIndicatorStyleMediumWhite; CGSize indsize = [UIProgressIndicator defaultSizeForStyle:style]; unsigned indoffset = (ovrrect.size.height - indsize.height) / 2; @@ -5231,22 +5454,22 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString [indicator_ setStyle:style]; [overlay_ addSubview:indicator_]; - CGSize prmsize = {200, indsize.width + 4}; + CGSize prmsize = {215, indsize.height + 4}; CGRect prmrect = {{ indoffset * 2 + indsize.width, #ifdef __OBJC2__ -1 + #endif - (ovrrect.size.height - prmsize.height) / 2 + unsigned(ovrrect.size.height - prmsize.height) / 2 }, prmsize}; - UIFont *font = [UIFont systemFontOfSize:12]; + UIFont *font = [UIFont systemFontOfSize:15]; prompt_ = [[UITextLabel alloc] initWithFrame:prmrect]; - [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : White_)]]; - [prompt_ setBackgroundColor:[UIColor colorWithCGColor:Clear_]]; + [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]]; + [prompt_ setBackgroundColor:[UIColor clearColor]]; [prompt_ setFont:font]; [overlay_ addSubview:prompt_]; @@ -5261,9 +5484,25 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString progress_ = [[UIProgressBar alloc] initWithFrame:prgrect]; [progress_ setStyle:0]; [overlay_ addSubview:progress_]; + + cancel_ = [[UINavigationButton alloc] initWithTitle:@"Cancel" style:UINavigationButtonStyleHighlighted]; + [cancel_ addTarget:self action:@selector(_onCancel) forControlEvents:UIControlEventTouchUpInside]; + + CGRect frame = [cancel_ frame]; + frame.size.width = 65; + frame.origin.x = ovrrect.size.width - frame.size.width - 5; + frame.origin.y = (ovrrect.size.height - frame.size.height) / 2; + [cancel_ setFrame:frame]; + + [cancel_ setBarStyle:barstyle]; } return self; } +- (void) _onCancel { + updating_ = false; + [cancel_ removeFromSuperview]; +} + - (void) _update { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -5294,6 +5533,14 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString } - (void) setProgressPercent:(float)percent { + [self + performSelectorOnMainThread:@selector(_setProgressPercent:) + withObject:[NSNumber numberWithFloat:percent] + waitUntilDone:YES + ]; +} + +- (void) startProgress { } - (void) addProgressOutput:(NSString *)output { @@ -5304,12 +5551,26 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString ]; } +- (bool) isCancelling:(size_t)received { + NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; + if (received_ != received) { + received_ = received; + last_ = now; + } else if (now - last_ > 15) + return true; + return !updating_; +} + - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { [sheet dismiss]; } - (void) _setProgressTitle:(NSString *)title { - [prompt_ setText:[title stringByAppendingString:@"..."]]; + [prompt_ setText:title]; +} + +- (void) _setProgressPercent:(NSNumber *)percent { + [progress_ setProgress:[percent floatValue]]; } - (void) _addProgressOutput:(NSString *)output { @@ -5488,7 +5749,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString detachNewThreadSelector:@selector(update_) toTarget:self withObject:nil - title:@"Updating Sources..." + title:@"Updating Sources" ]; } @@ -5576,7 +5837,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString detachNewThreadSelector:@selector(perform) toTarget:database_ withObject:nil - title:@"Running..." + title:@"Running" ]; } @@ -5592,7 +5853,7 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString detachNewThreadSelector:@selector(bootstrap_) toTarget:self withObject:nil - title:@"Bootstrap Install..." + title:@"Bootstrap Install" ]; } @@ -5981,7 +6242,8 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL || readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL || readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL || - readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL + readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL /*|| + readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL*/ ) { [self setIdleTimerDisabled:YES]; @@ -6094,6 +6356,7 @@ int main(int argc, char *argv[]) { bootstrap_ = argc > 1 && strcmp(argv[1], "--bootstrap") == 0; + App_ = [[NSBundle mainBundle] bundlePath]; Home_ = NSHomeDirectory(); { @@ -6177,6 +6440,8 @@ int main(int argc, char *argv[]) { [Metadata_ setObject:Sources_ forKey:@"Sources"]; } + Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease]; + if (access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL); @@ -6189,7 +6454,7 @@ int main(int argc, char *argv[]) { Blue_.Set(space_, 0.2, 0.2, 1.0, 1.0); Blueish_.Set(space_, 0x19/255.f, 0x32/255.f, 0x50/255.f, 1.0); Black_.Set(space_, 0.0, 0.0, 0.0, 1.0); - Clear_.Set(space_, 0.0, 0.0, 0.0, 0.0); + Off_.Set(space_, 0.9, 0.9, 0.9, 1.0); Red_.Set(space_, 1.0, 0.0, 0.0, 1.0); White_.Set(space_, 1.0, 1.0, 1.0, 1.0); Gray_.Set(space_, 0.4, 0.4, 0.4, 1.0);