Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of https://github.com/syko9000/AppSales-Mobile

…into syko9000-master
  • Loading branch information...
commit fb0a9d3073bf7d171fe1243d6ee180cac00f3d6c 2 parents 4cc218a + c6c6541
Ole Zorn authored
2  AppSales.xcodeproj/project.pbxproj
View
@@ -2297,7 +2297,7 @@
7F709D1E13BC98860008DBAD /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0420;
+ LastUpgradeCheck = 0430;
};
buildConfigurationList = 7F709D2113BC98860008DBAD /* Build configuration list for PBXProject "AppSales" */;
compatibilityVersion = "Xcode 3.2";
6 Classes/DashboardViewController.h
View
@@ -13,7 +13,7 @@
@interface DashboardViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, ColorPickerViewControllerDelegate> {
- Product *selectedProduct;
+ NSMutableArray *selectedProducts;
ASAccount *account;
UITableView *productsTableView;
UIView *topView;
@@ -37,7 +37,7 @@
@property (nonatomic, retain) ASAccount *account;
@property (nonatomic, retain) NSArray *products;
@property (nonatomic, retain) NSArray *visibleProducts;
-@property (nonatomic, retain) Product *selectedProduct;
+@property (nonatomic, retain) NSMutableArray *selectedProducts;
@property (nonatomic, retain) UITableView *productsTableView;
@property (nonatomic, retain) UIView *topView;
@property (nonatomic, retain) UIImageView *shadowView;
@@ -59,4 +59,6 @@
- (void)stopDownload:(id)sender;
- (UIView *)accessoryViewForRowAtIndexPath:(NSIndexPath *)indexPath;
+- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer;
+
@end
89 Classes/DashboardViewController.m
View
@@ -15,7 +15,7 @@
@implementation DashboardViewController
-@synthesize account, products, visibleProducts, selectedProduct;
+@synthesize account, products, visibleProducts, selectedProducts;
@synthesize productsTableView, topView, shadowView, colorPopover, statusToolbar, stopButtonItem, activityIndicator, statusLabel, progressBar;
@synthesize activeSheet;
@@ -24,6 +24,7 @@ - (id)initWithAccount:(ASAccount *)anAccount
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.account = anAccount;
+ self.selectedProducts = nil;
self.hidesBottomBarWhenPushed = [[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPad;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:[account managedObjectContext]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willShowPasscodeLock:) name:ASWillShowPasscodeLockNotification object:nil];
@@ -112,6 +113,7 @@ - (void)loadView
UIEdgeInsets productsTableScrollIndicatorInset = (statusVisible) ? UIEdgeInsetsMake(0, 0, 44, 0) : UIEdgeInsetsMake(0, 0, 0, 0);
productsTableView.contentInset = productsTableContentInset;
productsTableView.scrollIndicatorInsets = productsTableScrollIndicatorInset;
+ productsTableView.allowsMultipleSelection = YES;
self.view.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
[self.view addSubview:self.productsTableView];
@@ -251,16 +253,16 @@ - (void)reloadData
- (void)reloadTableView
{
//Reload the table view, preserving the current selection:
- NSIndexPath *selectedIndexPath = [self.productsTableView indexPathForSelectedRow];
- if (!selectedIndexPath) {
- if (self.selectedProduct) {
- selectedIndexPath = [NSIndexPath indexPathForRow:[self.products indexOfObject:self.selectedProduct] + 1 inSection:0];
- } else {
- selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
- }
- }
[self.productsTableView reloadData];
- [self.productsTableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ NSArray *selectedIndexPaths = [self.productsTableView indexPathsForSelectedRows];
+ if ([selectedIndexPaths count]) {
+ for (NSIndexPath* selectedIndexPath in selectedIndexPaths) {
+ [self.productsTableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
+ } else {
+ NSIndexPath* selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
+ [self.productsTableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
}
- (void)changeColor:(UIButton *)sender
@@ -330,10 +332,47 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
[cell.colorButton addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchUpInside];
cell.accessoryView = [self accessoryViewForRowAtIndexPath:indexPath];
-
+
+ bool t = [self.selectedProducts containsObject:product];
+ if (t) {
+ [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
+
+ UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
+ initWithTarget:self action:@selector(handleLongPress:)];
+ [cell addGestureRecognizer:lpgr];
+ [lpgr release];
+
return cell;
}
+- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
+{
+ if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
+ DashboardAppCell * cell = ((DashboardAppCell*)gestureRecognizer.view);
+ int i = [self.visibleProducts indexOfObject:cell.product];
+ NSIndexPath * indexPath = [NSIndexPath indexPathForRow:i+1 inSection:0];
+ [self.productsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+
+ if (cell.product) {
+ if (self.selectedProducts) {
+ if (![self.selectedProducts containsObject:cell.product]) {
+ [self.selectedProducts addObject:cell.product];
+ }
+ } else {
+ self.selectedProducts = [NSMutableArray arrayWithObject:cell.product];
+ NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
+ [self.productsTableView deselectRowAtIndexPath:indexPath animated:NO];
+ }
+ } else {
+ self.selectedProducts = nil;
+ [self deselectAllRowsInTableView:self.productsTableView exceptForIndexPath:nil];
+ NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
+ [self.productsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
+ }
+}
+
- (UIView *)accessoryViewForRowAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
@@ -341,9 +380,33 @@ - (UIView *)accessoryViewForRowAtIndexPath:(NSIndexPath *)indexPath
#pragma mark - Table view delegate
+- (void)deselectAllRowsInTableView:(UITableView*)tableView exceptForIndexPath:(NSIndexPath*)indexPath {
+ for (NSIndexPath * i in [tableView indexPathsForSelectedRows]) {
+ if ((indexPath.row == i.row) && (indexPath.section == i.section)) continue;
+ [tableView deselectRowAtIndexPath:i animated:NO];
+ }
+}
+
+- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (indexPath.row != 0) {
+ Product * p = [self.visibleProducts objectAtIndex:indexPath.row - 1];
+
+ [self.selectedProducts removeObject:p];
+
+ if ([self.selectedProducts count] == 0) {
+ self.selectedProducts = nil;
+ NSIndexPath * ip = [NSIndexPath indexPathForRow:0 inSection:0];
+ [tableView selectRowAtIndexPath:ip animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
+ } else {
+ [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
+ }
+}
+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
- self.selectedProduct = [(indexPath.row == 0) ? nil : self.visibleProducts objectAtIndex:indexPath.row - 1];
+ [self deselectAllRowsInTableView:tableView exceptForIndexPath:indexPath];
+ self.selectedProducts = (indexPath.row == 0) ? nil : [NSMutableArray arrayWithObject:[self.visibleProducts objectAtIndex:indexPath.row - 1]];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
@@ -363,7 +426,7 @@ - (void)dealloc
[account release];
[products release];
[visibleProducts release];
- [selectedProduct release];
+ [selectedProducts release];
[productsTableView release];
[topView release];
[shadowView release];
4 Classes/ReviewListViewController.h
View
@@ -13,7 +13,7 @@
@interface ReviewListViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
ASAccount *account;
- Product *product;
+ NSArray *products;
NSUInteger rating;
NSFetchedResultsController *fetchedResultsController;
@@ -23,6 +23,6 @@
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
-- (id)initWithAccount:(ASAccount *)acc product:(Product *)reviewProduct rating:(NSUInteger)ratingFilter;
+- (id)initWithAccount:(ASAccount *)acc products:(NSArray *)reviewProducts rating:(NSUInteger)ratingFilter;
@end
41 Classes/ReviewListViewController.m
View
@@ -17,14 +17,14 @@ @implementation ReviewListViewController
@synthesize fetchedResultsController, managedObjectContext;
-- (id)initWithAccount:(ASAccount *)acc product:(Product *)reviewProduct rating:(NSUInteger)ratingFilter
+- (id)initWithAccount:(ASAccount *)acc products:(NSArray *)reviewProducts rating:(NSUInteger)ratingFilter
{
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
account = [acc retain];
managedObjectContext = [[account managedObjectContext] retain];
rating = ratingFilter;
- product = [reviewProduct retain];
+ products = [reviewProducts retain];
self.title = NSLocalizedString(@"Reviews", nil);
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Check.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(markAllAsRead:)] autorelease];
@@ -114,19 +114,28 @@ - (NSFetchedResultsController *)fetchedResultsController
}
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Review" inManagedObjectContext:self.managedObjectContext];
- if (product) {
- if (rating == 0) {
- [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product == %@", product]];
- } else {
- [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product == %@ AND rating == %@", product, [NSNumber numberWithInteger:rating]]];
- }
- } else {
- if (rating == 0) {
- [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product.account == %@", account]];
- } else {
- [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product.account == %@ AND rating == %@", account, [NSNumber numberWithInteger:rating]]];
- }
- }
+
+ NSMutableArray* args = [NSMutableArray arrayWithArray:products];
+ NSMutableString* pred = [NSMutableString stringWithString:@""];
+
+ if (products) {
+ [pred appendString:@"(product == nil"];
+ for (Product* p in products) {
+ [pred appendString:@" OR product == %@"];
+ }
+ [pred appendString:@")"];
+ } else {
+ [pred appendString:@"product.account == %@"];
+ [args addObject:account];
+ }
+
+ if (rating != 0) {
+ [pred appendString:@" AND rating = %@"];
+ [args addObject:[NSNumber numberWithInt:rating]];
+ }
+
+ [fetchRequest setPredicate:[NSPredicate predicateWithFormat:pred argumentArray:args]];
+
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
@@ -163,7 +172,7 @@ - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
- (void)dealloc
{
- [product release];
+ [products release];
[account release];
[fetchedResultsController release];
[managedObjectContext release];
48 Classes/ReviewsViewController.m
View
@@ -117,10 +117,22 @@ - (NSUInteger)reviewSummaryView:(ReviewSummaryView *)view numberOfReviewsForRati
NSFetchRequest *reviewsCountFetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[reviewsCountFetchRequest setEntity:[NSEntityDescription entityForName:@"Review" inManagedObjectContext:self.account.managedObjectContext]];
- if (!self.selectedProduct) {
- [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product.account == %@ AND rating == %@", self.account, [NSNumber numberWithInt:rating]]];
+
+ NSMutableString * pred = [NSMutableString stringWithString:@"rating == %@"];
+ NSMutableArray * args = [NSMutableArray arrayWithArray:self.selectedProducts];
+ [args insertObject:[NSNumber numberWithInt:rating] atIndex:0];
+
+ if (![self.selectedProducts count]) {
+ [pred appendString:@" AND product.account = %@"];
+ [args addObject:self.account];
+ [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:pred argumentArray:args]];
} else {
- [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product == %@ AND rating == %@", self.selectedProduct, [NSNumber numberWithInt:rating]]];
+ [pred appendString:@" AND (product == nil"];
+ for (Product* p in self.selectedProducts) {
+ [pred appendString:@" OR product == %@"];
+ }
+ [pred appendString:@")"];
+ [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:pred argumentArray:args]];
}
NSUInteger numberOfReviewsForRating = [self.account.managedObjectContext countForFetchRequest:reviewsCountFetchRequest error:NULL];
return numberOfReviewsForRating;
@@ -132,10 +144,22 @@ - (NSUInteger)reviewSummaryView:(ReviewSummaryView *)view numberOfUnreadReviewsF
NSFetchRequest *reviewsCountFetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[reviewsCountFetchRequest setEntity:[NSEntityDescription entityForName:@"Review" inManagedObjectContext:self.account.managedObjectContext]];
- if (!self.selectedProduct) {
- [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product.account == %@ AND rating == %@ AND unread = TRUE", self.account, [NSNumber numberWithInt:rating]]];
+
+ NSMutableString * pred = [NSMutableString stringWithString:@"rating == %@ AND unread = TRUE"];
+ NSMutableArray * args = [NSMutableArray arrayWithArray:self.selectedProducts];
+ [args insertObject:[NSNumber numberWithInt:rating] atIndex:0];
+
+ if (![self.selectedProducts count]) {
+ [pred appendString:@" AND product.account = %@"];
+ [args addObject:self.account];
+ [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:pred argumentArray:args]];
} else {
- [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"product == %@ AND rating == %@ AND unread = TRUE", self.selectedProduct, [NSNumber numberWithInt:rating]]];
+ [pred appendString:@" AND (product == nil"];
+ for (Product* p in self.selectedProducts) {
+ [pred appendString:@" OR product == %@"];
+ }
+ [pred appendString:@")"];
+ [reviewsCountFetchRequest setPredicate:[NSPredicate predicateWithFormat:pred argumentArray:args]];
}
NSUInteger numberOfUnreadReviewsForRating = [self.account.managedObjectContext countForFetchRequest:reviewsCountFetchRequest error:NULL];
return numberOfUnreadReviewsForRating;
@@ -145,7 +169,7 @@ - (void)reviewSummaryView:(ReviewSummaryView *)view didSelectRating:(NSInteger)r
{
if (!self.account) return;
- ReviewListViewController *vc = [[[ReviewListViewController alloc] initWithAccount:self.account product:self.selectedProduct rating:rating] autorelease];
+ ReviewListViewController *vc = [[[ReviewListViewController alloc] initWithAccount:self.account products:self.selectedProducts rating:rating] autorelease];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self.navigationController pushViewController:vc animated:YES];
} else {
@@ -155,12 +179,22 @@ - (void)reviewSummaryView:(ReviewSummaryView *)view didSelectRating:(NSInteger)r
}
}
+- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
+ [super tableView:tableView didDeselectRowAtIndexPath:indexPath];
+ [self.reviewSummaryView reloadDataAnimated:YES];
+}
+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[self.reviewSummaryView reloadDataAnimated:YES];
}
+- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
+ [super handleLongPress:gestureRecognizer];
+ [self.reviewSummaryView reloadDataAnimated:YES];
+}
+
- (void)dealloc
{
[reviewsPopover release];
67 Classes/SalesViewController.m
View
@@ -62,7 +62,7 @@ - (id)initWithAccount:(ASAccount *)anAccount
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadData) name:ASViewSettingsDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willShowPasscodeLock:) name:ASWillShowPasscodeLockNotification object:nil];
- }
+ }
return self;
}
@@ -533,26 +533,37 @@ - (NSString *)graphView:(GraphView *)graphView labelForBarAtIndex:(NSUInteger)in
report = [self.sortedCalendarMonthReports objectAtIndex:index];
}
}
- if (viewMode == DashboardViewModeRevenue) {
- float revenue = [report totalRevenueInBaseCurrencyForProductWithID:self.selectedProduct.productID];
- NSString *labelText = [NSString stringWithFormat:@"%@%i", [[CurrencyManager sharedManager] baseCurrencyDescription], (int)roundf(revenue)];
- return labelText;
- } else {
- int value = 0;
- if (viewMode == DashboardViewModeSales) {
- value = [report totalNumberOfPaidDownloadsForProductWithID:self.selectedProduct.productID];
- } else if (viewMode == DashboardViewModeUpdates) {
- value = [report totalNumberOfUpdatesForProductWithID:self.selectedProduct.productID];
- } else if (viewMode == DashboardViewModeEducationalSales) {
- value = [report totalNumberOfEducationalSalesForProductWithID:self.selectedProduct.productID];
- } else if (viewMode == DashboardViewModeGiftPurchases) {
- value = [report totalNumberOfGiftPurchasesForProductWithID:self.selectedProduct.productID];
- } else if (viewMode == DashboardViewModePromoCodes) {
- value = [report totalNumberOfPromoCodeTransactionsForProductWithID:self.selectedProduct.productID];
- }
- NSString *labelText = [NSString stringWithFormat:@"%i", value];
- return labelText;
- }
+
+ float value = 0;
+
+ NSArray* tProducts = ((self.selectedProducts) ? self.selectedProducts : self.visibleProducts);
+
+ for (Product * selectedProduct in tProducts) {
+ if (viewMode == DashboardViewModeRevenue) {
+ value += [report totalRevenueInBaseCurrencyForProductWithID:selectedProduct.productID];
+ } else {
+ if (viewMode == DashboardViewModeSales) {
+ value += [report totalNumberOfPaidDownloadsForProductWithID:selectedProduct.productID];
+ } else if (viewMode == DashboardViewModeUpdates) {
+ value += [report totalNumberOfUpdatesForProductWithID:selectedProduct.productID];
+ } else if (viewMode == DashboardViewModeEducationalSales) {
+ value += [report totalNumberOfEducationalSalesForProductWithID:selectedProduct.productID];
+ } else if (viewMode == DashboardViewModeGiftPurchases) {
+ value += [report totalNumberOfGiftPurchasesForProductWithID:selectedProduct.productID];
+ } else if (viewMode == DashboardViewModePromoCodes) {
+ value += [report totalNumberOfPromoCodeTransactionsForProductWithID:selectedProduct.productID];
+ }
+ }
+ }
+
+ NSString *labelText = @"";
+ if (viewMode == DashboardViewModeRevenue) {
+ labelText = [NSString stringWithFormat:@"%@%i", [[CurrencyManager sharedManager] baseCurrencyDescription], (int)roundf(value)];
+ } else {
+ labelText = [NSString stringWithFormat:@"%i", (int)value];
+ }
+
+ return labelText;
}
- (NSString *)graphView:(GraphView *)graphView labelForSectionAtIndex:(NSUInteger)index
@@ -590,7 +601,7 @@ - (NSArray *)stackedValuesForReport:(id<ReportSummary>)report
NSMutableArray *stackedValues = [NSMutableArray array];
for (Product *product in self.products) {
NSString *productID = product.productID;
- if (!self.selectedProduct || self.selectedProduct == product) {
+ if (!self.selectedProducts || [self.selectedProducts containsObject:product]) {
float valueForProduct = 0.0;
if (viewMode == DashboardViewModeRevenue) {
valueForProduct = [report totalRevenueInBaseCurrencyForProductWithID:productID];
@@ -630,7 +641,7 @@ - (void)graphView:(GraphView *)view didSelectBarAtIndex:(NSUInteger)index withFr
}
}
ReportDetailViewController *vc = [[[ReportDetailViewController alloc] initWithReports:reports selectedIndex:index] autorelease];
- vc.selectedProduct = self.selectedProduct;
+ vc.selectedProduct = [self.selectedProducts lastObject];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self.navigationController pushViewController:vc animated:YES];
} else {
@@ -759,6 +770,16 @@ - (void)selectAdvancedViewMode:(UILongPressGestureRecognizer *)gestureRecognizer
#pragma mark - Table view delegate
+- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
+ [super handleLongPress:gestureRecognizer];
+ [self.graphView reloadValuesAnimated:YES];
+}
+
+- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
+ [super tableView:tableView didDeselectRowAtIndexPath:indexPath];
+ [self.graphView reloadValuesAnimated:YES];
+}
+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
Please sign in to comment.
Something went wrong with that request. Please try again.