1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) James Liggett 2007 <jrliggett@cox.net>
6 * anjuta is free software.
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)
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 */
35 git_ui_data_new (Git
* plugin
, GladeXML
* gxml
)
37 GitUIData
* data
= g_new0 (GitUIData
, 1);
38 data
->plugin
= plugin
;
45 git_ui_data_free (GitUIData
* data
)
47 g_object_unref (data
->gxml
);
52 git_progress_data_new (Git
*plugin
, const gchar
*text
)
54 GitProgressData
*data
;
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
);
68 git_progress_data_free (GitProgressData
*data
)
72 status
= anjuta_shell_get_status (ANJUTA_PLUGIN (data
->plugin
)->shell
,
80 on_message_view_destroy (Git
* plugin
, gpointer destroyed_view
)
82 plugin
->message_view
= NULL
;
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
,
96 if (!plugin
->message_view
)
98 plugin
->message_view
= ianjuta_message_manager_add_view (message_manager
,
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
,
113 git_check_input (GtkWidget
*parent
, GtkWidget
*widget
, const gchar
*input
,
114 const gchar
*error_message
)
123 if (strlen (input
) > 0)
129 dialog
= gtk_message_dialog_new (GTK_WINDOW (parent
),
130 GTK_DIALOG_DESTROY_WITH_PARENT
,
135 gtk_dialog_run (GTK_DIALOG (dialog
));
136 gtk_widget_destroy (dialog
);
138 gtk_window_set_focus (GTK_WINDOW (parent
), widget
);
146 git_get_log_from_textview (GtkWidget
* textview
)
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
);
160 status_pulse_timer (PulseProgressData
*data
)
162 anjuta_status_progress_pulse (data
->status
, data
->text
);
167 pulse_timer (GtkProgressBar
*progress_bar
)
169 gtk_progress_bar_pulse (progress_bar
);
174 on_pulse_timer_destroyed (PulseProgressData
*data
)
176 anjuta_status_progress_reset (data
->status
);
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
,
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
);
198 git_clear_status_bar_progress_pulse (guint timer_id
)
200 g_source_remove (timer_id
);
204 git_report_errors (AnjutaCommand
*command
, guint return_code
)
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
);
215 if (return_code
!= 0)
216 anjuta_util_dialog_error (NULL
, message
);
218 anjuta_util_dialog_warning (NULL
, message
);
225 stop_pulse_timer (gpointer timer_id
, GtkProgressBar
*progress_bar
)
227 g_source_remove (GPOINTER_TO_UINT (timer_id
));
231 git_pulse_progress_bar (GtkProgressBar
*progress_bar
)
235 timer_id
= g_timeout_add (100, (GSourceFunc
) pulse_timer
,
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
));
246 git_get_filename_from_full_path (gchar
*path
)
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);
256 return g_strdup ("");
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;
270 on_git_command_finished (AnjutaCommand
*command
, guint return_code
,
273 git_report_errors (command
, return_code
);
275 g_object_unref (command
);
279 on_git_status_command_data_arrived (AnjutaCommand
*command
,
280 AnjutaVcsStatusTreeView
*tree_view
)
282 GQueue
*status_queue
;
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
),
297 g_object_unref (status
);
303 on_git_command_info_arrived (AnjutaCommand
*command
, Git
*plugin
)
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
,
321 on_git_command_progress (AnjutaCommand
*command
, gfloat progress
,
322 GitProgressData
*data
)
324 AnjutaStatus
*status
;
327 status
= anjuta_shell_get_status (ANJUTA_PLUGIN (data
->plugin
)->shell
,
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
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
),
344 data
->last_progress
= ticks
;
348 on_git_list_branch_command_data_arrived (AnjutaCommand
*command
,
349 GitBranchComboData
*data
)
351 GQueue
*output_queue
;
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
);
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
);
375 git_select_all_status_items (GtkButton
*select_all_button
,
376 AnjutaVcsStatusTreeView
*tree_view
)
378 anjuta_vcs_status_tree_view_select_all (tree_view
);
382 git_clear_all_status_selections (GtkButton
*clear_button
,
383 AnjutaVcsStatusTreeView
*tree_view
)
385 anjuta_vcs_status_tree_view_unselect_all (tree_view
);
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
);
398 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (project
), active
);
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
));
413 git_send_raw_command_output_to_editor (AnjutaCommand
*command
,
414 IAnjutaEditor
*editor
)
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
);
430 on_git_diff_command_finished (AnjutaCommand
*command
, guint return_code
,
433 AnjutaStatus
*status
;
435 status
= anjuta_shell_get_status (ANJUTA_PLUGIN (plugin
)->shell
,
438 anjuta_status (status
, _("Git: Diff complete."), 5);
440 git_report_errors (command
, return_code
);
442 g_object_unref (command
);
446 git_stop_status_bar_progress_pulse (AnjutaCommand
*command
, guint return_code
,
449 git_clear_status_bar_progress_pulse (GPOINTER_TO_UINT (timer_id
));
453 git_hide_pulse_progress_bar (AnjutaCommand
*command
, guint return_code
,
454 GtkProgressBar
*progress_bar
)
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
),
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
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
,
499 git_cancel_data_arrived_signal_disconnect (AnjutaCommand
*command
,
501 GObject
*signal_target
)
503 g_object_weak_unref (signal_target
,
504 (GWeakNotify
) git_disconnect_data_arrived_signals
,