]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
Add -[Package relations].
[cydia.git] / MobileCydia.mm
index b53372b7430852e23bd52c3c313d267f211c7d7f..0a47412b9735783d59f20dfb80ed655083f8d636 100644 (file)
@@ -307,12 +307,13 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) {
 }
 
 - (int) yieldToPopupAlertAnimated:(BOOL)animated;
+
 @end
 
 @implementation CYAlertView
 
 - (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index {
-    if ((self = [super init])) {
+    if ((self = [super init]) != nil) {
         [self setTitle:title];
         [self setDelegate:self];
         for (NSString *button in buttons) [self addButtonWithTitle:button];
@@ -871,6 +872,7 @@ class Pcre {
 
 + (Address *) addressWithString:(NSString *)string;
 - (Address *) initWithString:(NSString *)string;
+
 @end
 
 @implementation Address
@@ -904,7 +906,10 @@ class Pcre {
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"address", @"name", nil];
+    return [NSArray arrayWithObjects:
+        @"address",
+        @"name",
+    nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -1329,6 +1334,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 - (pkgSourceList &) list;
 - (NSArray *) packages;
 - (NSArray *) sources;
+- (Source *) sourceWithKey:(NSString *)key;
 - (void) reloadData;
 
 - (void) configure;
@@ -1574,7 +1580,19 @@ static void PackageImport(const void *key, const void *value, void *context) {
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"description", @"distribution", @"host", @"key", @"label", @"name", @"origin", @"trusted", @"type", @"uri", @"version", nil];
+    return [NSArray arrayWithObjects:
+        @"description",
+        @"distribution",
+        @"host",
+        @"key",
+        @"label",
+        @"name",
+        @"origin",
+        @"trusted",
+        @"type",
+        @"uri",
+        @"version",
+    nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -1739,37 +1757,117 @@ static void PackageImport(const void *key, const void *value, void *context) {
 
 @end
 /* }}} */
-/* Relationship Class {{{ */
-@interface Relationship : NSObject {
-    NSString *type_;
-    NSString *id_;
+/* CydiaOperation Class {{{ */
+@interface CydiaOperation : NSObject {
+    NSString *operator_;
+    NSString *value_;
 }
 
-- (NSString *) type;
-- (NSString *) id;
-- (NSString *) name;
+- (NSString *) operator;
+- (NSString *) value;
 
 @end
 
-@implementation Relationship
+@implementation CydiaOperation
 
 - (void) dealloc {
-    [type_ release];
-    [id_ release];
+    [operator_ release];
+    [value_ release];
     [super dealloc];
 }
 
-- (NSString *) type {
-    return type_;
+- (id) initWithOperator:(const char *)_operator value:(const char *)value {
+    if ((self = [super init]) != nil) {
+        operator_ = [[NSString alloc] initWithUTF8String:_operator];
+        value_ = [[NSString alloc] initWithUTF8String:value];
+    } return self;
 }
 
-- (NSString *) id {
-    return id_;
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:
+        @"operator",
+        @"value",
+    nil];
 }
 
-- (NSString *) name {
-    _assert(false);
-    return nil;
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (NSString *) operator {
+    return operator_;
+}
+
+- (NSString *) value {
+    return value_;
+}
+
+@end
+/* }}} */
+/* CydiaRelation Class {{{ */
+@interface CydiaRelation : NSObject {
+    NSString *relationship_;
+    NSString *package_;
+    CydiaOperation *version_;
+}
+
+- (NSString *) relationship;
+- (NSString *) package;
+- (CydiaOperation *) version;
+
+@end
+
+@implementation CydiaRelation
+
+- (void) dealloc {
+    [relationship_ release];
+    [package_ release];
+    [version_ release];
+    [super dealloc];
+}
+
+- (id) initWithIterator:(pkgCache::DepIterator &)dep {
+    if ((self = [super init]) != nil) {
+        relationship_ = [[NSString alloc] initWithUTF8String:dep.DepType()];
+        package_ = [[NSString alloc] initWithUTF8String:dep.TargetPkg().Name()];
+
+        if (const char *version = dep.TargetVer())
+            version_ = [[CydiaOperation alloc] initWithOperator:dep.CompType() value:version];
+        else
+            version_ = [[NSNull null] retain];
+    } return self;
+}
+
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:
+        @"package",
+        @"relationship",
+        @"version",
+    nil];
+}
+
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (NSString *) relationship {
+    return relationship_;
+}
+
+- (NSString *) package {
+    return package_;
+}
+
+- (CydiaOperation *) version {
+    return version_;
 }
 
 @end
@@ -2049,8 +2147,15 @@ struct PackageNameOrdering :
 }
 
 + (NSString *) webScriptNameForSelector:(SEL)selector {
-    if (selector == @selector(hasTag:))
+    if (false);
+    else if (selector == @selector(clear))
+        return @"clear";
+    else if (selector == @selector(hasTag:))
         return @"hasTag";
+    else if (selector == @selector(install))
+        return @"install";
+    else if (selector == @selector(remove))
+        return @"remove";
     else
         return nil;
 }
@@ -2060,7 +2165,33 @@ struct PackageNameOrdering :
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"longDescription", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"warnings", nil];
+    return [NSArray arrayWithObjects:
+        @"applications",
+        @"author",
+        @"depiction",
+        @"essential",
+        @"homepage",
+        @"icon",
+        @"id",
+        @"installed",
+        @"latest",
+        @"longDescription",
+        @"longSection",
+        @"maintainer",
+        @"mode",
+        @"name",
+        @"purposes",
+        @"relations",
+        @"section",
+        @"shortDescription",
+        @"shortSection",
+        @"simpleSection",
+        @"size",
+        @"source",
+        @"sponsor",
+        @"support",
+        @"warnings",
+    nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -2071,6 +2202,31 @@ struct PackageNameOrdering :
     return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
 }
 
+- (NSArray *) relations {
+@synchronized (database_) {
+    NSMutableArray *relations([NSMutableArray arrayWithCapacity:16]);
+
+    for (pkgCache::DepIterator dep(version_.DependsList()); !dep.end(); ++dep) {
+        pkgCache::DepIterator start;
+        pkgCache::DepIterator end;
+        dep.GlobOr(start, end); // ++dep
+
+        NSMutableArray *ors([NSMutableArray arrayWithCapacity:2]);
+        [relations addObject:ors];
+
+        _forever {
+            [ors addObject:[[[CydiaRelation alloc] initWithIterator:start] autorelease]];
+
+            // yes, seriously. (wtf?)
+            if (start == end)
+                break;
+            ++start;
+        }
+    }
+
+    return relations;
+} }
+
 - (void) parse {
     if (parsed_ != NULL)
         return;
@@ -3004,7 +3160,7 @@ static NSString *Warning_;
     // XXX: actually implement this thing
     _assert(false);
     if (deadSources_)
-           CFRelease(deadSources_);
+        CFRelease(deadSources_);
     [self releasePackages];
     apr_pool_destroy(pool_);
     NSRecycleZone(zone_);
@@ -3201,6 +3357,13 @@ static NSString *Warning_;
     return sources;
 }
 
+- (Source *) sourceWithKey:(NSString *)key {
+    for (Source *source in [self sources]) {
+        if ([[source key] isEqualToString:key])
+            return source;
+    } return nil;
+}
+
 - (bool) popErrorWithTitle:(NSString *)title {
     bool fatal(false);
     std::string message;
@@ -3634,6 +3797,7 @@ static NSString *Warning_;
 }
 
 - (id) initWithDelegate:(IndirectDelegate *)indirect;
+
 @end
 
 @implementation CydiaObject
@@ -3654,7 +3818,13 @@ static NSString *Warning_;
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"device", @"firewire", @"imei", @"mac", @"serial", nil];
+    return [NSArray arrayWithObjects:
+        @"device",
+        @"firewire",
+        @"imei",
+        @"mac",
+        @"serial",
+    nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -3692,14 +3862,21 @@ static NSString *Warning_;
 #endif
 
 + (NSString *) webScriptNameForSelector:(SEL)selector {
-    if (selector == @selector(close))
+    if (false);
+    else if (selector == @selector(close))
         return @"close";
+    else if (selector == @selector(du:))
+        return @"du";
+    else if (selector == @selector(stringWithFormat:arguments:))
+        return @"format";
     else if (selector == @selector(getInstalledPackages))
         return @"getInstalledPackages";
     else if (selector == @selector(getPackageById:))
         return @"getPackageById";
     else if (selector == @selector(installPackages:))
         return @"installPackages";
+    else if (selector == @selector(localizedStringForKey:value:table:))
+        return @"localize";
     else if (selector == @selector(setButtonImage:withStyle:toFunction:))
         return @"setButtonImage";
     else if (selector == @selector(setButtonTitle:withStyle:toFunction:))
@@ -3712,16 +3889,10 @@ static NSString *Warning_;
         return @"setToken";
     else if (selector == @selector(setViewportWidth:))
         return @"setViewportWidth";
-    else if (selector == @selector(supports:))
-        return @"supports";
-    else if (selector == @selector(stringWithFormat:arguments:))
-        return @"format";
-    else if (selector == @selector(localizedStringForKey:value:table:))
-        return @"localize";
-    else if (selector == @selector(du:))
-        return @"du";
     else if (selector == @selector(statfs:))
         return @"statfs";
+    else if (selector == @selector(supports:))
+        return @"supports";
     else
         return nil;
 }
@@ -3877,8 +4048,8 @@ static NSString *Warning_;
 
 @implementation CYLoadingIndicator
 
-- (id)initWithFrame:(CGRect)frame {
-    if ((self = [super initWithFrame:frame])) {
+- (id) initWithFrame:(CGRect)frame {
+    if ((self = [super initWithFrame:frame]) != nil) {
         container_ = [[[UIView alloc] init] autorelease];
         [container_ setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin];
 
@@ -3917,13 +4088,16 @@ static NSString *Warning_;
         [spinner_ setFrame:spinrect];
         [label_ setFrame:textrect];
         [self addSubview:container_];
-    }
+    } return self;
+}
 
-    return self;
+- (UILabel *) label {
+    return label_;
 }
 
-- (UILabel *)label { return label_; }
-- (UIActivityIndicatorView *)activityIndicatorView { return spinner_; }
+- (UIActivityIndicatorView *) activityIndicatorView {
+    return spinner_;
+}
 
 @end
 /* }}} */
@@ -3937,6 +4111,7 @@ static NSString *Warning_;
     UITabBar *tabbar_;
     UINavigationBar *navbar_;
 }
+
 @end
 
 @implementation CYEmulatedLoadingController
@@ -3975,7 +4150,7 @@ static NSString *Warning_;
 }
 
 - (id) initWithDatabase:(Database *)database {
-    if ((self = [super init])) {
+    if ((self = [super init]) != nil) {
         database_ = database;
         [database_ setDelegate:self];
     } return self;
@@ -4455,6 +4630,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (SEL) selector;
 - (id) target;
 - (id) object;
+
 @end
 
 @implementation ProgressData
@@ -4607,7 +4783,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [self positionViews];
 }
 
-- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
     [self positionViews];
 }
 
@@ -6028,6 +6204,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 /* Home Controller {{{ */
 @interface HomeController : CYBrowserController {
 }
+
 @end
 
 @implementation HomeController
@@ -6101,6 +6278,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) queueStatusDidChange;
+
 @end
 
 @implementation ManageController
@@ -6215,14 +6393,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [prompt_ setFrame:prmrect];
 }
 
-- (void)setFrame:(CGRect)frame {
+- (void) setFrame:(CGRect)frame {
     [super setFrame:frame];
-
     [self positionViews];
 }
 
 - (id) initWithFrame:(CGRect)frame delegate:(id)delegate {
-    if ((self = [super initWithFrame:frame])) {
+    if ((self = [super initWithFrame:frame]) != nil) {
         [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
 
         [self setBarStyle:UIBarStyleBlack];
@@ -6978,8 +7155,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _trace();
 }
 
-- (void)editButtonClicked {
-    [self setEditing:!editing_];
+- (void) editButtonClicked {
+    [self setEditing:(!editing_)];
 }
 
 @end
@@ -7289,7 +7466,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     } return self;
 }
 
-- (void)viewDidAppear:(BOOL)animated {
+- (void) viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
 
     if (!searchloaded_) {
@@ -7459,7 +7636,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database package:(NSString *)package {
-    if ((self = [super init])) {
+    if ((self = [super init]) != nil) {
         database_ = database;
         name_ = [package retain];
     } return self;
@@ -7643,7 +7820,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 /* }}} */
 /* Source Controller {{{ */
 @interface SourceController : FilteredPackageListController {
-    Source *source_;
+    _transient Source *source_;
+    NSString *key_;
 }
 
 - (id) initWithDatabase:(Database *)database source:(Source *)source;
@@ -7657,12 +7835,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database source:(Source *)source {
-    source_ = source;
-
     if ((self = [super initWithDatabase:database title:[source label] filter:@selector(isVisibleInSource:) with:source]) != nil) {
+        source_ = source;
+        key_ = [[source key] retain];
     } return self;
 }
 
+- (void) reloadData {
+    source_ = [database_ sourceWithKey:key_];
+    [key_ release];
+    key_ = [[source_ key] retain];
+    [self setObject:source_];
+    [[self navigationItem] setTitle:[source_ label]];
+
+    [super reloadData];
+}
+
 @end
 /* }}} */
 /* Sources Controller {{{ */
@@ -7787,12 +7975,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [[self navigationController] pushViewController:controller animated:YES];
 }
 
-- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
     Source *source = [self sourceAtIndexPath:indexPath];
     return [source record] != nil;
 }
 
-- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
     Source *source = [self sourceAtIndexPath:indexPath];
     [Sources_ removeObjectForKey:[source key]];
     [delegate_ syncData];
@@ -7946,7 +8134,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
 }
 
-- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
     NSString *context([alert context]);
 
     if ([context isEqualToString:@"source"]) {
@@ -8199,7 +8387,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database delegate:(id)delegate {
-    if ((self = [super init])) {
+    if ((self = [super init]) != nil) {
         database_ = database;
         roledelegate_ = delegate;
     } return self;
@@ -8291,7 +8479,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return 0; // :(
 }
 
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     return nil; // This method is required by the protocol.
 }
 
@@ -8329,6 +8517,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     UILabel *status_;
     UILabel *caption_;
 }
+
 @end
 
 @implementation StashController
@@ -8917,7 +9106,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [[[CYPackageController alloc] initWithDatabase:database_ forPackage:name] autorelease];
 }
 
-- (CYViewController *) pageForURL:(NSURL *)url {
+- (CYViewController *) pageForURL:(NSURL *)url forExternal:(BOOL)external {
     NSString *scheme([[url scheme] lowercaseString]);
     if ([[url absoluteString] length] <= [scheme length] + 3)
         return nil;
@@ -8938,7 +9127,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         // This kind of URL can contain slashes in the argument, so we can't parse them below.
         NSString *destination = [[url absoluteString] substringFromIndex:([scheme length] + [@"://" length] + [base length] + [@"/" length])];
         controller = [[[CYBrowserController alloc] initWithURL:[NSURL URLWithString:destination]] autorelease];
-    } else if ([components count] == 1) {
+    } else if (!external && [components count] == 1) {
         if ([base isEqualToString:@"manage"]) {
             controller = [[[ManageController alloc] init] autorelease];
         }
@@ -8973,37 +9162,32 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             controller = [self pageForPackage:argument];
         }
 
-        if ([base isEqualToString:@"search"]) {
+        if (!external && [base isEqualToString:@"search"]) {
             controller = [[[SearchController alloc] initWithDatabase:database_] autorelease];
             [(SearchController *)controller setSearchTerm:argument];
         }
 
-        if ([base isEqualToString:@"sections"]) {
+        if (!external && [base isEqualToString:@"sections"]) {
             if ([argument isEqualToString:@"all"])
                 argument = nil;
             controller = [[[SectionController alloc] initWithDatabase:database_ section:argument] autorelease];
         }
 
-        if ([base isEqualToString:@"sources"]) {
+        if (!external && [base isEqualToString:@"sources"]) {
             if ([argument isEqualToString:@"add"]) {
                 controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease];
                 [(SourcesController *)controller showAddSourcePrompt];
             } else {
-                NSArray *sources = [database_ sources];
-                for (Source *source in sources) {
-                    if ([[source name] caseInsensitiveCompare:argument] == NSOrderedSame) {
-                        controller = [[[SourceController alloc] initWithDatabase:database_ source:source] autorelease];
-                        break;
-                    }
-                }
+                Source *source = [database_ sourceWithKey:argument];
+                controller = [[[SourceController alloc] initWithDatabase:database_ source:source] autorelease];
             }
         }
 
-        if ([base isEqualToString:@"launch"]) {
+        if (!external && [base isEqualToString:@"launch"]) {
             [self launchApplicationWithIdentifier:argument suspended:NO];
             return nil;
         }
-    } else if ([components count] == 3) {
+    } else if (!external && [components count] == 3) {
         NSString *arg1 = [components objectAtIndex:1];
         NSString *arg2 = [components objectAtIndex:2];
 
@@ -9023,8 +9207,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return controller;
 }
 
-- (BOOL) openCydiaURL:(NSURL *)url {
-    CYViewController *page([self pageForURL:url]);
+- (BOOL) openCydiaURL:(NSURL *)url forExternal:(BOOL)external {
+    CYViewController *page([self pageForURL:url forExternal:external]);
 
     if (page != nil) {
         CYNavigationController *nav = [[[CYNavigationController alloc] init] autorelease];
@@ -9039,7 +9223,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super applicationOpenURL:url];
 
     if (!loaded_) starturl_ = [url retain];
-    else [self openCydiaURL:url];
+    else [self openCydiaURL:url forExternal:YES];
 }
 
 - (void) applicationWillResignActive:(UIApplication *)application {
@@ -9120,7 +9304,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [tabbar_ setUpdateDelegate:self];
 }
 
-- (CYEmulatedLoadingController *)showEmulatedLoadingControllerInView:(UIView *)view {
+- (CYEmulatedLoadingController *) showEmulatedLoadingControllerInView:(UIView *)view {
     static CYEmulatedLoadingController *fake = nil;
 
     if (view != nil) {
@@ -9266,7 +9450,7 @@ _trace();
         for (unsigned int nav = 0; nav < [stack count]; nav++) {
             NSString *addr = [stack objectAtIndex:nav];
             NSURL *url = [NSURL URLWithString:addr];
-            CYViewController *page = [self pageForURL:url];
+            CYViewController *page = [self pageForURL:url forExternal:NO];
             if (page != nil)
                 [current addObject:page];
         }
@@ -9276,7 +9460,7 @@ _trace();
 
     // (Try to) show the startup URL.
     if (starturl_ != nil) {
-        [self openCydiaURL:starturl_];
+        [self openCydiaURL:starturl_ forExternal:NO];
         [starturl_ release];
         starturl_ = nil;
     }