aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-08-15 21:25:57 +0200
committerThomas White <taw@bitwiz.org.uk>2011-08-15 21:25:57 +0200
commit008fde3497c1669f516d6b43f5effd34258b1213 (patch)
treea781277a73b379cfc8a01b941eef2f5209f9b46e
parentb821d554b526f478bffee3dbdea73aa14081ce03 (diff)
Add loading and saving stuff
-rw-r--r--Makefile.am6
-rw-r--r--src/loadsave.c102
-rw-r--r--src/loadsave.h34
-rw-r--r--src/mainwindow.c142
-rw-r--r--src/objects.c2
-rw-r--r--src/presentation.c55
-rw-r--r--src/presentation.h3
7 files changed, 335 insertions, 9 deletions
diff --git a/Makefile.am b/Makefile.am
index 1b9681d..98e31d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,12 +10,12 @@ LDADD = $(top_builddir)/lib/libgnu.a @IGNORE_UNUSED_LIBRARIES_CFLAGS@
src_colloquium_SOURCES = src/colloquium.c src/presentation.c src/mainwindow.c \
src/slide_render.c src/objects.c src/slideshow.c \
- src/stylesheet.c
+ src/stylesheet.c src/loadsave.c
INCLUDES = "-I$(top_srcdir)/data"
-EXTRA_DIST += src/presentation.h src/mainwindow.h src/slide_render.h \
- src/objects.h src/slideshow.h src/stylesheet.h
+EXTRA_DIST += src/presentation.h src/mainwindow.h src/slide_render .h \
+ src/objects.h src/slideshow.h src/stylesheet.h src/loadsave.h
colloquiumdir = $(datadir)/colloquium
colloquium_DATA = data/colloquium.ui
diff --git a/src/loadsave.c b/src/loadsave.c
new file mode 100644
index 0000000..27476a0
--- /dev/null
+++ b/src/loadsave.c
@@ -0,0 +1,102 @@
+/*
+ * loadsave.v
+ *
+ * Colloquium - A tiny presentation program
+ *
+ * Copyright (c) 2011 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include "presentation.h"
+#include "objects.h"
+#include "stylesheet.h"
+
+
+int load_presentation(struct presentation *p, const char *filename)
+{
+ return 0;
+}
+
+
+static const char *type_text(enum objtype t)
+{
+ switch ( t )
+ {
+ case TEXT : return "text";
+ default : return "unknown";
+ }
+}
+
+
+static void write_stylesheet(StyleSheet *ss, FILE *fh)
+{
+}
+
+
+int save_presentation(struct presentation *p, const char *filename)
+{
+ FILE *fh;
+ int i;
+
+ fh = fopen(filename, "w");
+ if ( fh == NULL ) return 1;
+
+ fprintf(fh, "# Colloquium presentation file\n");
+ fprintf(fh, "version=0\n");
+
+ write_stylesheet(p->ss, fh);
+
+ for ( i=0; i<p->num_slides; i++ ) {
+
+ int j;
+ struct slide *s;
+
+ s = p->slides[i];
+
+ fprintf(fh, "++slide\n");
+ fprintf(fh, "width=%.2f\n", s->slide_width);
+ fprintf(fh, "height=%.2f\n", s->slide_height);
+
+ for ( j=0; j<s->num_objects; j++ ) {
+
+ struct object *o;
+
+ o = s->objects[j];
+
+ if ( o->empty ) continue;
+
+ fprintf(fh, "++object\n");
+ fprintf(fh, "type=%s\n", type_text(o->type));
+ fprintf(fh, "x=%.2f\n", o->x);
+ fprintf(fh, "y=%.2f\n", o->y);
+ fprintf(fh, "w=%.2f\n", o->bb_width);
+ fprintf(fh, "h=%.2f\n", o->bb_height);
+ fprintf(fh, "--object\n");
+ }
+
+ fprintf(fh, "--slide\n");
+
+ }
+
+ fclose(fh);
+ return 0;
+}
diff --git a/src/loadsave.h b/src/loadsave.h
new file mode 100644
index 0000000..68fdc4c
--- /dev/null
+++ b/src/loadsave.h
@@ -0,0 +1,34 @@
+/*
+ * loadsave.h
+ *
+ * Colloquium - A tiny presentation program
+ *
+ * Copyright (c) 2011 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LOADSAVE_H
+#define LOADSAVE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+extern int load_presentation(struct presentation *p, const char *filename);
+extern int save_presentation(struct presentation *p, const char *filename);
+
+#endif /* LOADSAVE_H */
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 7648f5a..ffb489e 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -37,6 +37,7 @@
#include "objects.h"
#include "slideshow.h"
#include "stylesheet.h"
+#include "loadsave.h"
static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget,
@@ -51,7 +52,138 @@ static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget,
static gint quit_sig(GtkWidget *widget, struct presentation *p)
{
- gtk_main_quit();
+ return 0;
+}
+
+
+static void show_error(struct presentation *p, const char *message)
+{
+ GtkWidget *window;
+
+ window = gtk_message_dialog_new(GTK_WINDOW(p->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE, message);
+ gtk_window_set_title(GTK_WINDOW(window), "Error");
+
+ g_signal_connect_swapped(window, "response",
+ G_CALLBACK(gtk_widget_destroy), window);
+ gtk_widget_show(window);
+}
+
+
+static gint open_response_sig(GtkWidget *d, gint response,
+ struct presentation *p)
+{
+ if ( response == GTK_RESPONSE_ACCEPT ) {
+
+ char *filename;
+
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
+
+ if ( p->completely_empty ) {
+ if ( load_presentation(p, filename) ) {
+ show_error(p, "Failed to open presentation");
+ } else {
+ open_mainwindow(p);
+ }
+ } else {
+ struct presentation *p;
+ p = new_presentation();
+ if ( load_presentation(p, filename) ) {
+ show_error(p, "Failed to open presentation");
+ } else {
+ open_mainwindow(p);
+ }
+ }
+
+ g_free(filename);
+
+ }
+
+ gtk_widget_destroy(d);
+
+ return 0;
+}
+
+
+static gint open_sig(GtkWidget *widget, struct presentation *p)
+{
+ GtkWidget *d;
+
+ d = gtk_file_chooser_dialog_new("Open Presentation",
+ GTK_WINDOW(p->window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ g_signal_connect(G_OBJECT(d), "response",
+ G_CALLBACK(open_response_sig), p);
+
+ gtk_widget_show_all(d);
+
+ return 0;
+}
+
+
+static gint saveas_response_sig(GtkWidget *d, gint response,
+ struct presentation *p)
+{
+ if ( response == GTK_RESPONSE_ACCEPT ) {
+
+ char *filename;
+
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
+
+ if ( save_presentation(p, filename) ) {
+ show_error(p, "Failed to save presentation");
+ }
+
+ g_free(filename);
+
+ }
+
+ gtk_widget_destroy(d);
+
+ return 0;
+}
+
+
+static gint saveas_sig(GtkWidget *widget, struct presentation *p)
+{
+ GtkWidget *d;
+
+ d = gtk_file_chooser_dialog_new("Save Presentation",
+ GTK_WINDOW(p->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ g_signal_connect(G_OBJECT(d), "response",
+ G_CALLBACK(saveas_response_sig), p);
+
+ gtk_widget_show_all(d);
+
+ return 0;
+}
+
+
+static gint save_sig(GtkWidget *widget, struct presentation *p)
+{
+ if ( p->filename == NULL ) {
+ return saveas_sig(widget, p);
+ }
+
+ save_presentation(p, p->filename);
+
+ return 0;
+}
+
+
+static gint save_ss_sig(GtkWidget *widget, struct presentation *p)
+{
return 0;
}
@@ -281,13 +413,13 @@ static void add_menu_bar(struct presentation *p, GtkWidget *vbox)
{ "NewAction", GTK_STOCK_NEW, "_New",
NULL, NULL, NULL },
{ "OpenAction", GTK_STOCK_OPEN, "_Open...",
- NULL, NULL, NULL },
+ NULL, NULL, G_CALLBACK(open_sig) },
{ "SaveAction", GTK_STOCK_SAVE, "_Save",
- NULL, NULL, NULL },
+ NULL, NULL, G_CALLBACK(save_sig) },
{ "SaveAsAction", GTK_STOCK_SAVE_AS, "Save _As...",
- NULL, NULL, NULL },
+ NULL, NULL, G_CALLBACK(saveas_sig) },
{ "SaveStyleAction", GTK_STOCK_SAVE_AS, "Save St_ylesheet",
- NULL, NULL, NULL },
+ NULL, NULL, G_CALLBACK(save_ss_sig) },
{ "QuitAction", GTK_STOCK_QUIT, "_Quit",
NULL, NULL, G_CALLBACK(quit_sig) },
diff --git a/src/objects.c b/src/objects.c
index 9c8ed41..ae634a5 100644
--- a/src/objects.c
+++ b/src/objects.c
@@ -253,6 +253,7 @@ void notify_style_update(struct presentation *p, struct text_style *ts)
}
+ p->completely_empty = 0;
if ( changed ) notify_slide_update(p);
}
@@ -281,6 +282,7 @@ void notify_layout_update(struct presentation *p, struct layout_element *le)
}
+ p->completely_empty = 0;
if ( changed ) notify_slide_update(p);
}
diff --git a/src/presentation.c b/src/presentation.c
index 9a493d5..fc9aea4 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -49,6 +49,9 @@ struct slide *add_slide(struct presentation *p, int pos)
new->object_seq = 0;
new->objects = NULL;
+ p->completely_empty = 0;
+ new->parent = p;
+
new->slide_width = p->slide_width;
new->slide_height = p->slide_height;
@@ -96,6 +99,8 @@ int add_object_to_slide(struct slide *s, struct object *o)
s->objects[s->num_objects++] = o;
o->parent = s;
+ s->parent->completely_empty = 0;
+
return 0;
}
@@ -146,14 +151,61 @@ struct object *find_object_at_position(struct slide *s, double x, double y)
}
+static char *safe_basename(const char *in)
+{
+ int i;
+ char *cpy;
+ char *res;
+
+ cpy = strdup(in);
+
+ /* Get rid of any trailing slashes */
+ for ( i=strlen(cpy)-1; i>0; i-- ) {
+ if ( cpy[i] == '/' ) {
+ cpy[i] = '\0';
+ } else {
+ break;
+ }
+ }
+
+ /* Find the base name */
+ for ( i=strlen(cpy)-1; i>0; i-- ) {
+ if ( cpy[i] == '/' ) {
+ i++;
+ break;
+ }
+ }
+
+ res = strdup(cpy+i);
+ /* If we didn't find a previous slash, i==0 so res==cpy */
+
+ free(cpy);
+
+ return res;
+}
+
+
+static void update_titlebar(struct presentation *p)
+{
+ free(p->titlebar);
+
+ if ( p->filename == NULL ) {
+ p->titlebar = strdup("(untitled)");
+ } else {
+ p->titlebar = safe_basename(p->filename);
+ }
+}
+
+
struct presentation *new_presentation()
{
struct presentation *new;
new = calloc(1, sizeof(struct presentation));
- new->titlebar = strdup("(untitled)");
new->filename = NULL;
+ new->titlebar = NULL;
+ update_titlebar(new);
new->window = NULL;
new->ui = NULL;
@@ -170,6 +222,7 @@ struct presentation *new_presentation()
new->view_slide_number = 0;
new->editing_object = NULL;
+ new->completely_empty = 1;
new->ss = new_stylesheet();
diff --git a/src/presentation.h b/src/presentation.h
index 60751d5..e471946 100644
--- a/src/presentation.h
+++ b/src/presentation.h
@@ -35,6 +35,8 @@
struct slide
{
+ struct presentation *parent;
+
cairo_surface_t *render_cache;
int render_cache_seq;
@@ -58,6 +60,7 @@ struct presentation
{
char *titlebar;
char *filename;
+ int completely_empty;
GtkWidget *window;
GtkWidget *drawingarea;