Set the svn:eol-style property on all text files to "native", so that
[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 "ui_util.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 #include "webbrowser.h"
43
44 #include "svnversion.h"
45
46 #include "../image/eicon3d64.xpm"
47 #include "gtkglobals.h"
48
49 extern GString *comp_info_str, *runtime_info_str;
50
51 #ifdef HAVE_PLUGINS
52 extern GtkWidget *about_plugins_page_new(void);
53 #endif
54
55 static void about_ethereal_destroy_cb(GtkWidget *, gpointer);
56
57
58 /*
59  * Keep a static pointer to the current "About Ethereal" window, if any, so
60  * that if somebody tries to do "About Ethereal" while there's already an
61  * "About Ethereal" window up, we just pop up the existing one, rather than
62  * creating a new one.
63  */
64 static GtkWidget *about_ethereal_w;
65
66
67 static void
68 about_ethereal(GtkWidget *parent, GtkWidget *main_vb, const char *title)
69 {
70   GtkWidget   *msg_label, *icon;
71 #if GTK_MAJOR_VERSION >= 2
72   gchar       *message;
73 #endif
74
75   icon = xpm_to_widget_from_parent(parent, eicon3d64_xpm);
76   gtk_container_add(GTK_CONTAINER(main_vb), icon);
77
78   msg_label = gtk_label_new(title);
79 #if GTK_MAJOR_VERSION >= 2
80   message = g_strdup_printf("<span size=\"x-large\" weight=\"bold\">%s</span>", title);
81   gtk_label_set_markup(GTK_LABEL(msg_label), message);
82   g_free(message);
83 #endif
84   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
85 }
86
87
88 GtkWidget *
89 splash_new(char *message)
90 {
91     GtkWidget *win;
92     GtkWidget *main_lb;
93
94     GtkWidget *main_vb;
95
96     win = splash_window_new();
97
98     /* When calling about_ethereal(), we must realize the top-level
99        widget for the window, otherwise GTK will throw a warning
100        because we don't have a colormap associated with that window and
101        can't handle the pixmap. */
102     gtk_widget_realize(win);
103
104     main_vb = gtk_vbox_new(FALSE, 6);
105     gtk_container_border_width(GTK_CONTAINER(main_vb), 24);
106     gtk_container_add(GTK_CONTAINER(win), main_vb);
107
108     about_ethereal(win, main_vb, "Ethereal - Network Protocol Analyzer");
109
110     main_lb = gtk_label_new(message);
111     gtk_container_add(GTK_CONTAINER(main_vb), main_lb);
112     OBJECT_SET_DATA(win, "splash_label", main_lb);
113     
114     gtk_widget_show_all(win);
115
116     splash_update(win, message);
117
118     return win;
119 }
120
121 void
122 splash_update(GtkWidget *win, char *message)
123 {
124     GtkWidget *main_lb;
125
126     if (win == NULL) return;
127
128     main_lb = OBJECT_GET_DATA(win, "splash_label");
129     gtk_label_set_text(GTK_LABEL(main_lb), message);
130
131     /* Process all pending GUI events before continuing, so that
132        the splash screen window gets updated. */
133     while (gtk_events_pending()) gtk_main_iteration();
134 }
135
136 guint
137 splash_destroy(GtkWidget *win)
138 {
139     if (win == NULL) return FALSE;
140
141     gtk_widget_destroy(win);
142     return FALSE;
143 }
144
145
146 static GtkWidget *
147 about_ethereal_page_new(void)
148 {
149   GtkWidget   *main_vb, *msg_label /*, *icon*/;
150   gchar       *message;
151   const char   title[] = "Ethereal - Network Protocol Analyzer";
152
153   main_vb = gtk_vbox_new(FALSE, 6);
154   gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
155
156   about_ethereal(top_level, main_vb, title);
157
158   msg_label = gtk_label_new("Version " VERSION
159 #ifdef SVNVERSION
160            " (" SVNVERSION ")"
161 #endif
162            " (C) 1998-2004 Gerald Combs <gerald@ethereal.com>\n\n");
163   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
164   
165   /* Construct the message string */
166   message = g_strdup_printf(
167        "%s\n\n"
168        "%s\n\n"
169
170        "Ethereal is Open Source Software released under the GNU General Public License.\n\n"
171
172            "Check the man page and http://www.ethereal.com for more information.",
173             comp_info_str->str, runtime_info_str->str);
174
175   msg_label = gtk_label_new(message);
176   g_free(message);
177   gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_FILL);
178   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
179
180   return main_vb;
181 }
182
183 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
184 static GtkWidget *
185 about_authors_page_new(void)
186 {
187   GtkWidget   *page;
188   char *absolute_path;
189
190   absolute_path = get_datafile_path("AUTHORS-SHORT");
191   page = text_page_new(absolute_path);
192
193   return page;
194 }
195 #endif
196
197 static void
198 about_folders_row(GtkWidget *table, const char *label, const char *dir, const char *tip)
199 {
200   simple_list_append(table, 0, label, 1, dir, 2, tip, -1);
201 }
202
203
204 static GtkWidget *
205 about_folders_page_new(void)
206 {
207   GtkWidget   *table;
208   const char *path;
209   gchar *titles[] = { "Name", "Folder", "Typical Files"};
210   GtkWidget *scrolledwindow;
211
212
213   scrolledwindow = scrolled_window_new(NULL, NULL);
214 #if GTK_MAJOR_VERSION >= 2
215   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), 
216                                    GTK_SHADOW_IN);
217 #endif
218
219   /* Container for our data */
220   table = simple_list_new(3, titles);
221
222   /* "file open" */
223   about_folders_row(table, "\"File\" dialogs", get_last_open_dir(),
224       "capture files");
225
226   /* temp */
227   path = get_tempfile_path("");
228   about_folders_row(table, "Temp", path,
229       "untitled capture files");
230   g_free((void *) path);
231
232   /* pers conf */
233   path = get_persconffile_path("", FALSE);
234   about_folders_row(table, "Personal configuration", path, 
235       "\"dfilters\", \"preferences\", \"ethers\", ...");
236   g_free((void *) path);
237
238   /* global conf */
239   path = get_datafile_dir();
240   about_folders_row(table, "Global configuration", path,
241       "\"dfilters\", \"preferences\", \"manuf\", ...");
242   /*g_free(path);*/
243
244   /* system */
245   path = get_systemfile_dir();
246   about_folders_row(table, "System", path,
247       "\"ethers\", \"ipxnets\"");
248   /*g_free(path);*/
249
250   /* program */
251   path = g_strdup(ethereal_path);
252   path = get_dirname((char *) path);
253   about_folders_row(table, "Program", path,
254       "program files");
255   g_free((void *) path);
256
257 #ifdef HAVE_PLUGINS
258   /* pers plugins */
259   path = get_plugins_pers_dir();
260   about_folders_row(table, "Personal Plugins", path,
261       "dissector plugins");
262   g_free((void *) path);
263
264   /* global plugins */
265   path = get_plugins_global_dir(PLUGIN_DIR);
266   about_folders_row(table, "Global Plugins", path,
267       "dissector plugins");
268   g_free((void *) path);
269 #endif
270
271   gtk_container_add(GTK_CONTAINER(scrolledwindow), table);
272
273   return scrolledwindow;
274 }
275
276
277 void
278 about_ethereal_cb( GtkWidget *w _U_, gpointer data _U_ )
279 {
280   GtkWidget   *main_vb, *main_nb, *bbox, *ok_btn;
281
282   GtkWidget   *page_lb, *about_page, *folders_page, *plugins_page;
283 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
284   GtkWidget   *authors_page;
285 #endif
286
287   if (about_ethereal_w != NULL) {
288     /* There's already an "About Ethereal" dialog box; reactivate it. */
289     reactivate_window(about_ethereal_w);
290     return;
291   }
292
293   /*
294    * XXX - use GtkDialog?  The GNOME 2.x GnomeAbout widget does.
295    * Should we use GtkDialog for simple_dialog() as well?  Or
296    * is the GTK+ 2.x GtkDialog appropriate but the 1.2[.x] one
297    * not?  (The GNOME 1.x GnomeAbout widget uses GnomeDialog.)
298    */
299   about_ethereal_w = dlg_window_new("About Ethereal");
300   /* set the initial position (must be done, before show is called!) */
301   /* default position is not appropriate for the about dialog */
302 #if GTK_MAJOR_VERSION >= 2
303   gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER_ON_PARENT);
304 #else
305   gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER);
306 #endif
307   /* setting the size is dangerous here, as making it too short will 
308    * clip content on GTK1, so simply use the natural size */
309   /*gtk_window_set_default_size(GTK_WINDOW(about_ethereal_w), 600, 400);*/
310   gtk_container_border_width(GTK_CONTAINER(about_ethereal_w), 6);
311
312   main_vb = gtk_vbox_new(FALSE, 12);
313   gtk_container_border_width(GTK_CONTAINER(main_vb), 6);
314   gtk_container_add(GTK_CONTAINER(about_ethereal_w), main_vb);
315
316   main_nb = gtk_notebook_new();
317   gtk_box_pack_start(GTK_BOX(main_vb), main_nb, TRUE, TRUE, 0);
318
319   about_page = about_ethereal_page_new();
320   page_lb = gtk_label_new("Ethereal");
321   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), about_page, page_lb);
322
323 #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
324   authors_page = about_authors_page_new();
325   page_lb = gtk_label_new("Authors");
326   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), authors_page, page_lb);
327 #endif
328
329   folders_page = about_folders_page_new();
330   page_lb = gtk_label_new("Folders");
331   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), folders_page, page_lb);
332
333 #ifdef HAVE_PLUGINS
334   plugins_page = about_plugins_page_new();
335   page_lb = gtk_label_new("Plugins");
336   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), plugins_page, page_lb);
337 #endif
338
339   /* Button row */
340   bbox = dlg_button_row_new(GTK_STOCK_OK, NULL);
341   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
342
343   ok_btn = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
344   window_set_cancel_button(about_ethereal_w, ok_btn, window_cancel_button_cb);
345
346   SIGNAL_CONNECT(about_ethereal_w, "delete_event", window_delete_event_cb, NULL);
347   SIGNAL_CONNECT(about_ethereal_w, "destroy", about_ethereal_destroy_cb, NULL);
348
349   gtk_widget_show_all(about_ethereal_w);
350   window_present(about_ethereal_w);
351 }
352
353 static void
354 about_ethereal_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
355 {
356   /* Note that we no longer have an "About Ethereal" dialog box. */
357   about_ethereal_w = NULL;
358 }
359
360
361 void
362 url_onlinepage_cb( GtkWidget *widget _U_, gpointer data _U_, onlinepage_action_e action)
363 {
364     switch(action) {
365     case(ONLINEPAGE_HOME):
366         browser_open_url ("http://www.ethereal.com");
367         break;
368     case(ONLINEPAGE_DOWNLOAD):
369         browser_open_url ("http://www.ethereal.com/download.html");
370         break;
371     case(ONLINEPAGE_USERGUIDE):
372         browser_open_url ("http://www.ethereal.com/docs/user-guide");
373         break;
374     case(ONLINEPAGE_FAQ):
375         browser_open_url ("http://www.ethereal.com/faq.html");
376         break;
377     case(ONLINEPAGE_SAMPLE):
378         browser_open_url ("http://www.ethereal.com/sample");
379         break;
380     default:
381         g_assert_not_reached();
382     }
383 }
384
385 void
386 url_localpage_cb( GtkWidget *w _U_, gpointer data _U_, localpage_action_e action)
387 {
388     switch(action) {
389     case(LOCALPAGE_MAN_ETHEREAL):
390         browser_open_data_file("ethereal.html");
391         break;
392     case(LOCALPAGE_MAN_ETHEREAL_FILTER):
393         browser_open_data_file("ethereal-filter.html");
394         break;
395     case(LOCALPAGE_MAN_TETHEREAL):
396         browser_open_data_file("tethereal.html");
397         break;
398     case(LOCALPAGE_MAN_MERGECAP):
399         browser_open_data_file("mergecap.html");
400         break;
401     case(LOCALPAGE_MAN_EDITCAP):
402         browser_open_data_file("editcap.html");
403         break;
404     case(LOCALPAGE_MAN_TEXT2PCAP):
405         browser_open_data_file("text2pcap.html");
406         break;
407     default:
408         g_assert_not_reached();
409     }
410 }
411