Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / plugins / git / git-log-dialog.c
blobcd595e28fa4911bd1c2b2d30e5a20c80980689ac
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-log-dialog.h"
26 #include "git-cat-file-menu.h"
28 enum
30 COL_REVISION,
32 NUM_COLS
35 typedef struct
37 Git *plugin;
38 GladeXML *gxml;
39 GtkListStore *list_store;
40 GtkCellRenderer *graph_renderer;
41 gchar *path;
42 GHashTable *refs;
43 GHashTable *filters;
44 } LogData;
46 static void
47 author_cell_function (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
48 GtkTreeModel *model, GtkTreeIter *iter,
49 gpointer user_data)
51 GitRevision *revision;
52 gchar *author;
54 gtk_tree_model_get (model, iter, COL_REVISION, &revision, -1);
55 author = git_revision_get_author (revision);
57 g_object_unref (revision);
59 g_object_set (renderer, "text", author, NULL);
61 g_free (author);
64 static void
65 date_cell_function (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
66 GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
68 GitRevision *revision;
69 gchar *date;
71 gtk_tree_model_get (model, iter, COL_REVISION, &revision, -1);
72 date = git_revision_get_formatted_date (revision);
74 g_object_unref (revision);
76 g_object_set (renderer, "text", date, NULL);
78 g_free (date);
81 static void
82 short_log_cell_function (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
83 GtkTreeModel *model, GtkTreeIter *iter,
84 gpointer user_data)
86 GitRevision *revision;
87 gchar *short_log;
89 gtk_tree_model_get (model, iter, COL_REVISION, &revision, -1);
90 short_log = git_revision_get_short_log (revision);
92 g_object_unref (revision);
94 g_object_set (renderer, "text", short_log, NULL);
96 g_free (short_log);
99 static void
100 ref_icon_cell_function (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
101 GtkTreeModel *model, GtkTreeIter *iter,
102 LogData *data)
104 GitRevision *revision;
105 gchar *sha;
107 gtk_tree_model_get (model, iter, COL_REVISION, &revision, -1);
108 sha = git_revision_get_sha (revision);
110 g_object_unref (revision);
112 if (g_hash_table_lookup_extended (data->refs, sha, NULL, NULL))
113 g_object_set (renderer, "stock-id", GTK_STOCK_INFO, NULL);
114 else
115 g_object_set (renderer, "stock-id", "", NULL);
117 g_free (sha);
120 static void
121 create_columns (LogData *data)
123 GtkWidget *log_changes_view;
124 gint font_size;
125 GtkTreeViewColumn *column;
126 GtkCellRenderer *renderer;
128 log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view");
129 font_size = PANGO_PIXELS (pango_font_description_get_size (GTK_WIDGET (log_changes_view)->style->font_desc));
131 /* Ref info */
132 column = gtk_tree_view_column_new ();
133 gtk_tree_view_append_column (GTK_TREE_VIEW (log_changes_view), column);
134 renderer = gtk_cell_renderer_pixbuf_new ();
135 gtk_tree_view_column_pack_start (column, renderer, TRUE);
136 gtk_tree_view_column_set_cell_data_func (column, renderer,
137 (GtkTreeCellDataFunc) ref_icon_cell_function,
138 data, NULL);
142 /* Graph */
143 column = gtk_tree_view_column_new ();
144 gtk_tree_view_append_column (GTK_TREE_VIEW (log_changes_view), column);
145 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
146 gtk_tree_view_column_set_min_width (column, font_size * 10);
147 gtk_tree_view_column_set_resizable (column, TRUE);
148 gtk_tree_view_column_pack_start (column, data->graph_renderer, TRUE);
149 gtk_tree_view_column_add_attribute (column, data->graph_renderer,
150 "revision", COL_REVISION);
151 gtk_tree_view_column_set_title (column, "Graph");
153 /* Short log */
154 column = gtk_tree_view_column_new ();
155 gtk_tree_view_append_column (GTK_TREE_VIEW (log_changes_view), column);
156 renderer = gtk_cell_renderer_text_new ();
157 g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
158 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
159 gtk_tree_view_column_set_min_width (column, font_size * 10);
160 gtk_tree_view_column_set_resizable (column, TRUE);
161 gtk_tree_view_column_set_expand (column, TRUE);
162 gtk_tree_view_column_pack_start (column, renderer, TRUE);
163 gtk_tree_view_column_set_cell_data_func (column, renderer,
164 (GtkTreeCellDataFunc) short_log_cell_function,
165 NULL, NULL);
166 gtk_tree_view_column_set_title (column, "Short log");
168 /* Author */
169 column = gtk_tree_view_column_new ();
170 gtk_tree_view_append_column (GTK_TREE_VIEW (log_changes_view), column);
171 renderer = gtk_cell_renderer_text_new ();
172 gtk_tree_view_column_set_resizable (column, TRUE);
173 gtk_tree_view_column_pack_start (column, renderer, TRUE);
174 gtk_tree_view_column_set_cell_data_func (column, renderer,
175 (GtkTreeCellDataFunc) author_cell_function,
176 NULL, NULL);
177 gtk_tree_view_column_set_title (column, "Author");
179 /* Date */
180 column = gtk_tree_view_column_new ();
181 gtk_tree_view_append_column (GTK_TREE_VIEW (log_changes_view), column);
182 renderer = gtk_cell_renderer_text_new ();
183 gtk_tree_view_column_set_resizable (column, TRUE);
184 gtk_tree_view_column_pack_start (column, renderer, TRUE);
185 gtk_tree_view_column_set_cell_data_func (column, renderer,
186 (GtkTreeCellDataFunc) date_cell_function,
187 NULL, NULL);
188 gtk_tree_view_column_set_title (column, "Date");
190 gtk_tree_view_set_model (GTK_TREE_VIEW (log_changes_view),
191 GTK_TREE_MODEL (data->list_store));
192 g_object_unref (data->list_store);
196 static void
197 on_log_command_finished (AnjutaCommand *command, guint return_code,
198 LogData *data)
200 GtkWidget *log_changes_view;
201 GQueue *queue;
202 GtkTreeIter iter;
203 GitRevision *revision;
205 if (return_code != 0)
207 git_report_errors (command, return_code);
208 g_object_unref (command);
210 return;
213 log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view");
215 g_object_ref (data->list_store);
216 gtk_tree_view_set_model (GTK_TREE_VIEW (log_changes_view), NULL);
218 queue = git_log_command_get_output_queue (GIT_LOG_COMMAND (command));
220 while (g_queue_peek_head (queue))
222 revision = g_queue_pop_head (queue);
224 gtk_list_store_append (data->list_store, &iter);
225 gtk_list_store_set (data->list_store, &iter, COL_REVISION, revision, -1);
226 g_object_unref (revision);
229 giggle_graph_renderer_validate_model (GIGGLE_GRAPH_RENDERER (data->graph_renderer),
230 GTK_TREE_MODEL (data->list_store),
231 COL_REVISION);
232 gtk_tree_view_set_model (GTK_TREE_VIEW (log_changes_view),
233 GTK_TREE_MODEL (data->list_store));
234 g_object_unref (data->list_store);
236 g_object_unref (command);
239 static void
240 on_ref_command_finished (AnjutaCommand *command, guint return_code,
241 LogData *data)
243 gchar *path;
244 const gchar *relative_path;
245 GtkWidget *log_changes_view;
246 GtkTreeViewColumn *graph_column;
247 gchar *author;
248 gchar *grep;
249 gchar *since_date;
250 gchar *until_date;
251 gchar *since_commit;
252 gchar *until_commit;
253 GitLogCommand *log_command;
254 gint pulse_timer_id;
256 path = g_object_get_data (G_OBJECT (command), "path");
257 relative_path = NULL;
259 if (return_code != 0)
261 git_report_errors (command, return_code);
262 g_object_unref (command);
264 return;
267 if (path)
269 relative_path = git_get_relative_path (path,
270 data->plugin->project_root_directory);
273 /* If the user is using any filters or getting the log of an individual,
274 * file or folder, hide the graph column, because we can't be assured that
275 * the graph will be correct in these cases */
276 log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view");
277 graph_column = gtk_tree_view_get_column (GTK_TREE_VIEW (log_changes_view),
280 if (g_hash_table_size (data->filters) > 0 || path)
281 gtk_tree_view_column_set_visible (graph_column, FALSE);
282 else
283 gtk_tree_view_column_set_visible (graph_column, TRUE);
285 /* Get the filter data */
286 author = g_hash_table_lookup (data->filters, "author");
287 grep = g_hash_table_lookup (data->filters, "grep");
288 since_date = g_hash_table_lookup (data->filters, "since-date");
289 until_date = g_hash_table_lookup (data->filters, "until-date");
290 since_commit = g_hash_table_lookup (data->filters, "since-commit");
291 until_commit = g_hash_table_lookup (data->filters, "until-commit");
293 if (data->refs)
294 g_hash_table_unref (data->refs);
296 data->refs = git_ref_command_get_refs (GIT_REF_COMMAND (command));
297 log_command = git_log_command_new (data->plugin->project_root_directory,
298 relative_path,
299 author, grep, since_date, until_date,
300 since_commit, until_commit);
302 gtk_list_store_clear (data->list_store);
304 pulse_timer_id = git_status_bar_progress_pulse (data->plugin,
305 _("Git: Retrieving"
306 " log..."));
308 g_signal_connect (G_OBJECT (log_command), "command-finished",
309 G_CALLBACK (git_stop_status_bar_progress_pulse),
310 GUINT_TO_POINTER (pulse_timer_id));
312 g_signal_connect (G_OBJECT (log_command), "command-finished",
313 G_CALLBACK (on_log_command_finished),
314 data);
316 anjuta_command_start (ANJUTA_COMMAND (log_command));
318 g_object_unref (command);
321 static void
322 on_log_view_button_clicked (GtkButton *button, LogData *data)
324 gchar *path;
325 AnjutaShell *shell;
326 GtkWidget *log_whole_project_check;
327 GtkWidget *log_path_entry;
328 GitRefCommand *ref_command;
330 path = NULL;
332 log_whole_project_check = glade_xml_get_widget (data->gxml,
333 "log_whole_project_check");
335 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (log_whole_project_check)))
337 log_path_entry = glade_xml_get_widget (data->gxml, "log_path_entry");
338 path = gtk_editable_get_chars (GTK_EDITABLE (log_path_entry), 0, -1);
340 /* Log widget belongs to the shell at this point. */
341 shell = ANJUTA_PLUGIN (data->plugin)->shell;
343 if (!git_check_input (GTK_WIDGET (shell), log_path_entry, path,
344 _("Please enter a path.")))
346 g_free (path);
347 return;
350 /* Don't allow the user to try to view revisions of directories */
351 git_cat_file_menu_set_sensitive (data->plugin,
352 !g_file_test (path,
353 G_FILE_TEST_IS_DIR));
355 else
357 /* Users can't get individual files if they're viewing the whole
358 * project log. */
359 git_cat_file_menu_set_sensitive (data->plugin, FALSE);
362 ref_command = git_ref_command_new (data->plugin->project_root_directory);
364 g_signal_connect (G_OBJECT (ref_command), "command-finished",
365 G_CALLBACK (on_ref_command_finished),
366 data);
369 /* Attach path to this command so it can be passed to the log command. */
370 g_object_set_data_full (G_OBJECT (ref_command), "path",
371 g_strdup (path), g_free);
373 g_free (path);
375 anjuta_command_start (ANJUTA_COMMAND (ref_command));
378 static void
379 on_log_vbox_destroy (GtkObject *log_vbox, LogData *data)
381 g_free (data->path);
382 g_object_unref (data->gxml);
384 if (data->refs)
385 g_hash_table_unref (data->refs);
387 g_hash_table_destroy (data->filters);
389 g_free (data);
392 static void
393 on_log_message_command_finished (AnjutaCommand *command, guint return_code,
394 LogData *data)
396 GtkWidget *log_text_view;
397 GtkTextBuffer *buffer;
398 gchar *log_message;
400 log_text_view = glade_xml_get_widget (data->gxml, "log_text_view");
401 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (log_text_view));
402 log_message = git_log_message_command_get_message (GIT_LOG_MESSAGE_COMMAND (command));
404 gtk_text_buffer_set_text (buffer, log_message, strlen (log_message));
406 g_free (log_message);
407 g_object_unref (command);
410 static gboolean
411 on_log_changes_view_row_selected (GtkTreeSelection *selection,
412 GtkTreeModel *model,
413 GtkTreePath *path,
414 gboolean path_currently_selected,
415 LogData *data)
417 GtkTreeIter iter;
418 GitRevision *revision;
419 gchar *sha;
420 GitLogMessageCommand *log_message_command;
422 if (!path_currently_selected)
424 gtk_tree_model_get_iter (model, &iter, path);
425 gtk_tree_model_get (model, &iter, COL_REVISION, &revision, -1);
426 sha = git_revision_get_sha (revision);
428 log_message_command = git_log_message_command_new (data->plugin->project_root_directory,
429 sha);
431 g_free (sha);
432 g_object_unref (revision);
434 g_signal_connect (G_OBJECT (log_message_command), "command-finished",
435 G_CALLBACK (on_log_message_command_finished),
436 data);
438 anjuta_command_start (ANJUTA_COMMAND (log_message_command));
441 return TRUE;
444 static gboolean
445 on_log_changes_view_query_tooltip (GtkWidget *log_changes_view, gint x, gint y,
446 gboolean keyboard_mode, GtkTooltip *tooltip,
447 LogData *data)
449 gboolean ret;
450 GtkTreeViewColumn *ref_column;
451 gint bin_x;
452 gint bin_y;
453 GtkTreeViewColumn *current_column;
454 GtkTreePath *path;
455 GtkTreeModel *model;
456 GtkTreeIter iter;
457 GitRevision *revision;
458 gchar *sha;
459 GList *ref_list;
460 GList *current_ref;
461 GString *tooltip_string;
462 gchar *ref_name;
463 GitRefType ref_type;
465 ret = FALSE;
467 ref_column = gtk_tree_view_get_column (GTK_TREE_VIEW (log_changes_view), 0);
469 gtk_tree_view_convert_widget_to_bin_window_coords (GTK_TREE_VIEW (log_changes_view),
470 x, y, &bin_x, &bin_y);
471 gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (log_changes_view), bin_x,
472 bin_y, &path, &current_column, NULL, NULL);
474 /* We need to be in the ref icon column */
475 if (current_column == ref_column)
477 model = gtk_tree_view_get_model (GTK_TREE_VIEW (log_changes_view));
478 gtk_tree_model_get_iter (model, &iter, path);
480 gtk_tree_model_get (model, &iter, COL_REVISION, &revision, -1);
481 sha = git_revision_get_sha (revision);
483 g_object_unref (revision);
485 ref_list = g_hash_table_lookup (data->refs, sha);
486 g_free (sha);
488 if (ref_list)
490 current_ref = ref_list;
491 tooltip_string = g_string_new ("");
493 while (current_ref)
495 ref_name = git_ref_get_name (GIT_REF (current_ref->data));
496 ref_type = git_ref_get_ref_type (GIT_REF (current_ref->data));
498 if (tooltip_string->len > 0)
499 g_string_append (tooltip_string, "\n");
501 switch (ref_type)
503 case GIT_REF_TYPE_BRANCH:
504 g_string_append_printf (tooltip_string,
505 _("<b>Branch:</b> %s"),
506 ref_name);
507 break;
508 case GIT_REF_TYPE_TAG:
509 g_string_append_printf (tooltip_string,
510 _("<b>Tag:</b> %s"),
511 ref_name);
512 break;
513 case GIT_REF_TYPE_REMOTE:
514 g_string_append_printf (tooltip_string,
515 _("<b>Remote:</b> %s"),
516 ref_name);
517 break;
518 default:
519 break;
522 g_free (ref_name);
523 current_ref = g_list_next (current_ref);
526 gtk_tooltip_set_markup (tooltip, tooltip_string->str);
527 g_string_free (tooltip_string, TRUE);
529 ret = TRUE;
533 gtk_tree_path_free (path);
534 return ret;
539 static gboolean
540 on_log_changes_view_button_press_event (GtkWidget *log_changes_view,
541 GdkEventButton *event,
542 Git *plugin)
544 GtkTreeSelection *selection;
546 if (event->type == GDK_BUTTON_PRESS)
548 if (event->button == 3)
550 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (log_changes_view));
552 if (gtk_tree_selection_count_selected_rows (selection) > 0)
554 gtk_menu_popup (GTK_MENU(plugin->log_popup_menu), NULL, NULL,
555 NULL, NULL, event->button, event->time);
559 return FALSE;
562 static void
563 on_log_filter_entry_changed (GtkEditable *editable, LogData *data)
565 gchar *filter_name;
566 gchar *text;
568 filter_name = g_object_get_data (G_OBJECT (editable), "filter-name");
569 text = gtk_editable_get_chars (editable, 0, -1);
571 if (strlen (text) > 0)
572 g_hash_table_insert (data->filters, filter_name, g_strdup (text));
573 else
574 g_hash_table_remove (data->filters, filter_name);
576 g_free (text);
579 static void
580 on_log_filter_date_changed (GtkCalendar *calendar, LogData *data)
582 gchar *filter_name;
583 guint year;
584 guint month;
585 guint day;
586 gchar *date;
588 filter_name = g_object_get_data (G_OBJECT (calendar), "filter-name");
590 gtk_calendar_get_date (calendar, &year, &month, &day);
591 date = g_strdup_printf ("%i-%02i-%02i", year, (month + 1), day);
592 g_hash_table_insert (data->filters, filter_name, g_strdup (date));
594 g_free (date);
597 static void
598 on_log_filter_date_check_toggled (GtkToggleButton *toggle_button, LogData *data)
600 GtkCalendar *calendar;
601 gchar *filter_name;
603 calendar = g_object_get_data (G_OBJECT (toggle_button), "calendar");
605 if (gtk_toggle_button_get_active (toggle_button))
607 gtk_widget_set_sensitive (GTK_WIDGET (calendar), TRUE);
609 /* Treat the currently selected date as a date to filter on */
610 on_log_filter_date_changed (calendar, data);
612 else
614 filter_name = g_object_get_data (G_OBJECT (calendar), "filter-name");
616 gtk_widget_set_sensitive (GTK_WIDGET (calendar), FALSE);
617 g_hash_table_remove (data->filters, filter_name);
621 static void
622 on_log_filter_clear_button_clicked (GtkButton *button, LogData *data)
624 GtkWidget *log_filter_author_entry;
625 GtkWidget *log_filter_grep_entry;
626 GtkWidget *log_filter_from_check;
627 GtkWidget *log_filter_to_check;
628 GtkWidget *log_filter_from_entry;
629 GtkWidget *log_filter_to_entry;
631 log_filter_author_entry = glade_xml_get_widget (data->gxml,
632 "log_filter_author_entry");
633 log_filter_grep_entry = glade_xml_get_widget (data->gxml,
634 "log_filter_grep_entry");
635 log_filter_from_check = glade_xml_get_widget (data->gxml,
636 "log_filter_from_check");
637 log_filter_to_check = glade_xml_get_widget (data->gxml,
638 "log_filter_to_check");
639 log_filter_from_entry = glade_xml_get_widget (data->gxml,
640 "log_filter_from_entry");
641 log_filter_to_entry = glade_xml_get_widget (data->gxml,
642 "log_filter_to_entry");
644 gtk_entry_set_text (GTK_ENTRY (log_filter_author_entry), "");
645 gtk_entry_set_text (GTK_ENTRY (log_filter_grep_entry), "");
646 gtk_entry_set_text (GTK_ENTRY (log_filter_from_entry), "");
647 gtk_entry_set_text (GTK_ENTRY (log_filter_from_entry), "");
648 gtk_entry_set_text (GTK_ENTRY (log_filter_to_entry), "");
650 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_filter_from_check),
651 FALSE);
652 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_filter_to_check),
653 FALSE);
657 static void
658 setup_filters (LogData *data)
660 GtkWidget *log_filter_author_entry;
661 GtkWidget *log_filter_grep_entry;
662 GtkWidget *log_filter_from_check;
663 GtkWidget *log_filter_to_check;
664 GtkWidget *log_filter_from_calendar;
665 GtkWidget *log_filter_to_calendar;
666 GtkWidget *log_filter_from_entry;
667 GtkWidget *log_filter_to_entry;
668 GtkWidget *log_filter_clear_button;
670 data->filters = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
671 g_free);
673 log_filter_author_entry = glade_xml_get_widget (data->gxml,
674 "log_filter_author_entry");
675 log_filter_grep_entry = glade_xml_get_widget (data->gxml,
676 "log_filter_grep_entry");
677 log_filter_from_check = glade_xml_get_widget (data->gxml,
678 "log_filter_from_check");
679 log_filter_to_check = glade_xml_get_widget (data->gxml,
680 "log_filter_to_check");
681 log_filter_from_calendar = glade_xml_get_widget (data->gxml,
682 "log_filter_from_calendar");
683 log_filter_to_calendar = glade_xml_get_widget (data->gxml,
684 "log_filter_to_calendar");
685 log_filter_from_entry = glade_xml_get_widget (data->gxml,
686 "log_filter_from_entry");
687 log_filter_to_entry = glade_xml_get_widget (data->gxml,
688 "log_filter_to_entry");
689 log_filter_clear_button = glade_xml_get_widget (data->gxml,
690 "log_filter_clear_button");
692 /* Each widget that has some kind of filter must have a "filter name"
693 * associated with it so that we can generically see how many filters
694 * the user asked for, so we can hide the graph column, and to get this
695 * information in a somewhat generic way. */
696 g_object_set_data (G_OBJECT (log_filter_author_entry), "filter-name",
697 "author");
698 g_object_set_data (G_OBJECT (log_filter_grep_entry), "filter-name",
699 "grep");
700 g_object_set_data (G_OBJECT (log_filter_from_calendar), "filter-name",
701 "since-date");
702 g_object_set_data (G_OBJECT (log_filter_to_calendar), "filter-name",
703 "until-date");
704 g_object_set_data (G_OBJECT (log_filter_from_entry), "filter-name",
705 "since-commit");
706 g_object_set_data (G_OBJECT (log_filter_to_entry), "filter-name",
707 "until-commit");
709 g_object_set_data (G_OBJECT (log_filter_from_check), "calendar",
710 log_filter_from_calendar);
711 g_object_set_data (G_OBJECT (log_filter_to_check), "calendar",
712 log_filter_to_calendar);
714 /* Each widget should have one generic handler that inserts its changes
715 * into the filter hash table as needed. */
716 g_signal_connect (G_OBJECT (log_filter_author_entry), "changed",
717 G_CALLBACK (on_log_filter_entry_changed),
718 data);
720 g_signal_connect (G_OBJECT (log_filter_grep_entry), "changed",
721 G_CALLBACK (on_log_filter_entry_changed),
722 data);
724 g_signal_connect (G_OBJECT (log_filter_from_entry), "changed",
725 G_CALLBACK (on_log_filter_entry_changed),
726 data);
728 g_signal_connect (G_OBJECT (log_filter_to_entry), "changed",
729 G_CALLBACK (on_log_filter_entry_changed),
730 data);
732 /* Calendars don't have one catch all signal that handles both month and
733 * day changes, so we have to connect to both signals. */
734 g_signal_connect (G_OBJECT (log_filter_from_calendar), "day-selected",
735 G_CALLBACK (on_log_filter_date_changed),
736 data);
738 g_signal_connect (G_OBJECT (log_filter_from_calendar), "month-changed",
739 G_CALLBACK (on_log_filter_date_changed),
740 data);
742 g_signal_connect (G_OBJECT (log_filter_to_calendar), "day-selected",
743 G_CALLBACK (on_log_filter_date_changed),
744 data);
746 g_signal_connect (G_OBJECT (log_filter_to_calendar), "month-changed",
747 G_CALLBACK (on_log_filter_date_changed),
748 data);
750 g_signal_connect (G_OBJECT (log_filter_from_check), "toggled",
751 G_CALLBACK (on_log_filter_date_check_toggled),
752 data);
754 g_signal_connect (G_OBJECT (log_filter_to_check), "toggled",
755 G_CALLBACK (on_log_filter_date_check_toggled),
756 data);
758 g_signal_connect (G_OBJECT (log_filter_clear_button), "clicked",
759 G_CALLBACK (on_log_filter_clear_button_clicked),
760 data);
763 GtkWidget *
764 git_log_window_create (Git *plugin)
766 LogData *data;
767 GtkWidget *log_window;
768 GtkWidget *log_vbox;
769 GtkWidget *log_changes_view;
770 GtkWidget *log_view_button;
771 GtkWidget *log_whole_project_check;
772 GtkWidget *log_path_entry;
773 GtkTreeSelection *selection;
775 data = g_new0 (LogData, 1);
776 data->gxml = glade_xml_new (GLADE_FILE, "log_window", NULL);
778 data->plugin = plugin;
779 data->path = NULL;
780 data->graph_renderer = giggle_graph_renderer_new ();
782 log_window = glade_xml_get_widget (data->gxml, "log_window");
783 log_vbox = glade_xml_get_widget (data->gxml, "log_vbox");
784 log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view");
785 log_whole_project_check = glade_xml_get_widget (data->gxml,
786 "log_whole_project_check");
787 log_path_entry = glade_xml_get_widget (data->gxml, "log_path_entry");
788 log_view_button = glade_xml_get_widget (data->gxml,
789 "log_view_button");
791 g_object_set_data (G_OBJECT (log_vbox), "log-data", data);
793 setup_filters (data);
795 g_signal_connect (G_OBJECT (log_changes_view), "query-tooltip",
796 G_CALLBACK (on_log_changes_view_query_tooltip),
797 data);
798 g_signal_connect (G_OBJECT (log_changes_view), "button-press-event",
799 G_CALLBACK (on_log_changes_view_button_press_event),
800 plugin);
803 g_signal_connect (G_OBJECT (log_view_button), "clicked",
804 G_CALLBACK (on_log_view_button_clicked),
805 data);
807 g_object_set_data (G_OBJECT (log_whole_project_check), "file-entry",
808 log_path_entry);
809 g_signal_connect (G_OBJECT (log_whole_project_check), "toggled",
810 G_CALLBACK (on_git_whole_project_toggled), plugin);
812 data->list_store = gtk_list_store_new (NUM_COLS,
813 G_TYPE_OBJECT);
814 create_columns (data);
816 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (log_changes_view));
817 gtk_tree_selection_set_select_function (selection,
818 (GtkTreeSelectionFunc) on_log_changes_view_row_selected,
819 data, NULL);
821 git_cat_file_menu_set_sensitive (plugin, FALSE);
823 g_signal_connect (G_OBJECT (log_vbox), "destroy",
824 G_CALLBACK (on_log_vbox_destroy),
825 data);
827 g_object_ref (log_vbox);
828 gtk_container_remove (GTK_CONTAINER (log_window), log_vbox);
829 gtk_widget_destroy (log_window);
831 return log_vbox;
834 void
835 on_menu_git_log (GtkAction *action, Git *plugin)
837 anjuta_shell_present_widget (ANJUTA_PLUGIN (plugin)->shell,
838 plugin->log_viewer, NULL);
841 void
842 on_fm_git_log (GtkAction *action, Git *plugin)
844 LogData *data;
845 GtkWidget *log_path_entry;
846 GtkWidget *log_whole_project_check;
848 data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
849 log_path_entry = glade_xml_get_widget (data->gxml,
850 "log_path_entry");
851 log_whole_project_check = glade_xml_get_widget (data->gxml,
852 "log_whole_project_check");
854 gtk_entry_set_text (GTK_ENTRY (log_path_entry),
855 plugin->current_fm_filename);
856 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_whole_project_check),
857 FALSE);
859 anjuta_shell_present_widget (ANJUTA_PLUGIN (plugin)->shell,
860 plugin->log_viewer, NULL);
863 void
864 git_log_window_clear (Git *plugin)
866 LogData *data;
867 GtkWidget *log_text_view;
868 GtkTextBuffer *buffer;
870 data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
871 log_text_view = glade_xml_get_widget (data->gxml, "log_text_view");
872 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (log_text_view));
874 gtk_list_store_clear (data->list_store);
875 gtk_text_buffer_set_text (buffer, "", 0);
878 GitRevision *
879 git_log_get_selected_revision (Git *plugin)
881 LogData *data;
882 GtkWidget *log_changes_view;
883 GitRevision *revision;
884 GtkTreeSelection *selection;
885 GtkTreeModel *model;
886 GtkTreeIter iter;
888 data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
889 log_changes_view = glade_xml_get_widget (data->gxml, "log_changes_view");
890 revision = NULL;
892 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (log_changes_view));
893 model = gtk_tree_view_get_model (GTK_TREE_VIEW (log_changes_view));
895 gtk_tree_selection_get_selected (selection, NULL, &iter);
896 gtk_tree_model_get (model, &iter, COL_REVISION, &revision, -1);
898 return revision;
901 gchar *
902 git_log_get_path (Git *plugin)
904 LogData *data;
905 GtkWidget *log_path_entry;
907 data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
908 log_path_entry = glade_xml_get_widget (data->gxml, "log_path_entry");
910 return gtk_editable_get_chars (GTK_EDITABLE (log_path_entry), 0, -1);