summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/jstest_main.c4
-rw-r--r--apps/pdfapp.c70
-rw-r--r--apps/pdfapp.h2
-rw-r--r--apps/win_main.c63
-rw-r--r--apps/x11_main.c5
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;