]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
Improved handling of the refresh sequence.
[cydia.git] / MobileCydia.mm
index 60edfa0feb5b2207f3f6300c0be7821a8babf787..bc4d9461818fc03da407599f462b2072f93ee561 100644 (file)
@@ -380,12 +380,10 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive |
 #define ForSaurik (0 && !ForRelease)
 #define LogBrowser (0 && !ForRelease)
 #define TrackResize (0 && !ForRelease)
-#define ManualRefresh (0 && !ForRelease)
+#define ManualRefresh (1 && !ForRelease)
 #define ShowInternals (0 && !ForRelease)
 #define IgnoreInstall (0 && !ForRelease)
-#define RecycleWebViews 0
-#define RecyclePackageViews (0 && ForRelease)
-#define AlwaysReload (1 && !ForRelease)
+#define AlwaysReload (0 && !ForRelease)
 
 #if !TraceLogging
 #undef _trace
@@ -1074,10 +1072,6 @@ static bool Changed_;
 static NSDate *now_;
 
 static bool IsWildcat_;
-
-#if RecycleWebViews
-static NSMutableArray *Documents_;
-#endif
 /* }}} */
 
 /* Display Helpers {{{ */
@@ -3695,14 +3689,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         return @"getPackageById";
     else if (selector == @selector(installPackages:))
         return @"installPackages";
-    else if (selector == @selector(setAutoPopup:))
-        return @"setAutoPopup";
     else if (selector == @selector(setButtonImage:withStyle:toFunction:))
         return @"setButtonImage";
     else if (selector == @selector(setButtonTitle:withStyle:toFunction:))
         return @"setButtonTitle";
-    else if (selector == @selector(setFinishHook:))
-        return @"setFinishHook";
     else if (selector == @selector(setPopupHook:))
         return @"setPopupHook";
     else if (selector == @selector(setSpecial:))
@@ -3813,10 +3803,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO];
 }
 
-- (void) setAutoPopup:(BOOL)popup {
-    [indirect_ setAutoPopup:popup];
-}
-
 - (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
     [indirect_ setButtonImage:button withStyle:style toFunction:function];
 }
@@ -3838,10 +3824,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     Changed_ = true;
 }
 
-- (void) setFinishHook:(id)function {
-    [indirect_ setFinishHook:function];
-}
-
 - (void) setPopupHook:(id)function {
     [indirect_ setPopupHook:function];
 }
@@ -3887,8 +3869,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host {
 }
 
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
+- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:view didClearWindowObject:window forFrame:frame];
 
     WebDataSource *source([frame dataSource]);
     NSURLResponse *response([source response]);
@@ -3924,8 +3906,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
 }
 
-- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source {
-    NSMutableURLRequest *copy = [request mutableCopy];
+- (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source {
+    NSMutableURLRequest *copy([[super webView:view resource:resource willSendRequest:request redirectResponse:response fromDataSource:source] mutableCopy]);
     [self _setMoreHeaders:copy];
     return copy;
 }
@@ -3939,7 +3921,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if ((self = [super initWithWidth:0 ofClass:[CYBrowserController class]]) != nil) {
         cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_];
 
-        WebView *webview([document_ webView]);
+        WebView *webview([[webview_ _documentView] webView]);
 
         Package *package([[Database sharedInstance] packageWithName:@"cydia"]);
 
@@ -4015,15 +3997,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (id) invokeDefaultMethodWithArguments:(NSArray *)args {
+- (void) _doContinue {
     [self dismissModalViewControllerAnimated:YES];
     [delegate_ cancelAndClear:NO];
+}
 
+- (id) invokeDefaultMethodWithArguments:(NSArray *)args {
+    [self performSelectorOnMainThread:@selector(_doContinue) withObject:nil waitUntilDone:NO];
     return nil;
 }
 
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
+- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:view didClearWindowObject:window forFrame:frame];
     [window setValue:changes_ forKey:@"changes"];
     [window setValue:issues_ forKey:@"issues"];
     [window setValue:sizes_ forKey:@"sizes"];
@@ -4968,6 +4953,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 
     [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator];
+    [self setSelectionStyle:editing ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleBlue];
+
     [content_ setNeedsDisplay];
 }
 
@@ -5134,6 +5121,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     NSString *name_;
     bool commercial_;
     NSMutableArray *buttons_;
+    UIBarButtonItem *button_;
 }
 
 - (id) initWithDatabase:(Database *)database;
@@ -5148,7 +5136,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [package_ release];
     if (name_ != nil)
         [name_ release];
+
     [buttons_ release];
+
+    if (button_ != nil)
+        [button_ release];
+
     [super dealloc];
 }
 
