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

« back to all changes in this revision

Viewing changes to src/gq-tab-search.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:
2
2
    GQ -- a GTK-based LDAP client
3
3
    Copyright (C) 1998-2003 Bert Vermeulen
4
4
    Copyright (C) 2002-2003 Peter Stamfest
 
5
    Copyright (C) 2006      Sven Herzberg
5
6
 
6
7
    This program is released under the Gnu General Public License with
7
8
    the additional exemption that compiling, linking, and/or using
37
38
 
38
39
#include "common.h"
39
40
#include "configfile.h"
 
41
#include "encode.h"
40
42
#include "errorchain.h"
 
43
#include "filter.h"
41
44
#include "gq-constants.h"
42
 
#include "gq-server-list.h"
 
45
#include "gq-enumerations.h"
 
46
#include "gq-export-dialog.h"
 
47
#include "gq-input-form.h"
 
48
#include "gq-server-model.h"
43
49
#include "gq-tab-browse.h"
44
 
#include "mainwin.h"
45
 
#include "util.h"
46
 
#include "formfill.h"
47
 
#include "input.h"
48
 
#include "template.h"
49
 
#include "tinput.h"
50
 
#include "filter.h"
51
 
#include "encode.h"
 
50
#include "gq-window.h"
52
51
#include "schema.h"
53
52
#include "state.h"
54
53
#include "syntax.h"
55
 
#include "browse-export.h"
 
54
#include "template.h"
 
55
#include "gq-utilities.h"
56
56
 
57
57
#define MAX_NUM_ATTRIBUTES              256
58
58
 
 
59
struct attrs {
 
60
        gchar *name;
 
61
        int column;
 
62
        struct attrs *next;
 
63
};
 
64
 
 
65
struct GqTabSearchPrivate {
 
66
        GtkWidget   * searchmode_combo;
 
67
 
 
68
        GtkWidget   * results_treeview;
 
69
        GtkListStore* results_liststore;
 
70
 
 
71
        GtkWidget   * results_display;
 
72
 
 
73
        GtkWidget   * search_combo;
 
74
        GtkWidget   * serverlist_combo;
 
75
        GtkWidget   * searchbase_combo;
 
76
 
 
77
        gboolean      populated_searchbase : 1;
 
78
        gboolean      search_lock : 1;
 
79
 
 
80
        GList       * history;
 
81
 
 
82
        int           last_options_tab;
 
83
 
 
84
        int scope;
 
85
        int chase_ref;
 
86
        int max_depth;
 
87
        GList *attrs;
 
88
};
 
89
#define P(i) (G_TYPE_INSTANCE_GET_PRIVATE((i), GQ_TYPE_TAB_SEARCH, struct GqTabSearchPrivate))
 
90
 
 
91
/* Search Mode Tree Model */
 
92
enum {
 
93
        MODE_COL_MODE,
 
94
        MODE_COL_TEXT,
 
95
        MODE_N_COLUMNS
 
96
};
 
97
 
 
98
/* Search Results Tree Model */
 
99
#warning "FIXME: make this a class for its own, so we don't need to keep the DN in memory twice"
 
100
enum {
 
101
        RES_COL_NAME,
 
102
        RES_COL_DN,
 
103
        RES_N_COLUMNS
 
104
};
 
105
 
 
106
static void results_popup_menu(GqTabSearch   * self,
 
107
                               GdkEventButton* event,
 
108
                               GqServerDn    * set);
 
109
 
59
110
static void find_in_browser(GqTab *tab);
60
111
static void add_all_to_browser(GqTab *tab);
61
112
static void add_selected_to_browser(GqTab *tab);
62
 
static void export_search_selected_entry(GqTab *tab);
 
113
static void export_search_selected_entry(GqTab* tab);
63
114
static void delete_search_selected(GqTab *tab);
64
115
static void query(GqTab *tab);
65
116
 
72
123
                                      GqTab *tab);
73
124
static void findbutton_clicked_callback(GqTab *tab);
74
125
 
75
 
static gboolean search_button_press_on_tree_item(GtkWidget *clist,
76
 
                                                 GdkEventButton *event,
77
 
                                                 GqTab *tab);
78
 
 
79
126
static void servername_changed_callback(GqTab *tab);
80
 
static int select_entry_callback(GtkWidget *clist, gint row, gint column,
81
 
                                 GdkEventButton *event, GqTab *tab);
82
 
static void search_edit_entry_callback(GqTab *tab);
 
127
static void search_edit_entry_callback(GqTabSearch *tab);
83
128
static void search_new_from_entry_callback(GtkWidget *w, GqTab *tab);
84
129
static void delete_search_entry(GqTab *tab);
85
130
 
86
 
static void search_save_snapshot(int error_context,
87
 
                                 char *state_name, GqTab *tab)
88
 
{
89
 
     GList *hist;
90
 
     char *tmp;
91
 
 
92
 
     hist = GQ_TAB_SEARCH(tab)->history;
93
 
     if (hist) {
94
 
          state_value_set_list(state_name, "history", hist);
95
 
     }
96
 
 
97
 
     state_value_set_list(state_name, "attributes", GQ_TAB_SEARCH(tab)->attrs);
98
 
     state_value_set_int(state_name, "chase", GQ_TAB_SEARCH(tab)->chase_ref);
99
 
     state_value_set_int(state_name, "max-depth", GQ_TAB_SEARCH(tab)->max_depth);
100
 
     state_value_set_int(state_name, "scope", GQ_TAB_SEARCH(tab)->scope);
101
 
 
102
 
     state_value_set_int(state_name, "last-options-tab",
103
 
                         GQ_TAB_SEARCH(tab)->last_options_tab);
104
 
 
105
 
     tmp =  gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(GQ_TAB_SEARCH(tab)->serverlist_combo)->entry), 0, -1);
106
 
     state_value_set_string(state_name, "lastserver", tmp);
107
 
     g_free(tmp);
108
 
}
109
 
 
110
 
static void
111
 
search_restore_selection(GQServerList* list, GqServer* server, gpointer user_data) {
112
 
        gpointer**i_tab_and_servername = user_data;
113
 
        gint *i = (gint*)i_tab_and_servername[0];
114
 
        GqTab* tab = GQ_TAB(i_tab_and_servername[1]);
115
 
        gchar const* servername = (gchar const*)i_tab_and_servername[2];
116
 
 
117
 
        if(!strcasecmp(server->name, servername)) {
118
 
                gtk_list_select_item(GTK_LIST(GTK_COMBO(GQ_TAB_SEARCH(tab)->serverlist_combo)->list), *i);
119
 
        }
120
 
 
121
 
        *i++;
122
 
}
123
 
 
124
 
static void search_restore_snapshot(int error_context,
125
 
                                    char *state_name, GqTab *tab,
126
 
                                    struct pbar_win *progress)
127
 
{
128
 
     GqServer *server;
129
 
     GList *searchhist;
130
 
     const char *lastserver;
131
 
 
132
 
     lastserver = state_value_get_string(state_name, "lastserver", NULL);
133
 
     if(lastserver && lastserver[0]) {
134
 
          gint i = 0;
135
 
          gpointer i_tab_and_servername[3] = {
136
 
                  &i,
137
 
                  tab,
138
 
                  (gchar*)lastserver
139
 
          };
140
 
          gq_server_list_foreach(gq_server_list_get(), search_restore_selection, i_tab_and_servername);
141
 
     }
 
131
gchar const*
 
132
gq_tab_search_get_base_dn(GqTabSearch const* self)
 
133
{
 
134
        g_return_val_if_fail(GQ_IS_TAB_SEARCH(self), NULL);
 
135
 
 
136
        return gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(P(self)->searchbase_combo)->entry));
 
137
}
 
138
 
 
139
void
 
140
gq_tab_search_set_base_dn(GqTabSearch* self,
 
141
                          gchar const* base_dn)
 
142
{
 
143
        g_return_if_fail(GQ_IS_TAB_SEARCH(self));
 
144
        g_return_if_fail(!base_dn || *base_dn);
 
145
 
 
146
        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(self)->searchbase_combo)->entry),
 
147
                           base_dn);
 
148
 
 
149
#warning "FIXME: enable"
 
150
        //g_object_notify(G_OBJECT(self), "base-dn");
 
151
}
 
152
 
 
153
GqSearchMode
 
154
gq_tab_search_get_mode(GqTabSearch const* self)
 
155
{
 
156
        GqSearchMode mode;
 
157
        GtkTreeIter iter;
 
158
 
 
159
        gtk_combo_box_get_active_iter(GTK_COMBO_BOX(P(self)->searchmode_combo), &iter);
 
160
        gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(P(self)->searchmode_combo)), &iter,
 
161
                           MODE_COL_MODE, &mode,
 
162
                           -1);
 
163
 
 
164
        return mode;
 
165
}
 
166
 
 
167
static void
 
168
tab_search_set_mode(GqTabSearch* self,
 
169
                    GqSearchMode mode)
 
170
{
 
171
        GtkTreeModel* model;
 
172
        GtkComboBox*  combo;
 
173
        GtkTreeIter   iter;
 
174
        GqSearchMode  mode2;
 
175
 
 
176
        combo = GTK_COMBO_BOX(P(self)->searchmode_combo);
 
177
        model = gtk_combo_box_get_model(combo);
 
178
        gtk_tree_model_iter_nth_child(model, &iter, NULL, mode);
 
179
        gtk_tree_model_get(model, &iter,
 
180
                           MODE_COL_MODE, &mode2,
 
181
                           -1);
 
182
 
 
183
        g_return_if_fail(mode == mode2);
 
184
 
 
185
        gtk_combo_box_set_active_iter(combo, &iter);
 
186
}
 
187
 
 
188
GqServer*
 
189
gq_tab_search_get_server(GqTabSearch const* self)
 
190
{
 
191
        GtkTreeIter   iter;
 
192
 
 
193
        g_return_val_if_fail(GQ_IS_TAB_SEARCH(self), NULL);
 
194
        g_return_val_if_fail(GTK_IS_COMBO_BOX(P(self)->serverlist_combo), NULL);
 
195
        g_return_val_if_fail(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(P(self)->serverlist_combo), &iter), NULL);
 
196
 
 
197
        return gq_server_model_get_server(GQ_SERVER_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(P(self)->serverlist_combo))), &iter);
 
198
}
 
199
 
 
200
void
 
201
gq_tab_search_set_server(GqTabSearch* self,
 
202
                         GqServer   * server)
 
203
{
 
204
        g_return_if_fail(GQ_IS_TAB_SEARCH(self));
 
205
        g_return_if_fail(!server || GQ_IS_SERVER(server));
 
206
 
 
207
#warning "FIXME: this connection could be better (so that the entry gets updated when the server gets renamed etc.)"
 
208
        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(self)->serverlist_combo)->entry),
 
209
                           gq_server_get_name(server));
 
210
 
 
211
#warning "FIXME: enable"
 
212
        //g_object_notify(G_OBJECT(self), "server");
 
213
}
 
214
 
 
215
static void
 
216
search_save_snapshot(int error_context G_GNUC_UNUSED,
 
217
                     char *state_name,
 
218
                     GqTab *tab)
 
219
{
 
220
        GtkTreeIter  iter;
 
221
        GqServer   * server;
 
222
        GList      * hist;
 
223
 
 
224
        hist = P(tab)->history;
 
225
        if (hist) {
 
226
                state_value_set_list(state_name, "history", hist);
 
227
        }
 
228
 
 
229
        state_value_set_list(state_name, "attributes", P(tab)->attrs);
 
230
        state_value_set_int(state_name, "chase", P(tab)->chase_ref);
 
231
        state_value_set_int(state_name, "max-depth", P(tab)->max_depth);
 
232
        state_value_set_int(state_name, "scope", P(tab)->scope);
 
233
        state_value_set_enum(state_name, "search-mode",
 
234
                             gq_tab_search_get_mode(GQ_TAB_SEARCH(tab)),
 
235
                             GQ_TYPE_SEARCH_MODE);
 
236
 
 
237
        state_value_set_int(state_name, "last-options-tab", P(tab)->last_options_tab);
 
238
 
 
239
        gtk_combo_box_get_active_iter(GTK_COMBO_BOX(P(tab)->serverlist_combo), &iter);
 
240
        server = gq_server_model_get_server(GQ_SERVER_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(P(tab)->serverlist_combo))),
 
241
                                            &iter);
 
242
        state_value_set_string(state_name, "lastserver", gq_server_get_name(server));
 
243
}
 
244
 
 
245
static void search_restore_snapshot(int error_context         G_GNUC_UNUSED,
 
246
                                    char *state_name,
 
247
                                    GqTab *tab,
 
248
                                    struct pbar_win *progress G_GNUC_UNUSED)
 
249
{
 
250
        GqSearchMode mode;
 
251
        GList*       searchhist;
 
252
        gchar const* lastserver;
 
253
 
 
254
        lastserver = state_value_get_string(state_name, "lastserver", NULL);
 
255
        if(lastserver && lastserver[0]) {
 
256
                GqServer* server = gq_server_list_get_by_name(gq_server_list_get(), lastserver);
 
257
                if(server) {
 
258
                        GtkTreeModel* model;
 
259
                        GtkTreeIter   iter;
 
260
                        model = gtk_combo_box_get_model(GTK_COMBO_BOX(P(tab)->serverlist_combo));
 
261
                        if(gq_server_model_get_iter(GQ_SERVER_MODEL(model), &iter, server)) {
 
262
                                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(P(tab)->serverlist_combo), &iter);
 
263
                        }
 
264
                }
 
265
        }
 
266
 
 
267
        mode = state_value_get_enum(state_name, "search-mode",
 
268
                                    GQ_SEARCH_MODE_BEGINS_WITH,
 
269
                                    GQ_TYPE_SEARCH_MODE);
 
270
        tab_search_set_mode(GQ_TAB_SEARCH(tab), mode);
142
271
 
143
272
     if (config->restore_search_history) {
144
273
          const GList *hist = state_value_get_list(state_name, "history");
145
274
          if (hist) {
146
275
               const GList *I;
147
276
 
148
 
               searchhist = GQ_TAB_SEARCH(tab)->history;
 
277
               searchhist = P(tab)->history;
149
278
               for (I = hist ; I ; I = g_list_next(I)) {
150
279
                    searchhist = g_list_append(searchhist, g_strdup(I->data));
151
280
               }
152
281
               searchhist = g_list_insert(searchhist, "", 0);
153
 
               gtk_combo_set_popdown_strings(GTK_COMBO(GQ_TAB_SEARCH(tab)->search_combo), searchhist);
 
282
               gtk_combo_set_popdown_strings(GTK_COMBO(P(tab)->search_combo), searchhist);
154
283
               searchhist = g_list_remove(searchhist, searchhist->data);
155
 
               GQ_TAB_SEARCH(tab)->history = searchhist;
 
284
               P(tab)->history = searchhist;
156
285
          }
157
286
 
158
287
          /* independently configurable? */
159
 
 
160
 
          GQ_TAB_SEARCH(tab)->chase_ref = 
161
 
               state_value_get_int(state_name, "chase", 1);
162
 
          GQ_TAB_SEARCH(tab)->max_depth = 
163
 
               state_value_get_int(state_name, "max-depth", 7);
164
 
          GQ_TAB_SEARCH(tab)->scope = 
165
 
               state_value_get_int(state_name, "scope", LDAP_SCOPE_SUBTREE);
166
 
 
167
 
          GQ_TAB_SEARCH(tab)->attrs = free_list_of_strings(GQ_TAB_SEARCH(tab)->attrs);
168
 
          GQ_TAB_SEARCH(tab)->attrs = 
 
288
          P(tab)->chase_ref = state_value_get_int(state_name, "chase", 1);
 
289
          P(tab)->max_depth = state_value_get_int(state_name, "max-depth", 7);
 
290
          P(tab)->scope = state_value_get_int(state_name, "scope", LDAP_SCOPE_SUBTREE);
 
291
 
 
292
          P(tab)->attrs = free_list_of_strings(P(tab)->attrs);
 
293
          P(tab)->attrs = 
169
294
               copy_list_of_strings(state_value_get_list(state_name,
170
295
                                                         "attributes"));
171
296
 
172
 
          GQ_TAB_SEARCH(tab)->last_options_tab =
173
 
               state_value_get_int(state_name, "last-options-tab", 0);
 
297
          P(tab)->last_options_tab = state_value_get_int(state_name, "last-options-tab", 0);
174
298
     }
