Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / patch / patch-plugin.c
blob9b680737620039881104e4a2903363925b458b19
1 /* patch-plugin.c (C) 2002 Johannes Schmid
2 * 2005 Massimo Cora' [ported to the new plugin architetture]
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.
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 Library General Public License for more details.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include <libanjuta/anjuta-launcher.h>
20 #include <libanjuta/anjuta-debug.h>
21 #include <libanjuta/interfaces/ianjuta-project-manager.h>
23 #include "plugin.h"
24 #include "patch-plugin.h"
26 #define BUILDER_FILE PACKAGE_DATA_DIR"/glade/patch-plugin.ui"
28 static void patch_level_changed (GtkAdjustment *adj);
30 static void on_ok_clicked (GtkButton *button, PatchPlugin* p_plugin);
31 static void on_cancel_clicked (GtkButton *button, PatchPlugin* plugin);
33 static void on_msg_arrived (AnjutaLauncher *launcher,
34 AnjutaLauncherOutputType output_type,
35 const gchar* line, gpointer data);
36 static void on_msg_buffer (IAnjutaMessageView *view, const gchar *line,
37 PatchPlugin *plugin);
39 static void on_patch_terminated (AnjutaLauncher *launcher,
40 gint child_pid, gint status, gulong time_taken,
41 gpointer data);
44 static gint patch_level = 0;
47 static void
48 patch_level_changed (GtkAdjustment *adj)
50 patch_level = (gint) gtk_adjustment_get_value (adj);
53 static gchar* get_project_uri(PatchPlugin *plugin)
55 GValue value = {0, };
56 gchar* uri;
57 GError* err = NULL;
58 anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell,
59 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
60 &value,
61 &err);
62 if (err)
64 g_error_free(err);
65 return NULL;
67 uri = g_value_dup_string (&value);
68 return uri;
71 void
72 patch_show_gui (PatchPlugin *plugin)
74 GtkWidget* table;
75 GtkWidget* scale;
76 GtkAdjustment* adj;
77 GError* error = NULL;
78 gchar* uri = get_project_uri(plugin);
79 GtkFileFilter* filter;
81 GtkBuilder* bxml = gtk_builder_new ();
83 if (!gtk_builder_add_from_file (bxml, BUILDER_FILE, &error))
85 g_warning ("Couldn't load builder file: %s", error->message);
86 g_error_free (error);
89 plugin->dialog = GTK_WIDGET (gtk_builder_get_object (bxml, "patch_dialog"));
90 plugin->output_label = GTK_WIDGET (gtk_builder_get_object (bxml, "output"));
92 table = GTK_WIDGET (gtk_builder_get_object (bxml, "patch_table"));
94 plugin->file_chooser = gtk_file_chooser_button_new(_("File/Directory to patch"),
95 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
96 gtk_widget_set_hexpand (GTK_WIDGET (plugin->file_chooser), TRUE);
98 plugin->patch_chooser = gtk_file_chooser_button_new(_("Patch file"),
99 GTK_FILE_CHOOSER_ACTION_OPEN);
100 gtk_widget_set_hexpand (GTK_WIDGET (plugin->patch_chooser), TRUE);
102 if (uri)
104 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin->file_chooser),
105 uri);
106 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin->patch_chooser),
107 uri);
109 g_free(uri);
111 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin->file_chooser),
112 30);
113 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin->patch_chooser),
114 30);
116 filter = gtk_file_filter_new ();
117 gtk_file_filter_add_pattern (filter, "*.diff");
118 gtk_file_filter_add_pattern (filter, "*.patch");
119 gtk_file_filter_set_name (filter, _("Patches"));
120 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (plugin->patch_chooser),
121 filter);
122 filter = gtk_file_filter_new ();
123 gtk_file_filter_add_pattern (filter, "*");
124 gtk_file_filter_set_name (filter, _("All files"));
125 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (plugin->patch_chooser),
126 filter);
128 gtk_grid_attach (GTK_GRID (table), plugin->file_chooser, 1, 0, 1, 1);
129 gtk_grid_attach (GTK_GRID (table), plugin->patch_chooser, 1, 1, 1, 1);
131 scale = GTK_WIDGET (gtk_builder_get_object (bxml, "patch_level_scale"));
132 adj = gtk_range_get_adjustment(GTK_RANGE(scale));
133 g_signal_connect (G_OBJECT(adj), "value_changed",
134 G_CALLBACK (patch_level_changed), NULL);
136 plugin->patch_button = GTK_WIDGET (gtk_builder_get_object (bxml, "patch_button"));
137 plugin->cancel_button = GTK_WIDGET (gtk_builder_get_object (bxml, "cancel_button"));
138 plugin->dry_run_check = GTK_WIDGET (gtk_builder_get_object (bxml, "dryrun"));
140 g_signal_connect (G_OBJECT (plugin->patch_button), "clicked",
141 G_CALLBACK(on_ok_clicked), plugin);
142 g_signal_connect (G_OBJECT (plugin->cancel_button), "clicked",
143 G_CALLBACK(on_cancel_clicked), plugin);
145 plugin->executing = FALSE;
146 gtk_widget_show_all (plugin->dialog);
150 static void
151 on_ok_clicked (GtkButton *button, PatchPlugin* p_plugin)
153 gchar* tmp;
154 gchar* directory;
155 gchar* patch_file;
156 GString* command;
157 gchar* message;
158 IAnjutaMessageManager *mesg_manager;
160 g_return_if_fail (p_plugin != NULL);
162 mesg_manager = anjuta_shell_get_interface
163 (ANJUTA_PLUGIN (p_plugin)->shell, IAnjutaMessageManager, NULL);
165 g_return_if_fail (mesg_manager != NULL);
167 tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(p_plugin->file_chooser));
168 if (!g_file_test (tmp, G_FILE_TEST_IS_DIR))
170 g_free (tmp);
171 anjuta_util_dialog_error(GTK_WINDOW(p_plugin->dialog),
172 _("Please select the directory where the patch should be applied"));
173 return;
175 directory = g_shell_quote (tmp);
176 g_free (tmp);
178 tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(p_plugin->patch_chooser));
179 patch_file = g_shell_quote (tmp);
180 g_free (tmp);
182 p_plugin->mesg_view =
183 ianjuta_message_manager_add_view (mesg_manager, _("Patch"),
184 ICON_FILE, NULL);
186 ianjuta_message_manager_set_current_view (mesg_manager, p_plugin->mesg_view, NULL);
188 g_signal_connect (G_OBJECT (p_plugin->mesg_view), "buffer-flushed",
189 G_CALLBACK (on_msg_buffer), p_plugin);
191 command = g_string_new (NULL);
193 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_plugin->dry_run_check)))
194 g_string_printf (command, "patch --dry-run -d %s -p %d -f -i %s",
195 directory, patch_level, patch_file);
196 else
197 g_string_printf (command, "patch -d %s -p %d -f -i %s",
198 directory, patch_level, patch_file);
200 message = g_strdup_printf (_("Patching %s using %s\n"),
201 directory, patch_file);
203 g_free (patch_file);
204 g_free (directory);
206 ianjuta_message_view_append (p_plugin->mesg_view,
207 IANJUTA_MESSAGE_VIEW_TYPE_NORMAL,
208 message, "", NULL);
210 ianjuta_message_view_append (p_plugin->mesg_view,
211 IANJUTA_MESSAGE_VIEW_TYPE_NORMAL,
212 _("Patching…\n"), "", NULL);
214 g_signal_connect (p_plugin->launcher, "child-exited",
215 G_CALLBACK (on_patch_terminated), p_plugin);
217 if (!anjuta_launcher_is_busy (p_plugin->launcher))
219 anjuta_launcher_execute (p_plugin->launcher, command->str,
220 (AnjutaLauncherOutputCallback)on_msg_arrived, p_plugin);
221 p_plugin->executing = TRUE;
222 gtk_label_set_text(GTK_LABEL(p_plugin->output_label), _("Patching…"));
223 gtk_widget_set_sensitive(p_plugin->patch_button, FALSE);
225 else
226 anjuta_util_dialog_error(GTK_WINDOW(p_plugin->dialog),
227 _("There are unfinished jobs: please wait until they are finished."));
228 g_string_free(command, TRUE);
231 static void
232 on_cancel_clicked (GtkButton *button, PatchPlugin* plugin)
234 if (plugin->executing == TRUE)
236 anjuta_launcher_reset(plugin->launcher);
238 gtk_widget_hide (GTK_WIDGET(plugin->dialog));
239 gtk_widget_destroy (GTK_WIDGET(plugin->dialog));
242 static void
243 on_msg_arrived (AnjutaLauncher *launcher,
244 AnjutaLauncherOutputType output_type,
245 const gchar* line, gpointer data)
247 g_return_if_fail (line != NULL);
249 PatchPlugin* p_plugin = ANJUTA_PLUGIN_PATCH (data);
250 ianjuta_message_view_buffer_append (p_plugin->mesg_view, line, NULL);
253 static void
254 on_patch_terminated (AnjutaLauncher *launcher,
255 gint child_pid, gint status, gulong time_taken,
256 gpointer data)
258 g_return_if_fail (launcher != NULL);
260 PatchPlugin* plugin = ANJUTA_PLUGIN_PATCH (data);
262 g_signal_handlers_disconnect_by_func (G_OBJECT (launcher),
263 G_CALLBACK (on_patch_terminated),
264 plugin);
266 if (status != 0)
268 gtk_label_set_text(GTK_LABEL(plugin->output_label),
269 _("Patch failed.\nPlease review the failure messages.\n"
270 "Examine and remove any rejected files.\n"));
271 gtk_widget_set_sensitive(plugin->patch_button, TRUE);
273 else
275 gtk_label_set_text(GTK_LABEL(plugin->output_label), _("Patching complete"));
276 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(plugin->dry_run_check)))
278 gtk_widget_hide (plugin->dialog);
279 gtk_widget_destroy (plugin->dialog);
281 else
282 gtk_widget_set_sensitive(plugin->patch_button, TRUE);
285 plugin->executing = FALSE;
286 plugin->mesg_view = NULL;
289 static void
290 on_msg_buffer (IAnjutaMessageView *view, const gchar *line,
291 PatchPlugin *plugin)
293 ianjuta_message_view_append (view, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, line, "", NULL);