2
GQ -- a GTK-based LDAP client
3
Copyright (C) 1998-2003 Bert Vermeulen
4
Copyright (C) 2002-2003 Peter Stamfest
6
This program is released under the Gnu General Public License with
7
the additional exemption that compiling, linking, and/or using
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
/* $Id: mainwin.c 975 2006-09-07 18:44:41Z herzi $ */
30
#include <glib/gi18n.h>
32
#include <gdk/gdkkeysyms.h>
36
#endif /* HAVE_CONFIG_H */
39
#include "gq-server-list.h"
40
#include "gq-tab-browse.h"
41
#ifdef HAVE_LDAP_STR2OBJECTCLASS
42
# include "gq-tab-schema.h"
44
#include "gq-tab-search.h"
47
#include "configfile.h"
56
#include "errorchain.h"
59
struct mainwin_data mainwin;
61
static void create_about_window(GtkWindow* parent);
63
static void close_current_tab(struct mainwin_data *win);
64
static void mainwin_destroyed(GtkWidget *widget, struct mainwin_data *win);
65
static void switchpage_refocus(GtkNotebook *notebook, GtkNotebookPage *page,
66
int pagenum, struct mainwin_data *win);
68
GqTab *get_last_of_mode(int mode)
70
if(!mainwin.lastofmode)
73
return g_hash_table_lookup(mainwin.lastofmode, GINT_TO_POINTER(mode));
77
void go_to_page(GqTab *tab)
79
gtk_notebook_set_page(GTK_NOTEBOOK(mainwin.mainbook),
80
gtk_notebook_page_num(GTK_NOTEBOOK(mainwin.mainbook),
85
void enter_last_of_mode(GqTab *tab)
88
if(!mainwin.lastofmode)
89
mainwin.lastofmode = g_hash_table_new(g_direct_hash, g_direct_equal);
91
g_hash_table_insert(mainwin.lastofmode, GINT_TO_POINTER(tab->type), tab);
96
append_name(GQServerList* list, GqServer* server, gpointer data) {
97
GList** serverlist = data;
98
*serverlist = g_list_append(*serverlist, server->name);
101
void fill_serverlist_combo(GtkWidget *combo)
103
GList *serverlist = NULL;
109
gq_server_list_foreach(gq_server_list_get(), append_name, &serverlist);
112
/* all servers were deleted -- pass an empty string to the combo */
113
serverlist = g_list_append(serverlist, "");
115
gtk_combo_set_popdown_strings(GTK_COMBO(combo), serverlist);
117
g_list_free(serverlist);
120
static gboolean mainwin_restore_snapshot(struct mainwin_data *win)
124
struct pbar_win *pw = NULL;
126
if (!config->restore_tabs) return FALSE;
127
if (!exists_entity("mainwin.tabs")) return FALSE;
129
pw = create_progress_bar_in_window(_("Restoring last GUI state"));
130
update_progress(pw, _("Restoring tabs"));
132
for (i = 0 ; ; i++) {
133
g_snprintf(tmp, sizeof(tmp), "mainwin.tabs.%d", i);
134
if (!exists_entity(tmp)) break;
135
type = state_value_get_int(tmp, "type", -1);
137
GqTab *tab = new_modetab(win, type);
138
int error_ctx = error_new_context("", pw->win);
140
if (GQ_TAB_GET_CLASS(tab)->restore_snapshot) {
141
GQ_TAB_GET_CLASS(tab)->restore_snapshot(error_ctx, tmp, tab, pw);
144
error_flush(error_ctx);
146
update_progress(pw, NULL);
147
if (pw->cancelled) break;
151
type = state_value_get_int("mainwin.tabs", "active", -1);
152
gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), type);
155
update_progress(pw, _("Restoring tabs"));
161
static void mainwin_save_snapshot(struct mainwin_data *win)
167
rm_value("mainwin.tabs");
169
if (!config->restore_tabs) return;
171
for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
172
g_snprintf(tmp, sizeof(tmp), "mainwin.tabs.%d", i);
173
state_value_set_int(tmp, "type", tab->type);
174
if (GQ_TAB_GET_CLASS(tab)->save_snapshot) {
176
error_new_context(_("Saving main window snapshot"), NULL);
177
GQ_TAB_GET_CLASS(tab)->save_snapshot(error_ctx, tmp, tab);
178
error_flush(error_ctx);
182
state_value_set_int("mainwin.tabs", "active",
183
gtk_notebook_get_current_page(GTK_NOTEBOOK(win->mainbook)));
187
/* gtk2 checked (multiple destroy callbacks safety), confidence 0.7:
188
cleanup_all_tabs semantics? */
189
static void mainwin_destroyed(GtkWidget *widget, struct mainwin_data *win)
191
mainwin_save_snapshot(win);
196
void cleanup(struct mainwin_data *win)
198
cleanup_all_tabs(win);
201
static gboolean ctrl_b_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
203
if(event && event->type == GDK_KEY_PRESS &&
204
event->state & GDK_CONTROL_MASK && event->keyval == GDK_b) {
205
g_signal_emit_by_name(obj, "activate");
206
g_signal_stop_emission_by_name(widget, "key_press_event");
214
static gboolean ctrl_w_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
216
if(event && event->type == GDK_KEY_PRESS &&
217
event->state & GDK_CONTROL_MASK && event->keyval == GDK_w) {
218
g_signal_emit_by_name(obj, "activate");
219
g_signal_stop_emission_by_name(widget, "key_press_event");
226
static void new_modetab_search(struct mainwin_data *win)
228
new_modetab(win, SEARCH_MODE);
231
static void new_modetab_browse(struct mainwin_data *win)
233
new_modetab(win, BROWSE_MODE);
236
static void new_modetab_schema(struct mainwin_data *win)
238
new_modetab(win, SCHEMA_MODE);
242
static GList *log_list = NULL;
243
static int log_list_len = 0;
245
void clear_message_history()
248
g_list_foreach(log_list, (GFunc) g_free, NULL);
249
g_list_free(log_list);
253
if (mainwin.ml_text) {
257
gtk_text_buffer_get_start_iter(mainwin.ml_buffer, &start);
258
gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &end);
260
gtk_text_buffer_delete(mainwin.ml_buffer, &start, &end);
265
void message_log_append(const char *buf)
267
log_list = g_list_append(log_list, g_strdup(buf));
270
if (mainwin.ml_text) {
272
gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &iter);
273
gtk_text_buffer_insert(mainwin.ml_buffer, &iter,
275
gtk_text_buffer_insert(mainwin.ml_buffer, &iter, "\n", 1);
277
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(mainwin.ml_text),
278
gtk_text_buffer_create_mark(mainwin.ml_buffer,
286
while (log_list_len > MESSAGE_LOG_MAX) {
287
g_free(log_list->data);
288
log_list = g_list_remove(log_list, log_list->data);
293
static void message_log_destroyed(GtkWidget *window,
294
struct mainwin_data *win)
296
win->ml_window = NULL;
298
win->ml_buffer = NULL;
301
static void clear_clicked(void)
303
clear_message_history();
306
static void message_log(struct mainwin_data *win)
308
GtkWidget *window, *vbox0, *scrwin, *text, *bbox, *button;
309
GtkTextBuffer *buffer;
315
if (win->ml_window) {
316
gdk_beep(); /* Is this OK, philosophically? */
317
gtk_window_present(GTK_WINDOW(win->ml_window));
321
window = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
322
"statusbar-log", 500, 350);
323
win->ml_window = window;
325
gtk_widget_realize(window);
327
g_signal_connect(window, "destroy",
328
G_CALLBACK(message_log_destroyed), win);
330
g_signal_connect(window, "key_press_event",
331
G_CALLBACK(close_on_esc),
334
/* current_search_options_window = window; */
335
gtk_window_set_title(GTK_WINDOW(window), _("Message Log"));
336
gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
338
vbox0 = gtk_vbox_new(FALSE, 0);
339
gtk_container_border_width(GTK_CONTAINER(vbox0),
340
CONTAINER_BORDER_WIDTH);
341
gtk_widget_show(vbox0);
342
gtk_container_add(GTK_CONTAINER(window), vbox0);
344
/* scrolled window to hold the log */
345
scrwin = gtk_scrolled_window_new(NULL, NULL);
346
gtk_widget_show(scrwin);
347
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
348
GTK_POLICY_AUTOMATIC,
349
GTK_POLICY_AUTOMATIC);
350
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwin),
352
gtk_box_pack_start(GTK_BOX(vbox0), scrwin, TRUE, TRUE, 0);
354
text = gtk_text_view_new();
355
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
356
win->ml_buffer = buffer;
358
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
359
gtk_text_buffer_get_end_iter(buffer, &iter);
363
gtk_widget_show(text);
364
gtk_container_add(GTK_CONTAINER(scrwin), text);
366
for (I = log_list ; I ; I = g_list_next(I) ) {
367
gtk_text_buffer_insert(buffer, &iter,
368
I->data, strlen(I->data));
369
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
372
gtk_text_buffer_get_end_iter(buffer, &iter);
373
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text),
374
gtk_text_buffer_create_mark(buffer, NULL,
380
bbox = gtk_hbutton_box_new();
381
gtk_widget_show(bbox);
383
gtk_box_pack_end(GTK_BOX(vbox0), bbox, FALSE, FALSE, 3);
385
button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
386
gtk_widget_show(button);
387
g_signal_connect(button, "clicked",
388
G_CALLBACK(clear_clicked),
390
gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, TRUE, 10);
392
button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
393
gtk_widget_show(button);
394
g_signal_connect_swapped(button, "clicked",
395
G_CALLBACK(gtk_widget_destroy),
397
gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, TRUE, 10);
399
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
400
gtk_widget_grab_default(button);
402
gtk_widget_show(window);
405
/* Callback function called when a tab gets removed from the
407
static void remove_tab(GtkContainer *notebook,
409
struct mainwin_data *win)
415
tab = gtk_object_get_data(GTK_OBJECT(content), "tab");
417
thismode = tab->type;
418
g_hash_table_insert(win->lastofmode, GINT_TO_POINTER(thismode), NULL);
420
/* try to find another tab with the same mode so we can put that
421
one into lastofmode... */
422
for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
423
if (tab->type == thismode) {
425
enter_last_of_mode(tab);
431
if (gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), 0) == NULL) {
432
gtk_widget_destroy(win->mainwin);
437
void mainwin_update_filter_menu(struct mainwin_data *win)
439
GList *menuitems = gtk_container_children(GTK_CONTAINER(win->filtermenu));
442
/* Filters | list of filters */
445
for ( I = g_list_first(menuitems) ; I ; I = g_list_next(I) ) {
446
GtkWidget *item = GTK_WIDGET(I->data);
447
gpointer data = gtk_object_get_data(GTK_OBJECT(item), "filter");
450
gtk_widget_destroy(item);
454
g_list_free(menuitems);
457
for ( I = g_list_first(config->filters) ; I ; I = g_list_next(I) ) {
458
struct gq_filter *filter;
461
filter = (struct gq_filter *) I->data;
462
menuitem = gtk_menu_item_new_with_label(filter->name);
464
gtk_object_set_data(GTK_OBJECT(menuitem), "filter", filter);
465
g_signal_connect_swapped(menuitem, "activate",
466
G_CALLBACK(filter_selected),
469
gtk_container_add(GTK_CONTAINER(win->filtermenu), menuitem);
470
gtk_widget_show(menuitem);
475
void create_mainwin(struct mainwin_data *win)
477
GtkWidget *outer_vbox, *main_vbox, *menubar, *menuitem, *submenu;
478
GtkWidget *File, *menuFile, *New, *Close, *ShowM, *Quit;
479
GtkWidget *Search, *Browse, *Schema;
480
GtkWidget *menuHelp, *Help, *About;
481
GtkWidget *Filters, *menuFilters;
482
GtkWidget *handlebox;
483
GtkAccelGroup *accel_group;
485
g_assert(win != NULL);
487
win->mainwin = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
488
"mainwin", 770, 478);
490
gtk_container_border_width(GTK_CONTAINER(win->mainwin), 0);
491
g_signal_connect(win->mainwin, "destroy",
492
G_CALLBACK(mainwin_destroyed),
494
gtk_window_set_title(GTK_WINDOW(win->mainwin), _("GQ"));
495
gtk_window_set_policy(GTK_WINDOW(win->mainwin), FALSE, TRUE, FALSE);
499
outer_vbox = gtk_vbox_new(FALSE, 2);
500
gtk_container_border_width(GTK_CONTAINER(outer_vbox), 0);
501
gtk_widget_show(outer_vbox);
502
gtk_container_add(GTK_CONTAINER(win->mainwin), outer_vbox);
504
accel_group = gtk_accel_group_new();
506
gtk_window_add_accel_group(GTK_WINDOW(win->mainwin), accel_group);
508
handlebox = gtk_handle_box_new();
509
gtk_widget_show(handlebox);
510
gtk_box_pack_start(GTK_BOX(outer_vbox), handlebox, FALSE, TRUE, 0);
512
menubar = gtk_menu_bar_new();
513
gtk_widget_show(menubar);
514
gtk_container_add(GTK_CONTAINER(handlebox), menubar);
517
File = gq_menu_item_new_with_label(_("_File"));
518
gtk_widget_show(File);
519
gtk_container_add(GTK_CONTAINER(menubar), File);
521
menuFile = gtk_menu_new();
522
gtk_menu_item_set_submenu(GTK_MENU_ITEM(File), menuFile);
525
New = gq_menu_item_new_with_label(_("_New tab"));
526
gtk_widget_show(New);
527
gtk_container_add(GTK_CONTAINER(menuFile), New);
528
submenu = gtk_menu_new();
529
gtk_menu_item_set_submenu(GTK_MENU_ITEM(New), submenu);
531
/* File | New | Search */
532
Search = gq_menu_item_new_with_label(_("_Search"));
533
gtk_widget_show(Search);
534
gtk_menu_append(GTK_MENU(submenu), Search);
535
g_signal_connect_swapped(Search, "activate",
536
G_CALLBACK(new_modetab_search),
538
gtk_widget_add_accelerator(Search, "activate", accel_group, 'S',
539
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
541
/* File | New | Browse */
542
Browse = gq_menu_item_new_with_label(_("_Browse"));
543
gtk_widget_show(Browse);
544
gtk_menu_append(GTK_MENU(submenu), Browse);
545
g_signal_connect_swapped(Browse, "activate",
546
G_CALLBACK(new_modetab_browse),
548
gtk_widget_add_accelerator(Browse, "activate", accel_group, 'B',
549
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
550
/* ctrl-b is used by text widgets, so the searchterm textbox that
551
always has focus in search mode blocks the above accelerator...*/
552
g_signal_connect(win->mainwin, "key_press_event",
553
G_CALLBACK(ctrl_b_hack),
556
/* File | New | Schema */
557
Schema = gq_menu_item_new_with_label(_("S_chema"));
558
gtk_widget_show(Schema);
559
gtk_menu_append(GTK_MENU(submenu), Schema);
560
gtk_widget_add_accelerator(Schema, "activate", accel_group, 'Z',
561
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
562
#ifdef HAVE_LDAP_STR2OBJECTCLASS
563
g_signal_connect_swapped(Schema, "activate",
564
G_CALLBACK(new_modetab_schema),
567
gtk_widget_set_sensitive(Schema, FALSE);
570
/* File | Preferences */
571
menuitem = gq_menu_item_new_with_label(_("_Preferences"));
572
gtk_widget_show(menuitem);
573
gtk_container_add(GTK_CONTAINER(menuFile), menuitem);
574
g_signal_connect_swapped(menuitem, "activate",
575
G_CALLBACK(create_prefs_window),
577
gtk_widget_add_accelerator(menuitem, "activate", accel_group, 'P',
578
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
581
Close = gq_menu_item_new_with_label(_("_Close tab"));
582
gtk_widget_show(Close);
583
gtk_container_add(GTK_CONTAINER(menuFile), Close);
584
g_signal_connect_swapped(Close, "activate",
585
G_CALLBACK(close_current_tab),
587
gtk_widget_add_accelerator(Close, "activate", accel_group, 'W',
588
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
590
g_signal_connect(win->mainwin, "key_press_event",
591
G_CALLBACK(ctrl_w_hack),
594
/* File | Show Message */
596
ShowM = gq_menu_item_new_with_label(_("Show _Message Log"));
597
gtk_widget_show(ShowM);
598
gtk_container_add(GTK_CONTAINER(menuFile), ShowM);
599
g_signal_connect_swapped(ShowM, "activate",
600
G_CALLBACK(message_log),
604
Quit = gq_menu_item_new_with_label(_("_Quit"));
605
gtk_widget_show(Quit);
606
gtk_container_add(GTK_CONTAINER(menuFile), Quit);
607
g_signal_connect_swapped(Quit, "activate",
608
G_CALLBACK(gtk_widget_destroy),
610
gtk_widget_add_accelerator(Quit, "activate", accel_group, 'Q',
611
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
615
Filters = gq_menu_item_new_with_label(_("F_ilters"));
616
gtk_widget_show(Filters);
617
gtk_container_add(GTK_CONTAINER(menubar), Filters);
619
menuFilters = gtk_menu_new();
620
gtk_menu_item_set_submenu(GTK_MENU_ITEM(Filters), menuFilters);
621
win->filtermenu = menuFilters;
624
New = gq_menu_item_new_with_label(_("_New filter"));
625
gtk_widget_show(New);
626
gtk_container_add(GTK_CONTAINER(menuFilters), New);
627
submenu = gtk_menu_new();
628
gtk_menu_item_set_submenu(GTK_MENU_ITEM(New), submenu);
630
/* Filters | New | From Search tab */
631
menuitem = gq_menu_item_new_with_label(_("From _Search tab"));
632
gtk_widget_show(menuitem);
633
gtk_menu_append(GTK_MENU(submenu), menuitem);
634
g_signal_connect_swapped(menuitem, "activate",
635
G_CALLBACK(add_filter),
638
/* Filters | New | Filter Editor */
639
menuitem = gq_menu_item_new_with_label(_("Filter _editor"));
640
gtk_widget_show(menuitem);
641
gtk_menu_append(GTK_MENU(submenu), menuitem);
642
g_signal_connect_swapped(menuitem, "activate",
643
G_CALLBACK(add_new_filter_callback),
646
/* Filters | Edit Filters */
647
menuitem = gq_menu_item_new_with_label(_("_Edit Filters"));
648
gtk_widget_show(menuitem);
649
gtk_container_add(GTK_CONTAINER(menuFilters), menuitem);
650
g_signal_connect_swapped(menuitem, "activate",
651
G_CALLBACK(show_filters),
654
/* Filters separator */
655
menuitem = gtk_menu_item_new();
656
gtk_widget_show(menuitem);
657
gtk_container_add(GTK_CONTAINER(menuFilters), menuitem);
659
mainwin_update_filter_menu(win);
662
Help = gq_menu_item_new_with_label(_("_Help"));
663
gtk_widget_show(Help);
664
gtk_container_add(GTK_CONTAINER(menubar), Help);
666
menuHelp = gtk_menu_new();
667
gtk_menu_item_set_submenu(GTK_MENU_ITEM(Help), menuHelp);
670
About = gq_menu_item_new_with_label(_("_About"));
671
gtk_widget_show(About);
672
gtk_container_add(GTK_CONTAINER(menuHelp), About);
673
g_signal_connect_swapped(About, "activate",
674
G_CALLBACK(create_about_window), win->mainwin);
676
main_vbox = gtk_vbox_new(FALSE, 2);
677
gtk_container_border_width(GTK_CONTAINER(main_vbox), 4);
678
gtk_widget_show(main_vbox);
679
gtk_box_pack_start(GTK_BOX(outer_vbox), main_vbox, TRUE, TRUE, 1);
681
win->mainbook = gtk_notebook_new();
682
gtk_widget_show(win->mainbook);
683
/* GTK_WIDGET_UNSET_FLAGS(GTK_NOTEBOOK(mainbook), GTK_CAN_FOCUS); */
684
gtk_box_pack_start(GTK_BOX(main_vbox), win->mainbook, TRUE, TRUE, 0);
686
win->statusbar = gtk_statusbar_new();
687
gtk_widget_show(win->statusbar);
689
gtk_box_pack_end(GTK_BOX(outer_vbox), win->statusbar, FALSE, FALSE, 0);
690
gtk_widget_set_sensitive(win->statusbar, TRUE);
692
g_signal_connect(win->mainbook, "switch-page",
693
G_CALLBACK(switchpage_refocus), win);
694
g_signal_connect(win->mainbook, "remove",
695
G_CALLBACK(remove_tab), win);
697
gtk_widget_realize(win->mainwin);
699
if (! mainwin_restore_snapshot(win)) {
700
new_modetab(win, SEARCH_MODE);
701
new_modetab(win, BROWSE_MODE | 32768);
702
new_modetab(win, SCHEMA_MODE | 32768);
705
gtk_widget_show(win->mainwin);
708
GqTab *mainwin_get_tab_nth(struct mainwin_data *win, int n)
711
gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->mainbook), n);
712
if (content == NULL) return NULL;
714
return gtk_object_get_data(GTK_OBJECT(content), "tab");
717
GqTab *mainwin_get_current_tab(GtkWidget *notebook)
719
int tabnum = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
720
GtkWidget *content = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
722
return gtk_object_get_data(GTK_OBJECT(content), "tab");
725
GqTab *new_modetab(struct mainwin_data *win, int mode)
727
GtkWidget *label, *focusbox;
732
focus = !(mode & 32768);
737
label = gq_label_new(_("_Search"));
738
tab = new_searchmode();
741
label = gq_label_new(_("_Browse"));
742
tab = new_browsemode();
744
#ifdef HAVE_LDAP_STR2OBJECTCLASS
746
label = gq_label_new(_("S_chema"));
747
tab = new_schemamode();
754
gtk_object_set_data(GTK_OBJECT(tab->content), "tab", tab);
758
gtk_widget_show(label);
759
gtk_notebook_append_page(GTK_NOTEBOOK(win->mainbook),
764
enter_last_of_mode(tab);
766
gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), -1);
768
focusbox = tab->focus;
770
gtk_widget_grab_focus(focusbox);
776
static void switchpage_refocus(GtkNotebook *notebook, GtkNotebookPage *page,
777
int pagenum, struct mainwin_data *win)
782
tab = mainwin_get_tab_nth(win, pagenum);
786
/* retrieve mode, store this pane as the last one used for this mode */
787
enter_last_of_mode(tab);
789
focusbox = tab->focus;
791
gtk_widget_grab_focus(focusbox);
792
gtk_editable_select_region(GTK_EDITABLE(focusbox), 0, -1);
797
void cleanup_all_tabs(struct mainwin_data *win)
799
/* don't waste time refocusing on disappearing tabs */
800
g_signal_handlers_disconnect_by_func(win->mainbook,
801
G_CALLBACK(switchpage_refocus), win);
805
static void close_current_tab(struct mainwin_data *win)
810
tabnum = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->mainbook));
811
content = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->mainbook), tabnum);
812
/* for whatever reason: gtk_notebook_remove_page does not call
813
the remove signal on the notebook. I consider this to be a GTK
816
/* gtk_notebook_remove_page(GTK_NOTEBOOK(win->mainbook), tabnum); */
818
gtk_widget_destroy(content);
821
void update_serverlist(struct mainwin_data *win)
826
for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
829
fill_serverlist_combo(GQ_TAB_SEARCH(tab)->serverlist_combo);
832
update_browse_serverlist(tab);
835
update_schema_serverlist(tab);
842
create_about_window(GtkWindow* parent) {
843
static gchar const* authors[] = {
847
"Sven Herzberg (current maintainer)",
850
GdkPixbuf* logo = gdk_pixbuf_new_from_file(PACKAGE_PREFIX "/share/pixmaps/gq/gq.xpm", NULL);
851
gtk_show_about_dialog(parent,
854
"comments", _("The gentleman's LDAP client"),
855
"copyright", _("Copyright (C) 1998-2003 Bert Vermeulen\n"
856
"Copyright (C) 2002-2003 Peter Stamfest\n"
857
"Copyright (C) 2006 Sven Herzberg"),
861
"name", _("GQ LDAP Client"),
862
"translator-credits", _("translator-credits"),
864
"website", "http://www.gq-project.org/",
865
"website-label", _("GQ Website"),
868
g_object_unref(logo);