175
299
}
176
300
 
177
301
static GtkWidget *current_search_options_window = NULL;
178
302
 
179
 
static void search_options_destroyed(GtkWidget *w)
 
303
static void
 
304
search_options_destroyed(void)
180
305
{
181
 
     current_search_options_window = NULL;  
 
306
        current_search_options_window = NULL;  
182
307
}
183
308
 
184
309
struct so_windata {
207
332
 
208
333
const char *lastoptions = "global.search.lastoptions";
209
334
 
210
 
static void so_okbutton_clicked(GtkWidget *w, struct so_windata *so)
 
335
static void
 
336
so_okbutton_clicked(struct so_windata *so)
211
337
{
212
338
     GqTab *tab = so->tab;
213
339
     GList *I;
214
340
 
215
341
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(so->chase_ref))) {
216
 
          GQ_TAB_SEARCH(tab)->chase_ref = 1;
 
342
          P(tab)->chase_ref = 1;
217
343
     } else {
218
 
          GQ_TAB_SEARCH(tab)->chase_ref = 0;
 
344
          P(tab)->chase_ref = 0;
219
345
     }
220
346
 
221
 
     GQ_TAB_SEARCH(tab)->max_depth =
 
347
     P(tab)->max_depth =
222
348
          gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(so->max));
223
349
 
224
350
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(so->onelevel))) {
225
 
          GQ_TAB_SEARCH(tab)->scope = LDAP_SCOPE_ONELEVEL;
 
351
          P(tab)->scope = LDAP_SCOPE_ONELEVEL;
226
352
     } else {
227
 
          GQ_TAB_SEARCH(tab)->scope = LDAP_SCOPE_SUBTREE;
 
353
          P(tab)->scope = LDAP_SCOPE_SUBTREE;
228
354
     }
229
355
 
230
 
     GQ_TAB_SEARCH(tab)->attrs = free_list_of_strings(GQ_TAB_SEARCH(tab)->attrs);
 
356
     P(tab)->attrs = free_list_of_strings(P(tab)->attrs);
231
357
 
232
358
     for( I = GTK_CLIST(so->list)->selection ; I ; I = g_list_next(I) ) {
233
359
          int row = GPOINTER_TO_INT(I->data);
235
361
 
236
362
          gtk_clist_get_text(GTK_CLIST(so->list), row, 0, &t);
237
363
 
238
 
          GQ_TAB_SEARCH(tab)->attrs = g_list_append(GQ_TAB_SEARCH(tab)->attrs,
 
364
          P(tab)->attrs = g_list_append(P(tab)->attrs,
239
365
                                                g_strdup(t));
240
366
     }
241
367
 
242
 
     GQ_TAB_SEARCH(tab)->last_options_tab = 
243
 
          gtk_notebook_get_current_page(GTK_NOTEBOOK(so->notebook));
244
 
 
245
 
     state_value_set_int(lastoptions, "chase", GQ_TAB_SEARCH(tab)->chase_ref);
246
 
     state_value_set_int(lastoptions, "max-depth", GQ_TAB_SEARCH(tab)->max_depth);
247
 
     state_value_set_int(lastoptions, "scope", GQ_TAB_SEARCH(tab)->scope);
248
 
     state_value_set_list(lastoptions, "attributes", GQ_TAB_SEARCH(tab)->attrs);
249
 
 
250
 
     state_value_set_int(lastoptions, "last-options-tab", 
251
 
                         GQ_TAB_SEARCH(tab)->last_options_tab);
 
368
     P(tab)->last_options_tab = gtk_notebook_get_current_page(GTK_NOTEBOOK(so->notebook));
 
369
 
 
370
     state_value_set_int(lastoptions, "chase", P(tab)->chase_ref);
 
371
     state_value_set_int(lastoptions, "max-depth", P(tab)->max_depth);
 
372
     state_value_set_int(lastoptions, "scope", P(tab)->scope);
 
373
     state_value_set_list(lastoptions, "attributes", P(tab)->attrs);
 
374
 
 
375
     state_value_set_int(lastoptions, "last-options-tab", P(tab)->last_options_tab);
252
376
 
253
377
     gtk_widget_destroy(so->win);
254
378
}
255
379
 
256
 
static void so_attrs_clear_clicked(GtkWidget *w, struct so_windata *so) 
 
380
static void
 
381
so_attrs_clear_clicked(struct so_windata *so) 
257
382
{
258
383
     gtk_clist_unselect_all( GTK_CLIST(so->list));
259
384
}
264
389
     LDAPObjectClass *oc;
265
390
};
266
391
 
267
 
static void so_select_by_oc(GtkWidget *w,
268
 
                            struct so_select_by_oc_cb_data *cbd) 
 
392
static void
 
393
so_select_by_oc(struct so_select_by_oc_cb_data *cbd) 
269
394
{
270
395
     int i, j;
271
396
     g_assert(cbd);
347
472
          gtk_menu_append(GTK_MENU(menu), menu_item);
348
473
          gtk_widget_show(menu_item);
349
474
 
350
 
          g_signal_connect(menu_item, "activate",
 
475
          g_signal_connect_swapped(menu_item, "activate",
351
476
                             G_CALLBACK(so_attrs_clear_clicked),
352
477
                             so);
353
478
 
383
508
                                                       cbd,
384
509
                                                       (GtkDestroyNotify)g_free);
385
510
                              gtk_menu_append(GTK_MENU(submenu), menu_item);
386
 
                              g_signal_connect(menu_item, "activate",
 
511
                              g_signal_connect_swapped(menu_item, "activate",
387
512
                                                 G_CALLBACK(so_select_by_oc),
388
513
                                                 cbd);
389
514
                              gtk_widget_show(menu_item);
432
557
     g_assert(tab);
433
558
 
434
559
     if(current_search_options_window) {
435
 
          gdk_beep(); /* Is this OK, philosophically? */
436
560
          gtk_window_present(GTK_WINDOW(current_search_options_window));
437
561
          return;
438
562
     }
456
580
     so->win = window;
457
581
 
458
582
     g_signal_connect(window, "destroy",
459
 
                        G_CALLBACK(search_options_destroyed), so);
 
583
                        G_CALLBACK(search_options_destroyed), NULL);
460
584
     g_signal_connect(window, "key_press_event",
461
585
                        G_CALLBACK(close_on_esc),
462
586
                        window);
530
654
                      0, 0);
531
655
     gtk_widget_show(label);
532
656
 
533
 
     entry = gtk_spin_button_new(GTK_ADJUSTMENT(gtk_adjustment_new(GQ_TAB_SEARCH(tab)->max_depth,
 
657
     entry = gtk_spin_button_new(GTK_ADJUSTMENT(gtk_adjustment_new(P(tab)->max_depth,
534
658
                                                                   0.0, 999.0,
535
659
                                                                   1.0, 5.0,
536
660
                                                                   1.0)),
538
662
     so->max = entry;
539
663
 
540
664
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_chase), 
541
 
                                  GQ_TAB_SEARCH(tab)->chase_ref);
 
665
                                  P(tab)->chase_ref);
542
666
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_show),
543
 
                                  !(GQ_TAB_SEARCH(tab)->chase_ref));
 
667
                                  !P(tab)->chase_ref);
544
668
 
545
669
     gtk_table_attach(GTK_TABLE(table), entry,
546
670
                      1, 2, 
565
689
     so->onelevel = radio;
566
690
 
567
691
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio),
568
 
                                  GQ_TAB_SEARCH(tab)->scope == LDAP_SCOPE_ONELEVEL
569
 
                                  );
 
692
                                  P(tab)->scope == LDAP_SCOPE_ONELEVEL);
570
693
 
571
694
/*      gtk_box_pack_start(GTK_BOX(vbox2), radio, TRUE, TRUE, 0); */
572
695
     gtk_table_attach(GTK_TABLE(table), radio,
581
704
     so->subtree = radio;
582
705
 
583
706
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio),
584
 
                                  GQ_TAB_SEARCH(tab)->scope != LDAP_SCOPE_ONELEVEL
585
 
                                  );
 
707
                                  P(tab)->scope != LDAP_SCOPE_ONELEVEL);
586
708
 
587
709
/*      gtk_box_pack_start(GTK_BOX(vbox2), radio, TRUE, TRUE, 0); */
588
710
     gtk_table_attach(GTK_TABLE(table), radio,
638
760
          GqServer *server;
639
761
          char *cur_servername;
640
762
          int opt;
641
 
          GtkWidget *servcombo = GQ_TAB_SEARCH(tab)->serverlist_combo;
642
763
 
643
 
          cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry), 0, -1);
 
764
          cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(P(tab)->serverlist_combo)->entry), 0, -1);
644
765
          server = gq_server_list_get_by_name(gq_server_list_get(), cur_servername);
645
766
          g_free(cur_servername);
646
767
 
667
788
                         for(i = 0; at->at_names[i]; i++) {
668
789
                              t[0] = (char*) at->at_names[i];
669
790
                              row = gtk_clist_append(GTK_CLIST(list), t);
670
 
                              if (g_list_find_custom(GQ_TAB_SEARCH(tab)->attrs,
 
791
                              if (g_list_find_custom(P(tab)->attrs,
671
792
                                                     t[0], 
672
793
                                                     (GCompareFunc) strcasecmp)) { /*UTF-8?*/
673
 
                                   gtk_clist_select_row(GTK_CLIST(list), 
674
 
                                                        row, 0);
 
794
                                   gtk_clist_select_row(GTK_CLIST(list), row, 0);
675
795
                              }
676
796
                         }
677
797
                    }
688
808
 
689
809
     gtk_box_pack_end(GTK_BOX(vbox0), bbox, FALSE, FALSE, 0);
690
810
 
691
 
     button = gtk_button_new_from_stock(GTK_STOCK_OK);
 
811
     button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
692
812
     gtk_widget_show(button);
693
 
     g_signal_connect(button, "clicked",
 
813
     g_signal_connect_swapped(button, "clicked",
694
814
                        G_CALLBACK(so_okbutton_clicked),
695
815
                        so);
696
816
     gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, TRUE, 10);
705
825
 
706
826
     gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, TRUE, 10);
707
827
 
708
 
     gtk_notebook_set_page(GTK_NOTEBOOK(notebook),
709
 
                           GQ_TAB_SEARCH(tab)->last_options_tab);
 
828
     gtk_notebook_set_page(GTK_NOTEBOOK(notebook), P(tab)->last_options_tab);
710
829
 
711
830
     gtk_widget_show(window);
712
831
}
718
837
     create_search_options_window(tab);
719
838
}
720
839
 
721
 
 
722
 
GqTab *new_searchmode()
723
 
{
724
 
     GtkWidget *main_clist, *searchmode_vbox, *hbox1, *scrwin;
725
 
     GtkWidget *searchcombo, *servcombo, *searchbase_combo;
726
 
     GtkWidget *findbutton, *optbutton;
727
 
     GList *searchhist;
728
 
     GqTabSearch *modeinfo;
729
 
     GqTab *tab = g_object_new(GQ_TYPE_TAB_SEARCH, NULL);
730
 
     const GList *last_attr;
731
 
 
732
 
     tab->type = SEARCH_MODE;
733
 
 
734
 
     modeinfo = GQ_TAB_SEARCH(tab);
735
 
 
736
 
     modeinfo->scope     = state_value_get_int(lastoptions, "scope",
737
 
                                               LDAP_SCOPE_SUBTREE);
738
 
     modeinfo->chase_ref = state_value_get_int(lastoptions, "chase", 1);
739
 
     modeinfo->max_depth = state_value_get_int(lastoptions, "max-depth", 7);
740
 
     modeinfo->last_options_tab =
741
 
          state_value_get_int(lastoptions, "last-options-tab", 0);
742
 
 
743
 
     /* copy attribute list */
744
 
     last_attr = state_value_get_list(lastoptions, "attributes");
745
 
 
746
 
     modeinfo->attrs = free_list_of_strings(modeinfo->attrs);
747
 
     modeinfo->attrs = copy_list_of_strings(last_attr);
748
 
 
749
 
     /* setup widgets */
750
 
 
751
 
     searchmode_vbox = gtk_vbox_new(FALSE, 0);
752
 
     hbox1 = gtk_hbox_new(FALSE, 0);
753
 
     gtk_widget_show(hbox1);
754
 
     gtk_box_pack_start(GTK_BOX(searchmode_vbox), hbox1, FALSE, FALSE, 3);
755
 
 
756
 
     /* Initially the list is empty. It might be changed to the data
757
 
        read from the persistant storage later on*/
758
 
     searchhist = modeinfo->history;
759
 
 
760
 
     /* searchterm combo box */
761
 
     GQ_TAB_SEARCH(tab)->search_combo = searchcombo = gtk_combo_new();
762
 
     gtk_combo_disable_activate(GTK_COMBO(searchcombo));
763
 
     if(searchhist)
764
 
          gtk_combo_set_popdown_strings(GTK_COMBO(searchcombo), searchhist);
765
 
     gtk_widget_show(searchcombo);
766
 
     GTK_WIDGET_SET_FLAGS(GTK_COMBO(searchcombo)->entry, GTK_CAN_FOCUS);
767
 
     GTK_WIDGET_SET_FLAGS(GTK_COMBO(searchcombo)->entry, GTK_RECEIVES_DEFAULT);
768
 
     gtk_box_pack_start(GTK_BOX(hbox1), searchcombo,
769
 
                        TRUE, TRUE, SEARCHBOX_PADDING);
770
 
     g_signal_connect_swapped(GTK_COMBO(searchcombo)->entry, "activate",
771
 
                               G_CALLBACK(findbutton_clicked_callback),
772
 
                               tab);
773
 
     tab->focus = GTK_COMBO(searchcombo)->entry;
774
 
 
775
 
     /* LDAP server combo box */
776
 
     servcombo = gtk_combo_new();
777
 
     fill_serverlist_combo(servcombo);
778
 
     gtk_box_pack_start(GTK_BOX(hbox1), servcombo,
779
 
                        FALSE, TRUE, SEARCHBOX_PADDING);
780
 
     gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(servcombo)->entry), FALSE);
781
 
     g_signal_connect_swapped(GTK_COMBO(servcombo)->entry, "changed",
782
 
                               G_CALLBACK(servername_changed_callback),
783
 
                               tab);
784
 
#ifdef OLD_FOCUS_HANDLING
785
 
     GTK_WIDGET_UNSET_FLAGS(GTK_ENTRY(GTK_COMBO(servcombo)->entry), GTK_CAN_FOCUS);
786
 
     GTK_WIDGET_UNSET_FLAGS(GTK_BUTTON(GTK_COMBO(servcombo)->button), GTK_CAN_FOCUS);
787
 
#endif
788
 
     gtk_widget_show(servcombo);
789
 
     modeinfo->serverlist_combo = servcombo;
790
 
 
791
 
     /* search base combo box */
792
 
     searchbase_combo = gtk_combo_new();
793
 
 
794
 
     if(gq_server_list_n_servers(gq_server_list_get())) {
795
 
          gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(searchbase_combo)->entry),
796
 
                             gq_server_list_get_server(gq_server_list_get(), 0)->basedn);
797
 
     }
798
 
 
799
 
     gtk_box_pack_start(GTK_BOX(hbox1), searchbase_combo,
800
 
                        FALSE, TRUE, SEARCHBOX_PADDING);
