1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C)    2000-2008 Cédric Auger (cedric@grisbi.org)            */
4 /*          2003-2008 Benjamin Drieu (bdrieu@april.org)                       */
5 /*          https://www.grisbi.org/                                           */
6 /*                                                                            */
7 /*  This program is free software; you can redistribute it and/or modify      */
8 /*  it under the terms of the GNU General Public License as published by      */
9 /*  the Free Software Foundation; either version 2 of the License, or         */
10 /*  (at your option) any later version.                                       */
11 /*                                                                            */
12 /*  This program is distributed in the hope that it will be useful,           */
13 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
14 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
15 /*  GNU General Public License for more details.                              */
16 /*                                                                            */
17 /*  You should have received a copy of the GNU General Public License         */
18 /*  along with this program; if not, write to the Free Software               */
19 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
20 /*                                                                            */
21 /* ************************************************************************** */
22 
23 /**
24  * \file gsb_assistant_account.c
25  * we find here the complete assistant to create a new account
26  */
27 
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "include.h"
34 #include <glib/gi18n.h>
35 
36 /*START_INCLUDE*/
37 #include "gsb_assistant_account.h"
38 #include "dialog.h"
39 #include "gsb_account.h"
40 #include "gsb_assistant.h"
41 #include "gsb_bank.h"
42 #include "gsb_currency.h"
43 #include "gsb_data_account.h"
44 #include "gsb_data_bank.h"
45 #include "gsb_data_currency.h"
46 #include "gsb_locale.h"
47 #include "gsb_real.h"
48 #include "gsb_select_icon.h"
49 #include "utils.h"
50 #include "utils_real.h"
51 #include "structures.h"
52 #include "erreur.h"
53 /*END_INCLUDE*/
54 
55 /*START_STATIC*/
56 static void gsb_assistant_account_change_account_icon ( GtkWidget *button, gpointer data );
57 static gboolean gsb_assistant_account_enter_page_finish ( GtkWidget * assistant, gint new_page );
58 static GtkWidget *gsb_assistant_account_page_2 ( GtkWidget *assistant );
59 static GtkWidget *gsb_assistant_account_page_3 ( GtkWidget *assistant );
60 static GtkWidget *gsb_assistant_account_page_finish ( GtkWidget *assistant );
61 static gboolean gsb_assistant_account_toggled_kind_account ( GtkWidget *button,
62 						      GtkWidget *assistant );
63 /*END_STATIC*/
64 
65 /*START_EXTERN*/
66 /*END_EXTERN*/
67 
68 static gchar * new_icon = NULL;
69 
70 enum FirstAccountAssistantPage
71 {
72     ACCOUNT_ASSISTANT_INTRO= 0,
73     ACCOUNT_ASSISTANT_PAGE_2,
74     ACCOUNT_ASSISTANT_PAGE_3,
75     ACCOUNT_ASSISTANT_PAGE_FINISH
76 };
77 
78 
79 static GtkWidget *account_combobox_currency = NULL;
80 static GtkWidget *account_combobox_bank = NULL;
81 static GtkWidget *account_entry_initial_amount = NULL;
82 
83 /**
84  * this function is called to launch the account assistant
85  * called directly by menu
86  *
87  * \param
88  *
89  * \return TRUE on success, FALSE otherwise (i.e. user cancelled).
90  */
gsb_assistant_account_run(void)91 GtkResponseType gsb_assistant_account_run ( void )
92 {
93 	gboolean result = FALSE;
94     GtkResponseType return_value;
95     GtkWidget *assistant;
96 
97     if ( new_icon && strlen ( new_icon ) > 0)
98         g_free ( new_icon );
99     assistant = gsb_assistant_new ( _("Create a new account"),
100 				    _("This assistant will help you to create a new account.\n"
101 				      "All that you do here can be changed later in the account configuration page." ),
102 				    NULL,
103 				    NULL );
104     gsb_assistant_add_page ( assistant,
105 			     gsb_assistant_account_page_2 (assistant),
106 			     ACCOUNT_ASSISTANT_PAGE_2,
107 			     ACCOUNT_ASSISTANT_INTRO,
108 			     ACCOUNT_ASSISTANT_PAGE_3,
109 			     NULL );
110     gsb_assistant_add_page ( assistant,
111 			     gsb_assistant_account_page_3 (assistant),
112 			     ACCOUNT_ASSISTANT_PAGE_3,
113 			     ACCOUNT_ASSISTANT_PAGE_2,
114 			     ACCOUNT_ASSISTANT_PAGE_FINISH,
115 			     NULL );
116     gsb_assistant_add_page ( assistant,
117 			     gsb_assistant_account_page_finish (assistant),
118 			     ACCOUNT_ASSISTANT_PAGE_FINISH,
119 			     ACCOUNT_ASSISTANT_PAGE_3,
120 			     0,
121 			     G_CALLBACK ( gsb_assistant_account_enter_page_finish ) );
122 
123     return_value = gsb_assistant_run (assistant);
124 
125     if (return_value == GTK_RESPONSE_APPLY)
126     {
127 		GtkWidget *account_entry_name;
128 
129 		/* Ok, we create the new account */
130 		account_entry_name = g_object_get_data (G_OBJECT (assistant), "account_entry_name");
131 		gsb_account_new ( GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT (assistant), "account_kind")),
132 				  gsb_currency_get_currency_from_combobox (account_combobox_currency),
133 				  gsb_bank_combo_list_get_bank_number (account_combobox_bank),
134 				  utils_real_get_from_string (gtk_entry_get_text (GTK_ENTRY (account_entry_initial_amount))),
135 				  gtk_entry_get_text (GTK_ENTRY (account_entry_name)),
136 				  new_icon );
137         result = TRUE; /* assistant was not cancelled */
138     }
139 
140     gtk_widget_destroy (assistant);
141     return result;
142 }
143 
144 
145 
146 /**
147  * create the page 2 of the account assistant
148  * this page ask for the kind of account
149  *
150  * \param assistant the GtkWidget assistant
151  *
152  * \return a GtkWidget containing the page
153  * */
gsb_assistant_account_page_2(GtkWidget * assistant)154 static GtkWidget *gsb_assistant_account_page_2 ( GtkWidget *assistant )
155 {
156     GtkWidget *page;
157     GtkWidget *vbox;
158     GtkWidget *label;
159     GtkWidget *button;
160     gint i;
161     gchar *account_type[] = {
162 	_("Bank account\nStandard account with credit card and cheques."),
163 	_("Cash account\nStandard cash account, to use with a cashier."),
164 	_("Liabilities account\nSpecial account to represent a debt, like a long-term loan."),
165 	_("Assets account\nSpecial account to represent an asset, like a car or special subscriptions."),
166 	NULL };
167 
168     page = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX );
169     gtk_container_set_border_width ( GTK_CONTAINER (page), BOX_BORDER_WIDTH );
170 
171     vbox = new_vbox_with_title_and_icon ( _("Account type selection"),
172 					  "gsb-ac-bank-32.png" );
173     gtk_box_pack_start ( GTK_BOX (page),
174 			 vbox,
175 			 TRUE, TRUE, 0 );
176 
177     label = gtk_label_new (_("Please select type for this account.\n"
178 			     "The account will be created with default payment methods chosen according to your choice.\n"
179 			     "If you are unsure and novice to accounting, we advise that you choose a bank account.\n"));
180     utils_labels_set_alignment ( GTK_LABEL (label),
181 			     0, 0.5 );
182     gtk_box_pack_start ( GTK_BOX (vbox),
183 			 label,
184 			 FALSE, FALSE, 0 );
185 
186     /* show the kind of accounts,
187      * the current kind will be saved as g_object_set in assistant widget */
188     i = 0;
189     button = NULL;
190     while (account_type[i])
191     {
192 	if (button)
193 	    button = gtk_radio_button_new_with_label_from_widget ( GTK_RADIO_BUTTON (button),
194 								   account_type[i]);
195 	else
196 	    button = gtk_radio_button_new_with_label ( NULL,
197 						       account_type[i] );
198 	g_object_set_data ( G_OBJECT (button),
199 			    "account_kind", GINT_TO_POINTER (i));
200 	g_signal_connect ( G_OBJECT (button),
201 			   "toggled",
202 			   G_CALLBACK (gsb_assistant_account_toggled_kind_account),
203 			   G_OBJECT (assistant));
204 	gtk_box_pack_start ( GTK_BOX (vbox),
205 			     button,
206 			     FALSE, FALSE, 0 );
207 	i++;
208     }
209 
210     gtk_widget_show_all (page);
211     return page;
212 }
213 
214 
215 /**
216  * create the page 3 of the account assistant
217  * this page ask for the currency, the bank and the initial amount
218  *
219  * \param assistant the GtkWidget assistant
220  *
221  * \return a GtkWidget containing the page
222  * */
gsb_assistant_account_page_3(GtkWidget * assistant)223 static GtkWidget *gsb_assistant_account_page_3 ( GtkWidget *assistant )
224 {
225     GtkWidget *page, *label, *button, *table;
226     GtkWidget *image;
227     GdkPixbuf *pixbuf;
228 
229     struct lconv *locale = gsb_locale_get_locale ( );
230 
231     page = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX );
232     gtk_container_set_border_width ( GTK_CONTAINER (page), BOX_BORDER_WIDTH );
233 
234     table = gtk_grid_new ();
235     gtk_grid_set_row_spacing (GTK_GRID (table), 6);
236     gtk_grid_set_column_spacing (GTK_GRID (table), 6);
237 
238     gtk_box_pack_start ( GTK_BOX (page), table,
239 			 FALSE, FALSE, 0 );
240 
241     /* choose the currency */
242     label = gtk_label_new ( _("Currency for the account: ") );
243     utils_labels_set_alignment ( GTK_LABEL ( label ), 0.0, 0.5 );
244     gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
245 
246     /* Guesstimate default currency from locale.  Default is USD since
247      * this would confuse US folks while rest of the world is used to
248      * configure stuff to their locale.  */
249     if ( ! gsb_data_currency_get_default_currency () &&
250 	 ! gsb_data_currency_new_from_iso4217_list ( locale -> int_curr_symbol ) )
251     {
252 	gsb_data_currency_new_from_iso4217_list ( "USD" );
253     }
254 
255     /* create the currency combobox */
256     account_combobox_currency = gsb_currency_make_combobox (TRUE);
257     gtk_grid_attach (GTK_GRID (table), account_combobox_currency, 1, 0, 1, 1);
258 
259     /* propose to add a currency */
260     button = gtk_button_new_with_label (_("Add/Change..."));
261     g_signal_connect ( G_OBJECT (button),
262 		       "clicked",
263 		       G_CALLBACK (gsb_currency_add_currency_set_combobox),
264 		       account_combobox_currency );
265     gtk_grid_attach (GTK_GRID (table), button, 2, 0, 1, 1);
266 
267     /* choose the bank */
268     label = gtk_label_new ( _("Bank for the account: ") );
269     utils_labels_set_alignment ( GTK_LABEL ( label ), 0.0, 0.5 );
270     gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
271 
272     account_combobox_bank = gsb_bank_create_combobox (0 );
273 
274     if ( gsb_data_bank_max_number() != 0 )
275     {
276 	gsb_bank_combo_list_set_bank ( account_combobox_bank, 1 );
277     }
278     else
279     {
280 	gsb_bank_combo_list_set_bank ( account_combobox_bank, 0 );
281     }
282     gtk_grid_attach (GTK_GRID (table), account_combobox_bank, 1, 1, 1, 1);
283 
284     /* set the initial amount */
285     label = gtk_label_new ( _("Opening balance: ") );
286     utils_labels_set_alignment ( GTK_LABEL ( label ), 0.0, 0.5 );
287     gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
288 
289     account_entry_initial_amount = gtk_entry_new ();
290     gtk_grid_attach (GTK_GRID (table), account_entry_initial_amount, 1, 2, 1, 1);
291 
292     /* création du choix de l'icône du compte */
293     /* Récupération de l'icône par défaut */
294     button = gtk_button_new ( );
295     gtk_widget_set_size_request ( button, 80, 80 );
296 	pixbuf = gsb_data_account_get_account_standard_pixbuf (0);
297     image = gtk_image_new_from_pixbuf (pixbuf);
298 	g_object_unref (G_OBJECT (pixbuf));
299     gtk_button_set_image ( GTK_BUTTON ( button ), image);
300     gtk_button_set_relief ( GTK_BUTTON ( button ), GTK_RELIEF_NORMAL );
301     gtk_grid_attach (GTK_GRID (table), button, 3, 0, 1, 3);
302 	utils_widget_set_padding (button, 20, 0);
303 	gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
304 	gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
305     g_object_set_data ( G_OBJECT (assistant), "bouton_icon", button );
306     g_signal_connect ( G_OBJECT( button ),
307                             "clicked",
308                             G_CALLBACK(gsb_assistant_account_change_account_icon),
309                             NULL );
310 
311     gtk_widget_show_all (page);
312     return page;
313 }
314 
315 
316 
317 /**
318  * create the last page of the account assistant
319  * it will ask the name of the new account and propose to create it
320  *
321  * \param assistant the GtkWidget assistant
322  *
323  * \return a GtkWidget containing the page
324  * */
gsb_assistant_account_page_finish(GtkWidget * assistant)325 static GtkWidget *gsb_assistant_account_page_finish ( GtkWidget *assistant )
326 {
327     GtkWidget *page;
328     GtkWidget *vbox;
329     GtkWidget *label;
330     GtkWidget *hbox;
331 	GtkWidget *account_entry_name;
332 
333     page = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX );
334     gtk_container_set_border_width ( GTK_CONTAINER (page), BOX_BORDER_WIDTH );
335 
336     vbox = gtk_box_new ( GTK_ORIENTATION_VERTICAL, MARGIN_BOX );
337     gtk_box_pack_start ( GTK_BOX (page),
338 			 vbox,
339 			 FALSE, FALSE, 0 );
340 
341     /* set up the menu */
342     label = gtk_label_new (_("You are about to validate the new account.\n"
343 			     "You juste have to enter a name and finish the assistant.\n"
344 			     "More options are available in the account configuration page once you created it.\n"));
345     utils_labels_set_alignment ( GTK_LABEL (label),
346 			     0.5, 0.5 );
347     gtk_box_pack_start ( GTK_BOX (vbox),
348 			 label,
349 			 FALSE, FALSE, 0 );
350 
351     /* enter the name */
352     hbox = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX);
353     gtk_box_pack_start ( GTK_BOX (vbox),
354 			 hbox,
355 			 FALSE, FALSE, 0 );
356 
357     label = gtk_label_new (_("Please enter the name of the new account: "));
358     gtk_box_pack_start ( GTK_BOX (hbox),
359 			 label,
360 			 FALSE, FALSE, 0 );
361 
362     account_entry_name = gtk_entry_new ();
363     g_object_set_data ( G_OBJECT (assistant), "account_entry_name", account_entry_name );
364     gtk_box_pack_start ( GTK_BOX (hbox),
365 			 account_entry_name,
366 			 FALSE, FALSE, 0 );
367 
368     gtk_widget_show_all (page);
369     return page;
370 }
371 
372 
373 
374 /**
375  *
376  *
377  *
378  *
379  */
gsb_assistant_account_enter_page_finish(GtkWidget * assistant,gint new_page)380 static gboolean gsb_assistant_account_enter_page_finish ( GtkWidget * assistant, gint new_page )
381 {
382     GtkWidget * account_entry_name = g_object_get_data ( G_OBJECT (assistant), "account_entry_name" );
383     gchar * default_name = NULL;
384     gint account_type = GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT (assistant), "account_kind" ) );
385 
386     switch ( account_type )
387     {
388 	case GSB_TYPE_BANK:
389 	    if ( gsb_bank_combo_list_get_bank_number ( account_combobox_bank ) >= 0 )
390 	    {
391 		const gchar * bank_name;
392 
393 		bank_name = gsb_data_bank_get_name ( gsb_bank_combo_list_get_bank_number ( account_combobox_bank ) );
394 		/* Do not use a bank name if no bank is set or if its
395 		 * name has not been changed. */
396 		if ( bank_name && strcmp ( bank_name, _("New bank") ) )
397 		    default_name = g_strdup_printf ( _("%s account"), bank_name );
398 		else
399 		    default_name = g_strdup ( _("Bank account" ) );
400 	    }
401 	    break;
402 
403 	case GSB_TYPE_CASH:
404 	    default_name = g_strdup_printf ( _("Cashier") );
405 	    break;
406 
407 	case GSB_TYPE_ASSET:
408 	    default_name = g_strdup_printf ( _("Assets account") );
409 	    break;
410 
411 	case GSB_TYPE_LIABILITIES:
412 	    default_name = g_strdup_printf ( _("Liabilities account"));
413 	    break;
414     }
415 
416     gtk_entry_set_text ( GTK_ENTRY ( account_entry_name ), default_name );
417     if ( default_name )
418 	g_free ( default_name );
419 
420     return FALSE;
421 }
422 
423 
424 /**
425  * callback called when toggle the choice of type of account
426  * it will save the choice in the assistant widget
427  *
428  * \param button
429  * \param assistant
430  *
431  * \return FALSE
432  * */
gsb_assistant_account_toggled_kind_account(GtkWidget * button,GtkWidget * assistant)433 gboolean gsb_assistant_account_toggled_kind_account ( GtkWidget *button,
434 						      GtkWidget *assistant )
435 {
436     GtkWidget *bouton_icon, *image;
437     GdkPixbuf *pixbuf;
438 
439     KindAccount account_kind;
440 
441     account_kind = GPOINTER_TO_INT ( g_object_get_data
442                 ( G_OBJECT (button), "account_kind"));
443     g_object_set_data ( G_OBJECT (assistant),
444                 "account_kind", GINT_TO_POINTER ( account_kind ) );
445 
446     bouton_icon = g_object_get_data ( G_OBJECT (assistant), "bouton_icon" );
447 	pixbuf = gsb_data_account_get_account_standard_pixbuf (account_kind);
448     image = gtk_image_new_from_pixbuf (pixbuf);
449 	g_object_unref (G_OBJECT (pixbuf));
450     gtk_button_set_image ( GTK_BUTTON ( bouton_icon ), image);
451     return FALSE;
452 }
453 
gsb_assistant_account_change_account_icon(GtkWidget * button,gpointer data)454 void gsb_assistant_account_change_account_icon ( GtkWidget *button, gpointer data )
455 {
456     GdkPixbuf * pixbuf;
457     GtkWidget *image;
458     gchar * name_icon;
459     GError *error = NULL;
460 
461     devel_debug ( NULL );
462     image = gtk_button_get_image ( GTK_BUTTON ( button ) );
463     pixbuf = gtk_image_get_pixbuf ( GTK_IMAGE ( image ) );
464     name_icon = g_object_get_data ( G_OBJECT ( pixbuf ), "name_icon" );
465     devel_debug (name_icon);
466     new_icon = gsb_select_icon_create_window ( name_icon );
467     if ( ! new_icon )
468         return;
469     devel_debug (new_icon);
470     pixbuf = gdk_pixbuf_new_from_file_at_size ( new_icon , 32, 32, &error );
471     if ( ! pixbuf )
472     {
473         devel_debug ( error -> message );
474         dialogue_error ( error -> message );
475         g_error_free ( error );
476     }
477     else
478     {
479 		image = gtk_image_new_from_pixbuf ( pixbuf );
480 		g_object_unref (G_OBJECT (pixbuf));
481 		if ( image )
482 			gtk_button_set_image ( GTK_BUTTON ( button ), image );
483     }
484 }
485