X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/15b41c774e2c7f74decc99a0003e8dd0498f2f23..33272aa75c4a61ed5b27ab440689048deb8d23a1:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index a204e887..936856db 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -41,14 +41,13 @@ #define USE_SYSTEM_MALLOC 1 /* #include Directives {{{ */ -#import "UICaboodle/UCPlatform.h" -#import "UICaboodle/UCLocalize.h" +#include "UICaboodle/UCPlatform.h" +#include "UICaboodle/UCLocalize.h" #include #include #include -#include #include #if 0 @@ -60,10 +59,14 @@ #include #include -#import +#include + +#include +#include "iPhonePrivate.h" + +#include #include -#import #include #include @@ -100,6 +103,7 @@ #include #include +#include #include #include @@ -116,53 +120,9 @@ extern "C" { #include -#import "UICaboodle/BrowserView.h" -#import "UICaboodle/ResetView.h" - -#import "substrate.h" - -// Apple's sample Reachability code, ASPL licensed. -#import "Reachability.h" -/* }}} */ - -/* Header Fixes and Updates {{{ */ -typedef enum { - UIModalPresentationFullScreen = 0, - UIModalPresentationPageSheet, - UIModalPresentationFormSheet, - UIModalPresentationCurrentContext, -} UIModalPresentationStyle; - -@interface UIAlertView (Private) -- (void)setNumberOfRows:(int)rows; -- (void)setContext:(id)context; -- (id)context; -@end - -@interface UIViewController (UIKit) -- (id)navigationItem; -- (id)navigationController; -- (id)tabBarItem; -@end +#include "UICaboodle/BrowserView.h" -@interface UITabBarController : UIViewController { - id _tabBar; - id _containerView; - id _viewControllerTransitionView; - id _viewControllers; - id _tabBarItemsToViewControllers; - id _selectedViewController; - id _moreNavigationController; - id _customizableViewControllers; - id _delegate; - id _selectedViewControllerDuringWillAppear; - id _transientViewController; - unsigned int isShowingMoreItem:1; - unsigned int needsToRebuildItems:1; - unsigned int isBarHidden:1; - unsigned int editButtonOnLeft:1; -} -@end +#include "substrate.h" /* }}} */ /* Profiler {{{ */ @@ -257,6 +217,15 @@ static _finline NSString *CydiaURL(NSString *path) { return [[NSString stringWithUTF8String:page] stringByAppendingString:path]; } +static _finline void UpdateExternalStatus(uint64_t newStatus) { + int notify_token; + if (notify_register_check("com.saurik.Cydia.status", ¬ify_token) == NOTIFY_STATUS_OK) { + notify_set_state(notify_token, newStatus); + notify_cancel(notify_token); + } + notify_post("com.saurik.Cydia.status"); +} + /* [NSObject yieldToSelector:(withObject:)] {{{*/ @interface NSObject (Cydia) - (id) yieldToSelector:(SEL)selector withObject:(id)object; @@ -342,6 +311,18 @@ static _finline NSString *CydiaURL(NSString *path) { } return self; } +- (void) _updateFrameForDisplay { + [super _updateFrameForDisplay]; + if ([self cancelButtonIndex] == -1) { + NSArray *buttons = [self buttons]; + if ([buttons count]) { + UIImage *background = [[buttons objectAtIndex:0] backgroundForState:0]; + for (UIThreePartButton *button in buttons) + [button setBackground:background forState:0]; + } + } +} + - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { button_ = buttonIndex + 1; } @@ -351,11 +332,9 @@ static _finline NSString *CydiaURL(NSString *path) { } - (int) yieldToPopupAlertAnimated:(BOOL)animated { + [self setRunsModal:YES]; button_ = 0; [self show]; - NSRunLoop *loop([NSRunLoop currentRunLoop]); - NSDate *future([NSDate distantFuture]); - while (button_ == 0 && [loop runMode:NSDefaultRunLoopMode beforeDate:future]); return button_; } @@ -394,7 +373,7 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | #define lprintf(args...) fprintf(stderr, args) -#define ForRelease 0 +#define ForRelease 1 #define TraceLogging (1 && !ForRelease) #define HistogramInsertionSort (0 && !ForRelease) #define ProfileTimes (0 && !ForRelease) @@ -405,7 +384,7 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | #define ShowInternals (0 && !ForRelease) #define IgnoreInstall (0 && !ForRelease) #define RecycleWebViews 0 -#define RecyclePackageViews (1 && ForRelease) +#define RecyclePackageViews (0 && ForRelease) #define AlwaysReload (1 && !ForRelease) #if !TraceLogging @@ -639,7 +618,9 @@ void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFCompar @end /* }}} */ -NSUInteger WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptObject *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) { +@implementation WebScriptObject (NSFastEnumeration) + +- (NSUInteger) countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count { size_t length([self count] - state->state); if (length <= 0) return 0; @@ -652,6 +633,8 @@ NSUInteger WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptO return length; } +@end + NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) { size_t length([self length] - state->state); if (length <= 0) @@ -665,10 +648,6 @@ NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *s return length; } -@interface NSString (UIKit) -- (NSString *) stringByAddingPercentEscapes; -@end - /* Cydia NSString Additions {{{ */ @interface NSString (Cydia) + (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length; @@ -734,7 +713,7 @@ NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *s - (NSString *) stringByAddingPercentEscapesIncludingReserved { return [(id)CFURLCreateStringByAddingPercentEscapes( - kCFAllocatorDefault, + kCFAllocatorDefault, (CFStringRef) self, NULL, CFSTR(";/?:@&=+$,"), @@ -994,17 +973,17 @@ class Pcre { @end /* }}} */ /* CoreGraphics Primitives {{{ */ -class CGColor { +class CYColor { private: CGColorRef color_; public: - CGColor() : + CYColor() : color_(NULL) { } - CGColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) : + CYColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) : color_(NULL) { Set(space, red, green, blue, alpha); @@ -1015,14 +994,14 @@ class CGColor { CGColorRelease(color_); } - ~CGColor() { + ~CYColor() { Clear(); } void Set(CGColorSpaceRef space, float red, float green, float blue, float alpha) { Clear(); float color[] = {red, green, blue, alpha}; - color_ = CGColorCreate(space, color); + color_ = CGColorCreate(space, (CGFloat *) color); } operator CGColorRef() { @@ -1045,15 +1024,15 @@ static NSArray *Finishes_; static bool Queuing_; -static CGColor Blue_; -static CGColor Blueish_; -static CGColor Black_; -static CGColor Off_; -static CGColor White_; -static CGColor Gray_; -static CGColor Green_; -static CGColor Purple_; -static CGColor Purplish_; +static CYColor Blue_; +static CYColor Blueish_; +static CYColor Black_; +static CYColor Off_; +static CYColor White_; +static CYColor Gray_; +static CYColor Green_; +static CYColor Purple_; +static CYColor Purplish_; static UIColor *InstallingColor_; static UIColor *RemovingColor_; @@ -1071,14 +1050,14 @@ static UIFont *Font18Bold_; static UIFont *Font22Bold_; static const char *Machine_ = NULL; -static const NSString *System_ = NULL; -static const NSString *SerialNumber_ = nil; -static const NSString *ChipID_ = nil; -static const NSString *Token_ = nil; -static const NSString *UniqueID_ = nil; -static const NSString *Build_ = nil; -static const NSString *Product_ = nil; -static const NSString *Safari_ = nil; +static NSString *System_ = nil; +static NSString *SerialNumber_ = nil; +static NSString *ChipID_ = nil; +static NSString *Token_ = nil; +static NSString *UniqueID_ = nil; +static NSString *Build_ = nil; +static NSString *Product_ = nil; +static NSString *Safari_ = nil; static CFLocaleRef Locale_; static NSArray *Languages_; @@ -1221,22 +1200,26 @@ bool isSectionVisible(NSString *section) { - (void) setConfigurationData:(NSString *)data; @end -@class PackageView; +@class PackageController; @protocol CydiaDelegate -- (void) setPackageView:(PackageView *)view; +- (void) setPackageController:(PackageController *)view; - (void) clearPackage:(Package *)package; - (void) installPackage:(Package *)package; - (void) installPackages:(NSArray *)packages; - (void) removePackage:(Package *)package; +- (void) beginUpdate; +- (BOOL) updating; - (void) distUpgrade; +- (void) loadData; - (void) updateData; - (void) syncData; -- (void) askForSettings; +- (void) showSettings; - (UIProgressHUD *) addProgressHUD; - (void) removeProgressHUD:(UIProgressHUD *)hud; -- (UIViewController *) pageForPackage:(NSString *)name; -- (PackageView *) packageView; +- (CYViewController *) pageForPackage:(NSString *)name; +- (PackageController *) packageController; +- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item; @end /* }}} */ @@ -1427,7 +1410,7 @@ typedef std::map< unsigned long, _H > SourceMap; @end /* }}} */ /* Delegate Helpers {{{ */ -@implementation NSObject(ProgressDelegate) +@implementation NSObject (ProgressDelegate) - (void) _setProgressErrorPackage:(NSArray *)args { [self performSelector:@selector(setProgressError:forPackage:) @@ -1452,8 +1435,11 @@ typedef std::map< unsigned long, _H > SourceMap; - (void) setProgressError:(NSString *)error forPackage:(NSString *)id { Package *package = id == nil ? nil : [[Database sharedInstance] packageWithName:id]; - // XXX: holy typecast batman! - [self setProgressError:error withTitle:(package == nil ? id : [package name])]; + + [self performSelector:@selector(setProgressError:withTitle:) + withObject:error + withObject:(package == nil ? id : [package name]) + ]; } @end @@ -1648,11 +1634,11 @@ typedef std::map< unsigned long, _H > SourceMap; } - (NSString *) depictionForPackage:(NSString *)package { - return depiction_.empty() ? nil : [depiction_ stringByReplacingOccurrencesOfString:@"*" withString:package]; + return depiction_.empty() ? nil : [static_cast(depiction_) stringByReplacingOccurrencesOfString:@"*" withString:package]; } - (NSString *) supportForPackage:(NSString *)package { - return support_.empty() ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package]; + return support_.empty() ? nil : [static_cast(support_) stringByReplacingOccurrencesOfString:@"*" withString:package]; } - (NSDictionary *) record { @@ -2194,7 +2180,7 @@ struct PackageNameOrdering : _end bool changed(false); - NSString *key([id_ lowercaseString]); + NSString *key([static_cast(id_) lowercaseString]); _profile(Package$initWithVersion$Metadata) metadata_ = [Packages_ objectForKey:key]; @@ -2500,12 +2486,14 @@ struct PackageNameOrdering : UIImage *icon(nil); if (!icon_.empty()) - if ([icon_ hasPrefix:@"file:///"]) - icon = [UIImage imageAtPath:[icon_ substringFromIndex:7]]; + if ([static_cast(icon_) hasPrefix:@"file:///"]) + // XXX: correct escaping + icon = [UIImage imageAtPath:[static_cast(icon_) substringFromIndex:7]]; if (icon == nil) if (section != nil) icon = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]; if (icon == nil) if (source_ != nil) if (NSString *dicon = [source_ defaultIcon]) if ([dicon hasPrefix:@"file:///"]) + // XXX: correct escaping icon = [UIImage imageAtPath:[dicon substringFromIndex:7]]; if (icon == nil) icon = [UIImage applicationImageNamed:@"unknown.png"]; @@ -3088,7 +3076,7 @@ static NSString *Warning_; return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:pool_ database:self]; } } -- (Database *) init { +- (id) init { if ((self = [super init]) != nil) { policy_ = NULL; records_ = NULL; @@ -3596,7 +3584,8 @@ static NSString *Warning_; return; if ([self popErrorWithTitle:title forOperation:ListUpdate(status, list, PulseInterval_)]) - /* XXX: ignore this because users suck and don't understand why refreshing is important: return */; + /* XXX: ignore this because users suck and don't understand why refreshing is important: return */ + /* XXX: why the hell is an empty if statement a clang error? */ (void) 0; [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"]; Changed_ = true; @@ -3616,7 +3605,7 @@ static NSString *Warning_; @end /* }}} */ -/* Confirmation View {{{ */ +/* Confirmation Controller {{{ */ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!iterator.end()) for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) { @@ -3867,7 +3856,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { id values[count]; for (unsigned i(0); i != count; ++i) values[i] = [arguments objectAtIndex:i]; - return [[[NSString alloc] initWithFormat:format arguments:reinterpret_cast(values)] autorelease]; + return [[[NSString alloc] initWithFormat:format arguments:*(reinterpret_cast(&values))] autorelease]; } - (NSString *) localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)table { @@ -3881,15 +3870,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Cydia View Controller {{{ */ -@interface CYViewController : UCViewController { } -@end - -@implementation CYViewController -@end -/* }}} */ - -@interface CYBrowserController : BrowserView { +/* Cydia Browser Controller {{{ */ +@interface CYBrowserController : BrowserController { CydiaObject *cydia_; } @@ -3954,7 +3936,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (id) init { - if ((self = [super initWithWidth:[[self view] bounds].size.width ofClass:[CYBrowserController class]]) != nil) { + if ((self = [super initWithWidth:0 ofClass:[CYBrowserController class]]) != nil) { cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_]; WebView *webview([document_ webView]); @@ -3978,14 +3960,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } @end +/* }}} */ -@protocol ConfirmationViewDelegate +/* Confirmation {{{ */ +@protocol ConfirmationControllerDelegate - (void) cancelAndClear:(bool)clear; - (void) confirmWithNavigationController:(UINavigationController *)navigation; - (void) queue; @end -@interface ConfirmationView : CYBrowserController { +@interface ConfirmationController : CYBrowserController { _transient Database *database_; UIAlertView *essential_; NSArray *changes_; @@ -3998,7 +3982,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end -@implementation ConfirmationView +@implementation ConfirmationController - (void) dealloc { [changes_ release]; @@ -4010,22 +3994,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super dealloc]; } -- (void) actionSheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)button { - NSString *context([sheet context]); - - if ([context isEqualToString:@"cancel"]) { - bool clear; - - if (button == [sheet cancelButtonIndex]) return; - else if (button == [sheet destructiveButtonIndex]) clear = true; - else clear = false; - - [sheet dismissWithClickedButtonIndex:0xDEADBEEF animated:YES]; - [self dismissModalViewControllerAnimated:YES]; - [delegate_ cancelAndClear:clear]; - } -} - - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button { NSString *context([alert context]); @@ -4047,11 +4015,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } +- (id) invokeDefaultMethodWithArguments:(NSArray *)args { + [self dismissModalViewControllerAnimated:YES]; + [delegate_ cancelAndClear:NO]; + + return nil; +} + - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { [super webView:sender didClearWindowObject:window forFrame:frame]; [window setValue:changes_ forKey:@"changes"]; [window setValue:issues_ forKey:@"issues"]; [window setValue:sizes_ forKey:@"sizes"]; + [window setValue:self forKey:@"queue"]; } - (id) initWithDatabase:(Database *)database { @@ -4142,7 +4118,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"confirm" ofType:@"html"]]]; UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] - initWithTitle:[NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")] + initWithTitle:UCLocalize("CANCEL") + // OLD: [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")] style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonClicked) @@ -4152,7 +4129,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } return self; } -- (void) didFinishLoading { +- (void) applyRightButton { UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:UCLocalize("CONFIRM") style:UIBarButtonItemStylePlain @@ -4160,27 +4137,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { action:@selector(confirmButtonClicked) ]; #if !AlwaysReload && !IgnoreInstall - if (issues_ == nil) [[self navigationItem] setRightBarButtonItem:rightItem]; - else [[self navigationItem] setRightBarButtonItem:nil]; + if (issues_ == nil && ![self isLoading]) [[self navigationItem] setRightBarButtonItem:rightItem]; + else [super applyRightButton]; +#else + [[self navigationItem] setRightBarButtonItem:nil]; #endif [rightItem release]; } - (void) cancelButtonClicked { - UIActionSheet *sheet = [[UIActionSheet alloc] - initWithTitle:nil - delegate:self - cancelButtonTitle:nil - destructiveButtonTitle:nil - otherButtonTitles:nil - ]; - - [sheet addButtonWithTitle:UCLocalize("CANCEL_CLEAR")]; - [sheet setDestructiveButtonIndex:[sheet numberOfButtons] - 1]; - [sheet addButtonWithTitle:UCLocalize("CONTINUE_QUEUING")]; - [sheet setContext:@"cancel"]; - - [delegate_ showActionSheet:[sheet autorelease] fromItem:[[self navigationItem] leftBarButtonItem]]; + [self dismissModalViewControllerAnimated:YES]; + [delegate_ cancelAndClear:YES]; } #if !AlwaysReload @@ -4239,8 +4206,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Progress View {{{ */ -@interface ProgressView : CYViewController < +/* Progress Controller {{{ */ +@interface ProgressController : CYViewController < ConfigurationDelegate, ProgressDelegate > { @@ -4265,11 +4232,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end -@protocol ProgressViewDelegate -- (void) progressViewIsComplete:(ProgressView *)sender; +@protocol ProgressControllerDelegate +- (void) progressControllerIsComplete:(ProgressController *)sender; @end -@implementation ProgressView +@implementation ProgressController - (void) dealloc { [database_ setDelegate:nil]; @@ -4288,7 +4255,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [database_ setDelegate:self]; delegate_ = delegate; - [[self view] setBackgroundColor:(CGColor *)[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]]; + [[self view] setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]]; progress_ = [[UIProgressBar alloc] init]; [progress_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)]; @@ -4334,7 +4301,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { (bounds.size.width - prgsize.width) / 2, bounds.size.height - prgsize.height - 64 }, prgsize}; - + float closewidth = bounds.size.width - 20; if (closewidth > 300) closewidth = 300; @@ -4362,8 +4329,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) viewWillAppear:(BOOL)animated { [super viewDidAppear:animated]; [[self navigationItem] setHidesBackButton:YES]; - [[[self navigationController] navigationBar] setBarStyle:1]; - + [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack]; + [self positionViews]; } @@ -4385,6 +4352,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) closeButtonPushed { running_ = NO; + UpdateExternalStatus(0); + switch (Finish_) { case 0: [self dismissModalViewControllerAnimated:YES]; @@ -4420,7 +4389,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [status_ removeFromSuperview]; [database_ popErrorWithTitle:title_]; - [delegate_ progressViewIsComplete:self]; + [delegate_ progressControllerIsComplete:self]; if (Finish_ < 4) { FileFd file; @@ -4458,6 +4427,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { system("su -c /usr/bin/uicache mobile"); + UpdateExternalStatus(Finish_ == 0 ? 2 : 0); + [delegate_ setStatusBarShowsProgress:NO]; } @@ -4469,6 +4440,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title { + UpdateExternalStatus(1); + if (title_ != nil) [title_ release]; if (title == nil) @@ -4639,8 +4612,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* }}} */ /* Cell Content View {{{ */ +@protocol ContentDelegate +- (void) drawContentRect:(CGRect)rect; +@end + @interface ContentView : UIView { - _transient id delegate_; + _transient id delegate_; } @end @@ -4653,7 +4630,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } return self; } -- (void) setDelegate:(id)delegate { +- (void) setDelegate:(id)delegate { delegate_ = delegate; } @@ -4664,7 +4641,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Package Cell {{{ */ -@interface PackageCell : UITableViewCell { +@interface PackageCell : UITableViewCell < + ContentDelegate +> { UIImage *icon_; NSString *name_; NSString *description_; @@ -4855,12 +4834,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!selected) UISetColor(commercial_ ? Purple_ : Black_); - [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ ellipsis:2]; - [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ ellipsis:2]; + [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]; if (!selected) UISetColor(commercial_ ? Purplish_ : Gray_); - [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ ellipsis:2]; + [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation]; if (placard_ != nil) [placard_ drawAtPoint:CGPointMake(width - 52, 9)]; @@ -4879,7 +4858,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Section Cell {{{ */ -@interface SectionCell : UITableViewCell { +@interface SectionCell : UITableViewCell < + ContentDelegate +> { NSString *basic_; NSString *section_; NSString *name_; @@ -4890,7 +4871,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { BOOL editing_; } -- (id) init; - (void) setSection:(Section *)section editing:(BOOL)editing; @end @@ -4987,7 +4967,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [switch_ setOn:(isSectionVisible(basic_) ? 1 : 0) animated:NO]; } - [self setAccessoryType:editing ? 0 : 1 /*UITableViewCellAccessoryDisclosureIndicator*/]; + [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator]; [content_ setNeedsDisplay]; } @@ -5000,7 +4980,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) drawContentRect:(CGRect)rect { BOOL selected = [self isSelected]; - + [icon_ drawInRect:CGRectMake(8, 7, 32, 32)]; if (selected) @@ -5013,7 +4993,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (editing_) width -= 87; - [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(width - 70) withFont:Font22Bold_ ellipsis:2]; + [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(width - 70) withFont:Font22Bold_ lineBreakMode:UILineBreakModeTailTruncation]; CGSize size = [count_ sizeWithFont:Font14_]; @@ -5026,7 +5006,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* }}} */ /* File Table {{{ */ -@interface FileTable : CYViewController { +@interface FileTable : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; Package *package_; NSString *name_; @@ -5051,13 +5034,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super dealloc]; } -- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section { +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return files_ == nil ? 0 : [files_ count]; } -- (float) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return 24; -} +/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 24.0f; +}*/ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *reuseIdentifier = @"Cell"; @@ -5068,7 +5051,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [cell setFont:[UIFont systemFontOfSize:16]]; } [cell setText:[files_ objectAtIndex:indexPath.row]]; - [cell setSelectionStyle:0 /*UITableViewCellSelectionStyleNone*/]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; return cell; } @@ -5082,6 +5065,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { files_ = [[NSMutableArray arrayWithCapacity:32] retain]; list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; + [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:24.0f]; [[self view] addSubview:list_]; [list_ setDataSource:self]; @@ -5140,8 +5125,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Package View {{{ */ -@interface PackageView : CYBrowserController { +/* Package Controller {{{ */ +@interface PackageController : CYBrowserController < + UIActionSheetDelegate +> { _transient Database *database_; Package *package_; NSString *name_; @@ -5154,7 +5141,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end -@implementation PackageView +@implementation PackageController - (void) dealloc { if (package_ != nil) @@ -5167,7 +5154,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) release { if ([self retainCount] == 1) - [delegate_ setPackageView:self]; + [delegate_ setPackageController:self]; [super release]; } @@ -5194,10 +5181,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSString *buttonName = [buttons_ objectAtIndex:button]; [self _clickButtonWithName:buttonName]; } - + [sheet dismissWithClickedButtonIndex:-1 animated:YES]; - } else { - [super alertSheet:sheet clickedButtonAtIndex:button]; } } @@ -5215,7 +5200,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } #if !AlwaysReload -- (void) _actionButtonClicked { +- (void) _customButtonClicked { int count([buttons_ count]); if (count == 0) return; @@ -5240,16 +5225,36 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [sheet setCancelButtonIndex:[sheet numberOfButtons] - 1]; } [sheet setContext:@"modify"]; - + [delegate_ showActionSheet:sheet fromItem:[[self navigationItem] rightBarButtonItem]]; } } -- (void) actionButtonClicked { - if (commercial_ && [self isLoading]) - [super _rightButtonClicked]; +// We don't want to allow non-commercial packages to do custom things to the install button, +// so it must call customButtonClicked with a custom commercial_ == 1 fallthrough. +- (void) customButtonClicked { + if (commercial_) + [super customButtonClicked]; else - [self _actionButtonClicked]; + [self _customButtonClicked]; +} + +- (void) reloadButtonClicked { + // Don't reload a package view by clicking the button. +} + +- (void) applyLoadingTitle { + // Don't show "Loading" as the title. Ever. +} + +- (UIBarButtonItem *) rightButton { + int count = [buttons_ count]; + return [[[UIBarButtonItem alloc] + initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0] + style:UIBarButtonItemStylePlain + target:self + action:@selector(customButtonClicked) + ] autorelease]; } #endif @@ -5295,7 +5300,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (special_ != NULL) { CGRect frame([document_ frame]); - frame.size.width = 320; frame.size.height = 0; [document_ setFrame:frame]; @@ -5319,18 +5323,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } -- (void) didFinishLoading { - int count = [buttons_ count]; - UIBarButtonItem *actionItem = [[UIBarButtonItem alloc] - initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0] - style:UIBarButtonItemStylePlain - target:self - action:@selector(actionButtonClicked) - ]; - [[self navigationItem] setRightBarButtonItem:actionItem]; - [actionItem release]; -} - - (bool) isLoading { return commercial_ ? [super isLoading] : false; } @@ -5342,7 +5334,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Package Table {{{ */ -@interface PackageTable : UIView { +@interface PackageTable : UIView < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; NSMutableArray *packages_; NSMutableArray *sections_; @@ -5406,7 +5401,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path { - PackageCell *cell([table dequeueReusableCellWithIdentifier:@"Package"]); + PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]); if (cell == nil) cell = [[[PackageCell alloc] init] autorelease]; [cell setPackage:[self packageAtIndexPath:path]]; @@ -5417,10 +5412,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; } -- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path { - return 73; +/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path { return [PackageCell heightForPackage:[self packageAtIndexPath:path]]; -} +}*/ - (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path { Package *package([self packageAtIndexPath:path]); @@ -5452,6 +5446,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:73.0f]; [self addSubview:list_]; [list_ setDataSource:self]; @@ -5593,8 +5588,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Filtered Package View {{{ */ -@interface FilteredPackageView : CYViewController { +/* Filtered Package Controller {{{ */ +@interface FilteredPackageController : CYViewController { _transient Database *database_; FilteredPackageTable *packages_; NSString *title_; @@ -5603,13 +5598,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object; @end - -@implementation FilteredPackageView + +@implementation FilteredPackageController - (void) dealloc { [packages_ release]; [title_ release]; - + [super dealloc]; } @@ -5619,13 +5614,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) didSelectPackage:(Package *)package { - PackageView *view([delegate_ packageView]); + PackageController *view([delegate_ packageController]); [view setPackage:package]; [view setDelegate:delegate_]; [[self navigationController] pushViewController:view animated:YES]; } -- (id) title { return title_; } +- (NSString *) title { return title_; } - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object { if ((self = [super init]) != nil) { @@ -5657,11 +5652,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } @end - + /* }}} */ -/* Add Source View {{{ */ -@interface AddSourceView : CYViewController { +/* Add Source Controller {{{ */ +@interface AddSourceController : CYViewController { _transient Database *database_; } @@ -5669,7 +5664,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end -@implementation AddSourceView +@implementation AddSourceController - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { @@ -5680,7 +5675,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ /* Source Cell {{{ */ -@interface SourceCell : UITableViewCell { +@interface SourceCell : UITableViewCell < + ContentDelegate +> { UIImage *icon_; NSString *origin_; NSString *description_; @@ -5708,7 +5705,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) setSource:(Source *)source { [self clearSource]; - + if (icon_ == nil) icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sources/%@.png", [source host]]]; if (icon_ == nil) @@ -5760,21 +5757,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (!selected) UISetColor(Black_); - [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ ellipsis:2]; + [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; if (!selected) UISetColor(Blue_); - [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ ellipsis:2]; + [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; if (!selected) UISetColor(Gray_); - [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 40) withFont:Font14_ ellipsis:2]; + [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 40) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation]; } @end /* }}} */ /* Source Table {{{ */ -@interface SourceTable : CYViewController { +@interface SourceTable : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; UITableView *list_; NSMutableArray *sources_; @@ -5795,6 +5795,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) initWithDatabase:(Database *)database; +- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated; + @end @implementation SourceTable @@ -5831,11 +5833,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; } -- (int) numberOfSectionsInTableView:(UITableView *)tableView { +- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return offset_ == 0 ? 1 : 2; } -- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(int)section { +- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { switch (section + (offset_ == 0 ? 1 : 0)) { case 0: return UCLocalize("ENTERED_BY_USER"); case 1: return UCLocalize("INSTALLED_BY_PACKAGE"); @@ -5844,7 +5846,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } -- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section { +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { int count = [sources_ count]; switch (section) { case 0: return (offset_ == 0 ? count : offset_); @@ -5876,18 +5878,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { SourceCell *cell = (SourceCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(cell == nil) cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease]; [cell setSource:[self sourceAtIndexPath:indexPath]]; - + return cell; } -- (int) tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath { - return 1; //UITableViewCellAccessoryDisclosureIndicator? +- (UITableViewCellAccessoryType) tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath { + return UITableViewCellAccessoryDisclosureIndicator; } - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { Source *source = [self sourceAtIndexPath:indexPath]; - FilteredPackageView *packages = [[[FilteredPackageView alloc] + FilteredPackageController *packages = [[[FilteredPackageController alloc] initWithDatabase:database_ title:[source label] filter:@selector(isVisibleInSource:) @@ -6035,7 +6037,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self _endConnection:connection]; } -- (id)title { return UCLocalize("SOURCES"); } +- (NSString *) title { return UCLocalize("SOURCES"); } - (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method { NSMutableURLRequest *request = [NSMutableURLRequest @@ -6117,7 +6119,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ((self = [super init]) != nil) { [[self navigationItem] setTitle:UCLocalize("SOURCES")]; [self updateButtonsForEditingStatus:NO animated:NO]; - + database_ = database; sources_ = [[NSMutableArray arrayWithCapacity:16] retain]; @@ -6156,7 +6158,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) addButtonClicked { - /*[book_ pushPage:[[[AddSourceView alloc] + /*[book_ pushPage:[[[AddSourceController alloc] initWithBook:book_ database:database_ ] autorelease]];*/ @@ -6203,33 +6205,51 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ]; [[self navigationItem] setRightBarButtonItem:rightItem animated:animated]; [rightItem release]; + + if (IsWildcat_ && !editing) { + UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc] + initWithTitle:UCLocalize("SETTINGS") + style:UIBarButtonItemStylePlain + target:self + action:@selector(settingsButtonClicked) + ]; + [[self navigationItem] setLeftBarButtonItem:settingsItem]; + [settingsItem release]; + } +} + +- (void) settingsButtonClicked { + [delegate_ showSettings]; } - (void) editButtonClicked { [list_ setEditing:![list_ isEditing] animated:YES]; - + [self updateButtonsForEditingStatus:[list_ isEditing] animated:YES]; } @end /* }}} */ -/* Installed View {{{ */ -@interface InstalledView : FilteredPackageView { +/* Installed Controller {{{ */ +@interface InstalledController : FilteredPackageController { BOOL expert_; } - (id) initWithDatabase:(Database *)database; +- (void) updateRoleButton; +- (void) queueStatusDidChange; + @end -@implementation InstalledView +@implementation InstalledController - (void) dealloc { [super dealloc]; } -- (id) title { return UCLocalize("INSTALLED"); } +- (NSString *) title { return UCLocalize("INSTALLED"); } - (id) initWithDatabase:(Database *)database { if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndVisible:) with:[NSNumber numberWithBool:YES]]) != nil) { @@ -6291,13 +6311,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Home View {{{ */ -@interface HomeView : CYBrowserController { +/* Home Controller {{{ */ +@interface HomeController : CYBrowserController { } @end -@implementation HomeView +@implementation HomeController - (void) _setMoreHeaders:(NSMutableURLRequest *)request { [super _setMoreHeaders:request]; @@ -6348,18 +6368,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Manage View {{{ */ -@interface ManageView : CYBrowserController { +/* Manage Controller {{{ */ +@interface ManageController : CYBrowserController { } +- (void) queueStatusDidChange; @end -@implementation ManageView +@implementation ManageController - (id) init { if ((self = [super init]) != nil) { [[self navigationItem] setTitle:UCLocalize("MANAGE")]; - + UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc] initWithTitle:UCLocalize("SETTINGS") style:UIBarButtonItemStylePlain @@ -6368,26 +6389,29 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ]; [[self navigationItem] setLeftBarButtonItem:settingsItem]; [settingsItem release]; - + [self queueStatusDidChange]; } return self; } - (void) settingsButtonClicked { - [delegate_ askForSettings]; - [delegate_ updateData]; + [delegate_ showSettings]; } #if !AlwaysReload - (void) queueButtonClicked { [delegate_ queue]; } -#endif -- (void) didFinishLoading { - [self queueStatusDidChange]; +- (void) applyLoadingTitle { + // No "Loading" title. } +- (void) applyRightButton { + // No right button. +} +#endif + - (void) queueStatusDidChange { #if !AlwaysReload if (!IsWildcat_ && Queuing_) { @@ -6398,7 +6422,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { action:@selector(queueButtonClicked) ]; [[self navigationItem] setRightBarButtonItem:queueItem]; - + [queueItem release]; } else { [[self navigationItem] setRightBarButtonItem:nil]; @@ -6425,71 +6449,74 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation RefreshBar +- (void) positionViews { + CGRect frame = [cancel_ frame]; + 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 prgsize = {75, 100}; + CGRect prgrect = {{ + [self frame].size.width - prgsize.width - 10, + ([self frame].size.height - prgsize.height) / 2 + } , prgsize}; + [progress_ setFrame:prgrect]; + + 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])) { [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [self setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]]; - [self setBarStyle:1]; + [self setBarStyle:UIBarStyleBlack]; - int barstyle([self _barStyle:NO]); - bool ugly(barstyle == 0); + UIBarStyle barstyle([self _barStyle:NO]); + bool ugly(barstyle == UIBarStyleDefault); UIProgressIndicatorStyle style = ugly ? UIProgressIndicatorStyleMediumBrown : UIProgressIndicatorStyleMediumWhite; - CGSize indsize([UIProgressIndicator defaultSizeForStyle:style]); - unsigned indoffset = ([self frame].size.height - indsize.height) / 2; - CGRect indrect = {{indoffset, indoffset}, indsize}; - - indicator_ = [[UIProgressIndicator alloc] initWithFrame:indrect]; + indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectZero]; [indicator_ setStyle:style]; + [indicator_ startAnimation]; [self addSubview:indicator_]; - CGSize prmsize = {215, indsize.height + 4}; - - CGRect prmrect = {{ - indoffset * 2 + indsize.width, - unsigned([self frame].size.height - prmsize.height) / 2 - 1 - }, prmsize}; - - UIFont *font([UIFont systemFontOfSize:15]); - - prompt_ = [[UITextLabel alloc] initWithFrame:prmrect]; - + prompt_ = [[UITextLabel alloc] initWithFrame:CGRectZero]; [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]]; [prompt_ setBackgroundColor:[UIColor clearColor]]; - [prompt_ setFont:font]; - + [prompt_ setFont:[UIFont systemFontOfSize:15]]; [self addSubview:prompt_]; - CGSize prgsize = {75, 100}; - - CGRect prgrect = {{ - [self frame].size.width - prgsize.width - 10, - ([self frame].size.height - prgsize.height) / 2 - } , prgsize}; - - progress_ = [[UIProgressBar alloc] initWithFrame:prgrect]; - [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; - [self addSubview:progress_]; - + progress_ = [[UIProgressBar alloc] initWithFrame:CGRectZero]; + [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin]; [progress_ setStyle:0]; + [self addSubview:progress_]; cancel_ = [[UINavigationButton alloc] initWithTitle:UCLocalize("CANCEL") style:UINavigationButtonStyleHighlighted]; - [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; [cancel_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; [cancel_ addTarget:delegate action:@selector(cancelPressed) forControlEvents:UIControlEventTouchUpInside]; + [cancel_ setBarStyle:barstyle]; - CGRect frame = [cancel_ frame]; - 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]; - - [cancel_ setBarStyle:barstyle]; - - [indicator_ startAnimation]; + [self positionViews]; } return self; } @@ -6518,12 +6545,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ +@class CYNavigationController; + /* Cydia Tab Bar Controller {{{ */ @interface CYTabBarController : UITabBarController { Database *database_; } -@end +@end @implementation CYTabBarController @@ -6533,12 +6562,12 @@ freeing the view controllers on tab change */ - (void) reloadData { size_t count([[self viewControllers] count]); for (size_t i(0); i != count; ++i) { - UIViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); + CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); [page reloadData]; } } -- (id) initWithDatabase: (Database *)database { +- (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; } return self; @@ -6548,11 +6577,9 @@ freeing the view controllers on tab change */ /* }}} */ /* Cydia Navigation Controller {{{ */ -@interface CYNavigationController : UINavigationController < - ProgressDelegate -> { +@interface CYNavigationController : UINavigationController { _transient Database *database_; - id delegate_; + id delegate_; } - (id) initWithDatabase:(Database *)database; @@ -6579,12 +6606,12 @@ freeing the view controllers on tab change */ - (void) reloadData { size_t count([[self viewControllers] count]); for (size_t i(0); i != count; ++i) { - UIViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); + CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]); [page reloadData]; } } -- (void) setDelegate:(id)delegate { +- (void) setDelegate:(id)delegate { delegate_ = delegate; } @@ -6697,8 +6724,11 @@ freeing the view controllers on tab change */ @end /* }}} */ -/* Sections View {{{ */ -@interface SectionsView : CYViewController { +/* Sections Controller {{{ */ +@interface SectionsController : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; NSMutableArray *sections_; NSMutableArray *filtered_; @@ -6711,9 +6741,11 @@ freeing the view controllers on tab change */ - (void) reloadData; - (void) resetView; +- (void) editButtonClicked; + @end -@implementation SectionsView +@implementation SectionsController - (void) dealloc { [list_ setDataSource:nil]; @@ -6736,13 +6768,13 @@ freeing the view controllers on tab change */ return section; } -- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section { +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return editing_ ? [sections_ count] : [filtered_ count] + 1; } -- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return 45; -} +/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 45.0f; +}*/ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *reuseIdentifier = @"SectionCell"; @@ -6773,7 +6805,7 @@ freeing the view controllers on tab change */ } } - FilteredPackageView *table = [[[FilteredPackageView alloc] + FilteredPackageController *table = [[[FilteredPackageController alloc] initWithDatabase:database_ title:title filter:@selector(isVisibleInSection:) @@ -6785,7 +6817,7 @@ freeing the view controllers on tab change */ [[self navigationController] pushViewController:table animated:YES]; } -- (id) title { return UCLocalize("SECTIONS"); } +- (NSString *) title { return UCLocalize("SECTIONS"); } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { @@ -6798,6 +6830,7 @@ freeing the view controllers on tab change */ list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:45.0f]; [[self view] addSubview:list_]; [list_ setDataSource:self]; @@ -6896,7 +6929,7 @@ freeing the view controllers on tab change */ target:self action:@selector(editButtonClicked) ]; - [[self navigationItem] setRightBarButtonItem:rightItem]; + [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] != nil]; [rightItem release]; [list_ reloadData]; @@ -6913,7 +6946,7 @@ freeing the view controllers on tab change */ [list_ reloadData]; else [delegate_ updateData]; - + [[self navigationItem] setTitle:editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")]; [[[self navigationItem] rightBarButtonItem] setTitle:[sections_ count] == 0 ? nil : editing_ ? UCLocalize("DONE") : UCLocalize("EDIT")]; [[[self navigationItem] rightBarButtonItem] setStyle:editing_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain]; @@ -6925,13 +6958,17 @@ freeing the view controllers on tab change */ @end /* }}} */ -/* Changes View {{{ */ -@interface ChangesView : CYViewController { +/* Changes Controller {{{ */ +@interface ChangesController : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; NSMutableArray *packages_; NSMutableArray *sections_; UITableView *list_; unsigned upgrades_; + BOOL hasSentFirstLoad_; } - (id) initWithDatabase:(Database *)database delegate:(id)delegate; @@ -6939,7 +6976,7 @@ freeing the view controllers on tab change */ @end -@implementation ChangesView +@implementation ChangesController - (void) dealloc { [list_ setDelegate:nil]; @@ -6953,7 +6990,12 @@ freeing the view controllers on tab change */ - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; + if (!hasSentFirstLoad_) { + hasSentFirstLoad_ = YES; + [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0]; + } else { + [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated]; + } } - (NSInteger) numberOfSectionsInTableView:(UITableView *)list { @@ -6980,21 +7022,20 @@ freeing the view controllers on tab change */ } - (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path { - PackageCell *cell([table dequeueReusableCellWithIdentifier:@"Package"]); + PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]); if (cell == nil) cell = [[[PackageCell alloc] init] autorelease]; [cell setPackage:[self packageAtIndexPath:path]]; return cell; } -- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path { - return 73; +/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path { return [PackageCell heightForPackage:[self packageAtIndexPath:path]]; -} +}*/ - (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path { Package *package([self packageAtIndexPath:path]); - PackageView *view([delegate_ packageView]); + PackageController *view([delegate_ packageController]); [view setDelegate:delegate_]; [view setPackage:package]; [[self navigationController] pushViewController:view animated:YES]; @@ -7002,7 +7043,7 @@ freeing the view controllers on tab change */ } - (void) refreshButtonClicked { - [[UIApplication sharedApplication] beginUpdate]; + [delegate_ beginUpdate]; [[self navigationItem] setLeftBarButtonItem:nil]; } @@ -7010,7 +7051,7 @@ freeing the view controllers on tab change */ [delegate_ distUpgrade]; } -- (id) title { return UCLocalize("CHANGES"); } +- (NSString *) title { return UCLocalize("CHANGES"); } - (id) initWithDatabase:(Database *)database delegate:(id)delegate { if ((self = [super init]) != nil) { @@ -7022,13 +7063,13 @@ freeing the view controllers on tab change */ list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [list_ setRowHeight:73.0f]; [[self view] addSubview:list_]; [list_ setDataSource:self]; [list_ setDelegate:self]; delegate_ = delegate; - [self reloadData]; } return self; } @@ -7078,7 +7119,7 @@ freeing the view controllers on tab change */ unseens = true; NSDate *seen; - _profile(ChangesView$reloadData$Remember) + _profile(ChangesController$reloadData$Remember) seen = [package seen]; _end @@ -7093,7 +7134,7 @@ freeing the view controllers on tab change */ [name autorelease]; } - _profile(ChangesView$reloadData$Allocate) + _profile(ChangesController$reloadData$Allocate) name = [NSString stringWithFormat:UCLocalize("NEW_AT"), name]; section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease]; [sections_ addObject:section]; @@ -7141,15 +7182,17 @@ freeing the view controllers on tab change */ target:self action:@selector(refreshButtonClicked) ]; - if (![[UIApplication sharedApplication] updating]) [[self navigationItem] setLeftBarButtonItem:leftItem]; + if (![delegate_ updating]) [[self navigationItem] setLeftBarButtonItem:leftItem]; [leftItem release]; } @end /* }}} */ -/* Search View {{{ */ -@interface SearchView : FilteredPackageView { - id search_; +/* Search Controller {{{ */ +@interface SearchController : FilteredPackageController < + UISearchBarDelegate +> { + UISearchBar *search_; } - (id) initWithDatabase:(Database *)database; @@ -7157,71 +7200,84 @@ freeing the view controllers on tab change */ @end -@implementation SearchView +@implementation SearchController - (void) dealloc { [search_ release]; [super dealloc]; } -- (void) searchBarSearchButtonClicked:(id)searchBar { +- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar { [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)]; [search_ resignFirstResponder]; [self reloadData]; } -- (void) searchBar:(id)searchBar textDidChange:(NSString *)text { +- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text { [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)]; [self reloadData]; } -- (id) title { return nil; } +- (NSString *) title { return nil; } - (id) initWithDatabase:(Database *)database { - if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil]) != nil) { - search_ = [[objc_getClass("UISearchBar") alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)]; + return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if (!search_) { + search_ = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, 44.0f)]; + [search_ layoutSubviews]; [search_ setPlaceholder:UCLocalize("SEARCH_EX")]; - [search_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; + UITextField *textField = [search_ searchField]; + [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; [search_ setDelegate:self]; - [[search_ searchField] setEnablesReturnKeyAutomatically:NO]; - [[self navigationItem] setTitleView:search_]; - } return self; + [textField setEnablesReturnKeyAutomatically:NO]; + [[self navigationItem] setTitleView:textField]; + } } - (void) _reloadData { } - (void) reloadData { - _profile(SearchView$reloadData) + _profile(SearchController$reloadData) [packages_ reloadData]; _end PrintTimes(); [packages_ resetCursor]; } +- (void) didSelectPackage:(Package *)package { + [search_ resignFirstResponder]; + [super didSelectPackage:package]; +} + @end /* }}} */ -/* Settings View {{{ */ -@interface SettingsView : CYViewController { +/* Settings Controller {{{ */ +@interface SettingsController : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { _transient Database *database_; NSString *name_; Package *package_; - UIPreferencesTable *table_; - _UISwitchSlider *subscribedSwitch_; - _UISwitchSlider *ignoredSwitch_; - UIPreferencesControlTableCell *subscribedCell_; - UIPreferencesControlTableCell *ignoredCell_; + UITableView *table_; + id subscribedSwitch_; + id ignoredSwitch_; + UITableViewCell *subscribedCell_; + UITableViewCell *ignoredCell_; } - (id) initWithDatabase:(Database *)database package:(NSString *)package; @end -@implementation SettingsView +@implementation SettingsController - (void) dealloc { - [table_ setDataSource:nil]; - [name_ release]; if (package_ != nil) [package_ release]; @@ -7230,64 +7286,32 @@ freeing the view controllers on tab change */ [ignoredSwitch_ release]; [subscribedCell_ release]; [ignoredCell_ release]; + [super dealloc]; } -- (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table { +- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { if (package_ == nil) return 0; - return 2; + return 1; } -- (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group { - if (package_ == nil) - return nil; - - switch (group) { - case 0: return nil; - case 1: return nil; - - _nodefault - } - - return nil; -} - -- (BOOL) preferencesTable:(UIPreferencesTable *)table isLabelGroup:(int)group { - if (package_ == nil) - return NO; - - switch (group) { - case 0: return NO; - case 1: return YES; - - _nodefault - } - - return NO; -} - -- (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group { +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (package_ == nil) return 0; - switch (group) { - case 0: return 1; - case 1: return 1; - - _nodefault - } + return 1; +} - return 0; +- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { + return UCLocalize("SHOW_ALL_CHANGES_EX"); } -- (void) onSomething:(UIPreferencesControlTableCell *)cell withKey:(NSString *)key { +- (void) onSomething:(BOOL)value withKey:(NSString *)key { if (package_ == nil) return; - _UISwitchSlider *slider([cell control]); - BOOL value([slider value] != 0); NSMutableDictionary *metadata([package_ metadata]); BOOL before; @@ -7303,37 +7327,21 @@ freeing the view controllers on tab change */ } } -- (void) onSubscribed:(UIPreferencesControlTableCell *)cell { - [self onSomething:cell withKey:@"IsSubscribed"]; +- (void) onSubscribed:(id)control { + [self onSomething:(int) [control isOn] withKey:@"IsSubscribed"]; } -- (void) onIgnored:(UIPreferencesControlTableCell *)cell { - [self onSomething:cell withKey:@"IsIgnored"]; +- (void) onIgnored:(id)control { + [self onSomething:(int) [control isOn] withKey:@"IsIgnored"]; } -- (id) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group { +- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (package_ == nil) return nil; - switch (group) { - case 0: switch (row) { - case 0: - return subscribedCell_; - case 1: - return ignoredCell_; - _nodefault - } break; - - case 1: switch (row) { - case 0: { - UIPreferencesControlTableCell *cell([[[UIPreferencesControlTableCell alloc] init] autorelease]); - [cell setShowSelection:NO]; - [cell setTitle:UCLocalize("SHOW_ALL_CHANGES_EX")]; - return cell; - } - - _nodefault - } break; + switch ([indexPath row]) { + case 0: return subscribedCell_; + case 1: return ignoredCell_; _nodefault } @@ -7341,7 +7349,7 @@ freeing the view controllers on tab change */ return nil; } -- (id) title { return UCLocalize("SETTINGS"); } +- (NSString *) title { return UCLocalize("SETTINGS"); } - (id) initWithDatabase:(Database *)database package:(NSString *)package { if ((self = [super init])) { @@ -7350,26 +7358,29 @@ freeing the view controllers on tab change */ [[self navigationItem] setTitle:UCLocalize("SETTINGS")]; - table_ = [[UIPreferencesTable alloc] initWithFrame:[[self view] bounds]]; + table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped]; + [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [table_ setAllowsSelection:NO]; [[self view] addSubview:table_]; - subscribedSwitch_ = [[_UISwitchSlider alloc] initWithFrame:CGRectMake(200, 10, 50, 20)]; - [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventTouchUpInside]; + subscribedSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; + [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; + [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged]; - ignoredSwitch_ = [[_UISwitchSlider alloc] initWithFrame:CGRectMake(200, 10, 50, 20)]; - [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventTouchUpInside]; + ignoredSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)]; + [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; + [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged]; - subscribedCell_ = [[UIPreferencesControlTableCell alloc] init]; - [subscribedCell_ setShowSelection:NO]; - [subscribedCell_ setTitle:UCLocalize("SHOW_ALL_CHANGES")]; - [subscribedCell_ setControl:subscribedSwitch_]; + subscribedCell_ = [[UITableViewCell alloc] init]; + [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")]; + [subscribedCell_ setAccessoryView:subscribedSwitch_]; - ignoredCell_ = [[UIPreferencesControlTableCell alloc] init]; - [ignoredCell_ setShowSelection:NO]; - [ignoredCell_ setTitle:UCLocalize("IGNORE_UPGRADES")]; - [ignoredCell_ setControl:ignoredSwitch_]; + ignoredCell_ = [[UITableViewCell alloc] init]; + [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")]; + [ignoredCell_ setAccessoryView:ignoredSwitch_]; [table_ setDataSource:self]; + [table_ setDelegate:self]; [self reloadData]; } return self; } @@ -7380,8 +7391,8 @@ freeing the view controllers on tab change */ package_ = [database_ packageWithName:name_]; if (package_ != nil) { [package_ retain]; - [subscribedSwitch_ setValue:([package_ subscribed] ? 1 : 0) animated:NO]; - [ignoredSwitch_ setValue:([package_ ignored] ? 1 : 0) animated:NO]; + [subscribedSwitch_ setOn:([package_ subscribed] ? 1 : 0) animated:NO]; + [ignoredSwitch_ setOn:([package_ ignored] ? 1 : 0) animated:NO]; } [table_ reloadData]; @@ -7390,8 +7401,8 @@ freeing the view controllers on tab change */ @end /* }}} */ -/* Signature View {{{ */ -@interface SignatureView : CYBrowserController { +/* Signature Controller {{{ */ +@interface SignatureController : CYBrowserController { _transient Database *database_; NSString *package_; } @@ -7400,7 +7411,7 @@ freeing the view controllers on tab change */ @end -@implementation SignatureView +@implementation SignatureController - (void) dealloc { [package_ release]; @@ -7424,6 +7435,176 @@ freeing the view controllers on tab change */ [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]]; } +@end +/* }}} */ +/* Role Controller {{{ */ +@interface RoleController : CYViewController < + UITableViewDataSource, + UITableViewDelegate +> { + _transient Database *database_; + id roledelegate_; + UITableView *table_; + UISegmentedControl *segment_; + UIView *container_; +} + +- (void) showDoneButton; +- (void) resizeSegmentedControl; + +@end + +@implementation RoleController +- (void) dealloc { + [table_ release]; + [segment_ release]; + [container_ release]; + + [super dealloc]; +} + +- (id) initWithDatabase:(Database *)database delegate:(id)delegate { + if ((self = [super init])) { + database_ = database; + roledelegate_ = delegate; + + [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")]; + + NSArray *items = [NSArray arrayWithObjects: + UCLocalize("USER"), + UCLocalize("HACKER"), + UCLocalize("DEVELOPER"), + nil]; + segment_ = [[UISegmentedControl alloc] initWithItems:items]; + container_ = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)]; + [container_ addSubview:segment_]; + + 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]; + + table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped]; + [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [table_ setDelegate:self]; + [table_ setDataSource:self]; + [[self view] addSubview:table_]; + [table_ reloadData]; + } 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) 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) doneButtonClicked { + [self save]; + [[self navigationController] dismissModalViewControllerAnimated:YES]; +} + +- (void) showDoneButton { + UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] + initWithTitle:UCLocalize("DONE") + style:UIBarButtonItemStyleDone + target:self + action:@selector(doneButtonClicked) + ]; + [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] == nil]; + [rightItem release]; +} + +- (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 { + if (section == 3) return 44.0f; + else return 0; +} + +- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + if (section == 3) return container_; + else return nil; +} + @end /* }}} */ @@ -7435,13 +7616,24 @@ freeing the view controllers on tab change */ bool dropped_; bool updating_; id updatedelegate_; - UIViewController *root_; + UITabBarController *root_; } +- (void) setTabBarController:(UITabBarController *)controller; + +- (void) dropBar:(BOOL)animated; +- (void) beginUpdate; +- (void) raiseBar:(BOOL)animated; +- (BOOL) updating; + @end @implementation CYContainer +- (BOOL) _reallyWantsFullScreenLayout { + return YES; +} + // NOTE: UIWindow only sends the top controller these messages, // So we have to forward them on. @@ -7466,10 +7658,10 @@ freeing the view controllers on tab change */ } - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { - return YES; /* XXX: return YES; */ + return IsWildcat_; } -- (void) setRootController:(UIViewController *)controller { +- (void) setTabBarController:(UITabBarController *)controller { root_ = controller; [[self view] addSubview:[root_ view]]; } @@ -7481,9 +7673,9 @@ freeing the view controllers on tab change */ - (void) beginUpdate { [self dropBar:YES]; [refreshbar_ start]; - + updating_ = true; - + [NSThread detachNewThreadSelector:@selector(performUpdate) toTarget:self @@ -7505,7 +7697,7 @@ freeing the view controllers on tab change */ - (void) completeUpdate { updating_ = false; - + [self raiseBar:YES]; [refreshbar_ stop]; [updatedelegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0]; @@ -7574,17 +7766,30 @@ freeing the view controllers on tab change */ updatedelegate_ = delegate; } +- (CGFloat) statusBarHeight { + if (UIInterfaceOrientationIsPortrait([self interfaceOrientation])) { + return [[UIApplication sharedApplication] statusBarFrame].size.height; + } else { + return [[UIApplication sharedApplication] statusBarFrame].size.width; + } +} + - (void) dropBar:(BOOL)animated { if (dropped_) return; dropped_ = true; [[self view] addSubview:refreshbar_]; + CGFloat sboffset = [self statusBarHeight]; + + CGRect barframe = [refreshbar_ frame]; + barframe.origin.y = sboffset; + [refreshbar_ setFrame:barframe]; + if (animated) [UIView beginAnimations:nil context:NULL]; - CGRect barframe = [refreshbar_ frame]; CGRect viewframe = [[root_ view] frame]; - viewframe.origin.y += barframe.size.height; - viewframe.size.height -= barframe.size.height; + viewframe.origin.y += barframe.size.height + sboffset; + viewframe.size.height -= barframe.size.height + sboffset; [[root_ view] setFrame:viewframe]; if (animated) [UIView commitAnimations]; @@ -7602,11 +7807,13 @@ freeing the view controllers on tab change */ [refreshbar_ removeFromSuperview]; + CGFloat sboffset = [self statusBarHeight]; + if (animated) [UIView beginAnimations:nil context:NULL]; CGRect barframe = [refreshbar_ frame]; CGRect viewframe = [[root_ view] frame]; - viewframe.origin.y -= barframe.size.height; - viewframe.size.height += barframe.size.height; + viewframe.origin.y -= barframe.size.height + sboffset; + viewframe.size.height += barframe.size.height + sboffset; [[root_ view] setFrame:viewframe]; if (animated) [UIView commitAnimations]; @@ -7614,31 +7821,40 @@ freeing the view controllers on tab change */ [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation]; } +- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { + // XXX: fix Apple's layout bug + [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation]; +} + - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { if (dropped_) { [self raiseBar:NO]; [self dropBar:NO]; } - + // XXX: fix Apple's layout bug [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation]; +} - // Resize refresh bar to fit the new size - CGRect barframe = [refreshbar_ frame]; - barframe.size.width = [[self view] frame].size.width; - [refreshbar_ setFrame:barframe]; +- (void) statusBarFrameChanged:(NSNotification *)notification { + if (dropped_) { + [self raiseBar:NO]; + [self dropBar:NO]; + } } - (void) dealloc { [refreshbar_ release]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } -- (id) initWithDatabase: (Database *)database { +- (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; refreshbar_ = [[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self]; } return self; @@ -7658,9 +7874,10 @@ typedef enum { } CYTabTag; @interface Cydia : UIApplication < - ConfirmationViewDelegate, - ProgressViewDelegate, - CydiaDelegate + ConfirmationControllerDelegate, + ProgressControllerDelegate, + CydiaDelegate, + UINavigationControllerDelegate > { UIWindow *window_; CYContainer *container_; @@ -7677,12 +7894,12 @@ typedef enum { UIKeyboard *keyboard_; UIProgressHUD *hud_; - SectionsView *sections_; - ChangesView *changes_; - ManageView *manage_; - SearchView *search_; + SectionsController *sections_; + ChangesController *changes_; + ManageController *manage_; + SearchController *search_; SourceTable *sources_; - InstalledView *installed_; + InstalledController *installed_; id queueDelegate_; #if RecyclePackageViews @@ -7692,13 +7909,14 @@ typedef enum { bool loaded_; } -- (UIViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class; -- (void) setPage:(UIViewController *)page; +- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class; +- (void) setPage:(CYViewController *)page; +- (void) loadData; @end static _finline void _setHomePage(Cydia *self) { - [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeView class]]]; + [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeController class]]]; } @implementation Cydia @@ -7775,7 +7993,7 @@ static _finline void _setHomePage(Cydia *self) { if (tag_ != 4 && search_ != nil) [search_ reloadData]; - [[tabbar_ selectedViewController] reloadData]; + [(CYNavigationController *)[tabbar_ selectedViewController] reloadData]; } - (int)indexOfTabWithTag:(int)tag { @@ -7784,17 +8002,32 @@ static _finline void _setHomePage(Cydia *self) { if ([[controller tabBarItem] tag] == tag) return i; i += 1; } - + return -1; } - (void) _refreshIfPossible { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - Reachability* reachability = [Reachability reachabilityWithHostName:@"cydia.saurik.com"]; - NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus]; - - if (loaded_ || ManualRefresh || remoteHostStatus == NotReachable) loaded: + + SCNetworkReachabilityFlags flags; { + SCNetworkReachabilityRef reachability(SCNetworkReachabilityCreateWithName(NULL, "cydia.saurik.com")); + SCNetworkReachabilityGetFlags(reachability, &flags); + CFRelease(reachability); + } + + // XXX: this elaborate mess is what Apple is using to determine this? :( + // XXX: do we care if the user has to intervene? maybe that's ok? + bool reachable( + (flags & kSCNetworkReachabilityFlagsReachable) != 0 && ( + (flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0 || ( + (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0 || + (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0 + ) && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0 || + (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0 + ) + ); + + if (loaded_ || ManualRefresh || !reachable) loaded: [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO]; else { loaded_ = true; @@ -7818,8 +8051,6 @@ static _finline void _setHomePage(Cydia *self) { } - (void) _reloadData { - UIView *block(); - UIProgressHUD *hud([self addProgressHUD]); [hud setText:(loaded_ ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))]; @@ -7848,7 +8079,7 @@ static _finline void _setHomePage(Cydia *self) { NSString *badge([[NSNumber numberWithInt:changes] stringValue]); [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:badge]; [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:YES]; - + if ([self respondsToSelector:@selector(setApplicationBadge:)]) [self setApplicationBadge:badge]; else @@ -7856,7 +8087,7 @@ static _finline void _setHomePage(Cydia *self) { } else { [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:nil]; [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:NO]; - + if ([self respondsToSelector:@selector(removeApplicationBadge)]) [self removeApplicationBadge]; else // XXX: maybe use setApplicationBadgeString also? @@ -7895,8 +8126,8 @@ static _finline void _setHomePage(Cydia *self) { [self _saveConfig]; - ProgressView *progress = [[[ProgressView alloc] initWithDatabase:database_ delegate:self] autorelease]; - UINavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease]; + ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease]; + CYNavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease]; if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet]; [container_ presentModalViewController:navigation animated:YES]; @@ -7930,9 +8161,9 @@ static _finline void _setHomePage(Cydia *self) { if (![database_ prepare]) return false; - ConfirmationView *page([[[ConfirmationView alloc] initWithDatabase:database_] autorelease]); + ConfirmationController *page([[[ConfirmationController alloc] initWithDatabase:database_] autorelease]); [page setDelegate:self]; - id confirm_ = [[CYNavigationController alloc] initWithRootViewController:page]; + CYNavigationController *confirm_ = [[CYNavigationController alloc] initWithRootViewController:page]; [confirm_ setDelegate:self]; if (IsWildcat_) [confirm_ setModalPresentationStyle:UIModalPresentationFormSheet]; @@ -7995,8 +8226,8 @@ static _finline void _setHomePage(Cydia *self) { } - (void) confirmWithNavigationController:(UINavigationController *)navigation { - ProgressView *progress = [[[ProgressView alloc] initWithDatabase:database_ delegate:self] autorelease]; - + ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease]; + if (navigation != nil) { [navigation pushViewController:progress animated:YES]; } else { @@ -8004,7 +8235,7 @@ static _finline void _setHomePage(Cydia *self) { if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet]; [container_ presentModalViewController:navigation animated:YES]; } - + [progress detachNewThreadSelector:@selector(perform) toTarget:database_ @@ -8013,87 +8244,87 @@ static _finline void _setHomePage(Cydia *self) { ]; } -- (void) progressViewIsComplete:(ProgressView *)progress { +- (void) progressControllerIsComplete:(ProgressController *)progress { [self complete]; } -- (void) setPage:(UIViewController *)page { +- (void) setPage:(CYViewController *)page { [page setDelegate:self]; - UINavigationController *navController = [tabbar_ selectedViewController]; - [navController setViewControllers:[NSArray arrayWithObject:page] animated:NO]; - for (UIViewController *page in [tabbar_ viewControllers]) { + CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController]; + [navController setViewControllers:[NSArray arrayWithObject:page]]; + for (CYNavigationController *page in [tabbar_ viewControllers]) { if (page != navController) [page setViewControllers:nil]; } } -- (UIViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class { +- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class { CYBrowserController *browser = [[[_class alloc] init] autorelease]; [browser loadURL:url]; return browser; } -- (SectionsView *) sectionsView { +- (SectionsController *) sectionsController { if (sections_ == nil) - sections_ = [[SectionsView alloc] initWithDatabase:database_]; + sections_ = [[SectionsController alloc] initWithDatabase:database_]; return sections_; } -- (ChangesView *) changesView { +- (ChangesController *) changesController { if (changes_ == nil) - changes_ = [[ChangesView alloc] initWithDatabase:database_ delegate:self]; + changes_ = [[ChangesController alloc] initWithDatabase:database_ delegate:self]; return changes_; } -- (ManageView *) manageView { +- (ManageController *) manageController { if (manage_ == nil) { - manage_ = (ManageView *) [[self + manage_ = (ManageController *) [[self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]] - withClass:[ManageView class] + withClass:[ManageController class] ] retain]; if (!IsWildcat_) queueDelegate_ = manage_; } return manage_; } -- (SearchView *) searchView { +- (SearchController *) searchController { if (search_ == nil) - search_ = [[SearchView alloc] initWithDatabase:database_]; + search_ = [[SearchController alloc] initWithDatabase:database_]; return search_; } -- (SourceTable *) sourcesView { +- (SourceTable *) sourcesController { if (sources_ == nil) sources_ = [[SourceTable alloc] initWithDatabase:database_]; return sources_; } -- (InstalledView *) installedView { +- (InstalledController *) installedController { if (installed_ == nil) { - installed_ = [[InstalledView alloc] initWithDatabase:database_]; + installed_ = [[InstalledController alloc] initWithDatabase:database_]; if (IsWildcat_) queueDelegate_ = installed_; } return installed_; } -- (void) tabBarController:(id)tabBarController didSelectViewController:(UIViewController *)viewController { +- (void) tabBarController:(id)tabBarController didSelectViewController:(UIViewController *)viewController { int tag = [[viewController tabBarItem] tag]; if (tag == tag_) { - [[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES]; + [(CYNavigationController *)[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES]; return; } else if (tag_ == 1) { - [[self sectionsView] resetView]; + [[self sectionsController] resetView]; } switch (tag) { case kCydiaTag: _setHomePage(self); break; - case kSectionsTag: [self setPage:[self sectionsView]]; break; - case kChangesTag: [self setPage:[self changesView]]; break; - case kManageTag: [self setPage:[self manageView]]; break; - case kInstalledTag: [self setPage:[self installedView]]; break; - case kSourcesTag: [self setPage:[self sourcesView]]; break; - case kSearchTag: [self setPage:[self searchView]]; break; + case kSectionsTag: [self setPage:[self sectionsController]]; break; + case kChangesTag: [self setPage:[self changesController]]; break; + case kManageTag: [self setPage:[self manageController]]; break; + case kInstalledTag: [self setPage:[self installedController]]; break; + case kSourcesTag: [self setPage:[self sourcesController]]; break; + case kSearchTag: [self setPage:[self searchController]]; break; _nodefault } @@ -8101,43 +8332,14 @@ static _finline void _setHomePage(Cydia *self) { tag_ = tag; } -- (void) askForSettings { - NSString *parenthetical(UCLocalize("PARENTHETICAL")); - - CYActionSheet *role([[[CYActionSheet alloc] - initWithTitle:UCLocalize("WHO_ARE_YOU") - buttons:[NSArray arrayWithObjects: - [NSString stringWithFormat:parenthetical, UCLocalize("USER"), UCLocalize("USER_EX")], - [NSString stringWithFormat:parenthetical, UCLocalize("HACKER"), UCLocalize("HACKER_EX")], - [NSString stringWithFormat:parenthetical, UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX")], - nil] - defaultButtonIndex:-1 - ] autorelease]); - - [role setMessage:UCLocalize("ROLE_EX")]; - - int button([role yieldToPopupAlertAnimated:YES]); - - switch (button) { - case 1: Role_ = @"User"; break; - case 2: Role_ = @"Hacker"; break; - case 3: Role_ = @"Developer"; break; - - _nodefault - } - - Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys: - Role_, @"Role", - nil]; - - [Metadata_ setObject:Settings_ forKey:@"Settings"]; - - Changed_ = true; - - [role dismiss]; +- (void) showSettings { + RoleController *role = [[RoleController alloc] initWithDatabase:database_ delegate:self]; + CYNavigationController *nav = [[CYNavigationController alloc] initWithRootViewController:role]; + if (IsWildcat_) [nav setModalPresentationStyle:UIModalPresentationFormSheet]; + [container_ presentModalViewController:nav animated:YES]; } -- (void) setPackageView:(PackageView *)view { +- (void) setPackageController:(PackageController *)view { WebThreadLock(); [view setPackage:nil]; #if RecyclePackageViews @@ -8147,19 +8349,19 @@ static _finline void _setHomePage(Cydia *self) { WebThreadUnlock(); } -- (PackageView *) _packageView { - return [[[PackageView alloc] initWithDatabase:database_] autorelease]; +- (PackageController *) _packageController { + return [[[PackageController alloc] initWithDatabase:database_] autorelease]; } -- (PackageView *) packageView { +- (PackageController *) packageController { #if RecyclePackageViews - PackageView *view; + PackageController *view; size_t count([details_ count]); if (count == 0) { - view = [self _packageView]; + view = [self _packageController]; renew: - [details_ addObject:[self _packageView]]; + [details_ addObject:[self _packageController]]; } else { view = [[[details_ lastObject] retain] autorelease]; [details_ removeLastObject]; @@ -8169,39 +8371,50 @@ static _finline void _setHomePage(Cydia *self) { return view; #else - return [self _packageView]; + return [self _packageController]; #endif } +// Returns the navigation controller for the queuing badge. +- (id) queueBadgeController { + int index = [self indexOfTabWithTag:kManageTag]; + if (index == -1) index = [self indexOfTabWithTag:kInstalledTag]; + + return [[tabbar_ viewControllers] objectAtIndex:index]; +} + - (void) cancelAndClear:(bool)clear { @synchronized (self) { if (clear) { - /* XXX: clear marks instead of reloading data */ - /*pkgCacheFile &cache([database_ cache]); + // Clear all marks. + pkgCacheFile &cache([database_ cache]); for (pkgCache::PkgIterator iterator = cache->PkgBegin(); !iterator.end(); ++iterator) { - if (!cache[iterator].Keep()) cache->MarkKeep(iterator, false, false); + // Unmark method taken from Synaptic Package Manager. + // Thanks for being sane, unlike Aptitude. + if (!cache[iterator].Keep()) { + cache->MarkKeep(iterator, false); + cache->SetReInstall(iterator, false); + } } - [self updateData]; - + // Stop queuing. Queuing_ = false; - [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:nil]; - [queueDelegate_ queueStatusDidChange];*/ - [self reloadData]; + [[[self queueBadgeController] tabBarItem] setBadgeValue:nil]; } else { + // Start queuing. Queuing_ = true; - - [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:UCLocalize("Q_D")]; - [[tabbar_ selectedViewController] reloadData]; - - [queueDelegate_ queueStatusDidChange]; - } + [[[self queueBadgeController] tabBarItem] setBadgeValue:UCLocalize("Q_D")]; + } + + // Show the changes in the current view. + [(CYNavigationController *) [tabbar_ selectedViewController] reloadData]; + [queueDelegate_ queueStatusDidChange]; } } - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button { NSString *context([alert context]); - + if ([context isEqualToString:@"fixhalf"]) { if (button == [alert firstOtherButtonIndex]) { @synchronized (self) { @@ -8253,6 +8466,8 @@ static _finline void _setHomePage(Cydia *self) { } - (void) applicationSuspend:(__GSEvent *)event { + // FIXME: This needs to be fixed, but we no longer have a progress_. + // What's the best solution? if (hud_ == nil)// && ![progress_ isRunning]) [super applicationSuspend:event]; } @@ -8273,7 +8488,7 @@ static _finline void _setHomePage(Cydia *self) { [window_ setUserInteractionEnabled:NO]; [hud show:YES]; - [window_ addSubview:hud]; + [[container_ view] addSubview:hud]; return hud; } @@ -8283,9 +8498,9 @@ static _finline void _setHomePage(Cydia *self) { [window_ setUserInteractionEnabled:YES]; } -- (UIViewController *) pageForPackage:(NSString *)name { +- (CYViewController *) pageForPackage:(NSString *)name { if (Package *package = [database_ packageWithName:name]) { - PackageView *view([self packageView]); + PackageController *view([self packageController]); [view setPackage:package]; return view; } else { @@ -8295,7 +8510,7 @@ static _finline void _setHomePage(Cydia *self) { } } -- (UIViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag { +- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag { if (tag != NULL) *tag = -1; @@ -8314,21 +8529,21 @@ static _finline void _setHomePage(Cydia *self) { path = [@"/" stringByAppendingString:path]; if ([path isEqualToString:@"/add-source"]) - return [[[AddSourceView alloc] initWithDatabase:database_] autorelease]; + return [[[AddSourceController alloc] initWithDatabase:database_] autorelease]; else if ([path isEqualToString:@"/storage"]) return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[CYBrowserController class]]; else if ([path isEqualToString:@"/sources"]) return [[[SourceTable alloc] initWithDatabase:database_] autorelease]; else if ([path isEqualToString:@"/packages"]) - return [[[InstalledView alloc] initWithDatabase:database_] autorelease]; + return [[[InstalledController alloc] initWithDatabase:database_] autorelease]; else if ([path hasPrefix:@"/url/"]) return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[CYBrowserController class]]; else if ([path hasPrefix:@"/launch/"]) [self launchApplicationWithIdentifier:[path substringFromIndex:8] suspended:NO]; else if ([path hasPrefix:@"/package-settings/"]) - return [[[SettingsView alloc] initWithDatabase:database_ package:[path substringFromIndex:18]] autorelease]; + return [[[SettingsController alloc] initWithDatabase:database_ package:[path substringFromIndex:18]] autorelease]; else if ([path hasPrefix:@"/package-signature/"]) - return [[[SignatureView alloc] initWithDatabase:database_ package:[path substringFromIndex:19]] autorelease]; + return [[[SignatureController alloc] initWithDatabase:database_ package:[path substringFromIndex:19]] autorelease]; else if ([path hasPrefix:@"/package/"]) return [self pageForPackage:[path substringFromIndex:9]]; else if ([path hasPrefix:@"/files/"]) { @@ -8347,13 +8562,21 @@ static _finline void _setHomePage(Cydia *self) { - (void) applicationOpenURL:(NSURL *)url { [super applicationOpenURL:url]; int tag; - if (UIViewController *page = [self pageForURL:url hasTag:&tag]) { + if (CYViewController *page = [self pageForURL:url hasTag:&tag]) { [self setPage:page]; tag_ = tag; [tabbar_ setSelectedViewController:(tag_ == -1 ? nil : [[tabbar_ viewControllers] objectAtIndex:tag_])]; } } +- (void) applicationWillResignActive:(UIApplication *)application { + // Stop refreshing if you get a phone call or lock the device. + if ([container_ updating]) [container_ cancelUpdate]; + + if ([[self superclass] instancesRespondToSelector:@selector(applicationWillResignActive:)]) + [super applicationWillResignActive:application]; +} + - (void) applicationDidFinishLaunching:(id)unused { [CYBrowserController _initialize]; @@ -8411,36 +8634,28 @@ static _finline void _setHomePage(Cydia *self) { return; } - if (Role_ == nil) - [self askForSettings]; - _trace(); - NSMutableArray *controllers = [NSMutableArray array]; - [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - if (IsWildcat_) [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - [controllers addObject:[[CYNavigationController alloc] initWithDatabase:database_]]; - - NSMutableArray *items = [NSMutableArray arrayWithObjects: + NSMutableArray *items([NSMutableArray arrayWithObjects: [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:kCydiaTag] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:kSectionsTag] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:kChangesTag] autorelease], [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:kSearchTag] autorelease], - nil - ]; - + nil]); + if (IsWildcat_) { [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source.png"] tag:kSourcesTag] autorelease] atIndex:3]; [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:kInstalledTag] autorelease] atIndex:3]; } else { [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:kManageTag] autorelease] atIndex:3]; } - - for (int i = 0; i < [items count]; i++) { - [[controllers objectAtIndex:i] setTabBarItem:[items objectAtIndex:i]]; + + NSMutableArray *controllers([NSMutableArray array]); + + for (UITabBarItem *item in items) { + CYNavigationController *controller([[[CYNavigationController alloc] initWithDatabase:database_] autorelease]); + [controller setTabBarItem:item]; + [controllers addObject:controller]; } tabbar_ = [[CYTabBarController alloc] initWithDatabase:database_]; @@ -8449,19 +8664,27 @@ static _finline void _setHomePage(Cydia *self) { [tabbar_ setSelectedIndex:0]; container_ = [[CYContainer alloc] initWithDatabase:database_]; - [[container_ view] setFrame:[window_ bounds]]; [container_ setUpdateDelegate:self]; - [container_ setRootController:tabbar_]; + [container_ setTabBarController:tabbar_]; [window_ addSubview:[container_ view]]; + [self performSelector:@selector(loadData) withObject:nil afterDelay:0]; +} + +- (void) loadData { + if (Role_ == nil) { + [self showSettings]; + return; + } + [UIKeyboard initImplementationNow]; [self reloadData]; #if RecyclePackageViews details_ = [[NSMutableArray alloc] initWithCapacity:4]; - [details_ addObject:[self _packageView]]; - [details_ addObject:[self _packageView]]; + [details_ addObject:[self _packageController]]; + [details_ addObject:[self _packageController]]; #endif PrintTimes(); @@ -8501,6 +8724,27 @@ MSHook(void, UIWebDocumentView$_setUIKitDelegate$, UIWebDocumentView *self, SEL return _UIWebDocumentView$_setUIKitDelegate$(self, _cmd, delegate); } +static NSNumber *shouldPlayKeyboardSounds; + +Class $UIHardware; + +MSHook(void, UIHardware$_playSystemSound$, Class self, SEL _cmd, int sound) { + switch (sound) { + case 1104: // Keyboard Button Clicked + case 1105: // Keyboard Delete Repeated + if (shouldPlayKeyboardSounds == nil) { + NSDictionary *dict([[[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.apple.preferences.sounds.plist"] autorelease]); + shouldPlayKeyboardSounds = [([dict objectForKey:@"keyboard"] ?: (id) kCFBooleanTrue) retain]; + } + + if (![shouldPlayKeyboardSounds boolValue]) + break; + + default: + _UIHardware$_playSystemSound$(self, _cmd, sound); + } +} + int main(int argc, char *argv[]) { _pooled _trace(); @@ -8513,7 +8757,6 @@ int main(int argc, char *argv[]) { _pooled PackageName = reinterpret_cast(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname)))); /* Library Hacks {{{ */ - class_addMethod(objc_getClass("WebScriptObject"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &WebScriptObject$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16"); class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16"); $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate"); @@ -8522,6 +8765,13 @@ int main(int argc, char *argv[]) { _pooled _UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$)); method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast(&$UIWebDocumentView$_setUIKitDelegate$)); } + + $UIHardware = objc_getClass("UIHardware"); + Method UIHardware$_playSystemSound$(class_getClassMethod($UIHardware, @selector(_playSystemSound:))); + if (UIHardware$_playSystemSound$ != NULL) { + _UIHardware$_playSystemSound$ = reinterpret_cast(method_getImplementation(UIHardware$_playSystemSound$)); + method_setImplementation(UIHardware$_playSystemSound$, reinterpret_cast(&$UIHardware$_playSystemSound$)); + } /* }}} */ /* Set Locale {{{ */ Locale_ = CFLocaleCopyCurrent(); @@ -8758,10 +9008,10 @@ int main(int argc, char *argv[]) { _pooled Warning_ = UCLocalize("WARNING"); _trace(); - int value = UIApplicationMain(argc, argv, @"Cydia", @"Cydia"); + int value(UIApplicationMain(argc, argv, @"Cydia", @"Cydia")); CGColorSpaceRelease(space_); CFRelease(Locale_); return value; -} \ No newline at end of file +}