1
/* This file is part of GQ
4
* Sven Herzberg <herzi@gnome-de.org>
6
* Copyright (C) 1998-2003 Bert Vermeulen
7
* Copyright (C) 2002-2003 Peter Stamfest
8
* Copyright (C) 2006 Sven Herzberg
10
* This program is released under the Gnu General Public License with
11
* the additional exemption that compiling, linking, and/or using
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as
16
* published by the Free Software Foundation; either version 2 of the
17
* License, or (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30
#include "gq-window.h"
35
#include <glib/gi18n.h>
37
#include <gdk/gdkkeysyms.h>
41
#endif /* HAVE_CONFIG_H */
44
#include "gq-server-list.h"
45
#include "gq-tab-browse.h"
46
#ifdef HAVE_LDAP_STR2OBJECTCLASS
47
# include "gq-tab-schema.h"
49
#include "gq-tab-search.h"
51
#include "configfile.h"
54
#include "errorchain.h"
56
#include "gq-diff-tab.h"
57
#include "gq-input-form.h"
58
#include "gq-utilities.h"
66
static void create_about_window(GtkWindow* parent);
68
static void close_current_tab(GqWindow *win);
69
static void mainwin_destroyed(GqWindow *win);
70
static void switchpage_refocus(GtkNotebook *notebook, GtkNotebookPage *page,
71
int pagenum, GqWindow *win);
74
gq_window_get_last_tab(GqWindow const* self,
78
g_return_val_if_fail(GQ_IS_WINDOW(self), NULL);
79
g_return_val_if_fail(self->tab_history, NULL);
81
n = gq_stack_get_n_elements(self->tab_history);
82
for(i = 0; i < n; i++) {
83
GqTab* tab = gq_stack_get_element(self->tab_history, i);
84
if(G_TYPE_CHECK_INSTANCE_TYPE(tab, type)) {
93
void go_to_page(GqTab *tab)
95
gtk_notebook_set_page(GTK_NOTEBOOK(mainwin.mainbook),
96
gtk_notebook_page_num(GTK_NOTEBOOK(mainwin.mainbook),
102
enter_last_of_mode(GqTab *tab)
104
g_return_if_fail(mainwin.tab_history);
106
gq_stack_raise(mainwin.tab_history, tab);
110
mainwin_restore_snapshot(GqWindow *win)
112
struct pbar_win *pw = NULL;
114
gboolean created = FALSE;
118
/* Initialize Tab types */
124
if (!config->restore_tabs) return FALSE;
125
if (!exists_entity("mainwin.tabs")) return FALSE;
127
pw = create_progress_bar_in_window(_("Restoring last GUI state"));
128
update_progress(pw, _("Restoring tabs"));
130
for (i = 0 ; ; i++) {
131
g_snprintf(tmp, sizeof(tmp), "mainwin.tabs.%d", i);
132
if (!exists_entity(tmp)) break;
133
type = state_value_get_type(tmp, "type", G_TYPE_INVALID);
134
if (type == G_TYPE_INVALID) {
135
gint old_type = state_value_get_int(tmp, "type", 0);
144
type = wrapper[old_type];
148
if(g_type_is_a(type, GQ_TYPE_TAB)) {
149
GqTab *tab = new_modetab(win, type, TRUE);
150
int error_ctx = error_new_context("", pw->win);
152
if (GQ_TAB_GET_CLASS(tab)->restore_snapshot) {
153
GQ_TAB_GET_CLASS(tab)->restore_snapshot(error_ctx, tmp, tab, pw);
156
error_flush(error_ctx);
160
update_progress(pw, NULL);
161
if (pw->cancelled) break;
165
type = state_value_get_int("mainwin.tabs", "active", -1);
166
gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), type);
169
update_progress(pw, _("Restoring tabs"));
172
return i > 0 && created;
176
mainwin_save_snapshot(GqWindow *win)
182
rm_value("mainwin.tabs");
184
if (!config->restore_tabs) return;
186
for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
187
g_snprintf(tmp, sizeof(tmp), "mainwin.tabs.%d", i);
188
state_value_set_type(tmp, "type", G_OBJECT_TYPE(tab));
189
if (GQ_TAB_GET_CLASS(tab)->save_snapshot) {
191
error_new_context(_("Saving main window snapshot"), NULL);
192
GQ_TAB_GET_CLASS(tab)->save_snapshot(error_ctx, tmp, tab);
193
error_flush(error_ctx);
197
state_value_set_int("mainwin.tabs", "active",
198
gtk_notebook_get_current_page(GTK_NOTEBOOK(win->mainbook)));
202
/* gtk2 checked (multiple destroy callbacks safety), confidence 0.7:
203
cleanup_all_tabs semantics? */
205
mainwin_destroyed(GqWindow *win)
207
mainwin_save_snapshot(win);
212
void cleanup(GqWindow *win)
214
cleanup_all_tabs(win);
217
static gboolean ctrl_b_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
219
if(event && event->type == GDK_KEY_PRESS &&
220
event->state & GDK_CONTROL_MASK && event->keyval == GDK_b) {
221
g_signal_emit_by_name(obj, "activate");
222
g_signal_stop_emission_by_name(widget, "key_press_event");
230
static gboolean ctrl_w_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
232
if(event && event->type == GDK_KEY_PRESS &&
233
event->state & GDK_CONTROL_MASK && event->keyval == GDK_w) {
234
g_signal_emit_by_name(obj, "activate");
235
g_signal_stop_emission_by_name(widget, "key_press_event");
242
static void new_modetab_search(GqWindow *win)
244
new_modetab(win, GQ_TYPE_TAB_SEARCH, TRUE);
247
static void new_modetab_browse(GqWindow *win)
249
new_modetab(win, GQ_TYPE_TAB_BROWSE, TRUE);
252
static void new_modetab_schema(GqWindow *win)
254
new_modetab(win, GQ_TYPE_TAB_SCHEMA, TRUE);
258
static GList *log_list = NULL;
259
static int log_list_len = 0;
262
clear_message_history(void)
265
g_list_foreach(log_list, (GFunc) g_free, NULL);
266
g_list_free(log_list);
270
if (mainwin.ml_text) {
274
gtk_text_buffer_get_start_iter(mainwin.ml_buffer, &start);
275
gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &end);
277
gtk_text_buffer_delete(mainwin.ml_buffer, &start, &end);
282
void message_log_append(const char *buf)
284
log_list = g_list_append(log_list, g_strdup(buf));
287
if (mainwin.ml_text) {
289
gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &iter);
290
gtk_text_buffer_insert(mainwin.ml_buffer, &iter,
292
gtk_text_buffer_insert(mainwin.ml_buffer, &iter, "\n", 1);
294
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(mainwin.ml_text),
295
gtk_text_buffer_create_mark(mainwin.ml_buffer,
303
while (log_list_len > MESSAGE_LOG_MAX) {
304
g_free(log_list->data);
305
log_list = g_list_remove(log_list, log_list->data);
311
message_log_destroyed(GqWindow *win)
313
win->ml_window = NULL;
315
win->ml_buffer = NULL;
318
static void clear_clicked(void)
320
clear_message_history();
323
static void message_log(GqWindow *win)
325
GtkWidget *window, *vbox0, *scrwin, *text, *bbox, *button;
326
GtkTextBuffer *buffer;
332
if (win->ml_window) {
333
gtk_window_present(GTK_WINDOW(win->ml_window));
337
window = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
338
"statusbar-log", 500, 350);
339
win->ml_window = window;
341
gtk_widget_realize(window);
343
g_signal_connect_swapped(window, "destroy",
344
G_CALLBACK(message_log_destroyed), win);
346
g_signal_connect(window, "key_press_event",
347
G_CALLBACK(close_on_esc),
350
/* current_search_options_window = window; */
351
gtk_window_set_title(GTK_WINDOW(window), _("Message Log"));
352
gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
354
vbox0 = gtk_vbox_new(FALSE, 0);
355
gtk_container_border_width(GTK_CONTAINER(vbox0),
356
CONTAINER_BORDER_WIDTH);
357
gtk_widget_show(vbox0);
358
gtk_container_add(GTK_CONTAINER(window), vbox0);
360
/* scrolled window to hold the log */
361
scrwin = gtk_scrolled_window_new(NULL, NULL);
362
gtk_widget_show(scrwin);
363
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
364
GTK_POLICY_AUTOMATIC,
365
GTK_POLICY_AUTOMATIC);
366
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwin),
368
gtk_box_pack_start(GTK_BOX(vbox0), scrwin, TRUE, TRUE, 0);
370
text = gtk_text_view_new();
371
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
372
win->ml_buffer = buffer;
374
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
375
gtk_text_buffer_get_end_iter(buffer, &iter);
379
gtk_widget_show(text);
380
gtk_container_add(GTK_CONTAINER(scrwin), text);
382
for (I = log_list ; I ; I = g_list_next(I) ) {
383
gtk_text_buffer_insert(buffer, &iter,
384
I->data, strlen(I->data));
385
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
388
gtk_text_buffer_get_end_iter(buffer, &iter);
389
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text),
390
gtk_text_buffer_create_mark(buffer, NULL,
396
bbox = gtk_hbutton_box_new();
397
gtk_widget_show(bbox);
399
gtk_box_pack_end(GTK_BOX(vbox0), bbox, FALSE, FALSE, 3);
401
button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
402
gtk_widget_show(button);
403
g_signal_connect_swapped(button, "clicked",
404
G_CALLBACK(gtk_widget_destroy),
406
gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, TRUE, 10);
408
button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
409
gtk_widget_show(button);
410
g_signal_connect(button, "clicked",
411
G_CALLBACK(clear_clicked),
413
gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, TRUE, 10);
415
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
416
gtk_widget_grab_default(button);
418
gtk_widget_show(window);
421
/* Callback function called when a tab gets removed from the
423
static void remove_tab(GtkContainer *notebook,
427
GqTab *old_tab = NULL;
430
old_tab = gtk_object_get_data(GTK_OBJECT(content), "tab");
433
gq_stack_remove(win->tab_history, old_tab);
435
#warning "FIXME: just grab this one from the history"
436
/* try to find another tab with the same mode so we can put that
437
one into lastofmode... */
438
for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
439
if (G_OBJECT_TYPE(tab) == G_OBJECT_TYPE(old_tab)) {
441
enter_last_of_mode(tab);
447
if (gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), 0) == NULL) {
448
gtk_widget_destroy(win->mainwin);
453
void mainwin_update_filter_menu(GqWindow *win)
455
GList *menuitems = gtk_container_children(GTK_CONTAINER(win->filtermenu));
458
/* Filters | list of filters */
461
for ( I = g_list_first(menuitems) ; I ; I = g_list_next(I) ) {
462
GtkWidget *item = GTK_WIDGET(I->data);
463
gpointer data = gtk_object_get_data(GTK_OBJECT(item), "filter");
466
gtk_widget_destroy(item);
470
g_list_free(menuitems);
473
for ( I = g_list_first(config->filters) ; I ; I = g_list_next(I) ) {
474
struct gq_filter *filter;
477
filter = (struct gq_filter *) I->data;
478
menuitem = gtk_menu_item_new_with_label(filter->name);
480
gtk_object_set_data(GTK_OBJECT(menuitem), "filter", filter);
481
g_signal_connect_swapped(menuitem, "activate",
482
G_CALLBACK(filter_selected),
485
gtk_container_add(GTK_CONTAINER(win->filtermenu), menuitem);
486
gtk_widget_show(menuitem);
491
window_help_manual(GqWindow* window)
493
GError* error = NULL;
494
gdk_spawn_command_line_on_screen(gtk_widget_get_screen(window->mainwin),
495
"yelp ghelp:gq-manual", &error);
497
// FIXME: show a nice error dialog
498
g_warning(_("Couldn't open help document: %s"), error->message);
503
void create_mainwin(GqWindow *win)
505
GtkWidget *outer_vbox, *main_vbox, *menubar, *menuitem, *submenu;
506
GtkWidget *File, *menuFile, *New, *Close, *ShowM, *Quit;
507
GtkWidget *Search, *Browse, *Schema;
508
GtkWidget *menuHelp, *Help, *About;
509
GtkWidget *Filters, *menuFilters;
510
GtkWidget *handlebox;
511
GtkAccelGroup *accel_group;
513
g_assert(win != NULL);
515
win->tab_history = gq_stack_new();
516
win->mainwin = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
517
"mainwin", 770, 478);
519
gtk_container_border_width(GTK_CONTAINER(win->mainwin), 0);
520
g_signal_connect_swapped(win->mainwin, "destroy",
521
G_CALLBACK(mainwin_destroyed), win);
522
gtk_window_set_title(GTK_WINDOW(win->mainwin), _("GQ"));
523
gtk_window_set_policy(GTK_WINDOW(win->mainwin), FALSE, TRUE, FALSE);
527
outer_vbox = gtk_vbox_new(FALSE, 2);
528
gtk_container_border_width(GTK_CONTAINER(outer_vbox), 0);
529
gtk_widget_show(outer_vbox);
530
gtk_container_add(GTK_CONTAINER(win->mainwin), outer_vbox);
532
accel_group = gtk_accel_group_new();
534
gtk_window_add_accel_group(GTK_WINDOW(win->mainwin), accel_group);
536
handlebox = gtk_handle_box_new();
537
gtk_widget_show(handlebox);
538
gtk_box_pack_start(GTK_BOX(outer_vbox), handlebox, FALSE, TRUE, 0);
540
menubar = gtk_menu_bar_new();
541
gtk_widget_show(menubar);
542
gtk_container_add(GTK_CONTAINER(handlebox), menubar);
545
File = gq_menu_item_new_with_label(_("_File"));
546
gtk_widget_show(File);
547
gtk_container_add(GTK_CONTAINER(menubar), File);
549
menuFile = gtk_menu_new();
550
gtk_menu_item_set_submenu(GTK_MENU_ITEM(File), menuFile);
553
New = gq_menu_item_new_with_label(_("_New tab"));
554
gtk_widget_show(New);
555
gtk_container_add(GTK_CONTAINER(menuFile), New);
556
submenu = gtk_menu_new();
557
gtk_menu_item_set_submenu(GTK_MENU_ITEM(New), submenu);
559
/* File | New | Search */
560
Search = gq_menu_item_new_with_label(_("_Search"));
561
gtk_widget_show(Search);
562
gtk_menu_append(GTK_MENU(submenu), Search);
563
g_signal_connect_swapped(Search, "activate",
564
G_CALLBACK(new_modetab_search),
566
gtk_widget_add_accelerator(Search, "activate", accel_group, 'S',
567
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
569
/* File | New | Browse */
570
Browse = gq_menu_item_new_with_label(_("_Browse"));
571
gtk_widget_show(Browse);
572
gtk_menu_append(GTK_MENU(submenu), Browse);
573
g_signal_connect_swapped(Browse, "activate",
574
G_CALLBACK(new_modetab_browse),
576
gtk_widget_add_accelerator(Browse, "activate", accel_group, 'B',
577
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
578
/* ctrl-b is used by text widgets, so the searchterm textbox that
579
always has focus in search mode blocks the above accelerator...*/
580
g_signal_connect(win->mainwin, "key_press_event",
581
G_CALLBACK(ctrl_b_hack),
584
/* File | New | Schema */
585
Schema = gq_menu_item_new_with_label(_("S_chema"));
586
gtk_widget_show(Schema);
587
gtk_menu_append(GTK_MENU(submenu), Schema);
588
gtk_widget_add_accelerator(Schema, "activate", accel_group, 'Z',
589
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
590
#ifdef HAVE_LDAP_STR2OBJECTCLASS
591
g_signal_connect_swapped(Schema, "activate",
592
G_CALLBACK(new_modetab_schema),
595
gtk_widget_set_sensitive(Schema, FALSE);
598
/* File | Preferences */
599
menuitem = gq_menu_item_new_with_label(_("_Preferences"));
600
gtk_widget_show(menuitem);
601
gtk_container_add(GTK_CONTAINER(menuFile), menuitem);
602
g_signal_connect_swapped(menuitem, "activate",
603
G_CALLBACK(create_prefs_window),
605
gtk_widget_add_accelerator(menuitem, "activate", accel_group, 'P',
606
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
609
Close = gq_menu_item_new_with_label(_("_Close tab"));
610
gtk_widget_show(Close);
611
gtk_container_add(GTK_CONTAINER(menuFile), Close);
612
g_signal_connect_swapped(Close, "activate",
613
G_CALLBACK(close_current_tab),
615
gtk_widget_add_accelerator(Close, "activate", accel_group, 'W',
616
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
618
g_signal_connect(win->mainwin, "key_press_event",
619
G_CALLBACK(ctrl_w_hack),
623
Quit = gq_menu_item_new_with_label(_("_Quit"));
624
gtk_widget_show(Quit);
625
gtk_container_add(GTK_CONTAINER(menuFile), Quit);
626
g_signal_connect_swapped(Quit, "activate",
627
G_CALLBACK(gtk_widget_destroy),
629
gtk_widget_add_accelerator(Quit, "activate", accel_group, 'Q',
630
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
634
Filters = gq_menu_item_new_with_label(_("F_ilters"));
635
gtk_widget_show(Filters);
636
gtk_container_add(GTK_CONTAINER(menubar), Filters);
638
menuFilters = gtk_menu_new();
639
gtk_menu_item_set_submenu(GTK_MENU_ITEM(Filters), menuFilters);
640
win->filtermenu = menuFilters;
643
New = gq_menu_item_new_with_label(_("_New filter"));
644
gtk_widget_show(New);
645
gtk_container_add(GTK_CONTAINER(menuFilters), New);
646
submenu = gtk_menu_new();
647
gtk_menu_item_set_submenu(GTK_MENU_ITEM(New), submenu);
649
/* Filters | New | From Search tab */
650
menuitem = gq_menu_item_new_with_label(_("From _Search tab"));
651
gtk_widget_show(menuitem);
652
gtk_menu_append(GTK_MENU(submenu), menuitem);
653
g_signal_connect_swapped(menuitem, "activate",
654
G_CALLBACK(add_filter),
657
/* Filters | New | Filter Editor */
658
menuitem = gq_menu_item_new_with_label(_("Filter _editor"));
659
gtk_widget_show(menuitem);
660
gtk_menu_append(GTK_MENU(submenu), menuitem);
661
g_signal_connect_swapped(menuitem, "activate",
662
G_CALLBACK(add_new_filter_callback),
665
/* Filters | Edit Filters */
666
menuitem = gq_menu_item_new_with_label(_("_Edit Filters"));
667
gtk_widget_show(menuitem);
668
gtk_container_add(GTK_CONTAINER(menuFilters), menuitem);
669
g_signal_connect_swapped(menuitem, "activate",
670
G_CALLBACK(show_filters),
673
/* Filters separator */
674
menuitem = gtk_menu_item_new();
675
gtk_widget_show(menuitem);
676
gtk_container_add(GTK_CONTAINER(menuFilters), menuitem);
678
mainwin_update_filter_menu(win);
681
Help = gq_menu_item_new_with_label(_("_Help"));
682
gtk_widget_show(Help);
683
gtk_container_add(GTK_CONTAINER(menubar), Help);
685
menuHelp = gtk_menu_new();
686
gtk_menu_item_set_submenu(GTK_MENU_ITEM(Help), menuHelp);
688
Help = gtk_image_menu_item_new_with_mnemonic(_("_Manual"));
689
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(Help),
690
gtk_image_new_from_stock(GTK_STOCK_HELP, GTK_ICON_SIZE_MENU));
691
gtk_widget_show(Help);
692
gtk_menu_shell_append(GTK_MENU_SHELL(menuHelp), Help);
693
g_signal_connect_swapped(Help, "activate",
694
G_CALLBACK(window_help_manual), win);
696
Help = gtk_separator_menu_item_new();
697
gtk_widget_show(Help);
698
gtk_menu_shell_append(GTK_MENU_SHELL(menuHelp), Help);
700
/* Help | Show Messages */
702
ShowM = gq_menu_item_new_with_label(_("Show _Messages"));
703
gtk_widget_show(ShowM);
704
gtk_container_add(GTK_CONTAINER(menuHelp), ShowM);
705
g_signal_connect_swapped(ShowM, "activate",
706
G_CALLBACK(message_log),
709
gtk_container_add(GTK_CONTAINER(menuHelp), gtk_separator_menu_item_new());
712
About = gq_menu_item_new_with_label(_("_About"));
713
gtk_widget_show(About);
714
gtk_container_add(GTK_CONTAINER(menuHelp), About);
715
g_signal_connect_swapped(About, "activate",
716
G_CALLBACK(create_about_window), win->mainwin);
718
main_vbox = gtk_vbox_new(FALSE, 2);
719
gtk_container_border_width(GTK_CONTAINER(main_vbox), 4);
720
gtk_widget_show(main_vbox);
721
gtk_box_pack_start(GTK_BOX(outer_vbox), main_vbox, TRUE, TRUE, 1);
723
win->mainbook = gtk_notebook_new();
724
gtk_notebook_set_homogeneous_tabs(GTK_NOTEBOOK(win->mainbook), FALSE);
725
gtk_widget_show(win->mainbook);
726
/* GTK_WIDGET_UNSET_FLAGS(GTK_NOTEBOOK(mainbook), GTK_CAN_FOCUS); */
727
gtk_box_pack_start(GTK_BOX(main_vbox), win->mainbook, TRUE, TRUE, 0);
729
win->statusbar = gtk_statusbar_new();
730
gtk_widget_show(win->statusbar);
732
gtk_box_pack_end(GTK_BOX(outer_vbox), win->statusbar, FALSE, FALSE, 0);
733
gtk_widget_set_sensitive(win->statusbar, TRUE);
735
g_signal_connect(win->mainbook, "switch-page",
736
G_CALLBACK(switchpage_refocus), win);
737
g_signal_connect(win->mainbook, "remove",
738
G_CALLBACK(remove_tab), win);
740
gtk_widget_realize(win->mainwin);
742
if (! mainwin_restore_snapshot(win)) {
743
new_modetab(win, GQ_TYPE_TAB_SEARCH, TRUE);
744
new_modetab(win, GQ_TYPE_TAB_BROWSE, FALSE);
745
new_modetab(win, GQ_TYPE_TAB_SCHEMA, FALSE);
748
gtk_widget_show(win->mainwin);
751
GqTab *mainwin_get_tab_nth(GqWindow *win, int n)
754
gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->mainbook), n);
755
if (content == NULL) return NULL;
757
return gtk_object_get_data(GTK_OBJECT(content), "tab");
760
GqTab *mainwin_get_current_tab(GtkWidget *notebook)
762
int tabnum = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
763
GtkWidget *content = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
765
return gtk_object_get_data(GTK_OBJECT(content), "tab");
769
new_modetab(GqWindow* win,
774
GtkWidget* tab_label;
775
GtkWidget* tab_button;
776
GtkWidget* tab_image;
780
tab = g_object_new(mode, NULL);
781
if(mode == GQ_TYPE_TAB_SEARCH) {
782
tab_label = gq_label_new(_("_Search"));
784
else if(mode == GQ_TYPE_TAB_BROWSE) {
785
tab_label = gq_label_new(_("_Browse"));
787
else if(G_OBJECT_TYPE(tab) == GQ_TYPE_DIFF_TAB) {
788
tab_label = gq_label_new(_("C_ompare"));
790
#ifdef HAVE_LDAP_STR2OBJECTCLASS
791
else if(mode == GQ_TYPE_TAB_SCHEMA) {
792
tab_label = gq_label_new(_("S_chema"));
796
g_warning("Invalid tab type %s", g_type_name(mode));
800
tab_box = gtk_hbox_new(FALSE, 6);
801
gtk_box_pack_start(GTK_BOX(tab_box), tab_label,
803
tab_button = gtk_button_new();
804
gtk_button_set_relief(GTK_BUTTON(tab_button), GTK_RELIEF_NONE);
805
g_signal_connect_swapped(tab_button, "clicked",
806
G_CALLBACK(gtk_widget_destroy), tab->content);
807
gtk_box_pack_start(GTK_BOX(tab_box), tab_button,
809
tab_image = gtk_image_new_from_stock(GTK_STOCK_CLOSE,
811
gtk_container_add(GTK_CONTAINER(tab_button), tab_image);
812
gtk_widget_show_all(tab_box);
814
#warning "FIXME: GET THIS ONLY CLEANER"
815
gtk_object_set_data(GTK_OBJECT(tab->content), "tab", tab);
819
gq_stack_push(win->tab_history, tab);
820
gtk_notebook_append_page(GTK_NOTEBOOK(win->mainbook),
825
enter_last_of_mode(tab);
827
gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), -1);
829
focusbox = tab->focus;
831
gtk_widget_grab_focus(focusbox);
838
switchpage_refocus(GtkNotebook * notebook G_GNUC_UNUSED,
839
GtkNotebookPage* page G_GNUC_UNUSED,
846
tab = mainwin_get_tab_nth(win, pagenum);
850
/* retrieve mode, store this pane as the last one used for this mode */
851
enter_last_of_mode(tab);
853
focusbox = tab->focus;
855
gtk_widget_grab_focus(focusbox);
856
gtk_editable_select_region(GTK_EDITABLE(focusbox), 0, -1);
861
void cleanup_all_tabs(GqWindow *win)
863
/* don't waste time refocusing on disappearing tabs */
864
g_signal_handlers_disconnect_by_func(win->mainbook,
865
G_CALLBACK(switchpage_refocus), win);
869
static void close_current_tab(GqWindow *win)
874
tabnum = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->mainbook));
875
content = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->mainbook), tabnum);
876
/* for whatever reason: gtk_notebook_remove_page does not call
877
the remove signal on the notebook. I consider this to be a GTK
880
/* gtk_notebook_remove_page(GTK_NOTEBOOK(win->mainbook), tabnum); */
882
gtk_widget_destroy(content);
885
void update_serverlist(GqWindow *win)
890
for(i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
891
#warning "FIXME: make this a generic update function for tabs"
892
if(GQ_IS_TAB_BROWSE(tab)) {
893
update_browse_serverlist(tab);
895
else if(GQ_IS_TAB_SCHEMA(tab)) {
896
update_schema_serverlist(tab);
902
about_dialog_activate_uri(GtkAboutDialog* dialog,
904
gpointer data G_GNUC_UNUSED)
906
gchar* shell_uri = g_shell_quote(uri);
907
gchar* command = g_strdup_printf("gnome-open %s", shell_uri);
908
gdk_spawn_command_line_on_screen(gtk_widget_get_screen(GTK_WIDGET(dialog)),
915
create_about_window(GtkWindow* parent) {
916
static gchar const* authors[] = {
920
"Sven Herzberg (current maintainer)",
923
GdkPixbuf* logo = gdk_pixbuf_new_from_file(PACKAGE_PREFIX "/share/pixmaps/gq/gq.xpm", NULL);
924
gtk_about_dialog_set_url_hook(about_dialog_activate_uri, NULL, NULL);
925
gtk_show_about_dialog(parent,
928
"comments", _("The gentleman's LDAP client"),
929
"copyright", _("Copyright (C) 1998-2003 Bert Vermeulen\n"
930
"Copyright (C) 2002-2003 Peter Stamfest\n"
931
"Copyright (C) 2006 Sven Herzberg"),
935
"name", _("GQ LDAP Client"),
936
"translator-credits", _("translator-credits"),
938
"website", "http://www.gq-project.org/",
939
"website-label", _("GQ Website"),
942
g_object_unref(logo);