1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * anjuta
4  * Copyright (C) James Liggett 2007 <jrliggett@cox.net>
5  *
6  * anjuta is free software.
7  *
8  * You may redistribute it and/or modify it under the terms of the
9  * GNU General Public License, as published by the Free Software
10  * Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  *
13  * anjuta is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with anjuta.  If not, write to:
20  * 	The Free Software Foundation, Inc.,
21  * 	51 Franklin Street, Fifth Floor
22  * 	Boston, MA  02110-1301, USA.
23  */
24 
25 #include "subversion-copy-dialog.h"
26 
27 static void
on_copy_other_revision_radio_toggled(GtkToggleButton * toggle_button,SubversionData * data)28 on_copy_other_revision_radio_toggled (GtkToggleButton *toggle_button,
29 									  SubversionData *data)
30 {
31 	GtkWidget *copy_revision_entry;
32 	GtkWidget *subversion_copy;
33 	gboolean active;
34 
35 	copy_revision_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml,
36 												"copy_revision_entry"));
37 	subversion_copy = GTK_WIDGET (gtk_builder_get_object (data->bxml,
38 											"subversion_copy"));
39 	active = gtk_toggle_button_get_active (toggle_button);
40 	gtk_widget_set_sensitive (copy_revision_entry, active);
41 
42 	if (active)
43 	{
44 		gtk_window_set_focus (GTK_WINDOW (subversion_copy),
45 							  copy_revision_entry);
46 	}
47 }
48 
49 
50 static void
on_copy_browse_button_clicked(GtkButton * button,SubversionData * data)51 on_copy_browse_button_clicked (GtkButton *button, SubversionData *data)
52 {
53 	GtkWidget *subversion_copy;
54 	GtkWidget *copy_source_entry;
55 	GtkWidget *file_chooser_dialog;
56 	gchar *selected_path;
57 
58 	subversion_copy = GTK_WIDGET (gtk_builder_get_object (data->bxml, "subversion_copy"));
59 	copy_source_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml, "copy_source_entry"));
60 	file_chooser_dialog = gtk_file_chooser_dialog_new ("Select file or folder",
61 													   GTK_WINDOW (subversion_copy),
62 													   GTK_FILE_CHOOSER_ACTION_OPEN,
63 													   GTK_STOCK_CANCEL,
64 													   GTK_RESPONSE_CANCEL,
65 													   GTK_STOCK_OPEN,
66 													   GTK_RESPONSE_ACCEPT,
67 													   NULL);
68 
69 	if (gtk_dialog_run (GTK_DIALOG (file_chooser_dialog)) == GTK_RESPONSE_ACCEPT)
70 	{
71 		selected_path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser_dialog));
72 		gtk_entry_set_text (GTK_ENTRY (copy_source_entry), selected_path);
73 		g_free (selected_path);
74 	}
75 
76 	gtk_widget_destroy (GTK_WIDGET (file_chooser_dialog));
77 }
78 
79 static gboolean
on_copy_dest_entry_focus_in(GtkWidget * widget,GdkEventFocus * event,SubversionData * data)80 on_copy_dest_entry_focus_in (GtkWidget *widget, GdkEventFocus *event,
81 							 SubversionData *data)
82 {
83 	GtkWidget *copy_source_entry;
84 	GtkWidget *copy_dest_entry;
85 	gchar *source_path;
86 	gchar *dest_path;
87 	gchar *stripped_source_path;
88 	gchar *stripped_dest_path;
89 	gchar *last_slash;
90 	gchar *source_path_parent;
91 	gchar *suggested_path;  /* source_path_parent with a slash (/) after it */
92 
93 	copy_source_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml, "copy_source_entry"));
94 	copy_dest_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml, "copy_dest_entry"));
95 	source_path = gtk_editable_get_chars (GTK_EDITABLE (copy_source_entry), 0,
96 										  -1);
97 	dest_path = gtk_editable_get_chars (GTK_EDITABLE (copy_dest_entry), 0,
98 										  -1);
99 	stripped_source_path = g_strstrip (source_path);
100 	stripped_dest_path = g_strstrip (dest_path);
101 
102 	/* Make sure not to overwrite a path the user has already put in. */
103 	if (strlen (stripped_source_path) > 0 &&
104 		strlen (stripped_dest_path) == 0)
105 	{
106 		last_slash = strrchr (stripped_source_path, '/');
107 
108 		if (last_slash)
109 		{
110 			source_path_parent = g_strndup (stripped_source_path,
111 											(last_slash -
112 											 stripped_source_path));
113 			suggested_path = g_strconcat (source_path_parent, "/", NULL);
114 
115 			gtk_entry_set_text (GTK_ENTRY (widget),
116 								suggested_path);
117 			gtk_editable_set_position (GTK_EDITABLE (widget), -1);
118 
119 			g_free (source_path_parent);
120 			g_free (suggested_path);
121 		}
122 	}
123 
124 	g_free (source_path);
125 
126 	return TRUE;
127 }
128 
129 static void
on_copy_command_finished(AnjutaCommand * command,guint return_code,Subversion * plugin)130 on_copy_command_finished (AnjutaCommand *command, guint return_code,
131 						  Subversion *plugin)
132 {
133 	AnjutaStatus *status;
134 
135 	status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell,
136 									  NULL);
137 
138 	anjuta_status (status, _("Subversion: Copy complete."), 5);
139 
140 	report_errors (command, return_code);
141 
142 	svn_copy_command_destroy (SVN_COPY_COMMAND (command));
143 }
144 
145 static void
on_subversion_copy_response(GtkDialog * dialog,gint response,SubversionData * data)146 on_subversion_copy_response (GtkDialog *dialog, gint response,
147 							 SubversionData *data)
148 {
149 	GtkWidget *copy_source_entry;
150 	GtkWidget *copy_dest_entry;
151 	GtkWidget *copy_working_copy_radio;
152 	GtkWidget *copy_repository_head_radio;
153 	GtkWidget *copy_other_revision_radio;
154 	GtkWidget *copy_revision_entry;
155 	GtkWidget *copy_log_view;
156 	gchar *source_path;
157 	gchar *dest_path;
158 	gchar *revision_text;
159 	glong revision;
160 	gchar *log;
161 	SvnCopyCommand *copy_command;
162 
163 	if (response == GTK_RESPONSE_OK)
164 	{
165 		copy_source_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml,
166 												  "copy_source_entry"));
167 		copy_dest_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml,
168 												"copy_dest_entry"));
169 		copy_working_copy_radio = GTK_WIDGET (gtk_builder_get_object (data->bxml,
170 														"copy_working_copy_radio"));
171 		copy_repository_head_radio = GTK_WIDGET (gtk_builder_get_object (data->bxml,
172 														   "copy_repository_head_radio"));
173 		copy_other_revision_radio = GTK_WIDGET (gtk_builder_get_object (data->bxml,
174 														  "copy_other_revision_radio"));
175 		copy_log_view = GTK_WIDGET (gtk_builder_get_object (data->bxml,
176 											  "copy_log_view"));
177 
178 		source_path = gtk_editable_get_chars (GTK_EDITABLE (copy_source_entry),
179 											  0, -1);
180 		dest_path = gtk_editable_get_chars (GTK_EDITABLE (copy_dest_entry),
181 											0, -1);
182 
183 		if (!check_input (GTK_WIDGET (dialog), copy_source_entry,
184 						  _("Please enter a source path.")))
185 		{
186 			return;
187 		}
188 
189 		if (!check_input (GTK_WIDGET (dialog), copy_dest_entry,
190 						  _("Please enter a destination path.")))
191 		{
192 			return;
193 		}
194 
195 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (copy_working_copy_radio)))
196 			revision = SVN_COPY_REVISION_WORKING;
197 
198 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (copy_repository_head_radio)))
199 			revision = SVN_COPY_REVISION_HEAD;
200 
201 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (copy_other_revision_radio)))
202 		{
203 			copy_revision_entry = GTK_WIDGET (gtk_builder_get_object (data->bxml,
204 														"copy_revision_entry"));
205 
206 			if (!check_input (GTK_WIDGET (dialog), copy_revision_entry,
207 						  	  _("Please enter a revision.")))
208 			{
209 				return;
210 			}
211 
212 			revision_text = gtk_editable_get_chars (GTK_EDITABLE (copy_revision_entry),
213 													0, -1);
214 			revision = atol (revision_text);
215 
216 			g_free (revision_text);
217 		}
218 
219 		log = get_log_from_textview (copy_log_view);
220 
221 		create_message_view (data->plugin);
222 
223 		copy_command = svn_copy_command_new (source_path, revision, dest_path,
224 											 log);
225 
226 		g_signal_connect (G_OBJECT (copy_command), "command-finished",
227 						  G_CALLBACK (on_copy_command_finished),
228 						  data->plugin);
229 
230 		g_signal_connect (G_OBJECT (copy_command), "data-arrived",
231 						  G_CALLBACK (on_command_info_arrived),
232 						  data->plugin);
233 
234 		anjuta_command_start (ANJUTA_COMMAND (copy_command));
235 	}
236 
237 	gtk_widget_destroy (GTK_WIDGET (dialog));
238 	subversion_data_free (data);
239 }
240 
241 static void
subversion_copy_dialog(GtkAction * action,Subversion * plugin,gchar * filename)242 subversion_copy_dialog (GtkAction *action, Subversion *plugin, gchar *filename)
243 {
244 	GtkBuilder *bxml = gtk_builder_new ();
245 	GtkWidget *subversion_copy;
246 	GtkWidget *copy_source_entry;
247 	GtkWidget *copy_dest_entry;
248 	GtkWidget *copy_browse_button;
249 	GtkWidget *copy_other_revision_radio;
250 	SubversionData *data;
251 	GError* error = NULL;
252 
253 	if (!gtk_builder_add_from_file (bxml, GLADE_FILE, &error))
254 	{
255 		g_warning ("Couldn't load builder file: %s", error->message);
256 		g_error_free (error);
257 	}
258 
259 	subversion_copy = GTK_WIDGET (gtk_builder_get_object (bxml, "subversion_copy"));
260 	copy_source_entry = GTK_WIDGET (gtk_builder_get_object (bxml, "copy_source_entry"));
261 	copy_dest_entry = GTK_WIDGET (gtk_builder_get_object (bxml, "copy_dest_entry"));
262 	copy_browse_button = GTK_WIDGET (gtk_builder_get_object (bxml, "copy_browse_button"));
263 	copy_other_revision_radio = GTK_WIDGET (gtk_builder_get_object (bxml,
264 													  "copy_other_revision_radio"));
265 
266 	data = subversion_data_new (plugin, bxml);
267 
268 	g_signal_connect (G_OBJECT (subversion_copy), "response",
269 					  G_CALLBACK (on_subversion_copy_response),
270 					  data);
271 
272 	g_signal_connect (G_OBJECT (copy_dest_entry), "focus-in-event",
273 					  G_CALLBACK (on_copy_dest_entry_focus_in),
274 					  data);
275 
276 	g_signal_connect (G_OBJECT (copy_browse_button), "clicked",
277 					  G_CALLBACK (on_copy_browse_button_clicked),
278 					  data);
279 
280 	g_signal_connect (G_OBJECT (copy_other_revision_radio), "toggled",
281 					  G_CALLBACK (on_copy_other_revision_radio_toggled),
282 					  data);
283 
284 	gtk_entry_set_text (GTK_ENTRY (copy_source_entry), filename);
285 
286 	gtk_widget_show (subversion_copy);
287 }
288 
289 void
on_menu_subversion_copy(GtkAction * action,Subversion * plugin)290 on_menu_subversion_copy (GtkAction *action, Subversion *plugin)
291 {
292 	subversion_copy_dialog (action, plugin, NULL);
293 }
294 
295 void
on_fm_subversion_copy(GtkAction * action,Subversion * plugin)296 on_fm_subversion_copy (GtkAction *action, Subversion *plugin)
297 {
298 	subversion_copy_dialog (action, plugin, plugin->fm_current_filename);
299 }
300