From 63bf23cdcb107e0ff61f0eda0ebfcc264877defe Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Sun, 22 Apr 2007 11:31:25 +0200 Subject: [PATCH 1/1] Initial commit. --- Makefile | 14 ++ config.h | 2 + src/main.c | 26 ++++ src/rakt-window.c | 352 ++++++++++++++++++++++++++++++++++++++++++++++ src/rakt-window.h | 57 ++++++++ 5 files changed, 451 insertions(+) create mode 100644 Makefile create mode 100644 config.h create mode 100644 src/main.c create mode 100644 src/rakt-window.c create mode 100644 src/rakt-window.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c12a570 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +CFLAGS += -I. -DHAVE_CONFIG_H `pkg-config --cflags poppler-glib gtk+-2.0` +LDFLAGS += `pkg-config --libs poppler-glib gtk+-2.0` + +BIN = src/raktpdf +OBJS = src/main.o src/rakt-window.o + +$(BIN): $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o $@ + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) $(BIN) diff --git a/config.h b/config.h new file mode 100644 index 0000000..bfb2e72 --- /dev/null +++ b/config.h @@ -0,0 +1,2 @@ +#define VERSION "0.0.1" +#define PACKAGE_NAME "RaktPDF" diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..398a78f --- /dev/null +++ b/src/main.c @@ -0,0 +1,26 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "rakt-window.h" + +int +main (int argc, char **argv) +{ + GtkWidget *window; + + gtk_init (&argc, &argv); + + g_set_application_name (PACKAGE_NAME); + + window = rakt_window_new (); + gtk_widget_show (window); + + gtk_main (); + + gtk_widget_destroy (window); + + return 0; +} diff --git a/src/rakt-window.c b/src/rakt-window.c new file mode 100644 index 0000000..59dfca4 --- /dev/null +++ b/src/rakt-window.c @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2007 Tilman Sauerbeck (tilman at code-monkey de) + * + * 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 2 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include +#include + +#include "rakt-window.h" + +typedef struct RaktWindowPriv RaktWindowPriv; + +struct RaktWindowPriv { + GtkWidget *content_vbox; + + /* Menu & toolbar */ + GtkUIManager *ui_manager; + GtkAction *action_prev; + GtkAction *action_next; + + GtkWidget *image; + GdkPixbuf *pixbuf; + PopplerDocument *document; + gint page_no; +}; + +static void window_finalize (GObject *object); + +static void on_add_widget (GtkUIManager *merge, GtkWidget *widget, RaktWindow *window); + +static void on_action_quit (GtkAction *action, RaktWindow *window); +static void on_action_open (GtkAction *action, RaktWindow *window); +static void on_action_go_next (GtkAction *action, RaktWindow *window); +static void on_action_go_previous (GtkAction *action, RaktWindow *window); +static void on_action_about (GtkAction *action, RaktWindow *window); + +static const GtkActionEntry action_entries[] = { + { + "FileMenu", NULL, "_File", NULL, NULL, NULL + }, + { + "HelpMenu", NULL, "_Help", NULL, NULL, NULL + }, + { + "Open", GTK_STOCK_OPEN, + "_Open", "O", "Open a PDF file", + G_CALLBACK (on_action_open) + }, + { + "Next", GTK_STOCK_GO_FORWARD, "_Next", + "n", "Next", + G_CALLBACK (on_action_go_next) + }, + { + "Previous", GTK_STOCK_GO_BACK, "_Previous", + "p", "Previous", + G_CALLBACK (on_action_go_previous) + }, + { + "Quit", GTK_STOCK_QUIT, + "_Quit", "Q", "Quit the application", + G_CALLBACK (on_action_quit) + }, + { + "About", GTK_STOCK_ABOUT, + "_About", NULL, "About this application", + G_CALLBACK (on_action_about) + } +}; + +static const gchar *ui_layout = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +G_DEFINE_TYPE (RaktWindow, rakt_window, GTK_TYPE_WINDOW) + +#define GET_PRIV(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), RAKT_TYPE_WINDOW, RaktWindowPriv)) + +static void +rakt_window_class_init (RaktWindowClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = window_finalize; + + g_type_class_add_private (object_class, sizeof (RaktWindowPriv)); +} + +static void +render_page (RaktWindow *window) +{ + RaktWindowPriv *priv; + PopplerPage *page; + double tmpw, tmph; + int width, height, n_pages; + + priv = GET_PRIV (window); + + n_pages = poppler_document_get_n_pages (priv->document); + gtk_action_set_sensitive (priv->action_prev, priv->page_no > 0); + gtk_action_set_sensitive (priv->action_next, priv->page_no < n_pages); + + page = poppler_document_get_page (priv->document, priv->page_no); + + poppler_page_get_size (page, &tmpw, &tmph); + + width = (int) tmpw; + height = (int) tmph; + + priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, + width, height); + + poppler_page_render_to_pixbuf (page, 0, 0, width, height, 1.0, 0, + priv->pixbuf); + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), priv->pixbuf); +} + +static void +open_document (RaktWindow *window, gchar *file) +{ + RaktWindowPriv *priv; + GError *error = NULL; + gchar real[PATH_MAX], buf[16 + PATH_MAX]; + + priv = GET_PRIV (window); + + realpath (file, real); + + g_strlcpy (buf, "file://", sizeof (buf)); + g_strlcat (buf, real, sizeof (buf)); + + priv->document = poppler_document_new_from_file (buf, NULL, &error); + + priv->page_no = 0; + render_page (window); +} + +static void +window_create_menu (RaktWindow *window) +{ + RaktWindowPriv *priv; + GtkActionGroup *action_group; + GError *error = NULL; + + priv = GET_PRIV (window); + + priv->ui_manager = gtk_ui_manager_new (); + + g_signal_connect (priv->ui_manager, + "add_widget", + G_CALLBACK (on_add_widget), + window); + + action_group = gtk_action_group_new ("Actions"); + gtk_action_group_add_actions (action_group, action_entries, + G_N_ELEMENTS (action_entries), window); + gtk_ui_manager_insert_action_group (priv->ui_manager, action_group, 0); + g_object_unref (action_group); + + gtk_ui_manager_add_ui_from_string (priv->ui_manager, ui_layout, -1, &error); + + if (error) + g_error ("Couldn't create UI: %s\n", error->message); + + gtk_ui_manager_ensure_update (priv->ui_manager); + + priv->action_prev = gtk_ui_manager_get_action (priv->ui_manager, + "ui/ToolBar/Previous"); + priv->action_next = gtk_ui_manager_get_action (priv->ui_manager, + "ui/ToolBar/Next"); + + gtk_action_set_sensitive (priv->action_prev, false); + gtk_action_set_sensitive (priv->action_next, false); +} + +static gboolean +on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + gtk_main_quit (); + + return FALSE; +} + +static void +rakt_window_init (RaktWindow *window) +{ + RaktWindowPriv *priv; + + priv = GET_PRIV (window); + + gtk_window_set_default_size (GTK_WINDOW (window), 640, 480); + gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); + + priv->content_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (priv->content_vbox); + gtk_container_add (GTK_CONTAINER (window), priv->content_vbox); + + window_create_menu (window); + + priv->image = gtk_image_new (); + + gtk_widget_show (priv->image); + gtk_box_pack_start (GTK_BOX (priv->content_vbox), priv->image, + TRUE, TRUE, 0); + + g_signal_connect (GTK_WINDOW (window), "delete-event", + G_CALLBACK (on_delete_event), NULL); +} + +static void +window_finalize (GObject *object) +{ + RaktWindowPriv *priv; + + priv = GET_PRIV (object); + + g_object_unref (priv->ui_manager); + + G_OBJECT_CLASS (rakt_window_parent_class)->finalize (object); +} + +static void +on_add_widget (GtkUIManager *merge, GtkWidget *widget, RaktWindow *window) +{ + RaktWindowPriv *priv; + + priv = GET_PRIV (window); + + gtk_box_pack_start (GTK_BOX (priv->content_vbox), widget, FALSE, FALSE, 0); +} + +static void +on_action_quit (GtkAction *action, RaktWindow *window) +{ + gtk_main_quit (); +} + +static void +on_action_open (GtkAction *action, RaktWindow *window) +{ + GtkWidget *dialog; + GtkFileFilter *filter; + gint n; + + dialog = gtk_file_chooser_dialog_new ("Open PDF", + GTK_WINDOW (window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, NULL); + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, "PDF files"); + gtk_file_filter_add_pattern (filter, "*.pdf"); + + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + + /* now run the dialog */ + n = gtk_dialog_run (GTK_DIALOG (dialog)); + + if (n == GTK_RESPONSE_ACCEPT) { + gchar *file; + + file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + open_document (window, file); + } + + gtk_widget_destroy (dialog); +} + +static void +on_action_go_next (GtkAction *action, RaktWindow *window) +{ + RaktWindowPriv *priv; + + priv = GET_PRIV (window); + + priv->page_no++; + render_page (window); +} + +static void +on_action_go_previous (GtkAction *action, RaktWindow *window) +{ + RaktWindowPriv *priv; + + priv = GET_PRIV (window); + + priv->page_no--; + render_page (window); +} + +static void +on_action_about (GtkAction *action, RaktWindow *window) +{ + const gchar *authors[] = { + "Tilman Sauerbeck", + NULL + }; + + gtk_show_about_dialog (GTK_WINDOW (window), + "name", PACKAGE_NAME, + "copyright", "Copyright (c) 2007 Tilman Sauerbeck", + "version", VERSION, + "authors", authors, + NULL); +} + +GtkWidget * +rakt_window_new (void) +{ + return g_object_new (RAKT_TYPE_WINDOW, NULL); +} diff --git a/src/rakt-window.h b/src/rakt-window.h new file mode 100644 index 0000000..194c64f --- /dev/null +++ b/src/rakt-window.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007 Tilman Sauerbeck (tilman at code-monkey de) + * + * 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 2 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __RAKT_WINDOW_H +#define __RAKT_WINDOW_H + +#include + +G_BEGIN_DECLS + +#define RAKT_TYPE_WINDOW \ + (rakt_window_get_type ()) +#define RAKT_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), RAKT_TYPE_WINDOW, RaktWindow)) +#define RAKT_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), RAKT_TYPE_WINDOW, RaktWindowClass)) +#define RAKT_IS_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RAKT_TYPE_WINDOW)) +#define RAKT_IS_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), RAKT_TYPE_WINDOW)) +#define RAKT_WINDOW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), RAKT_TYPE_WINDOW, RaktWindowClass)) + +typedef struct RaktWindow RaktWindow; +typedef struct RaktWindowClass RaktWindowClass; + +struct RaktWindow { + GtkWindow parent_instance; +}; + +struct RaktWindowClass { + GtkWindowClass parent_class; + void (*quitting) (RaktWindow *window); +}; + +GType rakt_window_get_type (void); +GtkWidget *rakt_window_new (void); + +G_END_DECLS + +#endif -- 2.30.2