diff options
-rw-r--r-- | apps/jstest_main.c | 4 | ||||
-rw-r--r-- | apps/pdfapp.c | 70 | ||||
-rw-r--r-- | apps/pdfapp.h | 2 | ||||
-rw-r--r-- | apps/win_main.c | 63 | ||||
-rw-r--r-- | apps/x11_main.c | 5 |
5 files changed, 130 insertions, 14 deletions
diff --git a/apps/jstest_main.c b/apps/jstest_main.c index ff7f9497..b5d90144 100644 --- a/apps/jstest_main.c +++ b/apps/jstest_main.c @@ -107,6 +107,10 @@ int wingetsavepath(pdfapp_t *app, char *buf, int len) return 0; } +void winreplacefile(char *source, char *target) +{ +} + void wincursor(pdfapp_t *app, int curs) { } diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 598b40b5..9760385b 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -187,6 +187,7 @@ void pdfapp_open(pdfapp_t *app, char *filename, int reload) } } + app->docpath = fz_strdup(ctx, filename); app->doctitle = filename; if (strrchr(app->doctitle, '\\')) app->doctitle = strrchr(app->doctitle, '\\') + 1; @@ -248,6 +249,10 @@ void pdfapp_close(pdfapp_t *app) fz_free(app->ctx, app->doctitle); app->doctitle = NULL; + if (app->docpath) + fz_free(app->ctx, app->docpath); + app->docpath = NULL; + if (app->image) fz_drop_pixmap(app->ctx, app->image); app->image = NULL; @@ -277,6 +282,32 @@ void pdfapp_close(pdfapp_t *app) fz_flush_warnings(app->ctx); } +static int gen_tmp_file(char *buf, int len) +{ + int i; + char *name = strrchr(buf, '/'); + + if (name == NULL) + name = strrchr(buf, '\\'); + + if (name != NULL) + name++; + else + name = buf; + + for (i = 0; i < 10000; i++) + { + FILE *f; + snprintf(name, buf+len-name, "tmp%04d", i); + f = fopen(buf, "r"); + if (f == NULL) + return 1; + fclose(f); + } + + return 0; +} + static int pdfapp_save(pdfapp_t *app) { char buf[PATH_MAX]; @@ -290,7 +321,44 @@ static int pdfapp_save(pdfapp_t *app) opts.do_garbage = 1; opts.do_linear = 0; - fz_write_document(app->doc, buf, &opts); + if (strcmp(buf, app->docpath) == 0) + { + if (gen_tmp_file(buf, PATH_MAX)) + { + int written; + + fz_var(written); + fz_try(app->ctx) + { + fz_write_document(app->doc, buf, &opts); + written = 1; + } + fz_catch(app->ctx) + { + written = 0; + } + + if (written) + { + char buf2[PATH_MAX]; + strncpy(buf2, app->docpath, PATH_MAX); + pdfapp_close(app); + winreplacefile(buf, buf2); + pdfapp_open(app, buf2, 1); + } + + return written; + } + else + { + return 0; + } + } + else + { + fz_write_document(app->doc, buf, &opts); + return 1; + } return 1; } diff --git a/apps/pdfapp.h b/apps/pdfapp.h index 2cdceb39..22e4ba67 100644 --- a/apps/pdfapp.h +++ b/apps/pdfapp.h @@ -40,11 +40,13 @@ extern int wingetsavepath(pdfapp_t*, char *buf, int len); extern void winalert(pdfapp_t *, fz_alert_event *alert); extern void winprint(pdfapp_t *); extern void winadvancetimer(pdfapp_t *, float duration); +extern void winreplacefile(char *source, char *target); struct pdfapp_s { /* current document params */ fz_document *doc; + char *docpath; char *doctitle; fz_outline *outline; diff --git a/apps/win_main.c b/apps/win_main.c index 165cbd07..3ae482ec 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -19,6 +19,8 @@ #define WM_MOUSEWHEEL 0x020A #endif +#define MIN(x,y) ((x) < (y) ? (x) : (y)) + #define ID_ABOUT 0x1000 #define ID_DOCINFO 0x1001 @@ -37,8 +39,10 @@ static int justcopied = 0; static pdfapp_t gapp; -static wchar_t wbuf[1024]; -static char filename[1024]; +#define PATH_MAX (1024) + +static wchar_t wbuf[PATH_MAX]; +static char filename[PATH_MAX]; /* * Create registry keys to associate MuPDF with PDF and XPS files. @@ -189,24 +193,30 @@ int winfilename(wchar_t *buf, int len) int wingetsavepath(pdfapp_t *app, char *buf, int len) { - OPENFILENAMEA ofn; - buf[0] = 0; - if (strlen(filename) < (unsigned int)len) - strcpy(buf, filename); + wchar_t twbuf[PATH_MAX]; + OPENFILENAME ofn; + + wcscpy(twbuf, wbuf); memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwndframe; - ofn.lpstrFile = buf; - ofn.nMaxFile = len; + ofn.lpstrFile = twbuf; + ofn.nMaxFile = PATH_MAX; ofn.lpstrInitialDir = NULL; - ofn.lpstrTitle = "MuPDF: Save PDF file"; - ofn.lpstrFilter = "Documents (*.pdf;*.xps;*.cbz;*.zip)\0*.zip;*.cbz;*.xps;*.pdf\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0All Files\0*\0\0"; + ofn.lpstrTitle = L"MuPDF: Save PDF file"; + ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.zip)\0*.zip;*.cbz;*.xps;*.pdf\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0All Files\0*\0\0"; ofn.Flags = OFN_HIDEREADONLY; - if (GetSaveFileNameA(&ofn)) + if (GetSaveFileName(&ofn)) { - if (strlen(buf) < sizeof(filename)) - strcpy(filename, buf); + int code = WideCharToMultiByte(CP_UTF8, 0, twbuf, -1, buf, MIN(PATH_MAX, len), NULL, NULL); + if (code == 0) + { + winerror(&gapp, "cannot convert filename to utf-8"); + return 0; + } + wcscpy(wbuf, twbuf); + strcpy(filename, buf); return 1; } else @@ -215,6 +225,33 @@ int wingetsavepath(pdfapp_t *app, char *buf, int len) } } +void winreplacefile(char *source, char *target) +{ + wchar_t wsource[PATH_MAX]; + wchar_t wtarget[PATH_MAX]; + + int sz = MultiByteToWideChar(CP_UTF8, 0, source, -1, wsource, PATH_MAX); + if (sz == 0) + { + winerror(&gapp, "cannot convert filename to Unicode"); + return; + } + + sz = MultiByteToWideChar(CP_UTF8, 0, target, -1, wtarget, PATH_MAX); + if (sz == 0) + { + winerror(&gapp, "cannot convert filename to Unicode"); + return; + } + +#if (_WIN32_WINNT >= 0x0500) + ReplaceFile(wtarget, wsource, NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL); +#else + DeleteFile(wtarget); + MoveFile(wsource, wtarget); +#endif +} + static char pd_filename[256] = "The file is encrypted."; static char pd_password[256] = ""; static char td_textinput[1024] = ""; diff --git a/apps/x11_main.c b/apps/x11_main.c index 9933242a..f4f8b24f 100644 --- a/apps/x11_main.c +++ b/apps/x11_main.c @@ -273,6 +273,11 @@ int wingetsavepath(pdfapp_t *app, char *buf, int len) return 0; } +void winreplacefile(char *source, char *target) +{ + rename(source, target); +} + void cleanup(pdfapp_t *app) { fz_context *ctx = app->ctx; |