1 /* #include Directives {{{ */
2 #include <Foundation/NSURL.h>
3 #include <UIKit/UIKit.h>
4 #import <GraphicsServices/GraphicsServices.h>
7 #include <ext/stdio_filebuf.h>
9 #include <apt-pkg/acquire.h>
10 #include <apt-pkg/acquire-item.h>
11 #include <apt-pkg/algorithms.h>
12 #include <apt-pkg/cachefile.h>
13 #include <apt-pkg/configuration.h>
14 #include <apt-pkg/debmetaindex.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/init.h>
17 #include <apt-pkg/pkgrecords.h>
18 #include <apt-pkg/sourcelist.h>
19 #include <apt-pkg/sptr.h>
21 #include <sys/sysctl.h>
27 /* Extension Keywords {{{ */
28 #define _trace() fprintf(stderr, "_trace()@%s:%u[%s]\n", __FILE__, __LINE__, __FUNCTION__)
30 #define _assert(test) do \
32 fprintf(stderr, "_assert(%d:%s)@%s:%u[%s]\n", errno, #test, __FILE__, __LINE__, __FUNCTION__); \
39 - (void) setApplicationNameForUserAgent:(NSString *)applicationName;
42 static const int PulseInterval_ = 50000;
43 const char *Machine_ = NULL;
44 const char *SerialNumber_ = NULL;
46 @interface NSString (CydiaBypass)
47 - (NSString *) stringByAddingPercentEscapes;
50 @protocol ProgressDelegate
51 - (void) setError:(NSString *)error;
52 - (void) setTitle:(NSString *)title;
53 - (void) setPercent:(float)percent;
54 - (void) addOutput:(NSString *)output;
57 /* Status Delegation {{{ */
59 public pkgAcquireStatus
70 void setDelegate(id delegate) {
74 virtual bool MediaChange(std::string media, std::string drive) {
78 virtual void IMSHit(pkgAcquire::ItemDesc &item) {
81 virtual void Fetch(pkgAcquire::ItemDesc &item) {
82 [delegate_ setTitle:[NSString stringWithCString:("Downloading " + item.ShortDesc).c_str()]];
85 virtual void Done(pkgAcquire::ItemDesc &item) {
88 virtual void Fail(pkgAcquire::ItemDesc &item) {
89 [delegate_ performSelectorOnMainThread:@selector(setStatusFail) withObject:nil waitUntilDone:YES];
92 virtual bool Pulse(pkgAcquire *Owner) {
93 bool value = pkgAcquireStatus::Pulse(Owner);
96 double(CurrentBytes + CurrentItems) /
97 double(TotalBytes + TotalItems)
100 [delegate_ setPercent:percent];
104 virtual void Start() {
107 virtual void Stop() {
111 /* Progress Delegation {{{ */
119 virtual void Update() {
120 [delegate_ setTitle:[NSString stringWithCString:Op.c_str()]];
121 [delegate_ setPercent:(Percent / 100)];
130 void setDelegate(id delegate) {
131 delegate_ = delegate;
134 virtual void Done() {
135 [delegate_ setPercent:1];
140 /* External Constants {{{ */
141 extern NSString *kUIButtonBarButtonAction;
142 extern NSString *kUIButtonBarButtonInfo;
143 extern NSString *kUIButtonBarButtonInfoOffset;
144 extern NSString *kUIButtonBarButtonSelectedInfo;
145 extern NSString *kUIButtonBarButtonStyle;
146 extern NSString *kUIButtonBarButtonTag;
147 extern NSString *kUIButtonBarButtonTarget;
148 extern NSString *kUIButtonBarButtonTitle;
149 extern NSString *kUIButtonBarButtonTitleVerticalHeight;
150 extern NSString *kUIButtonBarButtonTitleWidth;
151 extern NSString *kUIButtonBarButtonType;
153 /* Mime Addresses {{{ */
154 @interface Address : NSObject {
162 - (NSString *) email;
164 + (Address *) addressWithString:(NSString *)string;
165 - (Address *) initWithString:(NSString *)string;
168 @implementation Address
177 - (NSString *) name {
181 - (NSString *) email {
185 + (Address *) addressWithString:(NSString *)string {
186 return [[[Address alloc] initWithString:string] autorelease];
189 - (Address *) initWithString:(NSString *)string {
190 if ((self = [super init]) != nil) {
193 pcre *code = pcre_compile("^\"?(.*)\"? <([^>]*)>$", 0, &error, &offset, NULL);
196 fprintf(stderr, "%d:%s\n", offset, error);
200 pcre_extra *study = NULL;
202 pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture);
203 int matches[(capture + 1) * 3];
205 size_t size = [string length];
206 const char *data = [string UTF8String];
208 if (pcre_exec(code, study, data, size, 0, 0, matches, sizeof(matches) / sizeof(matches[0])) >= 0) {
209 name_ = [[NSString stringWithCString:(data + matches[2]) length:(matches[3] - matches[2])] retain];
210 email_ = [[NSString stringWithCString:(data + matches[4]) length:(matches[5] - matches[4])] retain];
212 name_ = [[NSString stringWithCString:data length:size] retain];
221 /* Right Alignment {{{ */
222 @interface UIRightTextLabel : UITextLabel {
223 float _savedRightEdgeX;
224 BOOL _sizedtofit_flag;
227 - (void) setFrame:(CGRect)frame;
228 - (void) setText:(NSString *)text;
229 - (void) realignText;
232 @implementation UIRightTextLabel
234 - (void) setFrame:(CGRect)frame {
235 [super setFrame:frame];
236 if (_sizedtofit_flag == NO) {
237 _savedRightEdgeX = frame.origin.x;
242 - (void) setText:(NSString *)text {
243 [super setText:text];
247 - (void) realignText {
248 CGRect oldFrame = [self frame];
250 _sizedtofit_flag = YES;
251 [self sizeToFit]; // shrink down size so I can right align it
253 CGRect newFrame = [self frame];
255 oldFrame.origin.x = _savedRightEdgeX - newFrame.size.width;
256 oldFrame.size.width = newFrame.size.width;
257 [super setFrame:oldFrame];
258 _sizedtofit_flag = NO;
263 /* Linear Algebra {{{ */
264 inline float interpolate(float begin, float end, float fraction) {
265 return (end - begin) * fraction + begin;
270 @interface ResetView : UIView {
271 UINavigationBar *navbar_;
275 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item;
280 - (NSString *) leftTitle;
281 - (NSString *) rightTitle;
284 @implementation ResetView
286 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item {
287 if ([[navbar_ navigationItems] count] == 1)
298 if ([[navbar_ navigationItems] count] == 1)
300 else while ([[navbar_ navigationItems] count] != 1)
301 [navbar_ popNavigationItem];
305 - (void) _resetView {
306 [navbar_ showButtonsWithLeftTitle:[self leftTitle] rightTitle:[self rightTitle]];
309 - (NSString *) leftTitle {
313 - (NSString *) rightTitle {
322 @interface Database : NSObject {
324 pkgRecords *records_;
325 pkgProblemResolver *resolver_;
333 - (void) _readStatus:(NSNumber *)fd;
334 - (void) _readOutput:(NSNumber *)fd;
336 - (Package *) packageWithName:(NSString *)name;
339 - (pkgCacheFile &) cache;
340 - (pkgRecords *) records;
341 - (pkgProblemResolver *) resolver;
348 - (void) setDelegate:(id)delegate;
351 /* Package Class {{{ */
352 @interface Package : NSObject {
353 pkgCache::PkgIterator iterator_;
355 pkgRecords::Parser *parser_;
356 pkgCache::VerIterator version_;
357 pkgCache::VerFileIterator file_;
360 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file;
361 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database;
364 - (NSString *) section;
365 - (NSString *) latest;
366 - (NSString *) installed;
367 - (Address *) maintainer;
369 - (NSString *) tagline;
370 - (NSString *) description;
371 - (NSComparisonResult) compareBySectionAndName:(Package *)package;
377 @implementation Package
379 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file {
380 if ((self = [super init]) != nil) {
381 iterator_ = iterator;
382 database_ = database;
386 parser_ = &[database_ records]->Lookup(file);
390 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database {
391 for (pkgCache::VerIterator version = iterator.VersionList(); !version.end(); ++version)
392 for (pkgCache::VerFileIterator file = version.FileList(); !file.end(); ++file)
393 return [[[Package alloc]
394 initWithIterator:iterator
402 - (NSString *) name {
403 return [[NSString stringWithCString:iterator_.Name()] lowercaseString];
406 - (NSString *) section {
407 return [NSString stringWithCString:iterator_.Section()];
410 - (NSString *) latest {
411 return [NSString stringWithCString:version_.VerStr()];
414 - (NSString *) installed {
415 return iterator_.CurrentVer().end() ? nil : [NSString stringWithCString:iterator_.CurrentVer().VerStr()];
418 - (Address *) maintainer {
419 return [Address addressWithString:[NSString stringWithCString:parser_->Maintainer().c_str()]];
423 return version_->InstalledSize;
426 - (NSString *) tagline {
427 return [NSString stringWithCString:parser_->ShortDesc().c_str()];
430 - (NSString *) description {
431 return [NSString stringWithCString:parser_->LongDesc().c_str()];
434 - (NSComparisonResult) compareBySectionAndName:(Package *)package {
435 NSComparisonResult result = [[self section] compare:[package section]];
436 if (result != NSOrderedSame)
438 return [[self name] compare:[package name]];
442 pkgProblemResolver *resolver = [database_ resolver];
443 resolver->Clear(iterator_);
444 resolver->Protect(iterator_);
445 [database_ cache]->MarkInstall(iterator_, false);
449 pkgProblemResolver *resolver = [database_ resolver];
450 resolver->Clear(iterator_);
451 resolver->Protect(iterator_);
452 resolver->Remove(iterator_);
453 [database_ cache]->MarkDelete(iterator_, true);
458 /* Section Class {{{ */
459 @interface Section : NSObject {
462 NSMutableArray *packages_;
467 - (Section *) initWithName:(NSString *)name row:(size_t)row;
470 - (void) addPackage:(Package *)package;
473 @implementation Section
481 - (Section *) initWithName:(NSString *)name row:(size_t)row {
482 if ((self = [super init]) != nil) {
483 name_ = [name retain];
485 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
489 - (NSString *) name {
497 - (void) addPackage:(Package *)package {
498 [packages_ addObject:package];
504 /* Confirmation View {{{ */
505 @protocol ConfirmationViewDelegate
510 @interface ConfirmationView : UIView {
513 UITransitionView *transition_;
515 UINavigationBar *navbar_;
516 UIPreferencesTable *table_;
521 - (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to;
522 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
524 - (id) initWithView:(UIView *)view database:(Database *)database delegate:(id)delegate;
528 @implementation ConfirmationView
531 [transition_ release];
538 - (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to {
539 if (from != nil && to == nil)
540 [self removeFromSuperview];
543 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
550 [transition_ transition:7 toView:nil];
556 - (id) initWithView:(UIView *)view database:(Database *)database delegate:(id)delegate {
557 if ((self = [super initWithFrame:[view bounds]]) != nil) {
558 database_ = database;
559 delegate_ = delegate;
561 transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
562 [self addSubview:transition_];
564 overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
566 CGSize navsize = [UINavigationBar defaultSize];
567 CGRect navrect = {{0, 0}, navsize};
568 CGRect bounds = [overlay_ bounds];
570 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
571 [navbar_ setBarStyle:1];
572 [navbar_ setDelegate:self];
574 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:@"Confirm"] autorelease];
575 [navbar_ pushNavigationItem:navitem];
576 [navbar_ showButtonsWithLeftTitle:@"Cancel" rightTitle:@"Confirm"];
578 table_ = [[UIPreferencesTable alloc] initWithFrame:CGRectMake(
579 0, navsize.height, bounds.size.width, bounds.size.height - navsize.height
582 [table_ setDataSource:self];
584 [overlay_ addSubview:navbar_];
585 [overlay_ addSubview:table_];
587 [view addSubview:self];
589 [transition_ setDelegate:self];
591 UIView *blank = [[[UIView alloc] initWithFrame:[transition_ bounds]] autorelease];
592 [transition_ transition:0 toView:blank];
593 [transition_ transition:3 toView:overlay_];
599 /* Package View {{{ */
600 @interface PackageView : UIView {
601 UIPreferencesTable *table_;
604 NSMutableArray *cells_;
610 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table;
611 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group;
612 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group;
614 - (BOOL) canSelectRow:(int)row;
615 - (void) tableRowSelected:(NSNotification *)notification;
617 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database;
618 - (void) setPackage:(Package *)package;
619 - (void) setDelegate:(id)delegate;
622 @implementation PackageView
633 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table {
637 - (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group {
644 return @"Description";
647 default: _assert(false);
651 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group {
661 default: _assert(false);
665 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group {
666 UIPreferencesTableCell *cell;
669 case 0: switch (row) {
671 cell = [cells_ objectAtIndex:0];
672 [cell setTitle:@"Name"];
673 [cell setValue:[package_ name]];
677 cell = [cells_ objectAtIndex:1];
678 [cell setTitle:@"Installed"];
679 NSString *installed([package_ installed]);
680 [cell setValue:(installed == nil ? @"n/a" : installed)];
684 cell = [cells_ objectAtIndex:2];
685 [cell setTitle:@"Latest"];
686 [cell setValue:[package_ latest]];
690 cell = [cells_ objectAtIndex:3];
691 [cell setTitle:@"Section"];
692 [cell setValue:[package_ section]];
696 double size = [package_ size];
698 while (size > 1024) {
703 cell = [cells_ objectAtIndex:4];
704 [cell setTitle:@"Size"];
705 [cell setValue:[NSString stringWithFormat:@"%.1f%c", size, "bkMG"[power]]];
709 cell = [cells_ objectAtIndex:5];
710 [cell setTitle:@"Maintainer"];
711 [cell setValue:[[package_ maintainer] name]];
712 [cell setShowDisclosure:YES];
713 [cell setShowSelection:YES];
716 default: _assert(false);
719 case 1: switch (row) {
721 cell = [cells_ objectAtIndex:6];
723 [cell setValue:[package_ tagline]];
727 cell = [cells_ objectAtIndex:7];
728 [cell setTitle:@"Description"];
729 [cell setValue:[package_ description]];
733 default: _assert(false);
739 - (BOOL) canSelectRow:(int)row {
743 - (void) tableRowSelected:(NSNotification *)notification {
744 switch ([table_ selectedRow]) {
746 [delegate_ openURL:[NSURL URLWithString:[NSString stringWithFormat:@"mailto:%@?subject=%@",
747 [[package_ maintainer] email],
748 [[NSString stringWithFormat:@"regarding apt package \"%@\"", [package_ name]] stringByAddingPercentEscapes]
754 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database {
755 if ((self = [super initWithFrame:frame]) != nil) {
756 database_ = [database retain];
758 table_ = [[UIPreferencesTable alloc] initWithFrame:[self bounds]];
759 [self addSubview:table_];
761 [table_ setDataSource:self];
762 [table_ setDelegate:self];
764 cells_ = [[NSMutableArray arrayWithCapacity:16] retain];
766 for (unsigned i = 0; i != 8; ++i) {
767 struct CGRect frame = [table_ frameOfPreferencesCellAtRow:0 inGroup:0];
768 UIPreferencesTableCell *cell = [[[UIPreferencesTableCell alloc] init] autorelease];
769 [cell setShowSelection:NO];
770 [cells_ addObject:cell];
775 - (void) setPackage:(Package *)package {
776 package_ = [package retain];
780 - (void) setDelegate:(id)delegate {
781 delegate_ = delegate;
786 /* Package Cell {{{ */
787 @interface PackageCell : UITableCell {
789 UIRightTextLabel *version_;
790 UITextLabel *description_;
795 - (PackageCell *) initWithPackage:(Package *)package;
797 - (void) _setSelected:(float)fraction;
798 - (void) setSelected:(BOOL)selected;
799 - (void) setSelected:(BOOL)selected withFade:(BOOL)fade;
800 - (void) _setSelectionFadeFraction:(float)fraction;
804 @implementation PackageCell
809 [description_ release];
813 - (PackageCell *) initWithPackage:(Package *)package {
814 if ((self = [super init]) != nil) {
815 GSFontRef bold = GSFontCreateWithName("Helvetica", kGSFontTraitBold, 22);
816 GSFontRef large = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 16);
817 GSFontRef small = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 14);
819 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
820 float clear[] = {0, 0, 0, 0};
822 name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 7, 250, 25)];
823 [name_ setText:[package name]];
824 [name_ setBackgroundColor:CGColorCreate(space, clear)];
825 [name_ setFont:bold];
827 version_ = [[UIRightTextLabel alloc] initWithFrame:CGRectMake(290, 7, 70, 25)];
828 [version_ setText:[package latest]];
829 [version_ setBackgroundColor:CGColorCreate(space, clear)];
830 [version_ setFont:large];
832 description_ = [[UITextLabel alloc] initWithFrame:CGRectMake(13, 35, 315, 20)];
833 [description_ setText:[package tagline]];
834 [description_ setBackgroundColor:CGColorCreate(space, clear)];
835 [description_ setFont:small];
837 [self addSubview:name_];
838 [self addSubview:version_];
839 [self addSubview:description_];
847 - (void) _setSelected:(float)fraction {
848 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
851 interpolate(0.0, 1.0, fraction),
852 interpolate(0.0, 1.0, fraction),
853 interpolate(0.0, 1.0, fraction),
857 interpolate(0.2, 1.0, fraction),
858 interpolate(0.2, 1.0, fraction),
859 interpolate(1.0, 1.0, fraction),
863 interpolate(0.4, 1.0, fraction),
864 interpolate(0.4, 1.0, fraction),
865 interpolate(0.4, 1.0, fraction),
868 [name_ setColor:CGColorCreate(space, black)];
869 [version_ setColor:CGColorCreate(space, blue)];
870 [description_ setColor:CGColorCreate(space, gray)];
873 - (void) setSelected:(BOOL)selected {
874 [self _setSelected:(selected ? 1.0 : 0.0)];
875 [super setSelected:selected];
878 - (void) setSelected:(BOOL)selected withFade:(BOOL)fade {
880 [self _setSelected:(selected ? 1.0 : 0.0)];
881 [super setSelected:selected withFade:fade];
884 - (void) _setSelectionFadeFraction:(float)fraction {
885 [self _setSelected:fraction];
886 [super _setSelectionFadeFraction:fraction];
891 /* Sources View {{{ */
892 @interface SourcesView : ResetView {
893 UISectionList *list_;
896 NSMutableArray *sources_;
899 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
901 - (id) initWithFrame:(CGRect)frame database:(Database *)database;
902 - (void) setDelegate:(id)delegate;
904 - (NSString *) leftTitle;
905 - (NSString *) rightTitle;
908 @implementation SourcesView
910 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
928 - (id) initWithFrame:(CGRect)frame database:(Database *)database {
929 if ((self = [super initWithFrame:frame]) != nil) {
930 database_ = database;
933 CGSize navsize = [UINavigationBar defaultSize];
934 CGRect navrect = {{0, 0}, navsize};
935 CGRect bounds = [self bounds];
937 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
938 [self addSubview:navbar_];
940 [navbar_ setBarStyle:1];
941 [navbar_ setDelegate:self];
943 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:@"Sources"] autorelease];
944 [navbar_ pushNavigationItem:navitem];
946 list_ = [[UISectionList alloc] initWithFrame:CGRectMake(
947 0, navsize.height, bounds.size.width, bounds.size.height - navsize.height
950 [list_ setDataSource:self];
951 //[list_ setShouldHideHeaderInShortLists:NO];
955 - (void) setDelegate:(id)delegate {
956 delegate_ = delegate;
959 - (void) reloadData {
961 _assert(list.ReadMainList());
963 sources_ = [[NSMutableArray arrayWithCapacity:16] retain];
965 for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source) {
966 metaIndex *index(*source);
967 fprintf(stderr, "\"%s\" \"%s\" \"%s\" \"%s\"\n", index->GetURI().c_str(), index->GetDist().c_str(), index->GetType(), index->IsTrusted() ? "true" : "false");
969 debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
973 fprintf(stderr, " \"%s\"\n", dindex->MetaIndexFile("Release").c_str());
975 std::ifstream release(dindex->MetaIndexFile("Release").c_str());
977 while (std::getline(release, line)) {
978 std::string::size_type colon(line.find(':'));
979 if (colon == std::string::npos)
981 std::string name(line.substr(0, colon));
982 std::string value(line.substr(colon + 1));
983 while (!value.empty() && value[0] == ' ')
984 value = value.substr(1);
985 std::cerr << "[" << name << "|" << value << "]" << std::endl;
992 - (NSString *) leftTitle {
993 return @"Refresh All";
996 - (NSString *) rightTitle {
1003 @implementation Database
1005 - (void) _readStatus:(NSNumber *)fd {
1006 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1008 __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
1009 std::istream is(&ib);
1014 pcre *code = pcre_compile("^([^:]*):([^:]*):([^:]*):(.*)$", 0, &error, &offset, NULL);
1016 pcre_extra *study = NULL;
1018 pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture);
1019 int matches[(capture + 1) * 3];
1021 while (std::getline(is, line)) {
1022 const char *data(line.c_str());
1024 _assert(pcre_exec(code, study, data, line.size(), 0, 0, matches, sizeof(matches) / sizeof(matches[0])) >= 0);
1026 std::istringstream buffer(line.substr(matches[6], matches[7] - matches[6]));
1029 [delegate_ setPercent:(percent / 100)];
1031 NSString *string = [NSString stringWithCString:(data + matches[8]) length:(matches[9] - matches[8])];
1032 std::string type(line.substr(matches[2], matches[3] - matches[2]));
1034 if (type == "pmerror")
1035 [delegate_ setError:string];
1036 else if (type == "pmstatus")
1037 [delegate_ setTitle:string];
1038 else if (type == "pmconffile")
1040 else _assert(false);
1046 - (void) _readOutput:(NSNumber *)fd {
1047 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1049 __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
1050 std::istream is(&ib);
1053 while (std::getline(is, line))
1054 [delegate_ addOutput:[NSString stringWithCString:line.c_str()]];
1059 - (Package *) packageWithName:(NSString *)name {
1060 pkgCache::PkgIterator iterator(cache_->FindPkg([name cString]));
1061 return iterator.end() ? nil : [Package packageWithIterator:iterator database:self];
1064 - (Database *) init {
1065 if ((self = [super init]) != nil) {
1071 _assert(pipe(fds) != -1);
1075 detachNewThreadSelector:@selector(_readStatus:)
1077 withObject:[[NSNumber numberWithInt:fds[0]] retain]
1080 _assert(pipe(fds) != -1);
1081 _assert(dup2(fds[1], 1) != -1);
1082 _assert(close(fds[1]) != -1);
1085 detachNewThreadSelector:@selector(_readOutput:)
1087 withObject:[[NSNumber numberWithInt:fds[0]] retain]
1092 - (pkgCacheFile &) cache {
1096 - (pkgRecords *) records {
1100 - (pkgProblemResolver *) resolver {
1104 - (void) reloadData {
1109 cache_.Open(progress_, true);
1110 records_ = new pkgRecords(cache_);
1111 resolver_ = new pkgProblemResolver(cache_);
1115 pkgRecords records(cache_);
1118 lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1119 _assert(!_error->PendingError());
1121 pkgAcquire fetcher(&status_);
1123 _assert(list.ReadMainList());
1125 SPtr<pkgPackageManager> manager(_system->CreatePM(cache_));
1126 _assert(manager->GetArchives(&fetcher, &list, &records));
1127 _assert(!_error->PendingError());
1128 _assert(fetcher.Run(PulseInterval_) != pkgAcquire::Failed);
1131 pkgPackageManager::OrderResult result = manager->DoInstall(statusfd_);
1133 if (result == pkgPackageManager::Failed)
1135 if (_error->PendingError())
1137 if (result != pkgPackageManager::Completed)
1143 _assert(list.ReadMainList());
1146 lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
1147 _assert(!_error->PendingError());
1149 pkgAcquire fetcher(&status_);
1150 _assert(list.GetIndexes(&fetcher));
1151 _assert(fetcher.Run(PulseInterval_) != pkgAcquire::Failed);
1153 bool failed = false;
1154 for (pkgAcquire::ItemIterator item = fetcher.ItemsBegin(); item != fetcher.ItemsEnd(); item++)
1155 if ((*item)->Status != pkgAcquire::Item::StatDone) {
1156 (*item)->Finished();
1160 if (!failed && _config->FindB("APT::Get::List-Cleanup", true) == true) {
1161 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists")));
1162 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/"));
1167 _assert(cache_->DelCount() == 0 && cache_->InstCount() == 0);
1168 _assert(pkgApplyStatus(cache_));
1170 if (cache_->BrokenCount() != 0) {
1171 _assert(pkgFixBroken(cache_));
1172 _assert(cache_->BrokenCount() == 0);
1173 _assert(pkgMinimizeUpgrade(cache_));
1176 _assert(pkgDistUpgrade(cache_));
1178 //InstallPackages(cache_, true);
1181 - (void) setDelegate:(id)delegate {
1182 delegate_ = delegate;
1183 status_.setDelegate(delegate);
1184 progress_.setDelegate(delegate);
1189 /* Progress Data {{{ */
1190 @interface ProgressData : NSObject {
1196 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object;
1203 @implementation ProgressData
1205 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object {
1206 if ((self = [super init]) != nil) {
1207 selector_ = selector;
1227 /* Progress View {{{ */
1228 @interface ProgressView : UIView <
1232 UIView *background_;
1233 UITransitionView *transition_;
1235 UINavigationBar *navbar_;
1236 UIProgressBar *progress_;
1237 UITextView *output_;
1238 UITextLabel *status_;
1240 UIAlertSheet *alert_;
1245 - (ProgressView *) initWithFrame:(struct CGRect)frame delegate:(id)delegate;
1246 - (void) setContentView:(UIView *)view;
1249 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button;
1251 - (void) _retachThread;
1252 - (void) _detachNewThreadData:(ProgressData *)data;
1253 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object;
1255 - (void) setError:(NSString *)error;
1256 - (void) _setError:(NSString *)error;
1258 - (void) setTitle:(NSString *)title;
1259 - (void) _setTitle:(NSString *)title;
1261 - (void) setPercent:(float)percent;
1262 - (void) _setPercent:(NSNumber *)percent;
1264 - (void) addOutput:(NSString *)output;
1265 - (void) _addOutput:(NSString *)output;
1267 - (void) setStatusFail;
1270 @protocol ProgressViewDelegate
1271 - (void) progressViewIsComplete:(ProgressView *)sender;
1274 @implementation ProgressView
1278 [background_ release];
1279 [transition_ release];
1282 [progress_ release];
1288 - (ProgressView *) initWithFrame:(struct CGRect)frame delegate:(id)delegate {
1289 if ((self = [super initWithFrame:frame]) != nil) {
1290 delegate_ = delegate;
1293 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
1294 float black[] = {0.0, 0.0, 0.0, 1.0};
1295 float white[] = {1.0, 1.0, 1.0, 1.0};
1296 float clear[] = {0.0, 0.0, 0.0, 0.0};
1298 background_ = [[UIView alloc] initWithFrame:[self bounds]];
1299 [background_ setBackgroundColor:CGColorCreate(space, black)];
1300 [self addSubview:background_];
1302 transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
1303 [self addSubview:transition_];
1305 overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
1307 CGSize navsize = [UINavigationBar defaultSize];
1308 CGRect navrect = {{0, 0}, navsize};
1310 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1311 [overlay_ addSubview:navbar_];
1313 [navbar_ setBarStyle:1];
1314 [navbar_ setDelegate:self];
1316 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:@"Running..."] autorelease];
1317 [navbar_ pushNavigationItem:navitem];
1319 CGRect bounds = [overlay_ bounds];
1320 CGSize prgsize = [UIProgressBar defaultSize];
1323 (bounds.size.width - prgsize.width) / 2,
1324 bounds.size.height - prgsize.height - 20
1327 progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
1328 [overlay_ addSubview:progress_];
1330 status_ = [[UITextLabel alloc] initWithFrame:CGRectMake(
1332 bounds.size.height - prgsize.height - 50,
1333 bounds.size.width - 20,
1337 [status_ setColor:CGColorCreate(space, white)];
1338 [status_ setBackgroundColor:CGColorCreate(space, clear)];
1340 [status_ setCentersHorizontally:YES];
1341 //[status_ setFont:font];
1343 output_ = [[UITextView alloc] initWithFrame:CGRectMake(
1345 navrect.size.height + 20,
1346 bounds.size.width - 20,
1347 bounds.size.height - navsize.height - 62 - navrect.size.height
1350 //[output_ setTextFont:@"Courier New"];
1351 [output_ setTextSize:12];
1353 [output_ setTextColor:CGColorCreate(space, white)];
1354 [output_ setBackgroundColor:CGColorCreate(space, clear)];
1356 [output_ setMarginTop:0];
1357 [output_ setAllowsRubberBanding:YES];
1359 [overlay_ addSubview:output_];
1360 [overlay_ addSubview:status_];
1362 [progress_ setStyle:0];
1366 - (void) setContentView:(UIView *)view {
1370 - (void) resetView {
1371 [transition_ transition:6 toView:view_];
1374 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
1380 - (void) _retachThread {
1381 [delegate_ progressViewIsComplete:self];
1385 - (void) _detachNewThreadData:(ProgressData *)data {
1386 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1388 [[data target] performSelector:[data selector] withObject:[data object]];
1389 [self performSelectorOnMainThread:@selector(_retachThread) withObject:nil waitUntilDone:YES];
1395 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object {
1396 [status_ setText:nil];
1397 [output_ setText:@""];
1398 [progress_ setProgress:0];
1400 [transition_ transition:6 toView:overlay_];
1403 detachNewThreadSelector:@selector(_detachNewThreadData:)
1405 withObject:[[ProgressData alloc]
1406 initWithSelector:selector
1413 - (void) setStatusFail {
1416 - (void) setError:(NSString *)error {
1418 performSelectorOnMainThread:@selector(_setError:)
1424 - (void) _setError:(NSString *)error {
1425 _assert(alert_ == nil);
1427 alert_ = [[UIAlertSheet alloc]
1428 initWithTitle:@"Package Error"
1429 buttons:[NSArray arrayWithObjects:@"Okay", nil]
1430 defaultButtonIndex:0
1435 [alert_ setBodyText:error];
1436 [alert_ popupAlertAnimated:YES];
1439 - (void) setTitle:(NSString *)title {
1441 performSelectorOnMainThread:@selector(_setTitle:)
1447 - (void) _setTitle:(NSString *)title {
1448 [status_ setText:[title stringByAppendingString:@"..."]];
1451 - (void) setPercent:(float)percent {
1453 performSelectorOnMainThread:@selector(_setPercent:)
1454 withObject:[NSNumber numberWithFloat:percent]
1459 - (void) _setPercent:(NSNumber *)percent {
1460 [progress_ setProgress:[percent floatValue]];
1463 - (void) addOutput:(NSString *)output {
1465 performSelectorOnMainThread:@selector(_addOutput:)
1471 - (void) _addOutput:(NSString *)output {
1472 [output_ setText:[NSString stringWithFormat:@"%@\n%@", [output_ text], output]];
1473 CGSize size = [output_ contentSize];
1474 CGRect rect = {{0, size.height}, {size.width, 0}};
1475 [output_ scrollRectToVisible:rect animated:YES];
1481 @protocol PackagesViewDelegate
1484 - (void) openURL:(NSString *)url;
1487 /* PackagesView {{{ */
1488 @interface PackagesView : ResetView {
1489 Database *database_;
1490 NSMutableArray *packages_;
1491 NSMutableArray *sections_;
1493 UISectionList *list_;
1494 UITransitionView *transition_;
1496 PackageView *pkgview_;
1499 - (int) numberOfSectionsInSectionList:(UISectionList *)list;
1500 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section;
1501 - (int) sectionList:(UISectionList *)list rowForSection:(int)section;
1503 - (int) numberOfRowsInTable:(UITable *)table;
1504 - (float) table:(UITable *)table heightForRow:(int)row;
1505 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col;
1506 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row;
1507 - (void) tableRowSelected:(NSNotification*)notification;
1509 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
1510 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item;
1512 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database;
1513 - (void) setDelegate:(id)delegate;
1515 - (void) reloadData;
1517 - (NSString *) title;
1518 - (void) perform:(Package *)package;
1519 - (void) addPackage:(Package *)package;
1522 @implementation PackagesView
1524 - (int) numberOfSectionsInSectionList:(UISectionList *)list {
1525 return [sections_ count];
1528 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section {
1529 return [[sections_ objectAtIndex:section] name];
1532 - (int) sectionList:(UISectionList *)list rowForSection:(int)section {
1533 return [[sections_ objectAtIndex:section] row];
1536 - (int) numberOfRowsInTable:(UITable *)table {
1537 return [packages_ count];
1540 - (float) table:(UITable *)table heightForRow:(int)row {
1544 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col {
1545 Package *package = [packages_ objectAtIndex:row];
1546 PackageCell *cell = [[[PackageCell alloc] initWithPackage:package] autorelease];
1550 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row {
1554 - (void) tableRowSelected:(NSNotification*)notification {
1555 int row = [[list_ table] selectedRow];
1559 package_ = [packages_ objectAtIndex:row];
1561 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:[package_ name]];
1562 [navbar_ pushNavigationItem:navitem];
1564 [navbar_ showButtonsWithLeftTitle:nil rightTitle:[self title]];
1566 [pkgview_ setPackage:package_];
1567 [transition_ transition:1 toView:pkgview_];
1570 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
1572 [self perform:package_];
1574 pkgProblemResolver *resolver = [database_ resolver];
1576 resolver->InstallProtect();
1577 if (!resolver->Resolve(true))
1580 [delegate_ perform];
1584 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item {
1586 [super navigationBar:navbar poppedItem:item];
1589 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database {
1590 if ((self = [super initWithFrame:frame]) != nil) {
1591 database_ = [database retain];
1593 struct CGRect bounds = [self bounds];
1594 CGSize navsize = [UINavigationBar defaultSize];
1595 CGRect navrect = {{0, 0}, navsize};
1597 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1598 [self addSubview:navbar_];
1600 [navbar_ setBarStyle:1];
1601 [navbar_ setDelegate:self];
1603 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:[self title]] autorelease];
1604 [navbar_ pushNavigationItem:navitem];
1605 [navitem setBackButtonTitle:@"Packages"];
1607 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
1608 bounds.origin.x, bounds.origin.y + navsize.height, bounds.size.width, bounds.size.height - navsize.height
1611 [self addSubview:transition_];
1613 list_ = [[UISectionList alloc] initWithFrame:[transition_ bounds] showSectionIndex:NO];
1614 [list_ setDataSource:self];
1615 [list_ setShouldHideHeaderInShortLists:NO];
1617 [transition_ transition:0 toView:list_];
1619 UITableColumn *column = [[UITableColumn alloc]
1620 initWithTitle:@"Name"
1622 width:frame.size.width
1625 UITable *table = [list_ table];
1626 [table setSeparatorStyle:1];
1627 [table addTableColumn:column];
1628 [table setDelegate:self];
1630 pkgview_ = [[PackageView alloc] initWithFrame:[transition_ bounds] database:database_];
1634 - (void) setDelegate:(id)delegate {
1635 delegate_ = delegate;
1636 [pkgview_ setDelegate:delegate];
1640 [transition_ transition:(resetting_ ? 0 : 2) toView:list_];
1641 UITable *table = [list_ table];
1642 [table selectRow:-1 byExtendingSelection:NO withFade:(resetting_ ? NO : YES)];
1646 - (void) reloadData {
1647 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
1649 if (sections_ != nil) {
1650 [sections_ release];
1654 for (pkgCache::PkgIterator iterator = [database_ cache]->PkgBegin(); !iterator.end(); ++iterator)
1655 if (Package *package = [Package packageWithIterator:iterator database:database_])
1656 [self addPackage:package];
1658 [packages_ sortUsingSelector:@selector(compareBySectionAndName:)];
1659 sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
1661 Section *section = nil;
1662 for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
1663 Package *package = [packages_ objectAtIndex:offset];
1664 NSString *name = [package section];
1666 if (section == nil || ![[section name] isEqual:name]) {
1667 section = [[Section alloc] initWithName:name row:offset];
1668 [sections_ addObject:section];
1671 [section addPackage:package];
1678 - (NSString *) title {
1682 - (void) perform:(Package *)package {
1685 - (void) addPackage:(Package *)package {
1686 [packages_ addObject:package];
1692 /* InstallView {{{ */
1693 @interface InstallView : PackagesView {
1696 - (NSString *) title;
1697 - (void) addPackage:(Package *)package;
1698 - (void) perform:(Package *)package;
1701 @implementation InstallView
1703 - (NSString *) title {
1707 - (void) addPackage:(Package *)package {
1708 if ([package installed] == nil)
1709 [super addPackage:package];
1712 - (void) perform:(Package *)package {
1718 /* UpgradeView {{{ */
1719 @interface UpgradeView : PackagesView {
1722 - (NSString *) title;
1723 - (NSString *) leftTitle;
1724 - (void) addPackage:(Package *)package;
1725 - (void) perform:(Package *)package;
1728 @implementation UpgradeView
1730 - (NSString *) title {
1734 - (NSString *) leftTitle {
1735 return @"Upgrade All";
1738 - (void) addPackage:(Package *)package {
1739 NSString *installed = [package installed];
1740 if (installed != nil && [[package latest] compare:installed] != NSOrderedSame)
1741 [super addPackage:package];
1744 - (void) perform:(Package *)package {
1750 /* UninstallView {{{ */
1751 @interface UninstallView : PackagesView {
1754 - (NSString *) title;
1755 - (void) addPackage:(Package *)package;
1756 - (void) perform:(Package *)package;
1759 @implementation UninstallView
1761 - (NSString *) title {
1762 return @"Uninstall";
1765 - (void) addPackage:(Package *)package {
1766 if ([package installed] != nil)
1767 [super addPackage:package];
1770 - (void) perform:(Package *)package {
1777 @interface Cydia : UIApplication <
1778 ConfirmationViewDelegate,
1779 PackagesViewDelegate,
1780 ProgressViewDelegate
1785 UITransitionView *transition_;
1786 UIButtonBar *buttonbar_;
1788 UIAlertSheet *alert_;
1789 ConfirmationView *confirm_;
1791 Database *database_;
1792 ProgressView *progress_;
1795 UINavigationBar *navbar_;
1796 UIScroller *scroller_;
1797 UIWebView *webview_;
1800 InstallView *install_;
1801 UpgradeView *upgrade_;
1802 UninstallView *uninstall_;
1803 SourcesView *sources_;
1807 - (void) reloadData;
1813 - (void) progressViewIsComplete:(ProgressView *)progress;
1815 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
1816 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button;
1817 - (void) buttonBarItemTapped:(id)sender;
1819 - (void) view:(UIView *)sender didSetFrame:(CGRect)frame;
1820 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration;
1822 - (void) applicationDidFinishLaunching:(id)unused;
1825 #include <objc/objc-class.h>
1827 @implementation Cydia
1830 NSMutableURLRequest *request = [NSMutableURLRequest
1832 cachePolicy:NSURLRequestReloadIgnoringCacheData
1833 timeoutInterval:30.0
1836 [request addValue:[NSString stringWithCString:Machine_] forHTTPHeaderField:@"X-Machine"];
1837 [request addValue:[NSString stringWithCString:SerialNumber_] forHTTPHeaderField:@"X-Serial-Number"];
1839 [webview_ loadRequest:request];
1842 - (void) reloadData {
1843 [database_ reloadData];
1844 [install_ reloadData];
1845 [upgrade_ reloadData];
1846 [uninstall_ reloadData];
1847 [sources_ reloadData];
1851 confirm_ = [[ConfirmationView alloc] initWithView:underlay_ database:database_ delegate:self];
1860 [overlay_ removeFromSuperview];
1863 detachNewThreadSelector:@selector(perform)
1871 detachNewThreadSelector:@selector(update)
1877 - (void) progressViewIsComplete:(ProgressView *)progress {
1880 if (confirm_ != nil) {
1881 [underlay_ addSubview:overlay_];
1882 [confirm_ removeFromSuperview];
1888 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
1895 _assert(alert_ == nil);
1897 alert_ = [[UIAlertSheet alloc]
1898 initWithTitle:@"About Cydia Packager"
1899 buttons:[NSArray arrayWithObjects:@"Close", nil]
1900 defaultButtonIndex:0
1905 [alert_ setBodyText:
1906 @"Copyright (C) 2007\n"
1907 "Jay Freeman (saurik)\n"
1908 "saurik@saurik.com\n"
1909 "http://www.saurik.com/\n"
1912 "http://www.theokorigroup.com/\n"
1914 "College of Creative Studies,\n"
1915 "University of California,\n"
1917 "http://www.ccs.ucsb.edu/\n"
1920 "bad_, BHSPitMonkey, Cobra, core,\n"
1921 "Corona, cromas, Darken, dtzWill,\n"
1922 "francis, Godores, jerry, Kingstone,\n"
1923 "lounger, rockabilly, tman, Wbiggs"
1926 [alert_ presentSheetFromButtonBar:buttonbar_];
1931 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
1937 - (void) buttonBarItemTapped:(id)sender {
1940 switch ([sender tag]) {
1941 case 1: view = featured_; break;
1942 case 2: view = install_; break;
1943 case 3: view = upgrade_; break;
1944 case 4: view = uninstall_; break;
1945 case 5: view = sources_; break;
1951 if ([view respondsToSelector:@selector(resetView)])
1952 [(id) view resetView];
1953 [transition_ transition:0 toView:view];
1956 - (void) view:(UIView *)view didSetFrame:(CGRect)frame {
1957 [scroller_ setContentSize:frame.size];
1960 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration {
1961 [scroller_ setContentSize:[webview_ bounds].size];
1964 - (void) applicationDidFinishLaunching:(id)unused {
1965 _assert(pkgInitConfig(*_config));
1966 _assert(pkgInitSystem(*_config, _system));
1971 CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
1972 window_ = [[UIWindow alloc] initWithContentRect:screenrect];
1974 [window_ orderFront: self];
1975 [window_ makeKey: self];
1976 [window_ _setHidden: NO];
1978 progress_ = [[ProgressView alloc] initWithFrame:[window_ bounds] delegate:self];
1979 [window_ setContentView:progress_];
1981 underlay_ = [[UIView alloc] initWithFrame:[progress_ bounds]];
1982 [progress_ setContentView:underlay_];
1984 overlay_ = [[UIView alloc] initWithFrame:[underlay_ bounds]];
1985 [underlay_ addSubview:overlay_];
1987 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
1988 0, 0, screenrect.size.width, screenrect.size.height - 48
1991 [overlay_ addSubview:transition_];
1993 featured_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
1995 CGSize navsize = [UINavigationBar defaultSize];
1996 CGRect navrect = {{0, 0}, navsize};
1998 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1999 [featured_ addSubview:navbar_];
2001 [navbar_ setBarStyle:1];
2002 [navbar_ setDelegate:self];
2004 [navbar_ showButtonsWithLeftTitle:@"About" rightTitle:@"Reload"];
2006 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:@"Featured"];
2007 [navbar_ pushNavigationItem:navitem];
2009 struct CGRect subbounds = [featured_ bounds];
2010 subbounds.origin.y += navsize.height;
2011 subbounds.size.height -= navsize.height;
2013 UIImageView *pinstripe = [[UIImageView alloc] initWithFrame:subbounds];
2014 [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]];
2015 [featured_ addSubview:pinstripe];
2017 scroller_ = [[UIScroller alloc] initWithFrame:subbounds];
2018 [featured_ addSubview:scroller_];
2020 [scroller_ setScrollingEnabled:YES];
2021 [scroller_ setAdjustForContentSizeChange:YES];
2022 [scroller_ setClipsSubviews:YES];
2023 [scroller_ setAllowsRubberBanding:YES];
2024 [scroller_ setScrollDecelerationFactor:0.99];
2025 [scroller_ setDelegate:self];
2027 webview_ = [[UIWebView alloc] initWithFrame:[scroller_ bounds]];
2028 [scroller_ addSubview:webview_];
2030 [webview_ setTilingEnabled:YES];
2031 [webview_ setTileSize:CGSizeMake(screenrect.size.width, 500)];
2032 [webview_ setAutoresizes:YES];
2033 [webview_ setDelegate:self];
2035 NSArray *buttonitems = [NSArray arrayWithObjects:
2036 [NSDictionary dictionaryWithObjectsAndKeys:
2037 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
2038 @"featured-up.png", kUIButtonBarButtonInfo,
2039 @"featured-dn.png", kUIButtonBarButtonSelectedInfo,
2040 [NSNumber numberWithInt:1], kUIButtonBarButtonTag,
2041 self, kUIButtonBarButtonTarget,
2042 @"Featured", kUIButtonBarButtonTitle,
2043 @"0", kUIButtonBarButtonType,
2046 [NSDictionary dictionaryWithObjectsAndKeys:
2047 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
2048 @"install-up.png", kUIButtonBarButtonInfo,
2049 @"install-dn.png", kUIButtonBarButtonSelectedInfo,
2050 [NSNumber numberWithInt:2], kUIButtonBarButtonTag,
2051 self, kUIButtonBarButtonTarget,
2052 @"Install", kUIButtonBarButtonTitle,
2053 @"0", kUIButtonBarButtonType,
2056 [NSDictionary dictionaryWithObjectsAndKeys:
2057 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
2058 @"upgrade-up.png", kUIButtonBarButtonInfo,
2059 @"upgrade-dn.png", kUIButtonBarButtonSelectedInfo,
2060 [NSNumber numberWithInt:3], kUIButtonBarButtonTag,
2061 self, kUIButtonBarButtonTarget,
2062 @"Upgrade", kUIButtonBarButtonTitle,
2063 @"0", kUIButtonBarButtonType,
2066 [NSDictionary dictionaryWithObjectsAndKeys:
2067 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
2068 @"uninstall-up.png", kUIButtonBarButtonInfo,
2069 @"uninstall-dn.png", kUIButtonBarButtonSelectedInfo,
2070 [NSNumber numberWithInt:4], kUIButtonBarButtonTag,
2071 self, kUIButtonBarButtonTarget,
2072 @"Uninstall", kUIButtonBarButtonTitle,
2073 @"0", kUIButtonBarButtonType,
2076 [NSDictionary dictionaryWithObjectsAndKeys:
2077 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
2078 @"sources-up.png", kUIButtonBarButtonInfo,
2079 @"sources-dn.png", kUIButtonBarButtonSelectedInfo,
2080 [NSNumber numberWithInt:5], kUIButtonBarButtonTag,
2081 self, kUIButtonBarButtonTarget,
2082 @"Sources", kUIButtonBarButtonTitle,
2083 @"0", kUIButtonBarButtonType,
2087 buttonbar_ = [[UIButtonBar alloc]
2089 withFrame:CGRectMake(
2090 0, screenrect.size.height - 48,
2091 screenrect.size.width, 48
2093 withItemList:buttonitems
2096 [buttonbar_ setDelegate:self];
2097 [buttonbar_ setBarStyle:1];
2098 [buttonbar_ setButtonBarTrackingMode:2];
2100 int buttons[5] = {1, 2, 3, 4, 5};
2101 [buttonbar_ registerButtonGroup:0 withButtons:buttons withCount:5];
2102 [buttonbar_ showButtonGroup:0 withDuration:0];
2104 for (int i = 0; i != 5; ++i)
2105 [[buttonbar_ viewWithTag:(i + 1)] setFrame:CGRectMake(
2106 i * 64 + 2, 1, 60, 48
2109 [buttonbar_ showSelectionForButton:1];
2110 [transition_ transition:0 toView:featured_];
2112 [overlay_ addSubview:buttonbar_];
2114 database_ = [[Database alloc] init];
2115 [database_ setDelegate:progress_];
2117 install_ = [[InstallView alloc] initWithFrame:[transition_ bounds] database:database_];
2118 [install_ setDelegate:self];
2120 upgrade_ = [[UpgradeView alloc] initWithFrame:[transition_ bounds] database:database_];
2121 [upgrade_ setDelegate:self];
2123 uninstall_ = [[UninstallView alloc] initWithFrame:[transition_ bounds] database:database_];
2124 [uninstall_ setDelegate:self];
2126 sources_ = [[SourcesView alloc] initWithFrame:[transition_ bounds] database:database_];
2127 [sources_ setDelegate:self];
2131 UIAlertSheet *alert = [[UIAlertSheet alloc]
2132 initWithTitle:@"Alert Title"
2133 buttons:[NSArray arrayWithObjects:@"Yes", nil]
2134 defaultButtonIndex:0
2139 NSLog(@"%p\n", [alert table]);
2140 [[alert table] setDelegate:self];
2141 [[alert table] reloadData];
2143 [alert addTextFieldWithValue:@"Title" label:@"Label"];
2144 [alert setShowsOverSpringBoardAlerts:YES];
2145 [alert setBodyText:@"This is an alert."];
2146 [alert presentSheetFromButtonBar:buttonbar_];
2147 //[alert popupAlertAnimated:YES];
2152 [progress_ resetView];
2154 Package *package([database_ packageWithName:@"cydia"]);
2155 NSString *application = package == nil ? @"Cydia" : [NSString stringWithFormat:@"Cydia/%@", [package installed]];
2156 WebView *webview = [webview_ webView];
2157 [webview setApplicationNameForUserAgent:application];
2159 url_ = [NSURL URLWithString:@"http://cydia.saurik.com/"];
2165 int main(int argc, char *argv[]) {
2166 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
2169 sysctlbyname("hw.machine", NULL, &size, NULL, 0);
2170 char *machine = new char[size];
2171 sysctlbyname("hw.machine", machine, &size, NULL, 0);
2174 if (CFMutableDictionaryRef dict = IOServiceMatching("IOPlatformExpertDevice"))
2175 if (io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, dict)) {
2176 if (CFTypeRef serial = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)) {
2177 SerialNumber_ = strdup(CFStringGetCStringPtr((CFStringRef) serial, CFStringGetSystemEncoding()));
2181 IOObjectRelease(service);
2184 UIApplicationMain(argc, argv, [Cydia class]);