801
 
     g_signal_connect(GTK_COMBO(searchbase_combo)->button, "button_press_event",
802
 
                        G_CALLBACK(searchbase_button_clicked), tab);
803
 
#ifdef OLD_FOCUS_HANDLING
804
 
     GTK_WIDGET_UNSET_FLAGS(GTK_ENTRY(GTK_COMBO(searchbase_combo)->entry), GTK_CAN_FOCUS);
805
 
     GTK_WIDGET_UNSET_FLAGS(GTK_BUTTON(GTK_COMBO(searchbase_combo)->button), GTK_CAN_FOCUS);
806
 
#endif
807
 
     gtk_widget_show(searchbase_combo);
808
 
     modeinfo->searchbase_combo = searchbase_combo;
809
 
 
810
 
     /* find button */
811
 
     findbutton = gq_button_new_with_label(_("_Find"));
812
 
#ifdef OLD_FOCUS_HANDLING
813
 
     GTK_WIDGET_UNSET_FLAGS(findbutton, GTK_CAN_FOCUS);
814
 
#endif
815
 
     gtk_widget_show(findbutton);
816
 
     gtk_box_pack_start(GTK_BOX(hbox1), findbutton, 
817
 
                        FALSE, TRUE, SEARCHBOX_PADDING);
818
 
     gtk_container_border_width(GTK_CONTAINER (findbutton), 0);
819
 
     g_signal_connect_swapped(findbutton, "clicked",
820
 
                               G_CALLBACK(findbutton_clicked_callback),
821
 
                               tab);
822
 
 
823
 
     /* Options button */
824
 
     optbutton = gq_button_new_with_label(_("_Options"));
825
 
#ifdef OLD_FOCUS_HANDLING
826
 
     GTK_WIDGET_UNSET_FLAGS(optbutton, GTK_CAN_FOCUS);
827
 
#endif
828
 
     gtk_widget_show(optbutton);
829
 
     gtk_box_pack_start(GTK_BOX(hbox1), optbutton,
830
 
                        FALSE, TRUE, SEARCHBOX_PADDING);
831
 
     gtk_container_border_width(GTK_CONTAINER (optbutton), 0);
832
 
     g_signal_connect_swapped(optbutton, "clicked",
833
 
                               G_CALLBACK(optbutton_clicked_callback),
834
 
                               tab);
835
 
 
836
 
 
837
 
     /* dummy clist, gets replaced on first search */
838
 
     scrwin = gtk_scrolled_window_new(NULL, NULL);
839
 
     gtk_widget_show(scrwin);
840
 
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
841
 
                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
842
 
     main_clist = gtk_clist_new(1);
843
 
     gtk_clist_set_selection_mode(GTK_CLIST(main_clist),
844
 
                                  GTK_SELECTION_EXTENDED);
845
 
     gtk_clist_set_column_title(GTK_CLIST(main_clist), 0, "");
846
 
     gtk_clist_column_titles_show(GTK_CLIST(main_clist));
847
 
     gtk_widget_show(main_clist);
848
 
     gtk_clist_column_titles_passive(GTK_CLIST(main_clist));
849
 
     modeinfo->main_clist = main_clist;
850
 
 
851
 
     gtk_container_add(GTK_CONTAINER(scrwin), main_clist);
852
 
     gtk_box_pack_start(GTK_BOX(searchmode_vbox), scrwin, TRUE, TRUE, 0);
853
 
 
854
 
     gtk_widget_show(searchmode_vbox);
855
 
 
856
 
     g_signal_connect_swapped(searchmode_vbox, "destroy",
857
 
                              G_CALLBACK(g_object_unref), tab);
858
 
 
859
 
     tab->content = searchmode_vbox;
860
 
     gtk_object_set_data(GTK_OBJECT(tab->content), "tab", tab);
861
 
     return tab;
862
 
}
863
 
 
864
 
 
865
 
static void servername_changed_callback(GqTab *tab)
 
840
static void
 
841
set_selected(GtkTreeModel* model,
 
842
             GtkTreePath * path G_GNUC_UNUSED,
 
843
             GtkTreeIter * iter,
 
844
             gpointer      search_tab)
 
845
{
 
846
        GqServerDn* sdn = NULL;
 
847
        gtk_tree_model_get(model, iter,
 
848
                           RES_COL_DN, &sdn,
 
849
                           -1);
 
850
        g_object_set_data_full(search_tab,
 
851
                               "selected-entry",
 
852
                               g_object_ref(sdn),
 
853
                               g_object_unref);
 
854
}
 
855
 
 
856
static void
 
857
results_selection_changed(GtkTreeSelection* selection,
 
858
                          GqTabSearch     * self)
 
859
{
 
860
        GqServerDn* entry = NULL;
 
861
 
 
862
        switch(gtk_tree_selection_count_selected_rows(selection)) {
 
863
        case 1:
 
864
                gtk_tree_selection_selected_foreach(selection, set_selected, self);
 
865
                entry = g_object_get_data(G_OBJECT(self), "selected-entry");
 
866
                break;
 
867
        default:
 
868
                break;
 
869
        }
 
870
        gq_input_form_set_entry(GQ_INPUT_FORM(P(self)->results_display), entry);
 
871
        g_object_set_data(G_OBJECT(self), "selected-entry", NULL);
 
872
}
 
873
 
 
874
static gboolean
 
875
results_button_pressed(GtkWidget     * treeview,
 
876
                       GdkEventButton* event,
 
877
                       GqTabSearch   * self)
 
878
{
 
879
        if(event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
 
880
                search_edit_entry_callback(self);
 
881
 
 
882
                return TRUE;
 
883
        }
 
884
        else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
 
885
                GtkTreeView* view = GTK_TREE_VIEW(treeview);
 
886
                GtkTreePath* path = NULL;
 
887
                GqServerDn * set  = NULL;
 
888
 
 
889
                if(gtk_tree_view_get_path_at_pos(view, event->x, event->y,
 
890
                                                 &path, NULL, NULL, NULL))
 
891
                {
 
892
                        GtkTreeModel* model = gtk_tree_view_get_model(view);
 
893
                        GtkTreeIter iter;
 
894
                        gtk_tree_model_get_iter(model, &iter, path);
 
895
                        gtk_tree_model_get(model, &iter,
 
896
                                           RES_COL_DN, &set,
 
897
                                           -1);
 
898
                        gtk_tree_path_free(path);
 
899
                        path = NULL;
 
900
 
 
901
                        results_popup_menu(self, event, set);
 
902
 
 
903
                        return TRUE;
 
904
                }
 
905
        }
 
906
 
 
907
        return FALSE;
 
908
}
 
909
 
 
910
GqTab*
 
911
gq_tab_search_new(void)
 
912
{
 
913
        return g_object_new(GQ_TYPE_TAB_SEARCH, NULL);
 
914
}
 
915
 
 
916
 
 
917
static void
 
918
servername_changed_callback(GqTab *tab)
866
919
{
867
920
     GList *searchbase_list;
868
 
     GtkWidget *servcombo, *searchbase_combo;
869
 
     GqServer *cur_server;
870
 
     char *cur_servername;
871
 
 
872
 
     servcombo = GQ_TAB_SEARCH(tab)->serverlist_combo;
873
 
     cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry), 0, -1);
874
 
     cur_server = gq_server_list_get_by_name(gq_server_list_get(), cur_servername);
875
 
     g_free(cur_servername);
876
 
 
877
 
     /* make sure searchbase gets refreshed next time the searchbase combo button is
878
 
        pressed. Just insert the server's default base DN for now */
879
 
     GQ_TAB_SEARCH(tab)->populated_searchbase = 0;
880
 
     searchbase_combo = GQ_TAB_SEARCH(tab)->searchbase_combo;
881
 
     if (cur_server) {
882
 
          gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(searchbase_combo)->entry), cur_server->basedn);
883
 
          searchbase_list = g_list_append(NULL, cur_server->basedn);
884
 
          gtk_combo_set_popdown_strings(GTK_COMBO(searchbase_combo), searchbase_list);
885
 
          g_list_free(searchbase_list);
886
 
     }
887
 
 
 
921
        GqServer *server;
 
922
        GtkTreeIter iter;
 
923
 
 
924
        if(!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(P(tab)->serverlist_combo), &iter)) {
 
925
                // no selection
 
926
                return;
 
927
        }
 
928
        server = gq_server_model_get_server(GQ_SERVER_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(P(tab)->serverlist_combo))),
 
929
                                            &iter);
 
930
 
 
931
        /* make sure searchbase gets refreshed next time the searchbase combo button is
 
932
           pressed. Just insert the server's default base DN for now */
 
933
        P(tab)->populated_searchbase = 0;
 
934
        if (server) {
 
935
                gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(tab)->searchbase_combo)->entry), server->basedn);
 
936
                searchbase_list = g_list_append(NULL, server->basedn);
 
937
                gtk_combo_set_popdown_strings(GTK_COMBO(P(tab)->searchbase_combo), searchbase_list);
 
938
                g_list_free(searchbase_list);
 
939
        }
888
940
}
889
941
 
890
942
 
891
 
static gint searchbase_button_clicked(GtkWidget *widget, 
 
943
static gint searchbase_button_clicked(GtkWidget *widget,
892
944
                                      GdkEventButton *event, GqTab *tab)
893
945
{
894
946
     GList *searchbase_list;
895
947
     GList *suffixes_list, *temp;
896
 
     GtkWidget *servcombo, *searchbase_combo;
897
948
     GqServer *server;
898
949
     int found_default_searchbase;
899
950
     char *cur_servername;
901
952
 
902
953
     found_default_searchbase = 0;
903
954
 
904
 
     if (!GQ_TAB_SEARCH(tab)->populated_searchbase && event->button == 1) {
905
 
          servcombo = GQ_TAB_SEARCH(tab)->serverlist_combo;
906
 
          cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry), 0, -1);
 
955
        if(!P(tab)->populated_searchbase && event->button == 1) {
 
956
          cur_servername = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(P(tab)->serverlist_combo)->entry), 0, -1);
907
957
          server = gq_server_list_get_by_name(gq_server_list_get(), cur_servername);
908
958
          g_free(cur_servername);
909
959
          if (!server)
926
976
          if (found_default_searchbase == 0)
927
977
               searchbase_list = g_list_prepend(searchbase_list, server->basedn);
928
978
 
929
 
          searchbase_combo = GQ_TAB_SEARCH(tab)->searchbase_combo;
930
 
          gtk_combo_set_popdown_strings(GTK_COMBO(searchbase_combo), searchbase_list);
 
979
          gtk_combo_set_popdown_strings(GTK_COMBO(P(tab)->searchbase_combo), searchbase_list);
931
980
 
932
981
          temp = suffixes_list;
933
982
          while (temp) {
938
987
               g_list_free(suffixes_list);
939
988
          g_list_free(searchbase_list);
940
989
 
941
 
          GQ_TAB_SEARCH(tab)->populated_searchbase = 1;
 
990
          P(tab)->populated_searchbase = 1;
942
991
 
943
992
          error_flush(error_context);
944
 
     }
 
993
        }
945
994
 
946
995
     return FALSE;
947
996
}
1031
1080
}
1032
1081
 
1033
1082
 
1034
 
char *make_filter(GqServer *server, char *querystring)
 
1083
char*
 
1084
make_filter(GqServer const* server,
 
1085
            gchar const*    querystring,
 
1086
            GqSearchMode    mode)
