X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/7f96382b0182971b80c46c1c83f1c720c56eb39c..9b96fe8ebf4577688a0b4179edcc71384e15e505:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index aba5704b..eecc2be4 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -382,11 +382,13 @@ extern NSString * const kCAFilterNearest; #define lprintf(args...) fprintf(stderr, args) #define ForRelease 1 -#define ForSaurik (1 && !ForRelease) +#define ForSaurik (0 && !ForRelease) +#define LogBrowser (1 && !ForRelease) +#define ManualRefresh (1 && !ForRelease) #define ShowInternals (1 && !ForRelease) #define IgnoreInstall (0 && !ForRelease) #define RecycleWebViews 0 -#define AlwaysReload (1 && !ForRelease) +#define AlwaysReload (0 && !ForRelease) #if ForRelease #undef _trace @@ -657,6 +659,8 @@ class Pcre { - (NSString *) name; - (NSString *) address; +- (void) setAddress:(NSString *)address; + + (Address *) addressWithString:(NSString *)string; - (Address *) initWithString:(NSString *)string; @end @@ -678,6 +682,15 @@ class Pcre { return address_; } +- (void) setAddress:(NSString *)address { + if (address_ != nil) + [address_ autorelease]; + if (address == nil) + address_ = nil; + else + address_ = [address retain]; +} + + (Address *) addressWithString:(NSString *)string { return [[[Address alloc] initWithString:string] autorelease]; } @@ -762,12 +775,20 @@ static const float KeyboardTime_ = 0.3f; #define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb" #define NotifyConfig_ "/etc/notify.conf" +static bool Queuing_; + static CGColor Blue_; static CGColor Blueish_; static CGColor Black_; static CGColor Off_; static CGColor White_; static CGColor Gray_; +static CGColor Green_; +static CGColor Purple_; +static CGColor Purplish_; + +static UIColor *InstallingColor_; +static UIColor *RemovingColor_; static NSString *App_; static NSString *Home_; @@ -910,6 +931,7 @@ bool isSectionVisible(NSString *section) { @end @protocol CydiaDelegate +- (void) clearPackage:(Package *)package; - (void) installPackage:(Package *)package; - (void) removePackage:(Package *)package; - (void) slideUp:(UIActionSheet *)alert; @@ -1033,6 +1055,8 @@ class Progress : /* Database Interface {{{ */ @interface Database : NSObject { + unsigned era_; + pkgCacheFile cache_; pkgDepCache::Policy *policy_; pkgRecords *records_; @@ -1055,6 +1079,7 @@ class Progress : } + (Database *) sharedInstance; +- (unsigned) era; - (void) _readCydia:(NSNumber *)fd; - (void) _readStatus:(NSNumber *)fd; @@ -1092,6 +1117,7 @@ class Progress : NSString *description_; NSString *label_; NSString *origin_; + NSString *support_; NSString *uri_; NSString *distribution_; @@ -1108,6 +1134,8 @@ class Progress : - (NSComparisonResult) compareByNameAndType:(Source *)source; +- (NSString *) supportForPackage:(NSString *)package; + - (NSDictionary *) record; - (BOOL) trusted; @@ -1142,6 +1170,7 @@ class Progress : _clear(description_) _clear(label_) _clear(origin_) + _clear(support_) _clear(version_) _clear(defaultIcon_) _clear(record_) @@ -1195,6 +1224,8 @@ class Progress : label_ = [[NSString stringWithUTF8String:value.c_str()] retain]; else if (name == "Origin") origin_ = [[NSString stringWithUTF8String:value.c_str()] retain]; + else if (name == "Support") + support_ = [[NSString stringWithUTF8String:value.c_str()] retain]; else if (name == "Version") version_ = [[NSString stringWithUTF8String:value.c_str()] retain]; } @@ -1234,6 +1265,10 @@ class Progress : return [lhs compare:rhs options:LaxCompareOptions_]; } +- (NSString *) supportForPackage:(NSString *)package { + return support_ == nil ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package]; +} + - (NSDictionary *) record { return record_; } @@ -1325,6 +1360,8 @@ class Progress : /* }}} */ /* Package Class {{{ */ @interface Package : NSObject { + unsigned era_; + pkgCache::PkgIterator iterator_; _transient Database *database_; pkgCache::VerIterator version_; @@ -1334,6 +1371,7 @@ class Progress : bool cached_; NSString *section_; + bool essential_; NSString *latest_; NSString *installed_; @@ -1346,6 +1384,7 @@ class Progress : NSString *homepage_; Address *sponsor_; Address *author_; + NSString *support_; NSArray *tags_; NSString *role_; @@ -1396,6 +1435,8 @@ class Progress : - (NSString *) depiction; - (Address *) author; +- (NSString *) support; + - (NSArray *) files; - (NSArray *) relationships; - (NSArray *) warnings; @@ -1410,6 +1451,7 @@ class Progress : - (BOOL) hasTag:(NSString *)tag; - (NSString *) primaryPurpose; - (NSArray *) purposes; +- (bool) isCommercial; - (NSComparisonResult) compareByName:(Package *)package; - (NSComparisonResult) compareBySection:(Package *)package; @@ -1431,7 +1473,6 @@ class Progress : - (void) dealloc { if (source_ != nil) [source_ release]; - if (section_ != nil) [section_ release]; @@ -1453,6 +1494,8 @@ class Progress : [sponsor_ release]; if (author_ != nil) [author_ release]; + if (support_ != nil) + [support_ release]; if (tags_ != nil) [tags_ release]; if (role_ != nil) @@ -1464,8 +1507,19 @@ class Progress : [super dealloc]; } ++ (NSString *) webScriptNameForSelector:(SEL)selector { + if (selector == @selector(hasTag:)) + return @"hasTag"; + else + return nil; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return [self webScriptNameForSelector:selector] == nil; +} + + (NSArray *) _attributeKeys { - return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"name", @"purposes", @"section", @"size", @"source", @"sponsor", @"tagline", @"warnings", nil]; + return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"mode", @"name", @"purposes", @"section", @"size", @"source", @"sponsor", @"support", @"tagline", @"warnings", nil]; } - (NSArray *) attributeKeys { @@ -1477,7 +1531,11 @@ class Progress : } - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database { - if ((self = [super init]) != nil) { _profile(Package$initWithIterator) + if ((self = [super init]) != nil) { + _profile(Package$initWithIterator) + @synchronized (database) { + era_ = [database era]; + iterator_ = iterator; database_ = database; @@ -1544,6 +1602,7 @@ class Progress : {"depiction", &depiction_}, {"homepage", &homepage_}, {"website", &website}, + {"support", &support_}, {"sponsor", &sponsor}, {"author", &author}, {"tag", &tag}, @@ -1664,7 +1723,25 @@ class Progress : Changed_ = true; } _end - _end } return self; + + const char *section(iterator_.Section()); + if (section == NULL) + section_ = nil; + else { + NSString *name([[NSString stringWithUTF8String:section] stringByReplacingCharacter:' ' withCharacter:'_']); + + lookup: + if (NSDictionary *value = [SectionMap_ objectForKey:name]) + if (NSString *rename = [value objectForKey:@"Rename"]) { + name = rename; + goto lookup; + } + + section_ = [[name stringByReplacingCharacter:'_' withCharacter:' '] retain]; + } + + essential_ = (iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES; + } _end } return self; } + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database { @@ -1679,23 +1756,6 @@ class Progress : } - (NSString *) section { - if (section_ != nil) - return section_; - - const char *section = iterator_.Section(); - if (section == NULL) - return nil; - - NSString *name = [[NSString stringWithUTF8String:section] stringByReplacingCharacter:' ' withCharacter:'_']; - - lookup: - if (NSDictionary *value = [SectionMap_ objectForKey:name]) - if (NSString *rename = [value objectForKey:@"Rename"]) { - name = rename; - goto lookup; - } - - section_ = [[name stringByReplacingCharacter:'_' withCharacter:' '] retain]; return section_; } @@ -1815,7 +1875,7 @@ class Progress : } - (BOOL) essential { - return (iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES; + return essential_; } - (BOOL) broken { @@ -1859,14 +1919,16 @@ class Progress : else return @"Remove"; case pkgDepCache::ModeKeep: - if ((state.iFlags & pkgDepCache::AutoKept) != 0) - return nil; + if ((state.iFlags & pkgDepCache::ReInstall) != 0) + return @"Reinstall"; + /*else if ((state.iFlags & pkgDepCache::AutoKept) != 0) + return nil;*/ else return nil; case pkgDepCache::ModeInstall: - if ((state.iFlags & pkgDepCache::ReInstall) != 0) + /*if ((state.iFlags & pkgDepCache::ReInstall) != 0) return @"Reinstall"; - else switch (state.Status) { + else*/ switch (state.Status) { case -1: return @"Downgrade"; case 0: @@ -1928,6 +1990,10 @@ class Progress : return author_; } +- (NSString *) support { + return support_ != nil ? support_ : [[self source] supportForPackage:id_]; +} + - (NSArray *) files { NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", id_]; NSMutableArray *files = [NSMutableArray arrayWithCapacity:128]; @@ -2029,8 +2095,17 @@ class Progress : - (Source *) source { if (!cached_) { - source_ = file_.end() ? nil : [[database_ getSource:file_.File()] retain]; - cached_ = true; + @synchronized (database_) { + if ([database_ era] != era_ || file_.end()) + source_ = nil; + else { + source_ = [database_ getSource:file_.File()]; + if (source_ != nil) + [source_ retain]; + } + + cached_ = true; + } } return source_; @@ -2098,6 +2173,10 @@ class Progress : return [purposes count] == 0 ? nil : purposes; } +- (bool) isCommercial { + return [self hasTag:@"cydia::commercial"]; +} + - (NSComparisonResult) compareByName:(Package *)package { NSString *lhs = [self name]; NSString *rhs = [package name]; @@ -2158,6 +2237,12 @@ class Progress : return _not(uint32_t) - value.key; } +- (void) clear { + pkgProblemResolver *resolver = [database_ resolver]; + resolver->Clear(iterator_); + resolver->Protect(iterator_); +} + - (void) install { pkgProblemResolver *resolver = [database_ resolver]; resolver->Clear(iterator_); @@ -2315,6 +2400,10 @@ static NSArray *Finishes_; return instance; } +- (unsigned) era { + return era_; +} + - (void) dealloc { _assert(false); [super dealloc]; @@ -2559,6 +2648,10 @@ static NSArray *Finishes_; } - (void) reloadData { _pooled + @synchronized (self) { + ++era_; + } + _error->Discard(); delete list_; @@ -2946,6 +3039,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @protocol ConfirmationViewDelegate - (void) cancel; - (void) confirm; +- (void) queue; @end @interface ConfirmationView : BrowserView { @@ -3110,11 +3204,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Cancel"; } +- (id) rightButtonTitle { + return issues_ != nil ? nil : [super rightButtonTitle]; +} + - (id) _rightButtonTitle { #if AlwaysReload || IgnoreInstall - return @"Reload"; + return [super _rightButtonTitle]; #else - return issues_ == nil ? @"Confirm" : nil; + return @"Confirm"; #endif } @@ -3673,12 +3771,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* }}} */ /* Package Cell {{{ */ -@interface PackageCell : UISimpleTableCell { +@interface PackageCell : UITableCell { UIImage *icon_; NSString *name_; NSString *description_; + bool commercial_; NSString *source_; UIImage *badge_; + bool cached_; + Package *package_; #ifdef USE_BADGES UITextLabel *status_; #endif @@ -3718,6 +3819,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [badge_ release]; badge_ = nil; } + + [package_ release]; + package_ = nil; } - (void) dealloc { @@ -3748,6 +3852,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { name_ = [[package name] retain]; description_ = [[package tagline] retain]; + commercial_ = [package isCommercial]; + + package_ = [package retain]; NSString *label = nil; bool trusted = false; @@ -3788,6 +3895,37 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [status_ setText:nil]; } #endif + + cached_ = false; +} + +- (void) drawRect:(CGRect)rect { + if (!cached_) { + UIColor *color; + + if (NSString *mode = [package_ mode]) { + bool remove([mode isEqualToString:@"Remove"] || [mode isEqualToString:@"Purge"]); + color = remove ? RemovingColor_ : InstallingColor_; + } else + color = [UIColor whiteColor]; + + [self setBackgroundColor:color]; + cached_ = true; + } + + [super drawRect:rect]; +} + +- (void) drawBackgroundInRect:(CGRect)rect withFade:(float)fade { + if (fade == 0) { + CGContextRef context(UIGraphicsGetCurrentContext()); + [[self backgroundColor] set]; + CGRect back(rect); + back.size.height -= 1; + CGContextFillRect(context, back); + } + + [super drawBackgroundInRect:rect withFade:fade]; } - (void) drawContentInRect:(CGRect)rect selected:(BOOL)selected { @@ -3817,17 +3955,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UISetColor(White_); if (!selected) - UISetColor(Black_); + UISetColor(commercial_ ? Purple_ : Black_); [name_ drawAtPoint:CGPointMake(48, 8) forWidth:240 withFont:Font18Bold_ ellipsis:2]; [source_ drawAtPoint:CGPointMake(58, 29) forWidth:225 withFont:Font12_ ellipsis:2]; if (!selected) - UISetColor(Gray_); + UISetColor(commercial_ ? Purplish_ : Gray_); [description_ drawAtPoint:CGPointMake(12, 46) forWidth:280 withFont:Font14_ ellipsis:2]; [super drawContentInRect:rect selected:selected]; } +- (void) setSelected:(BOOL)selected withFade:(BOOL)fade { + cached_ = false; + [super setSelected:selected withFade:fade]; +} + + (int) heightForPackage:(Package *)package { NSString *tagline([package tagline]); int height = tagline == nil || [tagline length] == 0 ? -17 : 0; @@ -4090,6 +4233,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _transient Database *database_; Package *package_; NSString *name_; + bool commercial_; NSMutableArray *buttons_; } @@ -4110,7 +4254,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) _clickButtonWithName:(NSString *)name { - if ([name isEqualToString:@"Install"]) + if ([name isEqualToString:@"Clear"]) + [delegate_ clearPackage:package_]; + else if ([name isEqualToString:@"Install"]) [delegate_ installPackage:package_]; else if ([name isEqualToString:@"Reinstall"]) [delegate_ installPackage:package_]; @@ -4147,14 +4293,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (bool) _allowJavaScriptPanel { - return false; + return commercial_; } #if !AlwaysReload -- (void) _rightButtonClicked { - /*[super _rightButtonClicked]; - return;*/ - +- (void) __rightButtonClicked { int count = [buttons_ count]; _assert(count != 0); @@ -4168,12 +4311,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [delegate_ slideUp:[[[UIActionSheet alloc] initWithTitle:nil buttons:buttons - defaultButtonIndex:2 + defaultButtonIndex:([buttons count] - 1) delegate:self context:@"modify" ] autorelease]]; } } + +- (void) _rightButtonClicked { + if (commercial_) + [super _rightButtonClicked]; + else + [self __rightButtonClicked]; +} #endif - (id) _rightButtonTitle { @@ -4208,9 +4358,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (package != nil) { package_ = [package retain]; name_ = [[package id] retain]; + commercial_ = [package isCommercial]; [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]]; + if ([package_ mode] != nil) + [buttons_ addObject:@"Clear"]; if ([package_ source] == nil); else if ([package_ upgradableAndEssential:NO]) [buttons_ addObject:@"Upgrade"]; @@ -4223,8 +4376,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } -- (bool) _loading { - return false; +- (bool) isLoading { + return commercial_ ? [super isLoading] : false; } - (void) reloadData { @@ -5093,7 +5246,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ] autorelease]; [sheet setBodyText: - @"Copyright (C) 2008\n" + @"Copyright (C) 2008-2009\n" "Jay Freeman (saurik)\n" "saurik@saurik.com\n" "http://www.saurik.com/\n" @@ -5138,11 +5291,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #if !AlwaysReload - (id) _rightButtonTitle { - return nil; + return Queuing_ ? @"Queue" : nil; +} + +- (UINavigationButtonStyle) rightButtonStyle { + return Queuing_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal; +} + +- (void) _rightButtonClicked { + [delegate_ queue]; } #endif -- (bool) _loading { +- (bool) isLoading { return false; } @@ -5864,10 +6025,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame)) { last = seen; - NSString *name(seen == nil ? [@"n/a ?" retain] : (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen)); + NSString *name; + if (seen == nil) + name = @"unknown?"; + else { + name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen); + [name autorelease]; + } + + name = [@"New at " stringByAppendingString:name]; section = [[[Section alloc] initWithName:name row:offset] autorelease]; [sections_ addObject:section]; - [name release]; } [section addToCount]; @@ -6514,7 +6682,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSString *badge([[NSNumber numberWithInt:changes] stringValue]); [buttonbar_ setBadgeValue:badge forButton:3]; if ([buttonbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)]) - [buttonbar_ setBadgeAnimated:YES forButton:3]; + [buttonbar_ setBadgeAnimated:([essential_ count] != 0) forButton:3]; [self setApplicationBadge:badge]; } else { [buttonbar_ setBadgeValue:nil forButton:3]; @@ -6523,11 +6691,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self removeApplicationBadge]; } + Queuing_ = false; + [buttonbar_ setBadgeValue:nil forButton:4]; + [self updateData]; // XXX: what is this line of code for? if ([packages count] == 0); - else if (Loaded_) loaded: + else if (Loaded_ || ManualRefresh) loaded: [self _loaded]; else { Loaded_ = YES; @@ -6633,6 +6804,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self popUpBook:confirm_]; } +- (void) queue { + @synchronized (self) { + [self perform]; + } +} + +- (void) clearPackage:(Package *)package { + @synchronized (self) { + [package clear]; + [self resolve]; + [self perform]; + } +} + - (void) installPackage:(Package *)package { @synchronized (self) { [package install]; @@ -6657,8 +6842,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) cancel { + [self slideUp:[[[UIActionSheet alloc] + initWithTitle:nil + buttons:[NSArray arrayWithObjects:@"Continue Queuing", @"Cancel and Clear", nil] + defaultButtonIndex:1 + delegate:self + context:@"cancel" + ] autorelease]]; +} + +- (void) complete { @synchronized (self) { [self _reloadData]; + if (confirm_ != nil) { [confirm_ release]; confirm_ = nil; @@ -6700,7 +6896,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [confirm_ popFromSuperviewAnimated:NO]; } - [self cancel]; + [self complete]; } - (void) setPage:(RVPage *)page { @@ -6908,7 +7104,39 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ([context isEqualToString:@"missing"]) [sheet dismiss]; - else if ([context isEqualToString:@"fixhalf"]) { + else if ([context isEqualToString:@"cancel"]) { + bool clear; + + switch (button) { + case 1: + clear = false; + break; + + case 2: + clear = true; + break; + + default: + _assert(false); + } + + [sheet dismiss]; + + @synchronized (self) { + if (clear) + [self _reloadData]; + else { + Queuing_ = true; + [buttonbar_ setBadgeValue:@"Q'd" forButton:4]; + [book_ reloadData]; + } + + if (confirm_ != nil) { + [confirm_ release]; + confirm_ = nil; + } + } + } else if ([context isEqualToString:@"fixhalf"]) { switch (button) { case 1: @synchronized (self) { @@ -7413,6 +7641,19 @@ int main(int argc, char *argv[]) { _pooled Off_.Set(space_, 0.9, 0.9, 0.9, 1.0); White_.Set(space_, 1.0, 1.0, 1.0, 1.0); Gray_.Set(space_, 0.4, 0.4, 0.4, 1.0); + Green_.Set(space_, 0.0, 0.5, 0.0, 1.0); + Purple_.Set(space_, 0.0, 0.0, 0.7, 1.0); + Purplish_.Set(space_, 0.4, 0.4, 0.8, 1.0); + /*Purple_.Set(space_, 1.0, 0.3, 0.0, 1.0); + Purplish_.Set(space_, 1.0, 0.6, 0.4, 1.0); ORANGE */ + /*Purple_.Set(space_, 1.0, 0.5, 0.0, 1.0); + Purplish_.Set(space_, 1.0, 0.7, 0.2, 1.0); ORANGISH */ + /*Purple_.Set(space_, 0.5, 0.0, 0.7, 1.0); + Purplish_.Set(space_, 0.7, 0.4, 0.8, 1.0); PURPLE */ + +//.93 + InstallingColor_ = [UIColor colorWithRed:0.88f green:1.00f blue:0.88f alpha:1.00f]; + RemovingColor_ = [UIColor colorWithRed:1.00f green:0.88f blue:0.88f alpha:1.00f]; Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];