diff --git a/gnucash/gnome-utils/gnc-tree-view-price.c b/gnucash/gnome-utils/gnc-tree-view-price.c index 35df37e7fb6..90e7c51b441 100644 --- a/gnucash/gnome-utils/gnc-tree-view-price.c +++ b/gnucash/gnome-utils/gnc-tree-view-price.c @@ -766,7 +766,7 @@ get_selected_prices_helper (GtkTreeModel *s_model, } /* - * Given an price tree view, return a list of the selected commodities. The + * Given a price tree view, return a list of the selected prices. The * price tree must be in multiple selection mode. * * Note: It is the responsibility of the caller to free the returned @@ -782,3 +782,47 @@ gnc_tree_view_price_get_selected_prices (GncTreeViewPrice *view) gtk_tree_selection_selected_foreach(selection, get_selected_prices_helper, &return_list); return return_list; } + +static void +get_selected_commodity_helper (GtkTreeModel *s_model, + GtkTreePath *s_path, + GtkTreeIter *s_iter, + gpointer data) +{ + GList **return_list = data; + GtkTreeModel *model, *f_model; + GtkTreeIter iter, f_iter; + gnc_commodity *commodity; + + gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), + &f_iter, s_iter); + + f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model)); + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model), + &iter, &f_iter); + + model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model)); + commodity = gnc_tree_model_price_get_commodity (GNC_TREE_MODEL_PRICE(model), &iter); + + if (commodity) + *return_list = g_list_append(*return_list, commodity); +} + +/* + * Given a price tree view, return a list of the selected rows that have + * commodities but are not prices, the parent rows for prices. The + * price tree must be in multiple selection mode. + * + * Note: It is the responsibility of the caller to free the returned + * list. + */ +GList * +gnc_tree_view_price_get_selected_commodities (GncTreeViewPrice *view) +{ + GtkTreeSelection *selection; + GList *return_list = NULL; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view)); + gtk_tree_selection_selected_foreach (selection, get_selected_commodity_helper, &return_list); + return return_list; +} diff --git a/gnucash/gnome-utils/gnc-tree-view-price.h b/gnucash/gnome-utils/gnc-tree-view-price.h index 1f7cd9f7508..d61a0dcf714 100644 --- a/gnucash/gnome-utils/gnc-tree-view-price.h +++ b/gnucash/gnome-utils/gnc-tree-view-price.h @@ -208,6 +208,19 @@ void gnc_tree_view_price_set_selected_price (GncTreeViewPrice *view, GList * gnc_tree_view_price_get_selected_prices (GncTreeViewPrice *view); +/** This function returns a list of commodities associated with the + * selected rows that are not prices but are the parent rows for + * prices in the price tree view. + * + * @note It only makes sense to call this function when the price + * tree is set to select multiple items. + * + * @param view A pointer to an price tree view. + * + * @return A list of commodities, or NULL if no commodity was selected. + */ +GList * gnc_tree_view_price_get_selected_commodities (GncTreeViewPrice *view); + /** @} */ G_END_DECLS diff --git a/gnucash/gnome/dialog-price-edit-db.c b/gnucash/gnome/dialog-price-edit-db.c index 29586d9c0e3..3936e5e5985 100644 --- a/gnucash/gnome/dialog-price-edit-db.c +++ b/gnucash/gnome/dialog-price-edit-db.c @@ -353,6 +353,8 @@ selection_changed_cb (GtkTreeSelection *selection, gpointer data) gboolean have_rows = (g_list_length (rows) > 0 ? TRUE : FALSE); change_source_flag (PRICE_REMOVE_SOURCE_COMM, have_rows, pdb_dialog); + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (rows); } static GDate @@ -513,16 +515,33 @@ gnc_prices_dialog_add_clicked (GtkWidget *widget, gpointer data) PricesDialog *pdb_dialog = data; GNCPrice *price = NULL; GList *price_list; + GList *comm_list; + gboolean unref_price = FALSE; ENTER(" "); - price_list = gnc_tree_view_price_get_selected_prices(pdb_dialog->price_tree); - if (price_list) + price_list = gnc_tree_view_price_get_selected_prices (pdb_dialog->price_tree); + comm_list = gnc_tree_view_price_get_selected_commodities (pdb_dialog->price_tree); + + if (price_list) // selected row is on a price { price = price_list->data; - g_list_free(price_list); + g_list_free (price_list); + } + else if (comm_list) // selection contains price parent rows + { + if (g_list_length (comm_list) == 1) // make sure it is only one parent + { + price = gnc_price_create (pdb_dialog->book); + gnc_price_set_commodity (price, comm_list->data); + unref_price = TRUE; + } + g_list_free (comm_list); } gnc_price_edit_dialog (pdb_dialog->window, pdb_dialog->session, price, GNC_PRICE_NEW); + + if (unref_price) + gnc_price_unref (price); LEAVE(" "); } @@ -570,12 +589,25 @@ gnc_prices_dialog_selection_changed (GtkTreeSelection *treeselection, gpointer data) { PricesDialog *pdb_dialog = data; + GtkTreeModel *model; GList *price_list; + GList *rows; gint length; ENTER(" "); - price_list = gnc_tree_view_price_get_selected_prices(pdb_dialog->price_tree); - length = g_list_length(price_list); + price_list = gnc_tree_view_price_get_selected_prices (pdb_dialog->price_tree); + length = g_list_length (price_list); + g_list_free (price_list); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW(pdb_dialog->price_tree)); + rows = gtk_tree_selection_get_selected_rows (treeselection, &model); + + // if selected rows greater than length, parents must of been selected also + if (g_list_length (rows) > length) + length = 0; + + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (rows); gtk_widget_set_sensitive (pdb_dialog->edit_button, length == 1);