~ubuntu-branches/ubuntu/trusty/gq/trusty

« back to all changes in this revision

Viewing changes to src/mainwin.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2009-10-25 23:34:56 UTC
  • mfrom: (1.1.4 upstream) (3.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091025233456-i794n3yg2cff930j
Tags: 1.3.4-1
* QA upload.
  + Set maintainer to Debian QA Group <packages@qa.debian.org>.
* New upstream release. (Closes: #534705).
  + Does not segfault on amd64. (Closes: #444312).
  + Remove all existing patches and change patch system to quilt.
  + Replace dpatch build-dep with quilt.
* 01_desktop_file.diff - Remove encoding and bogus categories 
  from desktop file.
* Copy in config.{sub,guess} on configure, rm them on clean.
  + Add build-dep on autotools-dev.
* Make clean not ignore errors.
* Add copyright holders and version path to GPL (GPL-2).
* Update watch file to use SF redirector. (Closes: #449749).
* Bump debhelper build-dep and compat to 5.
* Bump Standards Version to 3.8.3.
  + Menu policy transition.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    GQ -- a GTK-based LDAP client
3
 
    Copyright (C) 1998-2003 Bert Vermeulen
4
 
    Copyright (C) 2002-2003 Peter Stamfest
5
 
 
6
 
    This program is released under the Gnu General Public License with
7
 
    the additional exemption that compiling, linking, and/or using
8
 
    OpenSSL is allowed.
9
 
 
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.
14
 
 
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.
19
 
 
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
23
 
*/
24
 
 
25
 
/* $Id: mainwin.c 975 2006-09-07 18:44:41Z herzi $ */
26
 
 
27
 
#include <string.h>
28
 
 
29
 
#include <glib.h>
30
 
#include <glib/gi18n.h>
31
 
#include <gtk/gtk.h>
32
 
#include <gdk/gdkkeysyms.h>
33
 
 
34
 
#ifdef HAVE_CONFIG_H
35
 
# include <config.h>
36
 
#endif /* HAVE_CONFIG_H */
37
 
 
38
 
#include "common.h"
39
 
#include "gq-server-list.h"
40
 
#include "gq-tab-browse.h"
41
 
#ifdef HAVE_LDAP_STR2OBJECTCLASS
42
 
#    include "gq-tab-schema.h"
43
 
#endif
44
 
#include "gq-tab-search.h"
45
 
 
46
 
#include "mainwin.h"
47
 
#include "configfile.h"
48
 
#include "prefs.h"
49
 
#include "util.h"
50
 
#include "template.h"
51
 
#include "filter.h"
52
 
#include "COPYING.h"
53
 
#include "debug.h"
54
 
#include "input.h"
55
 
#include "state.h"
56
 
#include "errorchain.h"
57
 
#include "progress.h"
58
 
 
59
 
struct mainwin_data mainwin;
60
 
 
61
 
static void create_about_window(GtkWindow* parent);
62
 
 
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);
67
 
 
68
 
GqTab *get_last_of_mode(int mode)
69
 
{
70
 
     if(!mainwin.lastofmode)
71
 
          return NULL;
72
 
 
73
 
     return g_hash_table_lookup(mainwin.lastofmode, GINT_TO_POINTER(mode));
74
 
}
75
 
 
76
 
 
77
 
void go_to_page(GqTab *tab)
78
 
{
79
 
     gtk_notebook_set_page(GTK_NOTEBOOK(mainwin.mainbook),
80
 
                           gtk_notebook_page_num(GTK_NOTEBOOK(mainwin.mainbook),
81
 
                                                 tab->content));
82
 
}
83
 
 
84
 
 
85
 
void enter_last_of_mode(GqTab *tab)
86
 
{
87
 
 
88
 
     if(!mainwin.lastofmode)
89
 
          mainwin.lastofmode = g_hash_table_new(g_direct_hash, g_direct_equal);
90
 
 
91
 
     g_hash_table_insert(mainwin.lastofmode, GINT_TO_POINTER(tab->type), tab);
92
 
 
93
 
}
94
 
 
95
 
static void
96
 
append_name(GQServerList* list, GqServer* server, gpointer data) {
97
 
        GList** serverlist = data;
98
 
        *serverlist = g_list_append(*serverlist, server->name);
99
 
}
100
 
 
101
 
void fill_serverlist_combo(GtkWidget *combo)
102
 
{
103
 
     GList *serverlist = NULL;
104
 
     GqServer *server;
105
 
 
106
 
     if(combo == NULL)
107
 
          return;
108
 
 
109
 
     gq_server_list_foreach(gq_server_list_get(), append_name, &serverlist);
110
 
 
111
 
     if(!serverlist)
112
 
          /* all servers were deleted -- pass an empty string to the combo */
113
 
          serverlist = g_list_append(serverlist, "");
114
 
 
115
 
     gtk_combo_set_popdown_strings(GTK_COMBO(combo), serverlist);
116
 
 
117
 
     g_list_free(serverlist);
118
 
}
119
 
 
120
 
static gboolean mainwin_restore_snapshot(struct mainwin_data *win)
121
 
{
122
 
     int i, type;
123
 
     char tmp[32];
124
 
     struct pbar_win *pw = NULL;
125
 
 
126
 
     if (!config->restore_tabs) return FALSE;
127
 
     if (!exists_entity("mainwin.tabs")) return FALSE;
128
 
 
129
 
     pw = create_progress_bar_in_window(_("Restoring last GUI state"));
130
 
     update_progress(pw, _("Restoring tabs"));
131
 
 
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);
136
 
          if (type > 0) {
137
 
               GqTab *tab = new_modetab(win, type);
138
 
               int error_ctx = error_new_context("", pw->win);
139
 
 
140
 
               if (GQ_TAB_GET_CLASS(tab)->restore_snapshot) {
141
 
                    GQ_TAB_GET_CLASS(tab)->restore_snapshot(error_ctx, tmp, tab, pw);
142
 
               }
143
 
 
144
 
               error_flush(error_ctx);
145
 
          }
146
 
          update_progress(pw, NULL);
147
 
          if (pw->cancelled) break;
148
 
     }
149
 
 
150
 
     if (i > 0) {
151
 
          type = state_value_get_int("mainwin.tabs", "active", -1);
152
 
          gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), type);
153
 
     }
