dialog-commodities.c

00001 /********************************************************************\
00002  * dialog-commodities.c -- commodities dialog                       *
00003  * Copyright (C) 2001 Gnumatic, Inc.                                *
00004  * Author: Dave Peticolas <dave@krondo.com>                         *
00005  * Copyright (C) 2003,2005 David Hampton                            *
00006  *                                                                  *
00007  * This program is free software; you can redistribute it and/or    *
00008  * modify it under the terms of the GNU General Public License as   *
00009  * published by the Free Software Foundation; either version 2 of   *
00010  * the License, or (at your option) any later version.              *
00011  *                                                                  *
00012  * This program is distributed in the hope that it will be useful,  *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00015  * GNU General Public License for more details.                     *
00016  *                                                                  *
00017  * You should have received a copy of the GNU General Public License*
00018  * along with this program; if not, contact:                        *
00019  *                                                                  *
00020  * Free Software Foundation           Voice:  +1-617-542-5942       *
00021  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00022  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00023 \********************************************************************/
00024 
00025 #include "config.h"
00026 
00027 #include <gtk/gtk.h>
00028 #include <glib/gi18n.h>
00029 
00030 #include "dialog-commodity.h"
00031 #include "dialog-utils.h"
00032 #include "gnc-commodity.h"
00033 #include "gnc-component-manager.h"
00034 #include "qof.h"
00035 #include "gnc-tree-view-commodity.h"
00036 #include "gnc-ui.h"
00037 #include "gnc-ui-util.h"
00038 #include "gnc-gconf-utils.h"
00039 #include "gnc-gnome-utils.h"
00040 #include "gnc-session.h"
00041 
00042 
00043 #define DIALOG_COMMODITIES_CM_CLASS "dialog-commodities"
00044 #define GCONF_SECTION "dialogs/edit_commodities"
00045 
00046 /* This static indicates the debugging module that this .o belongs to.  */
00047 /* static short module = MOD_GUI; */
00048 
00049 typedef struct
00050 {
00051   GtkWidget * dialog;
00052   QofSession *session;
00053   QofBook *book;
00054 
00055   GncTreeViewCommodity * commodity_tree;
00056   GtkWidget * edit_button;
00057   GtkWidget * remove_button;
00058   gboolean    show_currencies;
00059 
00060   gboolean new;
00061 } CommoditiesDialog;
00062 
00063 
00064 void gnc_commodities_window_destroy_cb (GtkObject *object, CommoditiesDialog *cd);
00065 void gnc_commodities_dialog_response (GtkDialog *dialog, gint response, CommoditiesDialog *cd);
00066 void gnc_commodities_show_currencies_toggled (GtkToggleButton *toggle, CommoditiesDialog *cd);
00067 
00068 
00069 
00070 void
00071 gnc_commodities_window_destroy_cb (GtkObject *object,   CommoditiesDialog *cd)
00072 {
00073   gnc_unregister_gui_component_by_data (DIALOG_COMMODITIES_CM_CLASS, cd);
00074 
00075   g_free (cd);
00076 }
00077 
00078 static void
00079 edit_clicked (CommoditiesDialog *cd)
00080 {
00081   gnc_commodity *commodity;
00082 
00083   commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree);
00084   if (commodity == NULL)
00085     return;
00086 
00087   if (gnc_ui_edit_commodity_modal (commodity, cd->dialog))
00088     gnc_gui_refresh_all ();
00089 }
00090 
00091 static void
00092 row_activated_cb (GtkTreeView *view, GtkTreePath *path,
00093                   GtkTreeViewColumn *column, CommoditiesDialog *cd)
00094 {
00095   GtkTreeModel *model;
00096   GtkTreeIter iter;
00097 
00098   g_return_if_fail(view);
00099 
00100   model = gtk_tree_view_get_model(view);
00101   if (gtk_tree_model_get_iter(model, &iter, path))
00102   {
00103     if (gtk_tree_model_iter_has_child(model, &iter))
00104     {
00105       /* There are children, so it's not a commodity.
00106        * Just expand or collapse the row. */
00107       if (gtk_tree_view_row_expanded(view, path))
00108         gtk_tree_view_collapse_row(view, path);
00109       else
00110         gtk_tree_view_expand_row(view, path, FALSE);
00111     }
00112     else
00113       /* It's a commodity, so click the Edit button. */
00114       edit_clicked(cd);
00115   }
00116 }
00117 
00118 static void
00119 remove_clicked (CommoditiesDialog *cd)
00120 {
00121   GNCPriceDB *pdb;
00122   GList *node;
00123   GList *prices;
00124   GList *accounts;
00125   gboolean do_delete;
00126   gboolean can_delete;
00127   gnc_commodity *commodity;
00128   GtkWidget *dialog;
00129   const gchar *message, *warning;
00130   gint response;
00131   
00132   commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree);
00133   if (commodity == NULL)
00134     return;
00135 
00136   accounts = gnc_account_get_descendants (gnc_book_get_root_account(cd->book));
00137   can_delete = TRUE;
00138   do_delete = FALSE;
00139 
00140   for (node = accounts; node; node = node->next)
00141   {
00142     Account *account = node->data;
00143 
00144     if (commodity == xaccAccountGetCommodity (account))
00145     {
00146       can_delete = FALSE;
00147       break;
00148     }
00149   }
00150 
00151   /* FIXME check for transaction references */
00152 
00153   if (!can_delete)
00154   {
00155     const char *message = _("That commodity is currently used by "
00156                             "at least one of your accounts. You may "
00157                             "not delete it.");
00158 
00159     gnc_warning_dialog (cd->dialog, "%s", message);
00160     g_list_free (accounts);
00161     return;
00162   }
00163   g_list_free (accounts);
00164 
00165   pdb = gnc_pricedb_get_db (cd->book);
00166   prices = gnc_pricedb_get_prices(pdb, commodity, NULL);
00167   if (prices)
00168   {
00169     message = _("This commodity has price quotes. Are "
00170                 "you sure you want to delete the selected "
00171                 "commodity and its price quotes?");
00172     warning = "delete_commodity2";
00173   } else {
00174     message = _("Are you sure you want to delete the "
00175                 "selected commodity?");
00176     warning = "delete_commodity";
00177   }
00178 
00179   dialog = gtk_message_dialog_new(GTK_WINDOW(cd->dialog),
00180                                   GTK_DIALOG_DESTROY_WITH_PARENT,
00181                                   GTK_MESSAGE_QUESTION,
00182                                   GTK_BUTTONS_NONE,
00183                                   "%s", _("Delete commodity?"));
00184   gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
00185                                            "%s", message);
00186   gtk_dialog_add_buttons(GTK_DIALOG(dialog),
00187                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00188                          GTK_STOCK_DELETE, GTK_RESPONSE_OK,
00189                          (gchar *)NULL);
00190   response = gnc_dialog_run(GTK_DIALOG(dialog), warning);
00191   gtk_widget_destroy(dialog);
00192 
00193   if (response == GTK_RESPONSE_OK)
00194   {
00195     gnc_commodity_table *ct;
00196 
00197     ct = gnc_book_get_commodity_table (cd->book);
00198     for (node = prices; node; node = node->next)
00199       gnc_pricedb_remove_price(pdb, node->data);
00200 
00201     gnc_commodity_table_remove (ct, commodity);
00202     gnc_commodity_destroy (commodity);
00203     commodity = NULL;
00204   }
00205 
00206   gnc_price_list_destroy(prices);
00207   gnc_gui_refresh_all ();
00208 }
00209 
00210 static void
00211 add_clicked (CommoditiesDialog *cd)
00212 {
00213   gnc_commodity *commodity;
00214   const char *namespace;
00215 
00216   commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree);
00217   if (commodity)
00218     namespace = gnc_commodity_get_namespace (commodity);
00219   else
00220     namespace = NULL;
00221 
00222   commodity = gnc_ui_new_commodity_modal (namespace, cd->dialog);
00223 }
00224 
00225 void
00226 gnc_commodities_dialog_response (GtkDialog *dialog,
00227                                  gint response,
00228                                  CommoditiesDialog *cd)
00229 {
00230         switch (response) {
00231          case GNC_RESPONSE_NEW:
00232           add_clicked (cd);
00233           return;
00234 
00235          case GNC_RESPONSE_DELETE:
00236           remove_clicked (cd);
00237           return;
00238 
00239          case GNC_RESPONSE_EDIT:
00240           edit_clicked (cd);
00241           return;
00242 
00243          case GTK_RESPONSE_CLOSE:
00244          default:
00245           gnc_close_gui_component_by_data (DIALOG_COMMODITIES_CM_CLASS, cd);
00246           return;
00247         }
00248 }
00249 
00250 static void
00251 gnc_commodities_dialog_selection_changed (GtkTreeSelection *selection,
00252                                           CommoditiesDialog *cd)
00253 {
00254         gboolean remove_ok;
00255         gnc_commodity *commodity;
00256 
00257         commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree);
00258         remove_ok = commodity && !gnc_commodity_is_iso(commodity);
00259         gtk_widget_set_sensitive (cd->edit_button, commodity != NULL);
00260         gtk_widget_set_sensitive (cd->remove_button, remove_ok);
00261 }
00262 
00263 void
00264 gnc_commodities_show_currencies_toggled (GtkToggleButton *toggle,
00265                                          CommoditiesDialog *cd)
00266 {
00267 
00268         cd->show_currencies = gtk_toggle_button_get_active (toggle);
00269         gnc_tree_view_commodity_refilter (cd->commodity_tree);
00270 }
00271 
00272 static gboolean
00273 gnc_commodities_dialog_filter_ns_func (gnc_commodity_namespace *namespace,
00274                                        gpointer data)
00275 {
00276         CommoditiesDialog *cd = data;
00277         const gchar *name;
00278         GList *list;
00279 
00280         /* Never show the template list */
00281         name = gnc_commodity_namespace_get_name (namespace);
00282         if (safe_strcmp (name, "template") == 0)
00283           return FALSE;
00284 
00285         /* Check whether or not to show commodities */
00286         if (!cd->show_currencies && gnc_commodity_namespace_is_iso(name))
00287           return FALSE;
00288 
00289         /* Show any other namespace that has commodities */
00290         list = gnc_commodity_namespace_get_commodity_list(namespace);
00291         return (list != NULL);
00292 }
00293 
00294 static gboolean
00295 gnc_commodities_dialog_filter_cm_func (gnc_commodity *commodity,
00296                                        gpointer data)
00297 {
00298         CommoditiesDialog *cd = data;
00299 
00300         if (cd->show_currencies)
00301           return TRUE;
00302         return !gnc_commodity_is_iso(commodity);
00303 }
00304 
00305 static void
00306 gnc_commodities_dialog_create (GtkWidget * parent, CommoditiesDialog *cd)
00307 {
00308   GtkWidget *dialog;
00309   GtkWidget *button;
00310   GtkWidget *scrolled_window;
00311   GladeXML *xml;
00312   GtkTreeView *view;
00313   GtkTreeSelection *selection;
00314  
00315   xml = gnc_glade_xml_new ("commodities.glade", "Securities Dialog");
00316   dialog = glade_xml_get_widget (xml, "Securities Dialog");
00317 
00318   cd->dialog = dialog;
00319   cd->session = gnc_get_current_session();
00320   cd->book = qof_session_get_book(cd->session);
00321   cd->show_currencies = gnc_gconf_get_bool(GCONF_SECTION, "include_iso", NULL);
00322   
00323   glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func, cd);
00324 
00325   /* parent */
00326   if (parent != NULL)
00327     gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
00328 
00329   /* buttons */
00330   cd->remove_button = glade_xml_get_widget (xml, "remove_button");
00331   cd->edit_button = glade_xml_get_widget (xml, "edit_button");
00332 
00333   /* commodity tree */
00334     
00335     scrolled_window = glade_xml_get_widget (xml, "commodity_list_window");
00336     view = gnc_tree_view_commodity_new(cd->book,
00337                                        "gconf-section", GCONF_SECTION,
00338                                        "show-column-menu", TRUE,
00339                                        NULL);
00340     cd->commodity_tree = GNC_TREE_VIEW_COMMODITY(view);
00341     gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET(view));
00342     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(cd->commodity_tree), TRUE);
00343     gnc_tree_view_commodity_set_filter (cd->commodity_tree,
00344                                         gnc_commodities_dialog_filter_ns_func,
00345                                         gnc_commodities_dialog_filter_cm_func,
00346                                         cd, NULL);
00347     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
00348     g_signal_connect (G_OBJECT (selection), "changed",
00349                       G_CALLBACK (gnc_commodities_dialog_selection_changed), cd);
00350 
00351     g_signal_connect (G_OBJECT (cd->commodity_tree), "row-activated",
00352                       G_CALLBACK (row_activated_cb), cd);
00353 
00354     /* Show currency button */
00355     button = glade_xml_get_widget (xml, "show_currencies_button");
00356     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), cd->show_currencies);
00357 
00358   gnc_restore_window_size (GCONF_SECTION, GTK_WINDOW(cd->dialog));
00359 }
00360 
00361 static void
00362 close_handler (gpointer user_data)
00363 {
00364   CommoditiesDialog *cd = user_data;
00365 
00366   gnc_save_window_size(GCONF_SECTION, GTK_WINDOW(cd->dialog));
00367 
00368   gnc_gconf_set_bool(GCONF_SECTION, "include_iso", cd->show_currencies, NULL);
00369 
00370   gtk_widget_destroy(cd->dialog);
00371 }
00372 
00373 static void
00374 refresh_handler (GHashTable *changes, gpointer user_data)
00375 {
00376   CommoditiesDialog *cd = user_data;
00377 
00378   g_return_if_fail(cd != NULL);
00379 
00380   gnc_tree_view_commodity_refilter (cd->commodity_tree);
00381 }
00382 
00383 static gboolean
00384 show_handler (const char *class, gint component_id,
00385               gpointer user_data, gpointer iter_data)
00386 {
00387   CommoditiesDialog *cd = user_data;
00388 
00389   if (!cd)
00390     return(FALSE);
00391   gtk_window_present (GTK_WINDOW(cd->dialog));
00392   return(TRUE);
00393 }
00394 
00395 /********************************************************************\
00396  * gnc_commodities_dialog                                           *
00397  *   opens up a window to edit price information                    *
00398  *                                                                  * 
00399  * Args:   parent  - the parent of the window to be created         *
00400  * Return: nothing                                                  *
00401 \********************************************************************/
00402 void
00403 gnc_commodities_dialog (GtkWidget * parent)
00404 {
00405   CommoditiesDialog *cd;
00406   gint component_id;
00407 
00408   if (gnc_forall_gui_components (DIALOG_COMMODITIES_CM_CLASS,
00409                                  show_handler, NULL))
00410       return;
00411 
00412   cd = g_new0 (CommoditiesDialog, 1);
00413 
00414   gnc_commodities_dialog_create (parent, cd);
00415 
00416   component_id = gnc_register_gui_component (DIALOG_COMMODITIES_CM_CLASS,
00417                                              refresh_handler, close_handler,
00418                                              cd);
00419   gnc_gui_component_set_session (component_id, cd->session);
00420 
00421   gtk_widget_grab_focus (GTK_WIDGET(cd->commodity_tree));
00422 
00423   gtk_widget_show (cd->dialog);
00424 }

Generated on Fri Oct 10 05:06:04 2008 for GnuCash by  doxygen 1.5.2