@@ -5186,12 +5179,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
-- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
-    return [super webView:sender didFinishLoadForFrame:frame];
-}
-
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
+- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:view didClearWindowObject:window forFrame:frame];
     [window setValue:package_ forKey:@"package"];
 }
 
@@ -5248,13 +5237,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (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];
+    return button_;
 }
 #endif
 
@@ -5297,30 +5280,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [buttons_ addObject:UCLocalize("REINSTALL")];
         if (![package_ uninstalled])
             [buttons_ addObject:UCLocalize("REMOVE")];
+    }
 
-        if (special_ != NULL) {
-            CGRect frame([document_ frame]);
-            frame.size.height = 0;
-            [document_ setFrame:frame];
-
-            if ([scroller_ respondsToSelector:@selector(scrollPointVisibleAtTopLeft:)])
-                [scroller_ scrollPointVisibleAtTopLeft:CGPointZero];
-            else
-                [scroller_ scrollRectToVisible:CGRectZero animated:NO];
-
-            WebThreadLock();
-            [[[document_ webView] windowScriptObject] setValue:package_ forKey:@"package"];
-
-            [self setButtonTitle:nil withStyle:nil toFunction:nil];
-
-            [self setFinishHook:nil];
-            [self setPopupHook:nil];
-            WebThreadUnlock();
+    if (button_ != nil)
+        [button_ release];
 
-            //[self yieldToSelector:@selector(callFunction:) withObject:special_];
-            [super callFunction:special_];
-        }
+    NSString *title;
+    switch ([buttons_ count]) {
+        case 0: title = nil; break;
+        case 1: title = [buttons_ objectAtIndex:0]; break;
+        default: title = UCLocalize("MODIFY"); break;
     }
+
+    button_ = [[UIBarButtonItem alloc]
+        initWithTitle:title
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(customButtonClicked)
+    ];
 }
 
 - (bool) isLoading {
@@ -6787,6 +6764,9 @@ freeing the view controllers on tab change */
 }
 
 - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    if (editing_)
+        return;
+
     Section *section = [self sectionAtIndexPath:indexPath];
     NSString *name = [section name];
     NSString *title;
@@ -7044,7 +7024,7 @@ freeing the view controllers on tab change */
 
 - (void) refreshButtonClicked {
     [delegate_ beginUpdate];
-    [[self navigationItem] setLeftBarButtonItem:nil];
+    [[self navigationItem] setLeftBarButtonItem:nil animated:YES];
 }
 
 - (void) upgradeButtonClicked {
@@ -7419,9 +7399,9 @@ freeing the view controllers on tab change */
     [super dealloc];
 }
 
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
     // XXX: dude!
-    [super webView:sender didClearWindowObject:window forFrame:frame];
+    [super webView:view didClearWindowObject:window forFrame:frame];
 }
 
 - (id) initWithDatabase:(Database *)database package:(NSString *)package {
@@ -7697,6 +7677,7 @@ freeing the view controllers on tab change */
 }
 
 - (void) completeUpdate {
+    if (!updating_) return;
     updating_ = false;
 
     [self raiseBar:YES];
@@ -7705,8 +7686,10 @@ freeing the view controllers on tab change */
 }
 
 - (void) cancelUpdate {
-    [refreshbar_ cancel];
-    [self completeUpdate];
+    updating_ = false;
+    [self raiseBar:YES];
+    [refreshbar_ stop];
+    [updatedelegate_ performSelector:@selector(updateData) withObject:nil afterDelay:0];
 }
 
 - (void) cancelPressed {
@@ -7903,10 +7886,6 @@ typedef enum {
     InstalledController *installed_;
     id queueDelegate_;
 
-#if RecyclePackageViews
-    NSMutableArray *details_;
-#endif
-
     bool loaded_;
 }
 
@@ -8010,6 +7989,30 @@ static _finline void _setHomePage(Cydia *self) {
 - (void) _refreshIfPossible {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
+    bool recently = false;
+    NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
+    if (update != nil) {
+        NSTimeInterval interval([update timeIntervalSinceNow]);
+        if (interval <= 0 && interval > -(15*60))
+            recently = true;
+    }
+
+    // Don't automatic refresh if:
+    //  - We already refreshed recently.
+    //  - We already auto-refreshed this launch.
+    //  - Auto-refresh is disabled.
+    if (recently || loaded_ || ManualRefresh) {
+        [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO];
+
+        // If we are cancelling due to ManualRefresh or a recent refresh
+        // we need to make sure it knows it's already loaded.
+        loaded_ = true;
+        return;
+    } else {
+        // We are going to load, so remember that.
+        loaded_ = true;
+    }
+
     SCNetworkReachabilityFlags flags; {
         SCNetworkReachabilityRef reachability(SCNetworkReachabilityCreateWithName(NULL, "cydia.saurik.com"));
         SCNetworkReachabilityGetFlags(reachability, &flags);
@@ -8028,21 +8031,9 @@ static _finline void _setHomePage(Cydia *self) {
         )
     );
 
-    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;
-        }
-
+    // If we can reach the server, auto-refresh!
+    if (reachable)
         [container_ performSelectorOnMainThread:@selector(setUpdate:) withObject:update waitUntilDone:NO];
-    }
 
     [pool release];
 }