1035
1087
{
1036
1088
     char *filter = NULL;
1037
 
     int l = strlen(querystring);
1038
1089
 
1039
 
     if(querystring[0] == '(') {  /* UTF-8 OK */
 
1090
     if(*querystring == '(') {
1040
1091
          filter = g_strdup(querystring);
1041
1092
     }
1042
1093
     else if(g_utf8_strchr(querystring, -1, '=')) {
1043
 
          l += 3;
1044
 
          filter = g_malloc(l);
1045
 
          g_snprintf(filter, l, "(%s)", querystring);
 
1094
          filter = g_strdup_printf("(%s)", querystring);
1046
1095
     }
1047
1096
     else {
1048
 
          int sl = strlen(server->searchattr);
1049
 
          l += sl + 10;
1050
 
          filter = g_malloc(l + 1);
 
1097
                gchar const* format = NULL;
 
1098
                gchar const* attribute = NULL;
1051
1099
 
1052
 
          switch(config->search_argument) {
1053
 
          case SEARCHARG_BEGINS_WITH:
1054
 
               g_snprintf(filter, l, "(%s=%s*)", server->searchattr, querystring);
1055
 
               break;
1056
 
          case SEARCHARG_ENDS_WITH:
1057
 
               g_snprintf(filter, l, "(%s=*%s)", server->searchattr, querystring);
1058
 
               break;
1059
 
          case SEARCHARG_CONTAINS:
1060
 
               g_snprintf(filter, l, "(%s=*%s*)", server->searchattr, querystring);
1061
 
               break;
1062
 
          case SEARCHARG_EQUALS:
1063
 
               g_snprintf(filter, l, "(%s=%s)", server->searchattr, querystring);
 
1100
          switch(mode) {
 
1101
          case GQ_SEARCH_MODE_BEGINS_WITH:
 
1102
               format = "(%s=%s*)";
 
1103
               break;
 
1104
          case GQ_SEARCH_MODE_ENDS_WITH:
 
1105
               format = "(%s=*%s)";
 
1106
               break;
 
1107
          case GQ_SEARCH_MODE_CONTAINS:
 
1108
               format = "(%s=*%s*)";
 
1109
               break;
 
1110
          case GQ_SEARCH_MODE_EQUALS:
 
1111
               format = "(%s=%s)";
1064
1112
               break;
1065
1113
          default:
1066
 
               filter[0] = 0;
1067
 
               break;
 
1114
               g_assert_not_reached();
 
1115
               return NULL;
1068
1116
          };
 
1117
 
 
1118
                attribute = gq_server_get_search_attribute(server);
 
1119
 
 
1120
                if(!attribute) {
 
1121
#warning "FIXME: log this into the status bar"
 
1122
                        g_message(_("The server doesn't have a search attribute set. Using the default one (cn) now. "));
 
1123
                        attribute = "cn";
 
1124
                }
 
1125
                filter = g_strdup_printf(format, attribute, querystring);
1069
1126
     }
1070
1127
 
1071
 
     return(filter);
 
1128
     return filter;
1072
1129
}
1073
1130
 
1074
1131
 
1075
1132
static void add_to_search_history(GqTab *tab)
1076
1133
{
1077
1134
     gchar *searchterm;
1078
 
     GList *list, *last, *item;
 
1135
     GList *last, *item;
1079
1136
 
1080
 
     list = GQ_TAB_SEARCH(tab)->history;
1081
1137
     searchterm = gtk_editable_get_chars(GTK_EDITABLE(tab->focus), 0, -1);
1082
 
     if(list && !strcmp(list->data, searchterm)) {
 
1138
     if(P(tab)->history && !strcmp(P(tab)->history->data, searchterm)) {
1083
1139
          g_free(searchterm);
1084
1140
     }
1085
1141
     else {
1086
1142
          /* if this searchterm is already in history, delete it first */
1087
 
          item = g_list_find_custom(list, searchterm, (GCompareFunc) strcasecmp);
 
1143
          item = g_list_find_custom(P(tab)->history, searchterm, (GCompareFunc) strcasecmp);
1088
1144
          if(item) {
1089
1145
               g_free(item->data);
1090
 
               list = g_list_remove(list, item->data);
 
1146
               P(tab)->history = g_list_remove(P(tab)->history, item->data);
1091
1147
          }
1092
1148
 
1093
 
          list = g_list_insert(list, searchterm, 0);
1094
 
          if(g_list_length(list) > MAX_SEARCH_HISTORY_LENGTH) {
1095
 
               last = g_list_last(list);
 
1149
          P(tab)->history = g_list_insert(P(tab)->history, searchterm, 0);
 
1150
          if(g_list_length(P(tab)->history) > MAX_SEARCH_HISTORY_LENGTH) {
 
1151
               last = g_list_last(P(tab)->history);
1096
1152
               g_free(last->data);
1097
 
               list = g_list_remove(list, last->data);
 
1153
               P(tab)->history = g_list_remove(P(tab)->history, last->data);
1098
1154
          }
1099
 
          GQ_TAB_SEARCH(tab)->history = list;
1100
 
          gtk_combo_set_popdown_strings(GTK_COMBO(tab->focus->parent), list);
 
1155
          gtk_combo_set_popdown_strings(GTK_COMBO(tab->focus->parent), P(tab)->history);
1101
1156
     }
1102
1157
 
1103
1158
}
1104
1159
 
1105
 
static int fill_one_row(int query_context,
1106
 
                        GqServer *server,
1107
 
                        LDAP *ld, LDAPMessage *e,
1108
 
                        GtkWidget *clist,
1109
 
                        GString **tolist,
1110
 
                        int *columns_done,
1111
 
                        struct attrs *attrlist,
1112
 
                        GqTab *tab)
 
1160
static void
 
1161
fill_one_row(int           query_context G_GNUC_UNUSED,
 
1162
             GqServer    * server,
 
1163
             LDAP        * ld,
 
1164
             LDAPMessage * e,
 
1165
             GString     **tolist,
 
1166
             int         * columns_done  G_GNUC_UNUSED,
 
1167
             struct attrs* attrlist      G_GNUC_UNUSED, // may we'll need it again
 
1168
             GqTabSearch * self)
1113
1169
{
1114
 
     BerElement *berptr;
 
1170
        GtkTreeIter iter;
1115
1171
     int i;
1116
1172
     gchar *cl[MAX_NUM_ATTRIBUTES];
1117
 
     int cur_col;
1118
 
     int row;
1119
 
     char *dn, *attr, **vals;
1120
 
     struct dn_on_server *set;
 
1173
     char *dn, *attr G_GNUC_UNUSED, **vals G_GNUC_UNUSED;
 
1174
     GqServerDn *set;
1121
1175
 
1122
1176
     /* not every attribute necessarily comes back for
1123
1177
      * every entry, so clear this every time */
1125
1179
          cl[i] = NULL;
1126
1180
          g_string_truncate(tolist[i], 0);
1127
1181
     }
1128
 
     
 
1182
 
1129
1183
     dn = ldap_get_dn(ld, e);
1130
1184
     /* store for later reference */
1131
 
     set = new_dn_on_server(dn, server);
 
1185
     set = gq_server_dn_new(dn, server);
1132
1186
 
 
1187
#warning "FIXME: use this to find the matching attribute"
 
1188
#if 0
1133
1189
     if(config->showdn) {
1134
1190
          g_string_append(tolist[0], dn);
1135
1191
          cl[0] = tolist[0]->str;
1136
1192
     }
1137
 
#if defined(HAVE_LDAP_MEMFREE)
1138
1193
     ldap_memfree(dn);
1139
 
#else
1140
 
     free(dn);
1141
 
#endif
1142
 
     
 
1194
 
1143
1195
     for(attr = ldap_first_attribute(ld, e, &berptr); attr != NULL;
1144
1196
         attr = ldap_next_attribute(ld, e, berptr)) {
1145
1197
          if (!show_in_search(query_context, server, attr)) {
1146
1198
               ldap_memfree(attr);
1147
1199
               continue;
1148
1200
          }
1149
 
          
 
1201
 
1150
1202
          /* This should now work for ;binary as well */
1151
1203
          cur_col = column_by_attr(&attrlist, attr);
1152
1204
          if(cur_col == MAX_NUM_ATTRIBUTES) {
1159
1211
               gtk_clist_set_column_title(GTK_CLIST(clist), cur_col, c);
1160
1212
               /* setting the width somehow causes my gtk2 to not show
1161
1213
                  the title correctly - BUG */
1162
 
/*             gtk_clist_set_column_width(GTK_CLIST(clist), cur_col, 120); */
 
1214
/*             gtk_clist_set_column_width(GTK_CLIST(clist), cur_col, 120); */
1163
1215
               gtk_clist_set_column_resizeable(GTK_CLIST(clist), cur_col,
1164
1216
                                               TRUE);
1165
1217
               if (c) g_free(c);
1166
1218
               columns_done[cur_col] = 1;
1167
1219
          }
1168
 
          
 
1220
 
1169
1221
          vals = ldap_get_values(ld, e, attr);
1170
1222
          if(vals) {
1171
1223
               for(i = 0; vals[i] != NULL; i++) {
1201
1253
               break;
1202
1254
          }
1203
1255
     }
1204
 
     
1205
 
     /* insert row into result window */
1206
 
     row = gtk_clist_append(GTK_CLIST(clist), cl);
1207
 
     gtk_clist_set_row_data_full(GTK_CLIST(clist), row, set, 
1208
 
                                 (GtkDestroyNotify) free_dn_on_server);
1209
 
 
1210
 
     gtk_clist_column_titles_show(GTK_CLIST(clist));
1211
 
 
1212
 
     return row;
 
1256
#endif
 
1257
 
 
1258
        /* insert row into result model */
 
1259
        gtk_list_store_append(P(self)->results_liststore, &iter);
 
1260
        gtk_list_store_set(P(self)->results_liststore, &iter,
 
1261
                           RES_COL_NAME, gq_server_dn_get_dn(set),
 
1262
                           RES_COL_DN,   set,
 
1263
                           -1);
1213
1264
}
1214
1265
 
1215
1266
 
1243
1294
}
1244
1295
 
1245
1296
 
1246
 
static void add_referral(int error_context, 
1247
 
                         GqServer *server, 
1248
 
                         const char *referral, GList **nextlevel) 
 
1297
static void add_referral(int error_context,
 
1298
                         GqServer *server,
 
1299
                         const char *referral, GList **nextlevel)
1249
1300
{
1250
1301
     LDAPURLDesc *desc = NULL;
1251
1302
 
1252
1303
     if (ldap_url_parse(referral, &desc) == 0) {
1253
 
/*        GString *new_uri = g_string_sized_new(strlen(referral)); */
 
1304
/*        GString *new_uri = g_string_sized_new(strlen(referral)); */
1254
1305
          GqServer *newserver;
1255
1306
 
1256
1307
          newserver = get_referral_server(error_context, server, referral);
1257
1308
 
1258
 
/*        g_string_sprintf(new_uri, "%s://%s:%d/",  */
1259
 
/*                         desc->lud_scheme, */
1260
 
/*                         desc->lud_host, */
1261
 
/*                         desc->lud_port); */
1262
 
 
1263
 
/*        newserver = new_ldapserver(); */
1264
 
 
1265
 
/*        /\* some sensible settings for the "usual" case: */
1266
 
/*           Anonymous bind. Also show referrals *\/ */
1267
 
/*        newserver->ask_pw   = 0; */
1268
 
/*        newserver->show_ref = 1; */
 
1309
/*        g_string_sprintf(new_uri, "%s://%s:%d/",  */
 
1310
/*                         desc->lud_scheme, */
 
1311
/*                         desc->lud_host, */
 
1312
/*                         desc->lud_port); */
 
1313
 
 
1314
/*        newserver = new_ldapserver(); */
 
1315
 
 
1316
/*        /\* some sensible settings for the "usual" case: */
 
1317
/*           Anonymous bind. Also show referrals *\/ */
 
1318
/*        newserver->ask_pw   = 0; */
 
1319
/*        newserver->show_ref = 1; */
1269
1320
 
1270
1321
/* #warning "ADD CONFIG FOR EXTENDED REFERENCE CHASING" */
1271
 
/*        /\* check: do we have this server around already??? *\/ */
1272
 
/*        s = server_by_canon_name(new_uri->str, TRUE); */
1273
 
 
1274
 
/*        if (!s) { */
1275
 
/*             s = server; */
1276
 
/*        } */
1277
 
                                             
1278
 
/*        if (s) { */
1279
 
/*             copy_ldapserver(newserver, s); */
1280
 
/*             statusbar_msg(_("Initialized temporary server-definition '%1$s' from existing server '%2$s'"), new_uri->str, server->name); */
1281
 
/*        } else { */
1282
 
/*             statusbar_msg(_("Created temporary server-definition '%1$s' with no pre-set values."), new_uri->str); */
1283
 
/*        } */
1284
 
 
1285
 
/*        g_free_and_dup(newserver->name,     new_uri->str); */
1286
 
/*        g_free_and_dup(newserver->ldaphost, new_uri->str); */
1287
 
/*        g_free_and_dup(newserver->basedn,   desc->lud_dn); */
 
1322
/*        /\* check: do we have this server around already??? *\/ */
 
1323
/*        s = server_by_canon_name(new_uri->str, TRUE); */
 
1324
 
 
1325
/*        if (!s) { */
 
1326
/*             s = server; */
 
1327
/*        } */
 
1328
 
 
1329
/*        if (s) { */
 
1330
/*             copy_ldapserver(newserver, s); */
 
1331
/*             statusbar_msg(_("Initialized temporary server-definition '%1$s' from existing server '%2$s'"), new_uri->str, server->name); */
 
1332
/*        } else { */
 
1333
/*             statusbar_msg(_("Created temporary server-definition '%1$s' with no pre-set values."), new_uri->str); */
 
1334
/*        } */
 
1335
 
 
1336
/*        g_free_and_dup(newserver->name,     new_uri->str); */
 
1337
/*        g_free_and_dup(newserver->ldaphost, new_uri->str); */
 
1338
/*        g_free_and_dup(newserver->basedn,   desc->lud_dn); */
1288
1339
 
1289
1340
          newserver->quiet = 1;
1290
1341
 
1292
1343
 
1293
1344
          transient_add_server(newserver);
1294
1345
 
1295
 
          *nextlevel = g_list_append(*nextlevel, 
 
1346
          *nextlevel = g_list_append(*nextlevel,
1296
1347
                                     new_chasing(newserver, desc->lud_dn));
1297
1348
 
1298
1349
          ldap_free_urldesc(desc);
1299
 
/*        g_string_free(new_uri, TRUE); */
 
1350
/*        g_string_free(new_uri, TRUE); */
1300
1351
     }
1301
1352
}
1302
1353
 
1307
1358
 
1308
1359
 
1309
1360
/* static gint result_compare_func(GtkCList *clist, */
1310
 
/*                              gconstpointer ptr1, */
1311
 
/*                              gconstpointer ptr2) */
 
1361
/*                              gconstpointer ptr1, */
 
1362
/*                              gconstpointer ptr2) */
1312
1363
/* { */
1313
1364
 
1314
1365
/*      gtk_clist_get_sort_column(clist); */
1316
1367
 
1317
1368
/* } */
1318
1369
 
1319
 
 
1320
 
 
1321
 
 
1322
 
static void click_column(GtkCList *clist,
 
1370
#if 0
 
1371
static void click_column (GtkCList *clist,
1323
1372
                         gint column,
1324
1373
                         struct list_click_info *lci)
1325
1374
{
1333
1382
 
1334
1383
     gtk_clist_set_sort_type(clist, lci->last_type);
1335
1384
     gtk_clist_sort(clist);
1336
 
 
1337
1385
}
 
1386
#endif
1338
1387
 
1339
 
static void query(GqTab *tab)
 
1388
static void
 
1389
query(GqTab *tab)
1340
1390
{
 
1391
        GtkTreeIter iter;
1341
1392
     LDAP *ld;
1342
1393
     LDAPMessage *res, *e;
1343
 
     GtkWidget *main_clist, *new_main_clist, *scrwin, *focusbox;
1344
 
     GtkWidget *servcombo, *searchbase_combo;
 
1394
        GtkWidget *focusbox;
1345
1395
     GqServer *server;
1346
 
     gchar *cur_servername, *cur_searchbase, *enc_searchbase, *querystring;
 
1396
     gchar *cur_searchbase, *enc_searchbase, *querystring;
1347
1397
     GString *tolist[MAX_NUM_ATTRIBUTES];
1348
1398
     char *filter, *searchterm;
1349
1399
     int msg, rc, i, row, l;
1353
1403
     LDAPControl c;
1354
1404
     LDAPControl *ctrls[2] = { NULL, NULL } ;
1355
1405
     char *base;
1356
 
     struct list_click_info *lci;
1357
1406
     const char **attrs = NULL;
1358
1407
 
1359
1408
     GList *thislevel = NULL, *nextlevel = NULL;
1360
1409
     int level = 0;
1361
1410
     struct chasing *ch = NULL;
1362
 
     int query_context;
1363
 
 
1364
 
     if(GQ_TAB_SEARCH(tab)->search_lock)
1365
 
          return;
1366
 
 
1367
 
     GQ_TAB_SEARCH(tab)->search_lock = 1;
1368
 
 
1369
 
     query_context = error_new_context(_("Searching"), tab->win->mainwin);
 
1411
 
 
1412
        if(P(tab)->search_lock) {
 
1413
                return;
 
1414
        }
 
1415
 
 
1416
        P(tab)->search_lock = 1;
1370
1417
 
1371
1418
     focusbox = tab->focus;
1372
1419
     searchterm = gtk_editable_get_chars(GTK_EDITABLE(focusbox), 0, -1);
1374
1421
     g_free(searchterm);
1375
1422
 
1376
1423
     if(querystring[0] == 0) {
1377
 
          error_push(query_context, _("Please enter a valid search filter"));
 
1424
          error_push(0, _("Please enter a valid search filter"));
1378
1425
          goto done;
1379
1426
     }
1380
1427
 
 
1428
#warning "FIXME: memset()"
1381
1429
     for(i = 0; i < MAX_NUM_ATTRIBUTES; i++)
1382
1430
          columns_done[i] = 0;
1383
1431
 
1384
 
     servcombo = GQ_TAB_SEARCH(tab)->serverlist_combo;
1385
 
     cur_servername =
1386
 
          gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(servcombo)->entry),
1387
 
                                 0, -1);
1388
 
     server = gq_server_list_get_by_name(gq_server_list_get(), cur_servername);
1389
 
     if(!server) {
1390
 
          error_push(query_context, 
1391
 
                     _("Oops! Server '%s' not found!"), cur_servername);
1392
 
          g_free(cur_servername);
1393
 
          goto done;
1394
 
     }
1395
 
     g_free(cur_servername);
 
1432
        if(!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(P(tab)->serverlist_combo), &iter)) {
 
1433
#warning "FIXME: we should realize this earlier"
 
1434
                error_push(0, _("Oops! No Server selected!"));
 
1435
                goto done;
 
1436
        }
 
1437
        server = gq_server_model_get_server(GQ_SERVER_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(P(tab)->serverlist_combo))),
 
1438
                                            &iter);
1396
1439
 
1397
 
     filter = make_filter(server, querystring);
1398
 
     free(querystring);
 
1440
     filter = make_filter(server, querystring, gq_tab_search_get_mode(GQ_TAB_SEARCH(tab)));
 
1441
     g_free(querystring);
1399
1442
 
1400
1443
     statusbar_msg(_("Searching for %s"), filter);
1401
1444
 
1402
 
     searchbase_combo = GQ_TAB_SEARCH(tab)->searchbase_combo;
1403
 
     cur_searchbase = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(searchbase_combo)->entry), 0, -1);
 
1445
     cur_searchbase = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(P(tab)->searchbase_combo)->entry), 0, -1);
1404
1446
 
1405
1447
     enc_searchbase = encoded_string(cur_searchbase);
1406
1448
     g_free(cur_searchbase);
1407
1449
 
1408
 
     /* setup GUI - build new clist */
1409
 
     new_main_clist = gtk_clist_new(MAX_NUM_ATTRIBUTES);
1410
 
     gtk_clist_set_selection_mode(GTK_CLIST(new_main_clist),
1411
 
                                  GTK_SELECTION_EXTENDED);
