aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog8
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/e-shell-about-box.c372
-rw-r--r--shell/e-shell-about-box.h68
-rw-r--r--shell/e-shell-view-menu.c97
5 files changed, 483 insertions, 64 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 4c3135d9ee..c51a1e9d1b 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,11 @@
+2001-10-19 Ettore Perazzoli <ettore@ximian.com>
+
+ * e-shell-view-menu.c (command_about_box): Use EShellAboutBox.
+ (zero_pointer): Removed.
+
+ * e-shell-about-box.h: New.
+ * e-shell-about-box.c: New.
+
2001-10-18 Ettore Perazzoli <ettore@ximian.com>
* Makefile.am (evolution_SOURCES): Ooops. Remove stale files
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 8829330db2..2a2b847029 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -117,6 +117,8 @@ evolution_SOURCES = \
e-local-storage.h \
e-setup.c \
e-setup.h \
+ e-shell-about-box.h \
+ e-shell-about-box.c \
e-shell-constants.h \
e-shell-folder-commands.c \
e-shell-folder-commands.h \
diff --git a/shell/e-shell-about-box.c b/shell/e-shell-about-box.c
new file mode 100644
index 0000000000..71390c5313
--- /dev/null
+++ b/shell/e-shell-about-box.c
@@ -0,0 +1,372 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-shell-about-box.c
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * 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.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-shell-about-box.h"
+
+#include <gal/util/e-util.h>
+
+#include <gtk/gtkeventbox.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+
+#define PARENT_TYPE gtk_event_box_get_type ()
+static GtkEventBoxClass *parent_class = NULL;
+
+static const char *text[] = {
+ "",
+ N_("Evolution " VERSION),
+ N_("Copyright 1999, 2000, 2001 Ximian, Inc."),
+ "",
+ N_("Brought to you by"),
+ "",
+ "Seth Alves",
+ "Anders Carlsson",
+ "Damon Chaplin",
+ "Clifford R. Conover",
+ "Anna Dirks",
+ "Miguel de Icaza",
+ "Radek Doulik",
+ "Arturo Espinoza",
+ "Larry Ewing",
+ "Nat Friedman",
+ "Bertrand Guiheneuf",
+ "Iain Holmes",
+ "Tuomas Kuosmanen",
+ "Christopher J. Lahey",
+ "Jason Leach",
+ "Matthew Loper",
+ "Federico Mena",
+ "Rodrigo Moya",
+ "Eskil Heyn Olsen",
+ "Jesse Pavel",
+ "Ettore Perazzoli",
+ "JP Rosevear",
+ "Jeffrey Stedfast",
+ "Jakub Steiner",
+ "Russell Steinthal",
+ "Peter Teichman",
+ "Chris Toshok",
+ "Jon Trowbridge",
+ "Peter Williams",
+ "Dan Winship",
+ "Michael Zucchi"
+};
+#define NUM_TEXT_LINES (sizeof (text) / sizeof (*text))
+
+struct _EShellAboutBoxPrivate {
+ GdkPixmap *pixmap;
+ GdkPixmap *text_background_pixmap;
+ GdkGC *clipped_gc;
+ int text_y_offset;
+ int timeout_id;
+};
+
+
+#define ANIMATION_DELAY 40
+
+#define WIDTH 400
+#define HEIGHT 200
+
+#define TEXT_Y_OFFSET 57
+#define TEXT_X_OFFSET 60
+#define TEXT_WIDTH (WIDTH - 2 * TEXT_X_OFFSET)
+#define TEXT_HEIGHT 90
+
+#define IMAGE_PATH EVOLUTION_IMAGES "/about-box.png"
+
+
+/* The callback. */
+
+static int
+timeout_callback (void *data)
+{
+ EShellAboutBox *about_box;
+ EShellAboutBoxPrivate *priv;
+ GdkRectangle redraw_rect;
+ GtkWidget *widget;
+ int line_height;
+ int first_line;
+ int y;
+ int i;
+
+ about_box = E_SHELL_ABOUT_BOX (data);
+ priv = about_box->priv;
+
+ widget = GTK_WIDGET (about_box);
+
+ line_height = widget->style->font->ascent + widget->style->font->descent;
+
+ if (priv->text_y_offset < TEXT_HEIGHT) {
+ y = TEXT_Y_OFFSET + (TEXT_HEIGHT - priv->text_y_offset);
+ first_line = 0;
+ } else {
+ y = TEXT_Y_OFFSET - ((priv->text_y_offset - TEXT_HEIGHT) % line_height);
+ first_line = (priv->text_y_offset - TEXT_HEIGHT) / line_height;
+ }
+
+ gdk_draw_pixmap (priv->pixmap, priv->clipped_gc, priv->text_background_pixmap,
+ 0, 0,
+ TEXT_X_OFFSET, TEXT_Y_OFFSET, TEXT_WIDTH, TEXT_HEIGHT);
+
+ for (i = 0; i < TEXT_HEIGHT / line_height + 2; i ++) {
+ const char *line;
+ int x;
+
+ if (first_line + i >= NUM_TEXT_LINES)
+ break;
+
+ if (*text[first_line + i] == '\0')
+ line = "";
+ else
+ line = _(text[first_line + i]);
+
+ x = TEXT_X_OFFSET + (TEXT_WIDTH - gdk_string_width (widget->style->font, line)) / 2;
+
+ gdk_draw_string (priv->pixmap, widget->style->font, priv->clipped_gc, x, y, line);
+
+ y += line_height;
+ }
+
+ redraw_rect.x = TEXT_X_OFFSET;
+ redraw_rect.y = TEXT_Y_OFFSET;
+ redraw_rect.width = TEXT_WIDTH;
+ redraw_rect.height = TEXT_HEIGHT;
+ gtk_widget_draw (widget, &redraw_rect);
+
+ priv->text_y_offset ++;
+ if (priv->text_y_offset > line_height * NUM_TEXT_LINES + TEXT_HEIGHT)
+ priv->text_y_offset = 0;
+
+ return TRUE;
+}
+
+
+/* GtkObject methods. */
+
+static void
+impl_destroy (GtkObject *object)
+{
+ EShellAboutBox *about_box;
+ EShellAboutBoxPrivate *priv;
+
+ about_box = E_SHELL_ABOUT_BOX (object);
+ priv = about_box->priv;
+
+ if (priv->pixmap != NULL) {
+ gdk_pixmap_unref (priv->pixmap);
+ priv->pixmap = NULL;
+ }
+
+ if (priv->text_background_pixmap != NULL) {
+ gdk_pixmap_unref (priv->text_background_pixmap);
+ priv->text_background_pixmap = NULL;
+ }
+
+ if (priv->clipped_gc != NULL) {
+ gdk_gc_unref (priv->clipped_gc);
+ priv->clipped_gc = NULL;
+ }
+
+ if (priv->timeout_id != -1) {
+ g_source_remove (priv->timeout_id);
+ priv->timeout_id = -1;
+ }
+
+ g_free (priv);
+
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+/* GtkWidget methods. */
+
+static void
+impl_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ requisition->width = WIDTH;
+ requisition->height = HEIGHT;
+}
+
+static void
+impl_realize (GtkWidget *widget)
+{
+ EShellAboutBox *about_box;
+ EShellAboutBoxPrivate *priv;
+ GdkPixbuf *background_pixbuf;
+ GdkRectangle clip_rectangle;
+
+ (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+ about_box = E_SHELL_ABOUT_BOX (widget);
+ priv = about_box->priv;
+
+ background_pixbuf = gdk_pixbuf_new_from_file (IMAGE_PATH);
+ g_assert (background_pixbuf != NULL);
+ g_assert (gdk_pixbuf_get_width (background_pixbuf) == WIDTH);
+ g_assert (gdk_pixbuf_get_height (background_pixbuf) == HEIGHT);
+
+ g_assert (priv->pixmap == NULL);
+ priv->pixmap = gdk_pixmap_new (widget->window, WIDTH, HEIGHT, -1);
+
+ gdk_pixbuf_render_to_drawable (background_pixbuf, priv->pixmap, widget->style->black_gc,
+ 0, 0, 0, 0, WIDTH, HEIGHT,
+ GDK_RGB_DITHER_MAX, 0, 0);
+
+ g_assert (priv->clipped_gc == NULL);
+ priv->clipped_gc = gdk_gc_new (widget->window);
+ gdk_gc_copy (priv->clipped_gc, widget->style->black_gc);
+
+ clip_rectangle.x = TEXT_X_OFFSET;
+ clip_rectangle.y = TEXT_Y_OFFSET;
+ clip_rectangle.width = TEXT_WIDTH;
+ clip_rectangle.height = TEXT_HEIGHT;
+ gdk_gc_set_clip_rectangle (priv->clipped_gc, & clip_rectangle);
+
+ priv->text_background_pixmap = gdk_pixmap_new (widget->window, clip_rectangle.width, clip_rectangle.height, -1);
+ gdk_pixbuf_render_to_drawable (background_pixbuf, priv->text_background_pixmap, widget->style->black_gc,
+ TEXT_X_OFFSET, TEXT_Y_OFFSET,
+ 0, 0, TEXT_WIDTH, TEXT_HEIGHT,
+ GDK_RGB_DITHER_MAX, 0, 0);
+
+ g_assert (priv->timeout_id == -1);
+ priv->timeout_id = g_timeout_add (ANIMATION_DELAY, timeout_callback, about_box);
+
+ gdk_pixbuf_unref (background_pixbuf);
+}
+
+static void
+impl_unrealize (GtkWidget *widget)
+{
+ EShellAboutBox *about_box;
+ EShellAboutBoxPrivate *priv;
+
+ about_box = E_SHELL_ABOUT_BOX (widget);
+ priv = about_box->priv;
+
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+
+ g_assert (priv->clipped_gc != NULL);
+ gdk_gc_unref (priv->clipped_gc);
+ priv->clipped_gc = NULL;
+
+ g_assert (priv->pixmap != NULL);
+ gdk_pixmap_unref (priv->pixmap);
+ priv->pixmap = NULL;
+
+ if (priv->timeout_id != -1) {
+ g_source_remove (priv->timeout_id);
+ priv->timeout_id = -1;
+ }
+}
+
+static void
+impl_draw (GtkWidget *widget,
+ GdkRectangle *area)
+{
+ EShellAboutBox *about_box;
+ EShellAboutBoxPrivate *priv;
+
+ if (! GTK_WIDGET_DRAWABLE (widget))
+ return;
+
+ about_box = E_SHELL_ABOUT_BOX (widget);
+ priv = about_box->priv;
+
+ gdk_draw_pixmap (widget->window, widget->style->black_gc, priv->pixmap,
+ area->x, area->y,
+ area->x, area->y, area->width, area->height);
+}
+
+static int
+impl_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ if (! GTK_WIDGET_DRAWABLE (widget))
+ return FALSE;
+
+ gtk_widget_draw (widget, &event->area);
+
+ return TRUE;
+}
+
+
+static void
+class_init (GtkObjectClass *object_class)
+{
+ GtkWidgetClass *widget_class;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+
+ object_class->destroy = impl_destroy;
+
+ widget_class = GTK_WIDGET_CLASS (object_class);
+ widget_class->size_request = impl_size_request;
+ widget_class->realize = impl_realize;
+ widget_class->unrealize = impl_unrealize;
+ widget_class->draw = impl_draw;
+ widget_class->expose_event = impl_expose_event;
+}
+
+static void
+init (EShellAboutBox *shell_about_box)
+{
+ EShellAboutBoxPrivate *priv;
+
+ priv = g_new (EShellAboutBoxPrivate, 1);
+ priv->pixmap = NULL;
+ priv->text_background_pixmap = NULL;
+ priv->clipped_gc = NULL;
+ priv->timeout_id = -1;
+ priv->text_y_offset = 0;
+
+ shell_about_box->priv = priv;
+}
+
+
+void
+e_shell_about_box_construct (EShellAboutBox *about_box)
+{
+ g_return_if_fail (about_box != NULL);
+ g_return_if_fail (E_IS_SHELL_ABOUT_BOX (about_box));
+
+ /* Nothing to do here. */
+}
+
+GtkWidget *
+e_shell_about_box_new (void)
+{
+ EShellAboutBox *about_box;
+
+ about_box = gtk_type_new (e_shell_about_box_get_type ());
+ e_shell_about_box_construct (about_box);
+
+ return GTK_WIDGET (about_box);
+}
+
+
+E_MAKE_TYPE (e_shell_about_box, "EShellAboutBox", EShellAboutBox, class_init, init, GTK_TYPE_EVENT_BOX)
diff --git a/shell/e-shell-about-box.h b/shell/e-shell-about-box.h
new file mode 100644
index 0000000000..4ec80b71e8
--- /dev/null
+++ b/shell/e-shell-about-box.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-shell-about-box.h
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * 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.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifndef _E_SHELL_ABOUT_BOX_H_
+#define _E_SHELL_ABOUT_BOX_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnome.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define E_TYPE_SHELL_ABOUT_BOX (e_shell_about_box_get_type ())
+#define E_SHELL_ABOUT_BOX(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SHELL_ABOUT_BOX, EShellAboutBox))
+#define E_SHELL_ABOUT_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_ABOUT_BOX, EShellAboutBoxClass))
+#define E_IS_SHELL_ABOUT_BOX(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SHELL_ABOUT_BOX))
+#define E_IS_SHELL_ABOUT_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_ABOUT_BOX))
+
+
+typedef struct _EShellAboutBox EShellAboutBox;
+typedef struct _EShellAboutBoxPrivate EShellAboutBoxPrivate;
+typedef struct _EShellAboutBoxClass EShellAboutBoxClass;
+
+struct _EShellAboutBox {
+ GtkEventBox parent;
+
+ EShellAboutBoxPrivate *priv;
+};
+
+struct _EShellAboutBoxClass {
+ GtkEventBoxClass parent_class;
+};
+
+
+GtkType e_shell_about_box_get_type (void);
+void e_shell_about_box_construct (EShellAboutBox *about_box);
+GtkWidget *e_shell_about_box_new (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _E_SHELL_ABOUT_BOX_H_ */
diff --git a/shell/e-shell-view-menu.c b/shell/e-shell-view-menu.c
index ba4db225b3..e32a1a9d92 100644
--- a/shell/e-shell-view-menu.c
+++ b/shell/e-shell-view-menu.c
@@ -54,48 +54,13 @@
#include "e-shell-view-menu.h"
#include "e-shell-importer.h"
+#include "e-shell-about-box.h"
#include "e-shell-folder-commands.h"
#include "evolution-shell-component-utils.h"
-const char *authors[] = {
- "Seth Alves",
- "Anders Carlsson",
- "Damon Chaplin",
- "Clifford R. Conover",
- "Anna Dirks",
- "Miguel de Icaza",
- "Radek Doulik",
- "Arturo Espinoza",
- "Larry Ewing",
- "Nat Friedman",
- "Bertrand Guiheneuf",
- "Iain Holmes",
- "Tuomas Kuosmanen",
- "Christopher J. Lahey",
- "Jason Leach",
- "Matthew Loper",
- "Federico Mena",
- "Rodrigo Moya",
- "Eskil Heyn Olsen",
- "Jesse Pavel",
- "Ettore Perazzoli",
- "JP Rosevear",
- "Jeffrey Stedfast",
- "Jakub Steiner",
- "Russell Steinthal",
- "Peter Teichman",
- "Chris Toshok",
- "Jon Trowbridge",
- "Peter Williams",
- "Dan Winship",
- "Michael Zucchi",
- NULL
-};
-
-
/* Utility functions. */
static const char *
@@ -209,10 +174,19 @@ command_submit_bug (BonoboUIComponent *uih,
gnome_error_dialog (_("Bug buddy could not be run."));
}
-static void
-zero_pointer(GtkObject *object, void **pointer)
+static int
+about_box_event_callback (GtkWidget *widget,
+ GdkEvent *event,
+ void *data)
{
- *pointer = NULL;
+ GtkWidget **widget_pointer;
+
+ widget_pointer = (GtkWidget **) data;
+
+ gtk_widget_destroy (GTK_WIDGET (*widget_pointer));
+ *widget_pointer = NULL;
+
+ return TRUE;
}
static void
@@ -220,32 +194,27 @@ command_about_box (BonoboUIComponent *uih,
void *data,
const char *path)
{
- static GtkWidget *about_box = NULL;
-
- if (about_box) {
- gdk_window_raise(GTK_WIDGET(about_box)->window);
- } else {
- char *version;
-
- if (SUB_VERSION[0] == '\0')
- version = g_strdup (VERSION);
- else
- version = g_strdup_printf ("%s [%s]", VERSION, SUB_VERSION);
-
- about_box = gnome_about_new(_("Ximian Evolution"),
- version,
- _("Copyright 1999, 2000, 2001 Ximian, Inc."),
- authors,
- _("Ximian Evolution is a suite of groupware applications\n"
- "for mail, calendaring, and contact management\n"
- "within the GNOME desktop environment."),
- NULL);
- gtk_signal_connect(GTK_OBJECT(about_box), "destroy",
- GTK_SIGNAL_FUNC (zero_pointer), &about_box);
- gtk_widget_show(about_box);
-
- g_free (version);
+ static GtkWidget *about_box_window = NULL;
+ GtkWidget *about_box;
+
+ if (about_box_window != NULL) {
+ gdk_window_raise (about_box_window->window);
+ return;
}
+
+ about_box = e_shell_about_box_new ();
+ gtk_widget_show (about_box);
+
+ about_box_window = gtk_window_new (GTK_WINDOW_DIALOG);
+ gtk_signal_connect (GTK_OBJECT (about_box_window), "button_press_event",
+ GTK_SIGNAL_FUNC (about_box_event_callback), &about_box_window);
+ gtk_signal_connect (GTK_OBJECT (about_box_window), "delete_event",
+ GTK_SIGNAL_FUNC (about_box_event_callback), &about_box_window);
+
+ gtk_window_set_transient_for (GTK_WINDOW (about_box_window), GTK_WINDOW (data));
+ gtk_window_set_title (GTK_WINDOW (about_box_window), _("About Ximian Evolution"));
+ gtk_container_add (GTK_CONTAINER (about_box_window), about_box);
+ gtk_widget_show (about_box_window);
}
static void