1 /********************************************************************\
2  * dialog-price-editor.c -- price editor dialog                     *
3  * Copyright (C) 2001 Gnumatic, Inc.                                *
4  * Author: Dave Peticolas <dave@krondo.com>                         *
5  * Copyright (c) 2006 David Hampton <hampton@employees.org>         *
6  * Copyright (c) 2009 Herbert Thoma <herbie@hthoma.de>              *
7  * Copyright (c) 2011 Robert Fewell                                 *
8  *                                                                  *
9  * This program is free software; you can redistribute it and/or    *
10  * modify it under the terms of the GNU General Public License as   *
11  * published by the Free Software Foundation; either version 2 of   *
12  * the License, or (at your option) any later version.              *
13  *                                                                  *
14  * This program is distributed in the hope that it will be useful,  *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
17  * GNU General Public License for more details.                     *
18  *                                                                  *
19  * You should have received a copy of the GNU General Public License*
20  * along with this program; if not, contact:                        *
21  *                                                                  *
22  * Free Software Foundation           Voice:  +1-617-542-5942       *
23  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
24  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
25 \********************************************************************/
26 
27 #include <config.h>
28 
29 #include <gtk/gtk.h>
30 #include <glib/gi18n.h>
31 #include <time.h>
32 
33 #include "dialog-utils.h"
34 #include "gnc-gtk-utils.h"
35 #include "gnc-amount-edit.h"
36 #include "gnc-commodity-edit.h"
37 #include "dialog-commodity.h"
38 #include "gnc-general-select.h"
39 #include "gnc-component-manager.h"
40 #include "gnc-currency-edit.h"
41 #include "gnc-date-edit.h"
42 #include "qof.h"
43 #include "gnc-pricedb.h"
44 #include "gnc-session.h"
45 #include "gnc-ui.h"
46 #include "gnc-ui-util.h"
47 #include "gnc-warnings.h"
48 #include "engine-helpers.h"
49 
50 
51 #define DIALOG_PRICE_EDIT_CM_CLASS "dialog-price-edit"
52 #define GNC_PREFS_GROUP "dialogs.price-editor"
53 
54 /* This static indicates the debugging module that this .o belongs to.  */
55 G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI;
56 
57 
58 typedef struct
59 {
60     GtkWidget * dialog;
61     QofSession *session;
62     QofBook *book;
63     GNCPriceDB *price_db;
64     GNCPriceEditType type;
65 
66     GtkWidget * namespace_cbwe;
67     GtkWidget * commodity_cbwe;
68     GtkWidget * currency_edit;
69     GtkWidget * date_edit;
70     GtkWidget * source_entry;
71     GtkWidget * type_combobox;
72     GtkWidget * price_edit;
73 
74     GtkWidget * cancel_button;
75     GtkWidget * apply_button;
76     GtkWidget * ok_button;
77 
78     GNCPrice *price;
79     gboolean changed;
80     gboolean is_new;
81 
82 } PriceEditDialog;
83 
84 void pedit_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data);
85 void pedit_data_changed_cb (GtkWidget *w, gpointer data);
86 void pedit_commodity_ns_changed_cb (GtkComboBox *cbwe, gpointer data);
87 void pedit_commodity_changed_cb (GtkComboBox *cbwe, gpointer data);
88 
89 
90 static void
gnc_prices_set_changed(PriceEditDialog * pedit_dialog,gboolean changed)91 gnc_prices_set_changed (PriceEditDialog *pedit_dialog, gboolean changed)
92 {
93     pedit_dialog->changed = changed;
94 
95     gtk_widget_set_sensitive (pedit_dialog->apply_button, changed);
96     gtk_widget_set_sensitive (pedit_dialog->ok_button, changed);
97 }
98 
99 
100 static int
type_string_to_index(const char * type)101 type_string_to_index (const char *type)
102 {
103     if (g_strcmp0 (type, "bid") == 0)
104         return 0;
105 
106     if (g_strcmp0 (type, "ask") == 0)
107         return 1;
108 
109     if (g_strcmp0 (type, "last") == 0)
110         return 2;
111 
112     if (g_strcmp0 (type, "nav") == 0)
113         return 3;
114 
115     return 4;
116 }
117 
118 
119 static const char *
type_index_to_string(int index)120 type_index_to_string (int index)
121 {
122     switch (index)
123     {
124     case 0:
125         return "bid";
126     case 1:
127         return "ask";
128     case 2:
129         return "last";
130     case 3:
131         return "nav";
132     default:
133         return "unknown";
134     }
135 }
136 
137 
138 static void
price_to_gui(PriceEditDialog * pedit_dialog)139 price_to_gui (PriceEditDialog *pedit_dialog)
140 {
141     GNCPrintAmountInfo print_info;
142     gnc_commodity *commodity = NULL;
143     gnc_commodity *currency = NULL;
144     const gchar *name_space, *fullname;
145     const char *source;
146     const char *type;
147     gnc_numeric value;
148     time64 date;
149 
150     if (pedit_dialog->price)
151     {
152         commodity = gnc_price_get_commodity (pedit_dialog->price);
153     }
154 
155     if (commodity)
156     {
157         name_space = gnc_commodity_get_namespace(commodity);
158         fullname = gnc_commodity_get_printname(commodity);
159         gnc_ui_update_namespace_picker(pedit_dialog->namespace_cbwe,
160                                        name_space, DIAG_COMM_ALL);
161         gnc_ui_update_commodity_picker(pedit_dialog->commodity_cbwe,
162                                        name_space, fullname);
163 
164         currency = gnc_price_get_currency (pedit_dialog->price);
165         date = gnc_price_get_time64 (pedit_dialog->price);
166         source = gnc_price_get_source_string (pedit_dialog->price);
167         type = gnc_price_get_typestr (pedit_dialog->price);
168         value = gnc_price_get_value (pedit_dialog->price);
169     }
170     else
171     {
172         currency = gnc_default_currency ();
173         date = gnc_time (NULL);
174         source = "user:price-editor"; //Sync with source_names in gnc-pricedb.c
175         type = "";
176         value = gnc_numeric_zero ();
177     }
178 
179 
180     if (currency)
181     {
182         gnc_currency_edit_set_currency
183         (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit), currency);
184     }
185 
186     gnc_date_edit_set_time (GNC_DATE_EDIT (pedit_dialog->date_edit), date);
187 
188     gtk_entry_set_text (GTK_ENTRY (pedit_dialog->source_entry), source);
189 
190     gtk_combo_box_set_active (GTK_COMBO_BOX(pedit_dialog->type_combobox),
191                               type_string_to_index (type));
192 
193     print_info = gnc_commodity_print_info (currency, FALSE);
194     gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), print_info);
195     gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), 0);
196 
197     gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), value);
198 }
199 
200 
201 static gboolean
pedit_dialog_replace_found_price(PriceEditDialog * pedit_dialog,const gnc_commodity * commodity,const gnc_commodity * currency,time64 t)202 pedit_dialog_replace_found_price (PriceEditDialog *pedit_dialog,
203                                   const gnc_commodity *commodity,
204                                   const gnc_commodity *currency, time64 t)
205 {
206     gboolean price_found = FALSE;
207     GNCPrice *test_price = gnc_pricedb_lookup_day_t64 (pedit_dialog->price_db,
208                                                        commodity, currency, t);
209 
210     if (test_price)
211     {
212         if (pedit_dialog->is_new) // new price
213             price_found = TRUE;
214         else // edit price
215         {
216             if (!gnc_price_equal (test_price, pedit_dialog->price))
217                 price_found = TRUE;
218         }
219         gnc_price_unref (test_price);
220     }
221 
222     if (price_found)
223     {
224         gint response;
225         GtkWidget *dialog;
226         gchar *message = _("Are you sure you want to replace the existing price?");
227 
228         dialog = gtk_message_dialog_new (GTK_WINDOW (pedit_dialog->dialog),
229                                          GTK_DIALOG_DESTROY_WITH_PARENT,
230                                          GTK_MESSAGE_QUESTION,
231                                          GTK_BUTTONS_NONE,
232                                          "%s", _("Replace price?"));
233         gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
234                         "%s", message);
235 
236         gtk_dialog_add_buttons (GTK_DIALOG(dialog),
237                               _("_Cancel"), GTK_RESPONSE_CANCEL,
238                               _("_Replace"), GTK_RESPONSE_YES,
239                                (gchar *)NULL);
240         gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_YES);
241         response = gnc_dialog_run (GTK_DIALOG(dialog), GNC_PREF_WARN_PRICE_QUOTES_REPLACE);
242         gtk_widget_destroy (dialog);
243 
244         if (response == GTK_RESPONSE_CANCEL)
245             return FALSE;
246     }
247     return TRUE;
248 }
249 
250 
251 static const char *
gui_to_price(PriceEditDialog * pedit_dialog)252 gui_to_price (PriceEditDialog *pedit_dialog)
253 {
254     GNCPrintAmountInfo print_info;
255     gnc_commodity *commodity;
256     gnc_commodity *currency;
257     gchar         *name_space;
258     const gchar   *fullname;
259     const char *source;
260     const char *type;
261     gnc_numeric value;
262     time64 date;
263 
264     name_space = gnc_ui_namespace_picker_ns (pedit_dialog->namespace_cbwe);
265     fullname = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( GTK_COMBO_BOX(pedit_dialog->commodity_cbwe)))));
266 
267     commodity = gnc_commodity_table_find_full(gnc_get_current_commodities(), name_space, fullname);
268     if (!commodity)
269         return _("You must select a Security.");
270 
271     currency = gnc_currency_edit_get_currency
272                (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit));
273     if (!currency)
274         return _("You must select a Currency.");
275 
276     date = gnc_date_edit_get_date (GNC_DATE_EDIT (pedit_dialog->date_edit));
277 
278     source = gtk_entry_get_text (GTK_ENTRY (pedit_dialog->source_entry));
279 
280     type = type_index_to_string
281            (gtk_combo_box_get_active (GTK_COMBO_BOX (pedit_dialog->type_combobox)));
282 
283     print_info = gnc_commodity_print_info (currency, FALSE);
284     gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), print_info);
285     gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), 0);
286 
287     if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (pedit_dialog->price_edit), NULL))
288         return _("You must enter a valid amount.");
289 
290     value = gnc_amount_edit_get_amount
291             (GNC_AMOUNT_EDIT (pedit_dialog->price_edit));
292 
293     // test for existing price on same day
294     if (pedit_dialog_replace_found_price (pedit_dialog, commodity, currency, date))
295     {
296         if (!pedit_dialog->price)
297             pedit_dialog->price = gnc_price_create (pedit_dialog->book);
298         gnc_price_begin_edit (pedit_dialog->price);
299         gnc_price_set_commodity (pedit_dialog->price, commodity);
300         gnc_price_set_currency (pedit_dialog->price, currency);
301         gnc_price_set_time64 (pedit_dialog->price, date);
302         gnc_price_set_source_string (pedit_dialog->price, source);
303         gnc_price_set_typestr (pedit_dialog->price, type);
304         gnc_price_set_value (pedit_dialog->price, value);
305         gnc_price_commit_edit (pedit_dialog->price);
306         g_free (name_space);
307         return NULL;
308     }
309     else
310     {
311         g_free (name_space);
312         return "CANCEL";
313     }
314 }
315 
316 
317 static void
pedit_dialog_destroy_cb(GtkWidget * widget,gpointer data)318 pedit_dialog_destroy_cb (GtkWidget *widget, gpointer data)
319 {
320     PriceEditDialog *pedit_dialog = data;
321 
322     gnc_unregister_gui_component_by_data (DIALOG_PRICE_EDIT_CM_CLASS,
323                                           pedit_dialog);
324 
325     if (pedit_dialog->price)
326     {
327         gnc_price_unref (pedit_dialog->price);
328         pedit_dialog->price = NULL;
329         pedit_dialog->is_new = FALSE;
330     }
331 
332     g_free (pedit_dialog);
333 }
334 
335 
336 void
pedit_dialog_response_cb(GtkDialog * dialog,gint response,gpointer data)337 pedit_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
338 {
339     PriceEditDialog *pedit_dialog = data;
340     GNCPrice *new_price = NULL;
341     const char *error_str;
342 
343     if ((response == GTK_RESPONSE_OK) || (response == GTK_RESPONSE_APPLY))
344     {
345         error_str = gui_to_price (pedit_dialog);
346         if (g_strcmp0 (error_str, "CANCEL") == 0) // cancel from replace price dialog
347         {
348             // set the ok and cancel buttons sensitivity
349             gnc_prices_set_changed (pedit_dialog, FALSE);
350             return;
351         }
352         else if (error_str) // error string from gui
353         {
354             gnc_warning_dialog (GTK_WINDOW (pedit_dialog->dialog), "%s", error_str);
355             return;
356         }
357         // set the ok and cancel buttons sensitivity
358         gnc_prices_set_changed (pedit_dialog, FALSE);
359 
360         if (pedit_dialog->is_new)
361             gnc_pricedb_add_price (pedit_dialog->price_db, pedit_dialog->price);
362 
363         gnc_gui_refresh_all ();
364     }
365 
366     if (response == GTK_RESPONSE_APPLY)
367     {
368         new_price = gnc_price_clone (pedit_dialog->price, pedit_dialog->book);
369         pedit_dialog->is_new = TRUE;
370 
371         gnc_price_unref (pedit_dialog->price);
372         pedit_dialog->price = new_price;
373     }
374     else
375     {
376         gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(pedit_dialog->dialog));
377         gtk_widget_destroy (GTK_WIDGET (pedit_dialog->dialog));
378         pedit_dialog_destroy_cb (NULL, pedit_dialog);
379     }
380 }
381 
382 
383 void
pedit_commodity_ns_changed_cb(GtkComboBox * cbwe,gpointer data)384 pedit_commodity_ns_changed_cb (GtkComboBox *cbwe, gpointer data)
385 {
386     PriceEditDialog *pedit_dialog = data;
387     gchar *name_space;
388 
389     gnc_prices_set_changed (pedit_dialog, TRUE);
390 
391     name_space = gnc_ui_namespace_picker_ns (pedit_dialog->namespace_cbwe);
392     gnc_ui_update_commodity_picker (pedit_dialog->commodity_cbwe, name_space, NULL);
393 
394     g_free(name_space);
395 }
396 
397 
398 void
pedit_commodity_changed_cb(GtkComboBox * cbwe,gpointer data)399 pedit_commodity_changed_cb (GtkComboBox *cbwe, gpointer data)
400 {
401     gnc_commodity   *commodity = NULL;
402     gnc_commodity   *currency = NULL;
403     gchar           *name_space;
404     const gchar     *fullname;
405     GList           *price_list;
406     PriceEditDialog *pedit_dialog = data;
407 
408     gnc_prices_set_changed (pedit_dialog, TRUE);
409 
410     name_space = gnc_ui_namespace_picker_ns (pedit_dialog->namespace_cbwe);
411     fullname = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( GTK_COMBO_BOX(pedit_dialog->commodity_cbwe)))));
412 
413     commodity = gnc_commodity_table_find_full(gnc_get_current_commodities(), name_space, fullname);
414 
415     if (commodity)
416     {
417         price_list = gnc_pricedb_lookup_latest_any_currency
418                      (pedit_dialog->price_db, commodity);
419         if (price_list)
420         {
421             GNCPrice * price = (GNCPrice*)price_list->data;
422             if (gnc_commodity_equiv(commodity, gnc_price_get_currency(price)))
423                 currency = gnc_price_get_commodity((GNCPrice *)price);
424             else
425                 currency = gnc_price_get_currency((GNCPrice *)price);
426 
427             if (currency)
428                 gnc_currency_edit_set_currency
429                 (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit), currency);
430 
431             gnc_price_list_destroy(price_list);
432         }
433         else
434         {
435             gnc_currency_edit_set_currency
436             (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit), gnc_default_currency());
437         }
438     }
439 
440     g_free(name_space);
441 }
442 
443 
444 void
pedit_data_changed_cb(GtkWidget * w,gpointer data)445 pedit_data_changed_cb (GtkWidget *w, gpointer data)
446 {
447     PriceEditDialog *pedit_dialog = data;
448 
449     gnc_prices_set_changed (pedit_dialog, TRUE);
450 }
451 
452 
453 static void
gnc_price_pedit_dialog_create(GtkWidget * parent,PriceEditDialog * pedit_dialog,QofSession * session)454 gnc_price_pedit_dialog_create (GtkWidget *parent,
455                                PriceEditDialog *pedit_dialog,
456                                QofSession *session)
457 {
458     GtkBuilder *builder;
459     GNCPrintAmountInfo print_info;
460     GtkWidget *dialog;
461     GtkWidget *entry;
462     GtkWidget *box;
463     GtkWidget *w;
464     GtkWidget *label;
465     gchar     *name_space;
466 
467     builder = gtk_builder_new();
468     gnc_builder_add_from_file (builder, "dialog-price.glade", "liststore1");
469     gnc_builder_add_from_file (builder, "dialog-price.glade", "liststore2");
470     gnc_builder_add_from_file (builder, "dialog-price.glade", "liststore3");
471     gnc_builder_add_from_file (builder, "dialog-price.glade", "price_dialog");
472 
473     pedit_dialog->session = session;
474     pedit_dialog->book = qof_session_get_book(pedit_dialog->session);
475     pedit_dialog->price_db = gnc_pricedb_get_db(pedit_dialog->book);
476 
477     dialog =  GTK_WIDGET(gtk_builder_get_object (builder, "price_dialog"));
478     pedit_dialog->dialog = dialog;
479 
480     /* parent */
481     if (parent != NULL)
482         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
483 
484     w = GTK_WIDGET(gtk_builder_get_object (builder, "namespace_cbwe"));
485     pedit_dialog->namespace_cbwe = w;
486 
487     gnc_ui_update_namespace_picker(w, NULL, DIAG_COMM_ALL);
488     gnc_cbwe_require_list_item(GTK_COMBO_BOX(pedit_dialog->namespace_cbwe));
489     gtk_combo_box_set_active(GTK_COMBO_BOX(pedit_dialog->namespace_cbwe), 1);
490 
491     w = GTK_WIDGET(gtk_builder_get_object (builder, "commodity_cbwe"));
492     pedit_dialog->commodity_cbwe = w;
493 
494     gnc_cbwe_require_list_item(GTK_COMBO_BOX(pedit_dialog->commodity_cbwe));
495     name_space = gnc_ui_namespace_picker_ns(pedit_dialog->namespace_cbwe);
496     gnc_ui_update_commodity_picker(pedit_dialog->commodity_cbwe, name_space, NULL);
497     g_free(name_space);
498 
499     box = GTK_WIDGET(gtk_builder_get_object (builder, "currency_box"));
500     w = gnc_currency_edit_new ();
501     gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT (w),
502                                     gnc_default_currency ());
503     pedit_dialog->currency_edit = w;
504     gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
505     gtk_widget_show (w);
506     g_signal_connect (G_OBJECT (GTK_COMBO_BOX(w)), "changed",
507                       G_CALLBACK (pedit_data_changed_cb), pedit_dialog);
508     label = GTK_WIDGET(gtk_builder_get_object (builder, "currency_label"));
509     gtk_label_set_mnemonic_widget (GTK_LABEL(label), w);
510 
511     box = GTK_WIDGET(gtk_builder_get_object (builder, "date_box"));
512     w = gnc_date_edit_new (time (NULL), FALSE, FALSE);
513     pedit_dialog->date_edit = w;
514     gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
515     gtk_widget_show (w);
516     g_signal_connect (G_OBJECT (w), "date_changed",
517                       G_CALLBACK (pedit_data_changed_cb), pedit_dialog);
518     g_signal_connect (G_OBJECT (GNC_DATE_EDIT (w)->date_entry), "changed",
519                       G_CALLBACK (pedit_data_changed_cb), pedit_dialog);
520     gtk_entry_set_activates_default(GTK_ENTRY(GNC_DATE_EDIT(w)->date_entry), TRUE);
521     label = GTK_WIDGET(gtk_builder_get_object (builder, "date__label"));
522     gnc_date_make_mnemonic_target (GNC_DATE_EDIT(w), label);
523 
524     w = GTK_WIDGET(gtk_builder_get_object (builder, "source_entry"));
525     pedit_dialog->source_entry = w;
526 
527     w = GTK_WIDGET(gtk_builder_get_object (builder, "type_combobox"));
528     pedit_dialog->type_combobox = w;
529 
530     box = GTK_WIDGET(gtk_builder_get_object (builder, "price_box"));
531     w = gnc_amount_edit_new ();
532     pedit_dialog->price_edit = w;
533     gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
534     entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (w));
535     gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (w), TRUE);
536     print_info = gnc_default_price_print_info (gnc_currency_edit_get_currency
537                                               (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit)));
538     gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (w), print_info);
539     gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
540     gtk_widget_show (w);
541     label = GTK_WIDGET(gtk_builder_get_object (builder, "price_label"));
542     gnc_amount_edit_make_mnemonic_target (GNC_AMOUNT_EDIT(w), label);
543 
544     g_signal_connect (G_OBJECT (w), "changed",
545                       G_CALLBACK (pedit_data_changed_cb), pedit_dialog);
546 
547     w = GTK_WIDGET(gtk_builder_get_object (builder, "pd_cancel_button"));
548     pedit_dialog->cancel_button = w;
549 
550     w = GTK_WIDGET(gtk_builder_get_object (builder, "pd_apply_button"));
551     pedit_dialog->apply_button = w;
552 
553     w = GTK_WIDGET(gtk_builder_get_object (builder, "pd_ok_button"));
554     pedit_dialog->ok_button = w;
555 
556     gnc_prices_set_changed (pedit_dialog, FALSE);
557 
558     gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, pedit_dialog);
559 
560     g_object_unref(G_OBJECT(builder));
561 }
562 
563 
564 static void
close_handler(gpointer user_data)565 close_handler (gpointer user_data)
566 {
567     PriceEditDialog *pedit_dialog = user_data;
568 
569     gtk_dialog_response(GTK_DIALOG(pedit_dialog->dialog), GTK_RESPONSE_CANCEL);
570 }
571 
572 
573 static void
refresh_handler(GHashTable * changes,gpointer user_data)574 refresh_handler (GHashTable *changes, gpointer user_data)
575 {
576     //  PriceEditDialog *pedit_dialog = user_data;
577 
578     //  gnc_prices_load_prices (pedit_dialog);
579 }
580 
581 
582 static gboolean
show_handler(const char * klass,gint component_id,gpointer user_data,gpointer iter_data)583 show_handler (const char *klass, gint component_id,
584               gpointer user_data, gpointer iter_data)
585 {
586     PriceEditDialog *pedit_dialog = user_data;
587     GNCPrice * price = iter_data;
588 
589     if (!pedit_dialog || (pedit_dialog->price != price))
590         return(FALSE);
591 
592     gtk_window_present (GTK_WINDOW(pedit_dialog->dialog));
593     return(TRUE);
594 }
595 
596 
597 /********************************************************************\
598  * gnc_price_edit_dialog                                            *
599  *   opens up a window to edit price information                    *
600  *                                                                  *
601  * Args:   parent  - the parent of the window to be created         *
602  * Return: nothing                                                  *
603 \********************************************************************/
604 void
gnc_price_edit_dialog(GtkWidget * parent,QofSession * session,GNCPrice * price,GNCPriceEditType type)605 gnc_price_edit_dialog (GtkWidget * parent,
606                        QofSession *session,
607                        GNCPrice * price,
608                        GNCPriceEditType type)
609 {
610     PriceEditDialog *pedit_dialog;
611     gint component_id;
612 
613     if ((type == GNC_PRICE_EDIT) &&
614             (gnc_forall_gui_components (DIALOG_PRICE_EDIT_CM_CLASS,
615                                         show_handler, price)))
616         return;
617 
618     pedit_dialog = g_new0 (PriceEditDialog, 1);
619     gnc_price_pedit_dialog_create (parent, pedit_dialog, session);
620     gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(pedit_dialog->dialog), GTK_WINDOW(parent));
621     pedit_dialog->type = type;
622 
623     switch (type)
624     {
625     case GNC_PRICE_NEW:
626         if (price)
627         {
628             price = gnc_price_clone(price, pedit_dialog->book);
629 
630             gnc_price_set_source (price, PRICE_SOURCE_EDIT_DLG);
631             gnc_price_set_time64 (price, gnc_time (NULL));
632             gnc_price_set_value (price, gnc_numeric_zero ());
633         }
634 
635         pedit_dialog->is_new = TRUE;
636         /* New price will only have one ref, this dialog. */
637         break;
638     case GNC_PRICE_EDIT:
639         gnc_price_ref(price); /* Add ref from this dialog */
640         pedit_dialog->is_new = FALSE;
641         break;
642     }
643 
644     pedit_dialog->price = price;
645     price_to_gui(pedit_dialog);
646     gnc_prices_set_changed (pedit_dialog, FALSE);
647     component_id = gnc_register_gui_component (DIALOG_PRICE_EDIT_CM_CLASS,
648                    refresh_handler, close_handler,
649                    pedit_dialog);
650     gnc_gui_component_set_session (component_id, pedit_dialog->session);
651     gtk_widget_grab_focus (pedit_dialog->commodity_cbwe);
652     gtk_widget_show (pedit_dialog->dialog);
653 }
654 
655 
656 /********************************************************************\
657  * gnc_price_edit_by_guid                                           *
658  *   opens up a window to edit price information                    *
659  *                                                                  *
660  * Args:   parent  - the parent of the window to be created         *
661  * Return: nothing                                                  *
662 \********************************************************************/
663 GNCPrice *
gnc_price_edit_by_guid(GtkWidget * parent,const GncGUID * guid)664 gnc_price_edit_by_guid (GtkWidget * parent, const GncGUID * guid)
665 {
666     GNCPrice *price;
667     QofSession *session = gnc_get_current_session();
668     QofBook* book = qof_session_get_book (session);
669 
670     if (!book)
671         return (NULL);
672     price = gnc_price_lookup (guid, book);
673     if (price == NULL)
674         return(NULL);
675 
676     gnc_price_edit_dialog(parent, session, price, GNC_PRICE_EDIT);
677     return price;
678 }
679