[gtksourceview/gtksourcecompletion] Implemented accelerator (<Alt>+<num>) option for completion



commit 7f0b409f6150d5a6a85e97331a5e957fcebb52c3
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Mon Sep 21 13:25:25 2009 +0200

    Implemented accelerator (<Alt>+<num>) option for completion
    
    This allows you to easily activate one of the first ten items by using
    <Alt>+<num>. The rendering is not perfect yet.

 gtksourceview/completion.ui              |    5 +-
 gtksourceview/gtksourcecompletion.c      |  166 +++++++++++++++++++++++++++++-
 gtksourceview/gtksourcecompletionmodel.c |    9 ++
 gtksourceview/gtksourcecompletionmodel.h |    4 +
 4 files changed, 182 insertions(+), 2 deletions(-)
---
diff --git a/gtksourceview/completion.ui b/gtksourceview/completion.ui
index d930a11..e0281a9 100644
--- a/gtksourceview/completion.ui
+++ b/gtksourceview/completion.ui
@@ -31,9 +31,12 @@
                 <property name="show_expanders">False</property>
                 <child>
                   <object class="GtkTreeViewColumn" id="tree_view_column_proposal">
-                    <property name="sizing">GTK_TREE_VIEW_COLUMN_FIXED</property>
+                    <property name="sizing">fixed</property>
                     <property name="expand">True</property>
                     <child>
+                      <object class="GtkCellRendererText" id="cell_renderer_accelerator"/>
+                    </child>
+                    <child>
                       <object class="GtkCellRendererPixbuf" id="cell_renderer_icon"/>
                     </child>
                     <child>
diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index b43a668..5bc0075 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -1,4 +1,4 @@
-/*
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
  * gtksourcecompletion.c
  * This file is part of gtksourcecompletion
  *
@@ -78,6 +78,7 @@ enum
 	PROP_REMEMBER_INFO_VISIBILITY,
 	PROP_SELECT_ON_SHOW,
 	PROP_SHOW_HEADERS,
+	PROP_ENABLE_ACCELERATORS,
 	
 	PROP_AUTO_COMPLETE_DELAY,
 	
@@ -108,6 +109,7 @@ struct _GtkSourceCompletionPrivate
 	GtkWidget *hbox_info;
 	GtkWidget *label_info;
 	GtkWidget *image_info;
+	GtkCellRenderer *cell_renderer_accelerator;
 	
 	GtkWidget *tree_view_proposals;
 	GtkSourceCompletionModel *model_proposals;
@@ -117,6 +119,7 @@ struct _GtkSourceCompletionPrivate
 	gboolean info_visible;
 	gboolean select_on_show;
 	gboolean show_headers;
+	gboolean enable_accelerators;
 	
 	/* Page size */
 	guint proposal_page_size;
@@ -1162,6 +1165,43 @@ gtk_source_completion_move_page (GtkSourceCompletion *completion,
 	}
 }
 