154
 
 
155
 
     update_progress(pw, _("Restoring tabs"));
156
 
     free_progress(pw);
157
 
 
158
 
     return i > 0;
159
 
}
160
 
 
161
 
static void mainwin_save_snapshot(struct mainwin_data *win)
162
 
{
163
 
     GqTab *tab = NULL;
164
 
     int i;
165
 
     char tmp[32];
166
 
 
167
 
     rm_value("mainwin.tabs");
168
 
 
169
 
     if (!config->restore_tabs) return;
170
 
 
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) {
175
 
               int error_ctx =
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);
179
 
          }
180
 
     }
181
 
 
182
 
     state_value_set_int("mainwin.tabs", "active",
183
 
                         gtk_notebook_get_current_page(GTK_NOTEBOOK(win->mainbook)));
184
 
}
185
 
 
186
 
 
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)
190
 
{
191
 
     mainwin_save_snapshot(win);
192
 
     cleanup(win);
193
 
     gtk_main_quit();
194
 
}
195
 
 
196
 
void cleanup(struct mainwin_data *win)
197
 
{
198
 
     cleanup_all_tabs(win);
199
 
}
200
 
 
201
 
static gboolean ctrl_b_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
202
 
{
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");
207
 
          return(TRUE);
208
 
     }
209
 
 
210
 
     return(FALSE);
211
 
}
212
 
 
213
 
 
214
 
