Integrate adding files with the file manager
[anjuta-git-plugin.git] / plugins / patch / patch-plugin.c
blob45787778db725185f00f819efa4db804f3b8b6da
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>
22 #include "plugin.h"
23 #include "patch-plugin.h"
25 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/patch-plugin.glade"
27 static void patch_level_changed (GtkAdjustment *adj);
29 static void on_ok_clicked (GtkButton *button, PatchPlugin* p_plugin);
30 static void on_cancel_clicked (GtkButton *button, PatchPlugin* plugin);
32 static void on_msg_arrived (AnjutaLauncher *launcher,
33 AnjutaLauncherOutputType output_type,
34 const gchar* line, gpointer data);
35 static void on_msg_buffer (IAnjutaMessageView *view, const gchar *line,
36 PatchPlugin *plugin);
38 static void on_patch_terminated (AnjutaLauncher *launcher,
39 gint child_pid, gint status, gulong time_taken,
40 gpointer data);
43 static gint patch_level = 0;
46 static void
47 patch_level_changed (GtkAdjustment *adj)
49 patch_level = (gint) adj->value;
52 static gchar* get_project_uri(PatchPlugin *plugin)
54 GValue value = {0, };
55 gchar* uri;
56 GError* err = NULL;
57 anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell,
58 "project_root_uri",
59 &value,
60 &err);
61 if (err)
63 g_error_free(err);
64 return NULL;
66 uri = g_value_dup_string (&value);
67 return uri;
70 void
71 patch_show_gui (PatchPlugin *plugin)
73 GtkWidget* table;
74 GtkWidget* scale;
75 GtkAdjustment* adj;
76 gchar* uri = get_project_uri(plugin);
77 GtkFileFilter* filter;
79 GladeXML* gxml;
81 gxml = glade_xml_new(GLADE_FILE, "patch_dialog", NULL);
83 plugin->dialog = glade_xml_get_widget(gxml, "patch_dialog");
84 plugin->output_label = glade_xml_get_widget(gxml, "output");
86 table = glade_xml_get_widget(gxml, "patch_table");
88 plugin->file_chooser = gtk_file_chooser_button_new(_("File/Directory to patch"),
89 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
91 plugin->patch_chooser = gtk_file_chooser_button_new(_("Patch file"),
92 GTK_FILE_CHOOSER_ACTION_OPEN);
94 if (uri)
96 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin->file_chooser),
97 uri);
98 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin->patch_chooser),
99 uri);
101 g_free(uri);
103 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin->file_chooser),
104 30);
105 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin->patch_chooser),
106 30);
108 filter = gtk_file_filter_new ();
109 gtk_file_filter_add_pattern (filter, "*.diff");
110 gtk_file_filter_add_pattern (filter, "*.patch");
111 gtk_file_filter_set_name (filter, _("Patches"));
112 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (plugin->patch_chooser),
113 filter);
114 filter = gtk_file_filter_new ();
115 gtk_file_filter_add_pattern (filter, "*");
116 gtk_file_filter_set_name (filter, _("All files"));
117 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (plugin->patch_chooser),
118 filter);
120 gtk_table_attach_defaults(GTK_TABLE(table), plugin->file_chooser, 1, 2, 0, 1);
121 gtk_table_attach_defaults(GTK_TABLE(table), plugin->patch_chooser, 1, 2, 1, 2);
123 scale = glade_xml_get_widget(gxml, "patch_level_scale");
124 adj = gtk_range_get_adjustment(GTK_RANGE(scale));
125 g_signal_connect (G_OBJECT(adj), "value_changed",
126 GTK_SIGNAL_FUNC (patch_level_changed), NULL);
128 plugin->patch_button = glade_xml_get_widget(gxml, "patch_button");
129 plugin->cancel_button = glade_xml_get_widget(gxml, "cancel_button");
130 plugin->dry_run_check = glade_xml_get_widget(gxml, "dryrun");
132 g_signal_connect (G_OBJECT (plugin->patch_button), "clicked",
133 G_CALLBACK(on_ok_clicked), plugin);
134 g_signal_connect (G_OBJECT (plugin->cancel_button), "clicked",
135 G_CALLBACK(on_cancel_clicked), plugin);
137 plugin->executing = FALSE;
138 gtk_widget_show_all (plugin->dialog);
142 static void
143 on_ok_clicked (GtkButton *button, PatchPlugin* p_plugin)
145 const gchar* directory;
146 const gchar* patch_file;
147 GString* command = g_string_new (NULL);
148 gchar* message;
149 IAnjutaMessageManager *mesg_manager;
151 g_return_if_fail (p_plugin != NULL);
153 mesg_manager = anjuta_shell_get_interface
154 (ANJUTA_PLUGIN (p_plugin)->shell, IAnjutaMessageManager, NULL);
156 g_return_if_fail (mesg_manager != NULL);
158 p_plugin->mesg_view =
159 ianjuta_message_manager_add_view (mesg_manager, _("Patch"),
160 ICON_FILE, NULL);
162 ianjuta_message_manager_set_current_view (mesg_manager, p_plugin->mesg_view, NULL);
164 g_signal_connect (G_OBJECT (p_plugin->mesg_view), "buffer-flushed",
165 G_CALLBACK (on_msg_buffer), p_plugin);
167 directory = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(p_plugin->file_chooser));
168 patch_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(p_plugin->patch_chooser));
170 if (!g_file_test (directory, G_FILE_TEST_IS_DIR))
172 g_string_free (command, TRUE);
173 anjuta_util_dialog_error(GTK_WINDOW(p_plugin->dialog),
174 _("Please select the directory where the patch should be applied"));
175 return;
178 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_plugin->dry_run_check)))
179 g_string_sprintf (command, "patch --dry-run -d %s -p %d -f -i %s",
180 directory, patch_level, patch_file);
181 else
182 g_string_sprintf (command, "patch -d %s -p %d -f -i %s",
183 directory, patch_level, patch_file);
185 message = g_strdup_printf (_("Patching %s using %s\n"),
186 directory, patch_file);
188 ianjuta_message_view_append (p_plugin->mesg_view,
189 IANJUTA_MESSAGE_VIEW_TYPE_NORMAL,
190 message, "", NULL);
192 ianjuta_message_view_append (p_plugin->mesg_view,
193 IANJUTA_MESSAGE_VIEW_TYPE_NORMAL,
194 _("Patching...\n"), "", NULL);
196 g_signal_connect (p_plugin->launcher, "child-exited",
197 G_CALLBACK (on_patch_terminated), p_plugin);
199 if (!anjuta_launcher_is_busy (p_plugin->launcher))
201 anjuta_launcher_execute (p_plugin->launcher, command->str,
202 (AnjutaLauncherOutputCallback)on_msg_arrived, p_plugin);
203 p_plugin->executing = TRUE;
204 gtk_label_set_text(GTK_LABEL(p_plugin->output_label), "Patching...");
205 gtk_widget_set_sensitive(p_plugin->patch_button, FALSE);
207 else
208 anjuta_util_dialog_error(GTK_WINDOW(p_plugin->dialog),
209 _("There are unfinished jobs, please wait until they are finished."));
210 g_string_free(command, TRUE);
213 static void
214 on_cancel_clicked (GtkButton *button, PatchPlugin* plugin)
216 if (plugin->executing == TRUE)
218 anjuta_launcher_reset(plugin->launcher);
220 gtk_widget_hide (GTK_WIDGET(plugin->dialog));
221 gtk_widget_destroy (GTK_WIDGET(plugin->dialog));
224 static void
225 on_msg_arrived (AnjutaLauncher *launcher,
226 AnjutaLauncherOutputType output_type,
227 const gchar* line, gpointer data)
229 g_return_if_fail (line != NULL);
231 PatchPlugin* p_plugin = ANJUTA_PLUGIN_PATCH (data);
232 ianjuta_message_view_buffer_append (p_plugin->mesg_view, line, NULL);
235 static void
236 on_patch_terminated (AnjutaLauncher *launcher,
237 gint child_pid, gint status, gulong time_taken,
238 gpointer data)
240 g_return_if_fail (launcher != NULL);
242 PatchPlugin* plugin = ANJUTA_PLUGIN_PATCH (data);
244 g_signal_handlers_disconnect_by_func (G_OBJECT (launcher),
245 G_CALLBACK (on_patch_terminated),
246 plugin);
248 if (status != 0)
250 gtk_label_set_text(GTK_LABEL(plugin->output_label),
251 _("Patch failed.\nPlease review the failure messages.\n"
252 "Examine and remove any rejected files.\n"));
253 gtk_widget_set_sensitive(plugin->patch_button, TRUE);
255 else
257 gtk_label_set_text(GTK_LABEL(plugin->output_label), "Patching complete");
258 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(plugin->dry_run_check)))
260 gtk_widget_hide (plugin->dialog);
261 gtk_widget_destroy (plugin->dialog);
263 else
264 gtk_widget_set_sensitive(plugin->patch_button, TRUE);
267 plugin->executing = FALSE;
268 plugin->mesg_view = NULL;
271 static void
272 on_msg_buffer (IAnjutaMessageView *view, const gchar *line,
273 PatchPlugin *plugin)
275 ianjuta_message_view_append (view, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, line, "", NULL);