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  * Portions based on the original Subversion plugin
7  * Copyright (C) Johannes Schmid 2005
8  *
9  * anjuta is free software.
10  *
11  * You may redistribute it and/or modify it under the terms of the
12  * GNU General Public License, as published by the Free Software
13  * Foundation; either version 2 of the License, or (at your option)
14  * any later version.
15  *
16  * anjuta is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with anjuta.  If not, write to:
23  * 	The Free Software Foundation, Inc.,
24  * 	51 Franklin Street, Fifth Floor
25  * 	Boston, MA  02110-1301, USA.
26  */
27 
28 #include "subversion-commit-dialog.h"
29 
30 static void
on_commit_command_finished(AnjutaCommand * command,guint return_code,Subversion * plugin)31 on_commit_command_finished (AnjutaCommand *command, guint return_code,
32 							Subversion *plugin)
33 {
34 	AnjutaStatus *status;
35 
36 	status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell,
37 									  NULL);
38 
39 	anjuta_status (status, _("Subversion: Commit complete."), 5);
40 
41 	report_errors (command, return_code);
42 
43 	svn_commit_command_destroy (SVN_COMMIT_COMMAND (command));
44 }
45 
46 static GList*
subversion_commit_prepend_log(GList * logs,gchar * data)47 subversion_commit_prepend_log (GList *logs, gchar *data)
48 {
49 	logs = g_list_prepend(logs, data);
50 
51 	if (g_list_length(logs) > MAX_LOG_NUM)
52 		logs = g_list_remove(logs, g_list_last(logs)->data);
53 
54 	return logs;
55 }
56 
57 static void
on_subversion_commit_response(GtkDialog * dialog,gint response,SubversionData * data)58 on_subversion_commit_response(GtkDialog* dialog, gint response,
59 							  SubversionData* data)
60 {
61 	switch (response)
62 	{
63 		case GTK_RESPONSE_OK:
64 		{
65 			gchar* log;
66 			GtkWidget* logtext;
67 			GtkWidget* norecurse;
68 			GtkWidget* commit_prev_msg_enable;
69 			GtkWidget* commit_prev_msg_combo;
70 			GtkWidget *commit_status_view;
71 			GList *selected_paths;
72 			SvnCommitCommand *commit_command;
73 			guint pulse_timer_id;
74 			gboolean msg_enable_selected;
75 
76 			logtext = GTK_WIDGET (gtk_builder_get_object (data->bxml, "subversion_log_view"));
77 			commit_prev_msg_enable = GTK_WIDGET (gtk_builder_get_object (data->bxml, "commit_prev_msg_enable"));
78 
79 			log = get_log_from_textview(logtext);
80 			msg_enable_selected = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(commit_prev_msg_enable));
81 
82 			if (!g_utf8_strlen(log, -1) && (msg_enable_selected == FALSE))
83 			{
84 				gint result;
85 				GtkWidget* dlg = gtk_message_dialog_new(GTK_WINDOW(dialog),
86 														GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO,
87 														GTK_BUTTONS_YES_NO,
88 														_("Are you sure that you want to pass an empty log message?"));
89 				result = gtk_dialog_run(GTK_DIALOG(dlg));
90 				gtk_widget_destroy(dlg);
91 				if (result == GTK_RESPONSE_NO)
92 					break;
93 			}
94 
95 			commit_prev_msg_combo = GTK_WIDGET (gtk_builder_get_object (data->bxml, "commit_prev_msg_combo"));
96 
97 			norecurse = GTK_WIDGET (gtk_builder_get_object (data->bxml, "subversion_commit_norecurse"));
98 
99 			commit_status_view = GTK_WIDGET (gtk_builder_get_object (data->bxml,
100 													   "commit_status_view"));
101 
102 			selected_paths = anjuta_vcs_status_tree_view_get_selected (ANJUTA_VCS_STATUS_TREE_VIEW (commit_status_view));
103 
104 
105 			if (msg_enable_selected == TRUE)
106 			{
107 				commit_command = svn_commit_command_new (selected_paths,
108 													 gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT (commit_prev_msg_combo)),
109 													 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(norecurse)));
110 			}
111 			else
112 			{
113 				commit_command = svn_commit_command_new (selected_paths,
114 													 (gchar *) log,
115 													 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(norecurse)));
116 			}
117 
118 			svn_command_free_path_list (selected_paths);
119 
120 			create_message_view (data->plugin);
121 
122 			pulse_timer_id = status_bar_progress_pulse (data->plugin,
123 														_("Subversion: "
124 														  "Committing changes "
125 														  "to the "
126 														  "repository…"));
127 
128 			g_signal_connect (G_OBJECT (commit_command), "command-finished",
129 							  G_CALLBACK (stop_status_bar_progress_pulse),
130 							  GUINT_TO_POINTER (pulse_timer_id));
131 
132 			g_signal_connect (G_OBJECT (commit_command), "command-finished",
133 							  G_CALLBACK (on_commit_command_finished),
134 							  data->plugin);
135 
136 			g_signal_connect (G_OBJECT (commit_command), "command-finished",
137 							  G_CALLBACK (subversion_plugin_status_changed_emit),
138 							  data->plugin);
139 
140 			g_signal_connect (G_OBJECT (commit_command), "data-arrived",
141 							  G_CALLBACK (on_command_info_arrived),
142 							  data->plugin);
143 
144 			anjuta_command_start (ANJUTA_COMMAND (commit_command));
145 
146 			if (g_utf8_strlen(log, -1) && msg_enable_selected == FALSE)
147 				data->plugin->svn_commit_logs = subversion_commit_prepend_log(data->plugin->svn_commit_logs, log);
148 
149 			subversion_data_free(data);
150 			gtk_widget_destroy (GTK_WIDGET(dialog));
151 			break;
152 		}
153 		default:
154 		{
155 			subversion_data_free(data);
156 			gtk_widget_destroy(GTK_WIDGET(dialog));
157 			break;
158 		}
159 	}
160 }
161 
162 static void
select_all_files(AnjutaCommand * command,guint return_code,AnjutaVcsStatusTreeView * status_view)163 select_all_files (AnjutaCommand *command, guint return_code,
164 				  AnjutaVcsStatusTreeView *status_view)
165 {
166 	anjuta_vcs_status_tree_view_select_all (status_view);
167 }
168 
169 static void
on_prev_message_enable_clicked(GtkToggleButton * button,gpointer data)170 on_prev_message_enable_clicked (GtkToggleButton *button, gpointer data)
171 {
172 	if (gtk_toggle_button_get_active(button) == FALSE)
173 	{
174 		gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE);
175 	}
176 	else
177 	{
178 		gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);
179 	}
180 }
181 
182 static void
subversion_commit_dialog_populate_logs(gpointer msg,gpointer user_data)183 subversion_commit_dialog_populate_logs (gpointer msg, gpointer user_data)
184 {
185 	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(user_data), (gchar*) msg);
186 }
187 
188 static void
subversion_commit_dialog(GtkAction * action,Subversion * plugin,gchar * filename)189 subversion_commit_dialog (GtkAction* action, Subversion* plugin,
190 						  gchar *filename)
191 {
192 	GtkBuilder* bxml = gtk_builder_new ();
193 	GtkWidget* dialog;
194 	GtkWidget *logtext;
195 	GtkWidget *commit_select_all_button;
196 	GtkWidget *commit_clear_button;
197 	GtkWidget *commit_status_view;
198 	GtkWidget *commit_status_progress_bar;
199 	GtkWidget *commit_prev_msg_enable;
200 	GtkWidget *commit_prev_msg_combo;
201 	GtkCellRenderer *cell;
202   	GtkListStore *store;
203 	SvnStatusCommand *status_command;
204 	SubversionData* data;
205 	GError* error = NULL;
206 
207 	if (!gtk_builder_add_from_file (bxml, GLADE_FILE, &error))
208 	{
209 		g_warning ("Couldn't load builder file: %s", error->message);
210 		g_error_free (error);
211 	}
212 
213 	dialog = GTK_WIDGET (gtk_builder_get_object (bxml, "subversion_commit"));
214 	commit_select_all_button = GTK_WIDGET (gtk_builder_get_object (bxml,
215 													 "commit_select_all_button"));
216 	commit_clear_button = GTK_WIDGET (gtk_builder_get_object (bxml,
217 												"commit_clear_button"));
218 	commit_status_view = GTK_WIDGET (gtk_builder_get_object (bxml, "commit_status_view"));
219 	commit_status_progress_bar = GTK_WIDGET (gtk_builder_get_object (bxml,
220 													   "commit_status_progress_bar"));
221 	logtext = GTK_WIDGET (gtk_builder_get_object (bxml, "subversion_log_view"));
222 	status_command = svn_status_command_new (plugin->project_root_dir,
223 											 TRUE, TRUE);
224 	commit_prev_msg_enable = GTK_WIDGET (gtk_builder_get_object (bxml,
225 													   "commit_prev_msg_enable"));
226 	commit_prev_msg_combo = GTK_WIDGET (gtk_builder_get_object (bxml,
227 													   "commit_prev_msg_combo"));
228 
229 	g_signal_connect (G_OBJECT (commit_select_all_button), "clicked",
230 					  G_CALLBACK (select_all_status_items),
231 					  commit_status_view);
232 
233 	g_signal_connect (G_OBJECT (commit_clear_button), "clicked",
234 					  G_CALLBACK (clear_all_status_selections),
235 					  commit_status_view);
236 
237 	g_signal_connect (G_OBJECT (status_command), "command-finished",
238 					  G_CALLBACK (select_all_files),
239 					  commit_status_view);
240 
241 	g_signal_connect(G_OBJECT (commit_prev_msg_enable), "toggled",
242 	                 G_CALLBACK(on_prev_message_enable_clicked),
243 	                 logtext);
244 
245 	pulse_progress_bar (GTK_PROGRESS_BAR (commit_status_progress_bar));
246 
247 	g_signal_connect (G_OBJECT (status_command), "command-finished",
248 					  G_CALLBACK (cancel_data_arrived_signal_disconnect),
249 					  commit_status_view);
250 
251 	g_signal_connect (G_OBJECT (status_command), "command-finished",
252 					  G_CALLBACK (hide_pulse_progress_bar),
253 					  commit_status_progress_bar);
254 
255 	g_signal_connect (G_OBJECT (status_command), "command-finished",
256 					  G_CALLBACK (on_status_command_finished),
257 					  NULL);
258 
259 	g_signal_connect (G_OBJECT (status_command), "data-arrived",
260 					  G_CALLBACK (on_status_command_data_arrived),
261 					  commit_status_view);
262 
263 	g_object_weak_ref (G_OBJECT (commit_status_view),
264 					   (GWeakNotify) disconnect_data_arrived_signals,
265 					   status_command);
266 
267 	anjuta_command_start (ANJUTA_COMMAND (status_command));
268 
269 	data = subversion_data_new(plugin, bxml);
270 	g_signal_connect(G_OBJECT(dialog), "response",
271 		G_CALLBACK(on_subversion_commit_response), data);
272 
273 	store = gtk_list_store_new (1, G_TYPE_STRING);
274 	cell = gtk_cell_renderer_text_new ();
275   	gtk_cell_layout_clear(GTK_CELL_LAYOUT(commit_prev_msg_combo));
276     gtk_combo_box_set_model(GTK_COMBO_BOX(commit_prev_msg_combo), NULL);
277 	gtk_combo_box_set_model(GTK_COMBO_BOX(commit_prev_msg_combo), GTK_TREE_MODEL(store));
278 
279 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (commit_prev_msg_combo), cell, FALSE);
280 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (commit_prev_msg_combo), cell,
281                                   "text", 0,
282                                   NULL);
283 	g_object_unref (store);
284 
285 	gtk_widget_show_all (dialog);
286 
287 
288 
289 	g_list_foreach(plugin->svn_commit_logs, subversion_commit_dialog_populate_logs, commit_prev_msg_combo);
290 	gtk_combo_box_set_active(GTK_COMBO_BOX(commit_prev_msg_combo), 0);
291 }
292 
293 void
on_menu_subversion_commit(GtkAction * action,Subversion * plugin)294 on_menu_subversion_commit (GtkAction* action, Subversion* plugin)
295 {
296 	subversion_commit_dialog(action, plugin, plugin->current_editor_filename);
297 }
298 
299 void
on_fm_subversion_commit(GtkAction * action,Subversion * plugin)300 on_fm_subversion_commit (GtkAction* action, Subversion* plugin)
301 {
302 	subversion_commit_dialog(action, plugin, plugin->fm_current_filename);
303 }
304