static gboolean ctrl_w_hack(GtkWidget *widget, GdkEventKey *event, gpointer obj)
215
 
{
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");
220
 
          return(TRUE);
221
 
     }
222
 
 
223
 
     return(FALSE);
224
 
}
225
 
 
226
 
static void new_modetab_search(struct mainwin_data *win) 
227
 
{
228
 
     new_modetab(win, SEARCH_MODE);
229
 
}
230
 
 
231
 
static void new_modetab_browse(struct mainwin_data *win) 
232
 
{
233
 
     new_modetab(win, BROWSE_MODE);
234
 
}
235
 
 
236
 
static void new_modetab_schema(struct mainwin_data *win) 
237
 
{
238
 
     new_modetab(win, SCHEMA_MODE);
239
 
}
240
 
 
241
 
 
242
 
static GList *log_list = NULL;
243
 
static int log_list_len = 0;
244
 
 
245
 
void clear_message_history()
246
 
{
247
 
     if (log_list) {
248
 
          g_list_foreach(log_list, (GFunc) g_free, NULL);
249
 
          g_list_free(log_list);
250
 
          log_list = NULL;
251
 
     }
252
 
 
253
 
     if (mainwin.ml_text) {
254
 
          GtkTextIter start;
255
 
          GtkTextIter end;
256
 
          
257
 
          gtk_text_buffer_get_start_iter(mainwin.ml_buffer, &start);
258
 
          gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &end);
259
 
 
260
 
          gtk_text_buffer_delete(mainwin.ml_buffer, &start, &end);
261
 
     }
262
 
}
263
 
 
264
 
 
265
 
void message_log_append(const char *buf)
266
 
{
267
 
     log_list = g_list_append(log_list, g_strdup(buf));
268
 
     log_list_len++;
269
 
 
270
 
     if (mainwin.ml_text) {
271
 
          GtkTextIter iter;
272
 
          gtk_text_buffer_get_end_iter(mainwin.ml_buffer, &iter);
273
 
          gtk_text_buffer_insert(mainwin.ml_buffer, &iter,
274
 
                                 buf, strlen(buf));
275
 
          gtk_text_buffer_insert(mainwin.ml_buffer, &iter, "\n", 1);
276
 
 
277
 
          gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(mainwin.ml_text),
278
 
                                       gtk_text_buffer_create_mark(mainwin.ml_buffer,
279
 
                                                                   NULL,
280
 
                                                                   &iter,
281
 
                                                                   FALSE),
282
 
                                       0.0,
283
 
                                       FALSE,
284
 
                                       0.0, 0.0);
285
 
     }
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);
289
 
          log_list_len--;
290
 
     }
291
 
}
292
 
 
293
 
static void message_log_destroyed(GtkWidget *window,
294
 
                                  struct mainwin_data *win)
295
 
{
296
 
     win->ml_window = NULL;
297
 
     win->ml_text   = NULL;
298
 
     win->ml_buffer = NULL;
299
 
}
300
 
 
301
 
static void clear_clicked(void)
302
 
{
303
 
     clear_message_history();
304
 
}
305
 
 
306
 
static void message_log(struct mainwin_data *win) 
307
 
{
308
 
     GtkWidget *window, *vbox0, *scrwin, *text, *bbox, *button;
309
 
     GtkTextBuffer *buffer;
310
 
     GtkTextIter iter;
311
 
     GList *I;
312
 
 
313
 
     g_assert(win);
314
 
 
315
 
     if (win->ml_window) {
316
 
          gdk_beep(); /* Is this OK, philosophically? */
317
 
          gtk_window_present(GTK_WINDOW(win->ml_window));
318
 
          return;
319
 
     }
320
 
 
321
 
     window = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
322
 
                                      "statusbar-log", 500, 350);
323
 
     win->ml_window = window;
324
 
 
325
 
     gtk_widget_realize(window);
