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>
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
,
39 static void on_patch_terminated (AnjutaLauncher
*launcher
,
40 gint child_pid
, gint status
, gulong time_taken
,
44 static gint patch_level
= 0;
48 patch_level_changed (GtkAdjustment
*adj
)
50 patch_level
= (gint
) gtk_adjustment_get_value (adj
);
53 static gchar
* get_project_uri(PatchPlugin
*plugin
)
58 anjuta_shell_get_value (ANJUTA_PLUGIN (plugin
)->shell
,
59 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
67 uri
= g_value_dup_string (&value
);
72 patch_show_gui (PatchPlugin
*plugin
)
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
);
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
);
104 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin
->file_chooser
),
106 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER(plugin
->patch_chooser
),
111 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin
->file_chooser
),
113 gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(plugin
->patch_chooser
),
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
),
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
),
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
);
151 on_ok_clicked (GtkButton
*button
, PatchPlugin
* p_plugin
)
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
))
171 anjuta_util_dialog_error(GTK_WINDOW(p_plugin
->dialog
),
172 _("Please select the directory where the patch should be applied"));
175 directory
= g_shell_quote (tmp
);
178 tmp
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(p_plugin
->patch_chooser
));
179 patch_file
= g_shell_quote (tmp
);
182 p_plugin
->mesg_view
=
183 ianjuta_message_manager_add_view (mesg_manager
, _("Patch"),
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
);
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
);
206 ianjuta_message_view_append (p_plugin
->mesg_view
,
207 IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
,
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
);
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
);
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
));
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
);
254 on_patch_terminated (AnjutaLauncher
*launcher
,
255 gint child_pid
, gint status
, gulong time_taken
,
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
),
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
);
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
);
282 gtk_widget_set_sensitive(plugin
->patch_button
, TRUE
);
285 plugin
->executing
= FALSE
;
286 plugin
->mesg_view
= NULL
;
290 on_msg_buffer (IAnjutaMessageView
*view
, const gchar
*line
,
293 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
, line
, "", NULL
);