Provide not only copyright information, but a GPL blurb, in all the
[obnox/wireshark/wip.git] / gtk / about_dlg.c
1 /* about_dlg.c
2  *
3  * $Id$
4  *
5  * Ulf Lamping <ulf.lamping@web.de>
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 2000 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <gtk/gtk.h>
31
32 #include <epan/filesystem.h>
33 #include <epan/plugins.h>
34 #include "about_dlg.h"
35 #include "gui_utils.h"
36 #include "dlg_utils.h"
37 #include "compat_macros.h"
38 #include "globals.h"
39 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
40 #include "text_page.h"
41 #endif
42
43 #include "../image/eicon3d64.xpm"
44 #include "gtkglobals.h"
45 #include "version_info.h"
46 #include "main.h"
47 #include "plugins_dlg.h"
48
49 static void about_ethereal_destroy_cb(GtkWidget *, gpointer);
50
51
52 /*
53  * Keep a static pointer to the current "About Ethereal" window, if any, so
54  * that if somebody tries to do "About Ethereal" while there's already an
55  * "About Ethereal" window up, we just pop up the existing one, rather than
56  * creating a new one.
57  */
58 static GtkWidget *about_ethereal_w;
59
60
61 static void
62 about_ethereal(GtkWidget *parent, GtkWidget *main_vb, const char *title)
63 {
64   GtkWidget   *msg_label, *icon;
65 #if GTK_MAJOR_VERSION >= 2
66   gchar       *message;
67 #endif
68
69   icon = xpm_to_widget_from_parent(parent, eicon3d64_xpm);
70   gtk_container_add(GTK_CONTAINER(main_vb), icon);
71
72   msg_label = gtk_label_new(title);
73 #if GTK_MAJOR_VERSION >= 2
74   message = g_strdup_printf("<span size=\"x-large\" weight=\"bold\">%s</span>", title);
75   gtk_label_set_markup(GTK_LABEL(msg_label), message);
76   g_free(message);
77 #endif
78   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
79 }
80
81
82 GtkWidget *
83 splash_new(char *message)
84 {
85     GtkWidget *win;
86     GtkWidget *main_lb;
87
88     GtkWidget *main_vb;
89
90     win = splash_window_new();
91
92     /* When calling about_ethereal(), we must realize the top-level
93        widget for the window, otherwise GTK will throw a warning
94        because we don't have a colormap associated with that window and
95        can't handle the pixmap. */
96     gtk_widget_realize(win);
97
98     main_vb = gtk_vbox_new(FALSE, 6);
99     gtk_container_border_width(GTK_CONTAINER(main_vb), 24);
100     gtk_container_add(GTK_CONTAINER(win), main_vb);
101
102     about_ethereal(win, main_vb, "Ethereal - Network Protocol Analyzer");
103
104     main_lb = gtk_label_new(message);
105     gtk_container_add(GTK_CONTAINER(main_vb), main_lb);
106     OBJECT_SET_DATA(win, "splash_label", main_lb);
107     
108     gtk_widget_show_all(win);
109
110     splash_update(win, message);
111
112     return win;
113 }
114
115 void
116 splash_update(GtkWidget *win, char *message)
117 {
118     GtkWidget *main_lb;
119
120     if (win == NULL) return;
121
122     main_lb = OBJECT_GET_DATA(win, "splash_label");
123     gtk_label_set_text(GTK_LABEL(main_lb), message);
124
125     /* Process all pending GUI events before continuing, so that
126        the splash screen window gets updated. */
127     while (gtk_events_pending()) gtk_main_iteration();
128 }
129
130 guint
131 splash_destroy(GtkWidget *win)
132 {
133     if (win == NULL) return FALSE;
134
135     gtk_widget_destroy(win);
136     return FALSE;
137 }
138
139
140 static GtkWidget *
141 about_ethereal_page_new(void)
142 {
143   GtkWidget   *main_vb, *msg_label /*, *icon*/;
144   gchar       *message;
145   const char   title[] = "Ethereal - Network Protocol Analyzer";
146
147   main_vb = gtk_vbox_new(FALSE, 6);
148   gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
149
150   about_ethereal(top_level, main_vb, title);
151
152   /* Construct the message string */
153   message = g_strdup_printf(
154        "Version " VERSION "%s\n"
155        "\n"
156        "%s"
157        "\n"
158        "%s"
159        "\n"
160        "%s"
161        "\n"
162        "Ethereal is Open Source Software released under the GNU General Public License.\n"
163        "\n"
164        "Check the man page and http://www.ethereal.com for more information.",
165        svnversion, get_copyright_info(), comp_info_str->str,
166        runtime_info_str->str);
167
168   msg_label = gtk_label_new(message);
169   g_free(message);
170   gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_FILL);
171 #if GTK_MAJOR_VERSION >= 2
172   gtk_label_set_selectable(GTK_LABEL(msg_label), TRUE);
173 #endif
174   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
175
176   return main_vb;
177 }
178
179 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
180 static GtkWidget *
181 about_authors_page_new(void)
182 {
183   GtkWidget   *page;
184   char *absolute_path;
185
186   absolute_path = get_datafile_path("AUTHORS-SHORT");
187   page = text_page_new(absolute_path);
188
189   return page;
190 }
191 #endif
192
193 static void
194 about_folders_row(GtkWidget *table, const char *label, const char *dir, const char *tip)
195 {
196   simple_list_append(table, 0, label, 1, dir, 2, tip, -1);
197 }
198
199
200 static GtkWidget *
201 about_folders_page_new(void)
202 {
203   GtkWidget   *table;
204   const char *constpath;
205   char *path;
206   const gchar *titles[] = { "Name", "Folder", "Typical Files"};
207   GtkWidget *scrolledwindow;
208
209   scrolledwindow = scrolled_window_new(NULL, NULL);
210 #if GTK_MAJOR_VERSION >= 2
211   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), 
212                                    GTK_SHADOW_IN);
213 #endif
214
215   /* Container for our data */
216   table = simple_list_new(3, titles);
217
218   /* "file open" */
219   about_folders_row(table, "\"File\" dialogs", get_last_open_dir(),
220       "capture files");
221
222   /* temp */
223   path = get_tempfile_path("");
224   about_folders_row(table, "Temp", path,
225       "untitled capture files");
226   g_free((void *) path);
227
228   /* pers conf */
229   path = get_persconffile_path("", FALSE);
230   about_folders_row(table, "Personal configuration", path, 
231       "\"dfilters\", \"preferences\", \"ethers\", ...");
232   g_free((void *) path);
233
234   /* global conf */
235   constpath = get_datafile_dir();
236   about_folders_row(table, "Global configuration", constpath,
237       "\"dfilters\", \"preferences\", \"manuf\", ...");
238
239   /* system */
240   constpath = get_systemfile_dir();
241   about_folders_row(table, "System", constpath,
242       "\"ethers\", \"ipxnets\"");
243
244   /* program */
245   path = g_strdup(ethereal_path);
246   path = get_dirname(path);
247   about_folders_row(table, "Program", path,
248       "program files");
249   g_free((void *) path);
250
251 #ifdef HAVE_PLUGINS
252   /* pers plugins */
253   path = get_plugins_pers_dir();
254   about_folders_row(table, "Personal Plugins", path,
255       "dissector plugins");
256   g_free((void *) path);
257
258   /* global plugins */
259   path = get_plugins_global_dir(PLUGIN_DIR);
260   about_folders_row(table, "Global Plugins", path,
261       "dissector plugins");
262   g_free((void *) path);
263 #endif
264
265   gtk_container_add(GTK_CONTAINER(scrolledwindow), table);
266
267   return scrolledwindow;
268 }
269
270
271 void
272 about_ethereal_cb( GtkWidget *w _U_, gpointer data _U_ )
273 {
274   GtkWidget   *main_vb, *main_nb, *bbox, *ok_btn;
275
276   GtkWidget   *page_lb, *about_page, *folders_page, *plugins_page;
277 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
278   GtkWidget   *authors_page;
279 #endif
280
281   if (about_ethereal_w != NULL) {
282     /* There's already an "About Ethereal" dialog box; reactivate it. */
283     reactivate_window(about_ethereal_w);
284     return;
285   }
286
287   /*
288    * XXX - use GtkDialog?  The GNOME 2.x GnomeAbout widget does.
289    * Should we use GtkDialog for simple_dialog() as well?  Or
290    * is the GTK+ 2.x GtkDialog appropriate but the 1.2[.x] one
291    * not?  (The GNOME 1.x GnomeAbout widget uses GnomeDialog.)
292    */
293   about_ethereal_w = dlg_window_new("About Ethereal");
294   /* set the initial position (must be done, before show is called!) */
295   /* default position is not appropriate for the about dialog */
296 #if GTK_MAJOR_VERSION >= 2
297   gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER_ON_PARENT);
298 #else
299   gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER);
300 #endif
301   /* setting the size is dangerous here, as making it too short will 
302    * clip content on GTK1, so simply use the natural size */
303   /*gtk_window_set_default_size(GTK_WINDOW(about_ethereal_w), 600, 400);*/
304   gtk_container_border_width(GTK_CONTAINER(about_ethereal_w), 6);
305
306   main_vb = gtk_vbox_new(FALSE, 12);
307   gtk_container_border_width(GTK_CONTAINER(main_vb), 6);
308   gtk_container_add(GTK_CONTAINER(about_ethereal_w), main_vb);
309
310   main_nb = gtk_notebook_new();
311   gtk_box_pack_start(GTK_BOX(main_vb), main_nb, TRUE, TRUE, 0);
312
313   about_page = about_ethereal_page_new();
314   page_lb = gtk_label_new("Ethereal");
315   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), about_page, page_lb);
316
317 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
318   authors_page = about_authors_page_new();
319   page_lb = gtk_label_new("Authors");
320   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), authors_page, page_lb);
321 #endif
322
323   folders_page = about_folders_page_new();
324   page_lb = gtk_label_new("Folders");
325   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), folders_page, page_lb);
326
327 #ifdef HAVE_PLUGINS
328   plugins_page = about_plugins_page_new();
329   page_lb = gtk_label_new("Plugins");
330   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), plugins_page, page_lb);
331 #endif
332
333   /* Button row */
334   bbox = dlg_button_row_new(GTK_STOCK_OK, NULL);
335   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
336
337   ok_btn = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
338   window_set_cancel_button(about_ethereal_w, ok_btn, window_cancel_button_cb);
339
340   SIGNAL_CONNECT(about_ethereal_w, "delete_event", window_delete_event_cb, NULL);
341   SIGNAL_CONNECT(about_ethereal_w, "destroy", about_ethereal_destroy_cb, NULL);
342
343   gtk_widget_show_all(about_ethereal_w);
344   window_present(about_ethereal_w);
345 }
346
347 static void
348 about_ethereal_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
349 {
350   /* Note that we no longer have an "About Ethereal" dialog box. */
351   about_ethereal_w = NULL;
352 }
353
354