326
 
 
327
 
     g_signal_connect(window, "destroy",
328
 
                        G_CALLBACK(message_log_destroyed), win);
329
 
 
330
 
     g_signal_connect(window, "key_press_event",
331
 
                        G_CALLBACK(close_on_esc),
332
 
                        window);
333
 
 
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);
337
 
 
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);
343
 
 
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),
351
 
                                         GTK_SHADOW_IN);
352
 
     gtk_box_pack_start(GTK_BOX(vbox0), scrwin, TRUE, TRUE, 0);
353
 
 
354
 
     text = gtk_text_view_new();
355
 
     buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
356
 
     win->ml_buffer = buffer;
357
 
 
358
 
     gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
359
 
     gtk_text_buffer_get_end_iter(buffer, &iter);
360
 
 
361
 
     win->ml_text = text;
362
 
 
363
 
     gtk_widget_show(text);
364
 
     gtk_container_add(GTK_CONTAINER(scrwin), text); 
365
 
 
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);
370
 
     }
371
 
 
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,
375
 
                                                              &iter, FALSE),
376
 
                                  0.0,
377
 
                                  FALSE,
378
 
                                  0.0, 0.0);
379
 
 
380
 
     bbox = gtk_hbutton_box_new();
381
 
     gtk_widget_show(bbox);
382
 
 
383
 
     gtk_box_pack_end(GTK_BOX(vbox0), bbox, FALSE, FALSE, 3);
384
 
 
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),
389
 
                        win);
390
 
     gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, TRUE, 10);
391
 
 
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),
396
 
                               window);
397
 
     gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, TRUE, 10);
398
 
 
399
 
     GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
400
 
     gtk_widget_grab_default(button);
401
 
 
402
 
     gtk_widget_show(window);
403
 
}
404
 
 
405
 
/* Callback function called when a tab gets removed from the
406
 
   notebook. */
407
 
static void remove_tab(GtkContainer *notebook,
408
 
                       GtkWidget *content,
409
 
                       struct mainwin_data *win)
410
 
{
411
 
     int thismode;
412
 
     GqTab *tab = NULL;
413
 
     int i;
414
 
 
415
 
     tab = gtk_object_get_data(GTK_OBJECT(content), "tab");
416
 
     if (tab) {
417
 
          thismode = tab->type;
418
 
          g_hash_table_insert(win->lastofmode, GINT_TO_POINTER(thismode), NULL);
419
 
 
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) {
424
 
                    /* found one! */
425
 
                    enter_last_of_mode(tab);
426
 
                    break;
427
 
               }
428
 
          }
429
 
     }
430
 
 
431
 
     if (gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), 0) == NULL) {
432
 
          gtk_widget_destroy(win->mainwin);
433
 
     }
434
 
}
435
 
 
436
 
 
437
 
void mainwin_update_filter_menu(struct mainwin_data *win)
438
 
{
439
 
     GList *menuitems = gtk_container_children(GTK_CONTAINER(win->filtermenu));
440
 
     GList *I;
441
 
 
442
 
     /* Filters | list of filters */
443
 
 
444
 
     if (menuitems) {
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");
448
 
 
449
 
               if (data) {
450
 
                    gtk_widget_destroy(item);
451
 
               }
452
 
          }
453
 
 
454
 
          g_list_free(menuitems);
455
 
     }
456
 
 
457
 
     for ( I = g_list_first(config->filters) ; I ; I = g_list_next(I) ) {
458
 
          struct gq_filter *filter;
459
 
          GtkWidget *menuitem;
460
 
 
461
 
          filter = (struct gq_filter *) I->data;
462
 
          menuitem = gtk_menu_item_new_with_label(filter->name);
463
 
 
464
 
          gtk_object_set_data(GTK_OBJECT(menuitem), "filter", filter);
465
 
          g_signal_connect_swapped(menuitem, "activate",
466
 
                                    G_CALLBACK(filter_selected),
467
 
                                    filter);
468
 
 
469
 
          gtk_container_add(GTK_CONTAINER(win->filtermenu), menuitem);
470
 
          gtk_widget_show(menuitem);
471
 
     }
