#define USE_SYSTEM_MALLOC 1
/* #include Directives {{{ */
-#import "UICaboodle/UCPlatform.h"
-#import "UICaboodle/UCLocalize.h"
+#include "UICaboodle/UCPlatform.h"
+#include "UICaboodle/UCLocalize.h"
#include <objc/objc.h>
#include <objc/runtime.h>
#include <CoreGraphics/CoreGraphics.h>
-#include <GraphicsServices/GraphicsServices.h>
#include <Foundation/Foundation.h>
#if 0
#include <CoreFoundation/CFPriv.h>
#include <CoreFoundation/CFUniChar.h>
-#import <UIKit/UIKit.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#include <UIKit/UIKit.h>
+#include "iPhonePrivate.h"
+
+#include <IOKit/IOKitLib.h>
#include <WebCore/WebCoreThread.h>
-#import <WebKit/WebDefaultUIKitDelegate.h>
#include <algorithm>
#include <iomanip>
#include <sys/param.h>
#include <sys/mount.h>
+#include <fcntl.h>
#include <notify.h>
#include <dlfcn.h>
#include <ext/hash_map>
-#import "UICaboodle/BrowserView.h"
-#import "UICaboodle/ResetView.h"
+#include "UICaboodle/BrowserView.h"
-#import "substrate.h"
+#include "substrate.h"
/* }}} */
/* Profiler {{{ */
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;
- (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index {
if ((self = [super init])) {
- [self setTitle:title];
- [self setDelegate:self];
- for (NSString *button in buttons) [self addButtonWithTitle:button];
- [self setCancelButtonIndex:index];
+ [self setTitle:title];
+ [self setDelegate:self];
+ for (NSString *button in buttons) [self addButtonWithTitle:button];
+ [self setCancelButtonIndex:index];
} 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;
}
- (void) dismiss {
- [self dismissWithClickedButtonIndex:-1 animated:YES];
+ [self dismissWithClickedButtonIndex:-1 animated:YES];
}
- (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_;
}
[self setObject:info forKey:[info objectForKey:@"CFBundleIdentifier"]];
}
-@end
-/* }}} */
-/* Pop Transitions {{{ */
-@interface PopTransitionView : UITransitionView {
-}
-
-@end
-
-@implementation PopTransitionView
-
-- (void) transitionViewDidComplete:(UITransitionView *)view fromView:(UIView *)from toView:(UIView *)to {
- if (from != nil && to == nil)
- [self removeFromSuperview];
-}
-
-@end
-
-@implementation UIView (PopUpView)
-
-- (void) popFromSuperviewAnimated:(BOOL)animated {
- [[self superview] transition:(animated ? UITransitionPushFromTop : UITransitionNone) toView:nil];
-}
-
-- (void) popSubview:(UIView *)view {
- UITransitionView *transition([[[PopTransitionView alloc] initWithFrame:[self bounds]] autorelease]);
- [transition setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
- [self addSubview:transition];
-
- [transition setDelegate:transition];
-
- UIView *blank([[[UIView alloc] initWithFrame:[transition bounds]] autorelease]);
- [blank setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
-
- [transition transition:UITransitionNone toView:blank];
- [transition transition:UITransitionPushFromBottom toView:view];
-}
-
@end
/* }}} */
#define lprintf(args...) fprintf(stderr, args)
-#define ForRelease 0
+#define ForRelease 1
#define TraceLogging (1 && !ForRelease)
#define HistogramInsertionSort (0 && !ForRelease)
#define ProfileTimes (0 && !ForRelease)
CFIndex half = count / 2;
const char *probe = ptr + elementSize * half;
CFComparisonResult cr = comparator(element, probe, context);
- if (0 == cr) return (probe - (const char *)list) / elementSize;
+ if (0 == cr) return (probe - (const char *)list) / elementSize;
ptr = (cr < 0) ? ptr : probe + elementSize;
count = (cr < 0) ? half : (half + (count & 1) - 1);
}
CFIndex half = count / 2;
const char *probe = ptr + elementSize * half;
CFComparisonResult cr = comparator(element, probe, context);
- if (0 == cr) return (probe - (const char *)list) / elementSize;
+ if (0 == cr) return (probe - (const char *)list) / elementSize;
ptr = (cr < 0) ? ptr : probe + elementSize;
count = (cr < 0) ? half : (half + (count & 1) - 1);
}
@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;
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)
return length;
}
-@interface NSString (UIKit)
-- (NSString *) stringByAddingPercentEscapes;
-@end
-
/* Cydia NSString Additions {{{ */
@interface NSString (Cydia)
+ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length;
- (NSString *) stringByAddingPercentEscapesIncludingReserved {
return [(id)CFURLCreateStringByAddingPercentEscapes(
- kCFAllocatorDefault,
+ kCFAllocatorDefault,
(CFStringRef) self,
NULL,
CFSTR(";/?:@&=+$,"),
@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);
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() {
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_;
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_;
static CGColorSpaceRef space_;
-static bool reload_;
-
static NSDictionary *SectionMap_;
static NSMutableDictionary *Metadata_;
static _transient NSMutableDictionary *Settings_;
return hidden == nil || ![hidden boolValue];
}
+@class Cydia;
+
/* Delegate Prototypes {{{ */
@class Package;
@class Source;
- (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) showActionSheet:(UIActionSheet *)sheet fromItem:(UIButton *)item;
+- (void) beginUpdate;
+- (BOOL) updating;
- (void) distUpgrade;
+- (void) loadData;
- (void) updateData;
- (void) syncData;
-- (void) askForSettings;
+- (void) showSettings;
- (UIProgressHUD *) addProgressHUD;
- (void) removeProgressHUD:(UIProgressHUD *)hud;
-- (RVPage *) pageForPackage:(NSString *)name;
-- (PackageView *) packageView;
+- (CYViewController *) pageForPackage:(NSString *)name;
+- (PackageController *) packageController;
+- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
@end
/* }}} */
@end
/* }}} */
/* Delegate Helpers {{{ */
-@implementation NSObject(ProgressDelegate)
+@implementation NSObject (ProgressDelegate)
- (void) _setProgressErrorPackage:(NSArray *)args {
[self performSelector:@selector(setProgressError:forPackage:)
- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
Package *package = id == nil ? nil : [[Database sharedInstance] packageWithName:id];
- // XXX: holy typecast batman!
- [(id<ProgressDelegate>)self setProgressError:error withTitle:(package == nil ? id : [package name])];
+
+ [self performSelector:@selector(setProgressError:withTitle:)
+ withObject:error
+ withObject:(package == nil ? id : [package name])
+ ];
}
@end
UIImage *icon(nil);
if (!icon_.empty())
if ([icon_ hasPrefix:@"file:///"])
+ // XXX: correct escaping
icon = [UIImage imageAtPath:[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"];
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;
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;
@end
/* }}} */
-/* Confirmation View {{{ */
+/* Confirmation Controller {{{ */
bool DepSubstrate(const pkgCache::VerIterator &iterator) {
if (!iterator.end())
for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) {
return false;
}
+/* }}} */
/* Web Scripting {{{ */
@interface CydiaObject : NSObject {
id values[count];
for (unsigned i(0); i != count; ++i)
values[i] = [arguments objectAtIndex:i];
- return [[[NSString alloc] initWithFormat:format arguments:reinterpret_cast<va_list>(values)] autorelease];
+ return [[[NSString alloc] initWithFormat:format arguments:*(reinterpret_cast<va_list *>(&values))] autorelease];
}
- (NSString *) localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)table {
@end
/* }}} */
-@interface CydiaBrowserView : BrowserView {
+/* Cydia Browser Controller {{{ */
+@interface CYBrowserController : BrowserController {
CydiaObject *cydia_;
}
@end
-@implementation CydiaBrowserView
+@implementation CYBrowserController
- (void) dealloc {
[cydia_ release];
[cydia_ setDelegate:delegate];
}
-- (id) initWithBook:(RVBook *)book forWidth:(float)width {
- if ((self = [super initWithBook:book forWidth:width ofClass:[CydiaBrowserView class]]) != nil) {
+- (id) init {
+ if ((self = [super initWithWidth:0 ofClass:[CYBrowserController class]]) != nil) {
cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_];
WebView *webview([document_ webView]);
}
@end
+/* }}} */
-@protocol ConfirmationViewDelegate
+/* Confirmation {{{ */
+@protocol ConfirmationControllerDelegate
- (void) cancelAndClear:(bool)clear;
-- (void) confirm;
+- (void) confirmWithNavigationController:(UINavigationController *)navigation;
- (void) queue;
@end
-@interface ConfirmationView : CydiaBrowserView {
+@interface ConfirmationController : CYBrowserController {
_transient Database *database_;
UIAlertView *essential_;
NSArray *changes_;
BOOL substrate_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
@end
-@implementation ConfirmationView
+@implementation ConfirmationController
- (void) dealloc {
[changes_ release];
[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];
- [book_ popFromSuperviewAnimated:YES];
- [delegate_ cancelAndClear:clear];
- }
-}
-
-- (void) cancel {
- 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:[[book_ navigationBar] currentLeftView]];
-}
-
-- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
NSString *context([alert context]);
if ([context isEqualToString:@"remove"]) {
- if (button == [alert cancelButtonIndex]) {
- [self cancel];
+ if (button == [alert cancelButtonIndex]) {
+ [self dismissModalViewControllerAnimated:YES];
} else if (button == [alert firstOtherButtonIndex]) {
- if (substrate_)
- Finish_ = 2;
- [delegate_ confirm];
+ if (substrate_)
+ Finish_ = 2;
+ [delegate_ confirmWithNavigationController:[self navigationController]];
}
[alert dismissWithClickedButtonIndex:-1 animated:YES];
} else if ([context isEqualToString:@"unable"]) {
- [self cancel];
+ [self dismissModalViewControllerAnimated:YES];
[alert dismissWithClickedButtonIndex:-1 animated:YES];
} else {
- [super alertView:alert clickedButtonAtIndex:button];
- }
+ [super alertView:alert clickedButtonAtIndex:button];
+ }
+}
+
+- (id) invokeDefaultMethodWithArguments:(NSArray *)args {
+ [self dismissModalViewControllerAnimated:YES];
+ [delegate_ cancelAndClear:NO];
+
+ return nil;
}
- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
[window setValue:changes_ forKey:@"changes"];
[window setValue:issues_ forKey:@"issues"];
[window setValue:sizes_ forKey:@"sizes"];
+ [window setValue:self forKey:@"queue"];
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
database_ = database;
+ [[self navigationItem] setTitle:UCLocalize("CONFIRM")];
+
NSMutableArray *installing = [NSMutableArray arrayWithCapacity:16];
NSMutableArray *reinstalling = [NSMutableArray arrayWithCapacity:16];
NSMutableArray *upgrading = [NSMutableArray arrayWithCapacity:16];
essential_ = [[UIAlertView alloc]
initWithTitle:UCLocalize("REMOVING_ESSENTIALS")
- message:UCLocalize("REMOVING_ESSENTIALS_EX")
- delegate:self
- cancelButtonTitle:[NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")]
- otherButtonTitles:[NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")], nil
- ];
+ message:UCLocalize("REMOVING_ESSENTIALS_EX")
+ delegate:self
+ cancelButtonTitle:[NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")]
+ otherButtonTitles:[NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")], nil
+ ];
[essential_ setContext:@"remove"];
} else {
essential_ = [[UIAlertView alloc]
initWithTitle:UCLocalize("UNABLE_TO_COMPLY")
- message:UCLocalize("UNABLE_TO_COMPLY_EX")
- delegate:self
- cancelButtonTitle:UCLocalize("OKAY")
- otherButtonTitles:nil
+ message:UCLocalize("UNABLE_TO_COMPLY_EX")
+ delegate:self
+ cancelButtonTitle:UCLocalize("OKAY")
+ otherButtonTitles:nil
];
- [essential_ setContext:@"unable"];
+ [essential_ setContext:@"unable"];
}
changes_ = [[NSArray alloc] initWithObjects:
sizes_ = [[NSArray alloc] initWithObjects:
SizeString([database_ fetcher].FetchNeeded()),
SizeString([database_ fetcher].PartialPresent()),
- SizeString([database_ cache]->UsrSize()),
nil];
[self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"confirm" ofType:@"html"]]];
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("CANCEL")
+ // OLD: [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(cancelButtonClicked)
+ ];
+ [[self navigationItem] setLeftBarButtonItem:leftItem];
+ [leftItem release];
} return self;
}
-- (NSString *) backButtonTitle {
- return UCLocalize("CONFIRM");
-}
-
-- (NSString *) leftButtonTitle {
- return [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")];
-}
-
-- (id) rightButtonTitle {
- return issues_ != nil ? nil : [super rightButtonTitle];
-}
-
-- (id) _rightButtonTitle {
-#if AlwaysReload || IgnoreInstall
- return [super _rightButtonTitle];
+- (void) applyRightButton {
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("CONFIRM")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(confirmButtonClicked)
+ ];
+#if !AlwaysReload && !IgnoreInstall
+ if (issues_ == nil && ![self isLoading]) [[self navigationItem] setRightBarButtonItem:rightItem];
+ else [super applyRightButton];
#else
- return UCLocalize("CONFIRM");
+ [[self navigationItem] setRightBarButtonItem:nil];
#endif
+ [rightItem release];
}
-- (void) _leftButtonClicked {
- [self cancel];
+- (void) cancelButtonClicked {
+ [self dismissModalViewControllerAnimated:YES];
+ [delegate_ cancelAndClear:YES];
}
#if !AlwaysReload
-- (void) _rightButtonClicked {
+- (void) confirmButtonClicked {
#if IgnoreInstall
- return [super _rightButtonClicked];
+ return;
#endif
if (essential_ != nil)
- [essential_ popupAlertAnimated:YES];
+ [essential_ show];
else {
if (substrate_)
Finish_ = 2;
- [delegate_ confirm];
+ [delegate_ confirmWithNavigationController:[self navigationController]];
}
}
#endif
@end
/* }}} */
-/* Progress View {{{ */
-@interface ProgressView : UIView <
+/* Progress Controller {{{ */
+@interface ProgressController : CYViewController <
ConfigurationDelegate,
ProgressDelegate
> {
_transient Database *database_;
- UIView *view_;
- UIView *background_;
- UITransitionView *transition_;
- UIView *overlay_;
- UINavigationBar *navbar_;
UIProgressBar *progress_;
UITextView *output_;
UITextLabel *status_;
UIPushButton *close_;
- id delegate_;
BOOL running_;
SHA1SumValue springlist_;
SHA1SumValue notifyconf_;
NSString *title_;
}
-- (id) initWithFrame:(struct CGRect)frame database:(Database *)database delegate:(id)delegate;
-- (void) setContentView:(UIView *)view;
-- (void) resetView;
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
- (void) _retachThread;
- (void) _detachNewThreadData:(ProgressData *)data;
@end
-@protocol ProgressViewDelegate
-- (void) progressViewIsComplete:(ProgressView *)sender;
+@protocol ProgressControllerDelegate
+- (void) progressControllerIsComplete:(ProgressController *)sender;
@end
-@implementation ProgressView
+@implementation ProgressController
- (void) dealloc {
- [transition_ setDelegate:nil];
- [navbar_ setDelegate:nil];
-
- [view_ release];
- if (background_ != nil)
- [background_ release];
- [transition_ release];
- [overlay_ release];
- [navbar_ release];
+ [database_ setDelegate:nil];
[progress_ release];
[output_ release];
[status_ release];
[super dealloc];
}
-- (id) initWithFrame:(struct CGRect)frame database:(Database *)database delegate:(id)delegate {
- if ((self = [super initWithFrame:frame]) != nil) {
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+ if ((self = [super init]) != nil) {
database_ = database;
+ [database_ setDelegate:self];
delegate_ = delegate;
- transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
- [transition_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [transition_ setDelegate:self];
+ [[self view] setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]];
- overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
- [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-
- background_ = [[UIView alloc] initWithFrame:[self bounds]];
- [background_ setBackgroundColor:[UIColor blackColor]];
- [self addSubview:background_];
-
- [self addSubview:transition_];
-
- CGSize navsize = [UINavigationBar defaultSize];
- CGRect navrect = {{0, 0}, navsize};
-
- navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
- [navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [overlay_ addSubview:navbar_];
-
- [navbar_ setBarStyle:1];
- [navbar_ setDelegate:self];
-
- UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:nil] autorelease];
- [navbar_ pushNavigationItem:navitem];
-
- CGRect bounds = [overlay_ bounds];
- CGSize prgsize = [UIProgressBar defaultSize];
-
- CGRect prgrect = {{
- (bounds.size.width - prgsize.width) / 2,
- bounds.size.height - prgsize.height - 20
- }, prgsize};
-
- progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
+ progress_ = [[UIProgressBar alloc] init];
[progress_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
[progress_ setStyle:0];
- status_ = [[UITextLabel alloc] initWithFrame:CGRectMake(
- 10,
- bounds.size.height - prgsize.height - 50,
- bounds.size.width - 20,
- 24
- )];
-
+ status_ = [[UITextLabel alloc] init];
[status_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
-
[status_ setColor:[UIColor whiteColor]];
[status_ setBackgroundColor:[UIColor clearColor]];
-
[status_ setCentersHorizontally:YES];
//[status_ setFont:font];
- output_ = [[UITextView alloc] initWithFrame:CGRectMake(
- 10,
- navrect.size.height + 20,
- bounds.size.width - 20,
- bounds.size.height - navsize.height - 62 - navrect.size.height
- )];
+ output_ = [[UITextView alloc] init];
[output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [overlay_ addSubview:output_];
-
//[output_ setTextFont:@"Courier New"];
[output_ setFont:[[output_ font] fontWithSize:12]];
-
[output_ setTextColor:[UIColor whiteColor]];
[output_ setBackgroundColor:[UIColor clearColor]];
-
[output_ setMarginTop:0];
[output_ setAllowsRubberBanding:YES];
[output_ setEditable:NO];
+ [[self view] addSubview:output_];
- close_ = [[UIPushButton alloc] initWithFrame:CGRectMake(
- 10,
- bounds.size.height - prgsize.height - 50,
- bounds.size.width - 20,
- 32 + prgsize.height
- )];
-
+ close_ = [[UIPushButton alloc] init];
[close_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
-
[close_ setAutosizesToFit:NO];
[close_ setDrawsShadow:YES];
[close_ setStretchBackground:YES];
[close_ setEnabled:YES];
-
- UIFont *bold = [UIFont boldSystemFontOfSize:22];
- [close_ setTitleFont:bold];
-
+ [close_ setTitleFont:[UIFont boldSystemFontOfSize:22]];
[close_ addTarget:self action:@selector(closeButtonPushed) forEvents:UIControlEventTouchUpInside];
[close_ setBackground:[UIImage applicationImageNamed:@"green-up.png"] forState:0];
[close_ setBackground:[UIImage applicationImageNamed:@"green-dn.png"] forState:1];
} return self;
}
-- (void) setContentView:(UIView *)view {
- view_ = [view retain];
+- (void) positionViews {
+ CGRect bounds = [[self view] bounds];
+ CGSize prgsize = [UIProgressBar defaultSize];
+
+ CGRect prgrect = {{
+ (bounds.size.width - prgsize.width) / 2,
+ bounds.size.height - prgsize.height - 64
+ }, prgsize};
+
+ float closewidth = bounds.size.width - 20;
+ if (closewidth > 300) closewidth = 300;
+
+ [progress_ setFrame:prgrect];
+ [status_ setFrame:CGRectMake(
+ 10,
+ bounds.size.height - prgsize.height - 94,
+ bounds.size.width - 20,
+ 24
+ )];
+ [output_ setFrame:CGRectMake(
+ 10,
+ 20,
+ bounds.size.width - 20,
+ bounds.size.height - 106
+ )];
+ [close_ setFrame:CGRectMake(
+ (bounds.size.width - closewidth) / 2,
+ bounds.size.height - prgsize.height - 94,
+ closewidth,
+ 32 + prgsize.height
+ )];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [[self navigationItem] setHidesBackButton:YES];
+ [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
+
+ [self positionViews];
}
-- (void) resetView {
- [transition_ transition:6 toView:view_];
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [self positionViews];
}
-- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
NSString *context([alert context]);
if ([context isEqualToString:@"conffile"]) {
- FILE *input = [database_ input];
+ FILE *input = [database_ input];
if (button == [alert cancelButtonIndex]) fprintf(input, "N\n");
else if (button == [alert firstOtherButtonIndex]) fprintf(input, "Y\n");
- fflush(input);
-
- [alert dismissWithClickedButtonIndex:-1 animated:YES];
+ fflush(input);
}
}
- (void) closeButtonPushed {
running_ = NO;
+ UpdateExternalStatus(0);
+
switch (Finish_) {
case 0:
- [self resetView];
+ [self dismissModalViewControllerAnimated:YES];
break;
case 1:
}
- (void) _retachThread {
- UINavigationItem *item([navbar_ topItem]);
- [item setTitle:UCLocalize("COMPLETE")];
+ [[self navigationItem] setTitle:UCLocalize("COMPLETE")];
- [overlay_ addSubview:close_];
+ [[self view] addSubview:close_];
[progress_ removeFromSuperview];
[status_ removeFromSuperview];
[database_ popErrorWithTitle:title_];
- [delegate_ progressViewIsComplete:self];
+ [delegate_ progressControllerIsComplete:self];
if (Finish_ < 4) {
FileFd file;
}
switch (Finish_) {
- case 0: [close_ setTitle:UCLocalize("RETURN_TO_CYDIA")]; break;
+ case 0: [close_ setTitle:UCLocalize("RETURN_TO_CYDIA")]; break; /* XXX: Maybe UCLocalize("DONE")? */
case 1: [close_ setTitle:UCLocalize("CLOSE_CYDIA")]; break;
case 2: [close_ setTitle:UCLocalize("RESTART_SPRINGBOARD")]; break;
case 3: [close_ setTitle:UCLocalize("RELOAD_SPRINGBOARD")]; break;
system("su -c /usr/bin/uicache mobile");
+ UpdateExternalStatus(Finish_ == 0 ? 2 : 0);
+
[delegate_ setStatusBarShowsProgress:NO];
}
}
- (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title {
+ UpdateExternalStatus(1);
+
if (title_ != nil)
[title_ release];
if (title == nil)
else
title_ = [title retain];
- UINavigationItem *item([navbar_ topItem]);
- [item setTitle:title_];
+ [[self navigationItem] setTitle:title_];
[status_ setText:nil];
[output_ setText:@""];
[progress_ setProgress:0];
[close_ removeFromSuperview];
- [overlay_ addSubview:progress_];
- [overlay_ addSubview:status_];
+ [[self view] addSubview:progress_];
+ [[self view] addSubview:status_];
[delegate_ setStatusBarShowsProgress:YES];
running_ = YES;
}
}
- [transition_ transition:6 toView:overlay_];
-
[NSThread
detachNewThreadSelector:@selector(_detachNewThreadData:)
toTarget:self
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:UCLocalize("CONFIGURATION_UPGRADE")
- message:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]
- delegate:self
- cancelButtonTitle:UCLocalize("KEEP_OLD_COPY")
- otherButtonTitles:UCLocalize("ACCEPT_NEW_COPY"),
+ message:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]
+ delegate:self
+ cancelButtonTitle:UCLocalize("KEEP_OLD_COPY")
+ otherButtonTitles:UCLocalize("ACCEPT_NEW_COPY"),
// XXX: UCLocalize("SEE_WHAT_CHANGED"),
- nil
- ] autorelease];
+ nil
+ ] autorelease];
- [alert setContext:@"conffile"];
+ [alert setContext:@"conffile"];
[alert show];
}
/* }}} */
/* Cell Content View {{{ */
+@protocol ContentDelegate
+- (void) drawContentRect:(CGRect)rect;
+@end
+
@interface ContentView : UIView {
- _transient id delegate_;
+ _transient id<ContentDelegate> delegate_;
}
@end
} return self;
}
-- (void) setDelegate:(id)delegate {
+- (void) setDelegate:(id<ContentDelegate>)delegate {
delegate_ = delegate;
}
@end
/* }}} */
/* Package Cell {{{ */
-@interface PackageCell : UITableViewCell {
+@interface PackageCell : UITableViewCell <
+ ContentDelegate
+> {
UIImage *icon_;
NSString *name_;
NSString *description_;
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)];
@end
/* }}} */
/* Section Cell {{{ */
-@interface SectionCell : UITableViewCell {
+@interface SectionCell : UITableViewCell <
+ ContentDelegate
+> {
NSString *basic_;
NSString *section_;
NSString *name_;
BOOL editing_;
}
-- (id) init;
- (void) setSection:(Section *)section editing:(BOOL)editing;
@end
[switch_ setOn:(isSectionVisible(basic_) ? 1 : 0) animated:NO];
}
- [self setAccessoryType:editing ? 0 : 1 /*UITableViewCellAccessoryDisclosureIndicator*/];
+ [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator];
[content_ setNeedsDisplay];
}
- (void) drawContentRect:(CGRect)rect {
BOOL selected = [self isSelected];
-
+
[icon_ drawInRect:CGRectMake(8, 7, 32, 32)];
if (selected)
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_];
/* }}} */
/* File Table {{{ */
-@interface FileTable : RVPage {
+@interface FileTable : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
Package *package_;
NSString *name_;
UITableView *list_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
- (void) setPackage:(Package *)package;
@end
[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 = @"SourceCell";
+ static NSString *reuseIdentifier = @"Cell";
+
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
[cell setFont:[UIFont systemFontOfSize:16]];
}
-
[cell setText:[files_ objectAtIndex:indexPath.row]];
- [cell setSelectionStyle:0 /*UITableViewCellSelectionStyleNone*/];
+ [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
+
return cell;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
database_ = database;
+ [[self navigationItem] setTitle:UCLocalize("INSTALLED_FILES")];
+
files_ = [[NSMutableArray arrayWithCapacity:32] retain];
list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
- [self addSubview:list_];
+ [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [list_ setRowHeight:24.0f];
+ [[self view] addSubview:list_];
[list_ setDataSource:self];
[list_ setDelegate:self];
-
- [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
} return self;
}
[list_ reloadData];
}
-- (void) resetViewAnimated:(BOOL)animated {
- [list_ resetViewAnimated:animated];
-}
-
- (void) reloadData {
[self setPackage:[database_ packageWithName:name_]];
- [self reloadButtons];
-}
-
-- (NSString *) title {
- return UCLocalize("INSTALLED_FILES");
-}
-
-- (NSString *) backButtonTitle {
- return UCLocalize("FILES");
}
@end
/* }}} */
-/* Package View {{{ */
-@interface PackageView : CydiaBrowserView {
+/* Package Controller {{{ */
+@interface PackageController : CYBrowserController <
+ UIActionSheetDelegate
+> {
_transient Database *database_;
Package *package_;
NSString *name_;
NSMutableArray *buttons_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
- (void) setPackage:(Package *)package;
@end
-@implementation PackageView
+@implementation PackageController
- (void) dealloc {
if (package_ != nil)
- (void) release {
if ([self retainCount] == 1)
- [delegate_ setPackageView:self];
+ [delegate_ setPackageController:self];
[super release];
}
}
[sheet dismissWithClickedButtonIndex:-1 animated:YES];
- } else {
- [super alertSheet:sheet clickedButtonAtIndex:button];
}
}
}
#if !AlwaysReload
-- (void) __rightButtonClicked {
+- (void) _customButtonClicked {
int count([buttons_ count]);
if (count == 0)
return;
}
[sheet setContext:@"modify"];
- [delegate_ showActionSheet:sheet fromItem:[[book_ navigationBar] currentRightView]];
+ [delegate_ showActionSheet:sheet fromItem:[[self navigationItem] rightBarButtonItem]];
}
}
-- (void) _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 _rightButtonClicked];
+ [super customButtonClicked];
else
- [self __rightButtonClicked];
+ [self _customButtonClicked];
}
-#endif
-- (id) _rightButtonTitle {
- int count = [buttons_ count];
- return count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0];
+- (void) reloadButtonClicked {
+ // Don't reload a package view by clicking the button.
+}
+
+- (void) applyLoadingTitle {
+ // Don't show "Loading" as the title. Ever.
}
-- (NSString *) backButtonTitle {
- return @"Details";
+- (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
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
database_ = database;
buttons_ = [[NSMutableArray alloc] initWithCapacity:4];
[self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]];
if (special_ != NULL) {
CGRect frame([document_ frame]);
- frame.size.width = 320;
frame.size.height = 0;
[document_ setFrame:frame];
[super callFunction:special_];
}
}
-
- [self reloadButtons];
}
- (bool) isLoading {
@end
/* }}} */
/* Package Table {{{ */
-@interface PackageTable : RVPage {
+@interface PackageTable : UIView <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
- NSString *title_;
NSMutableArray *packages_;
NSMutableArray *sections_;
UITableView *list_;
NSMutableArray *index_;
NSMutableDictionary *indices_;
+ id target_;
+ SEL action_;
+ id delegate_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title;
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action;
- (void) setDelegate:(id)delegate;
- (void) setShouldHideHeaderInShortLists:(BOOL)hide;
+- (void) deselectWithAnimation:(BOOL)animated;
+
@end
@implementation PackageTable
- (void) dealloc {
- [list_ setDataSource:nil];
-
- [title_ release];
[packages_ release];
[sections_ release];
[list_ release];
[index_ release];
[indices_ release];
+
[super dealloc];
}
}
- (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;
- return [PackageCell heightForPackage:[self packageAtIndexPath:path]];
+- (void) deselectWithAnimation:(BOOL)animated {
+ [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
}
+/*- (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]);
package = [database_ packageWithName:[package id]];
- PackageView *view([delegate_ packageView]);
- [view setPackage:package];
- [view setDelegate:delegate_];
- [book_ pushPage:view];
+ [target_ performSelector:action_ withObject:package];
return path;
}
return index;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action {
+ if ((self = [super initWithFrame:frame]) != nil) {
database_ = database;
- title_ = [title retain];
+
+ target_ = target;
+ action_ = action;
index_ = [[NSMutableArray alloc] initWithCapacity:32];
indices_ = [[NSMutableDictionary alloc] initWithCapacity:32];
list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
[list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [list_ setRowHeight:73.0f];
[self addSubview:list_];
[list_ setDataSource:self];
[list_ setDelegate:self];
-
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
} return self;
}
_end
}
-- (NSString *) title {
- return title_;
-}
-
-- (void) resetViewAnimated:(BOOL)animated {
- [list_ resetViewAnimated:animated];
-}
-
- (void) resetCursor {
[list_ scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:NO];
}
- (void) setObject:(id)object;
- (void) setObject:(id)object forFilter:(SEL)filter;
-- (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object;
@end
- (void) setObject:(id)object forFilter:(SEL)filter {
[self setFilter:filter];
[self setObject:object];
-
}
- (bool) hasPackage:(Package *)package {
_end
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
- if ((self = [super initWithBook:book database:database title:title]) != nil) {
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object {
+ if ((self = [super initWithFrame:frame database:database target:target action:action]) != nil) {
[self setFilter:filter];
- object_ = object == nil ? nil : [object retain];
+ object_ = [object retain];
[self reloadData];
} return self;
}
@end
/* }}} */
-/* Add Source View {{{ */
-@interface AddSourceView : RVPage {
+/* Filtered Package Controller {{{ */
+@interface FilteredPackageController : CYViewController {
+ _transient Database *database_;
+ FilteredPackageTable *packages_;
+ NSString *title_;
+}
+
+- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
+
+@end
+
+@implementation FilteredPackageController
+
+- (void) dealloc {
+ [packages_ release];
+ [title_ release];
+
+ [super dealloc];
+}
+
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [packages_ deselectWithAnimation:animated];
+}
+
+- (void) didSelectPackage:(Package *)package {
+ PackageController *view([delegate_ packageController]);
+ [view setPackage:package];
+ [view setDelegate:delegate_];
+ [[self navigationController] pushViewController:view animated:YES];
+}
+
+- (NSString *) title { return title_; }
+
+- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
+ if ((self = [super init]) != nil) {
+ database_ = database;
+ title_ = [title copy];
+ [[self navigationItem] setTitle:title_];
+
+ packages_ = [[FilteredPackageTable alloc]
+ initWithFrame:[[self view] bounds]
+ database:database
+ target:self
+ action:@selector(didSelectPackage:)
+ filter:filter
+ with:object
+ ];
+
+ [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [[self view] addSubview:packages_];
+ } return self;
+}
+
+- (void) reloadData {
+ [packages_ reloadData];
+}
+
+- (void) setDelegate:(id)delegate {
+ [super setDelegate:delegate];
+ [packages_ setDelegate:delegate];
+}
+
+@end
+
+/* }}} */
+
+/* Add Source Controller {{{ */
+@interface AddSourceController : CYViewController {
_transient Database *database_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
@end
-@implementation AddSourceView
+@implementation AddSourceController
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
database_ = database;
} return self;
}
@end
/* }}} */
/* Source Cell {{{ */
-@interface SourceCell : UITableViewCell {
+@interface SourceCell : UITableViewCell <
+ ContentDelegate
+> {
UIImage *icon_;
NSString *origin_;
NSString *description_;
- (void) setSource:(Source *)source {
[self clearSource];
-
+
if (icon_ == nil)
icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sources/%@.png", [source host]]];
if (icon_ == nil)
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 : RVPage {
+@interface SourceTable : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
UITableView *list_;
NSMutableArray *sources_;
BOOL cydia_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
+
+- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated;
@end
[sources_ release];
[list_ release];
-
[super dealloc];
}
-- (int) numberOfSectionsInTableView:(UITableView *)tableView {
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+}
+
+- (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");
}
}
-- (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_);
case 1: return count - offset_;
- _nodefault
+ _nodefault
}
}
case 0: idx = indexPath.row; break;
case 1: idx = indexPath.row + offset_; break;
- _nodefault
+ _nodefault
}
return [sources_ objectAtIndex:idx];
}
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- Source *source = [self sourceAtIndexPath:indexPath];
+ static NSString *cellIdentifier = @"SourceCell";
- static NSString *cellIdentifier = @"Source";
SourceCell *cell = (SourceCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
- if(cell == nil) {
- cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
- }
-
- [cell setSource:source];
+ 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];
- PackageTable *packages = [[[FilteredPackageTable alloc]
- initWithBook:book_
- database:database_
+ FilteredPackageController *packages = [[[FilteredPackageController alloc]
+ initWithDatabase:database_
title:[source label]
filter:@selector(isVisibleInSource:)
with:source
[packages setDelegate:delegate_];
- [book_ pushPage:packages];
+ [[self navigationController] pushViewController:packages animated:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:UCLocalize("SOURCE_WARNING")
- message:warning
- delegate:self
- cancelButtonTitle:UCLocalize("CANCEL")
+ message:warning
+ delegate:self
+ cancelButtonTitle:UCLocalize("CANCEL")
otherButtonTitles:UCLocalize("ADD_ANYWAY"), nil
] autorelease];
- [alert setContext:@"warning"];
+ [alert setContext:@"warning"];
[alert setNumberOfRows:1];
[alert show];
} else
} else if (error_ != nil) {
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:UCLocalize("VERIFICATION_ERROR")
- message:[error_ localizedDescription]
- delegate:self
- cancelButtonTitle:UCLocalize("OK")
+ message:[error_ localizedDescription]
+ delegate:self
+ cancelButtonTitle:UCLocalize("OK")
otherButtonTitles:nil
] autorelease];
- [alert setContext:@"urlerror"];
+ [alert setContext:@"urlerror"];
[alert show];
} else {
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:UCLocalize("NOT_REPOSITORY")
- message:UCLocalize("NOT_REPOSITORY_EX")
- delegate:self
- cancelButtonTitle:UCLocalize("OK")
+ message:UCLocalize("NOT_REPOSITORY_EX")
+ delegate:self
+ cancelButtonTitle:UCLocalize("OK")
otherButtonTitles:nil
] autorelease];
- [alert setContext:@"trivial"];
+ [alert setContext:@"trivial"];
[alert show];
}
[self _endConnection:connection];
}
+- (NSString *) title { return UCLocalize("SOURCES"); }
+
- (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method {
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:href]
}
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
+ [[self navigationItem] setTitle:UCLocalize("SOURCES")];
+ [self updateButtonsForEditingStatus:NO animated:NO];
+
database_ = database;
sources_ = [[NSMutableArray arrayWithCapacity:16] retain];
- list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
+ list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
[list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self addSubview:list_];
+ [[self view] addSubview:list_];
[list_ setDataSource:self];
[list_ setDelegate:self];
[self reloadData];
-
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
} return self;
}
[sources_ sortUsingSelector:@selector(compareByNameAndType:)];
_trace();
- int count([sources_ count]);
+ int count([sources_ count]);
offset_ = 0;
for (int i = 0; i != count; i++) {
- if ([[sources_ objectAtIndex:i] record] == nil) break;
- else offset_++;
+ if ([[sources_ objectAtIndex:i] record] == nil) break;
+ else offset_++;
}
[list_ setEditing:NO];
+ [self updateButtonsForEditingStatus:NO animated:NO];
[list_ reloadData];
}
-- (void) resetViewAnimated:(BOOL)animated {
- [list_ resetViewAnimated:animated];
-}
-
-- (void) _leftButtonClicked {
- /*[book_ pushPage:[[[AddSourceView alloc]
+- (void) addButtonClicked {
+ /*[book_ pushPage:[[[AddSourceController alloc]
initWithBook:book_
database:database_
] autorelease]];*/
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:UCLocalize("ENTER_APT_URL")
- message:nil
- delegate:self
- cancelButtonTitle:UCLocalize("CANCEL")
- otherButtonTitles:UCLocalize("ADD_SOURCE"), nil
+ message:nil
+ delegate:self
+ cancelButtonTitle:UCLocalize("CANCEL")
+ otherButtonTitles:UCLocalize("ADD_SOURCE"), nil
] autorelease];
- [alert setContext:@"source"];
- [alert setTransform:CGAffineTransformTranslate([alert transform], 0.0, 100.0)];
+ [alert setContext:@"source"];
+ [alert setTransform:CGAffineTransformTranslate([alert transform], 0.0, 100.0)];
[alert setNumberOfRows:1];
[alert addTextFieldWithValue:@"http://" label:@""];
[alert show];
}
-- (void) _rightButtonClicked {
- [list_ setEditing:![list_ isEditing]];
- [book_ reloadButtonsForPage:self];
-}
-
-- (NSString *) title {
- return UCLocalize("SOURCES");
-}
-
-- (NSString *) leftButtonTitle {
- return [list_ isEditing] ? UCLocalize("ADD") : nil;
+- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated {
+ UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("ADD")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(addButtonClicked)
+ ];
+ [[self navigationItem] setLeftBarButtonItem:editing ? leftItem : [[self navigationItem] backBarButtonItem] animated:animated];
+ [leftItem release];
+
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:editing ? UCLocalize("DONE") : UCLocalize("EDIT")
+ style:editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
+ target:self
+ action:@selector(editButtonClicked)
+ ];
+ [[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];
+ }
}
-- (id) rightButtonTitle {
- return [list_ isEditing] ? UCLocalize("DONE") : UCLocalize("EDIT");
+- (void) settingsButtonClicked {
+ [delegate_ showSettings];
}
-- (UINavigationButtonStyle) rightButtonStyle {
- return [list_ isEditing] ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal;
+- (void) editButtonClicked {
+ [list_ setEditing:![list_ isEditing] animated:YES];
+
+ [self updateButtonsForEditingStatus:[list_ isEditing] animated:YES];
}
@end
/* }}} */
-/* Installed View {{{ */
-@interface InstalledView : RVPage {
- _transient Database *database_;
- FilteredPackageTable *packages_;
+/* Installed Controller {{{ */
+@interface InstalledController : FilteredPackageController {
BOOL expert_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
+
+- (void) updateRoleButton;
+- (void) queueStatusDidChange;
@end
-@implementation InstalledView
+@implementation InstalledController
- (void) dealloc {
- [packages_ release];
[super dealloc];
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
- database_ = database;
-
- packages_ = [[FilteredPackageTable alloc]
- initWithBook:book
- database:database
- title:nil
- filter:@selector(isInstalledAndVisible:)
- with:[NSNumber numberWithBool:YES]
- ];
-
- [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self addSubview:packages_];
+- (NSString *) title { return UCLocalize("INSTALLED"); }
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndVisible:) with:[NSNumber numberWithBool:YES]]) != nil) {
+ [self updateRoleButton];
+ [self queueStatusDidChange];
} return self;
}
-- (void) resetViewAnimated:(BOOL)animated {
- [packages_ resetViewAnimated:animated];
+#if !AlwaysReload
+- (void) queueButtonClicked {
+ [delegate_ queue];
}
+#endif
-- (void) reloadData {
- [packages_ reloadData];
+- (void) queueStatusDidChange {
+#if !AlwaysReload
+ if (IsWildcat_) {
+ UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("QUEUE")
+ style:UIBarButtonItemStyleDone
+ target:self
+ action:@selector(queueButtonClicked)
+ ];
+ if (Queuing_) [[self navigationItem] setLeftBarButtonItem:queueItem];
+ else [[self navigationItem] setLeftBarButtonItem:nil];
+ [queueItem release];
+ }
+#endif
}
-- (void) _rightButtonClicked {
- [packages_ setObject:[NSNumber numberWithBool:expert_]];
+- (void) reloadData {
[packages_ reloadData];
- expert_ = !expert_;
- [book_ reloadButtonsForPage:self];
-}
-
-- (NSString *) title {
- return UCLocalize("INSTALLED");
}
-- (NSString *) backButtonTitle {
- return UCLocalize("PACKAGES");
+- (void) updateRoleButton {
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE")
+ style:expert_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
+ target:self
+ action:@selector(roleButtonClicked)
+ ];
+ if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) [[self navigationItem] setRightBarButtonItem:rightItem];
+ [rightItem release];
}
-- (id) rightButtonTitle {
- return Role_ != nil && [Role_ isEqualToString:@"Developer"] ? nil : expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE");
-}
+- (void) roleButtonClicked {
+ [packages_ setObject:[NSNumber numberWithBool:expert_]];
+ [packages_ reloadData];
+ expert_ = !expert_;
-- (UINavigationButtonStyle) rightButtonStyle {
- return expert_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal;
+ [self updateRoleButton];
}
- (void) setDelegate:(id)delegate {
@end
/* }}} */
-/* Home View {{{ */
-@interface HomeView : CydiaBrowserView {
+/* Home Controller {{{ */
+@interface HomeController : CYBrowserController {
}
@end
-@implementation HomeView
+@implementation HomeController
- (void) _setMoreHeaders:(NSMutableURLRequest *)request {
[super _setMoreHeaders:request];
[request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
}
-- (void) _leftButtonClicked {
+- (void) aboutButtonClicked {
UIAlertView *alert = [[[UIAlertView alloc] init] autorelease];
[alert setTitle:UCLocalize("ABOUT_CYDIA")];
[alert addButtonWithTitle:UCLocalize("CLOSE")];
[alert show];
}
-- (NSString *) leftButtonTitle {
- return UCLocalize("ABOUT");
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [[self navigationController] setNavigationBarHidden:YES animated:animated];
+}
+
+- (void) viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+ [[self navigationController] setNavigationBarHidden:NO animated:animated];
+}
+
+- (id) init {
+ if ((self = [super init]) != nil) {
+ UIBarButtonItem *aboutItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("ABOUT")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(aboutButtonClicked)
+ ];
+ [[self navigationItem] setLeftBarButtonItem:aboutItem];
+ [aboutItem release];
+ } return self;
}
@end
/* }}} */
-/* Manage View {{{ */
-@interface ManageView : CydiaBrowserView {
+/* Manage Controller {{{ */
+@interface ManageController : CYBrowserController {
}
+- (void) queueStatusDidChange;
@end
-@implementation ManageView
+@implementation ManageController
-- (NSString *) title {
- return UCLocalize("MANAGE");
-}
+- (id) init {
+ if ((self = [super init]) != nil) {
+ [[self navigationItem] setTitle:UCLocalize("MANAGE")];
+
+ UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("SETTINGS")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(settingsButtonClicked)
+ ];
+ [[self navigationItem] setLeftBarButtonItem:settingsItem];
+ [settingsItem release];
-- (void) _leftButtonClicked {
- [delegate_ askForSettings];
- [delegate_ updateData];
+ [self queueStatusDidChange];
+ } return self;
}
-- (NSString *) leftButtonTitle {
- return UCLocalize("SETTINGS");
+- (void) settingsButtonClicked {
+ [delegate_ showSettings];
}
#if !AlwaysReload
-- (id) _rightButtonTitle {
- return Queuing_ ? UCLocalize("QUEUE") : nil;
+- (void) queueButtonClicked {
+ [delegate_ queue];
}
-- (UINavigationButtonStyle) rightButtonStyle {
- return Queuing_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal;
+- (void) applyLoadingTitle {
+ // No "Loading" title.
}
-- (void) _rightButtonClicked {
- [delegate_ queue];
+- (void) applyRightButton {
+ // No right button.
}
#endif
+- (void) queueStatusDidChange {
+#if !AlwaysReload
+ if (!IsWildcat_ && Queuing_) {
+ UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("QUEUE")
+ style:UIBarButtonItemStyleDone
+ target:self
+ action:@selector(queueButtonClicked)
+ ];
+ [[self navigationItem] setRightBarButtonItem:queueItem];
+
+ [queueItem release];
+ } else {
+ [[self navigationItem] setRightBarButtonItem:nil];
+ }
+#endif
+}
+
- (bool) isLoading {
return false;
}
@end
/* }}} */
-/* Cydia Book {{{ */
-@interface CYBook : RVBook <
- ProgressDelegate
-> {
- _transient Database *database_;
- UINavigationBar *overlay_;
- UINavigationBar *underlay_;
+/* Refresh Bar {{{ */
+@interface RefreshBar : UINavigationBar {
UIProgressIndicator *indicator_;
UITextLabel *prompt_;
UIProgressBar *progress_;
UINavigationButton *cancel_;
- bool updating_;
- bool dropped_;
}
-- (id) initWithFrame:(CGRect)frame database:(Database *)database;
-- (void) update;
-- (BOOL) updating;
-- (void) setUpdate:(NSDate *)date;
-
@end
-@implementation CYBook
-
-- (void) dealloc {
- [overlay_ release];
- [indicator_ release];
- [prompt_ release];
- [progress_ release];
- [cancel_ release];
- [super dealloc];
-}
-
-- (NSString *) getTitleForPage:(RVPage *)page {
- return [super getTitleForPage:page];
-}
-
-- (BOOL) updating {
- return updating_;
-}
-
-- (void) dropBar {
- if (dropped_)
- return;
- dropped_ = true;
-
- [UIView beginAnimations:nil context:NULL];
-
- CGRect ovrframe = [overlay_ frame];
- ovrframe.origin.y = 0;
- [overlay_ setFrame:ovrframe];
-
- CGRect barframe = [navbar_ frame];
- barframe.origin.y += ovrframe.size.height;
- [navbar_ setFrame:barframe];
-
- CGRect trnframe = [transition_ frame];
- trnframe.origin.y += ovrframe.size.height;
- trnframe.size.height -= ovrframe.size.height;
- [transition_ setFrame:trnframe];
-
- [UIView endAnimations];
-}
-
-- (void) raiseBar {
- if (!dropped_)
- return;
- dropped_ = false;
-
- [UIView beginAnimations:nil context:NULL];
-
- CGRect ovrframe = [overlay_ frame];
- ovrframe.origin.y = -ovrframe.size.height;
- [overlay_ setFrame:ovrframe];
-
- CGRect barframe = [navbar_ frame];
- barframe.origin.y -= ovrframe.size.height;
- [navbar_ setFrame:barframe];
-
- CGRect trnframe = [transition_ frame];
- trnframe.origin.y -= ovrframe.size.height;
- trnframe.size.height += ovrframe.size.height;
- [transition_ setFrame:trnframe];
-
- [UIView commitAnimations];
-}
-
-- (void) setUpdate:(NSDate *)date {
- [self update];
-}
-
-- (void) update {
- [self dropBar];
-
- [indicator_ startAnimation];
- [prompt_ setText:UCLocalize("UPDATING_DATABASE")];
- [progress_ setProgress:0];
+@implementation RefreshBar
- updating_ = true;
- [overlay_ addSubview:cancel_];
+- (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];
- [NSThread
- detachNewThreadSelector:@selector(_update)
- toTarget:self
- withObject:nil
- ];
-}
+ CGSize prgsize = {75, 100};
+ CGRect prgrect = {{
+ [self frame].size.width - prgsize.width - 10,
+ ([self frame].size.height - prgsize.height) / 2
+ } , prgsize};
+ [progress_ setFrame:prgrect];
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
- NSString *context([sheet context]);
+ CGSize indsize([UIProgressIndicator defaultSizeForStyle:[indicator_ activityIndicatorViewStyle]]);
+ unsigned indoffset = ([self frame].size.height - indsize.height) / 2;
+ CGRect indrect = {{indoffset, indoffset}, indsize};
+ [indicator_ setFrame:indrect];
- if ([context isEqualToString:@"refresh"])
- [sheet dismiss];
+ 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) _update_ {
- updating_ = false;
-
- [indicator_ stopAnimation];
-
- [self raiseBar];
+- (void)setFrame:(CGRect)frame {
+ [super setFrame:frame];
- [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+ [self positionViews];
}
-- (id) initWithFrame:(CGRect)frame database:(Database *)database {
- if ((self = [super initWithFrame:frame]) != nil) {
- database_ = database;
-
- CGRect ovrrect([navbar_ bounds]);
- ovrrect.size.height = [UINavigationBar defaultSize].height;
- ovrrect.origin.y = -ovrrect.size.height;
-
- overlay_ = [[UINavigationBar alloc] initWithFrame:ovrrect];
- [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [self addSubview:overlay_];
+- (id) initWithFrame:(CGRect)frame delegate:(id)delegate {
+ if ((self = [super initWithFrame:frame])) {
+ [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- ovrrect.origin.y = frame.size.height;
- underlay_ = [[UINavigationBar alloc] initWithFrame:ovrrect];
- [underlay_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [self addSubview:underlay_];
+ [self setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
+ [self setBarStyle:UIBarStyleBlack];
- [underlay_ setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
-
- [overlay_ setBarStyle:1];
- [underlay_ setBarStyle:1];
-
- int barstyle([overlay_ _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 = (ovrrect.size.height - indsize.height) / 2;
- CGRect indrect = {{indoffset, indoffset}, indsize};
-
- indicator_ = [[UIProgressIndicator alloc] initWithFrame:indrect];
+ indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectZero];
[indicator_ setStyle:style];
- [overlay_ addSubview:indicator_];
-
- CGSize prmsize = {215, indsize.height + 4};
-
- CGRect prmrect = {{
- indoffset * 2 + indsize.width,
- unsigned(ovrrect.size.height - prmsize.height) / 2 - 1
- }, prmsize};
-
- UIFont *font([UIFont systemFontOfSize:15]);
-
- prompt_ = [[UITextLabel alloc] initWithFrame:prmrect];
+ [indicator_ startAnimation];
+ [self addSubview:indicator_];
+ prompt_ = [[UITextLabel alloc] initWithFrame:CGRectZero];
[prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]];
[prompt_ setBackgroundColor:[UIColor clearColor]];
- [prompt_ setFont:font];
-
- [overlay_ addSubview:prompt_];
-
- CGSize prgsize = {75, 100};
-
- CGRect prgrect = {{
- ovrrect.size.width - prgsize.width - 10,
- (ovrrect.size.height - prgsize.height) / 2
- } , prgsize};
-
- progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
- [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [overlay_ addSubview:progress_];
+ [prompt_ setFont:[UIFont systemFontOfSize:15]];
+ [self addSubview:prompt_];
+ 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_ addTarget:self action:@selector(_onCancel) forControlEvents:UIControlEventTouchUpInside];
-
- CGRect frame = [cancel_ frame];
- frame.origin.x = ovrrect.size.width - frame.size.width - 5;
- frame.origin.y = (ovrrect.size.height - frame.size.height) / 2;
- [cancel_ setFrame:frame];
-
+ [cancel_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+ [cancel_ addTarget:delegate action:@selector(cancelPressed) forControlEvents:UIControlEventTouchUpInside];
[cancel_ setBarStyle:barstyle];
+
+ [self positionViews];
} return self;
}
-- (void) _onCancel {
- updating_ = false;
+- (void) cancel {
[cancel_ removeFromSuperview];
}
-- (void) _update { _pooled
- Status status;
- status.setDelegate(self);
- [database_ updateWithStatus:status];
+- (void) start {
+ [prompt_ setText:UCLocalize("UPDATING_DATABASE")];
+ [progress_ setProgress:0];
+ [self addSubview:cancel_];
+}
- [self
- performSelectorOnMainThread:@selector(_update_)
- withObject:nil
- waitUntilDone:NO
- ];
+- (void) stop {
+ [cancel_ removeFromSuperview];
}
-- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
- [prompt_ setText:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), error]];
+- (void) setPrompt:(NSString *)prompt {
+ [prompt_ setText:prompt];
}
-/*
- UIActionSheet *sheet = [[[UIActionSheet alloc]
- initWithTitle:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), UCLocalize("REFRESH")]
- buttons:[NSArray arrayWithObjects:
- UCLocalize("OK"),
- nil]
- defaultButtonIndex:0
- delegate:self
- context:@"refresh"
- ] autorelease];
+- (void) setProgress:(float)progress {
+ [progress_ setProgress:progress];
+}
- [sheet setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+@end
+/* }}} */
- [sheet setBodyText:error];
- [sheet popupAlertAnimated:YES];
+@class CYNavigationController;
- [self reloadButtons];
-*/
+/* Cydia Tab Bar Controller {{{ */
+@interface CYTabBarController : UITabBarController {
+ Database *database_;
+}
-- (void) setProgressTitle:(NSString *)title {
- [self
- performSelectorOnMainThread:@selector(_setProgressTitle:)
- withObject:title
- waitUntilDone:YES
- ];
+@end
+
+@implementation CYTabBarController
+
+/* XXX: some logic should probably go here related to
+freeing the view controllers on tab change */
+
+- (void) reloadData {
+ size_t count([[self viewControllers] count]);
+ for (size_t i(0); i != count; ++i) {
+ CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
+ [page reloadData];
+ }
}
-- (void) setProgressPercent:(float)percent {
- [self
- performSelectorOnMainThread:@selector(_setProgressPercent:)
- withObject:[NSNumber numberWithFloat:percent]
- waitUntilDone:YES
- ];
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
+ database_ = database;
+ } return self;
}
-- (void) startProgress {
+@end
+/* }}} */
+
+/* Cydia Navigation Controller {{{ */
+@interface CYNavigationController : UINavigationController {
+ _transient Database *database_;
+ id<UINavigationControllerDelegate> delegate_;
}
-- (void) addProgressOutput:(NSString *)output {
- [self
- performSelectorOnMainThread:@selector(_addProgressOutput:)
- withObject:output
- waitUntilDone:YES
- ];
+- (id) initWithDatabase:(Database *)database;
+- (void) reloadData;
+
+@end
+
+
+@implementation CYNavigationController
+
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
+ // Inherit autorotation settings for modal parents.
+ if ([self parentViewController] && [[self parentViewController] modalViewController] == self) {
+ return [[self parentViewController] shouldAutorotateToInterfaceOrientation:orientation];
+ } else {
+ return [super shouldAutorotateToInterfaceOrientation:orientation];
+ }
}
-- (bool) isCancelling:(size_t)received {
- return !updating_;
+- (void) dealloc {
+ [super dealloc];
}
-- (void) _setProgressTitle:(NSString *)title {
- [prompt_ setText:title];
+- (void) reloadData {
+ size_t count([[self viewControllers] count]);
+ for (size_t i(0); i != count; ++i) {
+ CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
+ [page reloadData];
+ }
}
-- (void) _setProgressPercent:(NSNumber *)percent {
- [progress_ setProgress:[percent floatValue]];
+- (void) setDelegate:(id<UINavigationControllerDelegate>)delegate {
+ delegate_ = delegate;
}
-- (void) _addProgressOutput:(NSString *)output {
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
+ database_ = database;
+ } return self;
}
@end
@end
/* }}} */
-/* Sections View {{{ */
-@interface SectionsView : RVPage {
+/* Sections Controller {{{ */
+@interface SectionsController : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
NSMutableArray *sections_;
NSMutableArray *filtered_;
BOOL editing_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
- (void) reloadData;
- (void) resetView;
+- (void) editButtonClicked;
+
@end
-@implementation SectionsView
+@implementation SectionsController
- (void) dealloc {
[list_ setDataSource:nil];
[super dealloc];
}
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+}
+
- (Section *) sectionAtIndexPath:(NSIndexPath *)indexPath {
Section *section = (editing_ ? [sections_ objectAtIndex:[indexPath row]] : ([indexPath row] == 0 ? nil : [filtered_ objectAtIndex:([indexPath row] - 1)]));
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 *cellIdentifier = @"SectionCell";
- SectionCell *cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
+ static NSString *reuseIdentifier = @"SectionCell";
+
+ SectionCell *cell = (SectionCell *) [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
+ if (cell == nil) cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
[cell setSection:[self sectionAtIndexPath:indexPath] editing:editing_];
return cell;
}
-
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Section *section = [self sectionAtIndexPath:indexPath];
NSString *name = [section name];
}
}
- PackageTable *table = [[[FilteredPackageTable alloc]
- initWithBook:book_
- database:database_
+ FilteredPackageController *table = [[[FilteredPackageController alloc]
+ initWithDatabase:database_
title:title
filter:@selector(isVisibleInSection:)
with:name
[table setDelegate:delegate_];
- [book_ pushPage:table];
+ [[self navigationController] pushViewController:table animated:YES];
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
+- (NSString *) title { return UCLocalize("SECTIONS"); }
+
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
database_ = database;
+ [[self navigationItem] setTitle:UCLocalize("SECTIONS")];
+
sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
filtered_ = [[NSMutableArray arrayWithCapacity:16] retain];
- list_ = [[UITableView alloc] initWithFrame:[self bounds]];
+ list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
[list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self addSubview:list_];
+ [list_ setRowHeight:45.0f];
+ [[self view] addSubview:list_];
- [list_ setDelegate:self];
[list_ setDataSource:self];
+ [list_ setDelegate:self];
[self reloadData];
-
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
} return self;
}
[filtered_ addObject:section];
}
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:[sections_ count] == 0 ? nil : UCLocalize("EDIT")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(editButtonClicked)
+ ];
+ [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] != nil];
+ [rightItem release];
+
[list_ reloadData];
_trace();
}
- (void) resetView {
if (editing_)
- [self _rightButtonClicked];
+ [self editButtonClicked];
}
-- (void) resetViewAnimated:(BOOL)animated {
- [list_ resetViewAnimated:animated];
-}
-
-- (void) _rightButtonClicked {
+- (void) editButtonClicked {
if ((editing_ = !editing_))
[list_ reloadData];
else
[delegate_ updateData];
- [book_ reloadTitleForPage:self];
- [book_ reloadButtonsForPage:self];
-}
-
-- (NSString *) title {
- return editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS");
-}
-
-- (NSString *) backButtonTitle {
- return UCLocalize("SECTIONS");
-}
-- (id) rightButtonTitle {
- return [sections_ count] == 0 ? nil : editing_ ? UCLocalize("DONE") : UCLocalize("EDIT");
-}
-
-- (UINavigationButtonStyle) rightButtonStyle {
- return editing_ ? UINavigationButtonStyleHighlighted : UINavigationButtonStyleNormal;
+ [[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];
}
- (UIView *) accessoryView {
@end
/* }}} */
-/* Changes View {{{ */
-@interface ChangesView : RVPage {
+/* Changes Controller {{{ */
+@interface ChangesController : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
NSMutableArray *packages_;
NSMutableArray *sections_;
UITableView *list_;
unsigned upgrades_;
+ BOOL hasSentFirstLoad_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database delegate:(id)delegate;
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
- (void) reloadData;
@end
-@implementation ChangesView
+@implementation ChangesController
- (void) dealloc {
[list_ setDelegate:nil];
[super dealloc];
}
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear: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 {
NSInteger count([sections_ count]);
return count == 0 ? 1 : count;
}
- (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];
- [book_ pushPage:view];
+ [[self navigationController] pushViewController:view animated:YES];
return path;
}
-- (void) _leftButtonClicked {
- [(CYBook *)book_ update];
- [self reloadButtons];
+- (void) refreshButtonClicked {
+ [delegate_ beginUpdate];
+ [[self navigationItem] setLeftBarButtonItem:nil];
}
-- (void) _rightButtonClicked {
+- (void) upgradeButtonClicked {
[delegate_ distUpgrade];
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database delegate:(id)delegate {
- if ((self = [super initWithBook:book]) != nil) {
+- (NSString *) title { return UCLocalize("CHANGES"); }
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+ if ((self = [super init]) != nil) {
database_ = database;
+ [[self navigationItem] setTitle:UCLocalize("CHANGES")];
packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
- list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
+ list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
[list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self addSubview:list_];
+ [list_ setRowHeight:73.0f];
+ [[self view] addSubview:list_];
- //XXX:[list_ setShouldHideHeaderInShortLists:NO];
[list_ setDataSource:self];
[list_ setDelegate:self];
- //[list_ setSectionListStyle:1];
delegate_ = delegate;
- [self reloadData];
-
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
} return self;
}
unseens = true;
NSDate *seen;
- _profile(ChangesView$reloadData$Remember)
+ _profile(ChangesController$reloadData$Remember)
seen = [package seen];
_end
[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];
[sections_ insertObject:upgradable atIndex:0];
[list_ reloadData];
- [self reloadButtons];
-}
-
-- (void) resetViewAnimated:(BOOL)animated {
- [list_ resetViewAnimated:animated];
-}
-
-- (NSString *) leftButtonTitle {
- return [(CYBook *)book_ updating] ? nil : UCLocalize("REFRESH");
-}
-
-- (id) rightButtonTitle {
- return upgrades_ == 0 ? nil : [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]];
-}
-- (NSString *) title {
- return UCLocalize("CHANGES");
+ UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+ initWithTitle:[NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(upgradeButtonClicked)
+ ];
+ if (upgrades_ > 0) [[self navigationItem] setRightBarButtonItem:rightItem];
+ [rightItem release];
+
+ UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("REFRESH")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(refreshButtonClicked)
+ ];
+ if (![delegate_ updating]) [[self navigationItem] setLeftBarButtonItem:leftItem];
+ [leftItem release];
}
@end
/* }}} */
-/* Search View {{{ */
-@protocol SearchViewDelegate
-- (void) showKeyboard:(BOOL)show;
-@end
-
-@interface SearchView : RVPage {
- UIView *accessory_;
- UISearchField *field_;
- FilteredPackageTable *table_;
- bool reload_;
+/* Search Controller {{{ */
+@interface SearchController : FilteredPackageController <
+ UISearchBarDelegate
+> {
+ UISearchBar *search_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithDatabase:(Database *)database;
- (void) reloadData;
@end
-@implementation SearchView
+@implementation SearchController
- (void) dealloc {
- [field_ setDelegate:nil];
-
- [accessory_ release];
- [field_ release];
- [table_ release];
+ [search_ release];
[super dealloc];
}
-- (void) _showKeyboard:(BOOL)show {
- CGSize keysize = [UIKeyboard defaultSize];
- CGRect keydown = [book_ pageBounds];
- CGRect keyup = keydown;
- keyup.size.height -= keysize.height - ButtonBarHeight_;
+- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
+ [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
+ [search_ resignFirstResponder];
+ [self reloadData];
+}
- float delay = KeyboardTime_ * ButtonBarHeight_ / keysize.height;
+- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text {
+ [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
+ [self reloadData];
+}
- UIFrameAnimation *animation = [[[UIFrameAnimation alloc] initWithTarget:[table_ list]] autorelease];
- [animation setSignificantRectFields:8];
+- (NSString *) title { return nil; }
- if (show) {
- [animation setStartFrame:keydown];
- [animation setEndFrame:keyup];
- } else {
- [animation setStartFrame:keyup];
- [animation setEndFrame:keydown];
- }
+- (id) initWithDatabase:(Database *)database {
+ return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil];
+}
- UIAnimator *animator = [UIAnimator sharedAnimator];
+- (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")];
+ UITextField *textField = [search_ searchField];
+ [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
+ [search_ setDelegate:self];
+ [textField setEnablesReturnKeyAutomatically:NO];
+ [[self navigationItem] setTitleView:textField];
+ }
+}
- [animator
- addAnimations:[NSArray arrayWithObjects:animation, nil]
- withDuration:(KeyboardTime_ - delay)
- start:!show
- ];
+- (void) _reloadData {
+}
- if (show)
- [animator performSelector:@selector(startAnimation:) withObject:animation afterDelay:delay];
+- (void) reloadData {
+ _profile(SearchController$reloadData)
+ [packages_ reloadData];
+ _end
+ PrintTimes();
+ [packages_ resetCursor];
+}
- //[delegate_ showKeyboard:show];
+- (void) didSelectPackage:(Package *)package {
+ [search_ resignFirstResponder];
+ [super didSelectPackage:package];
}
-- (void) textFieldDidBecomeFirstResponder:(UITextField *)field {
- [self _showKeyboard:YES];
- [table_ setObject:[field_ text] forFilter:@selector(isUnfilteredAndSelectedForBy:)];
- [self reloadData];
+@end
+/* }}} */
+/* Settings Controller {{{ */
+@interface SettingsController : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
+ _transient Database *database_;
+ NSString *name_;
+ Package *package_;
+ UITableView *table_;
+ id subscribedSwitch_;
+ id ignoredSwitch_;
+ UITableViewCell *subscribedCell_;
+ UITableViewCell *ignoredCell_;
}
-- (void) textFieldDidResignFirstResponder:(UITextField *)field {
- [self _showKeyboard:NO];
- [table_ setObject:[field_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
- [self reloadData];
+- (id) initWithDatabase:(Database *)database package:(NSString *)package;
+
+@end
+
+@implementation SettingsController
+
+- (void) dealloc {
+ [name_ release];
+ if (package_ != nil)
+ [package_ release];
+ [table_ release];
+ [subscribedSwitch_ release];
+ [ignoredSwitch_ release];
+ [subscribedCell_ release];
+ [ignoredCell_ release];
+
+ [super dealloc];
}
-- (void) keyboardInputChanged:(UIFieldEditor *)editor {
- if (reload_) {
- NSString *text([field_ text]);
- [field_ setClearButtonStyle:(text == nil || [text length] == 0 ? 0 : 2)];
- [table_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
- [self reloadData];
- reload_ = false;
- }
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ if (package_ == nil)
+ return 0;
+
+ return 1;
}
-- (void) textFieldClearButtonPressed:(UITextField *)field {
- reload_ = true;
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (package_ == nil)
+ return 0;
+
+ return 1;
}
-- (void) keyboardInputShouldDelete:(id)input {
- reload_ = true;
+- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
+ return UCLocalize("SHOW_ALL_CHANGES_EX");
}
-- (BOOL) keyboardInput:(id)input shouldInsertText:(NSString *)text isMarkedText:(int)marked {
- if ([text length] != 1 || [text characterAtIndex:0] != '\n') {
- reload_ = true;
- return YES;
- } else {
- [field_ resignFirstResponder];
- return NO;
+- (void) onSomething:(BOOL)value withKey:(NSString *)key {
+ if (package_ == nil)
+ return;
+
+ NSMutableDictionary *metadata([package_ metadata]);
+
+ BOOL before;
+ if (NSNumber *number = [metadata objectForKey:key])
+ before = [number boolValue];
+ else
+ before = NO;
+
+ if (value != before) {
+ [metadata setObject:[NSNumber numberWithBool:value] forKey:key];
+ Changed_ = true;
+ [delegate_ updateData];
}
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
- if ((self = [super initWithBook:book]) != nil) {
- CGRect pageBounds = [book_ pageBounds];
-
- table_ = [[FilteredPackageTable alloc]
- initWithBook:book
- database:database
- title:nil
- filter:@selector(isUnfilteredAndSearchedForBy:)
- with:nil
- ];
+- (void) onSubscribed:(id)control {
+ [self onSomething:(int) [control isOn] withKey:@"IsSubscribed"];
+}
- [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [self addSubview:table_];
+- (void) onIgnored:(id)control {
+ [self onSomething:(int) [control isOn] withKey:@"IsIgnored"];
+}
- [table_ setShouldHideHeaderInShortLists:NO];
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (package_ == nil)
+ return nil;
- CGRect cnfrect = {{7, 38}, {17, 18}};
+ switch ([indexPath row]) {
+ case 0: return subscribedCell_;
+ case 1: return ignoredCell_;
- CGRect area;
+ _nodefault
+ }
- area.origin.x = 10;
- area.origin.y = 1;
+ return nil;
+}
- area.size.width = [self bounds].size.width - area.origin.x * 2;
- area.size.height = [UISearchField defaultHeight];
+- (NSString *) title { return UCLocalize("SETTINGS"); }
- field_ = [[UISearchField alloc] initWithFrame:area];
- [field_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+ if ((self = [super init])) {
+ database_ = database;
+ name_ = [package retain];
- UIFont *font = [UIFont systemFontOfSize:16];
- [field_ setFont:font];
+ [[self navigationItem] setTitle:UCLocalize("SETTINGS")];
- [field_ setPlaceholder:UCLocalize("SEARCH_EX")];
- [field_ setDelegate:self];
+ table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
+ [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [table_ setAllowsSelection:NO];
+ [[self view] addSubview:table_];
- [field_ setPaddingTop:5];
+ subscribedSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+ [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+ [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged];
- UITextInputTraits *traits([field_ textInputTraits]);
- [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
- [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
- [traits setReturnKeyType:UIReturnKeySearch];
+ ignoredSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+ [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+ [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged];
- CGRect accrect = {{0, 6}, {6 + cnfrect.size.width + 6 + area.size.width + 6, area.size.height}};
+ subscribedCell_ = [[UITableViewCell alloc] init];
+ [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
+ [subscribedCell_ setAccessoryView:subscribedSwitch_];
- accessory_ = [[UIView alloc] initWithFrame:accrect];
- [accessory_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [accessory_ addSubview:field_];
+ ignoredCell_ = [[UITableViewCell alloc] init];
+ [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")];
+ [ignoredCell_ setAccessoryView:ignoredSwitch_];
- [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+ [table_ setDataSource:self];
+ [table_ setDelegate:self];
+ [self reloadData];
} return self;
}
-- (void) resetViewAnimated:(BOOL)animated {
- [table_ resetViewAnimated:animated];
-}
+- (void) reloadData {
+ if (package_ != nil)
+ [package_ autorelease];
+ package_ = [database_ packageWithName:name_];
+ if (package_ != nil) {
+ [package_ retain];
+ [subscribedSwitch_ setOn:([package_ subscribed] ? 1 : 0) animated:NO];
+ [ignoredSwitch_ setOn:([package_ ignored] ? 1 : 0) animated:NO];
+ }
-- (void) _reloadData {
+ [table_ reloadData];
}
-- (void) reloadData {
- _profile(SearchView$reloadData)
- [table_ reloadData];
- _end
- PrintTimes();
- [table_ resetCursor];
+@end
+/* }}} */
+
+/* Signature Controller {{{ */
+@interface SignatureController : CYBrowserController {
+ _transient Database *database_;
+ NSString *package_;
}
-- (UIView *) accessoryView {
- return accessory_;
+- (id) initWithDatabase:(Database *)database package:(NSString *)package;
+
+@end
+
+@implementation SignatureController
+
+- (void) dealloc {
+ [package_ release];
+ [super dealloc];
}
-- (NSString *) title {
- return nil;
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+ // XXX: dude!
+ [super webView:sender didClearWindowObject:window forFrame:frame];
}
-- (NSString *) backButtonTitle {
- return UCLocalize("SEARCH");
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+ if ((self = [super init]) != nil) {
+ database_ = database;
+ package_ = [package retain];
+ [self reloadData];
+ } return self;
}
-- (void) setDelegate:(id)delegate {
- [table_ setDelegate:delegate];
- [super setDelegate:delegate];
+- (void) reloadData {
+ [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]];
}
@end
/* }}} */
-/* Settings View {{{ */
-@interface SettingsView : RVPage {
+/* Role Controller {{{ */
+@interface RoleController : CYViewController <
+ UITableViewDataSource,
+ UITableViewDelegate
+> {
_transient Database *database_;
- NSString *name_;
- Package *package_;
- UIPreferencesTable *table_;
- _UISwitchSlider *subscribedSwitch_;
- _UISwitchSlider *ignoredSwitch_;
- UIPreferencesControlTableCell *subscribedCell_;
- UIPreferencesControlTableCell *ignoredCell_;
+ id roledelegate_;
+ UITableView *table_;
+ UISegmentedControl *segment_;
+ UIView *container_;
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database package:(NSString *)package;
+- (void) showDoneButton;
+- (void) resizeSegmentedControl;
@end
-@implementation SettingsView
-
+@implementation RoleController
- (void) dealloc {
- [table_ setDataSource:nil];
-
- [name_ release];
- if (package_ != nil)
- [package_ release];
[table_ release];
- [subscribedSwitch_ release];
- [ignoredSwitch_ release];
- [subscribedCell_ release];
- [ignoredCell_ release];
+ [segment_ release];
+ [container_ release];
+
[super dealloc];
}
-- (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table {
- if (package_ == nil)
- return 0;
+- (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];
- return 2;
+ 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;
}
-- (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group {
- if (package_ == nil)
- return nil;
+- (void) resizeSegmentedControl {
+ CGFloat width = [[self view] frame].size.width;
+ [segment_ setFrame:CGRectMake(width / 32.0f, 0, width - (width / 32.0f * 2.0f), 44.0f)];
+}
- switch (group) {
- case 0: return nil;
- case 1: return nil;
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
- _nodefault
- }
+ [self resizeSegmentedControl];
+}
- return nil;
+- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+ [self resizeSegmentedControl];
}
-- (BOOL) preferencesTable:(UIPreferencesTable *)table isLabelGroup:(int)group {
- if (package_ == nil)
- return NO;
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [self resizeSegmentedControl];
+}
+
+- (void) save {
+ NSString *role(nil);
- switch (group) {
- case 0: return NO;
- case 1: return YES;
+ switch ([segment_ selectedSegmentIndex]) {
+ case 0: role = @"User"; break;
+ case 1: role = @"Hacker"; break;
+ case 2: role = @"Developer"; break;
_nodefault
}
- return NO;
-}
+ if (![role isEqualToString:Role_]) {
+ bool rolling(Role_ == nil);
+ Role_ = role;
-- (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group {
- if (package_ == nil)
- return 0;
+ Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ Role_, @"Role",
+ nil];
- switch (group) {
- case 0: return 1;
- case 1: return 1;
+ [Metadata_ setObject:Settings_ forKey:@"Settings"];
- _nodefault
+ Changed_ = true;
+
+ if (rolling)
+ [roledelegate_ loadData];
+ else
+ [roledelegate_ updateData];
}
+}
- return 0;
+- (void) segmentChanged:(UISegmentedControl *)control {
+ [self showDoneButton];
}
-- (void) onSomething:(UIPreferencesControlTableCell *)cell withKey:(NSString *)key {
- if (package_ == nil)
- return;
+- (void) doneButtonClicked {
+ [self save];
+ [[self navigationController] dismissModalViewControllerAnimated:YES];
+}
- _UISwitchSlider *slider([cell control]);
- BOOL value([slider value] != 0);
- NSMutableDictionary *metadata([package_ metadata]);
+- (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];
+}
- BOOL before;
- if (NSNumber *number = [metadata objectForKey:key])
- before = [number boolValue];
- else
- before = NO;
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ // XXX: For not having a single cell in the table, this sure is a lot of sections.
+ return 6;
+}
- if (value != before) {
- [metadata setObject:[NSNumber numberWithBool:value] forKey:key];
- Changed_ = true;
- [delegate_ updateData];
- }
+- (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
+/* }}} */
+
+/* Cydia Container {{{ */
+@interface CYContainer : UIViewController <ProgressDelegate> {
+ _transient Database *database_;
+ RefreshBar *refreshbar_;
+
+ bool dropped_;
+ bool updating_;
+ id updatedelegate_;
+ UITabBarController *root_;
+}
+
+- (void) setTabBarController:(UITabBarController *)controller;
+
+- (void) dropBar:(BOOL)animated;
+- (void) beginUpdate;
+- (void) raiseBar:(BOOL)animated;
+
+@end
+
+@implementation CYContainer
+
+// NOTE: UIWindow only sends the top controller these messages,
+// So we have to forward them on.
+
+- (void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [root_ viewDidAppear:animated];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [root_ viewWillAppear:animated];
+}
+
+- (void) viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+ [root_ viewDidDisappear:animated];
+}
+
+- (void) viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+ [root_ viewWillDisappear:animated];
+}
+
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
+ return IsWildcat_;
}
-- (void) onSubscribed:(UIPreferencesControlTableCell *)cell {
- [self onSomething:cell withKey:@"IsSubscribed"];
+- (void) setTabBarController:(UITabBarController *)controller {
+ root_ = controller;
+ [[self view] addSubview:[root_ view]];
}
-- (void) onIgnored:(UIPreferencesControlTableCell *)cell {
- [self onSomething:cell withKey:@"IsIgnored"];
+- (void) setUpdate:(NSDate *)date {
+ [self beginUpdate];
}
-- (id) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group {
- if (package_ == nil)
- return nil;
+- (void) beginUpdate {
+ [self dropBar:YES];
+ [refreshbar_ start];
- 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;
- }
+ updating_ = true;
- _nodefault
- } break;
+ [NSThread
+ detachNewThreadSelector:@selector(performUpdate)
+ toTarget:self
+ withObject:nil
+ ];
+}
- _nodefault
- }
+- (void) performUpdate { _pooled
+ Status status;
+ status.setDelegate(self);
+ [database_ updateWithStatus:status];
- return nil;
+ [self
+ performSelectorOnMainThread:@selector(completeUpdate)
+ withObject:nil
+ waitUntilDone:NO
+ ];
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database package:(NSString *)package {
- if ((self = [super initWithBook:book])) {
- database_ = database;
- name_ = [package retain];
+- (void) completeUpdate {
+ updating_ = false;
+
+ [self raiseBar:YES];
+ [refreshbar_ stop];
+ [updatedelegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+}
- table_ = [[UIPreferencesTable alloc] initWithFrame:[self bounds]];
- [self addSubview:table_];
+- (void) cancelUpdate {
+ [refreshbar_ cancel];
+ [self completeUpdate];
+}
- subscribedSwitch_ = [[_UISwitchSlider alloc] initWithFrame:CGRectMake(200, 10, 50, 20)];
- [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventTouchUpInside];
+- (void) cancelPressed {
+ [self cancelUpdate];
+}
- ignoredSwitch_ = [[_UISwitchSlider alloc] initWithFrame:CGRectMake(200, 10, 50, 20)];
- [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventTouchUpInside];
+- (BOOL) updating {
+ return updating_;
+}
- subscribedCell_ = [[UIPreferencesControlTableCell alloc] init];
- [subscribedCell_ setShowSelection:NO];
- [subscribedCell_ setTitle:UCLocalize("SHOW_ALL_CHANGES")];
- [subscribedCell_ setControl:subscribedSwitch_];
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
+ [refreshbar_ setPrompt:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), error]];
+}
- ignoredCell_ = [[UIPreferencesControlTableCell alloc] init];
- [ignoredCell_ setShowSelection:NO];
- [ignoredCell_ setTitle:UCLocalize("IGNORE_UPGRADES")];
- [ignoredCell_ setControl:ignoredSwitch_];
+- (void) startProgress {
+}
- [table_ setDataSource:self];
- [self reloadData];
- } return self;
+- (void) setProgressTitle:(NSString *)title {
+ [self
+ performSelectorOnMainThread:@selector(_setProgressTitle:)
+ withObject:title
+ waitUntilDone:YES
+ ];
}
-- (void) resetViewAnimated:(BOOL)animated {
- [table_ resetViewAnimated:animated];
+- (bool) isCancelling:(size_t)received {
+ return !updating_;
}
-- (void) reloadData {
- if (package_ != nil)
- [package_ autorelease];
- 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];
- }
+- (void) setProgressPercent:(float)percent {
+ [self
+ performSelectorOnMainThread:@selector(_setProgressPercent:)
+ withObject:[NSNumber numberWithFloat:percent]
+ waitUntilDone:YES
+ ];
+}
- [table_ reloadData];
+- (void) addProgressOutput:(NSString *)output {
+ [self
+ performSelectorOnMainThread:@selector(_addProgressOutput:)
+ withObject:output
+ waitUntilDone:YES
+ ];
}
-- (NSString *) title {
- return UCLocalize("SETTINGS");
+- (void) _setProgressTitle:(NSString *)title {
+ [refreshbar_ setPrompt:title];
}
-@end
-/* }}} */
+- (void) _setProgressPercent:(NSNumber *)percent {
+ [refreshbar_ setProgress:[percent floatValue]];
+}
-/* Signature View {{{ */
-@interface SignatureView : CydiaBrowserView {
- _transient Database *database_;
- NSString *package_;
+- (void) _addProgressOutput:(NSString *)output {
}
-- (id) initWithBook:(RVBook *)book database:(Database *)database package:(NSString *)package;
+- (void) setUpdateDelegate:(id)delegate {
+ updatedelegate_ = delegate;
+}
-@end
+- (void) dropBar:(BOOL)animated {
+ if (dropped_) return;
+ dropped_ = true;
-@implementation SignatureView
+ [[self view] addSubview:refreshbar_];
-- (void) dealloc {
- [package_ release];
- [super dealloc];
-}
+ 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;
+ [[root_ view] setFrame:viewframe];
+ if (animated) [UIView commitAnimations];
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
- // XXX: dude!
- [super webView:sender didClearWindowObject:window forFrame:frame];
-}
+ // Ensure bar has the proper width for our view, it might have changed
+ barframe.size.width = viewframe.size.width;
+ [refreshbar_ setFrame:barframe];
-- (id) initWithBook:(RVBook *)book database:(Database *)database package:(NSString *)package {
- if ((self = [super initWithBook:book]) != nil) {
- database_ = database;
- package_ = [package retain];
- [self reloadData];
- } return self;
+ // XXX: fix Apple's layout bug
+ [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
}
-- (void) resetViewAnimated:(BOOL)animated {
+- (void) raiseBar:(BOOL)animated {
+ if (!dropped_) return;
+ dropped_ = false;
+
+ [refreshbar_ removeFromSuperview];
+
+ 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;
+ [[root_ view] setFrame:viewframe];
+ if (animated) [UIView commitAnimations];
+
+ // XXX: fix Apple's layout bug
+ [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
}
-- (void) reloadData {
- [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]];
+- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+ // XXX: fix Apple's layout bug
+ [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
}
-@end
-/* }}} */
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ if (dropped_) {
+ [self raiseBar:NO];
+ [self dropBar:NO];
+ }
-@interface CydiaViewController : UIViewController {
+ // XXX: fix Apple's layout bug
+ [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
}
-@end
+- (void) dealloc {
+ [refreshbar_ release];
+ [super dealloc];
+}
+
+- (id) initWithDatabase:(Database *)database {
+ if ((self = [super init]) != nil) {
+ database_ = database;
-@implementation CydiaViewController
+ [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
- return NO; // XXX: return YES;
+ refreshbar_ = [[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self];
+ } return self;
}
@end
+/* }}} */
+
+typedef enum {
+ kCydiaTag = 0,
+ kSectionsTag = 1,
+ kChangesTag = 2,
+ kManageTag = 3,
+ kInstalledTag = 4,
+ kSourcesTag = 5,
+ kSearchTag = 6
+} CYTabTag;
@interface Cydia : UIApplication <
- ConfirmationViewDelegate,
- ProgressViewDelegate,
- SearchViewDelegate,
- CydiaDelegate
+ ConfirmationControllerDelegate,
+ ProgressControllerDelegate,
+ CydiaDelegate,
+ UINavigationControllerDelegate
> {
UIWindow *window_;
- CydiaViewController *root_;
-
- UIView *underlay_;
- UIView *overlay_;
- CYBook *book_;
+ CYContainer *container_;
- NSArray *items_;
- UITabBar *toolbar_;
-
- RVBook *confirm_;
+ id tabbar_;
NSMutableArray *essential_;
NSMutableArray *broken_;
Database *database_;
- ProgressView *progress_;
int tag_;
UIKeyboard *keyboard_;
UIProgressHUD *hud_;
- SectionsView *sections_;
- ChangesView *changes_;
- ManageView *manage_;
- SearchView *search_;
+ SectionsController *sections_;
+ ChangesController *changes_;
+ ManageController *manage_;
+ SearchController *search_;
+ SourceTable *sources_;
+ InstalledController *installed_;
+ id queueDelegate_;
#if RecyclePackageViews
NSMutableArray *details_;
#endif
+
+ bool loaded_;
}
-- (RVPage *) _pageForURL:(NSURL *)url withClass:(Class)_class;
-- (void) setPage:(RVPage *)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
+- (void) beginUpdate {
+ [container_ beginUpdate];
+}
+
+- (BOOL) updating {
+ return [container_ updating];
+}
+
- (UIView *) rotatingContentViewForWindow:(UIWindow *)window {
return window_;
}
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:(count == 1 ? UCLocalize("HALFINSTALLED_PACKAGE") : [NSString stringWithFormat:UCLocalize("HALFINSTALLED_PACKAGES"), count])
- message:UCLocalize("HALFINSTALLED_PACKAGE_EX")
- delegate:self
- cancelButtonTitle:UCLocalize("FORCIBLY_CLEAR")
- otherButtonTitles:UCLocalize("TEMPORARY_IGNORE"), nil
+ message:UCLocalize("HALFINSTALLED_PACKAGE_EX")
+ delegate:self
+ cancelButtonTitle:UCLocalize("FORCIBLY_CLEAR")
+ otherButtonTitles:UCLocalize("TEMPORARY_IGNORE"), nil
] autorelease];
[alert setContext:@"fixhalf"];
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle:(count == 1 ? UCLocalize("ESSENTIAL_UPGRADE") : [NSString stringWithFormat:UCLocalize("ESSENTIAL_UPGRADES"), count])
- message:UCLocalize("ESSENTIAL_UPGRADE_EX")
- delegate:self
- cancelButtonTitle:UCLocalize("TEMPORARY_IGNORE")
+ message:UCLocalize("ESSENTIAL_UPGRADE_EX")
+ delegate:self
+ cancelButtonTitle:UCLocalize("TEMPORARY_IGNORE")
otherButtonTitles:UCLocalize("UPGRADE_ESSENTIAL"), UCLocalize("COMPLETE_UPGRADE"), nil
] autorelease];
if (tag_ != 4 && search_ != nil)
[search_ reloadData];
- [book_ reloadData];
+ [(CYNavigationController *)[tabbar_ selectedViewController] reloadData];
}
-- (void) _reloadData {
- UIView *block();
+- (int)indexOfTabWithTag:(int)tag {
+ int i = 0;
+ for (UINavigationController *controller in [tabbar_ viewControllers]) {
+ if ([[controller tabBarItem] tag] == tag) return i;
+ i += 1;
+ }
+
+ return -1;
+}
+
+- (void) _refreshIfPossible {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- static bool loaded(false);
+ 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;
+
+ NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
+
+ if (update != nil) {
+ NSTimeInterval interval([update timeIntervalSinceNow]);
+ if (interval <= 0 && interval > -(15*60))
+ goto loaded;
+ }
+
+ [container_ performSelectorOnMainThread:@selector(setUpdate:) withObject:update waitUntilDone:NO];
+ }
+
+ [pool release];
+}
+
+- (void) refreshIfPossible {
+ [NSThread detachNewThreadSelector:@selector(_refreshIfPossible) toTarget:self withObject:nil];
+}
+
+- (void) _reloadData {
UIProgressHUD *hud([self addProgressHUD]);
- [hud setText:(loaded ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))];
+ [hud setText:(loaded_ ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))];
[database_ yieldToSelector:@selector(reloadData) withObject:nil];
_trace();
if (changes != 0) {
NSString *badge([[NSNumber numberWithInt:changes] stringValue]);
- [[[toolbar_ items] objectAtIndex:2] setBadgeValue:badge];
- if ([toolbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
- [[[toolbar_ items] objectAtIndex:2] setAnimatedBadge:YES];
+ [[[[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
[self setApplicationBadgeString:badge];
} else {
- [[[toolbar_ items] objectAtIndex:2] setBadgeValue:nil];
- if ([toolbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
- [[[toolbar_ items] objectAtIndex:2] setAnimatedBadge:NO];
+ [[[[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?
[self setApplicationIconBadgeNumber:0];
}
- Queuing_ = false;
- [[[toolbar_ items] objectAtIndex:3] setBadgeValue:nil];
-
[self _updateData];
- if (loaded || ManualRefresh) loaded:
- [self _loaded];
- else {
- loaded = true;
-
- NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
-
- if (update != nil) {
- NSTimeInterval interval([update timeIntervalSinceNow]);
- if (interval <= 0 && interval > -(15*60))
- goto loaded;
- }
-
- [book_ setUpdate:update];
- }
+ [self refreshIfPossible];
}
- (void) updateData {
[self _saveConfig];
- [progress_
+ 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];
+
+ [progress
detachNewThreadSelector:@selector(update_)
toTarget:self
withObject:nil
- (void) reloadData {
@synchronized (self) {
- if (confirm_ == nil)
- [self _reloadData];
+ [self _reloadData];
}
}
_error->Discard();
}
-- (void) popUpBook:(RVBook *)book {
- [underlay_ popSubview:book];
-}
-
- (CGRect) popUpBounds {
- return [underlay_ bounds];
+ return [[tabbar_ view] bounds];
}
- (bool) perform {
if (![database_ prepare])
return false;
- confirm_ = [[RVBook alloc] initWithFrame:[self popUpBounds]];
- [confirm_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [confirm_ setDelegate:self];
-
- ConfirmationView *page([[[ConfirmationView alloc] initWithBook:confirm_ database:database_] autorelease]);
+ ConfirmationController *page([[[ConfirmationController alloc] initWithDatabase:database_] autorelease]);
[page setDelegate:self];
+ CYNavigationController *confirm_ = [[CYNavigationController alloc] initWithRootViewController:page];
+ [confirm_ setDelegate:self];
- [confirm_ setPage:page];
- [self popUpBook:confirm_];
+ if (IsWildcat_) [confirm_ setModalPresentationStyle:UIModalPresentationFormSheet];
+ [container_ presentModalViewController:confirm_ animated:YES];
return true;
}
- (void) complete {
@synchronized (self) {
[self _reloadData];
-
- if (confirm_ != nil) {
- [confirm_ release];
- confirm_ = nil;
- }
}
}
-- (void) confirm {
- [overlay_ removeFromSuperview];
- reload_ = true;
+- (void) confirmWithNavigationController:(UINavigationController *)navigation {
+ ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
- [progress_
+ if (navigation != nil) {
+ [navigation pushViewController:progress animated:YES];
+ } else {
+ navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
+ if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
+ [container_ presentModalViewController:navigation animated:YES];
+ }
+
+ [progress
detachNewThreadSelector:@selector(perform)
toTarget:database_
withObject:nil
];
}
-- (void) progressViewIsComplete:(ProgressView *)progress {
- if (confirm_ != nil) {
- [underlay_ addSubview:overlay_];
- [confirm_ popFromSuperviewAnimated:NO];
- }
-
+- (void) progressControllerIsComplete:(ProgressController *)progress {
[self complete];
}
-- (void) setPage:(RVPage *)page {
- [page resetViewAnimated:NO];
+- (void) setPage:(CYViewController *)page {
[page setDelegate:self];
- [book_ setPage:page];
+
+ CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController];
+ [navController setViewControllers:[NSArray arrayWithObject:page] animated:NO];
+ for (CYNavigationController *page in [tabbar_ viewControllers]) {
+ if (page != navController) [page setViewControllers:nil];
+ }
}
-- (RVPage *) _pageForURL:(NSURL *)url withClass:(Class)_class {
- CydiaBrowserView *browser = [[[_class alloc] initWithBook:book_] autorelease];
+- (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] initWithBook:book_ database:database_];
+ sections_ = [[SectionsController alloc] initWithDatabase:database_];
return sections_;
}
-- (ChangesView *) changesView {
+- (ChangesController *) changesController {
if (changes_ == nil)
- changes_ = [[ChangesView alloc] initWithBook:book_ database:database_ delegate:self];
+ changes_ = [[ChangesController alloc] initWithDatabase:database_ delegate:self];
return changes_;
}
-- (ManageView *) manageView {
- if (manage_ == nil)
- manage_ = (ManageView *) [[self
+- (ManageController *) manageController {
+ if (manage_ == nil) {
+ 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] initWithBook:book_ database:database_];
+ search_ = [[SearchController alloc] initWithDatabase:database_];
return search_;
}
-- (void) tabBar:(UITabBar *)sender didSelectItem:(UITabBarItem *)item {
- int tag = [item tag];
+- (SourceTable *) sourcesController {
+ if (sources_ == nil)
+ sources_ = [[SourceTable alloc] initWithDatabase:database_];
+ return sources_;
+}
+
+- (InstalledController *) installedController {
+ if (installed_ == nil) {
+ installed_ = [[InstalledController alloc] initWithDatabase:database_];
+ if (IsWildcat_) queueDelegate_ = installed_;
+ }
+ return installed_;
+}
+
+- (void) tabBarController:(id)tabBarController didSelectViewController:(UIViewController *)viewController {
+ int tag = [[viewController tabBarItem] tag];
if (tag == tag_) {
- [book_ resetViewAnimated:YES];
+ [(CYNavigationController *)[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES];
return;
- } else if (tag_ == 1)
- [[self sectionsView] resetView];
+ } else if (tag_ == 1) {
+ [[self sectionsController] resetView];
+ }
switch (tag) {
- case 0: _setHomePage(self); break;
+ case kCydiaTag: _setHomePage(self); break;
- case 1: [self setPage:[self sectionsView]]; break;
- case 2: [self setPage:[self changesView]]; break;
- case 3: [self setPage:[self manageView]]; break;
- case 4: [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
}
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
WebThreadUnlock();
}
-- (PackageView *) _packageView {
- return [[[PackageView alloc] initWithBook:book_ database: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];
return view;
#else
- return [self _packageView];
+ return [self _packageController];
#endif
}
- (void) cancelAndClear:(bool)clear {
@synchronized (self) {
if (clear) {
- [self _reloadData];
+ // Clear all marks.
+ pkgCacheFile &cache([database_ cache]);
+ for (pkgCache::PkgIterator iterator = cache->PkgBegin(); !iterator.end(); ++iterator) {
+ // 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);
+ }
+ }
+
+ // Stop queuing, and let the appropriate controller know it.
+ Queuing_ = false;
+ [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:nil];
+ [queueDelegate_ queueStatusDidChange];
} else {
- Queuing_ = true;
- [[[toolbar_ items] objectAtIndex:3] setBadgeValue:UCLocalize("Q_D")];
- [book_ reloadData];
+ // Start queuing, and let the controllers know.
+ Queuing_ = true;
+
+ [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:UCLocalize("Q_D")];
+ [(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]) {
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+ NSString *context([alert context]);
+
+ if ([context isEqualToString:@"fixhalf"]) {
+ if (button == [alert firstOtherButtonIndex]) {
@synchronized (self) {
for (Package *broken in broken_) {
[broken remove];
[self resolve];
[self perform];
}
- } else if (button == [alert cancelButtonIndex]) {
+ } else if (button == [alert cancelButtonIndex]) {
[broken_ removeAllObjects];
[self _loaded];
}
}
- (void) applicationSuspend:(__GSEvent *)event {
- if (hud_ == nil && ![progress_ isRunning])
+ // 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];
}
[window_ setUserInteractionEnabled:NO];
[hud show:YES];
- [progress_ addSubview:hud];
+ [[container_ view] addSubview:hud];
return hud;
}
[window_ setUserInteractionEnabled:YES];
}
-- (RVPage *) 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 {
NSURL *url([NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"unknown" ofType:@"html"]]);
url = [NSURL URLWithString:[[url absoluteString] stringByAppendingString:[NSString stringWithFormat:@"?%@", name]]];
- return [self _pageForURL:url withClass:[CydiaBrowserView class]];
+ return [self _pageForURL:url withClass:[CYBrowserController class]];
}
}
-- (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag {
+- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
if (tag != NULL)
*tag = -1;
path = [@"/" stringByAppendingString:path];
if ([path isEqualToString:@"/add-source"])
- return [[[AddSourceView alloc] initWithBook:book_ database: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:[CydiaBrowserView class]];
+ return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[CYBrowserController class]];
else if ([path isEqualToString:@"/sources"])
- return [[[SourceTable alloc] initWithBook:book_ database:database_] autorelease];
+ return [[[SourceTable alloc] initWithDatabase:database_] autorelease];
else if ([path isEqualToString:@"/packages"])
- return [[[InstalledView alloc] initWithBook:book_ database:database_] autorelease];
+ return [[[InstalledController alloc] initWithDatabase:database_] autorelease];
else if ([path hasPrefix:@"/url/"])
- return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[CydiaBrowserView class]];
+ 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] initWithBook:book_ database: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] initWithBook:book_ database: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/"]) {
NSString *name = [path substringFromIndex:7];
if (Package *package = [database_ packageWithName:name]) {
- FileTable *files = [[[FileTable alloc] initWithBook:book_ database:database_] autorelease];
+ FileTable *files = [[[FileTable alloc] initWithDatabase:database_] autorelease];
[files setPackage:package];
return files;
}
- (void) applicationOpenURL:(NSURL *)url {
[super applicationOpenURL:url];
int tag;
- if (RVPage *page = [self pageForURL:url hasTag:&tag]) {
+ if (CYViewController *page = [self pageForURL:url hasTag:&tag]) {
[self setPage:page];
tag_ = tag;
- [toolbar_ setSelectedItem:(tag_ == -1 ? nil : [items_ objectAtIndex: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 {
- [BrowserView _initialize];
+ [CYBrowserController _initialize];
[NSURLProtocol registerClass:[CydiaURLProtocol class]];
[window_ makeKey:self];
[window_ setHidden:NO];
- root_ = [[CydiaViewController alloc] init];
- [window_ addSubview:[root_ view]];
-
database_ = [Database sharedInstance];
- progress_ = [[ProgressView alloc] initWithFrame:[[root_ view] bounds] database:database_ delegate:self];
- [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [[root_ view] addSubview:progress_];
-
- [database_ setDelegate:progress_];
-
- underlay_ = [[UIView alloc] initWithFrame:[progress_ bounds]];
- [underlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [progress_ setContentView:underlay_];
-
- [progress_ resetView];
-
if (
readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
[self setIdleTimerDisabled:YES];
hud_ = [self addProgressHUD];
- [hud_ setText:@"Reorganizing\n\nWill Automatically\nClose When Done"];
+ [hud_ setText:@"Reorganizing:\n\nWill Automatically\nClose When Done"];
[self setStatusBarShowsProgress:YES];
[self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
return;
}
- if (Role_ == nil)
- [self askForSettings];
-
_trace();
- overlay_ = [[UIView alloc] initWithFrame:[underlay_ bounds]];
- [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-
- CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
-
- book_ = [[CYBook alloc] initWithFrame:CGRectMake(
- 0, 0, screenrect.size.width, screenrect.size.height - 48
- ) database:database_];
-
- [book_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
- [overlay_ addSubview:book_];
-
- [book_ setDelegate:self];
-
- items_ = [[NSArray arrayWithObjects:
- [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:0] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:1] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:2] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:3] autorelease],
- [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:4] autorelease],
- nil] retain];
- toolbar_ = [[UITabBar alloc]
- initWithFrame:CGRectMake(
- 0, screenrect.size.height - ButtonBarHeight_,
- screenrect.size.width, ButtonBarHeight_
- )
- ];
-
- [toolbar_ setItems:items_];
+ 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]);
- [toolbar_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
- [overlay_ addSubview:toolbar_];
+ 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];
+ }
- [toolbar_ setDelegate:self];
+ NSMutableArray *controllers([NSMutableArray array]);
- /*int buttons[5] = {1, 2, 3, 4, 5};
- [toolbar_ registerButtonGroup:0 withButtons:buttons withCount:5];
- [toolbar_ showButtonGroup:0 withDuration:0];
+ for (UITabBarItem *item in items) {
+ CYNavigationController *controller([[[CYNavigationController alloc] initWithDatabase:database_] autorelease]);
+ [controller setTabBarItem:item];
+ [controllers addObject:controller];
+ }
- for (int i = 0; i != 5; ++i) {
- UIView *button([toolbar_ viewWithTag:(i + 1)]);
+ tabbar_ = [[CYTabBarController alloc] initWithDatabase:database_];
+ [tabbar_ setViewControllers:controllers];
+ [tabbar_ setDelegate:self];
+ [tabbar_ setSelectedIndex:0];
- [button setFrame:CGRectMake(
- i * (screenrect.size.width / 5) + (screenrect.size.width / 5 - ButtonBarWidth_) / 2, 1,
- ButtonBarWidth_, ButtonBarHeight_
- )];
+ container_ = [[CYContainer alloc] initWithDatabase:database_];
+ [container_ setUpdateDelegate:self];
+ [container_ setTabBarController:tabbar_];
+ [window_ addSubview:[container_ view]];
- [button setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
- }*/
+ [self performSelector:@selector(loadData) withObject:nil afterDelay:0];
+}
- [toolbar_ setSelectedItem:[items_ objectAtIndex:0]];
+- (void) loadData {
+ if (Role_ == nil) {
+ [self showSettings];
+ return;
+ }
[UIKeyboard initImplementationNow];
- /*CGSize keysize = [UIKeyboard defaultSize];
- CGRect keyrect = {{0, [overlay_ bounds].size.height}, keysize};
- keyboard_ = [[UIKeyboard alloc] initWithFrame:keyrect];
- [overlay_ addSubview:keyboard_];*/
-
- [underlay_ addSubview:overlay_];
[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();
_setHomePage(self);
}
-- (void) showKeyboard:(BOOL)show {
- CGSize keysize([UIKeyboard defaultSize]);
- CGRect keydown = {{0, [overlay_ bounds].size.height}, keysize};
- CGRect keyup(keydown);
- keyup.origin.y -= keysize.height;
-
- UIFrameAnimation *animation([[[UIFrameAnimation alloc] initWithTarget:keyboard_] autorelease]);
- [animation setSignificantRectFields:2];
-
- if (show) {
- [animation setStartFrame:keydown];
- [animation setEndFrame:keyup];
- [keyboard_ activate];
- } else {
- [animation setStartFrame:keyup];
- [animation setEndFrame:keydown];
- [keyboard_ deactivate];
- }
-
- [[UIAnimator sharedAnimator]
- addAnimations:[NSArray arrayWithObjects:animation, nil]
- withDuration:KeyboardTime_
- start:YES
- ];
-}
-
-- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIButton *)item {
+- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item {
if (item != nil && IsWildcat_) {
- [sheet showFromRect:[[item superview] convertRect:[item frame] toView:window_] inView:window_ animated:YES];
+ [sheet showFromBarButtonItem:item animated:YES];
} else {
[sheet showInView:window_];
}
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();
PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(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");
_UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast<void (*)(UIWebDocumentView *, SEL, id)>(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$));
method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
}
+
+ $UIHardware = objc_getClass("UIHardware");
+ Method UIHardware$_playSystemSound$(class_getClassMethod($UIHardware, @selector(_playSystemSound:)));
+ if (UIHardware$_playSystemSound$ != NULL) {
+ _UIHardware$_playSystemSound$ = reinterpret_cast<void (*)(Class, SEL, int)>(method_getImplementation(UIHardware$_playSystemSound$));
+ method_setImplementation(UIHardware$_playSystemSound$, reinterpret_cast<IMP>(&$UIHardware$_playSystemSound$));
+ }
/* }}} */
/* Set Locale {{{ */
Locale_ = CFLocaleCopyCurrent();
Warning_ = UCLocalize("WARNING");
_trace();
- int value = UIApplicationMain(argc, argv, @"Cydia", @"Cydia");
+ int value(UIApplicationMain(argc, argv, @"Cydia", @"Cydia"));
CGColorSpaceRelease(space_);
CFRelease(Locale_);