X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/4121c5e002cf039931b67ef2c592783c64f0cc59..299aeacd7d337a1e57ca14660a151f5a9fd453e2:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 30997aa8..e0539fa0 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -863,6 +864,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; @@ -874,6 +885,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; @@ -888,29 +900,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; } @@ -919,6 +921,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]); @@ -946,9 +981,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) @@ -962,16 +995,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() { @@ -1012,7 +1036,7 @@ typedef std::map< unsigned long, _H > SourceMap; _transient NSObject *delegate_; _transient NSObject *progress_; - Status status_; + CydiaStatus status_; int cydiafd_; int statusfd_; @@ -1049,7 +1073,7 @@ typedef std::map< unsigned long, _H > SourceMap; - (bool) upgrade; - (void) update; -- (void) updateWithStatus:(Status &)status; +- (void) updateWithStatus:(CancelStatus &)status; - (void) setDelegate:(NSObject *)delegate; @@ -1057,11 +1081,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 @@ -1326,6 +1400,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; @@ -1355,6 +1433,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 @@ -1417,7 +1498,19 @@ 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("")); + files_.insert(file + "Release.gpg"); + files_.insert(file + "Release"); + base_.set(pool, file); + + std::vector *targets(dindex->ComputeIndexTargets()); + for (std::vector::const_iterator target(targets->begin()); target != targets->end(); ++target) { + std::string file((*target)->URI); + files_.insert(file); + files_.insert(file + ".gz"); + files_.insert(file + ".bz2"); + files_.insert(file + "Index"); + } delete targets; FileFd fd; if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly)) @@ -1653,6 +1746,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 {{{ */ @@ -3809,7 +3927,7 @@ class CydiaLogCleaner : [self updateWithStatus:status_]; } -- (void) updateWithStatus:(Status &)status { +- (void) updateWithStatus:(CancelStatus &)status { NSString *title(UCLocalize("REFRESHING_DATA")); pkgSourceList list; @@ -3853,6 +3971,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; @@ -6683,100 +6811,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi @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 -/* }}} */ - /* Cydia Navigation Controller Interface {{{ */ @interface UINavigationController (Cydia) @@ -6789,21 +6823,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 @@ -6823,21 +6855,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; } @@ -6846,8 +6872,14 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi } - (void) beginUpdate { - [(RefreshBar *) refreshbar_ start]; - [self dropBar:YES]; + 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; @@ -6862,8 +6894,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 @@ -6879,8 +6910,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]; } @@ -6903,25 +6937,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) startSourceFetch:(NSString *)uri { } -- (void) setProgressPercent:(NSNumber *)percent { - [refreshbar_ setProgress:[percent floatValue]]; -} - -- (void) setProgressStatus:(NSDictionary *)status { - if (status != nil) - [self setProgressPercent:[status objectForKey:@"Percent"]]; +- (void) stopSourceFetch:(NSString *)uri { } - (void) setUpdateDelegate:(id)delegate { @@ -6937,93 +6960,6 @@ 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_]; - - CGRect barframe([refreshbar_ frame]); - - 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(); - - [refreshbar_ setFrame:barframe]; - - CGRect viewframe = [transition frame]; - -if (kCFCoreFoundationVersionNumber < 800) { - if (animated) - [UIView beginAnimations:nil context:NULL]; - - 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]; -} - - // 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 /* }}} */ @@ -7518,22 +7454,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 { @@ -7598,6 +7542,8 @@ if (kCFCoreFoundationVersionNumber < 800) { } } - (void) _reloadData { + [self setLeftBarButtonItem]; + NSMutableArray *packages; reload: @@ -7687,13 +7633,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(); } } @@ -8020,12 +7959,9 @@ if (kCFCoreFoundationVersionNumber < 800) { /* Installed Controller {{{ */ @interface InstalledController : FilteredPackageListController { - BOOL expert_; } - (id) initWithDatabase:(Database *)database; - -- (void) updateRoleButton; - (void) queueStatusDidChange; @end @@ -8042,7 +7978,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; } @@ -8068,21 +8010,10 @@ if (kCFCoreFoundationVersionNumber < 800) { #endif } -- (void) updateRoleButton { - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:(expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE")) - style:(expert_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain) - target:self - action:@selector(roleButtonClicked) - ] autorelease]]; -} - -- (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 @@ -8090,15 +8021,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 @@ -8131,6 +8066,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]; @@ -8143,6 +8083,9 @@ if (kCFCoreFoundationVersionNumber < 800) { } - (void) setAllSource { + source_ = nil; + [indicator_ stopAnimating]; + icon_ = [UIImage applicationImageNamed:@"folder.png"]; origin_ = UCLocalize("ALL_SOURCES"); label_ = UCLocalize("ALL_SOURCES_EX"); @@ -8162,10 +8105,29 @@ 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 origin_; } @@ -8201,6 +8163,13 @@ if (kCFCoreFoundationVersionNumber < 800) { [label_ drawAtPoint:CGPointMake(52, 29) forWidth:(width - 61) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; } +- (void) setFetch:(NSNumber *)fetch { + if ([fetch boolValue]) + [indicator_ startAnimating]; + else + [indicator_ stopAnimating]; +} + @end /* }}} */ /* Sources Controller {{{ */ @@ -8219,10 +8188,8 @@ if (kCFCoreFoundationVersionNumber < 800) { _H hud_; _H error_; - //NSURLConnection *installer_; NSURLConnection *trivial_bz2_; NSURLConnection *trivial_gz_; - //NSURLConnection *automatic_; BOOL cydia_; } @@ -8243,10 +8210,8 @@ if (kCFCoreFoundationVersionNumber < 800) { } - (void) dealloc { - //[self _releaseConnection:installer_]; [self _releaseConnection:trivial_gz_]; [self _releaseConnection:trivial_bz2_]; - //[self _releaseConnection:automatic_]; [super dealloc]; } @@ -8489,8 +8454,6 @@ if (kCFCoreFoundationVersionNumber < 800) { case 1: { NSString *href = [[alert textField] text]; - //installer_ = [[self _requestHRef:href method:@"GET"] retain]; - if (![href hasSuffix:@"/"]) href_ = [href stringByAppendingString:@"/"]; else @@ -8498,7 +8461,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; @@ -8535,6 +8497,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]; @@ -8574,6 +8569,7 @@ if (kCFCoreFoundationVersionNumber < 800) { - (void) reloadData { [super reloadData]; + [self updateButtonsForEditingStatusAnimated:YES]; @synchronized (database_) { era_ = [database_ era]; @@ -8625,22 +8621,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]; +- (void) refreshButtonClicked { + if ([delegate_ requestUpdate]) + [self updateButtonsForEditingStatusAnimated:YES]; +} - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:(editing ? UCLocalize("DONE") : UCLocalize("EDIT")) - style:(editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain) - target:self - action:@selector(editButtonClicked) - ] autorelease] animated:animated]; +- (void) cancelButtonClicked { + [delegate_ cancelUpdate]; } - (void) editButtonClicked { @@ -8821,6 +8808,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]; }