472
 
}
473
 
 
474
 
 
475
 
void create_mainwin(struct mainwin_data *win)
476
 
{
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;
484
 
 
485
 
     g_assert(win != NULL);
486
 
 
487
 
     win->mainwin = stateful_gtk_window_new(GTK_WINDOW_TOPLEVEL,
488
 
                                            "mainwin", 770, 478);
489
 
 
490
 
     gtk_container_border_width(GTK_CONTAINER(win->mainwin), 0);
491
 
     g_signal_connect(win->mainwin, "destroy",
492
 
                        G_CALLBACK(mainwin_destroyed),
493
 
                        win);
494
 
     gtk_window_set_title(GTK_WINDOW(win->mainwin), _("GQ"));
495
 
     gtk_window_set_policy(GTK_WINDOW(win->mainwin), FALSE, TRUE, FALSE);
496
 
 
497
 
 
498
 
 
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);
503
 
 
504
 
     accel_group = gtk_accel_group_new();
505
 
 
506
 
     gtk_window_add_accel_group(GTK_WINDOW(win->mainwin), accel_group);
507
 
 
508
 
     handlebox = gtk_handle_box_new();
509
 
     gtk_widget_show(handlebox);
510
 
     gtk_box_pack_start(GTK_BOX(outer_vbox), handlebox, FALSE, TRUE, 0);
511
 
 
512
 
     menubar = gtk_menu_bar_new();
513
 
     gtk_widget_show(menubar);
514
 
     gtk_container_add(GTK_CONTAINER(handlebox), menubar);
515
 
 
516
 
     /* File menu */
517
 
     File = gq_menu_item_new_with_label(_("_File"));
518
 
     gtk_widget_show(File);
519
 
     gtk_container_add(GTK_CONTAINER(menubar), File);
520
 
 
521
 
     menuFile = gtk_menu_new();
522
 
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(File), menuFile);
523
 
 
524
 
     /* File | New */
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);
530
 
 
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),
537
 
                               win);
538
 
     gtk_widget_add_accelerator(Search, "activate", accel_group, 'S',
539
 
                                GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
540
 
 
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),
547
 
                               win);
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),
554
 
                        Browse);
555
 
 
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),
565
 
                               win);
566
 
#else
567
 
     gtk_widget_set_sensitive(Schema, FALSE);
568
 
#endif
569
 
 
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),
576
 
                               win);
577
 
     gtk_widget_add_accelerator(menuitem, "activate", accel_group, 'P',
578
 
                                GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
579
 
 
580
 
     /* File | Close */
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),
586
 
                               win);
587
 
     gtk_widget_add_accelerator(Close, "activate", accel_group, 'W',
588
 
                                GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
589
 
     /* :-( */
590
 
     g_signal_connect(win->mainwin, "key_press_event",
591
 
                        G_CALLBACK(ctrl_w_hack),
592
 
                        Close);
593
 
 
594
 
     /* File | Show Message */
595
 
 
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),
601
 
                               win);
602
 
 
603
 
     /* File | Quit */
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),
609
 
                               win->mainwin);
610
 
     gtk_widget_add_accelerator(Quit, "activate", accel_group, 'Q',
611
 
                                GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
612
 
 
613
 
 
614
 
     /* Filters menu */
615
 
     Filters = gq_menu_item_new_with_label(_("F_ilters"));
616
 
     gtk_widget_show(Filters);
617
 
     gtk_container_add(GTK_CONTAINER(menubar), Filters);
618
 
 
619
 
     menuFilters = gtk_menu_new();
620
 
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(Filters), menuFilters);
621
 
     win->filtermenu = menuFilters;
