Put all of the UI utility functions into the "git" namespace.
[anjuta-git-plugin.git] / plugins / git / git-ui-utils.c
blob81f79b18d1fda91ee94f6341417f21036cc556e3
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.
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.
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.
25 #include "git-ui-utils.h"
27 /* Private structure for pulse progress */
28 typedef struct
30 AnjutaStatus *status;
31 gchar *text;
32 } PulseProgressData;
34 GitUIData*
35 git_ui_data_new (Git* plugin, GladeXML* gxml)
37 GitUIData* data = g_new0 (GitUIData, 1);
38 data->plugin = plugin;
39 data->gxml = gxml;
41 return data;
44 void
45 git_ui_data_free (GitUIData* data)
47 g_object_unref (data->gxml);
48 g_free (data);
51 GitProgressData *
52 git_progress_data_new (Git *plugin, const gchar *text)
54 GitProgressData *data;
55 AnjutaStatus *status;
57 data = g_new0 (GitProgressData, 1);
58 data->plugin = plugin;
59 data->text = g_strdup (text);
60 data->last_progress = 100; /* Add the ticks when we get a progress signal */
62 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
64 return data;
67 void
68 git_progress_data_free (GitProgressData *data)
70 AnjutaStatus *status;
72 status = anjuta_shell_get_status (ANJUTA_PLUGIN (data->plugin)->shell,
73 NULL);
75 g_free (data->text);
76 g_free (data);
79 static void
80 on_message_view_destroy (Git* plugin, gpointer destroyed_view)
82 plugin->message_view = NULL;
85 void
86 git_create_message_view (Git *plugin)
88 IAnjutaMessageManager* message_manager;
91 message_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
92 IAnjutaMessageManager, NULL);
93 plugin->message_view = ianjuta_message_manager_get_view_by_name (message_manager,
94 _("Git"),
95 NULL);
96 if (!plugin->message_view)
98 plugin->message_view = ianjuta_message_manager_add_view (message_manager,
99 _("Git"),
100 ICON_FILE,
101 NULL);
102 g_object_weak_ref (G_OBJECT (plugin->message_view),
103 (GWeakNotify) on_message_view_destroy, plugin);
106 ianjuta_message_view_clear(plugin->message_view, NULL);
107 ianjuta_message_manager_set_current_view (message_manager,
108 plugin->message_view,
109 NULL);
112 gboolean
113 git_check_input (GtkWidget *parent, GtkWidget *widget, const gchar *input,
114 const gchar *error_message)
116 gboolean ret;
117 GtkWidget *dialog;
119 ret = FALSE;
121 if (input)
123 if (strlen (input) > 0)
124 ret = TRUE;
127 if (!ret)
129 dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
130 GTK_DIALOG_DESTROY_WITH_PARENT,
131 GTK_MESSAGE_WARNING,
132 GTK_BUTTONS_OK,
133 error_message);
135 gtk_dialog_run (GTK_DIALOG (dialog));
136 gtk_widget_destroy (dialog);
138 gtk_window_set_focus (GTK_WINDOW (parent), widget);
142 return ret;
145 gchar *
146 git_get_log_from_textview (GtkWidget* textview)
148 gchar* log;
149 GtkTextBuffer* textbuf;
150 GtkTextIter iterbegin, iterend;
152 textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
153 gtk_text_buffer_get_start_iter(textbuf, &iterbegin);
154 gtk_text_buffer_get_end_iter(textbuf, &iterend) ;
155 log = gtk_text_buffer_get_text(textbuf, &iterbegin, &iterend, FALSE);
156 return log;
159 static gboolean
160 status_pulse_timer (PulseProgressData *data)
162 anjuta_status_progress_pulse (data->status, data->text);
163 return TRUE;
166 static gboolean
167 pulse_timer (GtkProgressBar *progress_bar)
169 gtk_progress_bar_pulse (progress_bar);
170 return TRUE;
173 static void
174 on_pulse_timer_destroyed (PulseProgressData *data)
176 anjuta_status_progress_reset (data->status);
178 g_free (data->text);
179 g_free (data);
182 guint
183 git_status_bar_progress_pulse (Git *plugin, gchar *text)
185 PulseProgressData *data;
187 data = g_new0 (PulseProgressData, 1);
188 data->status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell,
189 NULL);
190 data->text = g_strdup (text);
192 return g_timeout_add_full (G_PRIORITY_DEFAULT, 100,
193 (GSourceFunc) status_pulse_timer, data,
194 (GDestroyNotify) on_pulse_timer_destroyed);
197 void
198 git_clear_status_bar_progress_pulse (guint timer_id)
200 g_source_remove (timer_id);
203 void
204 git_report_errors (AnjutaCommand *command, guint return_code)
206 gchar *message;
208 /* In some cases, git might report errors yet still indicate success.
209 * When this happens, use a warning dialog instead of an error, so the user
210 * knows that something actually happened. */
211 message = anjuta_command_get_error_message (command);
213 if (message)
215 if (return_code != 0)
216 anjuta_util_dialog_error (NULL, message);
217 else
218 anjuta_util_dialog_warning (NULL, message);
220 g_free (message);
224 static void
225 stop_pulse_timer (gpointer timer_id, GtkProgressBar *progress_bar)
227 g_source_remove (GPOINTER_TO_UINT (timer_id));
230 void
231 git_pulse_progress_bar (GtkProgressBar *progress_bar)
233 guint timer_id;
235 timer_id = g_timeout_add (100, (GSourceFunc) pulse_timer,
236 progress_bar);
237 g_object_set_data (G_OBJECT (progress_bar), "pulse-timer-id",
238 GUINT_TO_POINTER (timer_id));
240 g_object_weak_ref (G_OBJECT (progress_bar),
241 (GWeakNotify) stop_pulse_timer,
242 GUINT_TO_POINTER (timer_id));
245 gchar *
246 git_get_filename_from_full_path (gchar *path)
248 gchar *last_slash;
250 last_slash = strrchr (path, '/');
252 /* There might be a trailing slash in the string */
253 if ((last_slash - path) < strlen (path))
254 return g_strdup (last_slash + 1);
255 else
256 return g_strdup ("");
259 const gchar *
260 git_get_relative_path (const gchar *path, const gchar *working_directory)
262 /* Path could already be a relative path */
263 if (strstr (path, working_directory))
264 return path + strlen (working_directory) + 1;
265 else
266 return path;
269 void
270 on_git_command_finished (AnjutaCommand *command, guint return_code,
271 gpointer user_data)
273 git_report_errors (command, return_code);
275 g_object_unref (command);
278 void
279 on_git_status_command_data_arrived (AnjutaCommand *command,
280 AnjutaVcsStatusTreeView *tree_view)
282 GQueue *status_queue;
283 GitStatus *status;
284 gchar *path;
286 status_queue = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
288 while (g_queue_peek_head (status_queue))
290 status = g_queue_pop_head (status_queue);
291 path = git_status_get_path (status);
293 anjuta_vcs_status_tree_view_add (tree_view, path,
294 git_status_get_vcs_status (status),
295 FALSE);
297 g_object_unref (status);
298 g_free (path);
302 void
303 on_git_command_info_arrived (AnjutaCommand *command, Git *plugin)
305 GQueue *info;
306 gchar *message;
308 info = git_command_get_info_queue (GIT_COMMAND (command));
310 while (g_queue_peek_head (info))
312 message = g_queue_pop_head (info);
313 ianjuta_message_view_append (plugin->message_view,
314 IANJUTA_MESSAGE_VIEW_TYPE_INFO,
315 message, "", NULL);
316 g_free (message);
320 void
321 on_git_command_progress (AnjutaCommand *command, gfloat progress,
322 GitProgressData *data)
324 AnjutaStatus *status;
325 gint ticks;
327 status = anjuta_shell_get_status (ANJUTA_PLUGIN (data->plugin)->shell,
328 NULL);
330 /* There are cases where there are multiple stages to a task, and each
331 * has their own progress indicator. If one stage has completed and another
332 * is beginning, add another 100 ticks to reflect the progress of this new
333 * stage. */
334 if (data->last_progress == 100)
336 anjuta_status_progress_add_ticks (status, 100);
337 data->last_progress = 0;
340 ticks = progress * 100;
341 anjuta_status_progress_increment_ticks (status,
342 (ticks - data->last_progress),
343 data->text);
344 data->last_progress = ticks;
347 void
348 on_git_list_branch_command_data_arrived (AnjutaCommand *command,
349 GitBranchComboData *data)
351 GQueue *output_queue;
352 GitBranch *branch;
354 output_queue = git_branch_list_command_get_output (GIT_BRANCH_LIST_COMMAND (command));
356 while (g_queue_peek_head (output_queue))
358 branch = g_queue_pop_head (output_queue);
359 git_branch_combo_model_append (data->model, branch);
360 g_object_unref (branch);
364 void
365 on_git_list_branch_command_finished (AnjutaCommand *command, guint return_code,
366 GitBranchComboData *data)
368 gtk_combo_box_set_active (data->combo_box, 0);
370 git_report_errors (command, return_code);
371 g_object_unref (command);
374 void
375 git_select_all_status_items (GtkButton *select_all_button,
376 AnjutaVcsStatusTreeView *tree_view)
378 anjuta_vcs_status_tree_view_select_all (tree_view);
381 void
382 git_clear_all_status_selections (GtkButton *clear_button,
383 AnjutaVcsStatusTreeView *tree_view)
385 anjuta_vcs_status_tree_view_unselect_all (tree_view);
388 void
389 git_init_whole_project (Git *plugin, GtkWidget* project, gboolean active)
391 gboolean project_loaded;
393 project_loaded = (plugin->project_root_directory != NULL);
395 gtk_widget_set_sensitive(project, project_loaded);
397 if (project_loaded)
398 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (project), active);
401 void
402 on_git_whole_project_toggled (GtkToggleButton* project, Git *plugin)
404 GtkWidget *path_entry;
406 path_entry = g_object_get_data (G_OBJECT (project), "file-entry");
408 gtk_widget_set_sensitive (path_entry,
409 !gtk_toggle_button_get_active (project));
412 void
413 git_send_raw_command_output_to_editor (AnjutaCommand *command,
414 IAnjutaEditor *editor)
416 GQueue *output;
417 gchar *line;
419 output = git_raw_output_command_get_output (GIT_RAW_OUTPUT_COMMAND (command));
421 while (g_queue_peek_head (output))
423 line = g_queue_pop_head (output);
424 ianjuta_editor_append (editor, line, strlen (line), NULL);
425 g_free (line);
429 void
430 on_git_diff_command_finished (AnjutaCommand *command, guint return_code,
431 Git *plugin)
433 AnjutaStatus *status;
435 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell,
436 NULL);
438 anjuta_status (status, _("Git: Diff complete."), 5);
440 git_report_errors (command, return_code);
442 g_object_unref (command);
445 void
446 git_stop_status_bar_progress_pulse (AnjutaCommand *command, guint return_code,
447 gpointer timer_id)
449 git_clear_status_bar_progress_pulse (GPOINTER_TO_UINT (timer_id));
452 void
453 git_hide_pulse_progress_bar (AnjutaCommand *command, guint return_code,
454 GtkProgressBar *progress_bar)
456 guint timer_id;
458 /* If the progress bar has already been destroyed, the timer should be
459 * stopped by stop_pulse_timer */
460 if (GTK_IS_PROGRESS_BAR (progress_bar))
462 timer_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (progress_bar),
463 "pulse-timer-id"));
465 g_source_remove (GPOINTER_TO_UINT (timer_id));
466 gtk_widget_hide (GTK_WIDGET (progress_bar));
470 /* This function is normally intended to disconnect stock data-arrived signal
471 * handlers in this file. It is assumed that object is the user data for the
472 * callback. If you use any of the stock callbacks defined here, make sure
473 * to weak ref its target with this callback. Make sure to cancel this ref
474 * by connecting git_cancel_data_arrived_signal_disconnect to the
475 * command-finished signal so we don't try to disconnect signals on a destroyed
476 * command. */
477 void
478 git_disconnect_data_arrived_signals (AnjutaCommand *command, GObject *object)
480 guint data_arrived_signal;
482 if (ANJUTA_IS_COMMAND (command))
484 data_arrived_signal = g_signal_lookup ("data-arrived",
485 ANJUTA_TYPE_COMMAND);
487 g_signal_handlers_disconnect_matched (command,
488 G_SIGNAL_MATCH_DATA,
489 data_arrived_signal,
491 NULL,
492 NULL,
493 object);
498 void
499 git_cancel_data_arrived_signal_disconnect (AnjutaCommand *command,
500 guint return_code,
501 GObject *signal_target)
503 g_object_weak_unref (signal_target,
504 (GWeakNotify) git_disconnect_data_arrived_signals,
505 command);