summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPaul Gardiner <paul.gardiner@artifex.com>2014-01-09 14:45:00 +0000
committerPaul Gardiner <paul.gardiner@artifex.com>2014-01-09 14:45:43 +0000
commitd7ea5f971b84a138697546cbdba8ad76f1bb760e (patch)
treea7eaf2ef7e043d14a039877a46db315993022cb0 /platform
parent7faadb8537042ac310e64274d5164fa7f2d05199 (diff)
downloadmupdf-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')
-rw-r--r--platform/ios/Classes/MuDocumentController.h4
-rw-r--r--platform/ios/Classes/MuDocumentController.m111
-rw-r--r--platform/ios/Classes/MuLibraryController.h1
-rw-r--r--platform/ios/Classes/MuLibraryController.m22
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");
}