1412
 
 
1413
 
     GTK_CLIST(new_main_clist)->button_actions[2] = GTK_BUTTON_SELECTS;
1414
 
#ifdef OLD_FOCUS_HANDLING
1415
 
     GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(new_main_clist), GTK_CAN_FOCUS);
1416
 
#endif
1417
 
     gtk_widget_show(new_main_clist);
1418
 
     gtk_clist_column_titles_show(GTK_CLIST(new_main_clist));
1419
 
     gtk_clist_set_row_height(GTK_CLIST(new_main_clist), 0);
1420
 
 
1421
 
     g_signal_connect(new_main_clist, "select_row",
1422
 
                        G_CALLBACK(select_entry_callback),
1423
 
                        tab);
1424
 
/*       g_signal_connect(new_main_clist, "unselect_row", */
1425
 
/*                          G_CALLBACK(unselect_entry_callback), */
1426
 
/*                          tab); */
1427
 
     g_signal_connect(new_main_clist, "button_press_event",
1428
 
                        G_CALLBACK(search_button_press_on_tree_item),
1429
 
                        tab);
1430
 
 
1431
 
     lci = g_malloc0(sizeof(struct list_click_info));
1432
 
     lci->last_col = -1;
1433
 
 
1434
 
     gtk_object_set_data_full(GTK_OBJECT(new_main_clist), "lci", lci, g_free);
1435
 
     g_signal_connect(new_main_clist,
1436
 
                        "click-column",
1437
 
                        G_CALLBACK(click_column),
1438
 
                        lci);
1439
 
 
1440
 
     main_clist = GQ_TAB_SEARCH(tab)->main_clist;
1441
 
     gtk_clist_clear(GTK_CLIST(main_clist));
1442
 
     scrwin = main_clist->parent;
1443
 
     gtk_widget_destroy(main_clist);
1444
 
     GQ_TAB_SEARCH(tab)->main_clist = new_main_clist;
1445
 
 
1446
 
     gtk_container_add(GTK_CONTAINER(scrwin), new_main_clist);
 
1450
        /* setup results - clear model */
 
1451
        gtk_list_store_clear(P(tab)->results_liststore);
1447
1452
 
1448
1453
     /* prepare attrs list for searches */
1449
 
     l = g_list_length(GQ_TAB_SEARCH(tab)->attrs);
1450
 
     
 
1454
     l = g_list_length(P(tab)->attrs);
 
1455
 
1451
1456
     want_oc = 1;
