]> git.saurik.com Git - cydia.git/blobdiff - Cydia.mm
Merge branch 'master' of saurik.com:cydia
[cydia.git] / Cydia.mm
index 3dfb950568fda4026a97b01ac563132f30890255..936856dbaf73b03ff0404e25f9f57d07f4bbb24a 100644 (file)
--- a/Cydia.mm
+++ b/Cydia.mm
@@ -59,6 +59,8 @@
 #include <CoreFoundation/CFPriv.h>
 #include <CoreFoundation/CFUniChar.h>
 
+#include <SystemConfiguration/SystemConfiguration.h>
+
 #include <UIKit/UIKit.h>
 #include "iPhonePrivate.h"
 
@@ -119,12 +121,8 @@ extern "C" {
 #include <ext/hash_map>
 
 #include "UICaboodle/BrowserView.h"
-#include "UICaboodle/ResetView.h"
 
 #include "substrate.h"
-
-// Apple's sample Reachability code, ASPL licensed.
-#include "Reachability.h"
 /* }}} */
 
 /* Profiler {{{ */
@@ -313,7 +311,7 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) {
     } return self;
 }
 
-- (void)_updateFrameForDisplay {
+- (void) _updateFrameForDisplay {
     [super _updateFrameForDisplay];
     if ([self cancelButtonIndex] == -1) {
         NSArray *buttons = [self buttons];
@@ -375,7 +373,7 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive |
 
 #define lprintf(args...) fprintf(stderr, args)
 
-#define ForRelease 0
+#define ForRelease 1
 #define TraceLogging (1 && !ForRelease)
 #define HistogramInsertionSort (0 && !ForRelease)
 #define ProfileTimes (0 && !ForRelease)
@@ -386,7 +384,7 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive |
 #define ShowInternals (0 && !ForRelease)
 #define IgnoreInstall (0 && !ForRelease)
 #define RecycleWebViews 0
-#define RecyclePackageViews (1 && ForRelease)
+#define RecyclePackageViews (0 && ForRelease)
 #define AlwaysReload (1 && !ForRelease)
 
 #if !TraceLogging
@@ -620,7 +618,9 @@ void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFCompar
 @end
 /* }}} */
 
-NSUInteger WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptObject *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
+@implementation WebScriptObject (NSFastEnumeration)
+
+- (NSUInteger) countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count {
     size_t length([self count] - state->state);
     if (length <= 0)
         return 0;
@@ -633,6 +633,8 @@ NSUInteger WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptO
     return length;
 }
 
+@end
+
 NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
     size_t length([self length] - state->state);
     if (length <= 0)
@@ -971,17 +973,17 @@ class Pcre {
 @end
 /* }}} */
 /* CoreGraphics Primitives {{{ */
-class CGColor {
+class CYColor {
   private:
     CGColorRef color_;
 
   public:
-    CGColor() :
+    CYColor() :
         color_(NULL)
     {
     }
 
-    CGColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) :
+    CYColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) :
         color_(NULL)
     {
         Set(space, red, green, blue, alpha);
@@ -992,14 +994,14 @@ class CGColor {
             CGColorRelease(color_);
     }
 
-    ~CGColor() {
+    ~CYColor() {
         Clear();
     }
 
     void Set(CGColorSpaceRef space, float red, float green, float blue, float alpha) {
         Clear();
         float color[] = {red, green, blue, alpha};
-        color_ = CGColorCreate(space, color);
+        color_ = CGColorCreate(space, (CGFloat *) color);
     }
 
     operator CGColorRef() {
@@ -1022,15 +1024,15 @@ static NSArray *Finishes_;
 
 static bool Queuing_;
 
-static CGColor Blue_;
-static CGColor Blueish_;
-static CGColor Black_;
-static CGColor Off_;
-static CGColor White_;
-static CGColor Gray_;
-static CGColor Green_;
-static CGColor Purple_;
-static CGColor Purplish_;
+static CYColor Blue_;
+static CYColor Blueish_;
+static CYColor Black_;
+static CYColor Off_;
+static CYColor White_;
+static CYColor Gray_;
+static CYColor Green_;
+static CYColor Purple_;
+static CYColor Purplish_;
 
 static UIColor *InstallingColor_;
 static UIColor *RemovingColor_;
@@ -1048,14 +1050,14 @@ static UIFont *Font18Bold_;
 static UIFont *Font22Bold_;
 
 static const char *Machine_ = NULL;
-static const NSString *System_ = NULL;
-static const NSString *SerialNumber_ = nil;
-static const NSString *ChipID_ = nil;
-static const NSString *Token_ = nil;
-static const NSString *UniqueID_ = nil;
-static const NSString *Build_ = nil;
-static const NSString *Product_ = nil;
-static const NSString *Safari_ = nil;
+static NSString *System_ = nil;
+static NSString *SerialNumber_ = nil;
+static NSString *ChipID_ = nil;
+static NSString *Token_ = nil;
+static NSString *UniqueID_ = nil;
+static NSString *Build_ = nil;
+static NSString *Product_ = nil;
+static NSString *Safari_ = nil;
 
 static CFLocaleRef Locale_;
 static NSArray *Languages_;
@@ -1215,7 +1217,7 @@ bool isSectionVisible(NSString *section) {
 - (void) showSettings;
 - (UIProgressHUD *) addProgressHUD;
 - (void) removeProgressHUD:(UIProgressHUD *)hud;
-- (UCViewController *) pageForPackage:(NSString *)name;
+- (CYViewController *) pageForPackage:(NSString *)name;
 - (PackageController *) packageController;
 - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
 @end
@@ -1433,8 +1435,11 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
 - (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
@@ -1629,11 +1634,11 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 }
 
 - (NSString *) depictionForPackage:(NSString *)package {
-    return depiction_.empty() ? nil : [depiction_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+    return depiction_.empty() ? nil : [static_cast<id>(depiction_) stringByReplacingOccurrencesOfString:@"*" withString:package];
 }
 
 - (NSString *) supportForPackage:(NSString *)package {
-    return support_.empty() ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+    return support_.empty() ? nil : [static_cast<id>(support_) stringByReplacingOccurrencesOfString:@"*" withString:package];
 }
 
 - (NSDictionary *) record {
@@ -2175,7 +2180,7 @@ struct PackageNameOrdering :
         _end
 
         bool changed(false);
-        NSString *key([id_ lowercaseString]);
+        NSString *key([static_cast<id>(id_) lowercaseString]);
 
         _profile(Package$initWithVersion$Metadata)
             metadata_ = [Packages_ objectForKey:key];
@@ -2481,9 +2486,9 @@ struct PackageNameOrdering :
 
     UIImage *icon(nil);
     if (!icon_.empty())
-        if ([icon_ hasPrefix:@"file:///"])
+        if ([static_cast<id>(icon_) hasPrefix:@"file:///"])
             // XXX: correct escaping
-            icon = [UIImage imageAtPath:[icon_ substringFromIndex:7]];
+            icon = [UIImage imageAtPath:[static_cast<id>(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])
@@ -3071,7 +3076,7 @@ static NSString *Warning_;
     return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:pool_ database:self];
 } }
 
-- (Database *) init {
+- (id) init {
     if ((self = [super init]) != nil) {
         policy_ = NULL;
         records_ = NULL;
@@ -3579,7 +3584,8 @@ static NSString *Warning_;
         return;
 
     if ([self popErrorWithTitle:title forOperation:ListUpdate(status, list, PulseInterval_)])
-        /* XXX: ignore this because users suck and don't understand why refreshing is important: return */;
+        /* XXX: ignore this because users suck and don't understand why refreshing is important: return */
+        /* XXX: why the hell is an empty if statement a clang error? */ (void) 0;
 
     [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
     Changed_ = true;
@@ -3850,7 +3856,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     id values[count];
     for (unsigned i(0); i != count; ++i)
         values[i] = [arguments objectAtIndex:i];
-    return [[[NSString alloc] initWithFormat:format arguments:reinterpret_cast<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 {
@@ -3864,14 +3870,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @end
 /* }}} */
 
-/* Cydia View Controller {{{ */
-@interface CYViewController : UCViewController { }
-@end
-
-@implementation CYViewController
-@end
-/* }}} */
-
+/* Cydia Browser Controller {{{ */
 @interface CYBrowserController : BrowserController {
     CydiaObject *cydia_;
 }
@@ -3961,7 +3960,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 @end
+/* }}} */
 
+/* Confirmation {{{ */
 @protocol ConfirmationControllerDelegate
 - (void) cancelAndClear:(bool)clear;
 - (void) confirmWithNavigationController:(UINavigationController *)navigation;
@@ -5033,7 +5034,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
-- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section {
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return files_ == nil ? 0 : [files_ count];
 }
 
@@ -5229,9 +5230,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
+// 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 {
-    // Wait until it's done loading.
-    if (![self isLoading])
+    if (commercial_)
+        [super customButtonClicked];
+    else
         [self _customButtonClicked];
 }
 
@@ -5242,6 +5246,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) applyLoadingTitle {
     // Don't show "Loading" as the title. Ever.
 }
+
+- (UIBarButtonItem *) rightButton {
+    int count = [buttons_ count];
+    return [[[UIBarButtonItem alloc]
+        initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0]
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(customButtonClicked)
+    ] autorelease];
+}
 #endif
 
 - (id) initWithDatabase:(Database *)database {
@@ -5309,19 +5323,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (void) applyRightButton {
-    int count = [buttons_ count];
-    UIBarButtonItem *actionItem = [[UIBarButtonItem alloc]
-        initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0]
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(customButtonClicked)
-    ];
-    if (![self isLoading]) [[self navigationItem] setRightBarButtonItem:actionItem];
-    else [super applyRightButton];
-    [actionItem release];
-}
-
 - (bool) isLoading {
     return commercial_ ? [super isLoading] : false;
 }
@@ -5619,7 +5620,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [[self navigationController] pushViewController:view animated:YES];
 }
 
-- (id) title { return title_; }
+- (NSString *) title { return title_; }
 
 - (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
     if ((self = [super init]) != nil) {
@@ -5832,11 +5833,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
 }
 
-- (int) numberOfSectionsInTableView:(UITableView *)tableView {
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
     return offset_ == 0 ? 1 : 2;
 }
 
-- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(int)section {
+- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
     switch (section + (offset_ == 0 ? 1 : 0)) {
         case 0: return UCLocalize("ENTERED_BY_USER");
         case 1: return UCLocalize("INSTALLED_BY_PACKAGE");
@@ -5845,7 +5846,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section {
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     int count = [sources_ count];
     switch (section) {
         case 0: return (offset_ == 0 ? count : offset_);
@@ -6036,7 +6037,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [self _endConnection:connection];
 }
 
-- (id)title { return UCLocalize("SOURCES"); }
+- (NSString *) title { return UCLocalize("SOURCES"); }
 
 - (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method {
     NSMutableURLRequest *request = [NSMutableURLRequest
@@ -6248,7 +6249,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
-- (id) title { return UCLocalize("INSTALLED"); }
+- (NSString *) title { return UCLocalize("INSTALLED"); }
 
 - (id) initWithDatabase:(Database *)database {
     if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndVisible:) with:[NSNumber numberWithBool:YES]]) != nil) {
@@ -6566,7 +6567,7 @@ freeing the view controllers on tab change */
     }
 }
 
-- (id) initWithDatabase: (Database *)database {
+- (id) initWithDatabase:(Database *)database {
     if ((self = [super init]) != nil) {
         database_ = database;
     } return self;
@@ -6578,7 +6579,7 @@ freeing the view controllers on tab change */
 /* Cydia Navigation Controller {{{ */
 @interface CYNavigationController : UINavigationController {
     _transient Database *database_;
-    id delegate_;
+    id<UINavigationControllerDelegate> delegate_;
 }
 
 - (id) initWithDatabase:(Database *)database;
@@ -6610,7 +6611,7 @@ freeing the view controllers on tab change */
     }
 }
 
-- (void) setDelegate:(id)delegate {
+- (void) setDelegate:(id<UINavigationControllerDelegate>)delegate {
     delegate_ = delegate;
 }
 
@@ -6767,7 +6768,7 @@ freeing the view controllers on tab change */
     return section;
 }
 
-- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section {
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return editing_ ? [sections_ count] : [filtered_ count] + 1;
 }
 
@@ -6816,7 +6817,7 @@ freeing the view controllers on tab change */
     [[self navigationController] pushViewController:table animated:YES];
 }
 
-- (id) title { return UCLocalize("SECTIONS"); }
+- (NSString *) title { return UCLocalize("SECTIONS"); }
 
 - (id) initWithDatabase:(Database *)database {
     if ((self = [super init]) != nil) {
@@ -7050,7 +7051,7 @@ freeing the view controllers on tab change */
     [delegate_ distUpgrade];
 }
 
-- (id) title { return UCLocalize("CHANGES"); }
+- (NSString *) title { return UCLocalize("CHANGES"); }
 
 - (id) initWithDatabase:(Database *)database delegate:(id)delegate {
     if ((self = [super init]) != nil) {
@@ -7206,18 +7207,18 @@ freeing the view controllers on tab change */
     [super dealloc];
 }
 
-- (void) searchBarSearchButtonClicked:(id)searchBar {
+- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
     [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
     [search_ resignFirstResponder];
     [self reloadData];
 }
 
-- (void) searchBar:(id)searchBar textDidChange:(NSString *)text {
+- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text {
     [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
     [self reloadData];
 }
 
-- (id) title { return nil; }
+- (NSString *) title { return nil; }
 
 - (id) initWithDatabase:(Database *)database {
     return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil];
@@ -7348,7 +7349,7 @@ freeing the view controllers on tab change */
     return nil;
 }
 
-- (id) title { return UCLocalize("SETTINGS"); }
+- (NSString *) title { return UCLocalize("SETTINGS"); }
 
 - (id) initWithDatabase:(Database *)database package:(NSString *)package {
     if ((self = [super init])) {
@@ -7623,11 +7624,16 @@ freeing the view controllers on tab change */
 - (void) dropBar:(BOOL)animated;
 - (void) beginUpdate;
 - (void) raiseBar:(BOOL)animated;
+- (BOOL) updating;
 
 @end
 
 @implementation CYContainer
 
+- (BOOL) _reallyWantsFullScreenLayout {
+    return YES;
+}
+
 // NOTE: UIWindow only sends the top controller these messages,
 //       So we have to forward them on.
 
@@ -7652,7 +7658,7 @@ freeing the view controllers on tab change */
 }
 
 - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
-    return YES; /* XXX: return YES; */
+    return IsWildcat_;
 }
 
 - (void) setTabBarController:(UITabBarController *)controller {
@@ -7760,17 +7766,30 @@ freeing the view controllers on tab change */
     updatedelegate_ = delegate;
 }
 
+- (CGFloat) statusBarHeight {
+    if (UIInterfaceOrientationIsPortrait([self interfaceOrientation])) {
+        return [[UIApplication sharedApplication] statusBarFrame].size.height;
+    } else {
+        return [[UIApplication sharedApplication] statusBarFrame].size.width;
+    }
+}
+
 - (void) dropBar:(BOOL)animated {
     if (dropped_) return;
     dropped_ = true;
 
     [[self view] addSubview:refreshbar_];
 
+    CGFloat sboffset = [self statusBarHeight];
+
+    CGRect barframe = [refreshbar_ frame];   
+    barframe.origin.y = sboffset;
+    [refreshbar_ setFrame:barframe];
+
     if (animated) [UIView beginAnimations:nil context:NULL];
-    CGRect barframe = [refreshbar_ frame];
     CGRect viewframe = [[root_ view] frame];
-    viewframe.origin.y += barframe.size.height + 20.0f;
-    viewframe.size.height -= barframe.size.height + 20.0f;
+    viewframe.origin.y += barframe.size.height + sboffset;
+    viewframe.size.height -= barframe.size.height + sboffset;
     [[root_ view] setFrame:viewframe];
     if (animated) [UIView commitAnimations];
 
@@ -7788,11 +7807,13 @@ freeing the view controllers on tab change */
 
     [refreshbar_ removeFromSuperview];
 
+    CGFloat sboffset = [self statusBarHeight]; 
+
     if (animated) [UIView beginAnimations:nil context:NULL];
     CGRect barframe = [refreshbar_ frame];
     CGRect viewframe = [[root_ view] frame];
-    viewframe.origin.y -= barframe.size.height + 20.0f;
-    viewframe.size.height += barframe.size.height + 20.0f;
+    viewframe.origin.y -= barframe.size.height + sboffset;
+    viewframe.size.height += barframe.size.height + sboffset;
     [[root_ view] setFrame:viewframe];
     if (animated) [UIView commitAnimations];
 
@@ -7815,16 +7836,25 @@ freeing the view controllers on tab change */
     [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
 }
 
+- (void) statusBarFrameChanged:(NSNotification *)notification {
+    if (dropped_) {
+        [self raiseBar:NO];
+        [self dropBar:NO];
+    }
+}
+
 - (void) dealloc {
     [refreshbar_ release];
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
     [super dealloc];
 }
 
-- (id) initWithDatabase: (Database *)database {
+- (id) initWithDatabase:(Database *)database {
     if ((self = [super init]) != nil) {
         database_ = database;
 
         [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
 
         refreshbar_ = [[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self];
     } return self;
@@ -7846,7 +7876,8 @@ typedef enum {
 @interface Cydia : UIApplication <
     ConfirmationControllerDelegate,
     ProgressControllerDelegate,
-    CydiaDelegate
+    CydiaDelegate,
+    UINavigationControllerDelegate
 > {
     UIWindow *window_;
     CYContainer *container_;
@@ -7878,8 +7909,8 @@ typedef enum {
     bool loaded_;
 }
 
-- (UCViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class;
-- (void) setPage:(UCViewController *)page;
+- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class;
+- (void) setPage:(CYViewController *)page;
 - (void) loadData;
 
 @end
@@ -7978,10 +8009,25 @@ static _finline void _setHomePage(Cydia *self) {
 - (void) _refreshIfPossible {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-    Reachability* reachability = [Reachability reachabilityWithHostName:@"cydia.saurik.com"];
-    NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
+    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 || remoteHostStatus == NotReachable) loaded:
+    if (loaded_ || ManualRefresh || !reachable) loaded:
         [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO];
     else {
         loaded_ = true;
@@ -8081,7 +8127,7 @@ static _finline void _setHomePage(Cydia *self) {
     [self _saveConfig];
 
     ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
-    UINavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
+    CYNavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
     if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
     [container_ presentModalViewController:navigation animated:YES];
 
@@ -8117,7 +8163,7 @@ static _finline void _setHomePage(Cydia *self) {
 
     ConfirmationController *page([[[ConfirmationController alloc] initWithDatabase:database_] autorelease]);
     [page setDelegate:self];
-    id confirm_ = [[CYNavigationController alloc] initWithRootViewController:page];
+    CYNavigationController *confirm_ = [[CYNavigationController alloc] initWithRootViewController:page];
     [confirm_ setDelegate:self];
 
     if (IsWildcat_) [confirm_ setModalPresentationStyle:UIModalPresentationFormSheet];
@@ -8202,17 +8248,17 @@ static _finline void _setHomePage(Cydia *self) {
     [self complete];
 }
 
-- (void) setPage:(UCViewController *)page {
+- (void) setPage:(CYViewController *)page {
     [page setDelegate:self];
 
     CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController];
-    [navController setViewControllers:[NSArray arrayWithObject:page] animated:NO];
+    [navController setViewControllers:[NSArray arrayWithObject:page]];
     for (CYNavigationController *page in [tabbar_ viewControllers]) {
         if (page != navController) [page setViewControllers:nil];
     }
 }
 
-- (UCViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class {
+- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class {
     CYBrowserController *browser = [[[_class alloc] init] autorelease];
     [browser loadURL:url];
     return browser;
@@ -8329,29 +8375,40 @@ static _finline void _setHomePage(Cydia *self) {
 #endif
 }
 
+// Returns the navigation controller for the queuing badge.
+- (id) queueBadgeController {
+    int index = [self indexOfTabWithTag:kManageTag];
+    if (index == -1) index = [self indexOfTabWithTag:kInstalledTag];
+    
+    return [[tabbar_ viewControllers] objectAtIndex:index];
+}
+
 - (void) cancelAndClear:(bool)clear {
     @synchronized (self) {
         if (clear) {
-            /* XXX: clear marks instead of reloading data */
-            /*pkgCacheFile &cache([database_ cache]);
+            // Clear all marks.
+            pkgCacheFile &cache([database_ cache]);
             for (pkgCache::PkgIterator iterator = cache->PkgBegin(); !iterator.end(); ++iterator) {
-                if (!cache[iterator].Keep()) cache->MarkKeep(iterator, false, false);
+                // Unmark method taken from Synaptic Package Manager.
+                               // Thanks for being sane, unlike Aptitude.
+                               if (!cache[iterator].Keep()) {
+                                       cache->MarkKeep(iterator, false);
+                                       cache->SetReInstall(iterator, false);
+                               }
             }
 
-            [self updateData];
-
+                       // Stop queuing.
             Queuing_ = false;
-            [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:nil];
-            [queueDelegate_ queueStatusDidChange];*/
-            [self reloadData];
+            [[[self queueBadgeController] tabBarItem] setBadgeValue:nil];
         } else {
+                       // Start queuing.
             Queuing_ = true;
-
-            [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kManageTag] != -1 ? [self indexOfTabWithTag:kManageTag] : [self indexOfTabWithTag:kInstalledTag]] tabBarItem] setBadgeValue:UCLocalize("Q_D")];
-            [(CYNavigationController *)[tabbar_ selectedViewController] reloadData];
-
-            [queueDelegate_ queueStatusDidChange];
-        }
+            [[[self queueBadgeController] tabBarItem] setBadgeValue:UCLocalize("Q_D")];
+               }
+        
+               // Show the changes in the current view.
+        [(CYNavigationController *) [tabbar_ selectedViewController] reloadData];
+        [queueDelegate_ queueStatusDidChange];
     }
 }
 
@@ -8441,7 +8498,7 @@ static _finline void _setHomePage(Cydia *self) {
     [window_ setUserInteractionEnabled:YES];
 }
 
-- (UCViewController *) pageForPackage:(NSString *)name {
+- (CYViewController *) pageForPackage:(NSString *)name {
     if (Package *package = [database_ packageWithName:name]) {
         PackageController *view([self packageController]);
         [view setPackage:package];
@@ -8453,7 +8510,7 @@ static _finline void _setHomePage(Cydia *self) {
     }
 }
 
-- (UCViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
+- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
     if (tag != NULL)
         *tag = -1;
 
@@ -8505,7 +8562,7 @@ static _finline void _setHomePage(Cydia *self) {
 - (void) applicationOpenURL:(NSURL *)url {
     [super applicationOpenURL:url];
     int tag;
-    if (UCViewController *page = [self pageForURL:url hasTag:&tag]) {
+    if (CYViewController *page = [self pageForURL:url hasTag:&tag]) {
         [self setPage:page];
         tag_ = tag;
         [tabbar_ setSelectedViewController:(tag_ == -1 ? nil : [[tabbar_ viewControllers] objectAtIndex:tag_])];
@@ -8700,7 +8757,6 @@ int main(int argc, char *argv[]) { _pooled
     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");