aboutsummaryrefslogtreecommitdiff
path: root/src/mainwindow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainwindow.c')
-rw-r--r--src/mainwindow.c2008
1 files changed, 0 insertions, 2008 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
deleted file mode 100644
index 4c6809d..0000000
--- a/src/mainwindow.c
+++ /dev/null
@@ -1,2008 +0,0 @@
-/*
- * mainwindow.c
- *
- * Copyright © 2013-2014 Thomas White <taw@bitwiz.org.uk>
- *
- * This file is part of Colloquium.
- *
- * Colloquium 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 <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <assert.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <math.h>
-
-#include "presentation.h"
-#include "mainwindow.h"
-#include "render.h"
-#include "frame.h"
-#include "slideshow.h"
-#include "wrap.h"
-#include "notes.h"
-#include "pr_clock.h"
-#include "slide_sorter.h"
-#include "sc_parse.h"
-#include "sc_interp.h"
-
-
-/* Update a slide, once it's been edited in some way. */
-void rerender_slide(struct presentation *p)
-{
- struct slide *s = p->cur_edit_slide;
- int n = slide_number(p, s);
-
- free_render_buffers(s);
-
- s->rendered_thumb = render_slide(s, s->parent->thumb_slide_width,
- p->slide_width, p->slide_height, p->is,
- ISZ_THUMBNAIL, n);
-
- s->rendered_proj = render_slide(s, s->parent->proj_slide_width,
- p->slide_width, p->slide_height, p->is,
- ISZ_SLIDESHOW, n);
-
- s->rendered_edit = render_slide(s, s->parent->edit_slide_width,
- p->slide_width, p->slide_height, p->is,
- ISZ_EDITOR, n);
-}
-
-
-/* Ensure that "edit" and "proj" renderings are in order */
-static void render_edit_and_proj(struct presentation *p)
-{
- struct slide *s = p->cur_edit_slide;
- int n = slide_number(p, s);
-
- if ( s->rendered_proj == NULL ) {
- s->rendered_proj = render_slide(s, s->parent->proj_slide_width,
- p->slide_width, p->slide_height,
- p->is, ISZ_SLIDESHOW, n);
- }
-
- if ( s->rendered_edit == NULL ) {
- s->rendered_edit = render_slide(s, s->parent->edit_slide_width,
- p->slide_width, p->slide_height,
- p->is, ISZ_EDITOR, n);
- }
-}
-
-
-
-/* Force a redraw of the editor window */
-void redraw_editor(struct presentation *p)
-{
- gint w, h;
-
- w = gtk_widget_get_allocated_width(GTK_WIDGET(p->drawingarea));
- h = gtk_widget_get_allocated_height(GTK_WIDGET(p->drawingarea));
-
- gtk_widget_queue_draw_area(p->drawingarea, 0, 0, w, h);
-}
-
-
-static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget,
- GtkContainer *container)
-{
- gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
- if ( GTK_IS_TOOLBAR(widget) ) {
- gtk_toolbar_set_show_arrow(GTK_TOOLBAR(widget), TRUE);
- }
-}
-
-
-static gint quit_sig(GtkWidget *widget, struct presentation *p)
-{
- 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);
-}
-
-
-void update_toolbar(struct presentation *p)
-{
- GtkWidget *d;
- int cur_slide_number;
-
- d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/first");
- gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
- d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/prev");
- gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
- d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/next");
- gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
- d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/last");
- gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
-
- cur_slide_number = slide_number(p, p->cur_edit_slide);
- if ( cur_slide_number == 0 ) {
-
- d = gtk_ui_manager_get_widget(p->ui,
- "/ui/displaywindowtoolbar/first");
- gtk_widget_set_sensitive(GTK_WIDGET(d), FALSE);
- d = gtk_ui_manager_get_widget(p->ui,
- "/ui/displaywindowtoolbar/prev");
- gtk_widget_set_sensitive(GTK_WIDGET(d), FALSE);
-
- }
-
- if ( cur_slide_number == p->num_slides-1 ) {
-
- d = gtk_ui_manager_get_widget(p->ui,
- "/ui/displaywindowtoolbar/next");
- gtk_widget_set_sensitive(GTK_WIDGET(d), FALSE);
- d = gtk_ui_manager_get_widget(p->ui,
- "/ui/displaywindowtoolbar/last");
- gtk_widget_set_sensitive(GTK_WIDGET(d), FALSE);
-
- }
-
-
-}
-
-
-static void do_slide_update(struct presentation *p, PangoContext *pc)
-{
- rerender_slide(p);
- redraw_editor(p);
- if ( (p->slideshow != NULL)
- && (p->cur_edit_slide == p->cur_proj_slide) )
- {
- redraw_slideshow(p);
- }
-}
-
-
-/* Inelegance to make furniture selection menus work */
-struct menu_pl
-{
- struct presentation *p;
- char *style_name;
- GtkWidget *widget;
-};
-
-
-static gint add_furniture(GtkWidget *widget, struct menu_pl *pl)
-{
- sc_block_append_end(pl->p->cur_edit_slide->scblocks,
- strdup(pl->style_name), NULL, NULL);
-
- do_slide_update(pl->p, pl->p->pc);
-
- return 0;
-}
-
-
-static void update_style_menus(struct presentation *p)
-{
- GtkWidget *menu;
- SCInterpreter *scin;
- struct style_id *styles;
- int i, n_sty;
-
- /* Free old list */
- for ( i=0; i<p->n_style_menu; i++ ) {
- gtk_widget_destroy(p->style_menu[i].widget);
- free(p->style_menu[i].style_name);
- }
- free(p->style_menu);
-
- /* Get the list of styles from the style sheet */
- scin = sc_interp_new(NULL, NULL);
- if ( scin == NULL ) {
- fprintf(stderr, "Failed to set up interpreter.\n");
- return;
- }
- sc_interp_run_stylesheet(scin, p->stylesheet);
-
- styles = list_styles(scin, &n_sty);
- if ( styles == NULL ) return;
-
- sc_interp_destroy(scin);
-
- /* Set up list for next time */
- p->style_menu = calloc(n_sty, sizeof(struct menu_pl));
- if ( p->style_menu == NULL ) return;
-
- /* Add the styles to the "Insert" menu */
- menu = gtk_ui_manager_get_widget(p->ui, "/displaywindow/insert");
- menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
-
- for ( i=0; i<n_sty; i++ ) {
-
- GtkWidget *item;
-
- item = gtk_menu_item_new_with_label(styles[i].friendlyname);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-
- p->style_menu[i].p = p;
- p->style_menu[i].widget = item;
- p->style_menu[i].style_name = styles[i].name;
-
- g_signal_connect(G_OBJECT(item), "activate",
- G_CALLBACK(add_furniture),
- &p->style_menu[i]);
-
- free(styles[i].friendlyname);
- }
-
- gtk_widget_show_all(menu);
- free(styles);
-}
-
-
-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");
- }
- p->cur_edit_slide = p->slides[0];
- rerender_slide(p);
- update_toolbar(p);
- update_style_menus(p);
- if ( p->slideshow != NULL ) end_slideshow(p);
-
- } else {
-
- struct presentation *p;
-
- /* FIXME */
- 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 loadstyle_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));
- /* FIXME: Implement this (now easy) */
- //replace_stylesheet(p, filename);
- g_free(filename);
- update_style_menus(p);
- rerender_slide(p);
-
- }
-
- gtk_widget_destroy(d);
-
- return 0;
-}
-
-
-static gint loadstyle_sig(GtkWidget *widget, struct presentation *p)
-{
- GtkWidget *d;
-
- d = gtk_file_chooser_dialog_new("Load Stylesheet",
- 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(loadstyle_response_sig), p);
-
- gtk_widget_show_all(d);
-
- return 0;
-}
-
-
-static gint new_sig(GtkWidget *widget, struct presentation *pnn)
-{
- struct presentation *p;
-
- p = new_presentation();
- if ( p != NULL ) {
- struct slide *new;
- new = add_slide(p, 0);
- p->completely_empty = 1;
- /* FIXME: position */
- new->scblocks = sc_block_append_end(p->scblocks, "slide",
- NULL, NULL);
- attach_notes(new);
- open_mainwindow(p);
- }
-
- 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);
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(d),
- TRUE);
-
- 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_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));
-
- /* FIXME: Implement this */
-// if ( save_stylesheet(p->ss, filename) ) {
-// show_error(p, "Failed to save style sheet");
-// }
-
- g_free(filename);
-
- }
-
- gtk_widget_destroy(d);
-
- return 0;
-}
-
-
-static gint save_ss_sig(GtkWidget *widget, struct presentation *p)
-{
- GtkWidget *d;
-
- d = gtk_file_chooser_dialog_new("Save Style sheet",
- GTK_WINDOW(p->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(d),
- TRUE);
-
- g_signal_connect(G_OBJECT(d), "response",
- G_CALLBACK(save_ss_response_sig), p);
-
- gtk_widget_show_all(d);
-
- return 0;
-}
-
-
-static gint export_pdf_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 ( export_pdf(p, filename) ) {
- show_error(p, "Failed to export as PDF");
- }
-
- g_free(filename);
-
- }
-
- gtk_widget_destroy(d);
-
- return 0;
-}
-
-
-static gint export_pdf_sig(GtkWidget *widget, struct presentation *p)
-{
- GtkWidget *d;
-
- d = gtk_file_chooser_dialog_new("Export PDF",
- GTK_WINDOW(p->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(d),
- TRUE);
-
- g_signal_connect(G_OBJECT(d), "response",
- G_CALLBACK(export_pdf_response_sig), p);
-
- gtk_widget_show_all(d);
-
- return 0;
-}
-
-
-static gint about_sig(GtkWidget *widget, struct presentation *p)
-{
- GtkWidget *window;
-
- const gchar *authors[] = {
- "Thomas White <taw@bitwiz.org.uk>",
- NULL
- };
-
- window = gtk_about_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(p->window));
-
- gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(window),
- "Colloquium");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(window),
- PACKAGE_VERSION);
- gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(window),
- "© 2013 Thomas White <taw@bitwiz.org.uk>");
- gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),
- "A tiny presentation program");
- gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(window),
- "© 2013 Thomas White <taw@bitwiz.org.uk>\n");
- gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(window),
- "http://www.bitwiz.org.uk/");
- gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(window), authors);
-
- g_signal_connect(window, "response", G_CALLBACK(gtk_widget_destroy),
- NULL);
-
- gtk_widget_show_all(window);
-
- return 0;
-}
-
-
-static gint start_slideshow_sig(GtkWidget *widget, struct presentation *p)
-{
- try_start_slideshow(p);
- return FALSE;
-}
-
-
-/* Change the editor's slide to "np" */
-void change_edit_slide(struct presentation *p, struct slide *np)
-{
- /* If this slide is not being shown on the projector, we can free the
- * buffers */
- if ( p->cur_proj_slide != p->cur_edit_slide ) {
- free_render_buffers_except_thumb(p->cur_edit_slide);
- }
-
- p->cur_edit_slide = np;
- render_edit_and_proj(p);
-
- set_selection(p, NULL);
- update_toolbar(p);
- redraw_editor(p);
-
- if ( p->notes != NULL ) {
- notify_notes_slide_changed(p, np);
- }
-
- if ( (p->slideshow != NULL) && p->slideshow_linked ) {
- change_proj_slide(p, np);
- } /* else leave the slideshow alone */
-}
-
-
-static gint add_slide_sig(GtkWidget *widget, struct presentation *p)
-{
- struct slide *new;
- int cur_slide_number;
-
- cur_slide_number = slide_number(p, p->cur_edit_slide);
-
- new = add_slide(p, cur_slide_number+1);
- new->scblocks = sc_block_insert_after(p->cur_edit_slide->scblocks,
- "slide", NULL, NULL);
-
- change_edit_slide(p, new);
-
- return FALSE;
-}
-
-
-static gint first_slide_sig(GtkWidget *widget, struct presentation *p)
-{
- change_edit_slide(p, p->slides[0]);
- return FALSE;
-}
-
-
-static gint prev_slide_sig(GtkWidget *widget, struct presentation *p)
-{
- int cur_slide_number;
-
- cur_slide_number = slide_number(p, p->cur_edit_slide);
- if ( cur_slide_number == 0 ) return FALSE;
-
- change_edit_slide(p, p->slides[cur_slide_number-1]);
-
- return FALSE;
-}
-
-
-static gint next_slide_sig(GtkWidget *widget, struct presentation *p)
-{
- int cur_slide_number;
-
- cur_slide_number = slide_number(p, p->cur_edit_slide);
- if ( cur_slide_number == p->num_slides-1 ) return FALSE;
-
- change_edit_slide(p, p->slides[cur_slide_number+1]);
-
- return FALSE;
-}
-
-
-static gint last_slide_sig(GtkWidget *widget, struct presentation *p)
-{
- change_edit_slide(p, p->slides[p->num_slides-1]);
-
- return FALSE;
-}
-
-
-static gint open_stylesheet_sig(GtkWidget *widget, struct presentation *p)
-{
- /* FIXME */
- //if ( p->stylesheetwindow == NULL ) {
- // p->stylesheetwindow = open_stylesheet(p);
- //} /* else already open */
-
- return FALSE;
-}
-
-
-static gint open_notes_sig(GtkWidget *widget, struct presentation *p)
-{
- open_notes(p);
- return FALSE;
-}
-
-
-static gint open_clock_sig(GtkWidget *widget, struct presentation *p)
-{
- open_clock(p);
- return FALSE;
-}
-
-
-static gint open_slidesorter_sig(GtkWidget *widget, struct presentation *p)
-{
- open_slidesorter(p);
- return FALSE;
-}
-
-static gint delete_frame_sig(GtkWidget *widget, struct presentation *p)
-{
- int i;
-
- for ( i=0; i<p->n_selection; i++ ) {
- delete_subframe(p->cur_edit_slide, p->selection[i]);
- }
- p->n_selection = 0;
-
- rerender_slide(p);
- redraw_editor(p);
-
- return FALSE;
-}
-
-
-static void add_menu_bar(struct presentation *p, GtkWidget *vbox)
-{
- GError *error = NULL;
- GtkWidget *toolbar;
- GtkWidget *menu;
- GtkWidget *item;
-
- GtkActionEntry entries[] = {
-
- { "FileAction", NULL, "_File", NULL, NULL, NULL },
- { "NewAction", GTK_STOCK_NEW, "_New",
- NULL, NULL, G_CALLBACK(new_sig) },
- { "OpenAction", GTK_STOCK_OPEN, "_Open...",
- NULL, NULL, G_CALLBACK(open_sig) },
- { "LoadStyleAction", NULL, "_Load Stylesheet...",
- NULL, NULL, G_CALLBACK(loadstyle_sig) },
- { "SaveAction", GTK_STOCK_SAVE, "_Save",
- NULL, NULL, G_CALLBACK(save_sig) },
- { "SaveAsAction", GTK_STOCK_SAVE_AS, "Save _As...",
- NULL, NULL, G_CALLBACK(saveas_sig) },
- { "SaveStyleAction", NULL, "Save St_ylesheet",
- NULL, NULL, G_CALLBACK(save_ss_sig) },
- { "ExportPDFAction", NULL, "Export PDF",
- NULL, NULL, G_CALLBACK(export_pdf_sig) },
- { "QuitAction", GTK_STOCK_QUIT, "_Quit",
- NULL, NULL, G_CALLBACK(quit_sig) },
-
- { "EditAction", NULL, "_Edit", NULL, NULL, NULL },
- { "SorterAction", NULL, "_Open Slide Sorter...",
- NULL, NULL, G_CALLBACK(open_slidesorter_sig) },
- { "UndoAction", GTK_STOCK_UNDO, "_Undo",
- NULL, NULL, NULL },
- { "RedoAction", GTK_STOCK_REDO, "_Redo",
- NULL, NULL, NULL },
- { "CutAction", GTK_STOCK_CUT, "Cut",
- NULL, NULL, NULL },
- { "CopyAction", GTK_STOCK_COPY, "Copy",
- NULL, NULL, NULL },
- { "PasteAction", GTK_STOCK_PASTE, "Paste",
- NULL, NULL, NULL },
- { "DeleteFrameAction", GTK_STOCK_DELETE, "Delete Frame",
- NULL, NULL, G_CALLBACK(delete_frame_sig) },
- { "EditStyleAction", NULL, "Stylesheet...",
- NULL, NULL, G_CALLBACK(open_stylesheet_sig) },
-
- { "InsertAction", NULL, "_Insert", NULL, NULL, NULL },
- { "NewSlideAction", GTK_STOCK_ADD, "_New Slide",
- NULL, NULL, G_CALLBACK(add_slide_sig) },
-
- { "ToolsAction", NULL, "_Tools", NULL, NULL, NULL },
- { "TSlideshowAction", GTK_STOCK_FULLSCREEN, "_Start Slideshow",
- "F5", NULL, G_CALLBACK(start_slideshow_sig) },
- { "NotesAction", NULL, "_Open slide notes",
- "F8", NULL, G_CALLBACK(open_notes_sig) },
- { "ClockAction", NULL, "_Open presentation clock",
- "F9", NULL, G_CALLBACK(open_clock_sig) },
- { "PrefsAction", GTK_STOCK_PREFERENCES, "_Preferences",
- NULL, NULL, NULL },
-
- { "HelpAction", NULL, "_Help", NULL, NULL, NULL },
- { "AboutAction", GTK_STOCK_ABOUT, "_About...",
- NULL, NULL, G_CALLBACK(about_sig) },
-
- { "SlideshowAction", GTK_STOCK_FULLSCREEN, "Start Presentation",
- NULL, NULL, G_CALLBACK(start_slideshow_sig) },
- { "AddSlideAction", GTK_STOCK_ADD, "Add Slide",
- NULL, NULL, G_CALLBACK(add_slide_sig) },
- { "ButtonFirstSlideAction", GTK_STOCK_GOTO_FIRST, "First Slide",
- NULL, NULL, G_CALLBACK(first_slide_sig) },
- { "ButtonPrevSlideAction", GTK_STOCK_GO_BACK, "Previous Slide",
- NULL, NULL, G_CALLBACK(prev_slide_sig) },
- { "ButtonNextSlideAction", GTK_STOCK_GO_FORWARD, "Next Slide",
- NULL, NULL, G_CALLBACK(next_slide_sig) },
- { "ButtonLastSlideAction", GTK_STOCK_GOTO_LAST, "Last Slide",
- NULL, NULL, G_CALLBACK(last_slide_sig) },
-
- };
- guint n_entries = G_N_ELEMENTS(entries);
-
- p->action_group = gtk_action_group_new("mainwindow");
- gtk_action_group_add_actions(p->action_group, entries, n_entries, p);
-
- p->ui = gtk_ui_manager_new();
- gtk_ui_manager_insert_action_group(p->ui, p->action_group, 0);
- g_signal_connect(p->ui, "add_widget", G_CALLBACK(add_ui_sig), vbox);
- if ( gtk_ui_manager_add_ui_from_file(p->ui,
- DATADIR"/colloquium/colloquium.ui", &error) == 0 ) {
- fprintf(stderr, "Error loading main window menu bar: %s\n",
- error->message);
- return;
- }
-
- gtk_window_add_accel_group(GTK_WINDOW(p->window),
- gtk_ui_manager_get_accel_group(p->ui));
- gtk_ui_manager_ensure_update(p->ui);
-
- toolbar = gtk_ui_manager_get_widget(p->ui, "/displaywindowtoolbar");
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
- gtk_separator_tool_item_new(), -1);
-
- menu = gtk_ui_manager_get_widget(p->ui, "/displaywindow/insert");
- menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
- item = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-
- update_style_menus(p);
- update_toolbar(p);
-}
-
-
-static gint close_sig(GtkWidget *window, struct presentation *p)
-{
- free_presentation(p);
- return 0;
-}
-
-
-static void draw_editing_box(cairo_t *cr, struct frame *fr)
-{
- const double dash[] = {2.0, 2.0};
- double xmin, ymin, width, height;
- double ptot_w, ptot_h;
-
- xmin = fr->x;
- ymin = fr->y;
- width = fr->w;
- height = fr->h;
-
- cairo_new_path(cr);
- cairo_rectangle(cr, xmin, ymin, width, height);
- cairo_set_source_rgb(cr, 0.0, 0.69, 1.0);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
-
- cairo_new_path(cr);
- ptot_w = fr->pad_l + fr->pad_r;
- ptot_h = fr->pad_t + fr->pad_b;
- cairo_rectangle(cr, xmin+fr->pad_l, ymin+fr->pad_t,
- width-ptot_w, height-ptot_h);
- cairo_set_dash(cr, dash, 2, 0.0);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
- cairo_set_line_width(cr, 0.1);
- cairo_stroke(cr);
-
- cairo_set_dash(cr, NULL, 0, 0.0);
-}
-
-
-static void draw_caret(cairo_t *cr, struct frame *fr,
- int cursor_line, int cursor_box, int cursor_pos)
-{
- double xposd, yposd, line_height;
- double cx, clow, chigh;
- const double t = 1.8;
- struct wrap_box *box;
- int i;
-
- if ( fr == NULL ) return;
- if ( fr->n_lines == 0 ) return;
-
- /* Locate the cursor in a "logical" and "geographical" sense */
- box = &fr->lines[cursor_line].boxes[cursor_box];
- get_cursor_pos(box, cursor_pos, &xposd, &yposd, &line_height);
- xposd += fr->pad_l;
- yposd += fr->pad_t;
-
- for ( i=0; i<cursor_line; i++ ) {
- yposd += pango_units_to_double(fr->lines[i].height);
- }
-
- for ( i=0; i<cursor_box; i++ ) {
- int w = fr->lines[cursor_line].boxes[i].width;
- w += fr->lines[cursor_line].boxes[i].sp;
- xposd += pango_units_to_double(w);
- }
-
- cx = fr->x + xposd;
- clow = fr->y + yposd;
- chigh = clow + line_height;
-
- cairo_move_to(cr, cx, clow);
- cairo_line_to(cr, cx, chigh);
-
- cairo_move_to(cr, cx-t, clow-t);
- cairo_line_to(cr, cx, clow);
- cairo_move_to(cr, cx+t, clow-t);
- cairo_line_to(cr, cx, clow);
-
- cairo_move_to(cr, cx-t, chigh+t);
- cairo_line_to(cr, cx, chigh);
- cairo_move_to(cr, cx+t, chigh+t);
- cairo_line_to(cr, cx, chigh);
-
- cairo_set_source_rgb(cr, 0.86, 0.0, 0.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
-}
-
-
-static void draw_resize_handle(cairo_t *cr, double x, double y)
-{
- cairo_new_path(cr);
- cairo_rectangle(cr, x, y, 20.0, 20.0);
- cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 0.5);
- cairo_fill(cr);
-}
-
-
-static void draw_overlay(cairo_t *cr, struct presentation *p)
-{
- int i;
-
- for ( i=0; i<p->n_selection; i++ ) {
-
- double x, y, w, h;
-
- draw_editing_box(cr, p->selection[i]);
-
- x = p->selection[i]->x;
- y = p->selection[i]->y;
- w = p->selection[i]->w;
- h = p->selection[i]->h;
-
- /* Draw resize handles */
- /* FIXME: Not if this frame can't be resized */
- draw_resize_handle(cr, x, y+h-20.0);
- draw_resize_handle(cr, x+w-20.0, y);
- draw_resize_handle(cr, x, y);
- draw_resize_handle(cr, x+w-20.0, y+h-20.0);
- }
-
- /* If only one frame is selected, draw the caret */
- if ( p->n_selection == 1 ) {
- draw_caret(cr, p->cursor_frame, p->cursor_line, p->cursor_box,
- p->cursor_pos);
- }
-
- if ( (p->drag_status == DRAG_STATUS_DRAGGING)
- && ((p->drag_reason == DRAG_REASON_CREATE)
- || (p->drag_reason == DRAG_REASON_IMPORT)) )
- {
- cairo_new_path(cr);
- cairo_rectangle(cr, p->start_corner_x, p->start_corner_y,
- p->drag_corner_x - p->start_corner_x,
- p->drag_corner_y - p->start_corner_y);
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
- }
-
- if ( (p->drag_status == DRAG_STATUS_DRAGGING)
- && ((p->drag_reason == DRAG_REASON_RESIZE)
- || (p->drag_reason == DRAG_REASON_MOVE)) )
- {
- cairo_new_path(cr);
- cairo_rectangle(cr, p->box_x, p->box_y,
- p->box_width, p->box_height);
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
- }
-}
-
-
-static gboolean draw_sig(GtkWidget *da, cairo_t *cr,
- struct presentation *p)
-{
- double xoff, yoff;
- int width, height;
- int edit_slide_height;
-
- width = gtk_widget_get_allocated_width(GTK_WIDGET(da));
- height = gtk_widget_get_allocated_height(GTK_WIDGET(da));
-
- /* Overall background */
- cairo_rectangle(cr, 0.0, 0.0, width, height);
- if ( (p->slideshow != NULL) && !p->slideshow_linked ) {
- cairo_set_source_rgb(cr, 1.0, 0.3, 0.2);
- } else {
- cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
- }
- cairo_fill(cr);
-
- /* Get the overall size */
- edit_slide_height = (p->slide_height/p->slide_width)*p->edit_slide_width;
- xoff = (width - p->edit_slide_width)/2.0;
- yoff = (height - edit_slide_height)/2.0;
- p->border_offs_x = xoff; p->border_offs_y = yoff;
-
- /* Draw the slide from the cache */
- if ( p->cur_edit_slide->rendered_edit != NULL ) {
- cairo_set_source_surface(cr, p->cur_edit_slide->rendered_edit,
- xoff, yoff);
- cairo_paint(cr);
- } else {
- fprintf(stderr, "Current slide not rendered yet!\n");
- }
-
- cairo_translate(cr, xoff, yoff);
- draw_overlay(cr, p);
-
- return FALSE;
-}
-
-
-void update_titlebar(struct presentation *p)
-{
- get_titlebar_string(p);
-
- if ( p->window != NULL ) {
-
- char *title;
-
- title = malloc(strlen(p->titlebar)+14);
- sprintf(title, "%s - Colloquium", p->titlebar);
- gtk_window_set_title(GTK_WINDOW(p->window), title);
- free(title);
-
- }
-}
-
-
-static void fixup_cursor(struct presentation *p)
-{
- struct wrap_box *sbox;
-
- sbox = &p->cursor_frame->lines[p->cursor_line].boxes[p->cursor_box];
-
- if ( p->cursor_pos > sbox->len_chars ) {
- advance_cursor(p);
- }
-}
-
-
-static void move_cursor(struct presentation *p, signed int x, signed int y)
-{
- if ( x > 0 ) {
- advance_cursor(p);
- } else {
- move_cursor_back(p);
- }
-}
-
-
-static void insert_text(char *t, struct presentation *p)
-{
- int sln, sbx, sps;
- struct wrap_box *sbox;
- struct frame *fr = p->cursor_frame;
-
- if ( fr == NULL ) return;
-
- /* If this is, say, the top level frame, do nothing */
- if ( fr->boxes == NULL ) return;
-
- sln = p->cursor_line;
- sbx = p->cursor_box;
- sps = p->cursor_pos;
- sbox = &p->cursor_frame->lines[sln].boxes[sbx];
-
- sc_insert_text(sbox->scblock, sps+sbox->offs_char, t);
-
- fr->empty = 0;
-
- rerender_slide(p);
-
- fixup_cursor(p);
- advance_cursor(p);
-
- redraw_editor(p);
-}
-
-
-static void do_backspace(struct frame *fr, struct presentation *p)
-{
- int sln, sbx, sps;
-
- if ( fr == NULL ) return;
-
- /* If this is, say, the top level frame, do nothing */
- if ( fr->n_lines == 0 ) return;
-
- sln = p->cursor_line;
- sbx = p->cursor_box;
- sps = p->cursor_pos;
- struct wrap_box *sbox = &p->cursor_frame->lines[sln].boxes[sbx];
-
- move_cursor_back(p);
-
- /* Delete may cross wrap boxes and maybe SCBlock boundaries */
- struct wrap_line *fline = &p->cursor_frame->lines[p->cursor_line];
- struct wrap_box *fbox = &fline->boxes[p->cursor_box];
-
-// SCBlock *scbl = sbox->scblock;
-// do {
-// show_sc_blocks(scbl);
-// scbl = sc_block_next(scbl);
-// } while ( (scbl != fbox->scblock) && (scbl != NULL) );
-
- if ( (fbox->scblock == NULL) || (sbox->scblock == NULL) ) return;
- sc_delete_text(fbox->scblock, p->cursor_pos+fbox->offs_char,
- sbox->scblock, sps+sbox->offs_char);
-
-// scbl = sbox->scblock;
-// do {
-// show_sc_blocks(scbl);
-// scbl = sc_block_next(scbl);
-// } while ( (scbl != fbox->scblock) && (scbl != NULL) );
-
- rerender_slide(p);
- redraw_editor(p);
-}
-
-
-static gboolean im_commit_sig(GtkIMContext *im, gchar *str,
- struct presentation *p)
-{
- if ( p->n_selection == 0 ) {
- if ( str[0] == 'b' ) {
- check_toggle_blank(p);
- } else {
- printf("IM keypress: %s\n", str);
- }
- return FALSE;
- }
-
- insert_text(str, p);
-
- return FALSE;
-}
-
-
-static int within_frame(struct frame *fr, double x, double y)
-{
- if ( x < fr->x ) return 0;
- if ( y < fr->y ) return 0;
- if ( x > fr->x + fr->w ) return 0;
- if ( y > fr->y + fr->h ) return 0;
- return 1;
-}
-
-
-static struct frame *find_frame_at_position(struct frame *fr,
- double x, double y)
-{
- int i;
-
- for ( i=0; i<fr->num_children; i++ ) {
-
- if ( within_frame(fr->children[i], x, y) ) {
- return find_frame_at_position(fr->children[i], x, y);
- }
-
- }
-
- if ( within_frame(fr, x, y) ) return fr;
- return NULL;
-}
-
-
-static enum corner which_corner(double xp, double yp, struct frame *fr)
-{
- double x, y; /* Relative to object position */
-
- x = xp - fr->x;
- y = yp - fr->y;
-
- if ( x < 0.0 ) return CORNER_NONE;
- if ( y < 0.0 ) return CORNER_NONE;
- if ( x > fr->w ) return CORNER_NONE;
- if ( y > fr->h ) return CORNER_NONE;
-
- /* Top left? */
- if ( (x<20.0) && (y<20.0) ) return CORNER_TL;
- if ( (x>fr->w-20.0) && (y<20.0) ) return CORNER_TR;
- if ( (x<20.0) && (y>fr->h-20.0) ) {
- return CORNER_BL;
- }
- if ( (x>fr->w-20.0) && (y>fr->h-20.0) ) {
- return CORNER_BR;
- }
-
- return CORNER_NONE;
-}
-
-
-static void calculate_box_size(struct frame *fr, struct presentation *p,
- double x, double y)
-{
- double ddx, ddy, dlen, mult;
- double vx, vy, dbx, dby;
-
- ddx = x - p->start_corner_x;
- ddy = y - p->start_corner_y;
-
- if ( !fr->is_image ) {
-
- switch ( p->drag_corner ) {
-
- case CORNER_BR :
- p->box_x = fr->x;
- p->box_y = fr->y;
- p->box_width = fr->w + ddx;
- p->box_height = fr->h + ddy;
- break;
-
- case CORNER_BL :
- p->box_x = fr->x + ddx;
- p->box_y = fr->y;
- p->box_width = fr->w - ddx;
- p->box_height = fr->h + ddy;
- break;
-
- case CORNER_TL :
- p->box_x = fr->x + ddx;
- p->box_y = fr->y + ddy;
- p->box_width = fr->w - ddx;
- p->box_height = fr->h - ddy;
- break;
-
- case CORNER_TR :
- p->box_x = fr->x;
- p->box_y = fr->y + ddy;
- p->box_width = fr->w + ddx;
- p->box_height = fr->h - ddy;
- break;
-
- case CORNER_NONE :
- break;
-
- }
- return;
-
-
- }
-
- switch ( p->drag_corner ) {
-
- case CORNER_BR :
- vx = fr->w;
- vy = fr->h;
- break;
-
- case CORNER_BL :
- vx = -fr->w;
- vy = fr->h;
- break;
-
- case CORNER_TL :
- vx = -fr->w;
- vy = -fr->h;
- break;
-
- case CORNER_TR :
- vx = fr->w;
- vy = -fr->h;
- break;
-
- case CORNER_NONE :
- default:
- vx = 0.0;
- vy = 0.0;
- break;
-
- }
-
- dlen = (ddx*vx + ddy*vy) / p->diagonal_length;
- mult = (dlen+p->diagonal_length) / p->diagonal_length;
-
- p->box_width = fr->w * mult;
- p->box_height = fr->h * mult;
- dbx = p->box_width - fr->w;
- dby = p->box_height - fr->h;
-
- if ( p->box_width < 40.0 ) {
- mult = 40.0 / fr->w;
- }
- if ( p->box_height < 40.0 ) {
- mult = 40.0 / fr->h;
- }
- p->box_width = fr->w * mult;
- p->box_height = fr->h * mult;
- dbx = p->box_width - fr->w;
- dby = p->box_height - fr->h;
-
- switch ( p->drag_corner ) {
-
- case CORNER_BR :
- p->box_x = fr->x;
- p->box_y = fr->y;
- break;
-
- case CORNER_BL :
- p->box_x = fr->x - dbx;
- p->box_y = fr->y;
- break;
-
- case CORNER_TL :
- p->box_x = fr->x - dbx;
- p->box_y = fr->y - dby;
- break;
-
- case CORNER_TR :
- p->box_x = fr->x;
- p->box_y = fr->y - dby;
- break;
-
- case CORNER_NONE :
- break;
-
- }
-
-}
-
-
-static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
- struct presentation *p)
-{
- enum corner c;
- gdouble x, y;
- struct frame *clicked;
-
- x = event->x - p->border_offs_x;
- y = event->y - p->border_offs_y;
-
- if ( (p->n_selection > 0) && within_frame(p->selection[0], x, y) ) {
- clicked = p->selection[0];
- } else {
- clicked = find_frame_at_position(p->cur_edit_slide->top, x, y);
- }
-
- /* If the user clicked the currently selected frame, position cursor
- * or possibly prepare for resize */
- if ( (p->n_selection > 0) && (clicked == p->selection[0]) ) {
-
- struct frame *fr;
-
- fr = p->selection[0];
-
- /* Within the resizing region? */
- c = which_corner(x, y, fr);
- if ( c != CORNER_NONE ) {
-
- p->drag_reason = DRAG_REASON_RESIZE;
- p->drag_corner = c;
-
- p->start_corner_x = x;
- p->start_corner_y = y;
- p->diagonal_length = pow(fr->w, 2.0);
- p->diagonal_length += pow(fr->h, 2.0);
- p->diagonal_length = sqrt(p->diagonal_length);
-
- calculate_box_size(fr, p, x, y);
-
- p->drag_status = DRAG_STATUS_COULD_DRAG;
- p->drag_reason = DRAG_REASON_RESIZE;
-
- } else {
-
- p->cursor_frame = clicked;
- find_cursor(clicked, x-fr->x, y-fr->y,
- &p->cursor_line, &p->cursor_box,
- &p->cursor_pos);
-
- p->start_corner_x = event->x - p->border_offs_x;
- p->start_corner_y = event->y - p->border_offs_y;
- p->drag_status = DRAG_STATUS_COULD_DRAG;
- p->drag_reason = DRAG_REASON_MOVE;
-
- }
-
- } else if ( (clicked == NULL) || (clicked == p->cur_edit_slide->top) ) {
-
- /* Clicked no object. Deselect old object and set up for
- * (maybe) creating a new one. */
- set_selection(p, NULL);
- p->start_corner_x = event->x - p->border_offs_x;
- p->start_corner_y = event->y - p->border_offs_y;
- p->drag_status = DRAG_STATUS_COULD_DRAG;
- p->drag_reason = DRAG_REASON_CREATE;
-
- } else {
-
- /* Select new frame, no immediate dragging */
- p->drag_status = DRAG_STATUS_NONE;
- p->drag_reason = DRAG_REASON_NONE;
- set_selection(p, clicked);
-
- }
-
- gtk_widget_grab_focus(GTK_WIDGET(da));
- redraw_editor(p);
- return FALSE;
-}
-
-
-static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event,
- struct presentation *p)
-{
- struct frame *fr = p->selection[0];
- gdouble x, y;
-
- x = event->x - p->border_offs_x;
- y = event->y - p->border_offs_y;
-
- if ( p->drag_status == DRAG_STATUS_COULD_DRAG ) {
-
- /* We just got a motion signal, and the status was "could drag",
- * therefore the drag has started. */
- p->drag_status = DRAG_STATUS_DRAGGING;
-
- }
-
- switch ( p->drag_reason ) {
-
- case DRAG_REASON_NONE :
- break;
-
- case DRAG_REASON_CREATE :
- p->drag_corner_x = x;
- p->drag_corner_y = y;
- redraw_editor(p);
- break;
-
- case DRAG_REASON_IMPORT :
- /* Do nothing, handled by dnd_motion() */
- break;
-
- case DRAG_REASON_RESIZE :
- calculate_box_size(fr, p, x, y);
- redraw_editor(p);
- break;
-
- case DRAG_REASON_MOVE :
- p->box_x = (fr->x - p->start_corner_x) + x;
- p->box_y = (fr->y - p->start_corner_y) + y;
- p->box_width = fr->w;
- p->box_height = fr->h;
- redraw_editor(p);
- break;
-
- }
-
- gdk_event_request_motions(event);
- return FALSE;
-}
-
-
-static struct frame *create_frame(struct presentation *p, double x, double y,
- double w, double h)
-{
- struct frame *parent;
- struct frame *fr;
-
- parent = p->cur_edit_slide->top;
-
- if ( w < 0.0 ) {
- x += w;
- w = -w;
- }
-
- if ( h < 0.0 ) {
- y += h;
- h = -h;
- }
-
- fr = add_subframe(parent);
-
- /* Add to SC */
- fr->scblocks = sc_block_append_end(p->cur_edit_slide->scblocks,
- "f", NULL, NULL);
- sc_block_set_frame(fr->scblocks, fr);
- sc_block_append_inside(fr->scblocks, NULL, NULL, strdup(""));
-
- fr->x = x;
- fr->y = y;
- fr->w = w;
- fr->h = h;
- fr->is_image = 0;
- fr->empty = 1;
-
- update_geom(fr);
-
- return fr;
-}
-
-
-static void do_resize(struct presentation *p, double x, double y,
- double w, double h)
-{
- struct frame *fr;
-
- assert(p->n_selection > 0);
-
- if ( w < 0.0 ) {
- w = -w;
- x -= w;
- }
-
- if ( h < 0.0 ) {
- h = -h;
- y -= h;
- }
-
- fr = p->selection[0];
- fr->x = x;
- fr->y = y;
- fr->w = w;
- fr->h = h;
- update_geom(fr);
-
- rerender_slide(p);
- redraw_editor(p);
-}
-
-
-static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event,
- struct presentation *p)
-{
- gdouble x, y;
- struct frame *fr;
-
- x = event->x - p->border_offs_x;
- y = event->y - p->border_offs_y;
-
- /* Not dragging? Then I don't care. */
- if ( p->drag_status != DRAG_STATUS_DRAGGING ) return FALSE;
-
- p->drag_corner_x = x;
- p->drag_corner_y = y;
- p->drag_status = DRAG_STATUS_NONE;
-
- switch ( p->drag_reason )
- {
-
- case DRAG_REASON_NONE :
- printf("Release on pointless drag.\n");
- break;
-
- case DRAG_REASON_CREATE :
- fr = create_frame(p, p->start_corner_x, p->start_corner_y,
- p->drag_corner_x - p->start_corner_x,
- p->drag_corner_y - p->start_corner_y);
- rerender_slide(p);
- set_selection(p, fr);
- break;
-
- case DRAG_REASON_IMPORT :
- /* Do nothing, handled in dnd_drop() or dnd_leave() */
- break;
-
- case DRAG_REASON_RESIZE :
- do_resize(p, p->box_x, p->box_y, p->box_width, p->box_height);
- break;
-
- case DRAG_REASON_MOVE :
- do_resize(p, p->box_x, p->box_y, p->box_width, p->box_height);
- break;
-
- }
-
- p->drag_reason = DRAG_REASON_NONE;
-
- gtk_widget_grab_focus(GTK_WIDGET(da));
- redraw_editor(p);
- return FALSE;
-}
-
-
-static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event,
- struct presentation *p)
-{
- gboolean r;
- int claim = 0;
-
- /* Throw the event to the IM context and let it sort things out */
- r = gtk_im_context_filter_keypress(GTK_IM_CONTEXT(p->im_context),
- event);
- if ( r ) return FALSE; /* IM ate it */
-
- switch ( event->keyval ) {
-
- case GDK_KEY_Page_Up :
- prev_slide_sig(NULL, p);
- claim = 1;
- break;
-
- case GDK_KEY_Page_Down :
- next_slide_sig(NULL, p);
- claim = 1;
- break;
-
- case GDK_KEY_Escape :
- if ( p->slideshow != NULL ) end_slideshow(p);
- set_selection(p, NULL);
- redraw_editor(p);
- claim = 1;
- break;
-
- case GDK_KEY_Left :
- if ( p->n_selection == 1 ) {
- move_cursor(p, -1, 0);
- redraw_editor(p);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Right :
- if ( p->n_selection == 1 ) {
- move_cursor(p, +1, 0);
- redraw_editor(p);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Up :
- if ( p->n_selection == 1 ) {
- move_cursor(p, 0, -1);
- redraw_editor(p);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Down :
- if ( p->n_selection == 1 ) {
- move_cursor(p, 0, +1);
- redraw_editor(p);
- }
- claim = 1;
- break;
-
-
- case GDK_KEY_Return :
- im_commit_sig(NULL, "\n", p);
- claim = 1;
- break;
-
- case GDK_KEY_BackSpace :
- if ( p->n_selection == 1 ) {
- do_backspace(p->selection[0], p);
- claim = 1;
- }
- break;
-
- case GDK_KEY_B :
- case GDK_KEY_b :
- if ( p->slideshow != NULL ) {
- //if ( p->prefs->b_splits ) {
- toggle_slideshow_link(p);
- //} else {
- // p->ss_blank = 1-p->ss_blank;
- // redraw_slideshow(p);
- //}
- }
- claim = 1;
- break;
-
- }
-
- if ( claim ) return TRUE;
- return FALSE;
-}
-
-
-static gboolean dnd_motion(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, guint time, struct presentation *p)
-{
- GdkAtom target;
-
- /* If we haven't already requested the data, do so now */
- if ( !p->drag_preview_pending && !p->have_drag_data ) {
-
- target = gtk_drag_dest_find_target(widget, drag_context, NULL);
-
- if ( target != GDK_NONE ) {
- gtk_drag_get_data(widget, drag_context, target, time);
- p->drag_preview_pending = 1;
- } else {
- p->import_acceptable = 0;
- gdk_drag_status(drag_context, 0, time);
- }
-
- }
-
- if ( p->have_drag_data && p->import_acceptable ) {
-
- gdk_drag_status(drag_context, GDK_ACTION_LINK, time);
- p->start_corner_x = x - p->import_width/2.0;
- p->start_corner_y = y - p->import_height/2.0;
- p->drag_corner_x = x + p->import_width/2.0;
- p->drag_corner_y = y + p->import_height/2.0;
-
- redraw_editor(p);
-
- }
-
- return TRUE;
-}
-
-
-static gboolean dnd_drop(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, guint time, struct presentation *p)
-{
- GdkAtom target;
-
- target = gtk_drag_dest_find_target(widget, drag_context, NULL);
-
- if ( target == GDK_NONE ) {
- gtk_drag_finish(drag_context, FALSE, FALSE, time);
- } else {
- gtk_drag_get_data(widget, drag_context, target, time);
- }
-
- return TRUE;
-}
-
-
-static void chomp(char *s)
-{
- size_t i;
-
- if ( !s ) return;
-
- for ( i=0; i<strlen(s); i++ ) {
- if ( (s[i] == '\n') || (s[i] == '\r') ) {
- s[i] = '\0';
- return;
- }
- }
-}
-
-
-/* Scale the image down if it's a silly size */
-static void check_import_size(struct presentation *p)
-{
- if ( p->import_width > p->slide_width ) {
-
- int new_import_width;
-
- new_import_width = p->slide_width/2;
- p->import_height = (new_import_width *p->import_height)
- / p->import_width;
- p->import_width = new_import_width;
- }
-
- if ( p->import_height > p->slide_height ) {
-
- int new_import_height;
-
- new_import_height = p->slide_height/2;
- p->import_width = (new_import_height*p->import_width)
- / p->import_height;
- p->import_height = new_import_height;
- }
-}
-
-
-static void dnd_receive(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, GtkSelectionData *seldata,
- guint info, guint time, struct presentation *p)
-{
- if ( p->drag_preview_pending ) {
-
- gchar *filename = NULL;
- GdkPixbufFormat *f;
- gchar **uris;
- int w, h;
-
- p->have_drag_data = 1;
- p->drag_preview_pending = 0;
- uris = gtk_selection_data_get_uris(seldata);
- if ( uris != NULL ) {
- filename = g_filename_from_uri(uris[0], NULL, NULL);
- }
- g_strfreev(uris);
-
- if ( filename == NULL ) {
-
- /* This doesn't even look like a sensible URI.
- * Bail out. */
- gdk_drag_status(drag_context, 0, time);
- if ( p->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- p->drag_highlight = 0;
- }
- p->import_acceptable = 0;
- return;
-
- }
- chomp(filename);
-
- f = gdk_pixbuf_get_file_info(filename, &w, &h);
- g_free(filename);
-
- p->import_width = w;
- p->import_height = h;
-
- if ( f == NULL ) {
-
- gdk_drag_status(drag_context, 0, time);
- if ( p->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- p->drag_highlight = 0;
- }
- p->drag_status = DRAG_STATUS_NONE;
- p->drag_reason = DRAG_REASON_NONE;
- p->import_acceptable = 0;
-
- } else {
-
- /* Looks like a sensible image */
- gdk_drag_status(drag_context, GDK_ACTION_PRIVATE, time);
- p->import_acceptable = 1;
-
- if ( !p->drag_highlight ) {
- gtk_drag_highlight(widget);
- p->drag_highlight = 1;
- }
-
- check_import_size(p);
- p->drag_reason = DRAG_REASON_IMPORT;
- p->drag_status = DRAG_STATUS_DRAGGING;
-
- }
-
- } else {
-
- gchar **uris;
- char *filename = NULL;
-
- uris = gtk_selection_data_get_uris(seldata);
- if ( uris != NULL ) {
- filename = g_filename_from_uri(uris[0], NULL, NULL);
- }
- g_strfreev(uris);
-
- if ( filename != NULL ) {
-
- struct frame *fr;
- char *opts;
- size_t len;
- int w, h;
-
- gtk_drag_finish(drag_context, TRUE, FALSE, time);
- chomp(filename);
-
- w = p->drag_corner_x - p->start_corner_x;
- h = p->drag_corner_y - p->start_corner_y;
-
- len = strlen(filename)+64;
- opts = malloc(len);
- if ( opts == NULL ) {
- free(filename);
- fprintf(stderr, "Failed to allocate SC\n");
- return;
- }
- snprintf(opts, len, "1fx1f+0+0,filename=\"%s\"",
- filename);
-
- fr = create_frame(p, p->start_corner_x,
- p->start_corner_y, w, h);
- fr->is_image = 1;
- fr->empty = 0;
- sc_block_append_inside(fr->scblocks, "image", opts, "");
- show_hierarchy(p->cur_edit_slide->top, "");
- rerender_slide(p);
- set_selection(p, fr);
- redraw_editor(p);
- free(filename);
-
- } else {
-
- gtk_drag_finish(drag_context, FALSE, FALSE, time);
-
- }
-
- }
-}
-
-
-static void dnd_leave(GtkWidget *widget, GdkDragContext *drag_context,
- guint time, struct presentation *p)
-{
- if ( p->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- }
- p->have_drag_data = 0;
- p->drag_highlight = 0;
- p->drag_status = DRAG_STATUS_NONE;
- p->drag_reason = DRAG_REASON_NONE;
-}
-
-
-static gint realise_sig(GtkWidget *da, struct presentation *p)
-{
- GdkWindow *win;
-
- /* Keyboard and input method stuff */
- p->im_context = gtk_im_multicontext_new();
- win = gtk_widget_get_window(p->drawingarea);
- gtk_im_context_set_client_window(GTK_IM_CONTEXT(p->im_context), win);
- gdk_window_set_accept_focus(win, TRUE);
- g_signal_connect(G_OBJECT(p->im_context), "commit",
- G_CALLBACK(im_commit_sig), p);
- g_signal_connect(G_OBJECT(p->drawingarea), "key-press-event",
- G_CALLBACK(key_press_sig), p);
-
- /* FIXME: Can do this "properly" by setting up a separate font map */
- p->pc = gtk_widget_get_pango_context(da);
- rerender_slide(p);
-
- return FALSE;
-}
-
-
-int open_mainwindow(struct presentation *p)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *sw;
- GtkTargetEntry targets[1];
-
- if ( p->window != NULL ) {
- fprintf(stderr, "Presentation window is already open!\n");
- return 1;
- }
-
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- p->window = window;
-
- update_titlebar(p);
-
- g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(close_sig), p);
-
- vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add(GTK_CONTAINER(window), vbox);
-
- p->drawingarea = gtk_drawing_area_new();
- sw = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw),
- p->drawingarea);
- gtk_widget_set_size_request(GTK_WIDGET(p->drawingarea),
- p->slide_width + 20,
- p->slide_height + 20);
-
- add_menu_bar(p, vbox);
- gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
- g_signal_connect(G_OBJECT(p->drawingarea), "realize",
- G_CALLBACK(realise_sig), p);
- g_signal_connect(G_OBJECT(p->drawingarea), "button-press-event",
- G_CALLBACK(button_press_sig), p);
- g_signal_connect(G_OBJECT(p->drawingarea), "button-release-event",
- G_CALLBACK(button_release_sig), p);
- g_signal_connect(G_OBJECT(p->drawingarea), "motion-notify-event",
- G_CALLBACK(motion_sig), p);
-
- /* Drag and drop */
- targets[0].target = "text/uri-list";
- targets[0].flags = 0;
- targets[0].info = 1;
- gtk_drag_dest_set(p->drawingarea, 0, targets, 1, GDK_ACTION_PRIVATE);
- g_signal_connect(p->drawingarea, "drag-data-received",
- G_CALLBACK(dnd_receive), p);
- g_signal_connect(p->drawingarea, "drag-motion",
- G_CALLBACK(dnd_motion), p);
- g_signal_connect(p->drawingarea, "drag-drop",
- G_CALLBACK(dnd_drop), p);
- g_signal_connect(p->drawingarea, "drag-leave",
- G_CALLBACK(dnd_leave), p);
-
- gtk_widget_set_can_focus(GTK_WIDGET(p->drawingarea), TRUE);
- gtk_widget_add_events(GTK_WIDGET(p->drawingarea),
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
-
- g_signal_connect(G_OBJECT(p->drawingarea), "draw",
- G_CALLBACK(draw_sig), p);
-
- /* Default size */
- gtk_window_set_default_size(GTK_WINDOW(p->window), 1024+100, 768+150);
- gtk_window_set_resizable(GTK_WINDOW(p->window), TRUE);
-
- assert(p->num_slides > 0);
-
- gtk_widget_grab_focus(GTK_WIDGET(p->drawingarea));
-
- gtk_widget_show_all(window);
-
- return 0;
-}