mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 798960 - Transaction completion horizontal scrolling
This commit is the second part to the bug that will scroll horizontally to where the matching description text is.
This commit is contained in:
parent
0449b73e96
commit
d4be0d0711
@ -54,6 +54,7 @@ typedef struct _PopBox
|
||||
GtkListStore* item_store; // the item list store
|
||||
|
||||
gchar* newval; // string value to find
|
||||
gint newval_len; // length of string value to find
|
||||
|
||||
gboolean signals_connected; // list signals connected
|
||||
gboolean list_popped; // list is popped up
|
||||
@ -76,9 +77,10 @@ typedef struct _PopBox
|
||||
/** Enumeration for the list-store */
|
||||
enum GncCompletionColumn
|
||||
{
|
||||
TEXT_COL, //0
|
||||
TEXT_MARKUP_COL, //1
|
||||
WEIGHT_COL, //2
|
||||
TEXT_COL, //0
|
||||
TEXT_MARKUP_COL, //1
|
||||
WEIGHT_COL, //2
|
||||
FOUND_LOCATION_COL, //3
|
||||
};
|
||||
|
||||
static void gnc_completion_cell_gui_realize (BasicCell* bcell, gpointer w);
|
||||
@ -116,8 +118,8 @@ gnc_completion_cell_init (CompletionCell* cell)
|
||||
box->sheet = NULL;
|
||||
box->item_edit = NULL;
|
||||
box->item_list = NULL;
|
||||
box->item_store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,
|
||||
G_TYPE_INT);
|
||||
box->item_store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
|
||||
G_TYPE_INT, G_TYPE_INT);
|
||||
box->signals_connected = FALSE;
|
||||
box->list_popped = FALSE;
|
||||
box->autosize = FALSE;
|
||||
@ -156,6 +158,52 @@ select_item_cb (GncItemList* item_list, char* item_string, gpointer user_data)
|
||||
hide_popup (box);
|
||||
}
|
||||
|
||||
static gint
|
||||
text_width (PangoLayout *layout)
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
pango_layout_set_width (layout, -1);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
return logical_rect.width;
|
||||
}
|
||||
|
||||
static void
|
||||
horizontal_scroll_to_found_text (PopBox* box, char* item_string, gint found_location)
|
||||
{
|
||||
GtkAllocation alloc;
|
||||
gtk_widget_get_allocation (GTK_WIDGET(box->item_list->tree_view), &alloc);
|
||||
gint scroll_point = 0;
|
||||
gchar *start_string = g_utf8_substring (item_string, 0, found_location + box->newval_len);
|
||||
|
||||
PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(box->item_list->tree_view), item_string);
|
||||
PangoAttrList *atlist = pango_attr_list_new ();
|
||||
PangoAttribute *bold_weight = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||
bold_weight->start_index = found_location;
|
||||
bold_weight->end_index = found_location + box->newval_len;
|
||||
pango_attr_list_insert (atlist, bold_weight);
|
||||
pango_layout_set_attributes (layout, atlist);
|
||||
|
||||
gint item_string_width = text_width (layout);
|
||||
|
||||
pango_layout_set_text (layout, start_string, -1);
|
||||
|
||||
gint start_string_width = text_width (layout);
|
||||
|
||||
pango_attr_list_unref (atlist);
|
||||
g_object_unref (layout);
|
||||
g_free (start_string);
|
||||
|
||||
if (item_string_width <= alloc.width)
|
||||
scroll_point = 0;
|
||||
else
|
||||
scroll_point = start_string_width - alloc.width / 2;
|
||||
|
||||
if (scroll_point < 0)
|
||||
scroll_point = 0;
|
||||
|
||||
gtk_tree_view_scroll_to_point (box->item_list->tree_view, scroll_point, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
change_item_cb (GncItemList* item_list, char* item_string, gpointer user_data)
|
||||
{
|
||||
@ -165,6 +213,16 @@ change_item_cb (GncItemList* item_list, char* item_string, gpointer user_data)
|
||||
box->in_list_select = TRUE;
|
||||
gnucash_sheet_modify_current_cell (box->sheet, item_string);
|
||||
box->in_list_select = FALSE;
|
||||
|
||||
GtkTreeModel *model = gtk_tree_view_get_model (item_list->tree_view);
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (item_list->tree_view);
|
||||
GtkTreeIter iter;
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
gint found_location;
|
||||
gtk_tree_model_get (model, &iter, FOUND_LOCATION_COL, &found_location, -1);
|
||||
horizontal_scroll_to_found_text (box, item_string, found_location);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -434,7 +492,7 @@ gnc_completion_cell_set_value (CompletionCell* cell, const char* str)
|
||||
|
||||
static inline void
|
||||
list_store_append (GtkListStore *store, char* string,
|
||||
char* markup, gint weight)
|
||||
char* markup, gint weight, gint found_location)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
@ -446,7 +504,8 @@ list_store_append (GtkListStore *store, char* string,
|
||||
|
||||
gtk_list_store_set (store, &iter, TEXT_COL, string,
|
||||
TEXT_MARKUP_COL, markup,
|
||||
WEIGHT_COL, weight, -1);
|
||||
WEIGHT_COL, weight,
|
||||
FOUND_LOCATION_COL, found_location, -1);
|
||||
}
|
||||
|
||||
static char*
|
||||
@ -514,7 +573,7 @@ test_and_add (PopBox* box, const gchar *text, gint start_pos,
|
||||
if (g_strcmp0 (sub_text_norm_fold, box->newval) == 0) // exact match
|
||||
weight = 1;
|
||||
|
||||
list_store_append (box->item_store, key, markup, weight);
|
||||
list_store_append (box->item_store, key, markup, weight, found_location);
|
||||
}
|
||||
g_free (markup);
|
||||
g_free (prefix);
|
||||
@ -565,10 +624,6 @@ select_first_entry_in_list (PopBox* box)
|
||||
if (!gtk_tree_model_iter_next (model, &iter))
|
||||
return;
|
||||
|
||||
// reset horizontal scrolling
|
||||
gtk_tree_view_column_queue_resize (gtk_tree_view_get_column (
|
||||
box->item_list->tree_view, TEXT_COL));
|
||||
|
||||
gtk_tree_model_get (model, &iter, TEXT_COL, &string, -1);
|
||||
|
||||
gnc_item_list_select (box->item_list, string);
|
||||
@ -595,6 +650,8 @@ populate_list_store (CompletionCell* cell, const gchar* str)
|
||||
else
|
||||
return;
|
||||
|
||||
box->newval_len = g_utf8_strlen (str, -1);
|
||||
|
||||
// disconnect list store from tree view
|
||||
box->item_store = gnc_item_list_disconnect_store (box->item_list);
|
||||
|
||||
@ -607,7 +664,7 @@ populate_list_store (CompletionCell* cell, const gchar* str)
|
||||
|
||||
// add the don't first entry
|
||||
gchar *markup = g_markup_printf_escaped ("<i>%s</i>", DONT_TEXT);
|
||||
list_store_append (box->item_store, DONT_TEXT, markup, 0);
|
||||
list_store_append (box->item_store, DONT_TEXT, markup, 0, 0);
|
||||
g_free (markup);
|
||||
|
||||
// add to the list store
|
||||
@ -621,6 +678,10 @@ populate_list_store (CompletionCell* cell, const gchar* str)
|
||||
// reconnect list store to tree view
|
||||
gnc_item_list_connect_store (box->item_list, box->item_store);
|
||||
|
||||
// reset horizontal scrolling
|
||||
gtk_tree_view_column_queue_resize (gtk_tree_view_get_column (
|
||||
box->item_list->tree_view, TEXT_COL));
|
||||
|
||||
// if no entries, do not show popup
|
||||
if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL(box->item_store), NULL) == 1)
|
||||
{
|
||||
@ -892,6 +953,26 @@ popup_get_width (GtkWidget* widget,
|
||||
return alloc.width;
|
||||
}
|
||||
|
||||
static void
|
||||
tree_view_size_allocate_cb (GtkWidget *widget,
|
||||
G_GNUC_UNUSED GtkAllocation *allocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(widget));
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(widget));
|
||||
GtkTreeIter iter;
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
PopBox* box = user_data;
|
||||
gint found_location;
|
||||
gchar *item_text;
|
||||
gtk_tree_model_get (model, &iter, TEXT_COL, &item_text,
|
||||
FOUND_LOCATION_COL, &found_location, -1);
|
||||
horizontal_scroll_to_found_text (box, item_text, found_location);
|
||||
g_free (item_text);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_completion_cell_enter (BasicCell* bcell,
|
||||
int* cursor_position,
|
||||
@ -918,6 +999,9 @@ gnc_completion_cell_enter (BasicCell* bcell,
|
||||
gtk_tree_view_column_add_attribute (column, box->item_list->renderer,
|
||||
"markup", TEXT_MARKUP_COL);
|
||||
|
||||
g_signal_connect (G_OBJECT(box->item_list->tree_view), "size-allocate",
|
||||
G_CALLBACK(tree_view_size_allocate_cb), box);
|
||||
|
||||
completion_connect_signals (cell);
|
||||
|
||||
*cursor_position = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user