622
 
 
623
 
     /* Filters | New */
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);
629
 
 
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),
636
 
                               NULL);
637
 
 
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),
644
 
                               NULL);
645
 
 
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),
652
 
                               NULL);
653
 
 
654
 
     /* Filters separator */
655
 
     menuitem = gtk_menu_item_new();
656
 
     gtk_widget_show(menuitem);
657
 
     gtk_container_add(GTK_CONTAINER(menuFilters), menuitem);
658
 
 
659
 
     mainwin_update_filter_menu(win);
660
 
 
661
 
     /* Help menu */
662
 
     Help = gq_menu_item_new_with_label(_("_Help"));
663
 
     gtk_widget_show(Help);
664
 
     gtk_container_add(GTK_CONTAINER(menubar), Help);
665
 
 
666
 
     menuHelp = gtk_menu_new();
667
 
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(Help), menuHelp);
668
 
 
669
 
     /* Help | About */
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);
675
 
 
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);
680
 
 
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);
685
 
 
686
 
     win->statusbar = gtk_statusbar_new();
687
 
     gtk_widget_show(win->statusbar);
688
 
 
689
 
     gtk_box_pack_end(GTK_BOX(outer_vbox), win->statusbar, FALSE, FALSE, 0);
690
 
     gtk_widget_set_sensitive(win->statusbar, TRUE);
691
 
     
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);
696
 
 
697
 
     gtk_widget_realize(win->mainwin);
698
 
 
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);
703
 
     }
704
 
 
705
 
     gtk_widget_show(win->mainwin);
706
 
}
707
 
 
708
 
GqTab *mainwin_get_tab_nth(struct mainwin_data *win, int n)
709
 
{
710
 
     GtkWidget *content = 
711
 
          gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->mainbook), n);
712
 
     if (content == NULL) return NULL;
713
 
 
714
 
     return gtk_object_get_data(GTK_OBJECT(content), "tab");
715
 
}
716
 
 
717
 
GqTab *mainwin_get_current_tab(GtkWidget *notebook)
718
 
{
719
 
     int tabnum = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
720
 
     GtkWidget *content = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), 
721
 
                                                    tabnum);
722
 
     return gtk_object_get_data(GTK_OBJECT(content), "tab");
723
 
}
724
 
 
725
 
GqTab *new_modetab(struct mainwin_data *win, int mode)
726
 
{
727
 
     GtkWidget *label, *focusbox;
728
 
     GqTab *tab;
729
 
     int focus;
730
 
 
731
 
     /* hack, hack */
732
 
     focus = !(mode & 32768);
733
 
     mode &= 32767;
734
 
 
735
 
     switch(mode) {
736
 
     case SEARCH_MODE:
737
 
          label = gq_label_new(_("_Search"));
738
 
          tab = new_searchmode();
739
 
          break;
740
 
     case BROWSE_MODE:
741
 
          label = gq_label_new(_("_Browse"));
742
 
          tab = new_browsemode();
743
 
          break;
744
 
#ifdef HAVE_LDAP_STR2OBJECTCLASS
745
 
     case SCHEMA_MODE:
746
 
          label = gq_label_new(_("S_chema"));
747
 
          tab = new_schemamode();
748
 
          break;
749
 
#endif
750
 
     default:
751
 
          return NULL;
752
 
     }
753
 
 
754
 
     gtk_object_set_data(GTK_OBJECT(tab->content), "tab", tab);
755
 
 
756
 
     tab->win = win;
757
 
 
758
 
     gtk_widget_show(label);
759
 
     gtk_notebook_append_page(GTK_NOTEBOOK(win->mainbook), 
760
 
                              tab->content,
761
 
                              label);
762
 
 
763
 
     if(focus) {
764
 
          enter_last_of_mode(tab);
765
 
 
766
 
          gtk_notebook_set_page(GTK_NOTEBOOK(win->mainbook), -1);
767
 
 
768
 
          focusbox = tab->focus;
769
 
          if(focusbox)
770
 
               gtk_widget_grab_focus(focusbox);
771
 
     }
772
 
     return tab;
773
 
}
774
 
 
775
 
 
776
 
