1 /*
2 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
3 * Copyright (C) 2011 Vivien Malerba <malerba@gnome-db.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include <gtk/gtk.h>
20 #include <string.h>
21 #include <libgda-ui/libgda-ui.h>
main(int,char **)22 #include <libgda/libgda.h>
23 #include <libgda/virtual/gda-ldap-connection.h>
24
25 gchar *host = NULL;
26 gchar *base = NULL;
27 gchar *user = NULL;
28 gchar *password = NULL;
29 gboolean usessl = FALSE;
30
31 static GOptionEntry entries[] = {
32 { "server", 'h', 0, G_OPTION_ARG_STRING, &host, "Server", NULL},
33 { "basename", 'b', 0, G_OPTION_ARG_STRING, &base, "Base name", NULL},
34 { "user", 'u', 0, G_OPTION_ARG_STRING, &user, "User", NULL},
35 { "password", 'p', 0, G_OPTION_ARG_STRING, &password, "Password", NULL},
36 { "usessl", 's', 0, G_OPTION_ARG_NONE, &usessl, "Use SSL", NULL},
37 { NULL }
38 };
39
40
41 static GdaConnection *
42 open_ldap_connection ()
43 {
44 GString *cncstring = NULL;
45 gchar *enc;
46 GdaConnection *cnc;
47 GError *error = NULL;
48
49 if (host) {
50 cncstring = g_string_new ("");
51 enc = gda_rfc1738_encode (host);
52 g_string_append_printf (cncstring, "HOST=%s", enc);
53 g_free (enc);
54 }
55
56 if (base) {
57 if (cncstring)
58 g_string_append_c (cncstring, ';');
59 else
60 cncstring = g_string_new ("");
61 enc = gda_rfc1738_encode (base);
62 g_string_append_printf (cncstring, "DB_NAME=%s", enc);
63 g_free (enc);
64 }
65
66 if (user) {
67 if (cncstring)
68 g_string_append_c (cncstring, ';');
69 else
70 cncstring = g_string_new ("");
71 enc = gda_rfc1738_encode (user);
72 g_string_append_printf (cncstring, "USERNAME=%s", enc);
73 g_free (enc);
74 }
75
76 if (password) {
77 if (cncstring)
78 g_string_append_c (cncstring, ';');
79 else
80 cncstring = g_string_new ("");
81 enc = gda_rfc1738_encode (password);
82 g_string_append_printf (cncstring, "PASSWORD=%s", enc);
83 g_free (enc);
84 }
85
86 if (usessl) {
87 if (cncstring)
88 g_string_append_c (cncstring, ';');
89 else
90 cncstring = g_string_new ("");
91 g_string_append (cncstring, "USER_SSL=TRUE");
92 }
93
94 if (! cncstring) {
95 g_print ("No connection specified!\n");
96 exit (1);
97 }
98
99 g_print ("Using connection string: %s\n", cncstring->str);
100 cnc = gda_connection_open_from_string ("Ldap", cncstring->str,
101 NULL,
102 GDA_CONNECTION_OPTIONS_NONE, &error);
103 if (!cnc) {
104 g_print ("Error opening connection (cncstring=[%s]): %s\n",
105 cncstring->str,
106 error && error->message ? error->message : "No detail");
107 exit (1);
108 }
109 g_string_free (cncstring, TRUE);
110
111 return cnc;
112 }
113
114 typedef struct {
115 GtkTreeView *tview;
116 GdauiTreeStore *store;
117 GdaTree *tree;
118 GdaTreeNode *node;
119 } IdleData;
120
121 static void
122 idle_data_free (IdleData *data)
123 {
124 g_object_unref (data->tview);
125 g_object_unref (data->store);
126 g_object_unref (data->tree);
127 g_object_unref (data->node);
128 g_free (data);
129 }
130
131 static gboolean ldap_update_tree_part (IdleData *data);
132 static gboolean
133 test_expand_row_cb (GtkTreeView *tree_view, GtkTreeIter *iter,
134 G_GNUC_UNUSED GtkTreePath *path, GdaTree *tree)
135 {
136 GdaTreeNode *node;
137 GtkTreeModel *store;
138
139 store = gtk_tree_view_get_model (tree_view);
140 node = gdaui_tree_store_get_node (GDAUI_TREE_STORE (store), iter);
141 if (gda_tree_node_get_child_index (node, 0))
142 return FALSE;
143
144 const GValue *cv;
145 cv = gda_tree_node_get_node_attribute (node,
146 GDA_ATTRIBUTE_TREE_NODE_UNKNOWN_CHILDREN);
147 if (cv && (G_VALUE_TYPE (cv) == G_TYPE_BOOLEAN) &&
148 g_value_get_boolean (cv)) {
149 IdleData *data;
150 data = g_new (IdleData, 1);
151 data->tview = g_object_ref (G_OBJECT (tree_view));
152 data->store = g_object_ref (G_OBJECT (store));
153 data->tree = g_object_ref (G_OBJECT (tree));
154 data->node = g_object_ref (G_OBJECT (node));
155
156 g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc) ldap_update_tree_part,
157 data, (GDestroyNotify) idle_data_free);
158 }
159 return TRUE;
160 }
161
162 static gboolean
163 ldap_update_tree_part (IdleData *data)
164 {
165 gda_tree_update_children (data->tree, data->node, NULL);
166
167 GtkTreeIter iter;
168 if (gdaui_tree_store_get_iter (data->store, &iter, data->node) &&
169 gda_tree_node_get_child_index (data->node, 0)) {
170 GtkTreePath *path;
171 path = gtk_tree_model_get_path (GTK_TREE_MODEL (data->store), &iter);
172 g_signal_handlers_block_by_func (data->tview,
173 G_CALLBACK (test_expand_row_cb), data->tree);
174 gtk_tree_view_expand_row (data->tview, path, FALSE);
175 g_signal_handlers_unblock_by_func (data->tview,
176 G_CALLBACK (test_expand_row_cb), data->tree);
177 gtk_tree_path_free (path);
178 }
179
180 return FALSE;
181 }
182
183 static void
184 selection_changed_cb (GtkTreeSelection *sel, GdauiTreeStore *store)
185 {
186 GtkTreeIter iter;
187 if (gtk_tree_selection_get_selected (sel, NULL, &iter)) {
188 gchar *rdn;
189 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &rdn, -1);
190 g_print ("Selected RDN: %s\n", rdn);
191 g_free (rdn);
192
193 GdaTreeNode *node;
194 const GValue *cvalue;
195 node = gdaui_tree_store_get_node (store, &iter);
196 g_assert (node);
197 cvalue = gda_tree_node_get_node_attribute (node, "dn");
198 g_assert (cvalue);
199 g_print (" DN: %s\n", g_value_get_string (cvalue));
200 }
201 }
202
203 static GtkWidget *
204 create_window (GdaConnection *cnc)
205 {
206 GtkWidget *win = NULL;
207
208 /* Window */
209 win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
210 gtk_window_set_title (GTK_WINDOW (win), "LDAP Browser");
211 gtk_window_set_default_size (GTK_WINDOW (win), 640, 480);
212 gtk_container_set_border_width (GTK_CONTAINER (win), 5);
213 gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
214 g_signal_connect (G_OBJECT (win), "destroy", gtk_main_quit, NULL);
215
216 /* container */
217 GtkWidget *vb, *hp;
218 vb = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
219 gtk_container_add (GTK_CONTAINER (win), vb);
220 hp = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
221 gtk_box_pack_start (GTK_BOX (vb), hp, TRUE, TRUE, 0);
222
223 GdaTree *tree;
224 GdaTreeManager *mgr;
225 GtkTreeModel *store;
226 GtkWidget *tview, *sw;
227 GtkCellRenderer *renderer;
228 GtkTreeViewColumn *column;
229
230 tree = gda_tree_new ();
231 mgr = gda_tree_mgr_ldap_new (cnc, NULL);
232 gda_tree_add_manager (tree, mgr);
233 gda_tree_manager_add_manager (mgr, mgr);
234 g_object_unref (mgr);
235
236 gda_tree_update_children (tree, NULL, NULL);
237
238 store = gdaui_tree_store_new (tree, 1, G_TYPE_STRING, "rdn");
239 g_object_unref (tree);
240 tview = gtk_tree_view_new_with_model (store);
241 g_signal_connect (tview, "test-expand-row",
242 G_CALLBACK (test_expand_row_cb), tree);
243
244 renderer = gtk_cell_renderer_text_new ();
245 column = gtk_tree_view_column_new_with_attributes ("DN", renderer, "text", 0, NULL);
246 gtk_tree_view_append_column (GTK_TREE_VIEW (tview), column);
247 gtk_tree_view_set_expander_column (GTK_TREE_VIEW (tview), column);
248
249 sw = gtk_scrolled_window_new (NULL, NULL);
250 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC,
251 GTK_POLICY_AUTOMATIC);
252 gtk_container_add (GTK_CONTAINER (sw), tview);
253 gtk_paned_add1 (GTK_PANED (hp), sw);
254
255 /* selection */
256 GtkTreeSelection *sel;
257 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tview));
258 gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
259 g_signal_connect (sel, "changed",
260 G_CALLBACK (selection_changed_cb), store);
261
262 gtk_widget_show_all (vb);
263
264 return win;
265 }
266
267 /*
268 * Entree du programme:
269 */
270 int main (int argc, char ** argv)
271 {
272 GdaConnection *cnc;
273 GOptionContext *context;
274 GError *error = NULL;
275
276 context = g_option_context_new (NULL);
277 g_option_context_add_main_entries (context, entries, NULL);
278 if (!g_option_context_parse (context, &argc, &argv, &error)) {
279 g_print ("Can't parse arguments: %s", error->message);
280 exit (1);
281 }
282 g_option_context_free (context);
283
284 gtk_init (& argc, & argv);
285 gdaui_init ();
286
287 cnc = open_ldap_connection ();
288 gtk_widget_show (create_window (cnc));
289 gtk_main ();
290
291 g_object_unref (cnc);
292
293 return 0;
294 }
295