f9e1786d7106921660f805b86c8d7bd619973aa0
[samba.git] / source4 / lib / registry / tools / gregedit.c
1 /* 
2    Unix SMB/CIFS implementation.
3    GTK+ registry frontend
4    
5    Copyright (C) Jelmer Vernooij 2004
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #include <gdk/gdkkeysyms.h>
33 #include <gtk/gtk.h>
34 #include "includes.h"
35
36 GtkWidget *openfilewin;
37 GtkWidget *savefilewin;
38 GtkTreeStore *store_keys;
39 GtkListStore *store_vals;
40 GtkWidget *tree_keys;
41 GtkWidget *aboutwin;
42 GtkWidget *mainwin;
43
44 GtkWidget *rpcwin;
45 GtkWidget *rpcwin_host;
46 GtkWidget *rpcwin_user;
47 GtkWidget *rpcwin_password;
48 GtkWidget *save;
49 GtkWidget *save_as;
50 static GtkWidget* create_openfilewin (void);
51 static GtkWidget* create_savefilewin (void);
52 static GtkWidget* create_aboutwin (void);
53 REG_HANDLE *registry = NULL;
54
55 static void gtk_show_werror(WERROR err) 
56 {
57         GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(mainwin), 
58                  GTK_DIALOG_DESTROY_WITH_PARENT,
59          GTK_MESSAGE_ERROR,
60          GTK_BUTTONS_CLOSE,
61                  "Registry error: %s\n", win_errstr(err));
62         gtk_dialog_run (GTK_DIALOG (dialog));
63         gtk_widget_destroy (dialog);
64 }
65
66 static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2)
67 {
68         GtkTreeIter firstiter, iter, tmpiter;
69         REG_KEY *k, *sub;
70         char *name;
71         GValue value;
72         WERROR error;
73         int i;
74
75     gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), &firstiter, parent);
76
77     /* See if this row has ever had a name gtk_tree_store_set()'ed to it.
78        If not, read the directory contents */
79     gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &firstiter, 0, &name, -1);
80
81         if(name) return;
82
83         gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1);
84
85         g_assert(k);
86         
87         for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
88                 int count;
89                 /* Replace the blank child with the first directory entry
90            You may be tempted to remove the blank child node and then 
91            append a new one.  Don't.  If you remove the blank child 
92            node GTK gets confused and won't expand the parent row. */
93
94                 if(i == 0) {
95                         iter = firstiter;
96                 } else {
97                         gtk_tree_store_append(store_keys, &iter, parent);
98                 }
99                 gtk_tree_store_set (store_keys,
100                                             &iter, 
101                                                 0,
102                                                 reg_key_name(sub),
103                                                 1, 
104                                                 sub,
105                                                 -1);
106                 
107                 if(W_ERROR_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0) 
108                         gtk_tree_store_append(store_keys, &tmpiter, &iter);
109         }
110
111         if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
112 }
113
114 static void registry_load_root() 
115 {
116         REG_KEY *root;
117         GtkTreeIter iter, tmpiter;
118         WERROR error = WERR_OK;
119         int i = 0;
120         if(!registry) return;
121
122         gtk_tree_store_clear(store_keys);
123
124         while(1) {
125                 error = reg_get_hive(registry, i, &root);
126                 if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
127                         return;
128                 }
129                 if(!W_ERROR_IS_OK(error)) {
130                         gtk_show_werror(error);
131                         return;
132                 }
133
134                 /* Add the root */
135                 gtk_tree_store_append(store_keys, &iter, NULL);
136                 gtk_tree_store_set (store_keys,
137                                             &iter, 
138                                                 0,
139                                                 reg_key_name(root),
140                                                 1,
141                                                 root,
142                                                 -1);
143
144                 gtk_tree_store_append(store_keys, &tmpiter, &iter);
145                 i++;
146         }
147
148         gtk_widget_set_sensitive( save, True );
149         gtk_widget_set_sensitive( save_as, True );
150 }
151
152 static GtkWidget* create_rpcwin (void)
153 {
154   GtkWidget *dialog_vbox1;
155   GtkWidget *table1;
156   GtkWidget *label1;
157   GtkWidget *label2;
158   GtkWidget *label3;
159   GtkWidget *dialog_action_area1;
160   GtkWidget *cancelbutton1;
161   GtkWidget *okbutton1;
162
163   rpcwin = gtk_dialog_new ();
164   gtk_window_set_title (GTK_WINDOW (rpcwin), "Connect to remote server");
165
166   dialog_vbox1 = GTK_DIALOG (rpcwin)->vbox;
167   gtk_widget_show (dialog_vbox1);
168
169   table1 = gtk_table_new (3, 2, FALSE);
170   gtk_widget_show (table1);
171   gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0);
172
173   label1 = gtk_label_new ("Host:");
174   gtk_widget_show (label1);
175   gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1,
176                     (GtkAttachOptions) (GTK_FILL),
177                     (GtkAttachOptions) (0), 0, 0);
178   gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);
179
180   label2 = gtk_label_new ("User:");
181   gtk_widget_show (label2);
182   gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2,
183                     (GtkAttachOptions) (GTK_FILL),
184                     (GtkAttachOptions) (0), 0, 0);
185   gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
186
187   label3 = gtk_label_new ("Password:");
188   gtk_widget_show (label3);
189   gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3,
190                     (GtkAttachOptions) (GTK_FILL),
191                     (GtkAttachOptions) (0), 0, 0);
192   gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
193
194   rpcwin_host = gtk_entry_new ();
195   gtk_widget_show (rpcwin_host);
196   gtk_table_attach (GTK_TABLE (table1), rpcwin_host, 1, 2, 0, 1,
197                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
198                     (GtkAttachOptions) (0), 0, 0);
199
200   rpcwin_user = gtk_entry_new ();
201   gtk_widget_show (rpcwin_user);
202   gtk_table_attach (GTK_TABLE (table1), rpcwin_user, 1, 2, 1, 2,
203                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
204                     (GtkAttachOptions) (0), 0, 0);
205
206   rpcwin_password = gtk_entry_new ();
207   gtk_widget_show (rpcwin_password);
208   gtk_table_attach (GTK_TABLE (table1), rpcwin_password, 1, 2, 2, 3,
209                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
210                     (GtkAttachOptions) (0), 0, 0);
211   gtk_entry_set_visibility (GTK_ENTRY (rpcwin_password), FALSE);
212
213   dialog_action_area1 = GTK_DIALOG (rpcwin)->action_area;
214   gtk_widget_show (dialog_action_area1);
215   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
216
217   cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
218   gtk_widget_show (cancelbutton1);
219   gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), cancelbutton1, GTK_RESPONSE_CANCEL);
220   GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);
221
222   okbutton1 = gtk_button_new_from_stock ("gtk-ok");
223   gtk_widget_show (okbutton1);
224   gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), okbutton1, GTK_RESPONSE_OK);
225   GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);
226
227   return rpcwin;
228 }
229
230 static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data)
231 {
232         gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin()));
233         char *filename;
234         WERROR error;
235         switch(result) {
236         case GTK_RESPONSE_OK:
237                 filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin)));
238                 error = reg_open(user_data, filename, NULL, &registry);
239                 if(!W_ERROR_IS_OK(error)) {
240                         gtk_show_werror(error);
241                         break;
242                 }
243                 registry_load_root();
244                 break;
245         default:
246                 break;
247         }
248
249         gtk_widget_destroy(openfilewin);
250 }
251
252 static void on_open_gconf_activate                       (GtkMenuItem     *menuitem,
253                                                       gpointer         user_data)
254 {
255         WERROR error = reg_open("gconf", NULL, NULL, &registry);
256         if(!W_ERROR_IS_OK(error)) {
257                 gtk_show_werror(error);
258                 return;
259         }
260
261         registry_load_root();
262 }
263
264 static void on_open_remote_activate                (GtkMenuItem     *menuitem,
265                                                                                 gpointer         user_data)
266 {
267         char *location, *credentials;
268         gint result = gtk_dialog_run(GTK_DIALOG(create_rpcwin()));
269         WERROR error;
270         switch(result) {
271         case GTK_RESPONSE_OK:
272                 asprintf(&location, "ncacn_np:%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_host)));
273                 asprintf(&credentials, "%s%%%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_user)), gtk_entry_get_text(GTK_ENTRY(rpcwin_password)));
274                 error = reg_open("rpc", location, credentials, &registry);
275                 if(!W_ERROR_IS_OK(error)) {
276                         gtk_show_werror(error);
277                         break;
278                 }
279                 free(location); free(credentials);
280                 registry_load_root();
281                 break;
282         default:
283                 break;
284         }
285
286         gtk_widget_destroy(rpcwin);
287 }
288
289
290 static void on_save_activate                       (GtkMenuItem     *menuitem,
291                                                                                 gpointer         user_data)
292 {
293         WERROR error = reg_save(registry, NULL);
294         if(!W_ERROR_IS_OK(error)) {
295                 gtk_show_werror(error);
296         }
297 }
298
299
300 static void on_save_as_activate                    (GtkMenuItem     *menuitem,
301                                                                                 gpointer         user_data)
302 {
303         gint result;
304         WERROR error;
305         create_savefilewin();
306         result = gtk_dialog_run(GTK_DIALOG(savefilewin));
307         switch(result) {
308         case GTK_RESPONSE_OK:
309                 error = reg_save(registry, gtk_file_selection_get_filename(GTK_FILE_SELECTION(savefilewin)));
310                 if(!W_ERROR_IS_OK(error)) {
311                         gtk_show_werror(error);
312                 }
313                 break;
314
315         default:
316                 break;
317
318         }
319         gtk_widget_destroy(savefilewin);
320 }
321
322
323 static void on_quit_activate                       (GtkMenuItem     *menuitem,
324                                                                                 gpointer         user_data)
325 {
326         gtk_main_quit();
327 }
328
329
330 static void on_cut_activate                        (GtkMenuItem     *menuitem,
331                                                                                 gpointer         user_data)
332 {
333         /* FIXME */
334 }
335
336
337 static void on_copy_activate                       (GtkMenuItem     *menuitem,
338                                                                                 gpointer         user_data)
339 {
340         /* FIXME */
341 }
342
343
344 static void on_paste_activate                      (GtkMenuItem     *menuitem,
345                                                                                 gpointer         user_data)
346 {
347         /* FIXME */
348 }
349
350
351 static void on_delete_activate                     (GtkMenuItem     *menuitem,
352                                                                                 gpointer         user_data)
353 {
354         /* FIXME */
355 }
356
357
358 static void on_about_activate                      (GtkMenuItem     *menuitem,
359                                                                                 gpointer         user_data)
360 {
361         gtk_dialog_run(GTK_DIALOG(create_aboutwin()));
362         gtk_widget_destroy(aboutwin);
363 }
364
365 static void on_key_activate (GtkTreeView *treeview,
366                                           GtkTreePath *path,
367                                           gpointer user_data)
368 {
369         int i;
370         REG_KEY *k;
371         REG_VAL *val;
372         WERROR error;
373         GtkTreeIter parent;
374
375         gtk_tree_model_get_iter(GTK_TREE_MODEL(store_keys), &parent, path);
376         gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &parent, 1, &k, -1);
377
378         g_assert(k);
379
380         gtk_list_store_clear(store_vals);
381
382         for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) {
383                 GtkTreeIter iter;
384                 gtk_list_store_append(store_vals, &iter);
385                 gtk_list_store_set (store_vals,
386                                             &iter, 
387                                                 0,
388                                                 reg_val_name(val),
389                                                 1,
390                                                 str_regtype(reg_val_type(val)),
391                                                 2,
392                                                 reg_val_data_string(val),
393                                                 3, 
394                                                 val,
395                                                 -1);
396         }
397
398         if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
399 }
400
401 static GtkWidget* create_mainwin (void)
402 {
403         GtkWidget *vbox1;
404         GtkWidget *menubar;
405         GtkWidget *menu_file;
406         GtkWidget *menu_file_menu;
407         GtkWidget *open_nt4;
408         GtkWidget *open_w95;
409         GtkWidget *open_gconf;
410         GtkWidget *open_remote;
411         GtkWidget *separatormenuitem1;
412         GtkWidget *quit;
413         GtkWidget *men_edit;
414         GtkWidget *men_edit_menu;
415         GtkWidget *cut;
416         GtkWidget *copy;
417         GtkWidget *paste;
418         GtkWidget *delete;
419         GtkCellRenderer *renderer;
420         GtkTreeViewColumn *curcol;
421         GtkWidget *help;
422         GtkWidget *help_menu;
423         GtkWidget *about;
424         GtkWidget *hbox1;
425         GtkWidget *scrolledwindow1;
426         GtkWidget *scrolledwindow2;
427         GtkWidget *tree_vals;
428         GtkWidget *statusbar;
429         GtkAccelGroup *accel_group;
430         GtkTreeIter iter, child;
431
432         accel_group = gtk_accel_group_new ();
433
434         mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
435         gtk_window_set_title (GTK_WINDOW (mainwin), "Registry editor");
436         gtk_window_set_default_size (GTK_WINDOW (mainwin), 642, 562);
437
438         vbox1 = gtk_vbox_new (FALSE, 0);
439         gtk_widget_show (vbox1);
440         gtk_container_add (GTK_CONTAINER (mainwin), vbox1);
441
442         menubar = gtk_menu_bar_new ();
443         gtk_widget_show (menubar);
444         gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0);
445
446         menu_file = gtk_menu_item_new_with_mnemonic ("_File");
447         gtk_widget_show (menu_file);
448         gtk_container_add (GTK_CONTAINER (menubar), menu_file);
449
450         menu_file_menu = gtk_menu_new ();
451         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu);
452
453         if(reg_has_backend("nt4")) {
454                 open_nt4 = gtk_image_menu_item_new_with_mnemonic("Open _NT4 file");
455                 gtk_widget_show (open_nt4);
456                 gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4);
457
458                 g_signal_connect ((gpointer) open_nt4, "activate",
459                     G_CALLBACK (on_open_file_activate),
460                     "nt4");
461         }
462
463         if(reg_has_backend("w95")) {
464                 open_w95 = gtk_image_menu_item_new_with_mnemonic("Open Win_9x file");
465                 gtk_widget_show (open_w95);
466                 gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95);
467
468                 g_signal_connect ((gpointer) open_w95, "activate",
469                     G_CALLBACK (on_open_file_activate),
470                     "w95");
471         }
472
473         if(reg_has_backend("gconf")) {
474                 open_gconf = gtk_image_menu_item_new_with_mnemonic ("Open _GConf");
475                 gtk_widget_show (open_gconf);
476                 gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf);
477
478                 g_signal_connect ((gpointer) open_gconf, "activate",
479                     G_CALLBACK (on_open_gconf_activate),
480                     NULL);
481         }
482
483         if(reg_has_backend("rpc")) {
484                 open_remote = gtk_menu_item_new_with_mnemonic ("Open _Remote");
485                 gtk_widget_show (open_remote);
486                 gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote);
487
488                 g_signal_connect ((gpointer) open_remote, "activate",
489                     G_CALLBACK (on_open_remote_activate),
490                     NULL);
491         }
492
493         save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
494         gtk_widget_show (save);
495         gtk_widget_set_sensitive( save, False );
496         gtk_container_add (GTK_CONTAINER (menu_file_menu), save);
497
498         save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
499         gtk_widget_show (save_as);
500         gtk_widget_set_sensitive( save_as, False );
501         gtk_container_add (GTK_CONTAINER (menu_file_menu), save_as);
502
503         separatormenuitem1 = gtk_menu_item_new ();
504         gtk_widget_show (separatormenuitem1);
505         gtk_container_add (GTK_CONTAINER (menu_file_menu), separatormenuitem1);
506         gtk_widget_set_sensitive (separatormenuitem1, FALSE);
507
508         quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
509         gtk_widget_show (quit);
510         gtk_container_add (GTK_CONTAINER (menu_file_menu), quit);
511
512         men_edit = gtk_menu_item_new_with_mnemonic ("_Edit");
513         gtk_widget_show (men_edit);
514         gtk_container_add (GTK_CONTAINER (menubar), men_edit);
515
516   men_edit_menu = gtk_menu_new ();
517   gtk_menu_item_set_submenu (GTK_MENU_ITEM (men_edit), men_edit_menu);
518
519   cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
520   gtk_widget_show (cut);
521   gtk_widget_set_sensitive(cut, False);
522   gtk_container_add (GTK_CONTAINER (men_edit_menu), cut);
523
524   copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
525   gtk_widget_show (copy);
526   gtk_widget_set_sensitive(copy, False);
527   gtk_container_add (GTK_CONTAINER (men_edit_menu), copy);
528
529   paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
530   gtk_widget_show (paste);
531   gtk_widget_set_sensitive(paste, False);
532   gtk_container_add (GTK_CONTAINER (men_edit_menu), paste);
533
534   delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
535   gtk_widget_show (delete);
536   gtk_widget_set_sensitive(delete, False);
537   gtk_container_add (GTK_CONTAINER (men_edit_menu), delete);
538
539   help = gtk_menu_item_new_with_mnemonic ("_Help");
540   gtk_widget_show (help);
541   gtk_container_add (GTK_CONTAINER (menubar), help);
542
543   help_menu = gtk_menu_new ();
544   gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu);
545
546   about = gtk_menu_item_new_with_mnemonic ("_About");
547   gtk_widget_show (about);
548   gtk_container_add (GTK_CONTAINER (help_menu), about);
549
550   hbox1 = gtk_hbox_new (FALSE, 0);
551   gtk_widget_show (hbox1);
552   gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
553
554   scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
555   gtk_widget_show (scrolledwindow1);
556   gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
557
558   tree_keys = gtk_tree_view_new ();
559
560   /* Column names */
561   curcol = gtk_tree_view_column_new ();
562   gtk_tree_view_column_set_title(curcol, "Name");
563   renderer = gtk_cell_renderer_text_new();
564   gtk_tree_view_column_pack_start(curcol, renderer, True);
565
566   gtk_tree_view_append_column(GTK_TREE_VIEW(tree_keys), curcol);
567
568   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0);
569   gtk_widget_show (tree_keys);
570   gtk_container_add (GTK_CONTAINER (scrolledwindow1), tree_keys);
571   store_keys = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
572   gtk_tree_view_set_model(GTK_TREE_VIEW(tree_keys), GTK_TREE_MODEL(store_keys));
573   g_object_unref(store_keys);
574
575   g_signal_connect ((gpointer) tree_keys, "row-activated",
576                     G_CALLBACK (on_key_activate),
577                     NULL);
578
579   g_signal_connect ((gpointer) tree_keys, "row-expanded",
580                     G_CALLBACK (expand_key),
581                     NULL);
582
583   scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
584   gtk_widget_show (scrolledwindow2);
585   gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0);
586
587   tree_vals = gtk_tree_view_new ();
588     /* Column names */
589
590   curcol = gtk_tree_view_column_new ();
591   gtk_tree_view_column_set_title(curcol, "Name");
592   renderer = gtk_cell_renderer_text_new();
593   gtk_tree_view_column_pack_start(curcol, renderer, True);
594   gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
595   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0);
596
597   curcol = gtk_tree_view_column_new ();
598   gtk_tree_view_column_set_title(curcol, "Type");
599   renderer = gtk_cell_renderer_text_new();
600   gtk_tree_view_column_pack_start(curcol, renderer, True);
601   gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
602   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 1);
603
604   curcol = gtk_tree_view_column_new ();
605   gtk_tree_view_column_set_title(curcol, "Value");
606   renderer = gtk_cell_renderer_text_new();
607   gtk_tree_view_column_pack_start(curcol, renderer, True);
608   gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
609   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 2);
610
611   
612   gtk_widget_show (tree_vals);
613   gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals);
614
615   store_vals = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
616   gtk_tree_view_set_model(GTK_TREE_VIEW(tree_vals), GTK_TREE_MODEL(store_vals));
617   g_object_unref(store_vals);
618
619   statusbar = gtk_statusbar_new ();
620   gtk_widget_show (statusbar);
621   gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0);
622   gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE);
623
624   g_signal_connect ((gpointer) save, "activate",
625                     G_CALLBACK (on_save_activate),
626                     NULL);
627   g_signal_connect ((gpointer) save_as, "activate",
628                     G_CALLBACK (on_save_as_activate),
629                     NULL);
630   g_signal_connect ((gpointer) quit, "activate",
631                     G_CALLBACK (on_quit_activate),
632                     NULL);
633   g_signal_connect ((gpointer) cut, "activate",
634                     G_CALLBACK (on_cut_activate),
635                     NULL);
636   g_signal_connect ((gpointer) copy, "activate",
637                     G_CALLBACK (on_copy_activate),
638                     NULL);
639   g_signal_connect ((gpointer) paste, "activate",
640                     G_CALLBACK (on_paste_activate),
641                     NULL);
642   g_signal_connect ((gpointer) delete, "activate",
643                     G_CALLBACK (on_delete_activate),
644                     NULL);
645   g_signal_connect ((gpointer) about, "activate",
646                     G_CALLBACK (on_about_activate),
647                     NULL);
648
649   gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group);
650
651   return mainwin;
652 }
653
654 static GtkWidget* create_aboutwin (void)
655 {
656   GtkWidget *dialog_vbox1;
657   GtkWidget *image1;
658   GtkWidget *label1;
659   GtkWidget *label2;
660   GtkWidget *dialog_action_area1;
661   GtkWidget *closebutton1;
662
663   aboutwin = gtk_dialog_new ();
664   gtk_window_set_title (GTK_WINDOW (aboutwin), "About GRegEdit");
665   gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE);
666
667   dialog_vbox1 = GTK_DIALOG (aboutwin)->vbox;
668   gtk_widget_show (dialog_vbox1);
669
670   /* FIXME: Samba logo ? 
671   image1 = create_pixmap (aboutwin, "samba.png");
672   gtk_widget_show (image1);
673   gtk_box_pack_start (GTK_BOX (dialog_vbox1), image1, FALSE, TRUE, 0); */
674
675   label1 = gtk_label_new ("GRegEdit 0.1");
676   gtk_widget_show (label1);
677   gtk_box_pack_start (GTK_BOX (dialog_vbox1), label1, FALSE, FALSE, 0);
678   gtk_label_set_use_markup (GTK_LABEL (label1), TRUE);
679
680   label2 = gtk_label_new_with_mnemonic ("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\nPart of Samba\nhttp://www.samba.org/\n");
681   gtk_widget_show (label2);
682   gtk_box_pack_start (GTK_BOX (dialog_vbox1), label2, TRUE, FALSE, 0);
683   gtk_label_set_use_markup (GTK_LABEL (label2), TRUE);
684
685   dialog_action_area1 = GTK_DIALOG (aboutwin)->action_area;
686   gtk_widget_show (dialog_action_area1);
687   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
688
689   closebutton1 = gtk_button_new_from_stock ("gtk-close");
690   gtk_widget_show (closebutton1);
691   gtk_dialog_add_action_widget (GTK_DIALOG (aboutwin), closebutton1, GTK_RESPONSE_CLOSE);
692   GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT);
693
694   return aboutwin;
695 }
696
697
698 static GtkWidget* create_openfilewin (void)
699 {
700   GtkWidget *ok_button;
701   GtkWidget *cancel_button;
702
703   openfilewin = gtk_file_selection_new ("Select File");
704   gtk_container_set_border_width (GTK_CONTAINER (openfilewin), 10);
705
706   ok_button = GTK_FILE_SELECTION (openfilewin)->ok_button;
707   gtk_widget_show (ok_button);
708   GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
709
710   cancel_button = GTK_FILE_SELECTION (openfilewin)->cancel_button;
711   gtk_widget_show (cancel_button);
712   GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
713
714   return openfilewin;
715 }
716
717 static GtkWidget* create_savefilewin (void)
718 {
719   GtkWidget *ok_button;
720   GtkWidget *cancel_button;
721
722   savefilewin = gtk_file_selection_new ("Select File");
723   gtk_container_set_border_width (GTK_CONTAINER (savefilewin), 10);
724
725   ok_button = GTK_FILE_SELECTION (savefilewin)->ok_button;
726   gtk_widget_show (ok_button);
727   GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
728
729   cancel_button = GTK_FILE_SELECTION (savefilewin)->cancel_button;
730   gtk_widget_show (cancel_button);
731   GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
732
733   return savefilewin;
734 }
735
736  int main(int argc, char *argv[])
737 {
738   poptContext pc;
739   const char *backend = NULL;
740   const char *credentials = NULL;
741   const char *location;
742   int opt;
743   struct poptOption long_options[] = {
744        POPT_AUTOHELP
745        {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
746            {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%%password)", NULL},
747        POPT_TABLEEND
748     };
749                                                                               
750     gtk_init (&argc, &argv);
751
752     pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
753                                                                               
754     while((opt = poptGetNextOpt(pc)) != -1) {
755     }
756
757         location = poptGetArg(pc);
758
759         if(location) {
760                 WERROR error;
761
762                 if(!backend) {
763                         if(credentials)backend = "rpc";
764                         else backend = "nt4";
765                 }
766                 
767                 error = reg_open(backend, location, credentials, &registry);
768                 if(!W_ERROR_IS_OK(error)) {
769                         gtk_show_werror(error);
770                         return -1;
771                 }
772                 mainwin = create_mainwin ();
773                 registry_load_root();
774         } else 
775                 mainwin = create_mainwin ();
776
777         gtk_widget_show (mainwin);
778
779         gtk_main ();
780
781         if(registry)reg_free(registry);
782         return 0;
783 }