]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/gnome2-console/restore.c
Mark translatable strings in all source files.
[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(const 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(const 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       set_text(UA_sock->msg, UA_sock->msglen);
54    }
55 }
56
57 /*
58  * Move up one directory
59  */
60 void
61 on_restore_up_button_clicked(GtkButton *button, gpointer user_data)
62 {
63    split_path_and_filename(restore->fname, &restore->path, &restore->pnl,
64                               &restore->file, &restore->fnl);
65    FillDirectory(restore->path, restore);
66 }
67
68 static void mark_row(int row, bool mark)
69 {
70    char *file;
71    int len;
72    char new_mark[10];
73
74    gtk_clist_get_text(restore->list, row, FILE_COLUMN, &file);
75    if (mark) {
76       bstrncpy(new_mark, "x", sizeof(new_mark));
77       len = Mmsg(&restore->buf, "mark %s", file);
78    } else {
79       bstrncpy(new_mark, " ", sizeof(new_mark));
80       len = Mmsg(&restore->buf, "unmark %s", file);
81    }
82    gtk_clist_set_text(restore->list, row, CHECK_COLUMN, new_mark);
83     /* strip trailing slash from directory name */
84    while (len > 1 && restore->buf[len-1] == '/') {
85       restore->buf[len-1] = 0;
86    }
87    write_director(restore->buf);
88    discard_to_prompt();
89 }
90
91 void
92 on_restore_add_button_clicked(GtkButton *button, gpointer user_data)
93 {
94    int num_selected = g_list_length(restore->list->selection);
95    int row;
96
97    for (int i=0; i < num_selected; i++) {
98       row = (int)(long int)g_list_nth_data(restore->list->selection, i);
99       mark_row(row, true);
100    }
101 }
102
103
104 void
105 on_restore_remove_button_clicked(GtkButton *button, gpointer user_data)
106 {
107    int num_selected = g_list_length(restore->list->selection);
108    int row;
109
110    for (int i=0; i < num_selected; i++) {
111       row = (int)(long int)g_list_nth_data(restore->list->selection, i);
112       mark_row(row, false);
113    }
114 }
115
116 /*
117  * Called once at the beginning of the program for setup
118  */
119 void select_restore_setup()
120 {
121    const gchar *title[NUM_COLUMNS] = {_("Mark"), _("File"), _("Mode"), _("User"), _("Group"), _("Size"), _("Date")};
122
123    restore_file_selection = create_restore_file_selection();
124    if (!restore_file_selection) {
125       Dmsg0(000, "Restore_files not setup.\n");
126    }
127    restore_dir = lookup_widget(restore_file_selection, "restore_dir");
128    scrolled = lookup_widget(restore_file_selection, "scrolled");
129    if (!scrolled) {
130       Dmsg0(000, "Scrolled not setup.\n");
131    }
132
133    restore = new_window();
134
135 #ifdef needed
136    check_pixmap = gdk_pixmap_colormap_create_from_xpm(NULL,
137                   gdk_colormap_get_system(), &check_trans, NULL,
138                   "check.xpm");
139    blank_pixmap = gdk_pixmap_colormap_create_from_xpm(NULL,
140                   gdk_colormap_get_system(), &blank_trans, NULL,
141                   "blank.xpm");
142 #endif
143
144    /* XXX: Stupid gtk_clist_set_selection_mode() has incorrect declaration of the title argument */
145    /* XXX: Workaround by typecast... peter@ifm.liu.se */
146
147    restore->list = (GtkCList *)gtk_clist_new_with_titles(NUM_COLUMNS, (gchar **) title);
148    gtk_clist_set_selection_mode(restore->list, GTK_SELECTION_EXTENDED);
149    gtk_clist_set_sort_column(restore->list, FILE_COLUMN);
150    gtk_clist_set_auto_sort(restore->list, true);
151    gtk_signal_connect(GTK_OBJECT(restore->list), "click_column",
152                       G_CALLBACK(click_column_cb), restore);
153    gtk_signal_connect(GTK_OBJECT(restore->list), "select_row",
154                       G_CALLBACK(select_row_cb), restore);
155
156    gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(restore->list));
157    restore->buf   = get_pool_memory(PM_FNAME);
158    restore->fname = get_pool_memory(PM_FNAME);
159    restore->path  = get_pool_memory(PM_NAME);
160    restore->file  = get_pool_memory(PM_NAME);
161 }
162
163 /*
164  * Select files dialog called
165  */
166 void select_restore_files()
167 {
168    discard_to_prompt();
169    set_restore_dialog_defaults();
170    gtk_widget_show(GTK_WIDGET(restore->list));
171    FillDirectory("/", restore);
172    gtk_main();
173 }
174
175
176 /*
177  * Fill the CList box with files at path
178  */
179 void FillDirectory(const char *path, Window *restore)
180 {
181    char pathbuf[MAXSTRING];
182    char modes[20], user[20], group[20], size[20], date[30];
183    char file[1000];
184    char marked[10];
185    gchar *text[NUM_COLUMNS] = {marked, file, modes, user, group, size, date};
186    GtkCList *list = restore->list;
187    int row = 0;
188
189    stop_director_reader(NULL);
190    pm_strcpy(&restore->fname, path);
191    gtk_entry_set_text(GTK_ENTRY(restore_dir), restore->fname);
192    gtk_clist_freeze(list);
193    gtk_clist_clear(list);
194
195    bsnprintf(pathbuf, sizeof(pathbuf), "cd %s", path);
196    Dmsg1(100, "%s\n", pathbuf);
197    write_director(pathbuf);
198    discard_to_prompt();
199
200    write_director("dir");
201    while (bnet_recv(UA_sock) > 0) {
202       char *p = UA_sock->msg;
203       char *l;
204       strip_trailing_junk(UA_sock->msg);
205       if (*p == '$') {
206          break;
207       }
208       Dmsg1(200, "Got: %s\n", p);
209       if (!*p) {
210          continue;
211       }
212       l = p;
213       skip_nonspaces(&p);             /* permissions */
214       *p++ = 0;
215       bstrncpy(modes, l, sizeof(modes));
216       skip_spaces(&p);
217       skip_nonspaces(&p);             /* link count */
218       *p++ = 0;
219       skip_spaces(&p);
220       l = p;
221       skip_nonspaces(&p);             /* user */
222       *p++ = 0;
223       skip_spaces(&p);
224       bstrncpy(user, l, sizeof(user));
225       l = p;
226       skip_nonspaces(&p);             /* group */
227       *p++ = 0;
228       bstrncpy(group, l, sizeof(group));
229       skip_spaces(&p);
230       l = p;
231       skip_nonspaces(&p);             /* size */
232       *p++ = 0;
233       bstrncpy(size, l, sizeof(size));
234       skip_spaces(&p);
235       l = p;
236       skip_nonspaces(&p);             /* date/time */
237       skip_spaces(&p);
238       skip_nonspaces(&p);
239       *p++ = 0;
240       bstrncpy(date, l, sizeof(date));
241       skip_spaces(&p);
242       if (*p == '*') {
243          bstrncpy(marked, "x", sizeof(marked));
244          p++;
245       } else {
246          bstrncpy(marked, " ", sizeof(marked));
247       }
248       split_path_and_filename(p, &restore->path, &restore->pnl,
249                               &restore->file, &restore->fnl);
250
251 //    Dmsg1(000, "restore->fname=%s\n", restore->fname);
252       bstrncpy(file, restore->file, sizeof(file));
253 //    printf("modes=%s user=%s group=%s size=%s date=%s file=%s\n",
254 //       modes, user, group, size, date, file);
255
256       gtk_clist_append(list, text);
257
258       row++;
259    }
260
261    /* Fix up length of file column */
262    gtk_clist_set_column_width(list, FILE_COLUMN, gtk_clist_optimal_column_width(list, FILE_COLUMN));
263    gtk_clist_set_column_width(list, MODES_COLUMN, gtk_clist_optimal_column_width(list, MODES_COLUMN));
264    gtk_clist_thaw(list);
265    start_director_reader(NULL);
266 }
267
268 Window *new_window()
269 {
270    Window *window = (Window *)malloc(sizeof(Window));
271    memset(window, 0, sizeof(window));
272    return window;
273 }
274
275
276 /*
277  * User clicked a column title
278  */
279 static void click_column_cb(GtkCList *item, gint column, Window *restore)
280 {
281 }
282
283 /*
284  * User selected a row
285  */
286 static void select_row_cb(GtkCList *item, gint row, gint column,
287              GdkEventButton *event, Window *restore)
288 {
289    char *file;
290    char *marked = NULL;
291    /* Column non-negative => double click */
292    if (column >= 0) {
293       gtk_clist_unselect_row(item, row, column);
294       /* Double click on column 0 means to mark or unmark */
295       if (column == 0) {
296          gtk_clist_get_text(restore->list, row, CHECK_COLUMN, &marked);
297          Dmsg1(200, "Marked=%s\n", marked);
298          if (!marked || strcmp(marked, "x") != 0) {
299             mark_row(row, true);
300          } else {
301             mark_row(row, false);
302          }
303       } else {
304       /* Double clicking on directory means to move to it */
305          int len;
306          gtk_clist_get_text(item, row, FILE_COLUMN, &file);
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 }
331
332 #ifdef xxx
333    GdkPixmap *pixmap, *trans;
334          utf8_mark = g_locale_to_utf8(new_mark, -1, NULL, NULL, NULL);
335          gtk_clist_get_pixmap(restore->list, row, CHECK_COLUMN, &pixmap, &trans);
336          if (pixmap == blank_pixmap) {
337             bstrncpy(new_mark, "x", sizeof(new_mark));
338 //          gtk_clist_set_pixmap(item, row, CHECK_COLUMN, check_pixmap, check_trans);
339 #endif
340 #ifdef xxx
341 static void window_delete_cb(GtkWidget *item, GdkEvent *event, Window *restore)
342 {
343    gtk_widget_destroy(restore->window);
344    gtk_main_quit();
345    free_pool_memory(restore->buf);
346    free_pool_memory(restore->fname);
347    free_pool_memory(restore->path);
348    free_pool_memory(restore->file);
349    free(restore);
350 }
351 #endif
352 #ifdef xxx
353       if (marked) {
354          gtk_clist_set_pixmap(list, row, CHECK_COLUMN, check_pixmap, check_trans);
355       } else {
356          gtk_clist_set_pixmap(list, row, CHECK_COLUMN, blank_pixmap, blank_trans);
357       }
358 #endif