1 /* #include Directives {{{ */
2 #include <UIKit/UIKit.h>
3 #import <GraphicsServices/GraphicsServices.h>
5 #include <apt-pkg/acquire.h>
6 #include <apt-pkg/acquire-item.h>
7 #include <apt-pkg/algorithms.h>
8 #include <apt-pkg/cachefile.h>
9 #include <apt-pkg/configuration.h>
10 #include <apt-pkg/error.h>
11 #include <apt-pkg/init.h>
12 #include <apt-pkg/pkgrecords.h>
13 #include <apt-pkg/sourcelist.h>
18 /* Extension Keywords {{{ */
19 #define _trace() printf("_trace()@%s:%u[%s]\n", __FILE__, __LINE__, __FUNCTION__)
21 #define _assert(test) do \
23 printf("_assert(%s)@%s:%u[%s]\n", #test, __FILE__, __LINE__, __FUNCTION__); \
29 /* Status Delegation {{{ */
31 public pkgAcquireStatus
42 void setDelegate(id delegate) {
46 virtual bool MediaChange(std::string media, std::string drive) {
50 virtual void IMSHit(pkgAcquire::ItemDesc &item) {
51 [delegate_ performSelectorOnMainThread:@selector(setStatusIMSHit) withObject:nil waitUntilDone:YES];
54 virtual void Fetch(pkgAcquire::ItemDesc &item) {
55 [delegate_ performSelectorOnMainThread:@selector(setStatusFetch) withObject:nil waitUntilDone:YES];
58 virtual void Done(pkgAcquire::ItemDesc &item) {
59 [delegate_ performSelectorOnMainThread:@selector(setStatusDone) withObject:nil waitUntilDone:YES];
62 virtual void Fail(pkgAcquire::ItemDesc &item) {
63 [delegate_ performSelectorOnMainThread:@selector(setStatusFail) withObject:nil waitUntilDone:YES];
66 virtual bool Pulse(pkgAcquire *Owner) {
67 [delegate_ performSelectorOnMainThread:@selector(setStatusPulse) withObject:nil waitUntilDone:YES];
71 virtual void Start() {
72 [delegate_ performSelectorOnMainThread:@selector(setStatusStart) withObject:nil waitUntilDone:YES];
76 [delegate_ performSelectorOnMainThread:@selector(setStatusStop) withObject:nil waitUntilDone:YES];
80 /* Progress Delegation {{{ */
88 virtual void Update() {
89 printf("Update(): %f (%s)\n", Percent, Op.c_str());
98 void setDelegate(id delegate) {
102 virtual void Done() {
108 /* External Constants {{{ */
109 extern NSString *kUIButtonBarButtonAction;
110 extern NSString *kUIButtonBarButtonInfo;
111 extern NSString *kUIButtonBarButtonInfoOffset;
112 extern NSString *kUIButtonBarButtonSelectedInfo;
113 extern NSString *kUIButtonBarButtonStyle;
114 extern NSString *kUIButtonBarButtonTag;
115 extern NSString *kUIButtonBarButtonTarget;
116 extern NSString *kUIButtonBarButtonTitle;
117 extern NSString *kUIButtonBarButtonTitleVerticalHeight;
118 extern NSString *kUIButtonBarButtonTitleWidth;
119 extern NSString *kUIButtonBarButtonType;
121 /* Mime Addresses {{{ */
122 @interface Address : NSObject {
128 - (NSString *) email;
130 + (Address *) addressWithString:(NSString *)string;
131 - (Address *) initWithString:(NSString *)string;
134 @implementation Address
136 - (NSString *) name {
140 - (NSString *) email {
144 + (Address *) addressWithString:(NSString *)string {
145 return [[[Address alloc] initWithString:string] retain];
148 - (Address *) initWithString:(NSString *)string {
149 if ((self = [super init]) != nil) {
153 pcre *code = pcre_compile("^\"?(.*)\"? <([^>]*)>$", 0, &error, &offset, NULL);
156 printf("%d:%s\n", offset, error);
160 pcre_extra *study = NULL;
162 pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture);
164 size_t size = [string length];
165 const char *data = [string UTF8String];
167 int matches[(capture + 1) * 3];
168 pcre_exec(code, study, data, size, 0, 0, matches, sizeof(matches) / sizeof(matches[0]));
170 name_ = [[NSString stringWithCString:(data + matches[2]) length:(matches[3] - matches[2])] retain];
171 email_ = [[NSString stringWithCString:(data + matches[4]) length:(matches[5] - matches[4])] retain];
178 /* Right Alignment {{{ */
179 @interface UIRightTextLabel : UITextLabel {
180 float _savedRightEdgeX;
181 BOOL _sizedtofit_flag;
184 - (void) setFrame:(CGRect)frame;
185 - (void) setText:(NSString *)text;
186 - (void) realignText;
189 @implementation UIRightTextLabel
191 - (void) setFrame:(CGRect)frame {
192 [super setFrame:frame];
193 if (_sizedtofit_flag == NO) {
194 _savedRightEdgeX = frame.origin.x;
199 - (void) setText:(NSString *)text {
200 [super setText:text];
204 - (void) realignText {
205 CGRect oldFrame = [self frame];
207 _sizedtofit_flag = YES;
208 [self sizeToFit]; // shrink down size so I can right align it
210 CGRect newFrame = [self frame];
212 oldFrame.origin.x = _savedRightEdgeX - newFrame.size.width;
213 oldFrame.size.width = newFrame.size.width;
214 [super setFrame:oldFrame];
215 _sizedtofit_flag = NO;
221 @interface Database : NSObject {
223 pkgRecords *records_;
224 pkgProblemResolver *resolver_;
231 - (pkgCacheFile &) cache;
232 - (pkgRecords *) records;
233 - (pkgProblemResolver *) resolver;
237 - (void) setDelegate:(id)delegate;
240 /* Package Class {{{ */
241 @interface Package : NSObject {
242 pkgCache::PkgIterator iterator_;
245 pkgRecords::Parser *parser_;
246 pkgCache::VerIterator version_;
247 pkgCache::VerFileIterator file_;
250 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file;
251 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database;
254 - (NSString *) section;
256 - (NSString *) version;
257 - (Address *) maintainer;
259 - (NSString *) tagline;
260 - (NSString *) description;
261 - (UITableCell *) cell;
262 - (void) setCell:(UITableCell *)cell;
263 - (NSComparisonResult) compareBySectionAndName:(Package *)package;
269 @implementation Package
271 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file {
272 if ((self = [super init]) != nil) {
273 iterator_ = iterator;
274 database_ = database;
279 parser_ = &[database_ records]->Lookup(file);
283 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database {
284 for (pkgCache::VerIterator version = iterator.VersionList(); !version.end(); ++version)
285 for (pkgCache::VerFileIterator file = version.FileList(); !file.end(); ++file)
286 return [[Package alloc] initWithIterator:iterator database:database version:version file:file];
290 - (NSString *) name {
291 return [NSString stringWithCString:iterator_.Name()];
294 - (NSString *) section {
295 return [NSString stringWithCString:iterator_.Section()];
299 return iterator_->CurrentState != pkgCache::State::NotInstalled;
302 - (NSString *) version {
303 return [NSString stringWithCString:version_.VerStr()];
306 - (Address *) maintainer {
307 return [Address addressWithString:[NSString stringWithCString:parser_->Maintainer().c_str()]];
311 return version_->InstalledSize;
314 - (NSString *) tagline {
315 return [NSString stringWithCString:parser_->ShortDesc().c_str()];
318 - (NSString *) description {
319 return [NSString stringWithCString:parser_->LongDesc().c_str()];
322 - (UITableCell *) cell {
326 - (void) setCell:(UITableCell *)cell {
330 - (NSComparisonResult) compareBySectionAndName:(Package *)package {
331 NSComparisonResult result = [[self section] compare:[package section]];
332 if (result != NSOrderedSame)
334 return [[self name] compare:[package name]];
338 pkgProblemResolver *resolver = [database_ resolver];
339 resolver->Clear(iterator_);
340 resolver->Protect(iterator_);
341 [database_ cache]->MarkInstall(iterator_, false);
345 pkgProblemResolver *resolver = [database_ resolver];
346 resolver->Clear(iterator_);
347 resolver->Protect(iterator_);
348 resolver->Remove(iterator_);
349 [database_ cache]->MarkDelete(iterator_, false);
354 /* Section Class {{{ */
355 @interface Section : NSObject {
358 NSMutableArray *packages_;
361 - (Section *) initWithName:(NSString *)name row:(size_t)row;
364 - (void) addPackage:(Package *)package;
367 @implementation Section
369 - (Section *) initWithName:(NSString *)name row:(size_t)row {
370 if ((self = [super init]) != nil) {
371 name_ = [name retain];
373 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
377 - (NSString *) name {
385 - (void) addPackage:(Package *)package {
386 [packages_ addObject:package];
392 /* Confirmation View {{{ */
393 @interface ConfirmationView : UIView {
398 @implementation ConfirmationView
401 /* Package View {{{ */
402 @interface PackageView : UIPreferencesTable {
405 NSMutableArray *cells_;
408 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table;
409 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group;
410 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group;
412 - (PackageView *) initWithFrame:(struct CGRect)frame database:(Database *)database;
413 - (void) setPackage:(Package *)package;
416 @implementation PackageView
418 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table {
422 - (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group {
429 return @"Description";
432 default: _assert(false);
436 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group {
446 default: _assert(false);
450 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group {
451 UIPreferencesTableCell *cell;
454 case 0: switch (row) {
456 cell = [cells_ objectAtIndex:0];
457 [cell setTitle:@"Name"];
458 [cell setValue:[package_ name]];
462 cell = [cells_ objectAtIndex:1];
463 [cell setTitle:@"Version"];
464 [cell setValue:[package_ version]];
468 cell = [cells_ objectAtIndex:2];
469 [cell setTitle:@"Section"];
470 [cell setValue:[package_ section]];
474 double size = [package_ size];
476 while (size > 1024) {
481 cell = [cells_ objectAtIndex:3];
482 [cell setTitle:@"Size"];
483 [cell setValue:[NSString stringWithFormat:@"%.1f%c", size, "bkMG"[power]]];
487 cell = [cells_ objectAtIndex:4];
488 [cell setTitle:@"Maintainer"];
489 [cell setValue:[[package_ maintainer] name]];
490 [cell setShowDisclosure:YES];
491 [cell setShowSelection:YES];
494 default: _assert(false);
497 case 1: switch (row) {
499 cell = [cells_ objectAtIndex:5];
500 [cell setTitle:@"Tagline"];
501 [cell setValue:[package_ tagline]];
505 cell = [cells_ objectAtIndex:6];
506 [cell setTitle:@"Description"];
507 [cell setValue:[package_ description]];
511 default: _assert(false);
517 - (PackageView *) initWithFrame:(struct CGRect)frame database:(Database *)database {
518 if ((self = [super initWithFrame:frame]) != nil) {
519 database_ = database;
520 [self setDataSource:self];
522 cells_ = [[NSMutableArray arrayWithCapacity:16] retain];
524 for (unsigned i = 0; i != 6; ++i) {
525 struct CGRect frame = [self frameOfPreferencesCellAtRow:0 inGroup:0];
526 UIPreferencesTableCell *cell = [[UIPreferencesTableCell alloc] init];
527 [cell setShowSelection:NO];
528 [cells_ addObject:cell];
533 - (void) setPackage:(Package *)package {
541 @implementation Database
543 - (Database *) init {
544 if ((self = [super init]) != nil) {
550 - (pkgCacheFile &) cache {
554 - (pkgRecords *) records {
558 - (pkgProblemResolver *) resolver {
562 - (void) reloadData {
566 cache_.Open(progress_, true);
567 records_ = new pkgRecords(cache_);
568 resolver_ = new pkgProblemResolver(cache_);
572 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
575 _assert(list.ReadMainList());
578 lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
579 _assert(!_error->PendingError());
581 pkgAcquire fetcher(&status_);
582 _assert(list.GetIndexes(&fetcher));
583 _assert(fetcher.Run() != pkgAcquire::Failed);
586 for (pkgAcquire::ItemIterator item = fetcher.ItemsBegin(); item != fetcher.ItemsEnd(); item++)
587 if ((*item)->Status != pkgAcquire::Item::StatDone) {
592 if (!failed && _config->FindB("APT::Get::List-Cleanup", true) == true) {
593 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists")));
594 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/"));
601 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
603 _assert(cache_->DelCount() == 0 && cache_->InstCount() == 0);
604 _assert(pkgApplyStatus(cache_));
606 if (cache_->BrokenCount() != 0) {
607 _assert(pkgFixBroken(cache_));
608 _assert(cache_->BrokenCount() == 0);
609 _assert(pkgMinimizeUpgrade(cache_));
612 _assert(pkgDistUpgrade(cache_));
614 //InstallPackages(cache_, true);
619 - (void) setDelegate:(id)delegate {
620 status_.setDelegate(delegate);
621 progress_.setDelegate(delegate);
626 /* Progress Data {{{ */
627 @interface ProgressData : NSObject {
633 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object;
640 @implementation ProgressData
642 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object {
643 if ((self = [super init]) != nil) {
644 selector_ = selector;
665 @interface ProgressView : UIView {
667 UITransitionView *transition_;
669 UINavigationBar *navbar_;
672 - (ProgressView *) initWithFrame:(struct CGRect)frame;
673 - (void) setContentView:(UIView *)view;
676 - (void) _detachNewThreadData:(ProgressData *)data;
677 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object;
679 - (void) setStatusIMSHit;
680 - (void) setStatusFetch;
681 - (void) setStatusDone;
682 - (void) setStatusFail;
683 - (void) setStatusPulse;
685 - (void) setStatusStart;
686 - (void) setStatusStop;
689 @implementation ProgressView
691 - (ProgressView *) initWithFrame:(struct CGRect)frame {
692 if ((self = [super initWithFrame:frame]) != nil) {
693 transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
694 [self addSubview:transition_];
696 progress_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
698 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
699 float black[] = {0.0, 0.0, 0.0, 1.0};
700 [progress_ setBackgroundColor:CGColorCreate(space, black)];
702 CGSize navsize = [UINavigationBar defaultSize];
703 CGRect navrect = {{0, 0}, navsize};
705 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
706 [progress_ addSubview:navbar_];
708 [navbar_ setBarStyle:1];
709 [navbar_ setDelegate:self];
711 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:nil];
712 [navbar_ pushNavigationItem:navitem];
716 - (void) setContentView:(UIView *)view {
721 [transition_ transition:6 toView:view_];
724 - (void) _detachNewThreadData:(ProgressData *)data {
725 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
727 [[data target] performSelector:[data selector] withObject:[data object]];
728 [self performSelectorOnMainThread:@selector(resetView) withObject:nil waitUntilDone:YES];
733 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object {
734 [transition_ transition:6 toView:progress_];
737 detachNewThreadSelector:@selector(_detachNewThreadData:)
739 withObject:[[ProgressData alloc]
740 initWithSelector:selector
747 - (void) setStatusIMSHit {
751 - (void) setStatusFetch {
755 - (void) setStatusDone {
759 - (void) setStatusFail {
763 - (void) setStatusPulse {
767 - (void) setStatusStart {
771 - (void) setStatusStop {
777 @protocol PackagesDelegate
779 - (void) viewPackage:(Package *)package;
783 @interface Packages : UIView {
786 bool (*filter_)(Package *package);
787 NSMutableArray *packages_;
788 NSMutableArray *sections_;
790 UISectionList *list_;
791 UINavigationBar *navbar_;
792 UITransitionView *transition_;
794 PackageView *pkgview_;
798 - (int) numberOfSectionsInSectionList:(UISectionList *)list;
799 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section;
800 - (int) sectionList:(UISectionList *)list rowForSection:(int)section;
802 - (int) numberOfRowsInTable:(UITable *)table;
803 - (float) table:(UITable *)table heightForRow:(int)row;
804 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col;
805 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row;
806 - (void) tableRowSelected:(NSNotification*)notification;
808 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
809 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item;
811 - (Packages *) initWithFrame:(struct CGRect)frame title:(NSString *)title database:(Database *)database filter:(bool (*)(Package *))filter selector:(SEL)selector;
812 - (void) setDelegate:(id)delegate;
813 - (void) addPackage:(Package *)package;
814 - (NSMutableArray *) packages;
818 @implementation Packages
820 - (int) numberOfSectionsInSectionList:(UISectionList *)list {
821 return [sections_ count];
824 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section {
825 return [[sections_ objectAtIndex:section] name];
828 - (int) sectionList:(UISectionList *)list rowForSection:(int)section {
829 return [[sections_ objectAtIndex:section] row];
832 - (int) numberOfRowsInTable:(UITable *)table {
833 return [packages_ count];
836 - (float) table:(UITable *)table heightForRow:(int)row {
840 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col {
841 Package *package = [packages_ objectAtIndex:row]; {
842 UITableCell *cell = [package cell];
848 UIImageAndTextTableCell *cell_ = [[UIImageAndTextTableCell alloc] init];
849 [package setCell:cell_];
851 [cell_ setTitle:[package name]];
855 UITableCell *cell = [[UITableCell alloc] init];
856 [package setCell:cell];
858 GSFontRef bold = GSFontCreateWithName("Helvetica", kGSFontTraitBold, 22);
859 GSFontRef large = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 16);
860 GSFontRef small = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 14);
862 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
863 float blue[] = {0.2, 0.2, 1.0, 1.0};
864 float gray[] = {0.4, 0.4, 0.4, 1.0};
865 float clear[] = {0, 0, 0, 0};
867 UITextLabel *name = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 7, 250, 25)];
868 [name setText:[package name]];
869 [name setBackgroundColor:CGColorCreate(space, clear)];
872 UIRightTextLabel *version = [[UIRightTextLabel alloc] initWithFrame:CGRectMake(290, 7, 70, 25)];
873 [version setText:[package version]];
874 [version setColor:CGColorCreate(space, blue)];
875 [version setBackgroundColor:CGColorCreate(space, clear)];
876 [version setFont:large];
878 UITextLabel *description = [[UITextLabel alloc] initWithFrame:CGRectMake(13, 35, 315, 20)];
879 [description setText:[package tagline]];
880 [description setColor:CGColorCreate(space, gray)];
881 [description setBackgroundColor:CGColorCreate(space, clear)];
882 [description setFont:small];
884 [cell addSubview:name];
885 [cell addSubview:version];
886 [cell addSubview:description];
895 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row {
899 - (void) tableRowSelected:(NSNotification*)notification {
900 int row = [[list_ table] selectedRow];
904 package_ = [packages_ objectAtIndex:row];
906 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:[package_ name]];
907 [navbar_ pushNavigationItem:navitem];
909 [navbar_ showButtonsWithLeftTitle:nil rightTitle:title_];
911 [pkgview_ setPackage:package_];
912 [transition_ transition:1 toView:pkgview_];
916 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
918 printf("bef:%ld\n", [database_ cache]->InstCount());
919 [package_ performSelector:selector_];
921 pkgProblemResolver *resolver = [database_ resolver];
923 resolver->InstallProtect();
924 if (!resolver->Resolve(true))
927 printf("aft:%ld\n", [database_ cache]->InstCount());
932 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item {
933 [transition_ transition:2 toView:list_];
934 [navbar_ showButtonsWithLeftTitle:nil rightTitle:nil];
935 UITable *table = [list_ table];
936 [table selectRow:-1 byExtendingSelection:NO withFade:YES];
937 //UITableCell *cell = [table cellAtRow:[table selectedRow] column:0];
938 //[table selectCell:nil inRow:-1 column:-1 withFade:YES];
939 //[table highlightRow:-1];
940 //[cell setSelected:NO withFade:YES];
944 - (Packages *) initWithFrame:(struct CGRect)frame title:(NSString *)title database:(Database *)database filter:(bool (*)(Package *))filter selector:(SEL)selector {
945 if ((self = [super initWithFrame:frame]) != nil) {
947 database_ = database;
949 selector_ = selector;
951 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
953 struct CGRect bounds = [self bounds];
954 CGSize navsize = [UINavigationBar defaultSize];
955 CGRect navrect = {{0, 0}, navsize};
957 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
958 [self addSubview:navbar_];
960 [navbar_ setBarStyle:1];
961 [navbar_ setDelegate:self];
963 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:title];
964 [navbar_ pushNavigationItem:navitem];
965 [navitem setBackButtonTitle:@"Packages"];
967 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
968 bounds.origin.x, bounds.origin.y + navsize.height, bounds.size.width, bounds.size.height - navsize.height
971 [self addSubview:transition_];
973 list_ = [[UISectionList alloc] initWithFrame:[transition_ bounds] showSectionIndex:NO];
974 [list_ setDataSource:self];
976 [transition_ transition:0 toView:list_];
978 UITableColumn *column = [[UITableColumn alloc]
979 initWithTitle:@"Name"
981 width:frame.size.width
984 UITable *table = [list_ table];
985 [table setSeparatorStyle:1];
986 [table addTableColumn:column];
987 [table setDelegate:self];
989 pkgview_ = [[PackageView alloc] initWithFrame:[transition_ bounds] database:database_];
993 - (void) setDelegate:(id)delegate {
994 delegate_ = delegate;
997 - (void) addPackage:(Package *)package {
998 _assert(sections_ == nil);
999 [packages_ addObject:package];
1002 - (NSMutableArray *) packages {
1006 - (void) reloadData {
1007 for (pkgCache::PkgIterator iterator = [database_ cache]->PkgBegin(); !iterator.end(); ++iterator) {
1008 Package *package = [Package packageWithIterator:iterator database:database_];
1011 if (filter_(package))
1012 [self addPackage:package];
1015 [packages_ sortUsingSelector:@selector(compareBySectionAndName:)];
1016 sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
1018 Section *section = nil;
1019 for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
1020 Package *package = [packages_ objectAtIndex:offset];
1021 NSString *name = [package section];
1023 if (section == nil || ![[section name] isEqual:name]) {
1024 section = [[Section alloc] initWithName:name row:offset];
1025 [sections_ addObject:section];
1028 [section addPackage:package];
1036 bool IsInstalled(Package *package) {
1037 return [package installed];
1040 bool IsNotInstalled(Package *package) {
1041 return ![package installed];
1044 @interface Cydia : UIApplication <PackagesDelegate> {
1046 UITransitionView *transition_;
1048 Database *database_;
1049 ProgressView *progress_;
1052 UINavigationBar *navbar_;
1053 UIScroller *scroller_;
1054 UIWebView *webview_;
1058 Packages *uninstall_;
1062 - (void) reloadData;
1064 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
1065 - (void) buttonBarItemTapped:(id)sender;
1067 - (void) view:(UIView *)sender didSetFrame:(CGRect)frame;
1068 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration;
1070 - (void) viewPackage:(Package *)package;
1072 - (void) applicationDidFinishLaunching:(id)unused;
1075 @implementation Cydia
1078 [webview_ loadRequest:[NSURLRequest
1080 cachePolicy:NSURLRequestReloadIgnoringCacheData
1081 timeoutInterval:30.0
1085 - (void) reloadData {
1086 [database_ reloadData];
1087 [install_ reloadData];
1088 [uninstall_ reloadData];
1091 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
1102 - (void) buttonBarItemTapped:(id)sender {
1105 switch ([sender tag]) {
1106 case 1: view = featured_; break;
1107 case 2: view = install_; break;
1108 case 4: view = uninstall_; break;
1114 [transition_ transition:0 toView:view];
1117 - (void) view:(UIView *)view didSetFrame:(CGRect)frame {
1118 [scroller_ setContentSize:frame.size];
1121 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration {
1122 [scroller_ setContentSize:[webview_ bounds].size];
1125 - (void) viewPackage:(Package *)package {
1129 - (void) applicationDidFinishLaunching:(id)unused {
1130 _assert(pkgInitConfig(*_config));
1131 _assert(pkgInitSystem(*_config, _system));
1133 CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
1134 window_ = [[UIWindow alloc] initWithContentRect:screenrect];
1136 [window_ orderFront: self];
1137 [window_ makeKey: self];
1138 [window_ _setHidden: NO];
1140 progress_ = [[ProgressView alloc] initWithFrame:[window_ bounds]];
1141 [database_ setDelegate:progress_];
1142 [window_ setContentView:progress_];
1144 UIView *view = [[UIView alloc] initWithFrame:[progress_ bounds]];
1145 [progress_ setContentView:view];
1147 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
1148 0, 0, screenrect.size.width, screenrect.size.height - 48
1151 [view addSubview:transition_];
1153 featured_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
1155 CGSize navsize = [UINavigationBar defaultSize];
1156 CGRect navrect = {{0, 0}, navsize};
1158 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1159 [featured_ addSubview:navbar_];
1161 [navbar_ setBarStyle:1];
1162 [navbar_ setDelegate:self];
1164 [navbar_ showButtonsWithLeftTitle:@"About" rightTitle:@"Reload"];
1166 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:@"Featured"];
1167 [navbar_ pushNavigationItem:navitem];
1169 struct CGRect subbounds = [featured_ bounds];
1170 subbounds.origin.y += navsize.height;
1171 subbounds.size.height -= navsize.height;
1173 UIImageView *pinstripe = [[UIImageView alloc] initWithFrame:subbounds];
1174 [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]];
1175 [featured_ addSubview:pinstripe];
1177 scroller_ = [[UIScroller alloc] initWithFrame:subbounds];
1178 [featured_ addSubview:scroller_];
1180 [scroller_ setScrollingEnabled:YES];
1181 [scroller_ setAdjustForContentSizeChange:YES];
1182 [scroller_ setClipsSubviews:YES];
1183 [scroller_ setAllowsRubberBanding:YES];
1184 [scroller_ setScrollDecelerationFactor:0.99];
1185 [scroller_ setDelegate:self];
1187 webview_ = [[UIWebView alloc] initWithFrame:[scroller_ bounds]];
1188 [scroller_ addSubview:webview_];
1190 [webview_ setTilingEnabled:YES];
1191 [webview_ setTileSize:CGSizeMake(screenrect.size.width, 500)];
1192 [webview_ setAutoresizes:YES];
1193 [webview_ setDelegate:self];
1195 url_ = [NSURL URLWithString:@"http://cydia.saurik.com/"];
1198 NSArray *buttonitems = [NSArray arrayWithObjects:
1199 [NSDictionary dictionaryWithObjectsAndKeys:
1200 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1201 @"featured-up.png", kUIButtonBarButtonInfo,
1202 @"featured-dn.png", kUIButtonBarButtonSelectedInfo,
1203 [NSNumber numberWithInt:1], kUIButtonBarButtonTag,
1204 self, kUIButtonBarButtonTarget,
1205 @"Featured", kUIButtonBarButtonTitle,
1206 @"0", kUIButtonBarButtonType,
1209 [NSDictionary dictionaryWithObjectsAndKeys:
1210 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1211 @"install-up.png", kUIButtonBarButtonInfo,
1212 @"install-dn.png", kUIButtonBarButtonSelectedInfo,
1213 [NSNumber numberWithInt:2], kUIButtonBarButtonTag,
1214 self, kUIButtonBarButtonTarget,
1215 @"Install", kUIButtonBarButtonTitle,
1216 @"0", kUIButtonBarButtonType,
1219 [NSDictionary dictionaryWithObjectsAndKeys:
1220 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1221 @"upgrade-up.png", kUIButtonBarButtonInfo,
1222 @"upgrade-dn.png", kUIButtonBarButtonSelectedInfo,
1223 [NSNumber numberWithInt:3], kUIButtonBarButtonTag,
1224 self, kUIButtonBarButtonTarget,
1225 @"Upgrade", kUIButtonBarButtonTitle,
1226 @"0", kUIButtonBarButtonType,
1229 [NSDictionary dictionaryWithObjectsAndKeys:
1230 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1231 @"uninstall-up.png", kUIButtonBarButtonInfo,
1232 @"uninstall-dn.png", kUIButtonBarButtonSelectedInfo,
1233 [NSNumber numberWithInt:4], kUIButtonBarButtonTag,
1234 self, kUIButtonBarButtonTarget,
1235 @"Uninstall", kUIButtonBarButtonTitle,
1236 @"0", kUIButtonBarButtonType,
1239 [NSDictionary dictionaryWithObjectsAndKeys:
1240 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1241 @"sources-up.png", kUIButtonBarButtonInfo,
1242 @"sources-dn.png", kUIButtonBarButtonSelectedInfo,
1243 [NSNumber numberWithInt:5], kUIButtonBarButtonTag,
1244 self, kUIButtonBarButtonTarget,
1245 @"Sources", kUIButtonBarButtonTitle,
1246 @"0", kUIButtonBarButtonType,
1250 UIButtonBar *buttonbar = [[UIButtonBar alloc]
1252 withFrame:CGRectMake(
1253 0, screenrect.size.height - 48,
1254 screenrect.size.width, 48
1256 withItemList:buttonitems
1259 [buttonbar setDelegate:self];
1260 [buttonbar setBarStyle:1];
1261 [buttonbar setButtonBarTrackingMode:2];
1263 int buttons[5] = {1, 2, 3, 4, 5};
1264 [buttonbar registerButtonGroup:0 withButtons:buttons withCount:5];
1265 [buttonbar showButtonGroup:0 withDuration:0];
1267 for (int i = 0; i != 5; ++i)
1268 [[buttonbar viewWithTag:(i + 1)] setFrame:CGRectMake(
1269 i * 64 + 2, 1, 60, 48
1272 [buttonbar showSelectionForButton:1];
1273 [transition_ transition:0 toView:featured_];
1275 [view addSubview:buttonbar];
1277 database_ = [[Database alloc] init];
1279 install_ = [[Packages alloc] initWithFrame:[transition_ bounds] title:@"Install" database:database_ filter:&IsNotInstalled selector:@selector(install)];
1280 [install_ setDelegate:self];
1282 uninstall_ = [[Packages alloc] initWithFrame:[transition_ bounds] title:@"Uninstall" database:database_ filter:&IsInstalled selector:@selector(remove)];
1283 [uninstall_ setDelegate:self];
1286 UIAlertSheet *alert = [[UIAlertSheet alloc]
1287 initWithTitle:@"Alert Title"
1288 buttons:[NSArray arrayWithObjects:@"Yes", nil]
1289 defaultButtonIndex:0
1294 NSLog(@"%p\n", [alert table]);
1295 [[alert table] setDelegate:self];
1296 [[alert table] reloadData];
1298 [alert addTextFieldWithValue:@"Title" label:@"Label"];
1299 [alert setShowsOverSpringBoardAlerts:YES];
1300 [alert setBodyText:@"This is an alert."];
1301 [alert presentSheetFromButtonBar:buttonbar];
1302 //[alert popupAlertAnimated:YES];
1306 [progress_ resetView];
1307 //[progress_ detachNewThreadSelector:@selector(reloadData) toTarget:self withObject:nil];
1312 int main(int argc, char *argv[]) {
1313 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1314 UIApplicationMain(argc, argv, [Cydia class]);