mirror of
https://github.com/zxing/zxing.git
synced 2024-11-14 23:14:09 -08:00
ec506e27be
git-svn-id: https://zxing.googlecode.com/svn/trunk@1646 59b500cc-1b3d-0410-9834-0bbf25fbcc57
631 lines
22 KiB
Objective-C
631 lines
22 KiB
Objective-C
//
|
|
// DecoderViewController.m
|
|
// ZXing
|
|
//
|
|
// Created by Christian Brunschen on 22/05/2008.
|
|
/*
|
|
* Copyright 2008 ZXing authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#import "DecoderViewController.h"
|
|
#import "Decoder.h"
|
|
#import "NSString+HTML.h"
|
|
#import "ResultParser.h"
|
|
#import "ParsedResult.h"
|
|
#import "ResultAction.h"
|
|
|
|
#import "Database.h"
|
|
#import "ArchiveController.h"
|
|
#import "MessageViewController.h"
|
|
#import "Scan.h"
|
|
#import "TwoDDecoderResult.h"
|
|
|
|
// Michael Jurewitz, Dec 16, 2009 6:32 PM writes:
|
|
// https://devforums.apple.com/message/149553
|
|
// Notice Regarding UIGetScreenImage()
|
|
// After carefully considering the issue, Apple is now allowing applications to
|
|
// use the function UIGetScreenImage() to programmatically capture the current
|
|
// screen contents.
|
|
// Note that a future release of iPhone OS may provide a public API equivalent
|
|
// of this functionality. At such time, all applications using
|
|
// UIGetScreenImage() will be required to adopt the public API.
|
|
CGImageRef MyCGImageCopyScreenContents(void) {
|
|
extern CGImageRef UIGetScreenImage(void);
|
|
return UIGetScreenImage(); /* already retained */
|
|
}
|
|
|
|
@interface DecoderViewController()
|
|
- (void)takeScreenshot;
|
|
@end
|
|
|
|
@implementation DecoderViewController
|
|
|
|
@synthesize cameraBarItem;
|
|
@synthesize libraryBarItem;
|
|
@synthesize savedPhotosBarItem;
|
|
@synthesize archiveBarItem;
|
|
@synthesize actionBarItem;
|
|
|
|
@synthesize messageView;
|
|
@synthesize messageTextView;
|
|
@synthesize messageHelpButton;
|
|
@synthesize imageView;
|
|
@synthesize picker;
|
|
@synthesize toolbar;
|
|
|
|
@synthesize decoder;
|
|
@synthesize result;
|
|
@synthesize actions;
|
|
|
|
@synthesize resultPointViews;
|
|
|
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
|
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
|
|
// Initialization code
|
|
self.title =
|
|
NSLocalizedString(@"DecoderViewController AppTitle", @"Barcode Scanner");
|
|
|
|
Decoder *d = [[Decoder alloc] init];
|
|
self.decoder = d;
|
|
d.delegate = self;
|
|
[d release];
|
|
resultPointViews = [[NSMutableArray alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) messageReady:(id)sender {
|
|
MessageViewController *messageController = sender;
|
|
[[self navigationController] pushViewController:messageController animated:true];
|
|
[messageController release];
|
|
}
|
|
|
|
- (void) messageFailed:(id)sender {
|
|
MessageViewController *messageController = sender;
|
|
NSLog(@"Failed to load message!");
|
|
[messageController release];
|
|
}
|
|
|
|
- (void) showHints:(id)sender {
|
|
NSLog(@"Showing Hints!");
|
|
|
|
MessageViewController *hintsController =
|
|
[[MessageViewController alloc] initWithMessageFilename:@"Hints"
|
|
target:self
|
|
onSuccess:@selector(messageReady:)
|
|
onFailure:@selector(messageFailed:)];
|
|
hintsController.title =
|
|
NSLocalizedString(@"DecoderViewController Hints MessageViewController title", @"Hints");
|
|
[hintsController view];
|
|
}
|
|
|
|
- (void) showAbout:(id)sender {
|
|
NSLog(@"Showing About!");
|
|
|
|
MessageViewController *aboutController =
|
|
[[MessageViewController alloc] initWithMessageFilename:@"About"
|
|
target:self
|
|
onSuccess:@selector(messageReady:)
|
|
onFailure:@selector(messageFailed:)];
|
|
aboutController.title =
|
|
NSLocalizedString(@"DecoderViewController About MessageViewController title", @"About");
|
|
[aboutController view];
|
|
}
|
|
|
|
|
|
#define HELP_BUTTON_WIDTH (44.0)
|
|
#define HELP_BUTTON_HEIGHT (55.0)
|
|
|
|
|
|
#define FONT_NAME @"TimesNewRomanPSMT"
|
|
#define FONT_SIZE 16.0
|
|
|
|
- (void) reset {
|
|
self.result = nil;
|
|
[self clearImageView];
|
|
[self updateToolbar];
|
|
[self showMessage:NSLocalizedString(@"DecoderViewController take or choose picture",
|
|
@"Please take or choose a picture containing a barcode") helpButton:YES];
|
|
}
|
|
|
|
// Implement loadView if you want to create a view hierarchy programmatically
|
|
- (void)loadView {
|
|
[super loadView];
|
|
|
|
CGRect messageViewFrame = imageView.frame;
|
|
UIView *mView = [[UIView alloc] initWithFrame:messageViewFrame];
|
|
mView.backgroundColor = [UIColor darkGrayColor];
|
|
mView.alpha = 0.9;
|
|
mView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
|
|
UIViewAutoresizingFlexibleWidth |
|
|
UIViewAutoresizingFlexibleTopMargin;
|
|
|
|
UITextView *mTextView = [[UITextView alloc] initWithFrame:messageViewFrame];
|
|
mTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
|
|
UIViewAutoresizingFlexibleWidth;
|
|
mTextView.editable = false;
|
|
mTextView.scrollEnabled = true;
|
|
mTextView.font = [UIFont fontWithName:FONT_NAME size:FONT_SIZE];
|
|
mTextView.textColor = [UIColor whiteColor];
|
|
mTextView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.0];
|
|
mTextView.textAlignment = UITextAlignmentLeft;
|
|
mTextView.alpha = 1.0;
|
|
[mView addSubview:mTextView];
|
|
|
|
UIButton *mHelpButton = [[UIButton buttonWithType:UIButtonTypeInfoLight] retain];
|
|
mHelpButton.frame = CGRectMake(messageViewFrame.size.width - HELP_BUTTON_WIDTH, 0.0, HELP_BUTTON_WIDTH, HELP_BUTTON_HEIGHT);
|
|
|
|
mHelpButton.backgroundColor = [UIColor clearColor];
|
|
[mHelpButton setUserInteractionEnabled:YES];
|
|
[mHelpButton addTarget:self action:@selector(showHints:) forControlEvents:UIControlEventTouchUpInside];
|
|
|
|
self.messageHelpButton = mHelpButton;
|
|
[mHelpButton release];
|
|
|
|
self.messageTextView = mTextView;
|
|
[mTextView release];
|
|
|
|
self.messageView = mView;
|
|
[mView release];
|
|
|
|
[self.view addSubview:self.messageView];
|
|
|
|
// add the 'About' button at the top-right of the navigation bar
|
|
UIBarButtonItem *aboutButton =
|
|
[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"DecoderViewController about button title", @"About")
|
|
style:UIBarButtonItemStyleBordered
|
|
target:self
|
|
action:@selector(showAbout:)];
|
|
self.navigationItem.rightBarButtonItem = aboutButton;
|
|
[aboutButton release];
|
|
|
|
[self reset];
|
|
}
|
|
|
|
- (void) updateToolbar {
|
|
self.cameraBarItem.enabled = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
|
|
self.savedPhotosBarItem.enabled = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
|
|
self.libraryBarItem.enabled = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary];
|
|
self.archiveBarItem.enabled = true;
|
|
self.actionBarItem.enabled = (self.result != nil) && ([self.result actions] != nil) && ([self.result actions].count > 0);
|
|
}
|
|
|
|
|
|
// If you need to do additional setup after loading the view, override viewDidLoad.
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
}
|
|
|
|
|
|
- (void)clearImageView {
|
|
imageView.image = nil;
|
|
for (UIView *view in resultPointViews) {
|
|
[view removeFromSuperview];
|
|
}
|
|
[resultPointViews removeAllObjects];
|
|
}
|
|
|
|
- (void)pickAndDecodeFromSource:(UIImagePickerControllerSourceType) sourceType {
|
|
[self reset];
|
|
|
|
// Create the Image Picker
|
|
if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
|
|
UIImagePickerController* aPicker =
|
|
[[[UIImagePickerController alloc] init] autorelease];
|
|
aPicker.sourceType = sourceType;
|
|
aPicker.delegate = self;
|
|
self.picker = aPicker;
|
|
|
|
// [[NSUserDefaults standardUserDefaults] boolForKey:@"allowEditing"];
|
|
BOOL isCamera = (sourceType == UIImagePickerControllerSourceTypeCamera);
|
|
if ([picker respondsToSelector:@selector(setAllowsEditing:)]) {
|
|
// not in 3.0
|
|
[picker setAllowsEditing:!isCamera];
|
|
}
|
|
if (isCamera) {
|
|
if ([picker respondsToSelector:@selector(setShowsCameraControls:)]) {
|
|
[picker setShowsCameraControls:NO];
|
|
UIButton *cancelButton =
|
|
[UIButton buttonWithType:UIButtonTypeRoundedRect];
|
|
NSString *cancelString =
|
|
NSLocalizedString(@"DecoderViewController cancel button title", @"");
|
|
CGFloat height = [UIFont systemFontSize];
|
|
CGSize size =
|
|
[cancelString sizeWithFont:[UIFont systemFontOfSize:height]];
|
|
[cancelButton setTitle:cancelString forState:UIControlStateNormal];
|
|
CGRect appFrame = [[UIScreen mainScreen] bounds];
|
|
static const int kMargin = 10;
|
|
static const int kInternalXMargin = 10;
|
|
static const int kInternalYMargin = 10;
|
|
CGRect frame = CGRectMake(kMargin,
|
|
appFrame.size.height - (height + 2*kInternalYMargin + kMargin),
|
|
2*kInternalXMargin + size.width,
|
|
height + 2*kInternalYMargin);
|
|
[cancelButton setFrame:frame];
|
|
[cancelButton addTarget:self
|
|
action:@selector(cancel:)
|
|
forControlEvents:UIControlEventTouchUpInside];
|
|
picker.cameraOverlayView = cancelButton;
|
|
// The camera takes quite a while to start up. Hence the 2 second delay.
|
|
[self performSelector:@selector(takeScreenshot)
|
|
withObject:nil
|
|
afterDelay:2.0];
|
|
}
|
|
}
|
|
|
|
// Picker is displayed asynchronously.
|
|
[self presentModalViewController:picker animated:YES];
|
|
} else {
|
|
NSLog(@"Attempted to pick an image with illegal source type '%d'", sourceType);
|
|
}
|
|
}
|
|
|
|
- (IBAction)pickAndDecode:(id) sender {
|
|
UIImagePickerControllerSourceType sourceType;
|
|
int i = [sender tag];
|
|
|
|
switch (i) {
|
|
case 0: sourceType = UIImagePickerControllerSourceTypeCamera; break;
|
|
case 1: sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; break;
|
|
case 2: sourceType = UIImagePickerControllerSourceTypePhotoLibrary; break;
|
|
default: sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
|
|
}
|
|
[self pickAndDecodeFromSource:sourceType];
|
|
}
|
|
|
|
|
|
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
|
// Return YES for supported orientations
|
|
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
|
}
|
|
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
|
|
// Release anything that's not essential, such as cached data
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[decoder release];
|
|
[self clearImageView];
|
|
[imageView release];
|
|
[actionBarItem release];
|
|
[cameraBarItem release];
|
|
[libraryBarItem release];
|
|
[savedPhotosBarItem release];
|
|
[archiveBarItem release];
|
|
[toolbar release];
|
|
[picker release];
|
|
[actions release];
|
|
[resultPointViews release];
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)showMessage:(NSString *)message helpButton:(BOOL)showHelpButton {
|
|
#ifdef DEBUG
|
|
NSLog(@"Showing message '%@' %@ help Button", message, showHelpButton ? @"with" : @"without");
|
|
#endif
|
|
|
|
CGSize imageMaxSize = imageView.bounds.size;
|
|
if (showHelpButton) {
|
|
imageMaxSize.width -= messageHelpButton.frame.size.width;
|
|
}
|
|
CGSize size = [message sizeWithFont:messageTextView.font constrainedToSize:imageMaxSize lineBreakMode:UILineBreakModeWordWrap];
|
|
float height = 20.0 + fmin(100.0, size.height);
|
|
if (showHelpButton) {
|
|
height = fmax(HELP_BUTTON_HEIGHT, height);
|
|
}
|
|
|
|
CGRect messageFrame = imageView.bounds;
|
|
messageFrame.origin.y = CGRectGetMaxY(messageFrame) - height;
|
|
messageFrame.size.height = height;
|
|
[self.messageView setFrame:messageFrame];
|
|
messageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
|
|
CGRect messageViewBounds = [messageView bounds];
|
|
|
|
self.messageTextView.text = message;
|
|
messageTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
if (showHelpButton) {
|
|
CGRect textViewFrame;
|
|
CGRect helpButtonFrame;
|
|
|
|
CGRectDivide(messageViewBounds, &helpButtonFrame, &textViewFrame, HELP_BUTTON_WIDTH, CGRectMaxXEdge);
|
|
[self.messageTextView setFrame:textViewFrame];
|
|
|
|
[messageHelpButton setFrame:helpButtonFrame];
|
|
messageHelpButton.alpha = 1.0;
|
|
messageHelpButton.enabled = YES;
|
|
messageHelpButton.autoresizingMask =
|
|
UIViewAutoresizingFlexibleLeftMargin |
|
|
UIViewAutoresizingFlexibleTopMargin;
|
|
[messageView addSubview:messageHelpButton];
|
|
} else {
|
|
[messageHelpButton removeFromSuperview];
|
|
messageHelpButton.alpha = 0.0;
|
|
messageHelpButton.enabled = NO;
|
|
|
|
[self.messageTextView setFrame:messageViewBounds];
|
|
}
|
|
}
|
|
|
|
// DecoderDelegate methods
|
|
|
|
- (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset{
|
|
[self clearImageView];
|
|
[self.imageView setImage:subset];
|
|
[self showMessage:[NSString stringWithFormat:NSLocalizedString(@"DecoderViewController MessageWhileDecodingWithDimensions", @"Decoding image (%.0fx%.0f) ..."), image.size.width, image.size.height]
|
|
helpButton:NO];
|
|
}
|
|
|
|
- (void)decoder:(Decoder *)decoder
|
|
decodingImage:(UIImage *)image
|
|
usingSubset:(UIImage *)subset
|
|
progress:(NSString *)message {
|
|
[self clearImageView];
|
|
[self.imageView setImage:subset];
|
|
[self showMessage:message helpButton:NO];
|
|
}
|
|
|
|
- (void)presentResultForString:(NSString *)resultString {
|
|
self.result = [ResultParser parsedResultForString:resultString];
|
|
[self showMessage:[self.result stringForDisplay] helpButton:NO];
|
|
self.actions = self.result.actions;
|
|
#ifdef DEBUG
|
|
NSLog(@"result has %d actions", actions ? 0 : actions.count);
|
|
#endif
|
|
[self updateToolbar];
|
|
}
|
|
|
|
- (void)presentResultPoints:(NSArray *)resultPoints
|
|
forImage:(UIImage *)image
|
|
usingSubset:(UIImage *)subset {
|
|
// simply add the points to the image view
|
|
imageView.image = subset;
|
|
for (NSValue *pointValue in resultPoints) {
|
|
[imageView addResultPoint:[pointValue CGPointValue]];
|
|
}
|
|
}
|
|
|
|
- (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)twoDResult {
|
|
self.picker = nil;
|
|
[self presentResultForString:twoDResult.text];
|
|
|
|
[self presentResultPoints:twoDResult.points forImage:image usingSubset:subset];
|
|
|
|
// save the scan to the shared database
|
|
[[Database sharedDatabase] addScanWithText:twoDResult.text];
|
|
|
|
[self performResultAction:self];
|
|
}
|
|
|
|
- (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason {
|
|
if (self.picker && UIImagePickerControllerSourceTypeCamera == self.picker.sourceType) {
|
|
// If we are using the camera, and the user hasn't manually cancelled,
|
|
// take another snapshot and try to decode it.
|
|
[self takeScreenshot];
|
|
} else {
|
|
[self showMessage:reason helpButton:YES];
|
|
[self updateToolbar];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
|
|
[super willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
|
|
|
|
if (imageView.image) {
|
|
/*
|
|
CGRect viewBounds = imageView.bounds;
|
|
CGSize imageSize = imageView.image.size;
|
|
float scale = fmin(viewBounds.size.width / imageSize.width,
|
|
viewBounds.size.height / imageSize.height);
|
|
float xOffset = (viewBounds.size.width - scale * imageSize.width) / 2.0;
|
|
float yOffset = (viewBounds.size.height - scale * imageSize.height) / 2.0;
|
|
*/
|
|
|
|
for (UIView *view in resultPointViews) {
|
|
view.alpha = 0.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration {
|
|
[super willAnimateSecondHalfOfRotationFromInterfaceOrientation:fromInterfaceOrientation duration:duration];
|
|
|
|
if (imageView.image) {
|
|
/*
|
|
CGRect viewBounds = imageView.bounds;
|
|
CGSize imageSize = imageView.image.size;
|
|
float scale = fmin(viewBounds.size.width / imageSize.width,
|
|
viewBounds.size.height / imageSize.height);
|
|
float xOffset = (viewBounds.size.width - scale * imageSize.width) / 2.0;
|
|
float yOffset = (viewBounds.size.height - scale * imageSize.height) / 2.0;
|
|
*/
|
|
|
|
for (UIView *view in resultPointViews) {
|
|
view.alpha = 1.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)cancel:(id)sender {
|
|
self.picker = nil;
|
|
}
|
|
|
|
- (void)takeScreenshot {
|
|
if (picker) {
|
|
CGImageRef cgScreen = MyCGImageCopyScreenContents();
|
|
if (cgScreen) {
|
|
CGRect croppedFrame = CGRectMake(0, 0, CGImageGetWidth(cgScreen),
|
|
CGImageGetHeight(cgScreen) - (10+toolbar.bounds.size.height));
|
|
CGImageRef cgCropped = CGImageCreateWithImageInRect(cgScreen, croppedFrame);
|
|
if (cgCropped) {
|
|
UIImage *screenshot = [UIImage imageWithCGImage:cgCropped];
|
|
CGImageRelease(cgCropped);
|
|
[self.decoder decodeImage:screenshot];
|
|
}
|
|
CGImageRelease(cgScreen);
|
|
}
|
|
}
|
|
}
|
|
|
|
// UIImagePickerControllerDelegate methods
|
|
|
|
- (void)imagePickerController:(UIImagePickerController *)aPicker
|
|
didFinishPickingMediaWithInfo:(NSDictionary *)info {
|
|
UIImage *imageToDecode =
|
|
[info objectForKey:UIImagePickerControllerEditedImage];
|
|
if (!imageToDecode) {
|
|
imageToDecode = [info objectForKey:UIImagePickerControllerOriginalImage];
|
|
}
|
|
CGSize size = [imageToDecode size];
|
|
CGRect cropRect = CGRectMake(0.0, 0.0, size.width, size.height);
|
|
|
|
#ifdef DEBUG
|
|
NSLog(@"picked image size = (%f, %f)", size.width, size.height);
|
|
#endif
|
|
NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
|
|
|
|
NSValue *cropRectValue = [info objectForKey:UIImagePickerControllerCropRect];
|
|
if (cropRectValue) {
|
|
UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
|
|
if (originalImage) {
|
|
#ifdef DEBUG
|
|
NSLog(@"original image size = (%f, %f)", originalImage.size.width, originalImage.size.height);
|
|
#endif
|
|
cropRect = [cropRectValue CGRectValue];
|
|
#ifdef DEBUG
|
|
NSLog(@"crop rect = (%f, %f) x (%f, %f)", CGRectGetMinX(cropRect), CGRectGetMinY(cropRect), CGRectGetWidth(cropRect), CGRectGetHeight(cropRect));
|
|
#endif
|
|
if (([picker sourceType] == UIImagePickerControllerSourceTypeSavedPhotosAlbum) &&
|
|
[@"2.1" isEqualToString:systemVersion]) {
|
|
// adjust crop rect to work around bug in iPhone OS 2.1 when selecting from the photo roll
|
|
cropRect.origin.x *= 2.5;
|
|
cropRect.origin.y *= 2.5;
|
|
cropRect.size.width *= 2.5;
|
|
cropRect.size.height *= 2.5;
|
|
#ifdef DEBUG
|
|
NSLog(@"2.1-adjusted crop rect = (%f, %f) x (%f, %f)", CGRectGetMinX(cropRect), CGRectGetMinY(cropRect), CGRectGetWidth(cropRect), CGRectGetHeight(cropRect));
|
|
#endif
|
|
}
|
|
|
|
imageToDecode = originalImage;
|
|
}
|
|
}
|
|
|
|
[imageToDecode retain];
|
|
self.picker = nil;
|
|
[self.decoder decodeImage:imageToDecode cropRect:cropRect];
|
|
[imageToDecode release];
|
|
}
|
|
|
|
|
|
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)aPicker {
|
|
self.picker = nil;
|
|
}
|
|
|
|
- (void)setPicker:(UIImagePickerController *)aPicker {
|
|
if (picker != aPicker) {
|
|
[picker dismissModalViewControllerAnimated:YES];
|
|
picker = [aPicker retain];
|
|
[self updateToolbar];
|
|
}
|
|
}
|
|
|
|
- (void)navigationController:(UINavigationController *)navigationController
|
|
didShowViewController:(UIViewController *)viewController
|
|
animated:(BOOL)animated {
|
|
// no-op
|
|
}
|
|
|
|
- (void)navigationController:(UINavigationController *)navigationController
|
|
willShowViewController:(UIViewController *)viewController
|
|
animated:(BOOL)animated {
|
|
// no-op
|
|
}
|
|
|
|
- (void)performAction:(ResultAction *)action {
|
|
[action performActionWithController:self shouldConfirm:NO];
|
|
}
|
|
|
|
- (void)confirmAndPerformAction:(ResultAction *)action {
|
|
[action performActionWithController:self shouldConfirm:YES];
|
|
}
|
|
|
|
|
|
- (IBAction)performResultAction:(id)sender {
|
|
if (self.result == nil) {
|
|
NSLog(@"no result to perform an action on!");
|
|
return;
|
|
}
|
|
|
|
if (self.actions == nil || self.actions.count == 0) {
|
|
NSLog(@"result has no actions to perform!");
|
|
return;
|
|
}
|
|
|
|
if (self.actions.count == 1) {
|
|
ResultAction *action = [self.actions lastObject];
|
|
#ifdef DEBUG
|
|
NSLog(@"Result has the single action, (%@) '%@', performing it",
|
|
NSStringFromClass([action class]), [action title]);
|
|
#endif
|
|
[self performSelector:@selector(confirmAndPerformAction:)
|
|
withObject:action
|
|
afterDelay:0.0];
|
|
} else {
|
|
#ifdef DEBUG
|
|
NSLog(@"Result has multiple actions, popping up an action sheet");
|
|
#endif
|
|
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithFrame:self.view.bounds];
|
|
|
|
for (ResultAction *action in self.actions) {
|
|
[actionSheet addButtonWithTitle:[action title]];
|
|
}
|
|
|
|
int cancelIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"DecoderViewController cancel button title", @"Cancel")];
|
|
actionSheet.cancelButtonIndex = cancelIndex;
|
|
|
|
actionSheet.delegate = self;
|
|
|
|
[actionSheet showFromToolbar:self.toolbar];
|
|
}
|
|
}
|
|
|
|
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
|
|
if (buttonIndex < self.actions.count) {
|
|
int actionIndex = buttonIndex;
|
|
ResultAction *action = [self.actions objectAtIndex:actionIndex];
|
|
[self performSelector:@selector(performAction:)
|
|
withObject:action
|
|
afterDelay:0.0];
|
|
}
|
|
}
|
|
|
|
- (IBAction)showArchive:(id)sender {
|
|
ArchiveController *archiveController = [[ArchiveController alloc] initWithDecoderViewController:self];
|
|
[[self navigationController] pushViewController:archiveController animated:true];
|
|
[archiveController release];
|
|
}
|
|
|
|
- (void)showScan:(Scan *)scan {
|
|
[self clearImageView];
|
|
[self presentResultForString:scan.text];
|
|
[[self navigationController] popToViewController:self animated:YES];
|
|
}
|
|
|
|
@end
|