static UIColor *RemovingColor_;
static NSString *App_;
-static NSString *Home_;
static BOOL Advanced_;
static BOOL Ignored_;
bool IsWildcat_;
static CGFloat ScreenScale_;
+static NSString *Idiom_;
/* }}} */
/* Display Helpers {{{ */
@protocol ProgressDelegate
- (void) addProgressEvent:(CydiaProgressEvent *)event;
- (void) setProgressPercent:(NSNumber *)percent;
+- (void) setProgressStatus:(NSDictionary *)status;
- (void) setProgressCancellable:(NSNumber *)cancellable;
- (bool) isProgressCancelled;
- (void) setTitle:(NSString *)title;
virtual bool Pulse(pkgAcquire *Owner) {
bool value = pkgAcquireStatus::Pulse(Owner);
- float percent(
+ double percent(
double(CurrentBytes + CurrentItems) /
double(TotalBytes + TotalItems)
);
- [delegate_ performSelectorOnMainThread:@selector(setProgressPercent:) withObject:[NSNumber numberWithFloat:percent] waitUntilDone:YES];
+ [delegate_ performSelectorOnMainThread:@selector(setProgressStatus:) withObject:[NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithDouble:percent], @"Percent",
+
+ [NSNumber numberWithDouble:CurrentBytes], @"Current",
+ [NSNumber numberWithDouble:TotalBytes], @"Total",
+ [NSNumber numberWithDouble:CurrentCPS], @"Speed",
+ nil] waitUntilDone:YES];
+
if (value && ![delegate_ isProgressCancelled])
return true;
else {
virtual void Stop() {
pkgAcquireStatus::Stop();
[delegate_ performSelectorOnMainThread:@selector(setProgressCancellable:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:YES];
+ [delegate_ performSelectorOnMainThread:@selector(setProgressStatus:) withObject:nil waitUntilDone:YES];
}
};
/* }}} */
size_t size(line.size());
lprintf("S:%s\n", data);
- if (conffile_r(data, size))
+ if (conffile_r(data, size)) {
+ // status: /fail : conffile-prompt : '/fail' '/fail.dpkg-new' 1 1
[delegate_ performSelectorOnMainThread:@selector(setConfigurationData:) withObject:conffile_r[1] waitUntilDone:YES];
- else if (strncmp(data, "status: ", 8) == 0) {
+ } else if (strncmp(data, "status: ", 8) == 0) {
+ // status: <package>: {unpacked,half-configured,installed}
CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:(data + 8)] ofType:@"STATUS"]);
- [progress_ performSelectorOnMainThread:@selector(addProgressEvent) withObject:event waitUntilDone:YES];
+ [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES];
+ } else if (strncmp(data, "processing: ", 12) == 0) {
+ // processing: configure: config-test
+ CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:(data + 12)] ofType:@"STATUS"]);
+ [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES];
} else if (pmstatus_r(data, size)) {
std::string type([pmstatus_r[1] UTF8String]);
}
- (NSString *) idiom {
- UIDevice *device([UIDevice currentDevice]);
- if (![device respondsToSelector:@selector(userInterfaceIdiom)])
- return @"iphone";
-
- UIUserInterfaceIdiom idiom([device userInterfaceIdiom]);
- if (idiom == UIUserInterfaceIdiomPhone)
- return @"iphone";
- else if (idiom == UIUserInterfaceIdiomPad)
- return @"ipad";
- else
- return @"unknown";
+ return (id) Idiom_ ?: [NSNull null];
}
- (NSString *) plmn {
return @"refreshSources";
else if (selector == @selector(removeButton))
return @"removeButton";
+ else if (selector == @selector(substitutePackageNames:))
+ return @"substitutePackageNames";
else if (selector == @selector(scrollToBottom:))
return @"scrollToBottom";
else if (selector == @selector(setButtonImage:withStyle:toFunction:))
return @"setButtonTitle";
else if (selector == @selector(setHidesBackButton:))
return @"setHidesBackButton";
+ else if (selector == @selector(setHidesNavigationBar:))
+ return @"setHidesNavigationBar";
else if (selector == @selector(setNavigationBarStyle:))
return @"setNavigationBarStyle";
+ else if (selector == @selector(setNavigationBarTintRed:green:blue:alpha:))
+ return @"setNavigationBarTintColor";
else if (selector == @selector(setPopupHook:))
return @"setPopupHook";
else if (selector == @selector(setToken:))
[delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO];
}
+- (NSString *) substitutePackageNames:(NSString *)message {
+ NSMutableArray *words([[message componentsSeparatedByString:@" "] mutableCopy]);
+ for (size_t i(0), e([words count]); i != e; ++i) {
+ NSString *word([words objectAtIndex:i]);
+ if (Package *package = [[Database sharedInstance] packageWithName:word])
+ [words replaceObjectAtIndex:i withObject:[package name]];
+ }
+
+ return [words componentsJoinedByString:@" "];
+}
+
- (void) removeButton {
[indirect_ removeButton];
}
[indirect_ performSelectorOnMainThread:@selector(setHidesBackButtonByNumber:) withObject:value waitUntilDone:NO];
}
+- (void) setHidesNavigationBar:(NSString *)value {
+ [indirect_ performSelectorOnMainThread:@selector(setHidesNavigationBarByNumber:) withObject:value waitUntilDone:NO];
+}
+
- (void) setNavigationBarStyle:(NSString *)value {
[indirect_ performSelectorOnMainThread:@selector(setNavigationBarStyle:) withObject:value waitUntilDone:NO];
}
+- (void) setNavigationBarTintRed:(NSNumber *)red green:(NSNumber *)green blue:(NSNumber *)blue alpha:(NSNumber *)alpha {
+ float opacity(alpha == (id) [WebUndefined undefined] ? 1 : [alpha floatValue]);
+ UIColor *color([UIColor colorWithRed:[red floatValue] green:[green floatValue] blue:[blue floatValue] alpha:opacity]);
+ [indirect_ performSelectorOnMainThread:@selector(setNavigationBarTintColor:) withObject:color waitUntilDone:NO];
+}
+
- (void) _setToken:(NSString *)token {
Token_ = token;
} return self;
}
+// XXX: factor this out somewhere
+- (UIColor *) groupTableViewBackgroundColor {
+ UIDevice *device([UIDevice currentDevice]);
+ bool iPad([device respondsToSelector:@selector(userInterfaceIdiom)] && [device userInterfaceIdiom] == UIUserInterfaceIdiomPad);
+ return iPad ? [UIColor colorWithRed:0.821 green:0.834 blue:0.860 alpha:1] : [UIColor groupTableViewBackgroundColor];
+}
+
- (void) loadView {
[self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];
- [[self view] setBackgroundColor:[UIColor pinStripeColor]];
+ [[self view] setBackgroundColor:[self groupTableViewBackgroundColor]];
indicator_ = [[[CYLoadingIndicator alloc] initWithFrame:[[self view] bounds]] autorelease];
[indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
[NSNumber numberWithInteger:[database_ fetcher].PartialPresent()], @"resuming",
nil];
- [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/confirm/", UI_]]];
+ [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/confirm/", UI_]]];
[[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
initWithTitle:UCLocalize("CANCEL")
bool running_;
float percent_;
+ float current_;
+ float total_;
+ float speed_;
+
_H<NSMutableArray> events_;
_H<NSString> title_;
+ (NSArray *) _attributeKeys {
return [NSArray arrayWithObjects:
+ @"current",
@"events",
@"finish",
@"percent",
@"running",
+ @"speed",
@"title",
+ @"total",
nil];
}
return [NSNumber numberWithFloat:percent_];
}
+- (void) setCurrent:(float)value {
+ current_ = value;
+}
+
+- (NSNumber *) current {
+ return [NSNumber numberWithFloat:current_];
+}
+
+- (void) setTotal:(float)value {
+ total_ = value;
+}
+
+- (NSNumber *) total {
+ return [NSNumber numberWithFloat:total_];
+}
+
+- (void) setSpeed:(float)value {
+ speed_ = value;
+}
+
+- (NSNumber *) speed {
+ return [NSNumber numberWithFloat:speed_];
+}
+
- (NSArray *) events {
return events_;
}
[super dealloc];
}
+- (void) updateCancel {
+ [[self navigationItem] setLeftBarButtonItem:(cancel_ == 1 ? [[[UIBarButtonItem alloc]
+ initWithTitle:UCLocalize("CANCEL")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(cancel)
+ ] autorelease] : nil)];
+}
+
- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
if ((self = [super init]) != nil) {
database_ = database;
progress_ = [[[CydiaProgressData alloc] init] autorelease];
[progress_ setDelegate:self];
+
+ [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/progress/", UI_]]];
+
+ [scroller_ setBackgroundColor:[UIColor blackColor]];
+
+ [[self navigationItem] setHidesBackButton:YES];
+
+ [self updateCancel];
} return self;
}
[self dispatchEvent:@"CydiaProgressUpdate"];
}
-- (void) updateCancel {
- [[self navigationItem] setLeftBarButtonItem:(cancel_ == 1 ? [[[UIBarButtonItem alloc]
- initWithTitle:UCLocalize("CANCEL")
- style:UIBarButtonItemStylePlain
- target:self
- action:@selector(cancel)
- ] autorelease] : nil)];
-}
-
- (void) viewWillAppear:(BOOL)animated {
- if (![self hasLoaded]) {
- [scroller_ setBackgroundColor:[UIColor blackColor]];
- [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/progress/", UI_]]];
- }
-
- [super viewDidAppear:animated];
-
- [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
-
- [[self navigationItem] setHidesBackButton:YES];
+ if (![self hasLoaded])
+ [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
- [self updateCancel];
+ [super viewWillAppear:animated];
}
- (void) close {
[self updateProgress];
}
+- (void) setProgressStatus:(NSDictionary *)status {
+ if (status == nil) {
+ [progress_ setCurrent:0];
+ [progress_ setTotal:0];
+ [progress_ setSpeed:0];
+ } else {
+ [progress_ setPercent:[[status objectForKey:@"Percent"] floatValue]];
+
+ [progress_ setCurrent:[[status objectForKey:@"Current"] floatValue]];
+ [progress_ setTotal:[[status objectForKey:@"Total"] floatValue]];
+ [progress_ setSpeed:[[status objectForKey:@"Speed"] floatValue]];
+ }
+
+ [self updateProgress];
+}
+
@end
/* }}} */
UIActionSheetDelegate
> {
_transient Database *database_;
- Package *package_;
- NSString *name_;
+ _H<Package> package_;
+ _H<NSString> name_;
bool commercial_;
- NSMutableArray *buttons_;
- UIBarButtonItem *button_;
+ _H<NSMutableArray> buttons_;
+ _H<UIBarButtonItem> button_;
}
- (id) initWithDatabase:(Database *)database forPackage:(NSString *)name;
@implementation CYPackageController
-- (void) dealloc {
- if (package_ != nil)
- [package_ release];
- if (name_ != nil)
- [name_ release];
-
- [buttons_ release];
-
- if (button_ != nil)
- [button_ release];
-
- [super dealloc];
+- (NSURL *) navigationURL {
+ return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@", (id) name_]];
}
-- (NSURL *) navigationURL {
- return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@", name_]];
+- (bool) _allowNavigationAction {
+ // XXX: damn it... I really want this.
+ return true;
}
/* XXX: this is not safe at all... localization of /fail/ */
- (id) initWithDatabase:(Database *)database forPackage:(NSString *)name {
if ((self = [super init]) != nil) {
database_ = database;
- buttons_ = [[NSMutableArray alloc] initWithCapacity:4];
- name_ = [[NSString alloc] initWithString:name];
- [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/package/#!/%@", UI_, name_]]];
+ buttons_ = [NSMutableArray arrayWithCapacity:4];
+ name_ = [NSString stringWithString:name];
+ [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/package/%@", UI_, (id) name_]]];
} return self;
}
- (void) reloadData {
- if (package_ != nil)
- [package_ autorelease];
package_ = [database_ packageWithName:name_];
[buttons_ removeAllObjects];
if (package_ != nil) {
- [package_ parse];
+ [(Package *) package_ parse];
- package_ = [package_ retain];
commercial_ = [package_ isCommercial];
if ([package_ mode] != nil)
[buttons_ addObject:UCLocalize("REMOVE")];
}
- if (button_ != nil)
- [button_ release];
-
NSString *title;
switch ([buttons_ count]) {
case 0: title = nil; break;
default: title = UCLocalize("MODIFY"); break;
}
- button_ = [[UIBarButtonItem alloc]
+ button_ = [[[UIBarButtonItem alloc]
initWithTitle:title
style:UIBarButtonItemStylePlain
target:self
action:@selector(customButtonClicked)
- ];
+ ] autorelease];
[super reloadData];
}
@implementation HomeController
-+ (BOOL) shouldHideNavigationBar {
- return NO;
+- (id) init {
+ if ((self = [super init]) != nil) {
+ [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/home/", UI_]]];
+ } return self;
}
- (NSURL *) navigationURL {
[alert show];
}
-- (void) viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
-
- if ([[self class] shouldHideNavigationBar])
- [[self navigationController] setNavigationBarHidden:NO animated:animated];
-}
-
-- (void) viewWillAppear:(BOOL)animated {
- if (![self hasLoaded])
- [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/home/", UI_]]];
-
- [super viewWillAppear:animated];
-
- if ([[self class] shouldHideNavigationBar])
- [[self navigationController] setNavigationBarHidden:YES animated:animated];
-}
-
- (void) viewDidLoad {
[[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
initWithTitle:UCLocalize("ABOUT")
@implementation ManageController
-- (NSURL *) navigationURL {
- return [NSURL URLWithString:@"cydia://manage"];
+- (id) init {
+ if ((self = [super init]) != nil) {
+ [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/manage/", UI_]]];
+ } return self;
}
-- (void) viewWillAppear:(BOOL)animated {
- if (![self hasLoaded])
- [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/manage/", UI_]]];
-
- [super viewWillAppear:animated];
+- (NSURL *) navigationURL {
+ return [NSURL URLWithString:@"cydia://manage"];
}
- (void) viewDidLoad {
[refreshbar_ setProgress:[percent floatValue]];
}
+- (void) setProgressStatus:(NSDictionary *)status {
+ if (status != nil)
+ [self setProgressPercent:[status objectForKey:@"Percent"]];
+}
+
- (void) setUpdateDelegate:(id)delegate {
updatedelegate_ = delegate;
}
/* Section Controller {{{ */
@interface SectionController : FilteredPackageListController {
- NSString *section_;
+ _H<NSString> section_;
}
- (id) initWithDatabase:(Database *)database section:(NSString *)section;
@interface SearchController : FilteredPackageListController <
UISearchBarDelegate
> {
- UISearchBar *search_;
+ _H<UISearchBar> search_;
BOOL searchloaded_;
}
@implementation SearchController
- (void) dealloc {
- [search_ release];
+ [search_ setDelegate:nil];
[super dealloc];
}
- (id) initWithDatabase:(Database *)database {
if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil])) {
- search_ = [[UISearchBar alloc] init];
+ search_ = [[[UISearchBar alloc] init] autorelease];
+ [search_ setDelegate:self];
} return self;
}
textField = MSHookIvar<UITextField *>(search_, "_searchField");
[textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
- [search_ setDelegate:self];
[textField setEnablesReturnKeyAutomatically:NO];
[[self navigationItem] setTitleView:textField];
}
] autorelease];
[alert setContext:@"conffile"];
+ [alert setNumberOfRows:2];
[alert show];
}
else
ScreenScale_ = 1;
- NSMutableArray *parts([NSMutableArray arrayWithCapacity:2]);
- if (ScreenScale_ > 1)
- [parts addObject:@"@2x"];
- [parts addObject:(IsWildcat_ ? @"~ipad" : @"~iphone")];
- UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios%@", [parts componentsJoinedByString:@""]]);
+ UIDevice *device([UIDevice currentDevice]);
+ if (![device respondsToSelector:@selector(userInterfaceIdiom)])
+ Idiom_ = @"iphone";
+ else {
+ UIUserInterfaceIdiom idiom([device userInterfaceIdiom]);
+ if (idiom == UIUserInterfaceIdiomPhone)
+ Idiom_ = @"iphone";
+ else if (idiom == UIUserInterfaceIdiomPad)
+ Idiom_ = @"ipad";
+ else
+ NSLog(@"unknown UIUserInterfaceIdiom!");
+ }
+
+ UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios~%@", Idiom_]);
PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
else {
lang = [[Languages_ objectAtIndex:0] UTF8String];
setenv("LANG", lang, true);
+ std::setlocale(LC_ALL, lang);
}
- //std::setlocale(LC_ALL, lang);
NSLog(@"Setting Language: %s", lang);
/* }}} */
/* }}} */
App_ = [[NSBundle mainBundle] bundlePath];
- Home_ = NSHomeDirectory();
Advanced_ = YES;
setuid(0);
Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
#define MobileSubstrate_(name) \
- if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", F_OK) == 0) \
- dlopen("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", RTLD_LAZY | RTLD_GLOBAL);
+ if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", F_OK) == 0) { \
+ void *handle(dlopen("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", RTLD_LAZY | RTLD_GLOBAL)); \
+ if (handle == NULL) \
+ NSLog(@"%s", dlerror()); \
+ }
MobileSubstrate_(Activator)
MobileSubstrate_(libstatusbar)