static void switchpage_refocus(GtkNotebook *notebook, GtkNotebookPage *page,
777
 
                               int pagenum, struct mainwin_data *win)
778
 
{
779
 
     GtkWidget *focusbox;
780
 
     GqTab *tab;
781
 
 
782
 
     tab = mainwin_get_tab_nth(win, pagenum);
783
 
     if(!tab)
784
 
          return;
785
 
 
786
 
     /* retrieve mode, store this pane as the last one used for this mode */
787
 
     enter_last_of_mode(tab);
788
 
 
789
 
     focusbox = tab->focus;
790
 
     if(focusbox) {
791
 
          gtk_widget_grab_focus(focusbox);
792
 
          gtk_editable_select_region(GTK_EDITABLE(focusbox), 0, -1);
793
 
     }
794
 
}
795
 
 
796
 
 
797
 
void cleanup_all_tabs(struct mainwin_data *win)
798
 
{
799
 
     /* don't waste time refocusing on disappearing tabs */
800
 
     g_signal_handlers_disconnect_by_func(win->mainbook,
801
 
                                   G_CALLBACK(switchpage_refocus), win);
802
 
}
803
 
 
804
 
 
805
 
static void close_current_tab(struct mainwin_data *win)
806
 
{
807
 
     int tabnum;
808
 
     GtkWidget *content;
809
 
 
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
814
 
        bug */
815
 
 
816
 
/*      gtk_notebook_remove_page(GTK_NOTEBOOK(win->mainbook), tabnum); */
817
 
 
818
 
     gtk_widget_destroy(content);
819
 
}
820
 
 
821
 
void update_serverlist(struct mainwin_data *win)
822
 
{
823
 
     GqTab *tab;
824
 
     int i;
825
 
 
826
 
     for( i = 0 ; (tab = mainwin_get_tab_nth(win, i)) != NULL ; i++) {
827
 
          switch(tab->type) {
828
 
          case SEARCH_MODE:
829
 
               fill_serverlist_combo(GQ_TAB_SEARCH(tab)->serverlist_combo);
830
 
               break;
831
 
          case BROWSE_MODE:
832
 
               update_browse_serverlist(tab);
833
 
               break;
834
 
          case SCHEMA_MODE:
835
 
               update_schema_serverlist(tab);
836
 
               break;
837
 
          }
838
 
     }
839
 
}
840
 
 
841
 
static void
842
 
create_about_window(GtkWindow* parent) {
843
 
        static gchar const* authors[] = {
844
 
                "Bert Vermeulen",
845
 
                "Peter Stamfest",
846
 
                "David Malcom",
847
 
                "Sven Herzberg (current maintainer)",
848
 
                NULL
849
 
        };
850
 
        GdkPixbuf* logo = gdk_pixbuf_new_from_file(PACKAGE_PREFIX "/share/pixmaps/gq/gq.xpm", NULL);
851
 
        gtk_show_about_dialog(parent,
852
 
                              // "artists", NULL,
853
 
                              "authors", authors,
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"),
858
 
                              // documenters
859
 
                              "license", license,
860
 
                              "logo", logo,
861
 
                              "name", _("GQ LDAP Client"),
862
 
                              "translator-credits", _("translator-credits"),
863
 
                              "version", VERSION,
864
 
                              "website", "http://www.gq-project.org/",
865
 
                              "website-label", _("GQ Website"),
866
 
                              NULL);
867
 
        if(logo) {
868
 
                g_object_unref(logo);
869
 
        }
870
 
}
871
 
 
872
 
/*
873
 
   Local Variables:
874
 
   c-basic-offset: 5
875
 
   End:
876
 
*/