#include <math.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
+#include <locale.h>
#include "xournal.h"
#include "xo-interface.h"
f = gzopen(filename, "w");
if (f==NULL) return FALSE;
chk_attach_names();
+
+ setlocale(LC_NUMERIC, "C");
gzprintf(f, "<?xml version=\"1.0\" standalone=\"no\"?>\n"
"<title>Xournal document - see http://math.mit.edu/~auroux/software/xournal/</title>\n"
tmpf = fopen(tmpfn, "w");
if (tmpf != NULL && fwrite(pdfbuf, 1, pdflen, tmpf) == pdflen)
success = TRUE;
+ g_free(pdfbuf);
fclose(tmpf);
}
if (!success) {
gzprintf(f, "</page>\n");
}
gzclose(f);
+ setlocale(LC_NUMERIC, "");
+
return TRUE;
}
use new_journal() to reinitialize them */
}
+// sanitize a string containing floats, in case it may have , instead of .
+
+void cleanup_numeric(char *s)
+{
+ while (*s!=0) { if (*s==',') *s='.'; s++; }
+}
+
// the XML parser functions for open_journal()
struct Journal tmpJournal;
while (*attribute_names!=NULL) {
if (!strcmp(*attribute_names, "width")) {
if (has_attr & 1) *error = xoj_invalid();
- tmpPage->width = strtod(*attribute_values, &ptr);
+ cleanup_numeric((gchar *)*attribute_values);
+ tmpPage->width = g_ascii_strtod(*attribute_values, &ptr);
if (ptr == *attribute_values) *error = xoj_invalid();
has_attr |= 1;
}
else if (!strcmp(*attribute_names, "height")) {
if (has_attr & 2) *error = xoj_invalid();
- tmpPage->height = strtod(*attribute_values, &ptr);
+ cleanup_numeric((gchar *)*attribute_values);
+ tmpPage->height = g_ascii_strtod(*attribute_values, &ptr);
if (ptr == *attribute_values) *error = xoj_invalid();
has_attr |= 2;
}
else if (!strcmp(*attribute_names, "pageno")) {
if (tmpPage->bg->type != BG_PDF || (has_attr & 32))
{ *error = xoj_invalid(); return; }
- tmpPage->bg->file_page_seq = strtod(*attribute_values, &ptr);
+ tmpPage->bg->file_page_seq = strtol(*attribute_values, &ptr, 10);
if (ptr == *attribute_values) *error = xoj_invalid();
has_attr |= 32;
}
while (*attribute_names!=NULL) {
if (!strcmp(*attribute_names, "width")) {
if (has_attr & 1) *error = xoj_invalid();
- tmpItem->brush.thickness = strtod(*attribute_values, &ptr);
+ cleanup_numeric((gchar *)*attribute_values);
+ tmpItem->brush.thickness = g_ascii_strtod(*attribute_values, &ptr);
if (ptr == *attribute_values) *error = xoj_invalid();
has_attr |= 1;
}
element_name = g_markup_parse_context_get_element(context);
if (element_name == NULL) return;
if (!strcmp(element_name, "stroke")) {
+ cleanup_numeric((gchar *)text);
ptr = text;
n = 0;
while (text_len > 0) {
realloc_cur_path(n/2 + 1);
- ui.cur_path.coords[n] = strtod(text, (char **)(&ptr));
+ ui.cur_path.coords[n] = g_ascii_strtod(text, (char **)(&ptr));
if (ptr == text) break;
text_len -= (ptr - text);
text = ptr;
if (response != GTK_RESPONSE_YES) return FALSE;
dialog = gtk_file_chooser_dialog_new("Open PDF", GTK_WINDOW (winMain),
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+ GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
filt_all = gtk_file_filter_new();
gtk_file_filter_set_name(filt_all, "All files");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_pdf);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
gtk_widget_destroy(dialog);
return FALSE;
}
char buffer[1000];
int len;
gchar *tmpfn;
+ gboolean maybe_pdf;
f = gzopen(filename, "r");
if (f==NULL) return FALSE;
tmpFilename = filename;
error = NULL;
tmpBg_pdf = NULL;
+ maybe_pdf = TRUE;
while (valid && !gzeof(f)) {
len = gzread(f, buffer, 1000);
if (len<0) valid = FALSE;
+ if (maybe_pdf && len>=4 && !strncmp(buffer, "%PDF", 4))
+ { valid = FALSE; break; } // most likely pdf
+ else maybe_pdf = FALSE;
if (len<=0) break;
valid = g_markup_parse_context_parse(context, buffer, len, &error);
}
if (valid) valid = g_markup_parse_context_end_parse(context, &error);
if (tmpJournal.npages == 0) valid = FALSE;
g_markup_parse_context_free(context);
+
if (!valid) {
delete_journal(&tmpJournal);
- return FALSE;
+ if (!maybe_pdf) return FALSE;
+ // essentially same as on_fileNewBackground from here on
+ ui.saved = TRUE;
+ close_journal();
+ while (bgpdf.status != STATUS_NOT_INIT) gtk_main_iteration();
+ new_journal();
+ ui.zoom = DEFAULT_ZOOM;
+ gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+ update_page_stuff();
+ return init_bgpdf(filename, TRUE, DOMAIN_ABSOLUTE);
}
ui.saved = TRUE; // force close_journal() to do its job
ui.cur_layer = (struct Layer *)(g_list_last(ui.cur_page->layers)->data);
ui.saved = TRUE;
ui.zoom = DEFAULT_ZOOM;
- update_file_name(filename);
+ update_file_name(g_strdup(filename));
gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
make_canvas_items();
update_page_stuff();
void end_bgpdf_shutdown(void)
{
if (bgpdf.tmpdir!=NULL) {
- g_unlink(bgpdf.tmpfile_copy);
- g_free(bgpdf.tmpfile_copy);
+ if (bgpdf.tmpfile_copy!=NULL) {
+ g_unlink(bgpdf.tmpfile_copy);
+ g_free(bgpdf.tmpfile_copy);
+ bgpdf.tmpfile_copy = NULL;
+ }
g_rmdir(bgpdf.tmpdir);
g_free(bgpdf.tmpdir);
bgpdf.tmpdir = NULL;
gsize filelen;
if (bgpdf.status != STATUS_NOT_INIT) return FALSE;
+ bgpdf.tmpfile_copy = NULL;
bgpdf.tmpdir = mkdtemp(g_strdup(TMPDIR_TEMPLATE));
if (!bgpdf.tmpdir) return FALSE;
// make a local copy and check if it's a PDF
- if (!g_file_get_contents(pdfname, &filebuf, &filelen, NULL)) return FALSE;
+ if (!g_file_get_contents(pdfname, &filebuf, &filelen, NULL))
+ { end_bgpdf_shutdown(); return FALSE; }
if (filelen < 4 || strncmp(filebuf, "%PDF", 4))
- { g_free(filebuf); return FALSE; }
+ { g_free(filebuf); end_bgpdf_shutdown(); return FALSE; }
bgpdf.tmpfile_copy = g_strdup_printf("%s/bg.pdf", bgpdf.tmpdir);
f = fopen(bgpdf.tmpfile_copy, "w");
if (f == NULL || fwrite(filebuf, 1, filelen, f) != filelen)
- { g_free(filebuf); return FALSE; }
+ { g_free(filebuf); end_bgpdf_shutdown(); return FALSE; }
fclose(f);
g_free(filebuf);
bgpdf.status = STATUS_IDLE;
}
}
+// initialize the recent files list
+void init_mru(void)
+{
+ int i;
+ gsize lfptr;
+ char s[5];
+ GIOChannel *f;
+ gchar *str;
+ GIOStatus status;
+
+ g_strlcpy(s, "mru0", 5);
+ for (s[3]='0', i=0; i<MRU_SIZE; s[3]++, i++) {
+ ui.mrumenu[i] = GET_COMPONENT(s);
+ ui.mru[i] = NULL;
+ }
+ f = g_io_channel_new_file(ui.mrufile, "r", NULL);
+ if (f) status = G_IO_STATUS_NORMAL;
+ else status = G_IO_STATUS_ERROR;
+ i = 0;
+ while (status == G_IO_STATUS_NORMAL && i<MRU_SIZE) {
+ lfptr = 0;
+ status = g_io_channel_read_line(f, &str, NULL, &lfptr, NULL);
+ if (status == G_IO_STATUS_NORMAL && lfptr>0) {
+ str[lfptr] = 0;
+ ui.mru[i] = str;
+ i++;
+ }
+ }
+ if (f) {
+ g_io_channel_shutdown(f, FALSE, NULL);
+ g_io_channel_unref(f);
+ }
+ update_mru_menu();
+}
+
+void update_mru_menu(void)
+{
+ int i;
+ gboolean anyone = FALSE;
+
+ for (i=0; i<MRU_SIZE; i++) {
+ if (ui.mru[i]!=NULL) {
+ gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(ui.mrumenu[i]))),
+ g_basename(ui.mru[i]));
+ gtk_widget_show(ui.mrumenu[i]);
+ anyone = TRUE;
+ }
+ else gtk_widget_hide(ui.mrumenu[i]);
+ }
+ gtk_widget_set_sensitive(GET_COMPONENT("fileRecentFiles"), anyone);
+}
+
+void new_mru_entry(char *name)
+{
+ int i, j;
+
+ for (i=0;i<MRU_SIZE;i++)
+ if (ui.mru[i]!=NULL && !strcmp(ui.mru[i], name)) {
+ g_free(ui.mru[i]);
+ for (j=i+1; j<MRU_SIZE; j++) ui.mru[j-1] = ui.mru[j];
+ ui.mru[MRU_SIZE-1]=NULL;
+ }
+ if (ui.mru[MRU_SIZE-1]!=NULL) g_free(ui.mru[MRU_SIZE-1]);
+ for (j=MRU_SIZE-1; j>=1; j--) ui.mru[j] = ui.mru[j-1];
+ ui.mru[0] = g_strdup(name);
+ update_mru_menu();
+}
+
+void delete_mru_entry(int which)
+{
+ int i;
+
+ if (ui.mru[which]!=NULL) g_free(ui.mru[which]);
+ for (i=which+1;i<MRU_SIZE;i++)
+ ui.mru[i-1] = ui.mru[i];
+ ui.mru[MRU_SIZE-1] = NULL;
+ update_mru_menu();
+}
+
+void save_mru_list(void)
+{
+ FILE *f;
+ int i;
+
+ f = fopen(ui.mrufile, "w");
+ if (f==NULL) return;
+ for (i=0; i<MRU_SIZE; i++)
+ if (ui.mru[i]!=NULL) fprintf(f, "%s\n", ui.mru[i]);
+ fclose(f);
+}