diff options
author | Paul Gardiner <paul.gardiner@artifex.com> | 2014-01-09 14:45:00 +0000 |
---|---|---|
committer | Paul Gardiner <paul.gardiner@artifex.com> | 2014-01-09 14:45:43 +0000 |
commit | d7ea5f971b84a138697546cbdba8ad76f1bb760e (patch) | |
tree | a7eaf2ef7e043d14a039877a46db315993022cb0 /platform/ios/Classes | |
parent | 7faadb8537042ac310e64274d5164fa7f2d05199 (diff) | |
download | mupdf-d7ea5f971b84a138697546cbdba8ad76f1bb760e.tar.xz |
iOS: save changes on returning to the library
Also change the way the back button works, using an explicit action, rather
than relying on the navigation controller. Doing so allowed an alert dialog to
be displayed asking if document changes should be discarded or saved.
It also allowed the word-based button to be replaced by an icon-based one,
which saves space (important for iPod and iPhone).
We may want to also save on other occasions, but this at least provides some
way to do so.
Diffstat (limited to 'platform/ios/Classes')
-rw-r--r-- | platform/ios/Classes/MuDocumentController.h | 4 | ||||
-rw-r--r-- | platform/ios/Classes/MuDocumentController.m | 111 | ||||
-rw-r--r-- | platform/ios/Classes/MuLibraryController.h | 1 | ||||
-rw-r--r-- | platform/ios/Classes/MuLibraryController.m | 22 |
4 files changed, 127 insertions, 11 deletions
diff --git a/platform/ios/Classes/MuDocumentController.h b/platform/ios/Classes/MuDocumentController.h index 719fcd5e..d8fd7000 100644 --- a/platform/ios/Classes/MuDocumentController.h +++ b/platform/ios/Classes/MuDocumentController.h @@ -34,6 +34,7 @@ enum fz_document *doc; MuDocRef *docRef; NSString *key; + char *filePath; BOOL reflowMode; MuOutlineController *outline; UIScrollView *canvas; @@ -47,6 +48,7 @@ enum UIBarButtonItem *tickButton; UIBarButtonItem *deleteButton; UIBarButtonItem *reflowButton; + UIBarButtonItem *backButton; UIBarButtonItem *sliderWrapper; int barmode; int searchPage; @@ -58,7 +60,7 @@ enum int scroll_animating; // stop view updates during scrolling animations float scale; // scale applied to views (only used in reflow mode) } -- (id) initWithFilename: (NSString*)nsfilename document: (MuDocRef *)aDoc; +- (id) initWithFilename: (NSString*)nsfilename path:(char *)cstr document:(MuDocRef *)aDoc; - (void) createPageView: (int)number; - (void) gotoPage: (int)number animated: (BOOL)animated; - (void) onShowOutline: (id)sender; diff --git a/platform/ios/Classes/MuDocumentController.m b/platform/ios/Classes/MuDocumentController.m index 49448df1..d08b5950 100644 --- a/platform/ios/Classes/MuDocumentController.m +++ b/platform/ios/Classes/MuDocumentController.m @@ -44,9 +44,88 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out } } +static char *tmp_path(char *path) +{ + int f; + char *buf = malloc(strlen(path) + 6 + 1); + if (!buf) + return NULL; + + strcpy(buf, path); + strcat(buf, "XXXXXX"); + + f = mkstemp(buf); + + if (f >= 0) + { + close(f); + return buf; + } + else + { + free(buf); + return NULL; + } +} + +static void saveDoc(char *current_path, fz_document *doc) +{ + char *tmp; + fz_write_options opts; + opts.do_incremental = 1; + opts.do_ascii = 0; + opts.do_expand = 0; + opts.do_garbage = 0; + opts.do_linear = 0; + + tmp = tmp_path(current_path); + if (tmp) + { + int written = 0; + + fz_var(written); + fz_try(ctx) + { + FILE *fin = fopen(current_path, "rb"); + FILE *fout = fopen(tmp, "wb"); + char buf[256]; + int n, err = 1; + + if (fin && fout) + { + while ((n = fread(buf, 1, sizeof(buf), fin)) > 0) + fwrite(buf, 1, n, fout); + err = (ferror(fin) || ferror(fout)); + } + + if (fin) + fclose(fin); + if (fout) + fclose(fout); + + if (!err) + { + fz_write_document(doc, tmp, &opts); + written = 1; + } + } + fz_catch(ctx) + { + written = 0; + } + + if (written) + { + rename(tmp, current_path); + } + + free(tmp); + } +} + @implementation MuDocumentController -- (id) initWithFilename: (NSString*)filename document: (MuDocRef *)aDoc +- (id) initWithFilename: (NSString*)filename path:(char *)cstr document: (MuDocRef *)aDoc { self = [super init]; if (!self) @@ -59,6 +138,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out key = [filename retain]; docRef = [aDoc retain]; doc = docRef->doc; + filePath = strdup(cstr); dispatch_sync(queue, ^{}); @@ -92,6 +172,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [array addObject:reflowButton]; [array addObject:linkButton]; [[self navigationItem] setRightBarButtonItems: array ]; + [[self navigationItem] setLeftBarButtonItem:backButton]; } - (void) loadView @@ -168,6 +249,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out tickButton = [self resourceBasedButton:@"ic_check" withAction:@selector(onTick:)]; deleteButton = [self resourceBasedButton:@"ic_trash" withAction:@selector(onDelete:)]; searchBar = [[UISearchBar alloc] initWithFrame: CGRectMake(0,0,50,32)]; + backButton = [self resourceBasedButton:@"ic_arrow_left" withAction:@selector(onBack:)]; [searchBar setPlaceholder: @"Search"]; [searchBar setDelegate: self]; @@ -203,6 +285,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [tickButton release]; tickButton = nil; [deleteButton release]; deleteButton = nil; [canvas release]; canvas = nil; + free(filePath); filePath = NULL; [outline release]; [key release]; @@ -479,7 +562,6 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out case BARMODE_ANNOTATION: [[self navigationItem] setTitleView: nil]; [self addMainMenuButtons]; - [[self navigationItem] setLeftBarButtonItem: nil]; barmode = BARMODE_MAIN; break; @@ -498,6 +580,31 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out } } +- (void) onBack: (id)sender +{ + pdf_document *idoc = pdf_specifics(doc); + if (idoc && pdf_has_unsaved_changes(idoc)) + { + UIAlertView *saveAlert = [[UIAlertView alloc] + initWithTitle:@"Save changes?" message:nil delegate:self + cancelButtonTitle:@"Discard" otherButtonTitles:@"Save", nil]; + [saveAlert show]; + } + else + { + [[self navigationController] popViewControllerAnimated:YES]; + } +} + +- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == 1) + saveDoc(filePath, doc); + + [alertView dismissWithClickedButtonIndex:buttonIndex animated:YES]; + [[self navigationController] popViewControllerAnimated:YES]; +} + - (void) resetSearch { searchPage = -1; diff --git a/platform/ios/Classes/MuLibraryController.h b/platform/ios/Classes/MuLibraryController.h index 0f823d5d..d95f1652 100644 --- a/platform/ios/Classes/MuLibraryController.h +++ b/platform/ios/Classes/MuLibraryController.h @@ -21,6 +21,7 @@ NSTimer *timer; MuDocRef *doc; NSString *_filename; + char *_filePath; } - (void) openDocument: (NSString*)filename; - (void) askForPassword: (NSString*)prompt; diff --git a/platform/ios/Classes/MuLibraryController.m b/platform/ios/Classes/MuLibraryController.m index 7f21b303..f5e93351 100644 --- a/platform/ios/Classes/MuLibraryController.m +++ b/platform/ios/Classes/MuLibraryController.m @@ -153,19 +153,23 @@ static void showAlert(NSString *msg, NSString *filename) - (void) openDocument: (NSString*)nsfilename { - char filename[PATH_MAX]; + NSString *nspath = [[NSArray arrayWithObjects:NSHomeDirectory(), @"Documents", nsfilename, nil] + componentsJoinedByString:@"/"]; + _filePath = malloc(strlen([nspath UTF8String])+1); + if (_filePath == NULL) { + showAlert(@"Out of memory in openDocument", nsfilename); + return; + } - dispatch_sync(queue, ^{}); + strcpy(_filePath, [nspath UTF8String]); - strcpy(filename, [NSHomeDirectory() UTF8String]); - strcat(filename, "/Documents/"); - strcat(filename, [nsfilename UTF8String]); + dispatch_sync(queue, ^{}); - printf("open document '%s'\n", filename); + printf("open document '%s'\n", _filePath); _filename = [nsfilename retain]; [doc release]; - doc = [[MuDocRef alloc] initWithFilename:filename]; + doc = [[MuDocRef alloc] initWithFilename:_filePath]; if (!doc) { showAlert(@"Cannot open document", nsfilename); return; @@ -206,18 +210,20 @@ static void showAlert(NSString *msg, NSString *filename) - (void) onPasswordOkay { - MuDocumentController *document = [[MuDocumentController alloc] initWithFilename: _filename document: doc]; + MuDocumentController *document = [[MuDocumentController alloc] initWithFilename: _filename path:_filePath document: doc]; if (document) { [self setTitle: @"Library"]; [[self navigationController] pushViewController: document animated: YES]; [document release]; } [_filename release]; + free(_filePath); } - (void) onPasswordCancel { [_filename release]; + free(_filePath); printf("close document (password cancel)\n"); } |