]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/gnome2-console/restore.c
First cut restore GUI
[bacula/bacula] / bacula / src / gnome2-console / restore.c
1 /*
2  * Handle console GUI selection of files
3  *  Kern Sibbald, March, 2004
4  *
5 */
6
7 #include "bacula.h"
8 #include "console.h"
9 #include "interface.h"
10 #include "support.h"
11 #include "restore.h"
12
13 extern BSOCK *UA_sock;
14 void write_director(gchar *msg);
15 void start_director_reader(gpointer data);
16 void stop_director_reader(gpointer data);
17
18
19 /* Forward referenced subroutines */
20 void FillDirectory(char *path, Window *window);
21 Window *new_window();
22 static void click_column_cb(GtkCList *item, gint column, Window *restore);
23 static void select_row_cb(GtkCList *item, gint row, gint column, 
24              GdkEventButton *event, Window *restore);
25 void row_data_destroy_cb(gpointer data);
26 void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl,
27         POOLMEM **file, int *fnl);
28
29 #ifdef needed
30 static GdkPixmap *check_pixmap = NULL;
31 static GdkPixmap *check_trans = NULL;
32 static GdkPixmap *blank_pixmap = NULL;
33 static GdkPixmap *blank_trans = NULL;
34 #endif
35          
36 static GtkWidget *restore_dir;        /* current directory edit box */
37 static GtkWidget *scrolled;           /* select files scrolled window */
38 static Window *restore;
39
40 const int NUM_COLUMNS = 7;
41 const int CHECK_COLUMN = 0;
42 const int FILE_COLUMN = 1;
43 const int MODES_COLUMN = 2;
44 const int DATE_COLUMN = 6;
45
46
47 /*
48  * Read Director output and discard it until next prompt
49  */
50 static void discard_to_prompt()
51 {
52    while (bnet_recv(UA_sock) > 0) {
53    }
54 }
55
56 /*
57  * Move up one directory   
58  */
59 void
60 on_restore_up_button_clicked(GtkButton *button, gpointer user_data)
61 {
62    split_path_and_filename(restore->fname, &restore->path, &restore->pnl,
63                               &restore->file, &restore->fnl);
64    FillDirectory(restore->path, restore);
65 }
66
67 void
68 on_restore_add_button_clicked(GtkButton *button, gpointer user_data)
69 {
70
71 }
72
73
74 void
75 on_restore_remove_button_clicked(GtkButton *button, gpointer user_data)
76 {
77
78 }
79
80 /*
81  * Called once at the beginning of the program for setup
82  */
83 void select_restore_setup()
84 {
85    gchar *title[NUM_COLUMNS] = {"Mark", "File", "Mode", "User", "Group", "Size", "Date"};
86
87    restore_file_selection = create_restore_file_selection();
88    if (!restore_file_selection) {
89       Dmsg0(000, "Restore_files not setup.\n");
90    }
91    restore_dir = lookup_widget(restore_file_selection, "restore_dir");
92    scrolled = lookup_widget(restore_file_selection, "scrolled");
93    if (!scrolled) {
94       Dmsg0(000, "Scrolled not setup.\n");
95    }
96
97    restore = new_window();
98
99 #ifdef needed
100    check_pixmap = gdk_pixmap_colormap_create_from_xpm(NULL, 
101                   gdk_colormap_get_system(), &check_trans, NULL,
102                   "check.xpm");
103    blank_pixmap = gdk_pixmap_colormap_create_from_xpm(NULL, 
104                   gdk_colormap_get_system(), &blank_trans, NULL,
105                   "blank.xpm");
106 #endif
107
108    restore->list = (GtkCList *)gtk_clist_new_with_titles(NUM_COLUMNS, title);
109    gtk_clist_set_selection_mode(restore->list, GTK_SELECTION_EXTENDED);
110    gtk_clist_set_sort_column(restore->list, FILE_COLUMN);
111    gtk_clist_set_auto_sort(restore->list, true);
112    gtk_signal_connect(GTK_OBJECT(restore->list), "click_column", 
113                       G_CALLBACK(click_column_cb), restore);
114    gtk_signal_connect(GTK_OBJECT(restore->list), "select_row", 
115                       G_CALLBACK(select_row_cb), restore);
116
117    gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(restore->list));
118    restore->buf   = get_pool_memory(PM_FNAME);
119    restore->fname = get_pool_memory(PM_FNAME);
120    restore->path  = get_pool_memory(PM_NAME);
121    restore->file  = get_pool_memory(PM_NAME);
122 }
123
124 /*
125  * Select files dialog called
126  */
127 void select_restore_files()
128 {
129    discard_to_prompt();
130    set_restore_dialog_defaults();
131    gtk_widget_show(GTK_WIDGET(restore->list));
132    FillDirectory("/", restore);
133    gtk_main();
134 }
135
136
137 /*
138  * Fill the CList box with files at path
139  */
140 void FillDirectory(char *path, Window *restore)
141 {
142    char pathbuf[MAXSTRING];
143    char modes[20], user[20], group[20], size[20], date[30];
144    char file[1000];
145    char marked[10];
146    gchar *text[NUM_COLUMNS] = {marked, file, modes, user, group, size, date};
147    GtkCList *list = restore->list;
148    int row = 0;
149    
150    stop_director_reader(NULL);         
151    pm_strcpy(&restore->fname, path);
152    gtk_entry_set_text(GTK_ENTRY(restore_dir), restore->fname);
153    gtk_clist_freeze(list);
154    gtk_clist_clear(list); 
155
156    bsnprintf(pathbuf, sizeof(pathbuf), "cd %s", path);
157    Dmsg1(100, "%s\n", pathbuf);
158    write_director(pathbuf);
159    discard_to_prompt();
160
161    write_director("dir");
162    while (bnet_recv(UA_sock) > 0) {
163       char *p = UA_sock->msg;
164       char *l;
165       strip_trailing_junk(UA_sock->msg);
166       if (*p == '$') {
167          break;
168       }
169       Dmsg1(200, "Got: %s\n", p);
170       if (!*p) {
171          continue;
172       }
173       l = p;
174       skip_nonspaces(&p);             /* permissions */
175       *p++ = 0;
176       bstrncpy(modes, l, sizeof(modes));
177       skip_spaces(&p);
178       skip_nonspaces(&p);             /* link count */
179       *p++ = 0;
180       skip_spaces(&p);
181       l = p;
182       skip_nonspaces(&p);             /* user */
183       *p++ = 0;
184       skip_spaces(&p);
185       bstrncpy(user, l, sizeof(user));
186       l = p;
187       skip_nonspaces(&p);             /* group */
188       *p++ = 0;
189       bstrncpy(group, l, sizeof(group));
190       skip_spaces(&p);
191       l = p;
192       skip_nonspaces(&p);             /* size */
193       *p++ = 0;
194       bstrncpy(size, l, sizeof(size));
195       skip_spaces(&p);
196       l = p;
197       skip_nonspaces(&p);             /* date/time */
198       skip_spaces(&p);
199       skip_nonspaces(&p);  
200       *p++ = 0;
201       bstrncpy(date, l, sizeof(date));
202       skip_spaces(&p);
203       if (*p == '*') {
204          bstrncpy(marked, "x", sizeof(marked));
205          p++;
206       } else {
207          bstrncpy(marked, " ", sizeof(marked));
208       }
209       split_path_and_filename(p, &restore->path, &restore->pnl,
210                               &restore->file, &restore->fnl);
211
212 //    Dmsg1(000, "restore->fname=%s\n", restore->fname);
213       bstrncpy(file, restore->file, sizeof(file));
214 //    printf("modes=%s user=%s group=%s size=%s date=%s file=%s\n",
215 //       modes, user, group, size, date, file);
216
217       gtk_clist_append(list, text);
218
219 #ifdef xxx
220       if (marked) {
221          gtk_clist_set_pixmap(list, row, CHECK_COLUMN, check_pixmap, check_trans);
222       } else {
223          gtk_clist_set_pixmap(list, row, CHECK_COLUMN, blank_pixmap, blank_trans);
224       }
225 #endif
226       row++;
227    }
228
229    /* Fix up length of file column */
230    gtk_clist_set_column_width(list, FILE_COLUMN, gtk_clist_optimal_column_width(list, FILE_COLUMN));
231    gtk_clist_set_column_width(list, MODES_COLUMN, gtk_clist_optimal_column_width(list, MODES_COLUMN));
232    gtk_clist_thaw(list);
233    start_director_reader(NULL);
234 }
235
236 Window *new_window()
237 {
238    Window *window = (Window *)malloc(sizeof(Window));
239    memset(window, 0, sizeof(window));
240    return window;
241 }
242
243 #ifdef xxx
244 static void window_delete_cb(GtkWidget *item, GdkEvent *event, Window *restore)
245 {
246    gtk_widget_destroy(restore->window);
247    gtk_main_quit();
248    free_pool_memory(restore->buf);
249    free_pool_memory(restore->fname);
250    free_pool_memory(restore->path);
251    free_pool_memory(restore->file);
252    free(restore);
253 }
254 #endif
255
256 /*
257  * User clicked a column title
258  */
259 static void click_column_cb(GtkCList *item, gint column, Window *restore)
260 {
261 }
262
263 /*
264  * User selected a row
265  */
266 static void select_row_cb(GtkCList *item, gint row, gint column, 
267              GdkEventButton *event, Window *restore)
268 {
269 #ifdef xxx
270    GdkPixmap *pixmap, *trans;
271 #endif
272    char *file, *marked = NULL;
273    int len;
274    char new_mark[10];
275    /* Column non-negative => double click */
276    if (column >= 0) {
277       gtk_clist_unselect_row(item, row, column);
278       gtk_clist_get_text(item, row, FILE_COLUMN, &file);
279       /* Double click on column 0 means to mark or unmark */
280       if (column == 0) {
281 #ifdef xxx
282          utf8_mark = g_locale_to_utf8(new_mark, -1, NULL, NULL, NULL);
283          gtk_clist_get_pixmap(restore->list, row, CHECK_COLUMN, &pixmap, &trans);
284          if (pixmap == blank_pixmap) {
285             bstrncpy(new_mark, "x", sizeof(new_mark));
286 //          gtk_clist_set_pixmap(item, row, CHECK_COLUMN, check_pixmap, check_trans);
287 #endif
288          gtk_clist_get_text(restore->list, row, CHECK_COLUMN, &marked);
289          Dmsg1(200, "Marked=%s\n", marked);
290          if (!marked || strcmp(marked, "x") != 0) {
291             len = Mmsg(&restore->buf, "mark %s", file);
292             bstrncpy(new_mark, "x", sizeof(new_mark));
293          } else {
294             len = Mmsg(&restore->buf, "unmark %s", file);
295             bstrncpy(new_mark, " ", sizeof(new_mark));
296          }
297          gtk_clist_set_text(restore->list, row, CHECK_COLUMN, new_mark);
298          /* strip trailing slash from directory name */
299          while (len > 1 && restore->buf[len-1] == '/') {
300             restore->buf[len-1] = 0;
301          }
302          write_director(restore->buf);
303          discard_to_prompt();
304       } else {
305       /* Double clicking on directory means to move to it */
306          int len;
307          len = strlen(file);
308          if (len > 0 && file[len-1] == '/') {
309             /* Change to new directory */
310             pm_strcpy(&restore->path, restore->fname);
311             if (*file == '*') {
312                Mmsg(&restore->fname, "%s%s", restore->path, file+1);
313             } else {
314                Mmsg(&restore->fname, "%s%s", restore->path, file);
315             }
316             FillDirectory(restore->fname, restore);
317          }
318       }
319    }  
320 }
321
322 /*
323  * CList row is being destroyed get rid of our data
324  */
325 void row_data_destroy_cb(gpointer data)
326 {
327    if (data) {
328       free(data);
329    }
330 }