1 /* #include Directives {{{ */
2 #include <UIKit/UIKit.h>
3 #import <GraphicsServices/GraphicsServices.h>
6 #include <ext/stdio_filebuf.h>
8 #include <apt-pkg/acquire.h>
9 #include <apt-pkg/acquire-item.h>
10 #include <apt-pkg/algorithms.h>
11 #include <apt-pkg/cachefile.h>
12 #include <apt-pkg/configuration.h>
13 #include <apt-pkg/error.h>
14 #include <apt-pkg/init.h>
15 #include <apt-pkg/pkgrecords.h>
16 #include <apt-pkg/sourcelist.h>
17 #include <apt-pkg/sptr.h>
23 /* Extension Keywords {{{ */
24 #define _trace() fprintf(stderr, "_trace()@%s:%u[%s]\n", __FILE__, __LINE__, __FUNCTION__)
26 #define _assert(test) do \
28 fprintf(stderr, "_assert(%d:%s)@%s:%u[%s]\n", errno, #test, __FILE__, __LINE__, __FUNCTION__); \
34 @protocol ProgressDelegate
35 - (void) setError:(NSString *)error;
36 - (void) setTitle:(NSString *)title;
37 - (void) setPercent:(float)percent;
38 - (void) addOutput:(NSString *)output;
41 /* Status Delegation {{{ */
43 public pkgAcquireStatus
54 void setDelegate(id delegate) {
58 virtual bool MediaChange(std::string media, std::string drive) {
62 virtual void IMSHit(pkgAcquire::ItemDesc &item) {
63 [delegate_ performSelectorOnMainThread:@selector(setStatusIMSHit) withObject:nil waitUntilDone:YES];
66 virtual void Fetch(pkgAcquire::ItemDesc &item) {
67 [delegate_ setTitle:[NSString stringWithCString:item.Description.c_str()]];
70 virtual void Done(pkgAcquire::ItemDesc &item) {
71 [delegate_ performSelectorOnMainThread:@selector(setStatusDone) withObject:nil waitUntilDone:YES];
74 virtual void Fail(pkgAcquire::ItemDesc &item) {
75 [delegate_ performSelectorOnMainThread:@selector(setStatusFail) withObject:nil waitUntilDone:YES];
78 virtual bool Pulse(pkgAcquire *Owner) {
79 bool value = pkgAcquireStatus::Pulse(Owner);
82 double(CurrentBytes + CurrentItems) /
83 double(TotalBytes + TotalItems)
86 [delegate_ setPercent:percent];
90 virtual void Start() {
97 /* Progress Delegation {{{ */
105 virtual void Update() {
106 [delegate_ setTitle:[NSString stringWithCString:Op.c_str()]];
107 [delegate_ setPercent:(Percent / 100)];
116 void setDelegate(id delegate) {
117 delegate_ = delegate;
120 virtual void Done() {
121 [delegate_ setPercent:1];
126 /* External Constants {{{ */
127 extern NSString *kUIButtonBarButtonAction;
128 extern NSString *kUIButtonBarButtonInfo;
129 extern NSString *kUIButtonBarButtonInfoOffset;
130 extern NSString *kUIButtonBarButtonSelectedInfo;
131 extern NSString *kUIButtonBarButtonStyle;
132 extern NSString *kUIButtonBarButtonTag;
133 extern NSString *kUIButtonBarButtonTarget;
134 extern NSString *kUIButtonBarButtonTitle;
135 extern NSString *kUIButtonBarButtonTitleVerticalHeight;
136 extern NSString *kUIButtonBarButtonTitleWidth;
137 extern NSString *kUIButtonBarButtonType;
139 /* Mime Addresses {{{ */
140 @interface Address : NSObject {
148 - (NSString *) email;
150 + (Address *) addressWithString:(NSString *)string;
151 - (Address *) initWithString:(NSString *)string;
154 @implementation Address
162 - (NSString *) name {
166 - (NSString *) email {
170 + (Address *) addressWithString:(NSString *)string {
171 return [[[Address alloc] initWithString:string] autorelease];
174 - (Address *) initWithString:(NSString *)string {
175 if ((self = [super init]) != nil) {
178 pcre *code = pcre_compile("^\"?(.*)\"? <([^>]*)>$", 0, &error, &offset, NULL);
181 fprintf(stderr, "%d:%s\n", offset, error);
185 pcre_extra *study = NULL;
187 pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture);
188 int matches[(capture + 1) * 3];
190 size_t size = [string length];
191 const char *data = [string UTF8String];
193 _assert(pcre_exec(code, study, data, size, 0, 0, matches, sizeof(matches) / sizeof(matches[0])) >= 0);
195 name_ = [[NSString stringWithCString:(data + matches[2]) length:(matches[3] - matches[2])] retain];
196 email_ = [[NSString stringWithCString:(data + matches[4]) length:(matches[5] - matches[4])] retain];
203 /* Right Alignment {{{ */
204 @interface UIRightTextLabel : UITextLabel {
205 float _savedRightEdgeX;
206 BOOL _sizedtofit_flag;
209 - (void) setFrame:(CGRect)frame;
210 - (void) setText:(NSString *)text;
211 - (void) realignText;
214 @implementation UIRightTextLabel
216 - (void) setFrame:(CGRect)frame {
217 [super setFrame:frame];
218 if (_sizedtofit_flag == NO) {
219 _savedRightEdgeX = frame.origin.x;
224 - (void) setText:(NSString *)text {
225 [super setText:text];
229 - (void) realignText {
230 CGRect oldFrame = [self frame];
232 _sizedtofit_flag = YES;
233 [self sizeToFit]; // shrink down size so I can right align it
235 CGRect newFrame = [self frame];
237 oldFrame.origin.x = _savedRightEdgeX - newFrame.size.width;
238 oldFrame.size.width = newFrame.size.width;
239 [super setFrame:oldFrame];
240 _sizedtofit_flag = NO;
245 /* Linear Algebra {{{ */
246 inline float interpolate(float begin, float end, float fraction) {
247 return (end - begin) * fraction + begin;
251 @interface Database : NSObject {
253 pkgRecords *records_;
254 pkgProblemResolver *resolver_;
263 - (pkgCacheFile &) cache;
264 - (pkgRecords *) records;
265 - (pkgProblemResolver *) resolver;
272 - (void) setDelegate:(id)delegate;
275 /* Package Class {{{ */
276 @interface Package : NSObject {
277 pkgCache::PkgIterator iterator_;
279 pkgRecords::Parser *parser_;
280 pkgCache::VerIterator version_;
281 pkgCache::VerFileIterator file_;
284 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file;
285 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database;
288 - (NSString *) section;
290 - (NSString *) version;
291 - (Address *) maintainer;
293 - (NSString *) tagline;
294 - (NSString *) description;
295 - (NSComparisonResult) compareBySectionAndName:(Package *)package;
301 @implementation Package
303 - (Package *) initWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database version:(pkgCache::VerIterator)version file:(pkgCache::VerFileIterator)file {
304 if ((self = [super init]) != nil) {
305 iterator_ = iterator;
306 database_ = database;
310 parser_ = &[database_ records]->Lookup(file);
314 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator database:(Database *)database {
315 for (pkgCache::VerIterator version = iterator.VersionList(); !version.end(); ++version)
316 for (pkgCache::VerFileIterator file = version.FileList(); !file.end(); ++file)
317 return [[[Package alloc]
318 initWithIterator:iterator
326 - (NSString *) name {
327 return [NSString stringWithCString:iterator_.Name()];
330 - (NSString *) section {
331 return [NSString stringWithCString:iterator_.Section()];
335 return iterator_->CurrentState != pkgCache::State::NotInstalled;
338 - (NSString *) version {
339 return [NSString stringWithCString:version_.VerStr()];
342 - (Address *) maintainer {
343 return [Address addressWithString:[NSString stringWithCString:parser_->Maintainer().c_str()]];
347 return version_->InstalledSize;
350 - (NSString *) tagline {
351 return [NSString stringWithCString:parser_->ShortDesc().c_str()];
354 - (NSString *) description {
355 return [NSString stringWithCString:parser_->LongDesc().c_str()];
358 - (NSComparisonResult) compareBySectionAndName:(Package *)package {
359 NSComparisonResult result = [[self section] compare:[package section]];
360 if (result != NSOrderedSame)
362 return [[self name] compare:[package name]];
366 pkgProblemResolver *resolver = [database_ resolver];
367 resolver->Clear(iterator_);
368 resolver->Protect(iterator_);
369 [database_ cache]->MarkInstall(iterator_, false);
373 pkgProblemResolver *resolver = [database_ resolver];
374 resolver->Clear(iterator_);
375 resolver->Protect(iterator_);
376 resolver->Remove(iterator_);
377 [database_ cache]->MarkDelete(iterator_, true);
382 /* Section Class {{{ */
383 @interface Section : NSObject {
386 NSMutableArray *packages_;
391 - (Section *) initWithName:(NSString *)name row:(size_t)row;
394 - (void) addPackage:(Package *)package;
397 @implementation Section
405 - (Section *) initWithName:(NSString *)name row:(size_t)row {
406 if ((self = [super init]) != nil) {
407 name_ = [name retain];
409 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
413 - (NSString *) name {
421 - (void) addPackage:(Package *)package {
422 [packages_ addObject:package];
428 /* Confirmation View {{{ */
429 @interface ConfirmationView : UIView {
434 @implementation ConfirmationView
437 /* Package View {{{ */
438 @interface PackageView : UIPreferencesTable {
441 NSMutableArray *cells_;
446 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table;
447 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group;
448 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group;
450 - (PackageView *) initWithFrame:(struct CGRect)frame database:(Database *)database;
451 - (void) setPackage:(Package *)package;
454 @implementation PackageView
464 - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table {
468 - (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group {
475 return @"Description";
478 default: _assert(false);
482 - (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group {
492 default: _assert(false);
496 - (UIPreferencesTableCell *) preferencesTable:(UIPreferencesTable *)table cellForRow:(int)row inGroup:(int)group {
497 UIPreferencesTableCell *cell;
500 case 0: switch (row) {
502 cell = [cells_ objectAtIndex:0];
503 [cell setTitle:@"Name"];
504 [cell setValue:[package_ name]];
508 cell = [cells_ objectAtIndex:1];
509 [cell setTitle:@"Version"];
510 [cell setValue:[package_ version]];
514 cell = [cells_ objectAtIndex:2];
515 [cell setTitle:@"Section"];
516 [cell setValue:[package_ section]];
520 double size = [package_ size];
522 while (size > 1024) {
527 cell = [cells_ objectAtIndex:3];
528 [cell setTitle:@"Size"];
529 [cell setValue:[NSString stringWithFormat:@"%.1f%c", size, "bkMG"[power]]];
533 cell = [cells_ objectAtIndex:4];
534 [cell setTitle:@"Maintainer"];
535 [cell setValue:[[package_ maintainer] name]];
536 [cell setShowDisclosure:YES];
537 [cell setShowSelection:YES];
540 default: _assert(false);
543 case 1: switch (row) {
545 cell = [cells_ objectAtIndex:5];
547 [cell setValue:[package_ tagline]];
551 cell = [cells_ objectAtIndex:6];
552 [cell setTitle:@"Description"];
553 [cell setValue:[package_ description]];
557 default: _assert(false);
563 - (PackageView *) initWithFrame:(struct CGRect)frame database:(Database *)database {
564 if ((self = [super initWithFrame:frame]) != nil) {
565 database_ = [database retain];
566 [self setDataSource:self];
568 cells_ = [[NSMutableArray arrayWithCapacity:16] retain];
570 for (unsigned i = 0; i != 6; ++i) {
571 struct CGRect frame = [self frameOfPreferencesCellAtRow:0 inGroup:0];
572 UIPreferencesTableCell *cell = [[[UIPreferencesTableCell alloc] init] autorelease];
573 [cell setShowSelection:NO];
574 [cells_ addObject:cell];
579 - (void) setPackage:(Package *)package {
580 package_ = [package retain];
586 /* Package Cell {{{ */
587 @interface PackageCell : UITableCell {
589 UIRightTextLabel *version_;
590 UITextLabel *description_;
595 - (PackageCell *) initWithPackage:(Package *)package;
597 - (void) _setSelected:(float)fraction;
598 - (void) setSelected:(BOOL)selected;
599 - (void) setSelected:(BOOL)selected withFade:(BOOL)fade;
600 - (void) _setSelectionFadeFraction:(float)fraction;
604 @implementation PackageCell
609 [description_ release];
613 - (PackageCell *) initWithPackage:(Package *)package {
614 if ((self = [super init]) != nil) {
615 GSFontRef bold = GSFontCreateWithName("Helvetica", kGSFontTraitBold, 22);
616 GSFontRef large = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 16);
617 GSFontRef small = GSFontCreateWithName("Helvetica", kGSFontTraitNone, 14);
619 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
620 float clear[] = {0, 0, 0, 0};
622 name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 7, 250, 25)];
623 [name_ setText:[package name]];
624 [name_ setBackgroundColor:CGColorCreate(space, clear)];
625 [name_ setFont:bold];
627 version_ = [[UIRightTextLabel alloc] initWithFrame:CGRectMake(290, 7, 70, 25)];
628 [version_ setText:[package version]];
629 [version_ setBackgroundColor:CGColorCreate(space, clear)];
630 [version_ setFont:large];
632 description_ = [[UITextLabel alloc] initWithFrame:CGRectMake(13, 35, 315, 20)];
633 [description_ setText:[package tagline]];
634 [description_ setBackgroundColor:CGColorCreate(space, clear)];
635 [description_ setFont:small];
637 [self addSubview:name_];
638 [self addSubview:version_];
639 [self addSubview:description_];
647 - (void) _setSelected:(float)fraction {
648 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
651 interpolate(0.0, 1.0, fraction),
652 interpolate(0.0, 1.0, fraction),
653 interpolate(0.0, 1.0, fraction),
657 interpolate(0.2, 1.0, fraction),
658 interpolate(0.2, 1.0, fraction),
659 interpolate(1.0, 1.0, fraction),
663 interpolate(0.4, 1.0, fraction),
664 interpolate(0.4, 1.0, fraction),
665 interpolate(0.4, 1.0, fraction),
668 [name_ setColor:CGColorCreate(space, black)];
669 [version_ setColor:CGColorCreate(space, blue)];
670 [description_ setColor:CGColorCreate(space, gray)];
673 - (void) setSelected:(BOOL)selected {
674 [self _setSelected:(selected ? 1.0 : 0.0)];
675 [super setSelected:selected];
678 - (void) setSelected:(BOOL)selected withFade:(BOOL)fade {
680 [self _setSelected:(selected ? 1.0 : 0.0)];
681 [super setSelected:selected withFade:fade];
684 - (void) _setSelectionFadeFraction:(float)fraction {
685 [self _setSelected:fraction];
686 [super _setSelectionFadeFraction:fraction];
692 @implementation Database
694 - (void) _readStatus:(NSNumber *)fd {
695 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
697 __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
698 std::istream is(&ib);
703 pcre *code = pcre_compile("^([^:]*):([^:]*):([^:]*):(.*)$", 0, &error, &offset, NULL);
705 pcre_extra *study = NULL;
707 pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture);
708 int matches[(capture + 1) * 3];
710 while (std::getline(is, line)) {
711 const char *data(line.c_str());
712 fprintf(stderr, "fd(%s)\n", data);
714 _assert(pcre_exec(code, study, data, line.size(), 0, 0, matches, sizeof(matches) / sizeof(matches[0])) >= 0);
716 std::string type(line.substr(matches[2], matches[3] - matches[2]));
718 std::istringstream buffer(line.substr(matches[6], matches[7] - matches[6]));
721 [delegate_ setPercent:(percent / 100)];
723 NSString *string = [NSString stringWithCString:(data + matches[8]) length:(matches[9] - matches[8])];
725 if (type == "pmerror")
726 [delegate_ setError:string];
727 else if (type == "pmstatus")
728 [delegate_ setTitle:string];
734 - (void) _readOutput:(NSNumber *)fd {
735 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
737 __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
738 std::istream is(&ib);
741 while (std::getline(is, line))
742 [delegate_ addOutput:[NSString stringWithCString:line.c_str()]];
747 - (Database *) init {
748 if ((self = [super init]) != nil) {
754 _assert(pipe(fds) != -1);
755 printf("%d %d\n", fds[0], fds[1]);
759 detachNewThreadSelector:@selector(_readStatus:)
761 withObject:[[NSNumber numberWithInt:fds[0]] retain]
764 _assert(pipe(fds) != -1);
765 printf("%d %d\n", fds[0], fds[1]);
766 _assert(dup2(fds[1], 1) != -1);
767 _assert(close(fds[1]) != -1);
770 detachNewThreadSelector:@selector(_readOutput:)
772 withObject:[[NSNumber numberWithInt:fds[0]] retain]
777 - (pkgCacheFile &) cache {
781 - (pkgRecords *) records {
785 - (pkgProblemResolver *) resolver {
789 - (void) reloadData {
799 cache_.Open(progress_, true);
801 records_ = new pkgRecords(cache_);
803 resolver_ = new pkgProblemResolver(cache_);
809 pkgRecords records(cache_);
813 lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
814 _assert(!_error->PendingError());
817 pkgAcquire fetcher(&status_);
819 _assert(list.ReadMainList());
822 SPtr<pkgPackageManager> manager(_system->CreatePM(cache_));
823 _assert(manager->GetArchives(&fetcher, &list, &records));
824 _assert(!_error->PendingError());
825 _assert(fetcher.Run() != pkgAcquire::Failed);
829 pkgPackageManager::OrderResult result = manager->DoInstall(statusfd_);
831 if (result == pkgPackageManager::Failed)
833 if (_error->PendingError())
835 if (result != pkgPackageManager::Completed)
841 _assert(list.ReadMainList());
844 lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
845 _assert(!_error->PendingError());
847 pkgAcquire fetcher(&status_);
848 _assert(list.GetIndexes(&fetcher));
849 _assert(fetcher.Run() != pkgAcquire::Failed);
852 for (pkgAcquire::ItemIterator item = fetcher.ItemsBegin(); item != fetcher.ItemsEnd(); item++)
853 if ((*item)->Status != pkgAcquire::Item::StatDone) {
858 if (!failed && _config->FindB("APT::Get::List-Cleanup", true) == true) {
859 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists")));
860 _assert(fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/"));
865 _assert(cache_->DelCount() == 0 && cache_->InstCount() == 0);
866 _assert(pkgApplyStatus(cache_));
868 if (cache_->BrokenCount() != 0) {
869 _assert(pkgFixBroken(cache_));
870 _assert(cache_->BrokenCount() == 0);
871 _assert(pkgMinimizeUpgrade(cache_));
874 _assert(pkgDistUpgrade(cache_));
876 //InstallPackages(cache_, true);
879 - (void) setDelegate:(id)delegate {
880 delegate_ = delegate;
881 status_.setDelegate(delegate);
882 progress_.setDelegate(delegate);
887 /* Progress Data {{{ */
888 @interface ProgressData : NSObject {
894 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object;
901 @implementation ProgressData
903 - (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object {
904 if ((self = [super init]) != nil) {
905 selector_ = selector;
925 /* Progress View {{{ */
926 @interface ProgressView : UIView <
930 UITransitionView *transition_;
932 UINavigationBar *navbar_;
933 UIProgressBar *progress_;
935 UITextLabel *status_;
937 UIAlertSheet *alert_;
942 - (ProgressView *) initWithFrame:(struct CGRect)frame delegate:(id)delegate;
943 - (void) setContentView:(UIView *)view;
946 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button;
948 - (void) _retachThread;
949 - (void) _detachNewThreadData:(ProgressData *)data;
950 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object;
952 - (void) setError:(NSString *)error;
953 - (void) _setError:(NSString *)error;
955 - (void) setTitle:(NSString *)title;
956 - (void) _setTitle:(NSString *)title;
958 - (void) setPercent:(float)percent;
959 - (void) _setPercent:(NSNumber *)percent;
961 - (void) addOutput:(NSString *)output;
962 - (void) _addOutput:(NSString *)output;
964 - (void) setStatusIMSHit;
965 - (void) setStatusDone;
966 - (void) setStatusFail;
968 - (void) setStatusStart;
969 - (void) setStatusStop;
972 @protocol ProgressViewDelegate
973 - (void) progressViewIsComplete:(ProgressView *)sender;
976 @implementation ProgressView
980 [transition_ release];
989 - (ProgressView *) initWithFrame:(struct CGRect)frame delegate:(id)delegate {
990 if ((self = [super initWithFrame:frame]) != nil) {
991 delegate_ = delegate;
994 transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
995 [self addSubview:transition_];
997 CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
998 float black[] = {0.0, 0.0, 0.0, 1.0};
999 float white[] = {1.0, 1.0, 1.0, 1.0};
1000 float clear[] = {0.0, 0.0, 0.0, 0.0};
1002 overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
1003 [overlay_ setBackgroundColor:CGColorCreate(space, black)];
1005 CGSize navsize = [UINavigationBar defaultSize];
1006 CGRect navrect = {{0, 0}, navsize};
1008 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1009 [overlay_ addSubview:navbar_];
1011 [navbar_ setBarStyle:1];
1012 [navbar_ setDelegate:self];
1014 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:@"Running..."] autorelease];
1015 [navbar_ pushNavigationItem:navitem];
1017 CGRect bounds = [overlay_ bounds];
1018 CGSize prgsize = [UIProgressBar defaultSize];
1021 (bounds.size.width - prgsize.width) / 2,
1022 bounds.size.height - prgsize.height - 20
1025 progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
1026 [overlay_ addSubview:progress_];
1028 status_ = [[UITextLabel alloc] initWithFrame:CGRectMake(
1030 bounds.size.height - prgsize.height - 50,
1031 bounds.size.width - 20,
1035 [status_ setColor:CGColorCreate(space, white)];
1036 [status_ setBackgroundColor:CGColorCreate(space, clear)];
1038 [status_ setCentersHorizontally:YES];
1040 output_ = [[UITextView alloc] initWithFrame:CGRectMake(
1042 navrect.size.height + 20,
1043 bounds.size.width - 20,
1044 bounds.size.height - navsize.height - 62 - navrect.size.height
1047 //[output_ setTextFont:@"Courier New"];
1048 [output_ setTextSize:12];
1050 [output_ setTextColor:CGColorCreate(space, white)];
1051 [output_ setBackgroundColor:CGColorCreate(space, clear)];
1053 [output_ setMarginTop:0];
1054 [output_ setAllowsRubberBanding:YES];
1056 [overlay_ addSubview:output_];
1057 [overlay_ addSubview:status_];
1059 [progress_ setStyle:0];
1063 - (void) setContentView:(UIView *)view {
1067 - (void) resetView {
1068 [transition_ transition:6 toView:view_];
1072 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
1078 - (void) _retachThread {
1080 [delegate_ progressViewIsComplete:self];
1086 - (void) _detachNewThreadData:(ProgressData *)data {
1087 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1090 [[data target] performSelector:[data selector] withObject:[data object]];
1092 [self performSelectorOnMainThread:@selector(_retachThread) withObject:nil waitUntilDone:YES];
1099 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object {
1100 [status_ setText:nil];
1101 [output_ setText:@""];
1102 [progress_ setProgress:0];
1104 [transition_ transition:6 toView:overlay_];
1107 detachNewThreadSelector:@selector(_detachNewThreadData:)
1109 withObject:[[ProgressData alloc]
1110 initWithSelector:selector
1117 - (void) setStatusIMSHit {
1121 - (void) setStatusDone {
1125 - (void) setStatusFail {
1129 - (void) setError:(NSString *)error {
1131 performSelectorOnMainThread:@selector(_setError:)
1137 - (void) _setError:(NSString *)error {
1138 _assert(alert_ == nil);
1140 alert_ = [[UIAlertSheet alloc]
1141 initWithTitle:@"Package Error"
1142 buttons:[NSArray arrayWithObjects:@"Okay", nil]
1143 defaultButtonIndex:0
1148 [alert_ setBodyText:error];
1149 [alert_ popupAlertAnimated:YES];
1152 - (void) setTitle:(NSString *)title {
1154 performSelectorOnMainThread:@selector(_setTitle:)
1160 - (void) _setTitle:(NSString *)title {
1161 [status_ setText:[title stringByAppendingString:@"..."]];
1164 - (void) setPercent:(float)percent {
1166 performSelectorOnMainThread:@selector(_setPercent:)
1167 withObject:[NSNumber numberWithFloat:percent]
1172 - (void) _setPercent:(NSNumber *)percent {
1173 [progress_ setProgress:[percent floatValue]];
1176 - (void) addOutput:(NSString *)output {
1178 performSelectorOnMainThread:@selector(_addOutput:)
1184 - (void) _addOutput:(NSString *)output {
1185 [output_ setText:[NSString stringWithFormat:@"%@\n%@", [output_ text], output]];
1188 - (void) setStatusStart {
1192 - (void) setStatusStop {
1199 @protocol PackagesDelegate
1205 @interface Packages : UIView {
1207 Database *database_;
1208 bool (*filter_)(Package *package);
1209 NSMutableArray *packages_;
1210 NSMutableArray *sections_;
1212 UISectionList *list_;
1213 UINavigationBar *navbar_;
1214 UITransitionView *transition_;
1216 PackageView *pkgview_;
1220 - (int) numberOfSectionsInSectionList:(UISectionList *)list;
1221 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section;
1222 - (int) sectionList:(UISectionList *)list rowForSection:(int)section;
1224 - (int) numberOfRowsInTable:(UITable *)table;
1225 - (float) table:(UITable *)table heightForRow:(int)row;
1226 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col;
1227 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row;
1228 - (void) tableRowSelected:(NSNotification*)notification;
1230 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
1231 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item;
1233 - (Packages *) initWithFrame:(struct CGRect)frame title:(NSString *)title database:(Database *)database filter:(bool (*)(Package *))filter selector:(SEL)selector;
1234 - (void) setDelegate:(id)delegate;
1236 - (void) reloadData;
1239 @implementation Packages
1241 - (int) numberOfSectionsInSectionList:(UISectionList *)list {
1242 return [sections_ count];
1245 - (NSString *) sectionList:(UISectionList *)list titleForSection:(int)section {
1246 return [[sections_ objectAtIndex:section] name];
1249 - (int) sectionList:(UISectionList *)list rowForSection:(int)section {
1250 return [[sections_ objectAtIndex:section] row];
1253 - (int) numberOfRowsInTable:(UITable *)table {
1254 return [packages_ count];
1257 - (float) table:(UITable *)table heightForRow:(int)row {
1261 - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col {
1262 Package *package = [packages_ objectAtIndex:row];
1263 PackageCell *cell = [[[PackageCell alloc] initWithPackage:package] autorelease];
1267 - (BOOL) table:(UITable *)table showDisclosureForRow:(int)row {
1271 - (void) tableRowSelected:(NSNotification*)notification {
1272 int row = [[list_ table] selectedRow];
1276 package_ = [packages_ objectAtIndex:row];
1278 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:[package_ name]];
1279 [navbar_ pushNavigationItem:navitem];
1281 [navbar_ showButtonsWithLeftTitle:nil rightTitle:title_];
1283 [pkgview_ setPackage:package_];
1284 [transition_ transition:1 toView:pkgview_];
1287 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
1289 [package_ performSelector:selector_];
1291 pkgProblemResolver *resolver = [database_ resolver];
1293 resolver->InstallProtect();
1294 if (!resolver->Resolve(true))
1297 [delegate_ perform];
1301 - (void) navigationBar:(UINavigationBar *)navbar poppedItem:(UINavigationItem *)item {
1303 [navbar_ showButtonsWithLeftTitle:nil rightTitle:nil];
1306 - (Packages *) initWithFrame:(struct CGRect)frame title:(NSString *)title database:(Database *)database filter:(bool (*)(Package *))filter selector:(SEL)selector {
1307 if ((self = [super initWithFrame:frame]) != nil) {
1308 title_ = [title retain];
1309 database_ = [database retain];
1311 selector_ = selector;
1313 struct CGRect bounds = [self bounds];
1314 CGSize navsize = [UINavigationBar defaultSize];
1315 CGRect navrect = {{0, 0}, navsize};
1317 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1318 [self addSubview:navbar_];
1320 [navbar_ setBarStyle:1];
1321 [navbar_ setDelegate:self];
1323 UINavigationItem *navitem = [[[UINavigationItem alloc] initWithTitle:title] autorelease];
1324 [navbar_ pushNavigationItem:navitem];
1325 [navitem setBackButtonTitle:@"Packages"];
1327 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
1328 bounds.origin.x, bounds.origin.y + navsize.height, bounds.size.width, bounds.size.height - navsize.height
1331 [self addSubview:transition_];
1333 list_ = [[UISectionList alloc] initWithFrame:[transition_ bounds] showSectionIndex:NO];
1334 [list_ setDataSource:self];
1336 [transition_ transition:0 toView:list_];
1338 UITableColumn *column = [[UITableColumn alloc]
1339 initWithTitle:@"Name"
1341 width:frame.size.width
1344 UITable *table = [list_ table];
1345 [table setSeparatorStyle:1];
1346 [table addTableColumn:column];
1347 [table setDelegate:self];
1349 pkgview_ = [[PackageView alloc] initWithFrame:[transition_ bounds] database:database_];
1353 - (void) setDelegate:(id)delegate {
1354 delegate_ = delegate;
1358 [transition_ transition:2 toView:list_];
1359 UITable *table = [list_ table];
1360 [table selectRow:-1 byExtendingSelection:NO withFade:YES];
1364 - (void) reloadData {
1365 packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
1368 if (sections_ != nil) {
1369 [sections_ release];
1374 for (pkgCache::PkgIterator iterator = [database_ cache]->PkgBegin(); !iterator.end(); ++iterator) {
1375 Package *package = [Package packageWithIterator:iterator database:database_];
1378 if (filter_(package))
1379 [packages_ addObject:package];
1383 [packages_ sortUsingSelector:@selector(compareBySectionAndName:)];
1384 sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
1387 Section *section = nil;
1389 for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
1391 Package *package = [packages_ objectAtIndex:offset];
1393 NSString *name = [package section];
1396 if (section == nil || ![[section name] isEqual:name]) {
1397 section = [[Section alloc] initWithName:name row:offset];
1398 [sections_ addObject:section];
1402 [section addPackage:package];
1409 if (package_ != nil)
1410 [navbar_ popNavigationItem];
1416 bool IsInstalled(Package *package) {
1417 return [package installed];
1420 bool IsNotInstalled(Package *package) {
1421 return ![package installed];
1424 @interface Cydia : UIApplication <
1426 ProgressViewDelegate
1429 UITransitionView *transition_;
1430 UIButtonBar *buttonbar_;
1431 UIAlertSheet *alert_;
1433 Database *database_;
1434 ProgressView *progress_;
1437 UINavigationBar *navbar_;
1438 UIScroller *scroller_;
1439 UIWebView *webview_;
1443 Packages *uninstall_;
1447 - (void) reloadData;
1450 - (void) progressViewIsComplete:(ProgressView *)progress;
1452 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button;
1453 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button;
1454 - (void) buttonBarItemTapped:(id)sender;
1456 - (void) view:(UIView *)sender didSetFrame:(CGRect)frame;
1457 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration;
1459 - (void) applicationDidFinishLaunching:(id)unused;
1462 @implementation Cydia
1465 [webview_ loadRequest:[NSURLRequest
1467 cachePolicy:NSURLRequestReloadIgnoringCacheData
1468 timeoutInterval:30.0
1472 - (void) reloadData {
1474 [database_ reloadData];
1476 [install_ reloadData];
1478 [uninstall_ reloadData];
1485 detachNewThreadSelector:@selector(perform)
1491 - (void) progressViewIsComplete:(ProgressView *)progress {
1497 - (void) navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
1504 _assert(alert_ == nil);
1506 alert_ = [[UIAlertSheet alloc]
1507 initWithTitle:@"About Cydia Packager"
1508 buttons:[NSArray arrayWithObjects:@"Close", nil]
1509 defaultButtonIndex:0
1514 [alert_ setBodyText:
1515 @"Copyright (C) 2007\n"
1516 "Jay Freeman (saurik)\n"
1517 "saurik@saurik.com\n"
1518 "http://www.saurik.com/\n"
1521 "http://www.theokorigroup.com/\n"
1523 "College of Creative Studies,\n"
1524 "University of California,\n"
1526 "http://www.ccs.ucsb.edu/\n"
1529 "bad_, BHSPitMonkey, Cobra, core,\n"
1530 "Corona, cromas, Darken, dtzWill,\n"
1531 "francis, Godores, jerry, Kingstone,\n"
1532 "lounger, rockabilly, tman, Wbiggs"
1535 [alert_ presentSheetFromButtonBar:buttonbar_];
1540 - (void) alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
1546 - (void) buttonBarItemTapped:(id)sender {
1549 switch ([sender tag]) {
1550 case 1: view = featured_; break;
1551 case 2: view = install_; break;
1552 case 4: view = uninstall_; break;
1558 [transition_ transition:0 toView:view];
1561 - (void) view:(UIView *)view didSetFrame:(CGRect)frame {
1562 [scroller_ setContentSize:frame.size];
1565 - (void) view:(UIView *)view didDrawInRect:(CGRect)rect duration:(float)duration {
1566 [scroller_ setContentSize:[webview_ bounds].size];
1569 - (void) applicationDidFinishLaunching:(id)unused {
1570 _assert(pkgInitConfig(*_config));
1571 _assert(pkgInitSystem(*_config, _system));
1573 CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
1574 window_ = [[UIWindow alloc] initWithContentRect:screenrect];
1576 [window_ orderFront: self];
1577 [window_ makeKey: self];
1578 [window_ _setHidden: NO];
1580 progress_ = [[ProgressView alloc] initWithFrame:[window_ bounds] delegate:self];
1581 [window_ setContentView:progress_];
1583 UIView *view = [[UIView alloc] initWithFrame:[progress_ bounds]];
1584 [progress_ setContentView:view];
1586 transition_ = [[UITransitionView alloc] initWithFrame:CGRectMake(
1587 0, 0, screenrect.size.width, screenrect.size.height - 48
1590 [view addSubview:transition_];
1592 featured_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
1594 CGSize navsize = [UINavigationBar defaultSize];
1595 CGRect navrect = {{0, 0}, navsize};
1597 navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
1598 [featured_ addSubview:navbar_];
1600 [navbar_ setBarStyle:1];
1601 [navbar_ setDelegate:self];
1603 [navbar_ showButtonsWithLeftTitle:@"About" rightTitle:@"Reload"];
1605 UINavigationItem *navitem = [[UINavigationItem alloc] initWithTitle:@"Featured"];
1606 [navbar_ pushNavigationItem:navitem];
1608 struct CGRect subbounds = [featured_ bounds];
1609 subbounds.origin.y += navsize.height;
1610 subbounds.size.height -= navsize.height;
1612 UIImageView *pinstripe = [[UIImageView alloc] initWithFrame:subbounds];
1613 [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]];
1614 [featured_ addSubview:pinstripe];
1616 scroller_ = [[UIScroller alloc] initWithFrame:subbounds];
1617 [featured_ addSubview:scroller_];
1619 [scroller_ setScrollingEnabled:YES];
1620 [scroller_ setAdjustForContentSizeChange:YES];
1621 [scroller_ setClipsSubviews:YES];
1622 [scroller_ setAllowsRubberBanding:YES];
1623 [scroller_ setScrollDecelerationFactor:0.99];
1624 [scroller_ setDelegate:self];
1626 webview_ = [[UIWebView alloc] initWithFrame:[scroller_ bounds]];
1627 [scroller_ addSubview:webview_];
1629 [webview_ setTilingEnabled:YES];
1630 [webview_ setTileSize:CGSizeMake(screenrect.size.width, 500)];
1631 [webview_ setAutoresizes:YES];
1632 [webview_ setDelegate:self];
1634 url_ = [NSURL URLWithString:@"http://cydia.saurik.com/"];
1637 NSArray *buttonitems = [NSArray arrayWithObjects:
1638 [NSDictionary dictionaryWithObjectsAndKeys:
1639 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1640 @"featured-up.png", kUIButtonBarButtonInfo,
1641 @"featured-dn.png", kUIButtonBarButtonSelectedInfo,
1642 [NSNumber numberWithInt:1], kUIButtonBarButtonTag,
1643 self, kUIButtonBarButtonTarget,
1644 @"Featured", kUIButtonBarButtonTitle,
1645 @"0", kUIButtonBarButtonType,
1648 [NSDictionary dictionaryWithObjectsAndKeys:
1649 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1650 @"install-up.png", kUIButtonBarButtonInfo,
1651 @"install-dn.png", kUIButtonBarButtonSelectedInfo,
1652 [NSNumber numberWithInt:2], kUIButtonBarButtonTag,
1653 self, kUIButtonBarButtonTarget,
1654 @"Install", kUIButtonBarButtonTitle,
1655 @"0", kUIButtonBarButtonType,
1658 [NSDictionary dictionaryWithObjectsAndKeys:
1659 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1660 @"upgrade-up.png", kUIButtonBarButtonInfo,
1661 @"upgrade-dn.png", kUIButtonBarButtonSelectedInfo,
1662 [NSNumber numberWithInt:3], kUIButtonBarButtonTag,
1663 self, kUIButtonBarButtonTarget,
1664 @"Upgrade", kUIButtonBarButtonTitle,
1665 @"0", kUIButtonBarButtonType,
1668 [NSDictionary dictionaryWithObjectsAndKeys:
1669 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1670 @"uninstall-up.png", kUIButtonBarButtonInfo,
1671 @"uninstall-dn.png", kUIButtonBarButtonSelectedInfo,
1672 [NSNumber numberWithInt:4], kUIButtonBarButtonTag,
1673 self, kUIButtonBarButtonTarget,
1674 @"Uninstall", kUIButtonBarButtonTitle,
1675 @"0", kUIButtonBarButtonType,
1678 [NSDictionary dictionaryWithObjectsAndKeys:
1679 @"buttonBarItemTapped:", kUIButtonBarButtonAction,
1680 @"sources-up.png", kUIButtonBarButtonInfo,
1681 @"sources-dn.png", kUIButtonBarButtonSelectedInfo,
1682 [NSNumber numberWithInt:5], kUIButtonBarButtonTag,
1683 self, kUIButtonBarButtonTarget,
1684 @"Sources", kUIButtonBarButtonTitle,
1685 @"0", kUIButtonBarButtonType,
1689 buttonbar_ = [[UIButtonBar alloc]
1691 withFrame:CGRectMake(
1692 0, screenrect.size.height - 48,
1693 screenrect.size.width, 48
1695 withItemList:buttonitems
1698 [buttonbar_ setDelegate:self];
1699 [buttonbar_ setBarStyle:1];
1700 [buttonbar_ setButtonBarTrackingMode:2];
1702 int buttons[5] = {1, 2, 3, 4, 5};
1703 [buttonbar_ registerButtonGroup:0 withButtons:buttons withCount:5];
1704 [buttonbar_ showButtonGroup:0 withDuration:0];
1706 for (int i = 0; i != 5; ++i)
1707 [[buttonbar_ viewWithTag:(i + 1)] setFrame:CGRectMake(
1708 i * 64 + 2, 1, 60, 48
1711 [buttonbar_ showSelectionForButton:1];
1712 [transition_ transition:0 toView:featured_];
1714 [view addSubview:buttonbar_];
1716 database_ = [[Database alloc] init];
1717 [database_ setDelegate:progress_];
1719 install_ = [[Packages alloc] initWithFrame:[transition_ bounds] title:@"Install" database:database_ filter:&IsNotInstalled selector:@selector(install)];
1720 [install_ setDelegate:self];
1722 uninstall_ = [[Packages alloc] initWithFrame:[transition_ bounds] title:@"Uninstall" database:database_ filter:&IsInstalled selector:@selector(remove)];
1723 [uninstall_ setDelegate:self];
1727 UIAlertSheet *alert = [[UIAlertSheet alloc]
1728 initWithTitle:@"Alert Title"
1729 buttons:[NSArray arrayWithObjects:@"Yes", nil]
1730 defaultButtonIndex:0
1735 NSLog(@"%p\n", [alert table]);
1736 [[alert table] setDelegate:self];
1737 [[alert table] reloadData];
1739 [alert addTextFieldWithValue:@"Title" label:@"Label"];
1740 [alert setShowsOverSpringBoardAlerts:YES];
1741 [alert setBodyText:@"This is an alert."];
1742 [alert presentSheetFromButtonBar:buttonbar_];
1743 //[alert popupAlertAnimated:YES];
1748 [progress_ resetView];
1753 int main(int argc, char *argv[]) {
1754 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1755 UIApplicationMain(argc, argv, [Cydia class]);