/* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008 Jay Freeman (saurik)
+ * Copyright (C) 2008-2009 Jay Freeman (saurik)
*/
/*
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/tagfile.h>
#include <apr-1/apr_pools.h>
}
public:
+ _finline _H(const This_ &rhs) :
+ value_(rhs.value_ == nil ? nil : [rhs.value_ retain])
+ {
+ }
+
_finline _H(Type_ *value = NULL, bool mended = false) :
value_(value)
{
#define lprintf(args...) fprintf(stderr, args)
-#define ForRelease 0
+#define ForRelease 1
#define TraceLogging (1 && !ForRelease)
#define HistogramInsertionSort (0 && !ForRelease)
-#define ProfileTimes (1 && !ForRelease)
+#define ProfileTimes (0 && !ForRelease)
#define ForSaurik (0 && !ForRelease)
-#define LogBrowser (0 && !ForRelease)
+#define LogBrowser (1 && !ForRelease)
#define TrackResize (0 && !ForRelease)
#define ManualRefresh (1 && !ForRelease)
#define ShowInternals (0 && !ForRelease)
CFStringRef cache_;
_finline void clear_() {
- if (cache_ != nil)
+ if (cache_ != NULL) {
CFRelease(cache_);
+ cache_ = NULL;
+ }
}
public:
_finline CYString() :
data_(0),
size_(0),
- cache_(nil)
+ cache_(NULL)
{
}
static const float KeyboardTime_ = 0.3f;
#define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
-#define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb"
#define NotifyConfig_ "/etc/notify.conf"
static bool Queuing_;
return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]];
}
-NSString *StripVersion(const char *version) {
+static _finline CFStringRef CFCString(const char *value) {
+ return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+}
+
+const char *StripVersion_(const char *version) {
const char *colon(strchr(version, ':'));
if (colon != NULL)
version = colon + 1;
- return [NSString stringWithUTF8String:version];
+ return version;
+}
+
+CFStringRef StripVersion(const char *version) {
+ const char *colon(strchr(version, ':'));
+ if (colon != NULL)
+ version = colon + 1;
+ return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(version), strlen(version), kCFStringEncodingUTF8, NO);
+ // XXX: performance
+ return CFCString(version);
}
NSString *LocalizeSection(NSString *section) {
- (void) upgrade;
- (void) update;
-- (void) updateWithStatus:(Status &)status;
+- (NSString *) updateWithStatus:(Status &)status;
- (void) setDelegate:(id)delegate;
- (Source *) getSource:(pkgCache::PkgFileIterator)file;
/* Source Class {{{ */
@interface Source : NSObject {
- NSString *description_;
- NSString *label_;
- NSString *origin_;
- NSString *support_;
+ CYString depiction_;
+ CYString description_;
+ CYString label_;
+ CYString origin_;
+ CYString support_;
- NSString *uri_;
- NSString *distribution_;
- NSString *type_;
- NSString *version_;
+ CYString uri_;
+ CYString distribution_;
+ CYString type_;
+ CYString version_;
+
+ NSString *host_;
- NSString *defaultIcon_;
+ CYString defaultIcon_;
NSDictionary *record_;
BOOL trusted_;
}
-- (Source *) initWithMetaIndex:(metaIndex *)index;
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool;
- (NSComparisonResult) compareByNameAndType:(Source *)source;
+- (NSString *) depictionForPackage:(NSString *)package;
- (NSString *) supportForPackage:(NSString *)package;
- (NSDictionary *) record;
@implementation Source
-#define _clear(field) \
- if (field != nil) \
- [field release]; \
- field = nil;
-
- (void) _clear {
- _clear(uri_)
- _clear(distribution_)
- _clear(type_)
+ uri_.clear();
+ distribution_.clear();
+ type_.clear();
+
+ description_.clear();
+ label_.clear();
+ origin_.clear();
+ depiction_.clear();
+ support_.clear();
+ version_.clear();
+ defaultIcon_.clear();
+
+ if (record_ != nil) {
+ [record_ release];
+ record_ = nil;
+ }
- _clear(description_)
- _clear(label_)
- _clear(origin_)
- _clear(support_)
- _clear(version_)
- _clear(defaultIcon_)
- _clear(record_)
+ if (host_ != nil) {
+ [host_ release];
+ host_ = nil;
+ }
}
- (void) dealloc {
return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
}
-- (void) setMetaIndex:(metaIndex *)index {
+- (void) setMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
[self _clear];
trusted_ = index->IsTrusted();
- uri_ = [[NSString stringWithUTF8String:index->GetURI().c_str()] retain];
- distribution_ = [[NSString stringWithUTF8String:index->GetDist().c_str()] retain];
- type_ = [[NSString stringWithUTF8String:index->GetType()] retain];
+ uri_.set(pool, index->GetURI());
+ distribution_.set(pool, index->GetDist());
+ type_.set(pool, index->GetType());
debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
if (dindex != NULL) {
- std::ifstream release(dindex->MetaIndexFile("Release").c_str());
- std::string line;
- while (std::getline(release, line)) {
- std::string::size_type colon(line.find(':'));
- if (colon == std::string::npos)
- continue;
+ FileFd fd;
+ if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ pkgTagFile tags(&fd);
+
+ pkgTagSection section;
+ tags.Step(section);
+
+ struct {
+ const char *name_;
+ CYString *value_;
+ } names[] = {
+ {"default-icon", &defaultIcon_},
+ {"depiction", &depiction_},
+ {"description", &description_},
+ {"label", &label_},
+ {"origin", &origin_},
+ {"support", &support_},
+ {"version", &version_},
+ };
+
+ for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+ const char *start, *end;
- std::string name(line.substr(0, colon));
- std::string value(line.substr(colon + 1));
- while (!value.empty() && value[0] == ' ')
- value = value.substr(1);
-
- if (name == "Default-Icon")
- defaultIcon_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Description")
- description_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Label")
- label_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Origin")
- origin_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Support")
- support_ = [[NSString stringWithUTF8String:value.c_str()] retain];
- else if (name == "Version")
- version_ = [[NSString stringWithUTF8String:value.c_str()] retain];
+ if (section.Find(names[i].name_, start, end)) {
+ CYString &value(*names[i].value_);
+ value.set(pool, start, end - start);
+ }
+ }
}
}
record_ = [Sources_ objectForKey:[self key]];
if (record_ != nil)
record_ = [record_ retain];
+
+ host_ = [[[[NSURL URLWithString:uri_] host] lowercaseString] retain];
}
-- (Source *) initWithMetaIndex:(metaIndex *)index {
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
if ((self = [super init]) != nil) {
- [self setMetaIndex:index];
+ [self setMetaIndex:index inPool:pool];
} return self;
}
return [lhs compare:rhs options:LaxCompareOptions_];
}
+- (NSString *) depictionForPackage:(NSString *)package {
+ return depiction_.empty() ? nil : [depiction_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+}
+
- (NSString *) supportForPackage:(NSString *)package {
- return support_ == nil ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+ return support_.empty() ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
}
- (NSDictionary *) record {
}
- (NSString *) key {
- return [NSString stringWithFormat:@"%@:%@:%@", type_, uri_, distribution_];
+ return [NSString stringWithFormat:@"%@:%@:%@", (NSString *) type_, (NSString *) uri_, (NSString *) distribution_];
}
- (NSString *) host {
- return [[[NSURL URLWithString:[self uri]] host] lowercaseString];
+ return host_;
}
- (NSString *) name {
- return origin_ == nil ? [self host] : origin_;
+ return origin_.empty() ? host_ : origin_;
}
- (NSString *) description {
}
- (NSString *) label {
- return label_ == nil ? [self host] : label_;
+ return label_.empty() ? host_ : label_;
}
- (NSString *) origin {
bool visible_;
NSString *latest_;
- NSString *installed_;
+ CYString installed_;
CYString id_;
CYString name_;
Address *author$_;
CYString support_;
- NSArray *tags_;
+ NSMutableArray *tags_;
NSString *role_;
NSArray *relationships_;
- (NSString *) latest;
- (NSString *) installed;
+- (BOOL) uninstalled;
- (BOOL) valid;
- (BOOL) upgradableAndEssential:(BOOL)essential;
if (latest_ != nil)
[latest_ release];
- if (installed_ != nil)
- [installed_ release];
if (sponsor$_ != nil)
[sponsor$_ release];
_profile(Package$parse$Tagline)
const char *start, *end;
- if (parser->Find("Description", start, end)) {
+ if (parser->ShortDesc(start, end)) {
const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
if (stop == NULL)
stop = end;
database_ = database;
_profile(Package$initWithVersion$Latest)
- latest_ = [StripVersion(version_.VerStr()) retain];
+ latest_ = (NSString *) StripVersion(version_.VerStr());
_end
pkgCache::VerIterator current;
_profile(Package$initWithVersion$Versions)
current = iterator_.CurrentVer();
if (!current.end())
- installed_ = [StripVersion(current.VerStr()) retain];
+ installed_.set(pool_, StripVersion_(current.VerStr()));
if (!version_.end())
file_ = version_.FileList();
_profile(Package$initWithVersion$Name)
id_.set(pool_, iterator_.Name());
+ name_.set(pool, iterator_.Display());
_end
if (!file_.end()) {
_end
}
- /* XXX: get the damned Name */
+ visible_ = true;
_profile(Package$initWithVersion$Tags)
- if (tags_ != nil)
- for (NSString *tag in tags_)
- if ([tag hasPrefix:@"role::"]) {
- role_ = [[tag substringFromIndex:6] retain];
- break;
- }
+ pkgCache::TagIterator tag(iterator_.TagList());
+ if (!tag.end()) {
+ tags_ = [[NSMutableArray alloc] initWithCapacity:8];
+ do {
+ const char *name(tag.Name());
+ [tags_ addObject:(NSString *)CFCString(name)];
+ if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
+ role_ = (NSString *) CFCString(name + 6);
+ if (visible_ && strncmp(name, "require::", 9) == 0 && (
+ true
+ ))
+ visible_ = false;
+ ++tag;
+ } while (!tag.end());
+ }
_end
bool changed(false);
metadata_ = [Packages_ objectForKey:key];
if (metadata_ == nil) {
- firstSeen_ = [now_ retain];
+ firstSeen_ = now_;
metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
firstSeen_, @"FirstSeen",
if (version == nil) {
[metadata_ setObject:latest_ forKey:@"LastVersion"];
changed = true;
- } else if (![version isEqualToString:latest_]) {
+ } else {
+ if (![version isEqualToString:latest_]) {
[metadata_ setObject:latest_ forKey:@"LastVersion"];
lastSeen_ = now_;
[metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
changed = true;
- }
+ } }
}
metadata_ = [metadata_ retain];
_end
essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
- visible_ = [self hasSupportingRole] && [self unfiltered];
+ visible_ = visible_ && [self hasSupportingRole] && [self unfiltered];
} _end } return self;
}
}
- (NSString *) longSection {
- return LocalizeSection(section_);
+ return LocalizeSection([self section]);
}
- (NSString *) shortSection {
return installed_;
}
+- (BOOL) uninstalled {
+ return installed_.empty();
+}
+
- (BOOL) valid {
return !version_.end();
}
}
- (NSString *) depiction {
- return depiction_;
+ return !depiction_.empty() ? depiction_ : [[self source] depictionForPackage:id_];
}
- (Address *) sponsor {
}
- (bool) isInstalledAndVisible:(NSNumber *)number {
- return (![number boolValue] || [self visible]) && [self installed] != nil;
+ return (![number boolValue] || [self visible]) && ![self uninstalled];
}
- (bool) isVisiblyUninstalledInSection:(NSString *)name {
return
[self visible] &&
- [self installed] == nil && (
+ [self uninstalled] && (
name == nil ||
section == nil && [name length] == 0 ||
[name isEqualToString:section]
++era_;
}
+ [packages_ removeAllObjects];
+ sources_.clear();
+
_error->Discard();
delete list_;
delete policy_;
policy_ = NULL;
+ if (now_ != nil) {
+ [now_ release];
+ now_ = nil;
+ }
+
cache_.Close();
apr_pool_clear(pool_);
_trace();
- sources_.clear();
for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
if (!cached.end())
- sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source] autorelease];
+ sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease];
}
}
[packages_ release];
packages_ = nil;*/
- [packages_ removeAllObjects];
-
_trace();
for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator)
for (pkgAcquire::ItemIterator item = fetcher_->ItemsBegin(); item != fetcher_->ItemsEnd(); item++) {
if ((*item)->Status == pkgAcquire::Item::StatDone && (*item)->Complete)
continue;
+ if ((*item)->Status == pkgAcquire::Item::StatIdle)
+ continue;
std::string uri = (*item)->DescURI();
std::string error = (*item)->ErrorText;
[self updateWithStatus:status_];
}
-- (void) updateWithStatus:(Status &)status {
+- (NSString *) updateWithStatus:(Status &)status {
pkgSourceList list;
_assert(list.ReadMainList());
FileFd lock;
lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
- _assert(!_error->PendingError());
+
+ if (_error->PendingError()) {
+ std::string error;
+ if (!_error->PopMessage(error))
+ _assert(false);
+ _error->Discard();
+ return [NSString stringWithUTF8String:error.c_str()];
+ }
pkgAcquire fetcher(&status);
_assert(list.GetIndexes(&fetcher));
[Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
Changed_ = true;
}
+
+ return nil;
}
- (void) setDelegate:(id)delegate {
}
- (Source *) getSource:(pkgCache::PkgFileIterator)file {
- return sources_[file->ID];
+ SourceMap::const_iterator i(sources_.find(file->ID));
+ return i == sources_.end() ? nil : i->second;
}
@end
[transition_ transition:6 toView:view_];
}
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
- NSString *context([sheet context]);
-
- if ([context isEqualToString:@"error"])
- [sheet dismiss];
- else if ([context isEqualToString:@"conffile"]) {
- FILE *input = [database_ input];
-
- switch (button) {
- case 1:
- fprintf(input, "N\n");
- fflush(input);
- break;
- case 2:
- fprintf(input, "Y\n");
- fflush(input);
- break;
- default:
- _assert(false);
- }
-
- [sheet dismiss];
- }
-}
-
-- (void) closeButtonPushed {
- running_ = NO;
-
- switch (Finish_) {
- case 0:
- [self resetView];
- break;
-
- case 1:
- [delegate_ suspendWithAnimation:YES];
- break;
+- (void) _checkError {
+ if (_error->PendingError()) {
+ std::string error;
+ if (!_error->PopMessage(error))
+ _assert(false);
- case 2:
- system("launchctl stop com.apple.SpringBoard");
- break;
+ UIActionSheet *sheet = [[[UIActionSheet alloc]
+ initWithTitle:CYLocalize("ERROR")
+ buttons:[NSArray arrayWithObjects:CYLocalize("OKAY"), nil]
+ defaultButtonIndex:0
+ delegate:self
+ context:@"_error"
+ ] autorelease];
- case 3:
- system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
- break;
+ [sheet setBodyText:[NSString stringWithUTF8String:error.c_str()]];
+ [sheet popupAlertAnimated:YES];
- case 4:
- system("reboot");
- break;
+ return;
}
-}
-
-- (void) _retachThread {
- UINavigationItem *item = [navbar_ topItem];
- [item setTitle:CYLocalize("COMPLETE")];
-
- [overlay_ addSubview:close_];
- [progress_ removeFromSuperview];
- [status_ removeFromSuperview];
[delegate_ progressViewIsComplete:self];
if (Finish_ < 4) {
- FileFd file(SandboxTemplate_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(sandplate_ == sha1.Result()))
- Finish_ = 4;
- }
-
- if (Finish_ < 4) {
- FileFd file(NotifyConfig_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(notifyconf_ == sha1.Result()))
- Finish_ = 4;
+ FileFd file;
+ if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ if (!(notifyconf_ == sha1.Result()))
+ Finish_ = 4;
+ }
}
if (Finish_ < 3) {
- FileFd file(SpringBoard_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- if (!(springlist_ == sha1.Result()))
- Finish_ = 3;
+ FileFd file;
+ if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ if (!(springlist_ == sha1.Result()))
+ Finish_ = 3;
+ }
}
switch (Finish_) {
[delegate_ setStatusBarShowsProgress:NO];
}
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+ NSString *context([sheet context]);
+
+ if ([context isEqualToString:@"error"])
+ [sheet dismiss];
+ else if ([context isEqualToString:@"_error"]) {
+ [sheet dismiss];
+ [self _checkError];
+ } else if ([context isEqualToString:@"conffile"]) {
+ FILE *input = [database_ input];
+
+ switch (button) {
+ case 1:
+ fprintf(input, "N\n");
+ fflush(input);
+ break;
+ case 2:
+ fprintf(input, "Y\n");
+ fflush(input);
+ break;
+ default:
+ _assert(false);
+ }
+
+ [sheet dismiss];
+ }
+}
+
+- (void) closeButtonPushed {
+ running_ = NO;
+
+ switch (Finish_) {
+ case 0:
+ [self resetView];
+ break;
+
+ case 1:
+ [delegate_ suspendWithAnimation:YES];
+ break;
+
+ case 2:
+ system("launchctl stop com.apple.SpringBoard");
+ break;
+
+ case 3:
+ system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
+ break;
+
+ case 4:
+ system("reboot");
+ break;
+ }
+}
+
+- (void) _retachThread {
+ UINavigationItem *item = [navbar_ topItem];
+ [item setTitle:CYLocalize("COMPLETE")];
+
+ [overlay_ addSubview:close_];
+ [progress_ removeFromSuperview];
+ [status_ removeFromSuperview];
+
+ [self _checkError];
+}
+
- (void) _detachNewThreadData:(ProgressData *)data { _pooled
[[data target] performSelector:[data selector] withObject:[data object]];
[data release];
running_ = YES;
{
- FileFd file(SandboxTemplate_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- sandplate_ = sha1.Result();
- }
-
- {
- FileFd file(NotifyConfig_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- notifyconf_ = sha1.Result();
+ FileFd file;
+ if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ notifyconf_ = sha1.Result();
+ }
}
{
- FileFd file(SpringBoard_, FileFd::ReadOnly);
- MMap mmap(file, MMap::ReadOnly);
- SHA1Summation sha1;
- sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
- springlist_ = sha1.Result();
+ FileFd file;
+ if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+ _error->Discard();
+ else {
+ MMap mmap(file, MMap::ReadOnly);
+ SHA1Summation sha1;
+ sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+ springlist_ = sha1.Result();
+ }
}
[transition_ transition:6 toView:overlay_];
section_ = [section localized];
if (section_ != nil)
section_ = [section_ retain];
- name_ = [(section_ == nil ? CYLocalize("NO_SECTION") : section_) retain];
+ name_ = [(section_ == nil || [section_ length] == 0 ? CYLocalize("NO_SECTION") : section_) retain];
count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
if (editing_)
if ([package_ source] == nil);
else if ([package_ upgradableAndEssential:NO])
[buttons_ addObject:CYLocalize("UPGRADE")];
- else if ([package_ installed] == nil)
+ else if ([package_ uninstalled])
[buttons_ addObject:CYLocalize("INSTALL")];
else
[buttons_ addObject:CYLocalize("REINSTALL")];
- if ([package_ installed] != nil)
+ if (![package_ uninstalled])
[buttons_ addObject:CYLocalize("REMOVE")];
if (special_ != NULL) {
];
}
-- (void) _update_ {
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+ NSString *context([sheet context]);
+
+ if ([context isEqualToString:@"refresh"])
+ [sheet dismiss];
+}
+
+- (void) _update_:(NSString *)error {
updating_ = false;
[indicator_ stopAnimation];
[UIView commitAnimations];
- [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+ if (error == nil)
+ [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+ else {
+ UIActionSheet *sheet = [[[UIActionSheet alloc]
+ initWithTitle:[NSString stringWithFormat:CYLocalize("COLON_DELIMITED"), CYLocalize("ERROR"), CYLocalize("REFRESH")]
+ buttons:[NSArray arrayWithObjects:
+ CYLocalize("OK"),
+ nil]
+ defaultButtonIndex:0
+ delegate:self
+ context:@"refresh"
+ ] autorelease];
+
+ [sheet setBodyText:error];
+ [sheet popupAlertAnimated:YES];
+
+ [self reloadButtons];
+ }
}
- (id) initWithFrame:(CGRect)frame database:(Database *)database {
Status status;
status.setDelegate(self);
- [database_ updateWithStatus:status];
+ NSString *error([database_ updateWithStatus:status]);
[self
- performSelectorOnMainThread:@selector(_update_)
- withObject:nil
+ performSelectorOnMainThread:@selector(_update_:)
+ withObject:error
waitUntilDone:NO
];
}
return !updating_;
}
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
- [sheet dismiss];
-}
-
- (void) _setProgressTitle:(NSString *)title {
[prompt_ setText:title];
}
[*section addToCount];
_profile(SectionsView$reloadData$Filter)
- if (![package valid] || [package installed] != nil || ![package visible])
+ if (![package valid] || ![package uninstalled] || ![package visible])
continue;
_end
[section addToCount];
_profile(SectionsView$reloadData$Filter)
- if (![package valid] || [package installed] != nil || ![package visible])
+ if (![package valid] || ![package uninstalled] || ![package visible])
continue;
_end
_trace();
for (Package *package in packages)
if (
- [package installed] == nil && [package valid] && [package visible] ||
+ [package uninstalled] && [package valid] && [package visible] ||
[package upgradableAndEssential:YES]
)
[packages_ addObject:package];
ManageView *manage_;
SearchView *search_;
- PackageView *package_;
+ NSMutableArray *details_;
}
@end
}
- (void) setPackageView:(PackageView *)view {
- if (package_ == nil)
- package_ = [view retain];
+ WebThreadLock();
+ [view setPackage:nil];
+ if ([details_ count] < 3)
+ [details_ addObject:view];
+ WebThreadUnlock();
+}
+
+- (PackageView *) _packageView {
+ return [[[PackageView alloc] initWithBook:book_ database:database_] autorelease];
}
- (PackageView *) packageView {
PackageView *view;
+ size_t count([details_ count]);
- if (package_ == nil)
- view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease];
- else {
- return package_;
- view = [package_ autorelease];
- package_ = nil;
+ if (count == 0) {
+ view = [self _packageView];
+ renew:
+ [details_ addObject:[self _packageView]];
+ } else {
+ view = [[[details_ lastObject] retain] autorelease];
+ [details_ removeLastObject];
+ if (count == 1)
+ goto renew;
}
return view;
withClass:[ManageView class]
] retain];
- [self setPackageView:[self packageView]];
+ details_ = [[NSMutableArray alloc] initWithCapacity:4];
+ [details_ addObject:[self _packageView]];
+ [details_ addObject:[self _packageView]];
PrintTimes();
Changed_ = true;
+ [sheet dismiss];
+
if (reset)
[self updateData];
else
[self finish];
-
- [sheet dismiss];
} else if ([context isEqualToString:@"upgrade"]) {
switch (button) {
case 1:
if (
readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
- readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
+ readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL /*||
+ readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL*/ ||
readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
+ readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL /*||
readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL*/