1452
1457
     if (l) {
1453
1458
          /* fill attrs with pointers belonging to the
1454
1459
             list. The attrs[i] MUST NOT be free'd */
1455
1460
          const GList *I;
1456
 
          
 
1461
 
1457
1462
          want_oc = 0;
1458
1463
          attrs = g_malloc0(sizeof(const char *) * (l + 1));
1459
 
          for ( i = 0, I = GQ_TAB_SEARCH(tab)->attrs ; 
1460
 
                I ; 
1461
 
                i++, I = g_list_next(I)) {
 
1464
          for ( i = 0, I = P(tab)->attrs ; I ; i++, I = g_list_next(I)) {
1462
1465
               attrs[i] = I->data;
1463
1466
               if (strcasecmp(attrs[i], "objectclass") == 0) {
1464
1467
                    want_oc = 1;
1468
1471
 
1469
1472
     attrlist = NULL;
1470
1473
 
1471
 
     /* reserve columns 0 & 1 for DN and objectClass, respectively */
1472
 
     if(config->showdn) {
1473
 
          column_by_attr(&attrlist, "DN");
1474
 
          gtk_clist_set_column_title(GTK_CLIST(new_main_clist), 0, "DN");
1475
 
          gtk_clist_set_column_width(GTK_CLIST(new_main_clist), 0, 260);
1476
 
          gtk_clist_set_column_resizeable(GTK_CLIST(new_main_clist), 0, TRUE);
1477
 
          columns_done[0] = 1;
1478
 
     }
1479
 
 
1480
1474
     if (want_oc) {
1481
1475
          oc_col = column_by_attr(&attrlist, "objectClass");
 
1476
#warning "FIXME: check and enable object class information"
 
1477
#if 0
1482
1478
          gtk_clist_set_column_title(GTK_CLIST(new_main_clist), oc_col,
1483
1479
                                     "objectClass");
1484
1480
          gtk_clist_set_column_width(GTK_CLIST(new_main_clist), oc_col, 120);
1489
1485
 
1490
1486
/*        gtk_clist_set_column_visibility(GTK_CLIST(new_main_clist), */
1491
1487
/*                                        oc_col, 0); */
 
1488
#endif
1492
1489
     }
1493
1490
 
1494
1491
     for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) {
1510
1507
     ch = new_chasing(server, enc_searchbase);
1511
1508
     thislevel = g_list_append(thislevel, ch);
1512
1509
 
1513
 
     if (enc_searchbase) free(enc_searchbase);
 
1510
     if(enc_searchbase) {
 
1511
                g_free(enc_searchbase);
 
1512
                enc_searchbase = NULL;
 
1513
     }
1514
1514
 
1515
1515
     row = 0;
1516
1516
 
1517
 
     gtk_clist_freeze(GTK_CLIST(new_main_clist));
1518
 
 
1519
1517
     /* do the searching */
1520
1518
     set_busycursor();
1521
1519
 
1525
1523
               thislevel = nextlevel;
1526
1524
               nextlevel = NULL;
1527
1525
          }
1528
 
          if (level > GQ_TAB_SEARCH(tab)->max_depth) {
 
1526
          if (level > P(tab)->max_depth) {
1529
1527
               statusbar_msg(_("Reached maximum recursion depth"));
1530
1528
 
1531
1529
               g_list_foreach(thislevel, (GFunc) free_chasing, NULL);
1539
1537
          server = ch->server;
1540
1538
          base = ch->base;
1541
1539
 
1542
 
          if( (ld = open_connection(query_context, server)) != NULL) {
1543
 
               statusbar_msg(_("Searching on server '%1$s' below '%2$s'"), 
1544
 
                             server->name, base);
1545
 
               rc = ldap_search_ext(ld, base, 
1546
 
                                    GQ_TAB_SEARCH(tab)->scope,
 
1540
          if( (ld = open_connection(0, server)) != NULL) {
 
1541
               statusbar_msg(_("Searching on server '%1$s' below '%2$s'"),
 
1542
                             gq_server_get_name(server), base);
 
1543
               rc = ldap_search_ext(ld, base,
 
1544
                                    P(tab)->scope,
1547
1545
                                    filter,
1548
1546
                                    (char **)attrs,     /* attrs & API bug*/
1549
1547
                                    0,                  /* attrsonly */
1550
 
                                    GQ_TAB_SEARCH(tab)->chase_ref ? NULL : ctrls,
1551
 
/*                                  server->show_ref ? ctrls : NULL, */
 
1548
                                    P(tab)->chase_ref ? NULL : ctrls,
 
1549
/*                                  server->show_ref ? ctrls : NULL, */
1552
1550
                                    /* serverctrls */
1553
1551
                                    NULL,               /* clientctrls */
1554
1552
                                    NULL,               /* timeout */
1557
1555
 
1558
1556
               if(rc == -1) {
1559
1557
                    server->server_down++;
1560
 
                    error_push(query_context,
1561
 
                               _("Error searching below '%1$s': %2$s"), 
 
1558
                    error_push(0,
 
1559
                               _("Error searching below '%1$s': %2$s"),
1562
1560
                               enc_searchbase, ldap_err2string(rc));
1563
 
/*                  close_connection(server, FALSE); */
1564
 
/*                  GQ_TAB_SEARCH(tab)->search_lock = 0; */
1565
 
/*                  return; */
 
1561
/*                  close_connection(server, FALSE); */
 
1562
/*                  GQ_TAB_SEARCH(tab)->search_lock = 0; */
 
1563
/*                  return; */
1566
1564
                    goto cont;
1567
1565
               }
1568
 
          
 
1566
 
1569
1567
               for (rc = 1 ; rc ; ) {
1570
1568
                    int code = ldap_result(ld, msg, 0, NULL, &res);
1571
1569
                    if (code == -1) {
1572
1570
                         /* error */
1573
 
                         error_push(query_context,
 
1571
                         error_push(0,
1574
1572
                                    _("Unspecified error searching below '%1$s'"),
1575
1573
                                    enc_searchbase);
1576
1574
                         break;
1579
1577
                         e = ldap_next_message(ld, e) ) {
1580
1578
                         switch (ldap_msgtype(e)) {
1581
1579
                         case LDAP_RES_SEARCH_ENTRY:
1582
 
                              fill_one_row(query_context,
1583
 
                                           server, ld, e, new_main_clist,
 
1580
                              fill_one_row(0,
 
1581
                                           server, ld, e,
1584
1582
                                           tolist,
1585
1583
                                           columns_done,
1586
1584
                                           attrlist,
1587
 
                                           tab);
 
1585
                                           GQ_TAB_SEARCH(tab));
1588
1586
                              row++;
1589
1587
 
1590
1588
                              rc = 1;
1595
1593
 
1596
1594
                              if (rc == LDAP_SUCCESS) {
1597
1595
                                   for (i = 0 ; refs[i] ; i++) {
1598
 
                                        add_referral(query_context,
 
1596
                                        add_referral(0,
1599
1597
                                                     server,
1600
1598
                                                     refs[i], &nextlevel);
1601
1599
                                   }
1631
1629
     for(i = 0; i < MAX_NUM_ATTRIBUTES; i++) {
1632
1630
          g_string_free(tolist[i], TRUE);
1633
1631
     }
1634
 
/*      gtk_clist_thaw(GTK_CLIST(new_main_clist)); */
1635
 
 
1636
1632
 
1637
1633
     if(row > 0) {
1638
1634
/*        statusbar_msg("%s", ldap_err2string(msg)); */
1641
1637
                        row);
1642
1638
     }
1643
1639
 
1644
 
/*      gtk_clist_freeze(GTK_CLIST(new_main_clist)); */
1645
 
     gtk_clist_column_titles_active(GTK_CLIST(new_main_clist));
1646
 
 
1647
 
     for (i = 0 ; gtk_clist_get_column_widget(GTK_CLIST(new_main_clist), i) ;
1648
 
          i++ ) {
1649
 
          int opt = gtk_clist_optimal_column_width(GTK_CLIST(new_main_clist), i);
1650
 
          if (opt < 40) {
1651
 
               opt = 40;
1652
 
          }
1653
 
          if (opt > 150) {
1654
 
               opt = 150;
1655
 
          }
1656
 
          gtk_clist_set_column_width(GTK_CLIST(new_main_clist), i, opt);
1657
 
     }
1658
 
 
1659
 
     gtk_clist_thaw(GTK_CLIST(new_main_clist));
1660
 
 
1661
1640
     free_attrlist(attrlist);
1662
1641
     add_to_search_history(tab);
1663
1642
 
1664
 
 done:
1665
 
     error_flush(query_context);
1666
 
     GQ_TAB_SEARCH(tab)->search_lock = 0;
 
1643
done:
 
1644
        P(tab)->search_lock = 0;
1667
1645
}
1668
1646
 
1669
 
static void results_popup_menu(GqTab *tab, GdkEventButton *event,
1670
 
                               struct dn_on_server *set)
 
1647
static void
 
1648
results_popup_menu(GqTabSearch   * self,
 
1649
                   GdkEventButton* event,
 
1650
                   GqServerDn    * set)
1671
1651
{
 
1652
#define tab self
 
1653
        GtkTreeSelection* selection;
1672
1654
     GtkWidget *root_menu, *menu, *menu_item, *label;
1673
1655
     GtkWidget *submenu;
1674
 
     int transient = is_transient_server(set->server);
1675
 
     char **exploded_dn = NULL, *name;
1676
 
     GList *selection;
1677
 
     int have_sel;
 
1656
     int transient = is_transient_server(gq_server_dn_get_server(set));
 
1657
     char **exploded_dn = NULL;
 
1658
     gchar const *name;
 
1659
        int selected;
1678
1660
 
1679
 
     /* this is a hack to pass the selected set under the menu to the callbacks.
1680
 
        Each callback MUST clear this after use! */
1681
 
     GQ_TAB_SEARCH(tab)->set = set;
 
1661
        /* Check if several entries it should be sensitive */
 
1662
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(self)->results_treeview));
 
1663
        selected = gtk_tree_selection_count_selected_rows(selection);
1682
1664
 
1683
1665
     root_menu = gtk_menu_item_new_with_label("Root");
1684
1666
     gtk_widget_show(root_menu);
1686
1668
     menu = gtk_menu_new();
1687
1669
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(root_menu), menu);
1688
1670
 
1689
 
     exploded_dn = gq_ldap_explode_dn(set->dn, FALSE);
 
1671
     exploded_dn = gq_ldap_explode_dn(gq_server_dn_get_dn(set), FALSE);
1690
1672
 
1691
1673
     if (exploded_dn) {
1692
1674
          name = exploded_dn[0];
1693
1675
     } else {
1694
 
          name = set->dn;
 
1676
          name = gq_server_dn_get_dn(set);
1695
1677
     }
1696
1678
 
1697
1679
     label = gtk_menu_item_new_with_label(name);
1698
1680
     gtk_widget_set_sensitive(label, FALSE);
1699
1681
     gtk_widget_show(label);
1700
 
     
 
1682
 
1701
1683
     gtk_menu_append(GTK_MENU(menu), label);
1702
1684
     gtk_menu_set_title(GTK_MENU(menu), name);
1703
1685
 
1704
1686
     if (exploded_dn) gq_exploded_free(exploded_dn);
1705
1687
 
1706
 
     menu_item = gtk_separator_menu_item_new(); 
 
1688
     menu_item = gtk_separator_menu_item_new();
1707
1689
     gtk_menu_append(GTK_MENU(menu), menu_item);
1708
1690
     gtk_widget_set_sensitive(menu_item, FALSE);
1709
1691
     gtk_widget_show(menu_item);
1715
1697
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
1716
1698
     gtk_widget_show(menu_item);
1717
1699
 
1718
 
     /* Check if several entries it should be sensitive */
1719
 
     selection = GTK_CLIST(GQ_TAB_SEARCH(tab)->main_clist)->selection;
1720
 
     have_sel = (selection && g_list_length(selection) > 0);
1721
 
 
1722
1700
     /* Select All */
1723
1701
     menu_item = gtk_menu_item_new_with_label(_("Select All"));
1724
1702
     gtk_menu_append(GTK_MENU(submenu), menu_item);
1725
1703
     g_signal_connect_swapped(menu_item, "activate",
1726
 
                               G_CALLBACK(gtk_clist_select_all),
1727
 
                               GQ_TAB_SEARCH(tab)->main_clist);
 
1704
                              G_CALLBACK(gtk_tree_selection_select_all),
 
1705
                              selection);
1728
1706
     gtk_widget_show(menu_item);
1729
 
                              
 
1707
 
1730
1708
     /* Unselect All */
1731
1709
     menu_item = gtk_menu_item_new_with_label(_("Unselect All"));
1732
1710
     gtk_menu_append(GTK_MENU(submenu), menu_item);
1733
1711
     g_signal_connect_swapped(menu_item, "activate",
1734
 
                               G_CALLBACK(gtk_clist_unselect_all),
1735
 
                               GQ_TAB_SEARCH(tab)->main_clist);
 
1712
                              G_CALLBACK(gtk_tree_selection_unselect_all),
 
1713
                              selection);
1736
1714
     gtk_widget_show(menu_item);
1737
 
     gtk_widget_set_sensitive(menu_item, have_sel);
 
1715
     gtk_widget_set_sensitive(menu_item, 0 < selected);
1738
1716
 
1739
1717
     /* separator */
1740
1718
     menu_item = gtk_menu_item_new();
1741
1719
     gtk_menu_append(GTK_MENU(submenu), menu_item);
1742
1720
     gtk_widget_show(menu_item);
1743
1721
 
1744
 
     /* Export to LDIF*/
1745
 
     menu_item = gtk_menu_item_new_with_label(_("Export to LDIF"));
 
1722
        /* Export to LDIF*/
 
1723
        menu_item = gtk_image_menu_item_new_with_label(_("Export to LDIF"));
 
1724
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
 
1725
                                      gtk_image_new_from_stock(GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU));
1746
1726
     gtk_menu_append(GTK_MENU(submenu), menu_item);
1747
1727
     g_signal_connect_swapped(menu_item, "activate",
1748
1728
                               G_CALLBACK(export_search_selected_entry),
1749
1729
                               tab);
1750
1730
     gtk_widget_show(menu_item);
1751
 
     gtk_widget_set_sensitive(menu_item, have_sel);
 
1731
     gtk_widget_set_sensitive(menu_item, 0 < selected);
1752
1732
 
1753
1733
     /* Add to Browser*/
1754
1734
     menu_item = gtk_menu_item_new_with_label(_("Add to Browser"));
1757
1737
                               G_CALLBACK(add_selected_to_browser),
1758
1738
                               tab);
1759
1739
     gtk_widget_show(menu_item);
1760
 
     gtk_widget_set_sensitive(menu_item, have_sel);
 
1740
     gtk_widget_set_sensitive(menu_item, 0 < selected);
1761
1741
 
1762
1742
     /* separator */
1763
1743
     menu_item = gtk_menu_item_new();
1771
1751
                               G_CALLBACK(delete_search_selected),
1772
1752
                               tab);
1773
1753
     gtk_widget_show(menu_item);
1774
 
     gtk_widget_set_sensitive(menu_item, have_sel);
1775
 
 
 
1754
     gtk_widget_set_sensitive(menu_item, 0 < selected);
1776
1755
     /*** End of Selected submenu ***/
1777
1756
 
1778
1757
     /* Edit */
1822
1801
                               tab);
1823
1802
     gtk_widget_show(menu_item);
1824
1803
 
1825
 
 
1826
 
 
1827
1804
     gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
1828
1805
                    event->button, event->time);
1829
 
 
1830
 
}
1831
 
 
1832
 
 
1833
 
void find_in_browser(GqTab *tab)
1834
 
{
1835
 
     GQTreeWidget *ctree;
1836
 
     struct dn_on_server *set;
1837
 
     GqTab *browsetab;
1838
 
 
1839
 
     set = GQ_TAB_SEARCH(tab)->set;
1840
 
     GQ_TAB_SEARCH(tab)->set = NULL;
1841
 
     if(set == NULL || set->dn == NULL || strlen(set->dn) == 0)
1842
 
          return;
1843
 
 
1844
 
     /* find last used browser... */
1845
 
 
1846
 
     browsetab = get_last_of_mode(BROWSE_MODE);
1847
 
     if(browsetab) {
1848
 
          int ctx;
1849
 
          ctree = GQ_TAB_BROWSE(browsetab)->ctreeroot;
1850
 
          ctx = error_new_context(_("Finding entry in browser"),
1851
 
                                  GTK_WIDGET(ctree));
1852
 
          show_server_dn(ctx, ctree, set->server, set->dn, TRUE);
1853
 
          go_to_page(browsetab);
1854
 
          error_flush(ctx);
1855
 
     } else {
1856
 
          single_warning_popup(_("No browser available"));
1857
 
     }
1858
 
}
1859
 
 
1860
 
 
1861
 
void add_all_to_browser(GqTab *tab)
1862
 
{
1863
 
     GQTreeWidget *ctree;
1864
 
     struct dn_on_server *cur_resultset;
1865
 
     GqTab *browsetab;
1866
 
     int i;
1867
 
     GtkWidget *clist = GQ_TAB_SEARCH(tab)->main_clist;
1868
 
 
1869
 
     /* find last used browser... */
1870
 
     
1871
 
     browsetab = get_last_of_mode(BROWSE_MODE);
1872
 
     if(browsetab) {
1873
 
          int ctx;
1874
 
          ctree = GQ_TAB_BROWSE(browsetab)->ctreeroot;
1875
 
          ctx = error_new_context(_("Adding all to browser"), 
1876
 
                                  GTK_WIDGET(ctree));
1877
 
 
1878
 
          gtk_clist_freeze(GTK_CLIST(ctree));
1879
 
          for(i = 0 ;
1880
 
              (cur_resultset = gtk_clist_get_row_data(GTK_CLIST(clist), i)) != NULL ;
1881
 
              i++) {
1882
 
               show_server_dn(ctx, ctree, 
1883
 
                              cur_resultset->server, cur_resultset->dn, FALSE);
1884
 
          }
1885
 
          gtk_clist_thaw(GTK_CLIST(ctree));
1886
 
          go_to_page(browsetab);
1887
 
 
1888
 
          error_flush(ctx);
1889
 
     } else {
1890
 
          single_warning_popup(_("No browser available"));
1891
 
     }
1892
 
}
1893
 
 
1894
 
static void add_selected_to_browser(GqTab *tab)
1895
 
{
1896
 
     GQTreeWidget *ctree;
1897
 
     struct dn_on_server *cur_resultset;
1898
 
     GqTab *browsetab;
1899
 
     GtkWidget *clist = GQ_TAB_SEARCH(tab)->main_clist;
1900
 
     GList *sel, *I;
1901
 
 
1902
 
     /* find last used browser... */
1903
 
     
1904
 
     browsetab = get_last_of_mode(BROWSE_MODE);
1905
 
     if(browsetab) {
1906
 
          int ctx;
1907
 
          ctree = GQ_TAB_BROWSE(browsetab)->ctreeroot;
1908
 
          ctx = error_new_context(_("Adding selected entries to browser"), GTK_WIDGET(ctree));
1909
 
 
1910
 
          gtk_clist_freeze(GTK_CLIST(ctree));
1911
 
 
1912
 
          sel = GTK_CLIST(clist)->selection;
1913
 
 
1914
 
          for (I = sel ; I ; I = g_list_next(I)) {
1915
 
               cur_resultset = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(I->data));
1916
 
               show_server_dn(ctx, 
1917
 
                              ctree, 
1918
 
                              cur_resultset->server, cur_resultset->dn, FALSE);
1919
 
          }
1920
 
          gtk_clist_thaw(GTK_CLIST(ctree));
1921
 
          go_to_page(browsetab);
1922
 
 
1923
 
          error_flush(ctx);
1924
 
     } else {
1925
 
          single_warning_popup(_("No browser available"));
1926
 
     }
1927
 
}
1928
 
 
1929
 
 
1930
 
 
1931
 
static void export_search_selected_entry(GqTab *tab)
1932
 
{
1933
 
     struct dn_on_server *cur_resultset;
1934
 
     GqTab *browsetab;
1935
 
     GtkWidget *clist = GQ_TAB_SEARCH(tab)->main_clist;
1936
 
     GList *sel, *I;
1937
 
 
1938
 
     /* find last used browser... */
1939
 
     
1940
 
     browsetab = get_last_of_mode(BROWSE_MODE);
1941
 
     if(browsetab) {
1942
 
          GList *to_export = NULL;
1943
 
          struct dn_on_server *dos;
1944
 
          int error_context;
1945
 
 
1946
 
          sel = GTK_CLIST(clist)->selection;
1947
 
 
1948
 
          for (I = sel ; I ; I = g_list_next(I)) {
1949
 
               cur_resultset = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(I->data));
1950
 
 
1951
 
               dos = new_dn_on_server(cur_resultset->dn,
1952
 
                                      cur_resultset->server);
1953
 
               to_export = g_list_append(to_export, dos);
1954
 
          }
1955
 
          error_context = error_new_context(_("Exporting selected entries to LDIF"),
 
1806
#undef tab
 
1807
}
 
1808
 
 
1809
static void
 
1810
find_in_browser_foreach(GtkTreeModel* model,
 
1811
                        GtkTreePath * path G_GNUC_UNUSED,
 
1812
                        GtkTreeIter * iter,
 
1813
                        gpointer      data G_GNUC_UNUSED)
 
1814
{
 
1815
        GqTab      * browsetab;
 
1816
        GqServerDn * sdn;
 
1817
 
 
1818
        gtk_tree_model_get(model, iter,
 
1819
                           RES_COL_DN, &sdn,
 
1820
                           -1);
 
1821
 
 
1822
        /* find last used browser... */
 
1823
        browsetab = gq_window_get_last_tab(&mainwin, GQ_TYPE_TAB_BROWSE);
 
1824
        if(browsetab) {
 
1825
                GtkWidget* ctree;
 
1826
                int ctx;
 
1827
                ctree = GQ_TAB_BROWSE(browsetab)->ctreeroot;
 
1828
                ctx = error_new_context(_("Finding entry in browser"),
 
1829
                                  GTK_WIDGET(ctree));
 
1830
                show_server_dn(ctx, model, gq_server_dn_get_server(sdn),
 
1831
                         gq_server_dn_get_dn(sdn), TRUE);
 
1832
                go_to_page(browsetab);
 
1833
                error_flush(ctx);
 
1834
        } else {
 
1835
#warning "FIXME: just open a browser"
 
1836
                single_warning_popup(_("No browser available"));
 
1837
        }
 
1838
}
 
1839
 
 
1840
void
 
1841
find_in_browser(GqTab *tab)
 
1842
{
 
1843
#warning "FIXME: store the already used browsers and open new ones if necessary"
 
1844
        GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(tab)->results_treeview));
 
1845
        gtk_tree_selection_selected_foreach(sel, find_in_browser_foreach, tab);
 
1846
}
 
1847
 
 
1848
 
 
1849
struct ServerDnShowData {
 
1850
        gint       context;
 
1851
        GtkWidget* treeview;
 
1852
};
 
1853
 
 
1854
static gboolean
 
1855
server_dn_show_b(GtkTreeModel* model,
 
1856
                 GtkTreePath * path G_GNUC_UNUSED,
 
1857
                 GtkTreeIter * iter,
 
1858
                 gpointer      pdata)
 
1859
{
 
1860
        struct ServerDnShowData* data = pdata;
 
1861
        GqServerDn* dn = NULL;
 
1862
 
 
1863
        gtk_tree_model_get(model, iter,
 
1864
                           RES_COL_DN, &dn,
 
1865
                           -1);
 
1866
 
 
1867
        show_server_dn(data->context, model,
 
1868
                       gq_server_dn_get_server(dn),
 
1869
                       gq_server_dn_get_dn(dn), FALSE);
 
1870
 
 
1871
        return FALSE;
 
1872
}
 
1873
 
 
1874
void
 
1875
add_all_to_browser(GqTab *tab)
 
1876
{
 
1877
        GqTab *browsetab;
 
1878
        struct ServerDnShowData data = {
 
1879
                0, NULL
 
1880
        };
 
1881
 
 
1882
        /* find last used browser... */
 
1883
     browsetab = gq_window_get_last_tab(&mainwin, GQ_TYPE_TAB_BROWSE);
 
1884
        if(!browsetab) {
 
1885
#warning "FIXME: just open a fucking browser"
 
1886
                single_warning_popup(_("No browser available"));
 
1887
                return;
 
1888
        }
 
1889
 
 
1890
        data.context = error_new_context(_("Adding all to browser"), P(tab)->results_treeview);
 
1891
        data.treeview = GTK_WIDGET(GQ_TAB_BROWSE(browsetab)->ctreeroot);
 
1892
        gtk_tree_model_foreach(GTK_TREE_MODEL(P(tab)->results_liststore),
 
1893
                               server_dn_show_b,
 
1894
                               &data);
 
1895
        error_flush(data.context);
 
1896
        go_to_page(browsetab);
 
1897
}
 
1898
 
 
1899
static void
 
1900
server_dn_show(GtkTreeModel* model,
 
1901
               GtkTreePath * path,
 
1902
               GtkTreeIter * iter,
 
1903
               gpointer      data)
 
1904
{
 
1905
        server_dn_show_b(model, path,
 
1906
                         iter, data);
 
1907
}
 
1908
 
 
1909
static void
 
1910
add_selected_to_browser(GqTab *tab)
 
1911
{
 
1912
        GqTab* browsetab;
 
1913
        struct ServerDnShowData data = {
 
1914
                0, NULL
 
1915
        };
 
1916
 
 
1917
        /* find last used browser... */
 
1918
        browsetab = gq_window_get_last_tab(&mainwin, GQ_TYPE_TAB_BROWSE);
 
1919
        if(!browsetab) {
 
1920
#warning "FIXME: just open a fucking browser"
 
1921
                single_warning_popup(_("No browser available"));
 
1922
                return;
 
1923
        }
 
1924
 
 
1925
        data.context = error_new_context(_("Adding selected entries to browser"),
 
1926
                                         P(tab)->results_treeview);
 
1927
        data.treeview = GTK_WIDGET(GQ_TAB_BROWSE(browsetab)->ctreeroot);
 
1928
 
 
1929
        gtk_clist_freeze(GTK_CLIST(GQ_TAB_BROWSE(browsetab)->ctreeroot));
 
1930
        gtk_tree_selection_selected_foreach(gtk_tree_view_get_selection(GTK_TREE_VIEW(P(tab)->results_treeview)),
 
1931
                                            server_dn_show,
 
1932
                                            &data);
 
1933
        gtk_clist_thaw(GTK_CLIST(GQ_TAB_BROWSE(browsetab)->ctreeroot));
 
1934
        go_to_page(browsetab);
 
1935
 
 
1936
        error_flush(data.context);
 
1937
}
 
1938
 
 
1939
static void
 
1940
collect_selected(GtkTreeModel* model,
 
1941
                 GtkTreePath * path G_GNUC_UNUSED,
 
1942
                 GtkTreeIter * iter,
 
1943
                 gpointer      data)
 
1944
{
 
1945
        GqServerDn* entry;
 
1946
        GList     **list = data;
 
1947
 
 
1948
        gtk_tree_model_get(model, iter,
 
1949
                           RES_COL_DN, &entry,
 
1950
                           -1);
 
1951
        *list = g_list_prepend(*list, g_object_ref(entry));
 
1952
}
 
1953
 
 
1954
static void
 
1955
export_search_selected_entry(GqTab* tab)
 
1956
{
 
1957
     GqTab *browsetab;
 
1958
 
 
1959
     /* find last used browser... */
 
1960
 
 
1961
     browsetab = gq_window_get_last_tab(&mainwin, GQ_TYPE_TAB_BROWSE);
 
1962
     if(browsetab) {
 
1963
                GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(tab)->results_treeview));
 
1964
                gint              error_context;
 
1965
                GList           * list = NULL;
 
1966
 
 
1967
                gtk_tree_selection_selected_foreach(sel, collect_selected, &list);
 
1968
 
 
1969
                error_context = error_new_context(_("Exporting selected entries to LDIF"),
1956
1970
                                            tab->win->mainwin);
1957
1971
 
1958
 
          export_many(error_context, tab->win->mainwin, to_export);
 
1972
                gq_export_server_dns(error_context, GTK_WINDOW(tab->win->mainwin), list);
1959
1973
 
1960
 
          error_flush(error_context);
 
1974
                error_flush(error_context);
1961
1975
     } else {
 
1976
#warning "FIXME: just open a fucking browser"
1962
1977
          single_warning_popup(_("No browser available"));
1963
1978
     }
1964
1979
}
1965
1980
 
1966
 
static void delete_search_selected(GqTab *tab)
1967
 
