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
|
GtkListStore* item_store; // the item list store
|
||||||
|
|
||||||
gchar* newval; // string value to find
|
gchar* newval; // string value to find
|
||||||
|
gint newval_len; // length of string value to find
|
||||||
|
|
||||||
gboolean signals_connected; // list signals connected
|
gboolean signals_connected; // list signals connected
|
||||||
gboolean list_popped; // list is popped up
|
gboolean list_popped; // list is popped up
|
||||||
@ -79,6 +80,7 @@ enum GncCompletionColumn
|
|||||||
TEXT_COL, //0
|
TEXT_COL, //0
|
||||||
TEXT_MARKUP_COL, //1
|
TEXT_MARKUP_COL, //1
|
||||||
WEIGHT_COL, //2
|
WEIGHT_COL, //2
|
||||||
|
FOUND_LOCATION_COL, //3
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gnc_completion_cell_gui_realize (BasicCell* bcell, gpointer w);
|
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->sheet = NULL;
|
||||||
box->item_edit = NULL;
|
box->item_edit = NULL;
|
||||||
box->item_list = NULL;
|
box->item_list = NULL;
|
||||||
box->item_store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,
|
box->item_store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
|
||||||
G_TYPE_INT);
|
G_TYPE_INT, G_TYPE_INT);
|
||||||
box->signals_connected = FALSE;
|
box->signals_connected = FALSE;
|
||||||
box->list_popped = FALSE;
|
box->list_popped = FALSE;
|
||||||
box->autosize = FALSE;
|
box->autosize = FALSE;
|
||||||
@ -156,6 +158,52 @@ select_item_cb (GncItemList* item_list, char* item_string, gpointer user_data)
|
|||||||
hide_popup (box);
|
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
|
static void
|
||||||
change_item_cb (GncItemList* item_list, char* item_string, gpointer user_data)
|
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;
|
box->in_list_select = TRUE;
|
||||||
gnucash_sheet_modify_current_cell (box->sheet, item_string);
|
gnucash_sheet_modify_current_cell (box->sheet, item_string);
|
||||||
box->in_list_select = FALSE;
|
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
|
static void
|
||||||
@ -434,7 +492,7 @@ gnc_completion_cell_set_value (CompletionCell* cell, const char* str)
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
list_store_append (GtkListStore *store, char* string,
|
list_store_append (GtkListStore *store, char* string,
|
||||||
char* markup, gint weight)
|
char* markup, gint weight, gint found_location)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
@ -446,7 +504,8 @@ list_store_append (GtkListStore *store, char* string,
|
|||||||
|
|
||||||
gtk_list_store_set (store, &iter, TEXT_COL, string,
|
gtk_list_store_set (store, &iter, TEXT_COL, string,
|
||||||
TEXT_MARKUP_COL, markup,
|
TEXT_MARKUP_COL, markup,
|
||||||
WEIGHT_COL, weight, -1);
|
WEIGHT_COL, weight,
|
||||||
|
FOUND_LOCATION_COL, found_location, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
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
|
if (g_strcmp0 (sub_text_norm_fold, box->newval) == 0) // exact match
|
||||||
weight = 1;
|
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 (markup);
|
||||||
g_free (prefix);
|
g_free (prefix);
|
||||||
@ -565,10 +624,6 @@ select_first_entry_in_list (PopBox* box)
|
|||||||
if (!gtk_tree_model_iter_next (model, &iter))
|
if (!gtk_tree_model_iter_next (model, &iter))
|
||||||
return;
|
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);
|
gtk_tree_model_get (model, &iter, TEXT_COL, &string, -1);
|
||||||
|
|
||||||
gnc_item_list_select (box->item_list, string);
|
gnc_item_list_select (box->item_list, string);
|
||||||
@ -595,6 +650,8 @@ populate_list_store (CompletionCell* cell, const gchar* str)
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
box->newval_len = g_utf8_strlen (str, -1);
|
||||||
|
|
||||||
// disconnect list store from tree view
|
// disconnect list store from tree view
|
||||||
box->item_store = gnc_item_list_disconnect_store (box->item_list);
|
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
|
// add the don't first entry
|
||||||
gchar *markup = g_markup_printf_escaped ("<i>%s</i>", DONT_TEXT);
|
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);
|
g_free (markup);
|
||||||
|
|
||||||
// add to the list store
|
// add to the list store
|
||||||
@ -621,6 +678,10 @@ populate_list_store (CompletionCell* cell, const gchar* str)
|
|||||||
// reconnect list store to tree view
|
// reconnect list store to tree view
|
||||||
gnc_item_list_connect_store (box->item_list, box->item_store);
|
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 no entries, do not show popup
|
||||||
if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL(box->item_store), NULL) == 1)
|
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;
|
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
|
static gboolean
|
||||||
gnc_completion_cell_enter (BasicCell* bcell,
|
gnc_completion_cell_enter (BasicCell* bcell,
|
||||||
int* cursor_position,
|
int* cursor_position,
|
||||||
@ -918,6 +999,9 @@ gnc_completion_cell_enter (BasicCell* bcell,
|
|||||||
gtk_tree_view_column_add_attribute (column, box->item_list->renderer,
|
gtk_tree_view_column_add_attribute (column, box->item_list->renderer,
|
||||||
"markup", TEXT_MARKUP_COL);
|
"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);
|
completion_connect_signals (cell);
|
||||||
|
|
||||||
*cursor_position = -1;
|
*cursor_position = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user