1 /*-
2  * Copyright (C) 2007-2011  Peter de Ridder <peter@xfce.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #include <dirent.h>
24 
25 #include <libxfce4util/libxfce4util.h>
26 
27 #include <subversion-1/svn_path.h>
28 
29 #define USE_FILE_ENTRY_REPLACEMENT 1
30 
31 #ifndef USE_FILE_ENTRY_REPLACEMENT
32 //#include "tsh-file-chooser-entry.h"
33 //#include "gtkfilechooserentry.h"
34 //#include <gtk/gtkfilechooserentry.h>
35 #endif
36 
37 #include "tsh-relocate-dialog.h"
38 
39 #ifdef USE_FILE_ENTRY_REPLACEMENT
40 static void browse_callback_from(GtkButton *, TshRelocateDialog *);
41 #endif
42 
43 #ifdef USE_FILE_ENTRY_REPLACEMENT
44 static void browse_callback_to(GtkButton *, TshRelocateDialog *);
45 #endif
46 
47 struct _TshRelocateDialog
48 {
49 	GtkDialog dialog;
50 
51 	GtkWidget *from;
52 	GtkWidget *to;
53 	GtkWidget *path;
54 #ifdef USE_FILE_ENTRY_REPLACEMENT
55   GtkWidget *filechooser_from;
56   GtkWidget *filechooser_to;
57 #endif
58 };
59 
60 struct _TshRelocateDialogClass
61 {
62 	GtkDialogClass dialog_class;
63 };
64 
G_DEFINE_TYPE(TshRelocateDialog,tsh_relocate_dialog,GTK_TYPE_DIALOG)65 G_DEFINE_TYPE (TshRelocateDialog, tsh_relocate_dialog, GTK_TYPE_DIALOG)
66 
67 static void
68 tsh_relocate_dialog_class_init (TshRelocateDialogClass *klass)
69 {
70 }
71 
72 static void
tsh_relocate_dialog_init(TshRelocateDialog * dialog)73 tsh_relocate_dialog_init (TshRelocateDialog *dialog)
74 {
75 	GtkWidget *grid;
76 	GtkWidget *label;
77 #ifdef USE_FILE_ENTRY_REPLACEMENT
78   GtkWidget *box;
79   GtkWidget *button;
80   GtkWidget *image;
81 #endif
82 
83 	grid = gtk_grid_new ();
84 
85 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), grid, FALSE, TRUE, 0);
86 	gtk_widget_show (grid);
87 
88 	label = gtk_label_new_with_mnemonic (_("_From:"));
89 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
90 
91 #ifdef USE_FILE_ENTRY_REPLACEMENT
92   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
93 	dialog->from = gtk_entry_new();
94   dialog->filechooser_from = gtk_file_chooser_dialog_new(_("Select a folder"), GTK_WINDOW(dialog),
95                                                     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
96                                                     _("_Cancel"), GTK_RESPONSE_CANCEL,
97                                                     _("_OK"), GTK_RESPONSE_OK,
98                                                     NULL);
99 #else
100 	dialog->from = gtk_file_chooser_entry_new(_("Select a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);//tsh_file_chooser_entry_new ();
101 	//dialog->from = _gtk_file_chooser_entry_new(FALSE);
102 #endif
103 
104 #ifdef USE_FILE_ENTRY_REPLACEMENT
105   image = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU);
106   button = gtk_button_new();
107   gtk_button_set_image(GTK_BUTTON(button), image);
108   g_signal_connect(button, "clicked", G_CALLBACK(browse_callback_from), dialog);
109 
110   gtk_box_pack_start(GTK_BOX(box), dialog->from, TRUE, TRUE, 0);
111   gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0);
112 
113 	gtk_widget_show(dialog->from);
114 	gtk_widget_show(button);
115 
116 	gtk_widget_set_hexpand (box, TRUE);
117 	gtk_grid_attach (GTK_GRID (grid), box, 1, 0, 1, 1);
118 #else
119 	gtk_widget_set_hexpand (dialog->from, TRUE);
120 	gtk_grid_attach (GTK_GRID (grid), dialog->from, 1, 0, 1, 1);
121 #endif
122 
123 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->from);
124 	gtk_widget_show(label);
125 #ifdef USE_FILE_ENTRY_REPLACEMENT
126 	gtk_widget_show(box);
127 #else
128 	gtk_widget_show(dialog->from);
129 	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog->from), FALSE);
130 #endif
131 
132 	label = gtk_label_new_with_mnemonic (_("_To:"));
133 	gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
134 
135 #ifdef USE_FILE_ENTRY_REPLACEMENT
136   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
137 	dialog->to = gtk_entry_new();
138   dialog->filechooser_to = gtk_file_chooser_dialog_new(_("Select a folder"), GTK_WINDOW(dialog),
139                                                     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
140                                                     _("_Cancel"), GTK_RESPONSE_CANCEL,
141                                                     _("_OK"), GTK_RESPONSE_OK,
142                                                     NULL);
143 #else
144 	dialog->to = gtk_file_chooser_entry_new(_("Select a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);//tsh_file_chooser_entry_new ();
145 	//dialog->to = _gtk_file_chooser_entry_new(FALSE);
146 #endif
147 
148 #ifdef USE_FILE_ENTRY_REPLACEMENT
149   image = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU);
150   button = gtk_button_new();
151   gtk_button_set_image(GTK_BUTTON(button), image);
152   g_signal_connect(button, "clicked", G_CALLBACK(browse_callback_to), dialog);
153 
154   gtk_box_pack_start(GTK_BOX(box), dialog->to, TRUE, TRUE, 0);
155   gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0);
156 
157 	gtk_widget_show(dialog->to);
158 	gtk_widget_show(button);
159 
160 	gtk_widget_set_hexpand (box, TRUE);
161 	gtk_grid_attach (GTK_GRID (grid), box, 1, 1, 1, 1);
162 #else
163 	gtk_widget_set_hexpand (dialog->to, TRUE);
164 	gtk_grid_attach (GTK_GRID (grid), dialog->to, 1, 1, 1, 1);
165 #endif
166 
167 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->to);
168 	gtk_widget_show(label);
169 #ifdef USE_FILE_ENTRY_REPLACEMENT
170 	gtk_widget_show(box);
171 #else
172 	gtk_widget_show(dialog->to);
173 	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog->to), FALSE);
174 #endif
175 
176 	label = gtk_label_new_with_mnemonic (_("_Directory:"));
177 	gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
178 
179 	dialog->path = gtk_file_chooser_button_new (_("Select a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
180 	gtk_widget_set_hexpand (dialog->path, TRUE);
181 	gtk_grid_attach (GTK_GRID (grid), dialog->path, 1, 2, 1, 1);
182 
183 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->path);
184 	gtk_widget_show(label);
185 	gtk_widget_show(dialog->path);
186 
187 	gtk_window_set_title (GTK_WINDOW (dialog), _("Relocate"));
188 
189 	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
190 	                        _("_Cancel"), GTK_RESPONSE_CANCEL,
191 	                        _("_OK"), GTK_RESPONSE_OK,
192 	                        NULL);
193 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
194 
195 	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
196 }
197 
198 GtkWidget*
tsh_relocate_dialog_new(const gchar * title,GtkWindow * parent,GtkDialogFlags flags,const gchar * from,const gchar * to,const gchar * local_dir)199 tsh_relocate_dialog_new (const gchar *title, GtkWindow *parent, GtkDialogFlags flags, const gchar *from, const gchar *to, const gchar *local_dir)
200 {
201 	TshRelocateDialog *dialog = g_object_new (TSH_TYPE_RELOCATE_DIALOG, NULL);
202 
203 	if(title)
204 		gtk_window_set_title (GTK_WINDOW(dialog), title);
205 
206 	if(parent)
207 		gtk_window_set_transient_for (GTK_WINDOW(dialog), parent);
208 
209 	if(flags & GTK_DIALOG_MODAL)
210 		gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
211 
212 	if(flags & GTK_DIALOG_DESTROY_WITH_PARENT)
213 		gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
214 
215 	if(from)
216   {
217     if(svn_path_is_url (from))
218     {
219 #ifndef USE_FILE_ENTRY_REPLACEMENT
220       gtk_file_chooser_entry_set_uri(GTK_FILE_CHOOSER_ENTRY(dialog->from), from);
221 #endif
222     }
223     else
224     {
225       gchar *absolute = NULL;
226       if(!g_path_is_absolute (from))
227       {
228         //TODO: ".."
229         gchar *currdir = g_get_current_dir();
230         absolute = g_build_filename(currdir, (from[0] == '.' && (!from[1] || from[1] == G_DIR_SEPARATOR || from[1] == '/'))?&from[1]:from, NULL);
231         g_free (currdir);
232       }
233 #ifndef USE_FILE_ENTRY_REPLACEMENT
234       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog->from), absolute?absolute:from);
235 #endif
236       g_free (absolute);
237     }
238   }
239 
240 	if(to)
241   {
242     if(svn_path_is_url (to))
243     {
244 #ifndef USE_FILE_ENTRY_REPLACEMENT
245       gtk_file_chooser_entry_set_uri(GTK_FILE_CHOOSER_ENTRY(dialog->to), to);
246 #endif
247     }
248     else
249     {
250       gchar *absolute = NULL;
251       if(!g_path_is_absolute (to))
252       {
253         //TODO: ".."
254         gchar *currdir = g_get_current_dir();
255         absolute = g_build_filename(currdir, (to[0] == '.' && (!to[1] || to[1] == G_DIR_SEPARATOR || to[1] == '/'))?&to[1]:to, NULL);
256         g_free (currdir);
257       }
258 #ifndef USE_FILE_ENTRY_REPLACEMENT
259       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog->to), absolute?absolute:to);
260 #endif
261       g_free (absolute);
262     }
263   }
264 
265 	if(local_dir)
266   {
267     gboolean isdir = TRUE;
268     gchar *absolute = NULL;
269     DIR *dir;
270     FILE *fp;
271     if(!g_path_is_absolute (local_dir))
272     {
273       //TODO: ".."
274       gchar *currdir = g_get_current_dir();
275       absolute = g_build_filename(currdir, (local_dir[0] == '.' && (!local_dir[1] || local_dir[1] == G_DIR_SEPARATOR || local_dir[1] == '/'))?&local_dir[1]:local_dir, NULL);
276       g_free (currdir);
277     }
278     dir = opendir(absolute?absolute:local_dir);
279     if(dir)
280       closedir(dir);
281     else if((fp = fopen(absolute?absolute:local_dir, "r")))
282     {
283       fclose(fp);
284       isdir = FALSE;
285     }
286     if(isdir)
287       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog->path), absolute?absolute:local_dir);
288     else
289     {
290       gtk_file_chooser_set_action (GTK_FILE_CHOOSER(dialog->path), GTK_FILE_CHOOSER_ACTION_OPEN);
291       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(dialog->path), absolute?absolute:local_dir);
292     }
293     g_free (absolute);
294   }
295 
296 	return GTK_WIDGET(dialog);
297 }
298 
tsh_relocate_dialog_get_from(TshRelocateDialog * dialog)299 gchar* tsh_relocate_dialog_get_from (TshRelocateDialog *dialog)
300 {
301   g_return_val_if_fail (TSH_IS_RELOCATE_DIALOG (dialog), NULL);
302 
303 #ifdef USE_FILE_ENTRY_REPLACEMENT
304 	return g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->from)));
305 #else
306 	return gtk_file_chooser_entry_get_uri(GTK_FILE_CHOOSER_ENTRY(dialog->from));
307 #endif
308 }
309 
tsh_relocate_dialog_get_to(TshRelocateDialog * dialog)310 gchar* tsh_relocate_dialog_get_to (TshRelocateDialog *dialog)
311 {
312   g_return_val_if_fail (TSH_IS_RELOCATE_DIALOG (dialog), NULL);
313 
314 #ifdef USE_FILE_ENTRY_REPLACEMENT
315 	return g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->to)));
316 #else
317 	return gtk_file_chooser_entry_get_uri(GTK_FILE_CHOOSER_ENTRY(dialog->to));
318 #endif
319 }
320 
tsh_relocate_dialog_get_directory(TshRelocateDialog * dialog)321 gchar* tsh_relocate_dialog_get_directory (TshRelocateDialog *dialog)
322 {
323   g_return_val_if_fail (TSH_IS_RELOCATE_DIALOG (dialog), NULL);
324 
325 	return gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog->path));
326 }
327 
328 #ifdef USE_FILE_ENTRY_REPLACEMENT
329 static void
browse_callback_from(GtkButton * button,TshRelocateDialog * dialog)330 browse_callback_from(GtkButton *button, TshRelocateDialog *dialog)
331 {
332   gtk_widget_show(dialog->filechooser_from);
333   if(gtk_dialog_run(GTK_DIALOG(dialog->filechooser_from)) == GTK_RESPONSE_OK)
334   {
335     gchar *url = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog->filechooser_from));
336     gtk_entry_set_text(GTK_ENTRY(dialog->from), url);
337     g_free(url);
338   }
339   gtk_widget_hide(dialog->filechooser_from);
340 }
341 #endif
342 
343 #ifdef USE_FILE_ENTRY_REPLACEMENT
344 static void
browse_callback_to(GtkButton * button,TshRelocateDialog * dialog)345 browse_callback_to(GtkButton *button, TshRelocateDialog *dialog)
346 {
347   gtk_widget_show(dialog->filechooser_to);
348   if(gtk_dialog_run(GTK_DIALOG(dialog->filechooser_to)) == GTK_RESPONSE_OK)
349   {
350     gchar *url = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog->filechooser_to));
351     gtk_entry_set_text(GTK_ENTRY(dialog->to), url);
352     g_free(url);
353   }
354   gtk_widget_hide(dialog->filechooser_to);
355 }
356 #endif
357