{
1968
 
     struct dn_on_server *set;
1969
 
     GtkWidget *clist = GQ_TAB_SEARCH(tab)->main_clist;
1970
 
     GList *sel, *I;
1971
 
 
1972
 
     sel = GTK_CLIST(clist)->selection;
1973
 
     if (g_list_length(sel) > 0) {
1974
 
          int answer = 
1975
 
               question_popup(_("Do you really want to delete the selected entries?"),
1976
 
                              _("Do you really want to delete the selected entries?")
1977
 
                              );
1978
 
 
1979
 
          /* FIXME: sort by ldapserver and keep connection open across
1980
 
             deletions  */
1981
 
          if (answer) {
1982
 
               GList *deld = NULL;
1983
 
               int ctx = error_new_context(_("Deleting selected entries"), 
1984
 
                                           GTK_WIDGET(clist));
1985
 
 
1986
 
               for (I = g_list_last(sel) ; I ; I = g_list_previous(I)) {
1987
 
                    set = gtk_clist_get_row_data(GTK_CLIST(clist),
1988
 
                                                 GPOINTER_TO_INT(I->data));
1989
 
                    if (delete_entry(ctx, set->server, set->dn)) {
1990
 
                         deld = g_list_append(deld, I->data);
1991
 
                    }
1992
 
               }
1993
 
               gtk_clist_freeze(GTK_CLIST(clist));
1994
 
               for (I = g_list_first(deld) ; I ; I = g_list_next(I)) {
1995
 
                    gtk_clist_remove(GTK_CLIST(clist),
1996
 
                                     GPOINTER_TO_INT(I->data));
1997
 
               }
1998
 
               g_list_free(deld);
1999
 
               gtk_clist_thaw(GTK_CLIST(clist));
2000
 
 
2001
 
               error_flush(ctx);
2002
 
          }
2003
 
     }
2004
 
}
2005
 
 
2006
 
static void search_new_from_entry_callback(GtkWidget *w, GqTab *tab)
2007
 
{
2008
 
     struct dn_on_server *set;
2009
 
     int error_context;
2010
 
 
2011
 
     set = GQ_TAB_SEARCH(tab)->set;
2012
 
     GQ_TAB_SEARCH(tab)->set = NULL;
2013
 
     if(set == NULL || set->dn == NULL)
2014
 
          return;
2015
 
     
2016
 
     error_context = error_new_context(_("Creating new entry from search result"), w);
2017
 
 
2018
 
     new_from_entry(error_context, set->server, set->dn);
2019
 
 
2020
 
     error_flush(error_context);
2021
 
}
2022
 
 
2023
 
static void search_edit_entry_callback(GqTab *tab)
2024
 
{
2025
 
     struct dn_on_server *set;
2026
 
 
2027
 
     set = GQ_TAB_SEARCH(tab)->set;
2028
 
     GQ_TAB_SEARCH(tab)->set = NULL;
2029
 
     if(set == NULL || set->dn == NULL)
2030
 
          return;
2031
 
 
2032
 
     edit_entry(set->server, set->dn);
2033
 
}
2034
 
 
2035
 
static void delete_search_entry(GqTab *tab)
2036
 
{
2037
 
     struct dn_on_server *set;
2038
 
     int ctx;
2039
 
 
2040
 
     set = GQ_TAB_SEARCH(tab)->set;
2041
 
     GQ_TAB_SEARCH(tab)->set = NULL;
2042
 
     if(set == NULL || set->dn == NULL)
2043
 
          return;
2044
 
 
2045
 
     ctx = error_new_context(_("Deleting entry"), 
2046
 
                             GQ_TAB_SEARCH(tab)->main_clist);
2047
 
     
2048
 
     delete_entry(ctx, set->server, set->dn);
2049
 
 
2050
 
     error_flush(ctx);
2051
 
}
2052
 
 
2053
 
static int select_entry_callback(GtkWidget *clist, gint row, gint column,
2054
 
                                 GdkEventButton *event, GqTab *tab)
2055
 
{
2056
 
     struct dn_on_server *set;
2057
 
 
2058
 
     if(event) {
2059
 
          set = gtk_clist_get_row_data(GTK_CLIST(clist), row);
2060
 
 
2061
 
          if(event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
2062
 
               GQ_TAB_SEARCH(tab)->set = set;
2063
 
               search_edit_entry_callback(tab);
2064
 
          }
2065
 
     }
2066
 
 
2067
 
     return(TRUE);
2068
 
}
2069
 
 
2070
 
 
2071
 
static gboolean search_button_press_on_tree_item(GtkWidget *clist,
2072
 
                                                 GdkEventButton *event,
2073
 
                                                 GqTab *tab)
2074
 
{
2075
 
     struct dn_on_server *set;
2076
 
     int rc, row, column;
2077
 
 
2078
 
     if (event->type == GDK_BUTTON_PRESS && event->button == 3
2079
 
         && event->window == GTK_CLIST(clist)->clist_window) {
2080
 
          rc = gtk_clist_get_selection_info(GTK_CLIST(clist),
2081
 
                                            event->x, event->y, &row, &column);
2082
 
          if (rc == 0)
2083
 
               return TRUE;
2084
 
 
2085
 
          set = gtk_clist_get_row_data(GTK_CLIST(clist), row);
2086
 
          results_popup_menu(tab, event, set);
2087
 
 
2088
 
          g_signal_stop_emission_by_name(clist,
2089
 
                                       "button_press_event");
2090
 
     }
2091
 
 
2092
 
     return FALSE;
2093
 
}
2094
 
 
2095
 
void fill_out_search(GqTab *tab,
2096
 
                     GqServer *server,
2097
 
                     const char *search_base_dn)
2098
 
{
2099
 
     GtkCombo *server_combo, *searchbase_combo;
2100
 
 
2101
 
     if (!search_base_dn) {
2102
 
          search_base_dn = server->basedn;
2103
 
     }
2104
 
 
2105
 
     server_combo = (GtkCombo *) GQ_TAB_SEARCH(tab)->serverlist_combo;
2106
 
     searchbase_combo = (GtkCombo *) GQ_TAB_SEARCH(tab)->searchbase_combo;
2107
 
 
2108
 
     gtk_entry_set_text(GTK_ENTRY(server_combo->entry), server->name);
2109
 
     gtk_entry_set_text(GTK_ENTRY(searchbase_combo->entry), search_base_dn);
2110
 
 
2111
 
     gtk_editable_set_position(GTK_EDITABLE(server_combo->entry), 0);
2112
 
     gtk_editable_set_position(GTK_EDITABLE(searchbase_combo->entry), 0);
2113
 
 
2114
 
     /* make tab visible */
2115
 
     go_to_page(tab);
 
1981
static void
 
1982
server_dn_queue_for_delete(GtkTreeModel* model,
 
1983
                           GtkTreePath * path G_GNUC_UNUSED,
 
1984
                           GtkTreeIter * iter,
 
1985
                           gpointer data)
 
1986
{
 
1987
        GqServerDn* entry = NULL;
 
1988
        GList     **to_delete = data;
 
1989
 
 
1990
        gtk_tree_model_get(model, iter,
 
1991
                           RES_COL_DN, &entry,
 
1992
                           -1);
 
1993
 
 
1994
        *to_delete = g_list_prepend(*to_delete, g_object_ref(entry));
 
1995
}
 
1996
 
 
1997
static void
 
1998
delete_search_selected(GqTab *tab)
 
1999
{
 
2000
        GtkTreeSelection* sel;
 
2001
        GqServerDn      * entry;
 
2002
        GtkWidget       * treeview = P(tab)->results_treeview;
 
2003
        GList           * to_delete = NULL,
 
2004
                        * iterator;
 
2005
        gint              context;
 
2006
 
 
2007
        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
 
2008
 
 
2009
#warning "FIXME: we should realize this earlier"
 
2010
        g_return_if_fail(!gtk_tree_selection_count_selected_rows(sel));
 
2011
 
 
2012
#warning "FIXME: start working on undelete support so this question gets obsolete"
 
2013
#warning "FIXME: set a parent window"
 
2014
        if(!question_popup(NULL,
 
2015
                           _("Do you really want to delete the selected entries?"),
 
2016
                           _("Do you really want to delete the selected entries?")))
 
2017
        {
 
2018
                return;
 
2019
        }
 
2020
 
 
2021
        // TRANSLATORS: there is a unicode symbold for the ellipsis (...): u2026
 
2022
        context = error_new_context(_("Preparing deletion..."),
 
2023
                                    treeview);
 
2024
        gtk_tree_selection_selected_foreach(sel,
 
2025
                                            server_dn_queue_for_delete,
 
2026
                                            &to_delete);
 
2027
        error_flush(context);
 
2028
 
 
2029
        /* FIXME: sort by ldapserver and keep connection open across
 
2030
         * deletions  */
 
2031
        context = error_new_context(_("Deleting selected entries"),
 
2032
                                    treeview);
 
2033
 
 
2034
        for (iterator = g_list_last(to_delete) ; iterator ; iterator = g_list_previous(iterator)) {
 
2035
                entry = iterator->data;
 
2036
 
 
2037
                if(delete_entry(context, gq_server_dn_get_server(entry),
 
2038
                   gq_server_dn_get_dn(entry)))
 
2039
                {
 
2040
                        //deld = g_list_append(deld, I->data);
 
2041
                }
 
2042
                else {
 
2043
#warning "FIXME: cancel deletion, revert the beginning and return to a clean directory state"
 
2044
                }
 
2045
        }
 
2046
 
 
2047
#warning "FIXME: remove the deleted entries from the search list"
 
2048
        for (iterator = g_list_first(to_delete) ; iterator ; iterator = g_list_next(iterator)) {
 
2049
#if 0
 
2050
                gtk_clist_remove(GTK_CLIST(clist),
 
2051
                                 GPOINTER_TO_INT(I->data));
 
2052
#endif
 
2053
                g_object_unref(iterator->data);
 
2054
                iterator->data = NULL;
 
2055
        }
 
2056
        g_list_free(to_delete);
 
2057
 
 
2058
        error_flush(context);
 
2059
}
 
2060
 
 
2061
static void
 
2062
search_tab_new_from_entry_foreach(GtkTreeModel* model,
 
2063
                                  GtkTreePath * path G_GNUC_UNUSED,
 
2064
                                  GtkTreeIter * iter,
 
2065
                                  gpointer      data)
 
2066
{
 
2067
        GqServerDn *set;
 
2068
        int error_context;
 
2069
 
 
2070
        gtk_tree_model_get(model, iter,
 
2071
                           RES_COL_DN, &set,
 
2072
                           -1);
 
2073
 
 
2074
        error_context = error_new_context(_("Creating new entry from search result"), data);
 
2075
 
 
2076
#warning "FIXME: set the parent window somehow"
 
2077
        new_from_entry(gq_server_dn_get_server(set),
 
2078
                       gq_server_dn_get_dn(set));
 
2079
 
 
2080
        error_flush(error_context);
 
2081
}
 
2082
 
 
2083
#warning "FIXME: check whether the widget is necessary if the tab is a widget"
 
2084
static void
 
2085
search_new_from_entry_callback(GtkWidget* w,
 
2086
                               GqTab    * tab G_GNUC_UNUSED)
 
2087
{
 
2088
        GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(tab)->results_treeview));
 
2089
        gtk_tree_selection_selected_foreach(sel, search_tab_new_from_entry_foreach, w);
 
2090
}
 
2091
 
 
2092
static void
 
2093
search_tab_edit_entry_foreach(GtkTreeModel* model,
 
2094
                              GtkTreePath * path G_GNUC_UNUSED,
 
2095
                              GtkTreeIter * iter,
 
2096
                              gpointer      data)
 
2097
{
 
2098
        G_GNUC_UNUSED GqTabSearch* self = GQ_TAB_SEARCH(data);
 
2099
        GqServerDn * set;
 
2100
 
 
2101
        gtk_tree_model_get(model, iter,
 
2102
                           RES_COL_DN, &set,
 
2103
                           -1);
 
2104
 
 
2105
        edit_entry(gq_server_dn_get_server(set),
 
2106
                   gq_server_dn_get_dn(set));
 
2107
}
 
2108
 
 
2109
static void
 
2110
search_edit_entry_callback(GqTabSearch *self)
 
2111
{
 
2112
        GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(self)->results_treeview));
 
2113
        gtk_tree_selection_selected_foreach(sel, search_tab_edit_entry_foreach, self);
 
2114
}
 
2115
 
 
2116
static void
 
2117
delete_search_entry_foreach(GtkTreeModel* model,
 
2118
                            GtkTreePath * path G_GNUC_UNUSED,
 
2119
                            GtkTreeIter * iter,
 
2120
                            gpointer      data)
 
2121
{
 
2122
        GqTabSearch* self = GQ_TAB_SEARCH(data);
 
2123
        GqServerDn *set;
 
2124
        int ctx;
 
2125
 
 
2126
#warning "FIXME: add some way to visualize deleted items and/or deletion problems in the tree"
 
2127
#warning "FIXME: queue items for deletion, delete async and remove items from the search results"
 
2128
        gtk_tree_model_get(model, iter,
 
2129
                           RES_COL_DN, &set,
 
2130
                           -1);
 
2131
 
 
2132
        ctx = error_new_context(_("Deleting entry"),
 
2133
                                P(self)->results_treeview);
 
2134
 
 
2135
        delete_entry(ctx, gq_server_dn_get_server(set),
 
2136
                     gq_server_dn_get_dn(set));
 
2137
 
 
2138
        error_flush(ctx);
 
2139
}
 
2140
 
 
2141
static void
 
2142
delete_search_entry(GqTab *tab)
 
2143
{
 
2144
        GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(P(tab)->results_treeview));
 
2145
        gtk_tree_selection_selected_foreach(sel, delete_search_entry_foreach, tab);
 
2146
}
 
2147
 
 
2148
void
 
2149
fill_out_search(GqTab      * tab,
 
2150
                GqServer   * server,
 
2151
                gchar const* search_base_dn)
 
2152
{
 
2153
#warning "FIXME: take a GqTabSearch as the first parameter"
 
2154
        g_return_if_fail(GQ_IS_TAB_SEARCH(tab));
 
2155
        g_return_if_fail(GQ_IS_SERVER(server));
 
2156
        g_return_if_fail(!search_base_dn || *search_base_dn);
 
2157
 
 
2158
        if (!search_base_dn) {
 
2159
                search_base_dn = server->basedn;
 
2160
        }
 
2161
 
 
2162
        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(tab)->serverlist_combo)->entry), gq_server_get_name(server));
 
2163
        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(tab)->searchbase_combo)->entry), search_base_dn);
 
2164
 
 
2165
        gtk_editable_set_position(GTK_EDITABLE(GTK_COMBO(P(tab)->serverlist_combo)->entry), 0);
 
2166
        gtk_editable_set_position(GTK_EDITABLE(GTK_COMBO(P(tab)->searchbase_combo)->entry), 0);
 
2167
 
 
2168
        /* make tab visible */
 
2169
        go_to_page(tab);
2116
2170
}
2117
2171
 
2118
2172
/* GType */
2119
2173
G_DEFINE_TYPE(GqTabSearch, gq_tab_search, GQ_TYPE_TAB);
2120
2174
 
2121
2175
static void
2122
 
gq_tab_search_init(GqTabSearch* self) {}
2123
 
 
2124
 
static void
2125
 
tab_dispose(GObject* object)
 
