X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/5fe2bcc666ee632689fded66cca7dd523d3a2728..3f88f20507c0870b890db839c17186d6928fae29:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index d959185e..900e76ed 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -38,7 +38,6 @@ #include #endif -#include #include #include @@ -55,6 +54,7 @@ #include #include +#include #include #include @@ -727,7 +727,6 @@ static CGColorSpaceRef space_; static NSDictionary *SectionMap_; static NSMutableDictionary *Metadata_; static _transient NSMutableDictionary *Settings_; -static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; static _transient NSMutableDictionary *Values_; static _transient NSMutableDictionary *Sections_; @@ -864,6 +863,16 @@ static NSString *CYHex(NSData *data, bool reverse = false) { @class CYPackageController; +@protocol SourceDelegate +- (void) setFetch:(NSNumber *)fetch; +@end + +@protocol FetchDelegate +- (bool) isSourceCancelled; +- (void) startSourceFetch:(NSString *)uri; +- (void) stopSourceFetch:(NSString *)uri; +@end + @protocol CydiaDelegate - (void) returnToCydia; - (void) saveState; @@ -875,6 +884,7 @@ static NSString *CYHex(NSData *data, bool reverse = false) { - (void) removePackage:(Package *)package; - (void) beginUpdate; - (BOOL) updating; +- (bool) requestUpdate; - (void) distUpgrade; - (void) loadData; - (void) updateData; @@ -882,7 +892,6 @@ static NSString *CYHex(NSData *data, bool reverse = false) { - (void) syncData; - (void) addSource:(NSDictionary *)source; - (void) addTrivialSource:(NSString *)href; -- (void) showSettings; - (UIProgressHUD *) addProgressHUD; - (void) removeProgressHUD:(UIProgressHUD *)hud; - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item; @@ -890,29 +899,19 @@ static NSString *CYHex(NSData *data, bool reverse = false) { @end /* }}} */ -/* Status Delegation {{{ */ -class Status : +/* CancelStatus {{{ */ +class CancelStatus : public pkgAcquireStatus { private: - _transient NSObject *delegate_; bool cancelled_; public: - Status() : - delegate_(nil), + CancelStatus() : cancelled_(false) { } - void setDelegate(NSObject *delegate) { - delegate_ = delegate; - } - - NSObject *getDelegate() const { - return delegate_; - } - virtual bool MediaChange(std::string media, std::string drive) { return false; } @@ -921,6 +920,39 @@ class Status : Done(item); } + virtual bool Pulse_(pkgAcquire *Owner) = 0; + + virtual bool Pulse(pkgAcquire *Owner) { + if (pkgAcquireStatus::Pulse(Owner) && Pulse_(Owner)) + return true; + else { + cancelled_ = true; + return false; + } + } + + _finline bool WasCancelled() const { + return cancelled_; + } +}; +/* }}} */ +/* DelegateStatus {{{ */ +class CydiaStatus : + public CancelStatus +{ + private: + _transient NSObject *delegate_; + + public: + CydiaStatus() : + delegate_(nil) + { + } + + void setDelegate(NSObject *delegate) { + delegate_ = delegate; + } + virtual void Fetch(pkgAcquire::ItemDesc &item) { NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]); CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), name] ofType:kCydiaProgressEventTypeStatus forItem:item]); @@ -948,9 +980,7 @@ class Status : [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } - virtual bool Pulse(pkgAcquire *Owner) { - bool value = pkgAcquireStatus::Pulse(Owner); - + virtual bool Pulse_(pkgAcquire *Owner) { double percent( double(CurrentBytes + CurrentItems) / double(TotalBytes + TotalItems) @@ -964,16 +994,7 @@ class Status : [NSNumber numberWithDouble:CurrentCPS], @"Speed", nil] waitUntilDone:YES]; - if (value && ![delegate_ isProgressCancelled]) - return true; - else { - cancelled_ = true; - return false; - } - } - - _finline bool WasCancelled() const { - return cancelled_; + return ![delegate_ isProgressCancelled]; } virtual void Start() { @@ -1014,7 +1035,7 @@ typedef std::map< unsigned long, _H > SourceMap; _transient NSObject *delegate_; _transient NSObject *progress_; - Status status_; + CydiaStatus status_; int cydiafd_; int statusfd_; @@ -1051,7 +1072,7 @@ typedef std::map< unsigned long, _H > SourceMap; - (bool) upgrade; - (void) update; -- (void) updateWithStatus:(Status &)status; +- (void) updateWithStatus:(CancelStatus &)status; - (void) setDelegate:(NSObject *)delegate; @@ -1059,11 +1080,61 @@ typedef std::map< unsigned long, _H > SourceMap; - (NSObject *) progressDelegate; - (Source *) getSource:(pkgCache::PkgFileIterator)file; +- (void) setFetch:(bool)fetch forURI:(const char *)uri; +- (void) resetFetch; - (NSString *) mappedSectionForPointer:(const char *)pointer; @end /* }}} */ +/* SourceStatus {{{ */ +class SourceStatus : + public CancelStatus +{ + private: + _transient NSObject *delegate_; + _transient Database *database_; + + public: + SourceStatus(NSObject *delegate, Database *database) : + delegate_(delegate), + database_(database) + { + } + + void Set(bool fetch, pkgAcquire::ItemDesc &desc) { + desc.Owner->ID = 0; + [database_ setFetch:fetch forURI:desc.Owner->DescURI().c_str()]; + } + + virtual void Fetch(pkgAcquire::ItemDesc &desc) { + Set(true, desc); + } + + virtual void Done(pkgAcquire::ItemDesc &desc) { + Set(false, desc); + } + + virtual void Fail(pkgAcquire::ItemDesc &desc) { + Set(false, desc); + } + + virtual bool Pulse_(pkgAcquire *Owner) { + for (pkgAcquire::ItemCIterator item = Owner->ItemsBegin(); item != Owner->ItemsEnd(); ++item) + if ((*item)->ID != 0); + else if ((*item)->Status == pkgAcquire::Item::StatIdle) { + (*item)->ID = 1; + [database_ setFetch:true forURI:(*item)->DescURI().c_str()]; + } else (*item)->ID = 0; + return ![delegate_ isSourceCancelled]; + } + + virtual void Stop() { + pkgAcquireStatus::Stop(); + [database_ resetFetch]; + } +}; +/* }}} */ /* ProgressEvent Implementation {{{ */ @implementation CydiaProgressEvent @@ -1328,6 +1399,10 @@ static void PackageImport(const void *key, const void *value, void *context) { _H record_; BOOL trusted_; + + std::set fetches_; + std::set files_; + _transient NSObject *delegate_; } - (Source *) initWithMetaIndex:(metaIndex *)index forDatabase:(Database *)database inPool:(apr_pool_t *)pool; @@ -1357,6 +1432,9 @@ static void PackageImport(const void *key, const void *value, void *context) { - (NSString *) defaultIcon; - (NSURL *) iconURL; +- (void) setFetch:(bool)fetch forURI:(const char *)uri; +- (void) resetFetch; + @end @implementation Source @@ -1419,7 +1497,21 @@ static void PackageImport(const void *key, const void *value, void *context) { debReleaseIndex *dindex(dynamic_cast(index)); if (dindex != NULL) { - base_.set(pool, dindex->MetaIndexURI("")); + std::string file(dindex->MetaIndexURI("")); + base_.set(pool, file); + + pkgAcquire acquire; + dindex->GetIndexes(&acquire, true); + for (pkgAcquire::ItemIterator item(acquire.ItemsBegin()); item != acquire.ItemsEnd(); item++) { + std::string file((*item)->DescURI()); + files_.insert(file); + if (file.length() < sizeof("Packages.bz2") || file.substr(file.length() - sizeof("Packages.bz2")) != "/Packages.bz2") + continue; + file = file.substr(0, file.length() - 4); + files_.insert(file); + files_.insert(file + ".gz"); + files_.insert(file + "Index"); + } FileFd fd; if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly)) @@ -1655,6 +1747,31 @@ static void PackageImport(const void *key, const void *value, void *context) { return defaultIcon_; } +- (void) setDelegate:(NSObject *)delegate { + delegate_ = delegate; +} + +- (bool) fetch { + return !fetches_.empty(); +} + +- (void) setFetch:(bool)fetch forURI:(const char *)uri { + if (!fetch) { + if (fetches_.erase(uri) == 0) + return; + } else if (files_.find(uri) == files_.end()) + return; + else if (!fetches_.insert(uri).second) + return; + + [delegate_ performSelectorOnMainThread:@selector(setFetch:) withObject:[NSNumber numberWithBool:[self fetch]] waitUntilDone:NO]; +} + +- (void) resetFetch { + fetches_.clear(); + [delegate_ performSelectorOnMainThread:@selector(setFetch:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:NO]; +} + @end /* }}} */ /* CydiaOperation Class {{{ */ @@ -1926,7 +2043,6 @@ struct ParsedPackage { - (uint32_t) rank; - (BOOL) matches:(NSArray *)query; -- (bool) hasSupportingRole; - (BOOL) hasTag:(NSString *)tag; - (NSString *) primaryPurpose; - (NSArray *) purposes; @@ -1944,7 +2060,7 @@ struct ParsedPackage { - (bool) isUnfilteredAndSearchedForBy:(NSArray *)query; - (bool) isUnfilteredAndSelectedForBy:(NSString *)search; - (bool) isInstalledAndUnfiltered:(NSNumber *)number; -- (bool) isVisibleInSection:(NSString *)section; +- (bool) isVisibleInSection:(NSString *)section source:(Source *)source; - (bool) isVisibleInSource:(Source *)source; @end @@ -2040,9 +2156,9 @@ CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) { CFStringRef lhn(lhi), rhn(rhi); if (lhn == NULL) - return rhn == NULL ? NSOrderedSame : NSOrderedAscending; + return rhn == NULL ? kCFCompareEqualTo : kCFCompareLessThan; else if (rhn == NULL) - return NSOrderedDescending; + return kCFCompareGreaterThan; _profile(PackageNameCompare$NumbersLast) if (!lhi.empty() && !rhi.empty()) { @@ -2050,7 +2166,7 @@ CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) { UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0)); bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet)); if (lha != CFUniCharIsMemberOf(rhc, kCFUniCharLetterCharacterSet)) - return lha ? NSOrderedAscending : NSOrderedDescending; + return lha ? kCFCompareLessThan : kCFCompareGreaterThan; } _end @@ -2070,7 +2186,7 @@ struct PackageNameOrdering : std::binary_function { _finline bool operator ()(Package *lhs, Package *rhs) const { - return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending; + return PackageNameCompare(lhs, rhs, NULL) == kCFCompareLessThan; } }; @@ -2602,8 +2718,8 @@ struct PackageNameOrdering : return false; _end - _profile(Package$unfiltered$hasSupportingRole) - if (_unlikely(![self hasSupportingRole])) + _profile(Package$unfiltered$role) + if (_unlikely(role_ > 3)) return false; _end @@ -2644,7 +2760,7 @@ struct PackageNameOrdering : - (BOOL) hasMode { @synchronized (database_) { if ([database_ era] != era_ || iterator_.end()) - return nil; + return NO; pkgDepCache::StateCache &state([database_ cache][iterator_]); return state.Mode != pkgDepCache::ModeKeep; @@ -2939,24 +3055,6 @@ struct PackageNameOrdering : return rank_ != 0; } -- (bool) hasSupportingRole { - if (role_ == 0) - return true; - if (role_ == 1) - return true; - if ([Role_ isEqualToString:@"User"]) - return false; - if (role_ == 2) - return true; - if ([Role_ isEqualToString:@"Hacker"]) - return false; - if (role_ == 3) - return true; - if ([Role_ isEqualToString:@"Developer"]) - return false; - _assert(false); -} - - (NSArray *) tags { return tags_; } @@ -3076,16 +3174,19 @@ struct PackageNameOrdering : } - (bool) isInstalledAndUnfiltered:(NSNumber *)number { - return ![self uninstalled] && (![number boolValue] && role_ != 7 || [self unfiltered]); + return ![self uninstalled] && role_ <= ([number boolValue] ? 1 : 3); } -- (bool) isVisibleInSection:(NSString *)name { +- (bool) isVisibleInSection:(NSString *)name source:(Source *)source { NSString *section([self section]); return ( name == nil || section == nil && [name length] == 0 || [name isEqualToString:section] + ) && ( + source == nil || + [self source] == source ) && [self visible]; } @@ -3827,7 +3928,7 @@ class CydiaLogCleaner : [self updateWithStatus:status_]; } -- (void) updateWithStatus:(Status &)status { +- (void) updateWithStatus:(CancelStatus &)status { NSString *title(UCLocalize("REFRESHING_DATA")); pkgSourceList list; @@ -3871,6 +3972,16 @@ class CydiaLogCleaner : return i == sourceMap_.end() ? nil : i->second; } +- (void) setFetch:(bool)fetch forURI:(const char *)uri { + for (Source *source in (id) sourceList_) + [source setFetch:fetch forURI:uri]; +} + +- (void) resetFetch { + for (Source *source in (id) sourceList_) + [source resetFetch]; +} + - (NSString *) mappedSectionForPointer:(const char *)section { _H *mapped; @@ -4082,7 +4193,7 @@ static _H Diversions_; } - (NSString *) role { - return (id) Role_ ?: [NSNull null]; + return (id) [NSNull null]; } - (NSString *) model { @@ -4914,7 +5025,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { reason = @"virtual"; } - NSDictionary *version(start.TargetVer() == 0 ? [NSNull null] : [NSDictionary dictionaryWithObjectsAndKeys: + NSDictionary *version(start.TargetVer() == 0 ? (NSDictionary *) [NSNull null] : [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithUTF8String:start.CompType()], @"operator", [NSString stringWithUTF8String:start.TargetVer()], @"value", nil]); @@ -5649,7 +5760,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!highlighted) UISetColor(commercial_ ? Purple_ : Black_); - [name_ drawAtPoint:CGPointMake(36, 8) forWidth:(width - (placard_ == nil ? 68 : 94)) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; + [name_ drawAtPoint:CGPointMake(36, 8) forWidth:(width - (placard_ == nil ? 68 : 94)) withFont:Font18Bold_ lineBreakMode:NSLineBreakByTruncatingTail]; if (placard_ != nil) [placard_ drawAtPoint:CGPointMake(width - 52, 11)]; @@ -5692,12 +5803,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!highlighted) UISetColor(commercial_ ? Purple_ : Black_); - [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; - [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; + [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ lineBreakMode:NSLineBreakByTruncatingTail]; + [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:NSLineBreakByTruncatingTail]; if (!highlighted) UISetColor(commercial_ ? Purplish_ : Gray_); - [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation]; + [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ lineBreakMode:NSLineBreakByTruncatingTail]; if (placard_ != nil) [placard_ drawAtPoint:CGPointMake(width - 52, 9)]; @@ -5783,7 +5894,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { section_ = [section localized]; name_ = section_ == nil || [section_ length] == 0 ? UCLocalize("NO_SECTION") : (NSString *) section_; - count_ = [NSString stringWithFormat:@"%d", [section count]]; + count_ = [NSString stringWithFormat:@"%zd", [section count]]; if (editing_) [switch_ setOn:(isSectionVisible(basic_) ? 1 : 0) animated:NO]; @@ -5820,7 +5931,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!highlighted) UISetColor(Black_); - [name_ drawAtPoint:CGPointMake(48, 12) forWidth:(width - 58) withFont:Font18_ lineBreakMode:UILineBreakModeTailTruncation]; + [name_ drawAtPoint:CGPointMake(48, 12) forWidth:(width - 58) withFont:Font18_ lineBreakMode:NSLineBreakByTruncatingTail]; CGSize size = [count_ sizeWithFont:Font14_]; @@ -6520,10 +6631,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { SEL filter_; IMP imp_; _H object_; + _H stuff_; } - (void) setObject:(id)object; +- (void) setStuff:(id)object; +- (void) setObject:(id)object andStuff:(id)stuff; + - (void) setObject:(id)object forFilter:(SEL)filter; +- (void) setObject:(id)object andStuff:(id)stuff forFilter:(SEL)filter; - (SEL) filter; - (void) setFilter:(SEL)filter; @@ -6554,10 +6670,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { object_ = object; } } +- (void) setStuff:(id)stuff { +@synchronized (self) { + stuff_ = stuff; +} } + +- (void) setObject:(id)object andStuff:(id)stuff { +@synchronized (self) { + object_ = object; + stuff_ = stuff; +} } + - (void) setObject:(id)object forFilter:(SEL)filter { @synchronized (self) { [self setFilter:filter]; - [self setObject:object]; + object_ = object; +} } + +- (void) setObject:(id)object andStuff:(id)stuff forFilter:(SEL)filter { +@synchronized (self) { + [self setFilter:filter]; + object_ = object; + stuff_ = stuff; } } - (NSMutableArray *) _reloadPackages { @@ -6570,16 +6704,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { IMP imp; SEL filter; _H object; + _H stuff; @synchronized (self) { imp = imp_; filter = filter_; object = object_; + stuff = stuff_; } _profile(PackageTable$reloadData$Filter) for (Package *package in packages) - if ([package valid] && (*reinterpret_cast(imp))(package, filter, object)) + if ([package valid] && (*reinterpret_cast(imp))(package, filter, object, stuff)) [filtered addObject:package]; _end @@ -6589,7 +6725,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { if ((self = [super initWithDatabase:database title:title]) != nil) { [self setFilter:filter]; - [self setObject:object]; + object_ = object; + } return self; +} + +- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object with:(id)stuff { + if ((self = [super initWithDatabase:database title:title]) != nil) { + [self setFilter:filter]; + object_ = object; + stuff_ = stuff; } return self; } @@ -6665,156 +6809,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi ] autorelease]; } -@end -/* }}} */ -/* Manage Controller {{{ */ -@interface ManageController : CydiaWebViewController { -} - -- (void) queueStatusDidChange; - -@end - -@implementation ManageController - -- (id) init { - if ((self = [super init]) != nil) { - [self setURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]]; - } return self; -} - -- (NSURL *) navigationURL { - return [NSURL URLWithString:@"cydia://manage"]; -} - -- (UIBarButtonItem *) leftButton { - return [[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("SETTINGS") - style:UIBarButtonItemStylePlain - target:self - action:@selector(settingsButtonClicked) - ] autorelease]; -} - -- (void) settingsButtonClicked { - [delegate_ showSettings]; -} - -- (void) queueButtonClicked { - [delegate_ queue]; -} - -- (UIBarButtonItem *) rightButton { - return Queuing_ ? [[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("QUEUE") - style:UIBarButtonItemStyleDone - target:self - action:@selector(queueButtonClicked) - ] autorelease] : nil; -} - -- (void) queueStatusDidChange { - [self applyRightButton]; -} - -- (bool) isLoading { - return !Queuing_ && [super isLoading]; -} - -@end -/* }}} */ - -/* Refresh Bar {{{ */ -@interface RefreshBar : UINavigationBar { - _H indicator_; - _H prompt_; - _H cancel_; -} - -@end - -@implementation RefreshBar - -- (void) positionViews { - CGRect frame = [cancel_ frame]; - frame.size = [cancel_ sizeThatFits:frame.size]; - frame.origin.x = [self frame].size.width - frame.size.width - 5; - frame.origin.y = ([self frame].size.height - frame.size.height) / 2; - [cancel_ setFrame:frame]; - - CGSize indsize([UIProgressIndicator defaultSizeForStyle:[indicator_ activityIndicatorViewStyle]]); - unsigned indoffset = ([self frame].size.height - indsize.height) / 2; - CGRect indrect = {{indoffset, indoffset}, indsize}; - [indicator_ setFrame:indrect]; - - CGSize prmsize = {215, indsize.height + 4}; - CGRect prmrect = {{ - indoffset * 2 + indsize.width, - unsigned([self frame].size.height - prmsize.height) / 2 - 1 - }, prmsize}; - [prompt_ setFrame:prmrect]; -} - -- (void) setFrame:(CGRect)frame { - [super setFrame:frame]; - [self positionViews]; -} - -- (id) initWithFrame:(CGRect)frame delegate:(id)delegate { - if ((self = [super initWithFrame:frame]) != nil) { - [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; - - [self setBarStyle:UIBarStyleBlack]; - - UIBarStyle barstyle([self _barStyle:NO]); - bool ugly(barstyle == UIBarStyleDefault); - - UIProgressIndicatorStyle style = ugly ? - UIProgressIndicatorStyleMediumBrown : - UIProgressIndicatorStyleMediumWhite; - - indicator_ = [[[UIProgressIndicator alloc] initWithFrame:CGRectZero] autorelease]; - [(UIProgressIndicator *) indicator_ setStyle:style]; - [indicator_ startAnimation]; - [self addSubview:indicator_]; - - prompt_ = [[[UITextLabel alloc] initWithFrame:CGRectZero] autorelease]; - [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]]; - [prompt_ setBackgroundColor:[UIColor clearColor]]; - [prompt_ setFont:[UIFont systemFontOfSize:15]]; - [self addSubview:prompt_]; - - cancel_ = [[[UINavigationButton alloc] initWithTitle:UCLocalize("CANCEL") style:UINavigationButtonStyleHighlighted] autorelease]; - [cancel_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - [cancel_ addTarget:delegate action:@selector(cancelPressed) forControlEvents:UIControlEventTouchUpInside]; - [cancel_ setBarStyle:barstyle]; - - [self positionViews]; - } return self; -} - -- (void) setCancellable:(bool)cancellable { - if (cancellable) - [self addSubview:cancel_]; - else - [cancel_ removeFromSuperview]; -} - -- (void) start { - [prompt_ setText:UCLocalize("UPDATING_DATABASE")]; -} - -- (void) stop { - [self setCancellable:NO]; -} - -- (void) setPrompt:(NSString *)prompt { - [prompt_ setText:prompt]; -} - -- (void) setProgress:(float)progress { -} - @end /* }}} */ @@ -6830,21 +6824,19 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi /* Cydia Tab Bar Controller {{{ */ @interface CydiaTabBarController : CyteTabBarController < UITabBarControllerDelegate, - ProgressDelegate + FetchDelegate > { _transient Database *database_; - _H refreshbar_; - bool dropped_; + _H indicator_; + bool updating_; // XXX: ok, "updatedelegate_"?... _transient NSObject *updatedelegate_; } - (NSArray *) navigationURLCollection; -- (void) dropBar:(BOOL)animated; - (void) beginUpdate; -- (void) raiseBar:(BOOL)animated; - (BOOL) updating; @end @@ -6864,21 +6856,15 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi return items; } -- (void) dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; [self setDelegate:self]; - [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; + indicator_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteTiny] autorelease]; + [indicator_ setOrigin:CGPointMake(kCFCoreFoundationVersionNumber >= 800 ? 2 : 4, 2)]; - refreshbar_ = [[[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self] autorelease]; + [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; } return self; } @@ -6887,8 +6873,17 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi } - (void) beginUpdate { - [(RefreshBar *) refreshbar_ start]; - [self dropBar:YES]; + if (updating_) + return; + + UIViewController *controller([[self viewControllers] objectAtIndex:1]); + UITabBarItem *item([controller tabBarItem]); + + [item setBadgeValue:@""]; + UIView *badge(MSHookIvar([item view], "_badge")); + + [indicator_ startAnimating]; + [badge addSubview:indicator_]; [updatedelegate_ retainNetworkActivityIndicator]; updating_ = true; @@ -6903,8 +6898,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi - (void) performUpdate { NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); - Status status; - status.setDelegate(self); + SourceStatus status(self, database_); [database_ updateWithStatus:status]; [self @@ -6920,8 +6914,11 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi updating_ = false; [updatedelegate_ releaseNetworkActivityIndicator]; - [self raiseBar:YES]; - [refreshbar_ stop]; + UIViewController *controller([[self viewControllers] objectAtIndex:1]); + [[controller tabBarItem] setBadgeValue:nil]; + + [indicator_ removeFromSuperview]; + [indicator_ stopAnimating]; [updatedelegate_ performSelector:selector withObject:nil afterDelay:0]; } @@ -6944,25 +6941,14 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi return updating_; } -- (void) addProgressEvent:(CydiaProgressEvent *)event { - [refreshbar_ setPrompt:[event compoundMessage]]; -} - -- (bool) isProgressCancelled { +- (bool) isSourceCancelled { return !updating_; } -- (void) setProgressCancellable:(NSNumber *)cancellable { - [refreshbar_ setCancellable:(updating_ && [cancellable boolValue])]; -} - -- (void) setProgressPercent:(NSNumber *)percent { - [refreshbar_ setProgress:[percent floatValue]]; +- (void) startSourceFetch:(NSString *)uri { } -- (void) setProgressStatus:(NSDictionary *)status { - if (status != nil) - [self setProgressPercent:[status objectForKey:@"Percent"]]; +- (void) stopSourceFetch:(NSString *)uri { } - (void) setUpdateDelegate:(id)delegate { @@ -6978,123 +6964,36 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi return [[[self _transitionView] superview] superview]; } -- (void) dropBar:(BOOL)animated { - if (dropped_) - return; - dropped_ = true; - - UIView *transition([self transitionView]); - [[self view] addSubview:refreshbar_]; +@end +/* }}} */ - CGRect barframe([refreshbar_ frame]); +/* Cydia Navigation Controller Implementation {{{ */ +@implementation UINavigationController (Cydia) - if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) // XXX: _UIApplicationLinkedOnOrAfter(4) - barframe.origin.y = 0; - else if (kCFCoreFoundationVersionNumber < 800) - barframe.origin.y = CYStatusBarHeight(); - else - barframe.origin.y = 0; //-barframe.size.height + CYStatusBarHeight(); +- (NSArray *) navigationURLCollection { + NSMutableArray *stack([NSMutableArray array]); - [refreshbar_ setFrame:barframe]; + for (CyteViewController *controller in [self viewControllers]) { + NSString *url = [[controller navigationURL] absoluteString]; + if (url != nil) + [stack addObject:url]; + } - CGRect viewframe = [transition frame]; + return stack; +} -if (kCFCoreFoundationVersionNumber < 800) { - if (animated) - [UIView beginAnimations:nil context:NULL]; +- (void) reloadData { + [super reloadData]; - float adjust(barframe.size.height); - if (kCFCoreFoundationVersionNumber >= 800) - adjust -= CYStatusBarHeight(); - viewframe.origin.y += adjust; - viewframe.size.height -= adjust; - [transition setFrame:viewframe]; + UIViewController *visible([self visibleViewController]); + if (visible != nil) + [visible reloadData]; - if (animated) - [UIView commitAnimations]; -} - - // Ensure bar has the proper width for our view, it might have changed - barframe.size.width = viewframe.size.width; - [refreshbar_ setFrame:barframe]; -} - -- (void) raiseBar:(BOOL)animated { - if (!dropped_) - return; - dropped_ = false; - - UIView *transition([self transitionView]); - [refreshbar_ removeFromSuperview]; - - CGRect barframe([refreshbar_ frame]); - -if (kCFCoreFoundationVersionNumber < 800) { - if (animated) - [UIView beginAnimations:nil context:NULL]; - - CGRect viewframe = [transition frame]; - float adjust(barframe.size.height); - if (kCFCoreFoundationVersionNumber >= 800) - adjust -= CYStatusBarHeight(); - viewframe.origin.y -= adjust; - viewframe.size.height += adjust; - [transition setFrame:viewframe]; - - if (animated) - [UIView commitAnimations]; -} -} - -- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - bool dropped(dropped_); - - if (dropped) - [self raiseBar:NO]; - - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - - if (dropped) - [self dropBar:NO]; -} - -- (void) statusBarFrameChanged:(NSNotification *)notification { - if (dropped_) { - [self raiseBar:NO]; - [self dropBar:NO]; - } -} - -@end -/* }}} */ - -/* Cydia Navigation Controller Implementation {{{ */ -@implementation UINavigationController (Cydia) - -- (NSArray *) navigationURLCollection { - NSMutableArray *stack([NSMutableArray array]); - - for (CyteViewController *controller in [self viewControllers]) { - NSString *url = [[controller navigationURL] absoluteString]; - if (url != nil) - [stack addObject:url]; - } - - return stack; -} - -- (void) reloadData { - [super reloadData]; - - UIViewController *visible([self visibleViewController]); - if (visible != nil) - [visible reloadData]; - - // on the iPad, this view controller is ALSO visible. :( - if (IsWildcat_) - if (UIViewController *top = [self topViewController]) - if (top != visible) - [top reloadData]; + // on the iPad, this view controller is ALSO visible. :( + if (IsWildcat_) + if (UIViewController *top = [self topViewController]) + if (top != visible) + [top reloadData]; } - (void) unloadData { @@ -7213,45 +7112,52 @@ if (kCFCoreFoundationVersionNumber < 800) { /* Section Controller {{{ */ @interface SectionController : FilteredPackageListController { + _H key_; _H section_; } -- (id) initWithDatabase:(Database *)database section:(NSString *)section; +- (id) initWithDatabase:(Database *)database source:(Source *)source section:(NSString *)section; @end @implementation SectionController - (NSURL *) referrerURL { - NSString *name = section_; - if (name == nil) - name = @"all"; - - return [NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/sections/%@", UI_, [name stringByAddingPercentEscapesIncludingReserved]]]; + NSString *name(section_); + name = name ?: @"*"; + NSString *key(key_); + key = key ?: @"*"; + return [NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/sections/%@/%@", UI_, [key stringByAddingPercentEscapesIncludingReserved], [name stringByAddingPercentEscapesIncludingReserved]]]; } - (NSURL *) navigationURL { - NSString *name = section_; - if (name == nil) - name = @"all"; - - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sections/%@", [name stringByAddingPercentEscapesIncludingReserved]]]; + NSString *name(section_); + name = name ?: @"*"; + NSString *key(key_); + key = key ?: @"*"; + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sections/%@/%@", [key stringByAddingPercentEscapesIncludingReserved], [name stringByAddingPercentEscapesIncludingReserved]]]; } -- (id) initWithDatabase:(Database *)database section:(NSString *)name { +- (id) initWithDatabase:(Database *)database source:(Source *)source section:(NSString *)section { NSString *title; - if (name == nil) + if (section == nil) title = UCLocalize("ALL_PACKAGES"); - else if (![name isEqual:@""]) - title = [[NSBundle mainBundle] localizedStringForKey:Simplify(name) value:nil table:@"Sections"]; + else if (![section isEqual:@""]) + title = [[NSBundle mainBundle] localizedStringForKey:Simplify(section) value:nil table:@"Sections"]; else title = UCLocalize("NO_SECTION"); - if ((self = [super initWithDatabase:database title:title filter:@selector(isVisibleInSection:) with:name]) != nil) { - section_ = name; + if ((self = [super initWithDatabase:database title:title filter:@selector(isVisibleInSection:source:) with:section with:source]) != nil) { + key_ = [source key]; + section_ = section; } return self; } +- (void) reloadData { + [super setStuff:[database_ sourceWithKey:key_]]; + [super reloadData]; +} + @end /* }}} */ /* Sections Controller {{{ */ @@ -7260,12 +7166,13 @@ if (kCFCoreFoundationVersionNumber < 800) { UITableViewDelegate > { _transient Database *database_; + _H key_; _H sections_; _H filtered_; _H list_; } -- (id) initWithDatabase:(Database *)database; +- (id) initWithDatabase:(Database *)database source:(Source *)source; - (void) editButtonClicked; @end @@ -7273,7 +7180,13 @@ if (kCFCoreFoundationVersionNumber < 800) { @implementation SectionsController - (NSURL *) navigationURL { - return [NSURL URLWithString:@"cydia://sections"]; + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sources/%@", [key_ stringByAddingPercentEscapesIncludingReserved]]]; +} + +- (Source *) source { + if (key_ == nil) + return nil; + return [database_ sourceWithKey:key_]; } - (void) updateNavigationItem { @@ -7354,6 +7267,7 @@ if (kCFCoreFoundationVersionNumber < 800) { SectionController *controller = [[[SectionController alloc] initWithDatabase:database_ + source:[self source] section:[section name] ] autorelease]; [controller setDelegate:delegate_]; @@ -7385,9 +7299,10 @@ if (kCFCoreFoundationVersionNumber < 800) { [super releaseSubviews]; } -- (id) initWithDatabase:(Database *)database { +- (id) initWithDatabase:(Database *)database source:(Source *)source { if ((self = [super init]) != nil) { database_ = database; + key_ = [source key]; } return self; } @@ -7401,8 +7316,13 @@ if (kCFCoreFoundationVersionNumber < 800) { NSMutableDictionary *sections([NSMutableDictionary dictionaryWithCapacity:32]); + Source *source([self source]); + _trace(); for (Package *package in packages) { + if (source != nil && [package source] != source) + continue; + NSString *name([package section]); NSString *key(name == nil ? @"" : name); @@ -7538,22 +7458,30 @@ if (kCFCoreFoundationVersionNumber < 800) { [alert dismissWithClickedButtonIndex:-1 animated:YES]; } +- (void) setLeftBarButtonItem { + if ([delegate_ updating]) + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("CANCEL") + style:UIBarButtonItemStyleDone + target:self + action:@selector(cancelButtonClicked) + ] autorelease] animated:YES]; + else + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("REFRESH") + style:UIBarButtonItemStylePlain + target:self + action:@selector(refreshButtonClicked) + ] autorelease] animated:YES]; +} + - (void) refreshButtonClicked { - if (IsReachable("cydia.saurik.com")) { - [delegate_ beginUpdate]; - [[self navigationItem] setLeftBarButtonItem:nil animated:YES]; - } else { - UIAlertView *alert = [[[UIAlertView alloc] - initWithTitle:[NSString stringWithFormat:Colon_, Error_, UCLocalize("REFRESH")] - message:@"Host Unreachable" // XXX: Localize - delegate:self - cancelButtonTitle:UCLocalize("OK") - otherButtonTitles:nil - ] autorelease]; + if ([delegate_ requestUpdate]) + [self setLeftBarButtonItem]; +} - [alert setContext:@"norefresh"]; - [alert show]; - } +- (void) cancelButtonClicked { + [delegate_ cancelUpdate]; } - (void) upgradeButtonClicked { @@ -7618,6 +7546,8 @@ if (kCFCoreFoundationVersionNumber < 800) { } } - (void) _reloadData { + [self setLeftBarButtonItem]; + NSMutableArray *packages; reload: @@ -7707,13 +7637,6 @@ if (kCFCoreFoundationVersionNumber < 800) { action:@selector(upgradeButtonClicked) ] autorelease]) animated:YES]; - [[self navigationItem] setLeftBarButtonItem:([delegate_ updating] ? nil : [[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("REFRESH") - style:UIBarButtonItemStylePlain - target:self - action:@selector(refreshButtonClicked) - ] autorelease]) animated:YES]; - PrintTimes(); } } @@ -8040,12 +7963,9 @@ if (kCFCoreFoundationVersionNumber < 800) { /* Installed Controller {{{ */ @interface InstalledController : FilteredPackageListController { - BOOL expert_; } - (id) initWithDatabase:(Database *)database; - -- (void) updateRoleButton; - (void) queueStatusDidChange; @end @@ -8062,7 +7982,13 @@ if (kCFCoreFoundationVersionNumber < 800) { - (id) initWithDatabase:(Database *)database { if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndUnfiltered:) with:[NSNumber numberWithBool:YES]]) != nil) { - [self updateRoleButton]; + UISegmentedControl *segmented([[[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:UCLocalize("SIMPLE"), UCLocalize("EXPERT"), nil]] autorelease]); + [segmented setSelectedSegmentIndex:0]; + [segmented setSegmentedControlStyle:UISegmentedControlStyleBar]; + [[self navigationItem] setTitleView:segmented]; + + [segmented addTarget:self action:@selector(modeChanged:) forEvents:UIControlEventValueChanged]; + [self queueStatusDidChange]; } return self; } @@ -8075,37 +8001,23 @@ if (kCFCoreFoundationVersionNumber < 800) { - (void) queueStatusDidChange { #if !AlwaysReload - if (IsWildcat_) { - if (Queuing_) { - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("QUEUE") - style:UIBarButtonItemStyleDone - target:self - action:@selector(queueButtonClicked) - ] autorelease]]; - } else { - [[self navigationItem] setLeftBarButtonItem:nil]; - } - } -#endif -} - -- (void) updateRoleButton { - if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:(expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE")) - style:(expert_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain) + if (Queuing_) { + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("QUEUE") + style:UIBarButtonItemStyleDone target:self - action:@selector(roleButtonClicked) + action:@selector(queueButtonClicked) ] autorelease]]; + } else { + [[self navigationItem] setLeftBarButtonItem:nil]; + } +#endif } -- (void) roleButtonClicked { - [self setObject:[NSNumber numberWithBool:expert_]]; +- (void) modeChanged:(UISegmentedControl *)segmented { + bool simple([segmented selectedSegmentIndex] == 0); + [self setObject:[NSNumber numberWithBool:simple]]; [self reloadData]; - expert_ = !expert_; - - [self updateRoleButton]; } @end @@ -8113,15 +8025,19 @@ if (kCFCoreFoundationVersionNumber < 800) { /* Source Cell {{{ */ @interface SourceCell : CyteTableViewCell < - CyteTableViewCellDelegate + CyteTableViewCellDelegate, + SourceDelegate > { + _H source_; _H url_; _H icon_; _H origin_; _H label_; + _H indicator_; } - (void) setSource:(Source *)source; +- (void) setFetch:(NSNumber *)fetch; @end @@ -8154,6 +8070,11 @@ if (kCFCoreFoundationVersionNumber < 800) { } - (void) setSource:(Source *)source { + source_ = source; + [source_ setDelegate:self]; + + [self setFetch:[NSNumber numberWithBool:[source_ fetch]]]; + icon_ = [UIImage applicationImageNamed:@"unknown.png"]; origin_ = [source name]; @@ -8165,6 +8086,16 @@ if (kCFCoreFoundationVersionNumber < 800) { [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:url_]; } +- (void) setAllSource { + source_ = nil; + [indicator_ stopAnimating]; + + icon_ = [UIImage applicationImageNamed:@"folder.png"]; + origin_ = UCLocalize("ALL_SOURCES"); + label_ = UCLocalize("ALL_SOURCES_EX"); + [content_ setNeedsDisplay]; +} + - (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { if ((self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) != nil) { UIView *content([self contentView]); @@ -8178,12 +8109,31 @@ if (kCFCoreFoundationVersionNumber < 800) { [content_ setDelegate:self]; [content_ setOpaque:YES]; + indicator_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGraySmall] autorelease]; + [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin];// | UIViewAutoresizingFlexibleBottomMargin]; + [content addSubview:indicator_]; + [[content_ layer] setContentsGravity:kCAGravityTopLeft]; } return self; } +- (void) layoutSubviews { + [super layoutSubviews]; + + UIView *content([self contentView]); + CGRect bounds([content bounds]); + + CGRect frame([indicator_ frame]); + frame.origin.x = bounds.size.width - frame.size.width; + frame.origin.y = (bounds.size.height - frame.size.height) / 2; + + if (kCFCoreFoundationVersionNumber < 800) + frame.origin.x -= 8; + [indicator_ setFrame:frame]; +} + - (NSString *) accessibilityLabel { - return label_; + return origin_; } - (void) drawContentRect:(CGRect)rect { @@ -8210,50 +8160,18 @@ if (kCFCoreFoundationVersionNumber < 800) { if (!highlighted) UISetColor(Black_); - [origin_ drawAtPoint:CGPointMake(52, 8) forWidth:(width - 61) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; + [origin_ drawAtPoint:CGPointMake(52, 8) forWidth:(width - 61) withFont:Font18Bold_ lineBreakMode:NSLineBreakByTruncatingTail]; if (!highlighted) UISetColor(Gray_); - [label_ drawAtPoint:CGPointMake(52, 29) forWidth:(width - 61) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; -} - -@end -/* }}} */ -/* Source Controller {{{ */ -@interface SourceController : FilteredPackageListController { - _transient Source *source_; - _H key_; + [label_ drawAtPoint:CGPointMake(52, 29) forWidth:(width - 61) withFont:Font12_ lineBreakMode:NSLineBreakByTruncatingTail]; } -- (id) initWithDatabase:(Database *)database source:(Source *)source; - -@end - -@implementation SourceController - -- (NSURL *) referrerURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/sources/%@", UI_, [key_ stringByAddingPercentEscapesIncludingReserved]]]; -} - -- (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sources/%@", [key_ stringByAddingPercentEscapesIncludingReserved]]]; -} - -- (id) initWithDatabase:(Database *)database source:(Source *)source { - if ((self = [super initWithDatabase:database title:[source label] filter:@selector(isVisibleInSource:) with:source]) != nil) { - source_ = source; - key_ = [source key]; - } return self; -} - -- (void) reloadData { - source_ = [database_ sourceWithKey:key_]; - key_ = [source_ key]; - [self setObject:source_]; - - [[self navigationItem] setTitle:[source_ label]]; - - [super reloadData]; +- (void) setFetch:(NSNumber *)fetch { + if ([fetch boolValue]) + [indicator_ startAnimating]; + else + [indicator_ stopAnimating]; } @end @@ -8274,10 +8192,8 @@ if (kCFCoreFoundationVersionNumber < 800) { _H hud_; _H error_; - //NSURLConnection *installer_; NSURLConnection *trivial_bz2_; NSURLConnection *trivial_gz_; - //NSURLConnection *automatic_; BOOL cydia_; } @@ -8298,10 +8214,8 @@ if (kCFCoreFoundationVersionNumber < 800) { } - (void) dealloc { - //[self _releaseConnection:installer_]; [self _releaseConnection:trivial_gz_]; [self _releaseConnection:trivial_bz2_]; - //[self _releaseConnection:automatic_]; [super dealloc]; } @@ -8316,57 +8230,70 @@ if (kCFCoreFoundationVersionNumber < 800) { } - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { - return 1; + return 2; } - (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + if (section == 1) + return UCLocalize("INDIVIDUAL_SOURCES"); return nil; } - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [sources_ count]; + switch (section) { + case 0: return 1; + case 1: return [sources_ count]; + default: return 0; + } } - (Source *) sourceAtIndexPath:(NSIndexPath *)indexPath { @synchronized (database_) { if ([database_ era] != era_) return nil; - + if ([indexPath section] != 1) + return nil; NSUInteger index([indexPath row]); - return index < [sources_ count] ? [sources_ objectAtIndex:index] : nil; + if (index >= [sources_ count]) + return nil; + return [sources_ objectAtIndex:index]; } } - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"SourceCell"; SourceCell *cell = (SourceCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; - if(cell == nil) cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease]; - [cell setSource:[self sourceAtIndexPath:indexPath]]; + if (cell == nil) cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease]; [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + Source *source([self sourceAtIndexPath:indexPath]); + if (source == nil) + [cell setAllSource]; + else + [cell setSource:source]; + return cell; } - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - Source *source = [self sourceAtIndexPath:indexPath]; - if (source == nil) return; - - SourceController *controller = [[[SourceController alloc] + SectionsController *controller([[[SectionsController alloc] initWithDatabase:database_ - source:source - ] autorelease]; + source:[self sourceAtIndexPath:indexPath] + ] autorelease]); [controller setDelegate:delegate_]; - [[self navigationController] pushViewController:controller animated:YES]; } - (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + if ([indexPath section] != 1) + return false; Source *source = [self sourceAtIndexPath:indexPath]; return [source record] != nil; } - (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + _assert([indexPath section] == 1); if (editingStyle == UITableViewCellEditingStyleDelete) { Source *source = [self sourceAtIndexPath:indexPath]; if (source == nil) return; @@ -8379,6 +8306,10 @@ if (kCFCoreFoundationVersionNumber < 800) { } } +- (void) tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath { + [self updateButtonsForEditingStatusAnimated:YES]; +} + - (void) complete { [delegate_ addTrivialSource:href_]; href_ = nil; @@ -8531,7 +8462,21 @@ if (kCFCoreFoundationVersionNumber < 800) { case 1: { NSString *href = [[alert textField] text]; - //installer_ = [[self _requestHRef:href method:@"GET"] retain]; + static Pcre href_r("^http(s?)://[^# ]*$"); + if (!href_r(href)) { + UIAlertView *alert = [[[UIAlertView alloc] + initWithTitle:Error_ + message:UCLocalize("INVALID_URL") + delegate:self + cancelButtonTitle:UCLocalize("OK") + otherButtonTitles:nil + ] autorelease]; + + [alert setContext:@"badurl"]; + [alert show]; + + break; + } if (![href hasSuffix:@"/"]) href_ = [href stringByAppendingString:@"/"]; @@ -8540,7 +8485,6 @@ if (kCFCoreFoundationVersionNumber < 800) { trivial_bz2_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.bz2"] method:@"HEAD"] retain]; trivial_gz_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.gz"] method:@"HEAD"] retain]; - //trivial_bz2_ = [[self _requestHRef:[href stringByAppendingString:@"dists/Release"] method:@"HEAD"] retain]; cydia_ = false; @@ -8577,6 +8521,39 @@ if (kCFCoreFoundationVersionNumber < 800) { } } +- (void) updateButtonsForEditingStatusAnimated:(BOOL)animated { + BOOL editing([list_ isEditing]); + + if (editing) + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("ADD") + style:UIBarButtonItemStylePlain + target:self + action:@selector(addButtonClicked) + ] autorelease] animated:animated]; + else if ([delegate_ updating]) + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("CANCEL") + style:UIBarButtonItemStyleDone + target:self + action:@selector(cancelButtonClicked) + ] autorelease] animated:animated]; + else + [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("REFRESH") + style:UIBarButtonItemStylePlain + target:self + action:@selector(refreshButtonClicked) + ] autorelease] animated:animated]; + + [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:(editing ? UCLocalize("DONE") : UCLocalize("EDIT")) + style:(editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain) + target:self + action:@selector(editButtonClicked) + ] autorelease] animated:animated]; +} + - (void) loadView { list_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; @@ -8616,6 +8593,7 @@ if (kCFCoreFoundationVersionNumber < 800) { - (void) reloadData { [super reloadData]; + [self updateButtonsForEditingStatusAnimated:YES]; @synchronized (database_) { era_ = [database_ era]; @@ -8667,34 +8645,13 @@ if (kCFCoreFoundationVersionNumber < 800) { [self showAddSourcePrompt]; } -- (void) updateButtonsForEditingStatusAnimated:(BOOL)animated { - BOOL editing([list_ isEditing]); - - [[self navigationItem] setLeftBarButtonItem:(editing ? [[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("ADD") - style:UIBarButtonItemStylePlain - target:self - action:@selector(addButtonClicked) - ] autorelease] : [[self navigationItem] backBarButtonItem]) animated:animated]; - - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:(editing ? UCLocalize("DONE") : UCLocalize("EDIT")) - style:(editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain) - target:self - action:@selector(editButtonClicked) - ] autorelease] animated:animated]; - - if (IsWildcat_ && !editing) - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("SETTINGS") - style:UIBarButtonItemStylePlain - target:self - action:@selector(settingsButtonClicked) - ] autorelease]]; +- (void) refreshButtonClicked { + if ([delegate_ requestUpdate]) + [self updateButtonsForEditingStatusAnimated:YES]; } -- (void) settingsButtonClicked { - [delegate_ showSettings]; +- (void) cancelButtonClicked { + [delegate_ cancelUpdate]; } - (void) editButtonClicked { @@ -8705,200 +8662,6 @@ if (kCFCoreFoundationVersionNumber < 800) { @end /* }}} */ -/* Settings Controller {{{ */ -@interface SettingsController : CyteViewController < - UITableViewDataSource, - UITableViewDelegate -> { - _transient Database *database_; - // XXX: ok, "roledelegate_"?... - _transient id roledelegate_; - _H table_; - _H segment_; - _H container_; -} - -- (void) showDoneButton; -- (void) resizeSegmentedControl; - -@end - -@implementation SettingsController - -- (void) loadView { - table_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped] autorelease]; - [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [table_ setDelegate:self]; - [(UITableView *) table_ setDataSource:self]; - [self setView:table_]; - - NSArray *items = [NSArray arrayWithObjects: - UCLocalize("USER"), - UCLocalize("HACKER"), - UCLocalize("DEVELOPER"), - nil]; - segment_ = [[[UISegmentedControl alloc] initWithItems:items] autorelease]; - container_ = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)] autorelease]; - [container_ addSubview:segment_]; -} - -- (void) viewDidLoad { - [super viewDidLoad]; - - [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")]; - - int index = -1; - if ([Role_ isEqualToString:@"User"]) index = 0; - if ([Role_ isEqualToString:@"Hacker"]) index = 1; - if ([Role_ isEqualToString:@"Developer"]) index = 2; - if (index != -1) { - [segment_ setSelectedSegmentIndex:index]; - [self showDoneButton]; - } - - [segment_ addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged]; - [self resizeSegmentedControl]; -} - -- (void) releaseSubviews { - table_ = nil; - segment_ = nil; - container_ = nil; - - [super releaseSubviews]; -} - -- (id) initWithDatabase:(Database *)database delegate:(id)delegate { - if ((self = [super init]) != nil) { - database_ = database; - roledelegate_ = delegate; - } return self; -} - -- (void) resizeSegmentedControl { - CGFloat width = [[self view] frame].size.width; - [segment_ setFrame:CGRectMake(width / 32.0f, 0, width - (width / 32.0f * 2.0f), 44.0f)]; -} - -- (void) viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self resizeSegmentedControl]; -} - -- (void) viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [segment_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin)]; - [self resizeSegmentedControl]; -} - -- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { - [self resizeSegmentedControl]; -} - -- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [self resizeSegmentedControl]; -} - -- (void) save { - NSString *role(nil); - - switch ([segment_ selectedSegmentIndex]) { - case 0: role = @"User"; break; - case 1: role = @"Hacker"; break; - case 2: role = @"Developer"; break; - - _nodefault - } - - if (![role isEqualToString:Role_]) { - bool rolling(Role_ == nil); - Role_ = role; - - Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys: - Role_, @"Role", - nil]; - - [Metadata_ setObject:Settings_ forKey:@"Settings"]; - Changed_ = true; - - if (rolling) - [roledelegate_ loadData]; - else - [roledelegate_ updateData]; - } -} - -- (void) segmentChanged:(UISegmentedControl *)control { - [self showDoneButton]; -} - -- (void) saveAndClose { - [self save]; - - [[self navigationItem] setRightBarButtonItem:nil]; - [[self navigationController] dismissModalViewControllerAnimated:YES]; -} - -- (void) doneButtonClicked { - UIActivityIndicatorView *spinner = [[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20.0f, 20.0f)] autorelease]; - [spinner startAnimating]; - UIBarButtonItem *spinItem = [[[UIBarButtonItem alloc] initWithCustomView:spinner] autorelease]; - [[self navigationItem] setRightBarButtonItem:spinItem]; - - [self performSelector:@selector(saveAndClose) withObject:nil afterDelay:0]; -} - -- (void) showDoneButton { - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("DONE") - style:UIBarButtonItemStyleDone - target:self - action:@selector(doneButtonClicked) - ] autorelease] animated:([[self navigationItem] rightBarButtonItem] == nil)]; -} - -- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { - // XXX: For not having a single cell in the table, this sure is a lot of sections. - return 6; -} - -- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 0; // :( -} - -- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - return nil; // This method is required by the protocol. -} - -- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - if (section == 1) - return UCLocalize("ROLE_EX"); - if (section == 4) - return [NSString stringWithFormat: - @"%@: %@\n%@: %@\n%@: %@", - UCLocalize("USER"), UCLocalize("USER_EX"), - UCLocalize("HACKER"), UCLocalize("HACKER_EX"), - UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX") - ]; - else return nil; -} - -- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return section == 3 ? 44.0f : 0; -} - -- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - return section == 3 ? container_ : nil; -} - -- (void) reloadData { - [super reloadData]; - - [table_ reloadData]; -} - -@end -/* }}} */ /* Stash Controller {{{ */ @interface StashController : CyteViewController { _H spinner_; @@ -8938,7 +8701,7 @@ if (kCFCoreFoundationVersionNumber < 800) { [caption_ setTextColor:[UIColor whiteColor]]; [caption_ setBackgroundColor:[UIColor clearColor]]; [caption_ setShadowColor:[UIColor blackColor]]; - [caption_ setTextAlignment:UITextAlignmentCenter]; + [caption_ setTextAlignment:NSTextAlignmentCenter]; [view addSubview:caption_]; CGRect statusrect; @@ -8953,7 +8716,7 @@ if (kCFCoreFoundationVersionNumber < 800) { [status_ setTextColor:[UIColor whiteColor]]; [status_ setBackgroundColor:[UIColor clearColor]]; [status_ setShadowColor:[UIColor blackColor]]; - [status_ setTextAlignment:UITextAlignmentCenter]; + [status_ setTextAlignment:NSTextAlignmentCenter]; [view addSubview:status_]; } @@ -9069,6 +8832,30 @@ if (kCFCoreFoundationVersionNumber < 800) { [tabbar_ beginUpdate]; } +- (void) cancelUpdate { + [tabbar_ cancelUpdate]; +} + +- (bool) requestUpdate { + if (IsReachable("cydia.saurik.com")) { + [self beginUpdate]; + return true; + } else { + UIAlertView *alert = [[[UIAlertView alloc] + initWithTitle:[NSString stringWithFormat:Colon_, Error_, UCLocalize("REFRESH")] + message:@"Host Unreachable" // XXX: Localize + delegate:self + cancelButtonTitle:UCLocalize("OK") + otherButtonTitles:nil + ] autorelease]; + + [alert setContext:@"norefresh"]; + [alert show]; + + return false; + } +} + - (BOOL) updating { return [tabbar_ updating]; } @@ -9442,10 +9229,6 @@ if (kCFCoreFoundationVersionNumber < 800) { [self unlockSuspend]; } -- (void) showSettings { - [self presentModalViewController:[[[SettingsController alloc] initWithDatabase:database_ delegate:self] autorelease] force:NO]; -} - - (void) retainNetworkActivityIndicator { if (activity_++ == 0) [self setNetworkActivityIndicatorVisible:YES]; @@ -9645,14 +9428,6 @@ if (kCFCoreFoundationVersionNumber < 800) { NSString *destination = [[url absoluteString] substringFromIndex:([scheme length] + [@"://" length] + [base length] + [@"/" length])]; controller = [[[CydiaWebViewController alloc] initWithURL:[NSURL URLWithString:destination]] autorelease]; } else if (!external && [components count] == 1) { - if ([base isEqualToString:@"manage"]) { - controller = [[[ManageController alloc] init] autorelease]; - } - - if ([base isEqualToString:@"storage"]) { - controller = [[[CydiaWebViewController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/storage/", UI_]]] autorelease]; - } - if ([base isEqualToString:@"sources"]) { controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; } @@ -9662,7 +9437,7 @@ if (kCFCoreFoundationVersionNumber < 800) { } if ([base isEqualToString:@"sections"]) { - controller = [[[SectionsController alloc] initWithDatabase:database_] autorelease]; + controller = [[[SectionsController alloc] initWithDatabase:database_ source:nil] autorelease]; } if ([base isEqualToString:@"search"]) { @@ -9677,20 +9452,20 @@ if (kCFCoreFoundationVersionNumber < 800) { controller = [[[InstalledController alloc] initWithDatabase:database_] autorelease]; } } else if ([components count] == 2) { - NSString *argument = [components objectAtIndex:1]; + NSString *argument = [[components objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; if ([base isEqualToString:@"package"]) { controller = [self pageForPackage:argument withReferrer:referrer]; } if (!external && [base isEqualToString:@"search"]) { - controller = [[[SearchController alloc] initWithDatabase:database_ query:[argument stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] autorelease]; + controller = [[[SearchController alloc] initWithDatabase:database_ query:argument] autorelease]; } if (!external && [base isEqualToString:@"sections"]) { - if ([argument isEqualToString:@"all"]) + if ([argument isEqualToString:@"all"] || [argument isEqualToString:@"*"]) argument = nil; - controller = [[[SectionController alloc] initWithDatabase:database_ section:[argument stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] autorelease]; + controller = [[[SectionController alloc] initWithDatabase:database_ source:nil section:argument] autorelease]; } if (!external && [base isEqualToString:@"sources"]) { @@ -9698,8 +9473,8 @@ if (kCFCoreFoundationVersionNumber < 800) { controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; [(SourcesController *)controller showAddSourcePrompt]; } else { - Source *source = [database_ sourceWithKey:[argument stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - controller = [[[SourceController alloc] initWithDatabase:database_ source:source] autorelease]; + Source *source([database_ sourceWithKey:argument]); + controller = [[[SectionsController alloc] initWithDatabase:database_ source:source] autorelease]; } } @@ -9708,8 +9483,8 @@ if (kCFCoreFoundationVersionNumber < 800) { return nil; } } else if (!external && [components count] == 3) { - NSString *arg1 = [components objectAtIndex:1]; - NSString *arg2 = [components objectAtIndex:2]; + NSString *arg1 = [[components objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString *arg2 = [[components objectAtIndex:2] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; if ([base isEqualToString:@"package"]) { if ([arg2 isEqualToString:@"settings"]) { @@ -9721,6 +9496,12 @@ if (kCFCoreFoundationVersionNumber < 800) { } } } + + if ([base isEqualToString:@"sections"]) { + Source *source([arg1 isEqualToString:@"*"] ? nil : [database_ sourceWithKey:arg1]); + NSString *section([arg2 isEqualToString:@"*"] ? nil : arg2); + controller = [[[SectionController alloc] initWithDatabase:database_ source:source section:section] autorelease]; + } } [controller setDelegate:self]; @@ -9830,31 +9611,19 @@ if (kCFCoreFoundationVersionNumber < 800) { if (kCFCoreFoundationVersionNumber < 800) { items = [NSMutableArray arrayWithObjects: [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:0] autorelease], - [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:0] autorelease], + [[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"install.png"] tag:0] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:0] autorelease], + [[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:0] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:0] autorelease], nil]; - - if (IsWildcat_) { - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source.png"] tag:0] autorelease] atIndex:3]; - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:0] autorelease] atIndex:3]; - } else { - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:0] autorelease] atIndex:3]; - } } else { items = [NSMutableArray arrayWithObjects: [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home7.png"] selectedImage:[UIImage applicationImageNamed:@"home7s.png"]] autorelease], - [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install7.png"] selectedImage:[UIImage applicationImageNamed:@"install7s.png"]] autorelease], + [[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"install7.png"] selectedImage:[UIImage applicationImageNamed:@"install7s.png"]] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes7.png"] selectedImage:[UIImage applicationImageNamed:@"changes7s.png"]] autorelease], + [[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage7.png"] selectedImage:[UIImage applicationImageNamed:@"manage7s.png"]] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search7.png"] selectedImage:[UIImage applicationImageNamed:@"search7s.png"]] autorelease], nil]; - - if (IsWildcat_) { - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source7.png"] selectedImage:[UIImage applicationImageNamed:@"source7s.png"]] autorelease] atIndex:3]; - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage7.png"] selectedImage:[UIImage applicationImageNamed:@"manage7s.png"]] autorelease] atIndex:3]; - } else { - [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage7.png"] selectedImage:[UIImage applicationImageNamed:@"manage7s.png"]] autorelease] atIndex:3]; - } } NSMutableArray *controllers([NSMutableArray array]); @@ -9982,29 +9751,18 @@ _trace(); - (NSArray *) defaultStartPages { NSMutableArray *standard = [NSMutableArray array]; [standard addObject:[NSArray arrayWithObject:@"cydia://home"]]; - [standard addObject:[NSArray arrayWithObject:@"cydia://sections"]]; + [standard addObject:[NSArray arrayWithObject:@"cydia://sources"]]; [standard addObject:[NSArray arrayWithObject:@"cydia://changes"]]; - if (!IsWildcat_) { - [standard addObject:[NSArray arrayWithObject:@"cydia://manage"]]; - } else { - [standard addObject:[NSArray arrayWithObject:@"cydia://installed"]]; - [standard addObject:[NSArray arrayWithObject:@"cydia://sources"]]; - } + [standard addObject:[NSArray arrayWithObject:@"cydia://installed"]]; [standard addObject:[NSArray arrayWithObject:@"cydia://search"]]; return standard; } - (void) loadData { _trace(); - if (Role_ == nil) { - [window_ setUserInteractionEnabled:YES]; - [self showSettings]; - return; - } else { - if ([emulated_ modalViewController] != nil) - [emulated_ dismissModalViewControllerAnimated:YES]; - [window_ setUserInteractionEnabled:NO]; - } + if ([emulated_ modalViewController] != nil) + [emulated_ dismissModalViewControllerAnimated:YES]; + [window_ setUserInteractionEnabled:NO]; [self reloadDataWithInvocation:nil]; [self refreshIfPossible]; @@ -10446,9 +10204,6 @@ int main(int argc, char *argv[]) { Version_ = [Metadata_ objectForKey:@"Version"]; } - if (Settings_ != nil) - Role_ = [Settings_ objectForKey:@"Role"]; - if (Values_ == nil) { Values_ = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease]; [Metadata_ setObject:Values_ forKey:@"Values"]; @@ -10482,6 +10237,16 @@ int main(int argc, char *argv[]) { Changed_ = true; } + + _H broken([NSMutableArray array]); + for (NSString *key in (id) Sources_) + if ([key rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"# "]].location != NSNotFound) + [broken addObject:key]; + if ([broken count] != 0) { + for (NSString *key in (id) broken) + [Sources_ removeObjectForKey:key]; + Changed_ = true; + } broken = nil; /* }}} */ CydiaWriteSources();