+static gboolean
+activate_by_accelerator (GtkSourceCompletion *completion,
+                         gint                 num)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL (completion->priv->model_proposals);
+	gint i = -1;
+
+	if (num < 0 || num > 9)
+	{
+		return FALSE;
+	}
+	
+	num = num == 0 ? 9 : num - 1;
+	
+	if (gtk_tree_model_get_iter_first (model, &iter))
+	{
+		do
+		{
+			if (!gtk_source_completion_model_iter_is_header (completion->priv->model_proposals,
+			                                                 &iter))
+			{
+				++i;
+			}
+		} while (i < num && gtk_tree_model_iter_next (model, &iter));
+		
+		if (i == num)
+		{
+			gtk_tree_selection_select_iter (
+				gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view_proposals)),
+				&iter);
+
+			activate_current_proposal (completion);
+		}
+	}
+	return TRUE;
+}
 
 static gboolean
 view_key_press_event_cb (GtkSourceView       *view,
@@ -1192,6 +1232,13 @@ view_key_press_event_cb (GtkSourceView       *view,
 		return TRUE;
 	}
 	
+	if (completion->priv->enable_accelerators &&
+	    mod == GDK_MOD1_MASK && 
+	    event->keyval >= GDK_0 && event->keyval <= GDK_9)
+	{
+		return activate_by_accelerator (completion, event->keyval - GDK_0);
+	}
+	
 	binding_set = gtk_binding_set_by_class (GTK_SOURCE_COMPLETION_GET_CLASS (completion));
 
 	if (gtk_binding_set_activate (binding_set,
@@ -1497,6 +1544,9 @@ gtk_source_completion_get_property (GObject    *object,
 		case PROP_SHOW_HEADERS:
 			g_value_set_boolean (value, completion->priv->show_headers);
 			break;
+		case PROP_ENABLE_ACCELERATORS:
+			g_value_set_boolean (value, completion->priv->enable_accelerators);
+			break;
 		case PROP_AUTO_COMPLETE_DELAY:
 			g_value_set_uint (value, completion->priv->auto_complete_delay);
 			break;
@@ -1546,6 +1596,16 @@ gtk_source_completion_set_property (GObject      *object,
 				                                              completion->priv->show_headers);
 			}
 			break;
+		case PROP_ENABLE_ACCELERATORS:
+			completion->priv->enable_accelerators = g_value_get_boolean (value);
+			
+			if (completion->priv->cell_renderer_accelerator != NULL)
+			{
+				g_object_set (completion->priv->cell_renderer_accelerator,
+				              "visible", completion->priv->enable_accelerators,
+				              NULL);
+			}
+			break;
 		case PROP_AUTO_COMPLETE_DELAY:
 			completion->priv->auto_complete_delay = g_value_get_uint (value);
 			break;
@@ -1765,6 +1825,21 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	/**
+	 * GtkSourceCompletion:enable-accelerators:
+	 *
+	 * Determines whether you can activate the first ten proposals in the
+	 * completion window with <Alt>+<num>.
+	 *
+	 */
+	g_object_class_install_property (object_class,
+	                                 PROP_ENABLE_ACCELERATORS,
+	                                 g_param_spec_boolean ("enable-accelerators",
+	                                                       _("Enable Accelerators"),
+	                                                       _("Enable accelerators in the completion window"),
+	                                                       TRUE,
+	                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	
+	/**
 	 * GtkSourceCompletion:auto-complete-delay:
 	 *
 	 * Determines the popup delay (in milliseconds) at which the completion
@@ -2184,6 +2259,85 @@ render_proposal_text_func (GtkTreeViewColumn   *column,
 	}
 }
 
+static gint
+iter_accelerator (GtkSourceCompletion *completion,
+                  GtkTreeIter         *iter)
+{
+	GtkTreeIter it;
+	GtkTreeModel *model = GTK_TREE_MODEL (completion->priv->model_proposals);
+	gint ret = 0;
+	
+	if (!gtk_tree_model_get_iter_first (model, &it))
+	{
+		return -1;
+	}
+	
+	do
+	{
+		if (!gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, 
+		                                                 &it))
+		{
+			if (gtk_source_completion_model_iter_equal (completion->priv->model_proposals,
+			                                            iter,
+			                                            &it))
+			{
+				return ret;
+			}
+
+			++ret;
+		}
+	} while (ret < 10 && gtk_tree_model_iter_next (model, &it));
+	
+	return -1;
+}
+
+static void
+render_proposal_accelerator_func (GtkTreeViewColumn   *column,
+                                  GtkCellRenderer     *cell,
+                                  GtkTreeModel        *model,
+                                  GtkTreeIter         *iter,
+                                  GtkSourceCompletion *completion)
+{
+	g_object_set (cell, "visible", completion->priv->enable_accelerators, NULL);
+	
+	if (completion->priv->enable_accelerators)
+	{
+		GtkStyle *style;
+		gboolean isheader;
+		
+		isheader = gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, 
+		                                                       iter);
+		
+		style = gtk_widget_get_style (GTK_WIDGET (completion->priv->tree_view_proposals));
+
+		if (isheader)
+		{
+			g_object_set (cell, 
+			              "background-gdk", &(style->bg[GTK_STATE_INSENSITIVE]),
+			              "text", "  ",
+			              NULL);
+		}
+		else
+		{
+			gint accel = iter_accelerator (completion, iter);
+			gchar *text = NULL;
+			
+			if (accel != -1)
+			{
+				text = g_strdup_printf ("<small>%d</small>", accel == 9 ? 0 : accel + 1);
+			}
+			
+			g_object_set (cell, 
+				      "foreground-gdk", &(style->fg[GTK_STATE_INSENSITIVE]),
+				      "background-set", FALSE,
+				      "markup", text,
+				      "weight", PANGO_WEIGHT_BOLD,
+				      NULL);
+			g_free (text);
+		}
+	}
+}
+
 static gboolean
 selection_func (GtkTreeSelection    *selection,
                 GtkTreeModel        *model,
@@ -2366,6 +2520,16 @@ initialize_ui (GtkSourceCompletion *completion)
 	                                         completion,
 	                                         NULL);
 
+	completion->priv->cell_renderer_accelerator = 
+			GTK_CELL_RENDERER (gtk_builder_get_object (builder,
+			                                           "cell_renderer_accelerator"));
+
+	gtk_tree_view_column_set_cell_data_func (column,
+	                                         completion->priv->cell_renderer_accelerator,
+	                                         (GtkTreeCellDataFunc)render_proposal_accelerator_func,
+	                                         completion,
+	                                         NULL);
+
 	g_signal_connect_after (completion->priv->model_proposals,
 	                        "row-inserted",
 	                        G_CALLBACK (on_row_inserted_cb),
diff --git a/gtksourceview/gtksourcecompletionmodel.c b/gtksourceview/gtksourcecompletionmodel.c
index c1440b5..e3b6f68 100644
--- a/gtksourceview/gtksourcecompletionmodel.c
+++ b/gtksourceview/gtksourcecompletionmodel.c
@@ -1425,3 +1425,12 @@ gtk_source_completion_model_get_visible_providers (GtkSourceCompletionModel *mod
 	return model->priv->visible_providers;
 }
 
+gboolean
+gtk_source_completion_model_iter_equal (GtkSourceCompletionModel *model,
+                                        GtkTreeIter              *iter1,
+                                        GtkTreeIter              *iter2)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model), FALSE);
+	
+	return iter1->user_data == iter2->user_data;
+}
diff --git a/gtksourceview/gtksourcecompletionmodel.h b/gtksourceview/gtksourcecompletionmodel.h
index 447f0d4..bb2b8e7 100644
--- a/gtksourceview/gtksourcecompletionmodel.h
+++ b/gtksourceview/gtksourcecompletionmodel.h
@@ -105,6 +105,10 @@ gboolean 	gtk_source_completion_model_iter_previous (GtkSourceCompletionModel
 gboolean 	gtk_source_completion_model_iter_last 	(GtkSourceCompletionModel           *model,
 							 GtkTreeIter                        *iter);
 
+gboolean	gtk_source_completion_model_iter_equal	(GtkSourceCompletionModel           *model,
+							 GtkTreeIter                        *iter1,
+							 GtkTreeIter                        *iter2);
+
 G_END_DECLS
 
 #endif /* __GTK_SOURCE_COMPLETION_MODEL_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]