2176
gq_tab_search_init(GqTabSearch* self)
2126
2177
{
2127
 
        GqTabSearch* self = GQ_TAB_SEARCH(object);
2128
 
 
2129
 
        if(self->main_clist) {
2130
 
                gtk_clist_clear(GTK_CLIST(self->main_clist));
2131
 
                gtk_widget_destroy(self->main_clist);
2132
 
                self->main_clist = NULL;
2133
 
        }
2134
 
 
2135
 
        G_OBJECT_CLASS(gq_tab_search_parent_class)->dispose(object);
 
2178
        GtkWidget *searchmode_vbox, *table, *scrwin;
 
2179
     GtkWidget *findbutton, *optbutton;
 
2180
        GtkWidget* label;
 
2181
        GtkWidget* paned;
 
2182
#define modeinfo self
 
2183
     const GList *last_attr;
 
2184
        GtkCellRenderer* renderer;
 
2185
        GtkTreeModel* model;
 
2186
        GqTab          * tab = GQ_TAB(self);
 
2187
        gchar* label_text;
 
2188
        gint   i;
 
2189
 
 
2190
 
 
2191
        P(modeinfo)->scope     = state_value_get_int(lastoptions, "scope",
 
2192
                                                  LDAP_SCOPE_SUBTREE);
 
2193
        P(modeinfo)->chase_ref = state_value_get_int(lastoptions, "chase", 1);
 
2194
        P(self)->max_depth = state_value_get_int(lastoptions, "max-depth", 7);
 
2195
        P(self)->last_options_tab = state_value_get_int(lastoptions, "last-options-tab", 0);
 
2196
 
 
2197
     /* copy attribute list */
 
2198
     last_attr = state_value_get_list(lastoptions, "attributes");
 
2199
 
 
2200
        P(self)->attrs = free_list_of_strings(P(self)->attrs);
 
2201
        P(self)->attrs = copy_list_of_strings(last_attr);
 
2202
 
 
2203
     /* setup widgets */
 
2204
     searchmode_vbox = gtk_vbox_new(FALSE, 0);
 
2205
     table = gtk_table_new(2, 5, FALSE);
 
2206
        gtk_container_set_border_width(GTK_CONTAINER(table), 6);
 
2207
        gtk_table_set_row_spacings(GTK_TABLE(table), 6);
 
2208
        gtk_table_set_col_spacings(GTK_TABLE(table), 6);
 
2209
     gtk_widget_show(table);
 
2210
     gtk_box_pack_start(GTK_BOX(searchmode_vbox), table, FALSE, FALSE, 3);
 
2211
 
 
2212
        /* search label */
 
2213
        label = gtk_label_new(NULL);
 
2214
        label_text = g_strdup_printf("<b>%s</b>", _("Search:"));
 
2215
        gtk_label_set_markup(GTK_LABEL(label), label_text);
 
2216
        g_free(label_text);
 
2217
        label_text = NULL;
 
2218
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 
2219
        gtk_widget_show(label);
 
2220
        gtk_table_attach(GTK_TABLE(table), label,
 
2221
                         0,1, 0,1,
 
2222
                         GTK_FILL, GTK_EXPAND,
 
2223
                         0,0);
 
2224
 
 
2225
        model = GTK_TREE_MODEL(gtk_list_store_new(MODE_N_COLUMNS, G_TYPE_INT, G_TYPE_STRING));
 
2226
        for(i = 0; ; i++) {
 
2227
                GtkTreeIter  iter;
 
2228
                gchar const* text = NULL;
 
2229
 
 
2230
                switch(i) {
 
2231
                case GQ_SEARCH_MODE_BEGINS_WITH:
 
2232
                        text = _("Attribute begins with");
 
2233
                        break;
 
2234
                case GQ_SEARCH_MODE_ENDS_WITH:
 
2235
                        text = _("Attribute ends with");
 
2236
                        break;
 
2237
                case GQ_SEARCH_MODE_CONTAINS:
 
2238
                        text = _("Attribute matches");
 
2239
                        break;
 
2240
                case GQ_SEARCH_MODE_EQUALS:
 
2241
                        text = _("Attribute matches exactly");
 
2242
                        break;
 
2243
                default:
 
2244
                        break;
 
2245
                }
 
2246
 
 
2247
                if(text) {
 
2248
                        gtk_list_store_append(GTK_LIST_STORE(model), &iter);
 
2249
                        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
 
2250
                                           MODE_COL_MODE, i,
 
2251
                                           MODE_COL_TEXT, text,
 
2252
                                           -1);
 
2253
                } else {
 
2254
                        break;
 
2255
                }
 
2256
        }
 
2257
        P(tab)->searchmode_combo = gtk_combo_box_new_with_model(model);
 
2258
        gtk_combo_box_set_active(GTK_COMBO_BOX(P(tab)->searchmode_combo), 0);
 
2259
        renderer = gtk_cell_renderer_text_new();
 
2260
        gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(P(tab)->searchmode_combo),
 
2261
                                 renderer,
 
2262
                                 TRUE);
 
2263
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(P(tab)->searchmode_combo),
 
2264
                                       renderer,
 
2265
                                       "text", 1,
 
2266
                                       NULL);
 
2267
        g_object_unref(model);
 
2268
        gtk_widget_show(P(tab)->searchmode_combo);
 
2269
        gtk_table_attach(GTK_TABLE(table), P(tab)->searchmode_combo,
 
2270
                         1,2, 0,1,
 
2271
                         GTK_FILL, GTK_EXPAND | GTK_FILL,
 
2272
                         0,0);
 
2273
 
 
2274
        /* searchterm combo box */
 
2275
        P(tab)->search_combo = gtk_combo_new();
 
2276
        gtk_combo_disable_activate(GTK_COMBO(P(tab)->search_combo));
 
2277
        if(P(self)->history) {
 
2278
                gtk_combo_set_popdown_strings(GTK_COMBO(P(tab)->search_combo), P(self)->history);
 
2279
        }
 
2280
        gtk_widget_show(P(tab)->search_combo);
 
2281
        GTK_WIDGET_SET_FLAGS(GTK_COMBO(P(tab)->search_combo)->entry, GTK_CAN_FOCUS);
 
2282
        GTK_WIDGET_SET_FLAGS(GTK_COMBO(P(tab)->search_combo)->entry, GTK_RECEIVES_DEFAULT);
 
2283
        gtk_table_attach(GTK_TABLE(table), P(tab)->search_combo,
 
2284
                         2,4, 0,1,
 
2285
                         GTK_EXPAND | GTK_FILL, GTK_EXPAND,
 
2286
                         0,0);
 
2287
        g_signal_connect_swapped(GTK_COMBO(P(tab)->search_combo)->entry, "activate",
 
2288
                                 G_CALLBACK(findbutton_clicked_callback), tab);
 
2289
        tab->focus = GTK_COMBO(P(tab)->search_combo)->entry;
 
2290
 
 
2291
        /* server label */
 
2292
        label = gtk_label_new(_("Server"));
 
2293
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 
2294
        gtk_widget_show(label);
 
2295
        gtk_table_attach(GTK_TABLE(table), label,
 
2296
                         0,1, 1,2,
 
2297
                         GTK_FILL, GTK_EXPAND,
 
2298
                         0,0);
 
2299
 
 
2300
        /* LDAP server combo box */
 
2301
        P(self)->serverlist_combo = gtk_combo_box_new();
 
2302
        {
 
2303
                GtkCellRenderer* renderer;
 
2304
                GtkTreeModel* model = gq_server_model_new(gq_server_list_get());
 
2305
                gtk_combo_box_set_model(GTK_COMBO_BOX(P(self)->serverlist_combo),
 
2306
                                        model);
 
2307
                g_object_unref(model);
 
2308
                gtk_combo_box_set_active(GTK_COMBO_BOX(P(self)->serverlist_combo), 0);
 
2309
 
 
2310
                renderer = gtk_cell_renderer_pixbuf_new();
 
2311
                gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(P(self)->serverlist_combo),
 
2312
                                           renderer, FALSE);
 
2313
                gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(P(self)->serverlist_combo), renderer,
 
2314
                                               "icon-name", GQ_SERVER_MODEL_COL_STATUS,
 
2315
                                               NULL);
 
2316
                renderer = gtk_cell_renderer_text_new();
 
2317
                gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(P(self)->serverlist_combo),
 
2318
                                           renderer, TRUE);
 
2319
                gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(P(self)->serverlist_combo),
 
2320
                                               renderer,
 
2321
                                               "text", GQ_SERVER_MODEL_COL_NAME,
 
2322
                                               NULL);
 
2323
        }
 
2324
        gtk_table_attach(GTK_TABLE(table), P(self)->serverlist_combo,
 
2325
                         1,2, 1,2,
 
2326
                         GTK_FILL, GTK_EXPAND,
 
2327
                         0,0);
 
2328
        g_signal_connect_swapped(P(self)->serverlist_combo, "changed",
 
2329
                                 G_CALLBACK(servername_changed_callback), tab);
 
2330
        gtk_widget_show(P(self)->serverlist_combo);
 
2331
 
 
2332
        /* base dn label */
 
2333
        label = gtk_label_new(_("Base DN"));
 
2334
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 
2335
        gtk_widget_show(label);
 
2336
        gtk_table_attach(GTK_TABLE(table), label,
 
2337
                         2,3, 1,2,
 
2338
                         GTK_FILL, GTK_EXPAND,
 
2339
                         0,0);
 
2340
 
 
2341
        /* search base combo box */
 
2342
        P(self)->searchbase_combo = gtk_combo_new();
 
2343
 
 
2344
        if(gq_server_list_n_servers(gq_server_list_get())) {
 
2345
                gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(P(self)->searchbase_combo)->entry),
 
2346
                                   gq_server_list_get_server(gq_server_list_get(), 0)->basedn);
 
2347
        }
 
2348
 
 
2349
        gtk_table_attach(GTK_TABLE(table), P(self)->searchbase_combo,
 
2350
                      3,4, 1,2,
 
2351
                      GTK_EXPAND | GTK_FILL, GTK_EXPAND,
 
2352
                      0,0);
 
2353
        g_signal_connect(GTK_COMBO(P(self)->searchbase_combo)->button, "button_press_event",
 
2354
                        G_CALLBACK(searchbase_button_clicked), tab);
 
2355
        gtk_widget_show(P(self)->searchbase_combo);
 
2356
 
 
2357
     /* find button */
 
2358
     findbutton = gq_button_new_with_label(_("_Find"));
 
2359
     gtk_widget_show(findbutton);
 
2360
     gtk_table_attach(GTK_TABLE(table), findbutton,
 
2361
                      4,5, 0,1,
 
2362
                      GTK_FILL, GTK_EXPAND | GTK_FILL,
 
2363
                      0,0);
 
2364
     gtk_container_border_width(GTK_CONTAINER (findbutton), 0);
 
2365
     g_signal_connect_swapped(findbutton, "clicked",
 
2366
                               G_CALLBACK(findbutton_clicked_callback),
 
2367
                               tab);
 
2368
 
 
2369
     /* Options button */
 
2370
     optbutton = gq_button_new_with_label(_("_Options"));
 
2371
     gtk_widget_show(optbutton);
 
2372
     gtk_table_attach(GTK_TABLE(table), optbutton,
 
2373
                      4,5, 1,2,
 
2374
                      GTK_FILL, GTK_EXPAND | GTK_FILL,
 
2375
                      0,0);
 
2376
     gtk_container_border_width(GTK_CONTAINER (optbutton), 0);
 
2377
     g_signal_connect_swapped(optbutton, "clicked",
 
2378
                               G_CALLBACK(optbutton_clicked_callback),
 
2379
                               tab);
 
2380
 
 
2381
        /* results paned */
 
2382
#warning "FIXME: save the paned position"
 
2383
        paned = gtk_hpaned_new();
 
2384
        gtk_widget_show(paned);
 
2385
        gtk_box_pack_start(GTK_BOX(searchmode_vbox), paned, TRUE, TRUE, 0);
 
2386
 
 
2387
        /* search result display */
 
2388
        /* this is added before the tree, because setting the tree model causes
 
2389
         * a "changed" event on the tree selection wich requires the results
 
2390
         * display to be set */
 
2391
        P(self)->results_display = gq_input_form_new();
 
2392
        gtk_widget_show(P(self)->results_display);
 
2393
        gtk_paned_pack2(GTK_PANED(paned), P(self)->results_display,
 
2394
                        FALSE, FALSE);
 
2395
        gq_input_form_set_editable(GQ_INPUT_FORM(P(self)->results_display), TRUE);
 
2396
 
 
2397
        /* results treeview */
 
2398
        scrwin = gtk_scrolled_window_new(NULL, NULL);
 
2399
        gtk_paned_pack1(GTK_PANED(paned), scrwin,
 
2400
                        TRUE, FALSE);
 
2401
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
 
2402
                                       GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
2403
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwin),
 
2404
                                            GTK_SHADOW_IN);
 
2405
        P(self)->results_treeview = gtk_tree_view_new();
 
2406
        gtk_container_add(GTK_CONTAINER(scrwin), P(self)->results_treeview);
 
2407
        gtk_widget_show_all(scrwin);
 
2408
        g_signal_connect(P(self)->results_treeview, "button-press-event",
 
2409
                         G_CALLBACK(results_button_pressed), self);
 
2410
        gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(P(self)->results_treeview)),
 
2411
                                    GTK_SELECTION_MULTIPLE);
 
2412
        g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(P(self)->results_treeview)), "changed",
 
2413
                         G_CALLBACK(results_selection_changed), self);
 
2414
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(P(self)->results_treeview), -1,
 
2415
                                                    _("Distinguished Name (DN)"), gtk_cell_renderer_text_new(),
 
2416
                                                    "text", RES_COL_NAME,
 
2417
                                                    NULL);
 
2418
#warning "FIXME: add attribute and match columns"
 
2419
#if 0
 
2420
#warning "FIXME: let the tree view support sort columns"
 
2421
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(P(self)->results_treeview), -1,
 
2422
                                                    _("Attribute"), gtk_cell_renderer_text_new(),
 
2423
#warning "FIXME: add the attribute column"
 
2424
                                                    // "text", 0,
 
2425
                                                    NULL);
 
2426
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(P(self)->results_treeview), -1,
 
2427
                                                    _("Match"), gtk_cell_renderer_text_new(),
 
2428
#warning "FIXME: add the match column"
 
2429
                                                    // "text", 0,
 
2430
                                                    NULL);
 
2431
#endif
 
2432
 
 
2433
        P(self)->results_liststore = gtk_list_store_new(RES_N_COLUMNS, G_TYPE_STRING, GQ_TYPE_SERVER_DN);
 
2434
        gtk_tree_view_set_model(GTK_TREE_VIEW(P(self)->results_treeview),
 
2435
                                GTK_TREE_MODEL(P(self)->results_liststore));
 
2436
        g_object_unref(P(self)->results_liststore);
 
2437
 
 
2438
        gtk_widget_show(searchmode_vbox);
 
2439
 
 
2440
     g_signal_connect_swapped(searchmode_vbox, "destroy",
 
2441
                              G_CALLBACK(g_object_unref), tab);
 
2442
 
 
2443
     tab->content = searchmode_vbox;
 
2444
     gtk_object_set_data(GTK_OBJECT(tab->content), "tab", tab);
 
2445
#undef modeinfo
2136
2446
}
2137
2447
 
2138
2448
static void
2140
2450
{
2141
2451
        GqTabSearch* self = GQ_TAB_SEARCH(object);
2142
2452
 
2143
 
        while(self->history) {
2144
 
                g_free(self->history->data);
2145
 
                self->history = g_list_delete_link(self->history, self->history);
2146
 
        }
 
2453
        g_list_foreach(P(self)->history, (GFunc)g_free, NULL);
 
2454
        g_list_free(P(self)->history);
2147
2455
 
2148
2456
        G_OBJECT_CLASS(gq_tab_search_parent_class)->finalize(object);
2149
2457
}
2155
2463
        GObjectClass* object_class = G_OBJECT_CLASS(self_class);
2156
2464
        GqTabClass* tab_class = GQ_TAB_CLASS(self_class);
2157
2465
 
2158
 
        object_class->dispose  = tab_dispose;
2159
2466
        object_class->finalize = tab_finalize;
2160
2467
 
2161
2468
        tab_class->save_snapshot    = search_save_snapshot;
2162
2469
        tab_class->restore_snapshot = search_restore_snapshot;
 
2470
 
 
2471
        g_type_class_add_private(self_class, sizeof(struct GqTabSearchPrivate));
2163
2472
}
2164
2473