@@ -8076,18 +8067,19 @@ static _finline void _setHomePage(Cydia *self) {
         }
     }
 
+    UITabBarItem *changesItem = [[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem];
     if (changes != 0) {
         NSString *badge([[NSNumber numberWithInt:changes] stringValue]);
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:badge];
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:YES];
+        [changesItem setBadgeValue:badge];
+        [changesItem setAnimatedBadge:YES];
 
         if ([self respondsToSelector:@selector(setApplicationBadge:)])
             [self setApplicationBadge:badge];
         else
             [self setApplicationBadgeString:badge];
     } else {
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:nil];
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:NO];
+        [changesItem setBadgeValue:nil];
+        [changesItem setAnimatedBadge:NO];
 
         if ([self respondsToSelector:@selector(removeApplicationBadge)])
             [self removeApplicationBadge];
@@ -8343,10 +8335,6 @@ static _finline void _setHomePage(Cydia *self) {
 - (void) setPackageController:(PackageController *)view {
     WebThreadLock();
     [view setPackage:nil];
-#if RecyclePackageViews
-    if ([details_ count] < 3)
-        [details_ addObject:view];
-#endif
     WebThreadUnlock();
 }
 
@@ -8355,25 +8343,7 @@ static _finline void _setHomePage(Cydia *self) {
 }
 
 - (PackageController *) packageController {
-#if RecyclePackageViews
-    PackageController *view;
-    size_t count([details_ count]);
-
-    if (count == 0) {
-        view = [self _packageController];
-      renew:
-        [details_ addObject:[self _packageController]];
-    } else {
-        view = [[[details_ lastObject] retain] autorelease];
-        [details_ removeLastObject];
-        if (count == 1)
-            goto renew;
-    }
-
-    return view;
-#else
     return [self _packageController];
-#endif
 }
 
 // Returns the navigation controller for the queuing badge.
@@ -8603,40 +8573,6 @@ static _finline void _setHomePage(Cydia *self) {
 
     database_ = [Database sharedInstance];
 
-    if (
-        readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
-        //readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL ||
-        //readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL ||
-        false
-    ) {
-        [self setIdleTimerDisabled:YES];
-
-        hud_ = [self addProgressHUD];
-        [hud_ setText:@"Reorganizing:\n\nWill Automatically\nClose When Done"];
-        [self setStatusBarShowsProgress:YES];
-
-        [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
-
-        [self setStatusBarShowsProgress:NO];
-        [self removeProgressHUD:hud_];
-        hud_ = nil;
-
-        if (ExecFork() == 0) {
-            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
-            perror("launchctl stop");
-        }
-
-        return;
-    }
-
-    _trace();
-
     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],
@@ -8669,6 +8605,38 @@ static _finline void _setHomePage(Cydia *self) {
     [container_ setTabBarController:tabbar_];
     [window_ addSubview:[container_ view]];
 
+    if (
+        readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
+        //readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL ||
+        //readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL ||
+        false
+    ) {
+        [self setIdleTimerDisabled:YES];
+
+        hud_ = [self addProgressHUD];
+        [hud_ setText:@"Reorganizing:\n\nWill Automatically\nClose When Done"];
+        [self setStatusBarShowsProgress:YES];
+
+        [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
+
+        [self setStatusBarShowsProgress:NO];
+        [self removeProgressHUD:hud_];
+        hud_ = nil;
+
+        if (ExecFork() == 0) {
+            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
+            perror("launchctl stop");
+        }
+
+        return;
+    }
+
     [self performSelector:@selector(loadData) withObject:nil afterDelay:0];
 }
 
@@ -8682,12 +8650,6 @@ static _finline void _setHomePage(Cydia *self) {
 
     [self reloadData];
 
-#if RecyclePackageViews
-    details_ = [[NSMutableArray alloc] initWithCapacity:4];
-    [details_ addObject:[self _packageController]];
-    [details_ addObject:[self _packageController]];
-#endif
-
     PrintTimes();
 
     _setHomePage(self);
@@ -8931,10 +8893,6 @@ int main(int argc, char *argv[]) { _pooled
     }
     /* }}} */
 
-#if RecycleWebViews
-    Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease];
-#endif
-
     Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
 
     if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", F_OK) == 0)