1 /********************************************************************\
2  * gnc-ui-util.h -- utility functions for the GnuCash UI            *
3  * Copyright (C) 2000 Dave Peticolas <dave@krondo.com>              *
4  *                                                                  *
5  * This program is free software; you can redistribute it and/or    *
6  * modify it under the terms of the GNU General Public License as   *
7  * published by the Free Software Foundation; either version 2 of   *
8  * the License, or (at your option) any later version.              *
9  *                                                                  *
10  * This program is distributed in the hope that it will be useful,  *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
13  * GNU General Public License for more details.                     *
14  *                                                                  *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact:                        *
17  *                                                                  *
18  * Free Software Foundation           Voice:  +1-617-542-5942       *
19  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
20  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
21 \********************************************************************/
22 
23 /** @addtogroup GUI
24     @{ */
25 /** @addtogroup GuiUtility Utility functions for the GnuCash GUI
26  * @{ */
27 /** @file gnc-ui-util.h
28     @brief  utility functions for the GnuCash UI
29     @author Copyright (C) 2000 Dave Peticolas <dave@krondo.com>
30 */
31 
32 #ifndef GNC_UI_UTIL_H
33 #define GNC_UI_UTIL_H
34 
35 #include <glib.h>
36 #include <locale.h>
37 
38 #include "Account.h"
39 #include "gncOwner.h"
40 #include "qof.h"
41 
42 
43 typedef QofSession * (*QofSessionCB) (void);
44 
45 
46 gchar *gnc_normalize_account_separator (const gchar* separator);
47 gboolean gnc_reverse_balance(const Account *account);
48 
49 /* Backward compatibility *******************************************
50  * Return book's UNREVERSED_BUDGET feature check. */
51 gboolean gnc_using_unreversed_budgets (QofBook* book);
52 
53 /* Backward compatibility *******************************************
54  * Compare book's UNREVERSED_BUDGET with unreverse_check. If they
55  * match, return account reversal according to global pref. If they
56  * don't match, return FALSE. */
57 gboolean gnc_reverse_budget_balance (const Account *account, gboolean unreversed);
58 
59 /* Backward compatibility *******************************************
60  * Return that book's support opening balance accounts by equity type slot */
61 void gnc_set_use_equity_type_opening_balance_account (QofBook* book);
62 gboolean gnc_using_equity_type_opening_balance_account (QofBook* book);
63 
64 /* Default directory sections ***************************************/
65 #define GNC_PREFS_GROUP_OPEN_SAVE    "dialogs.open-save"
66 #define GNC_PREFS_GROUP_EXPORT       "dialogs.export-accounts"
67 #define GNC_PREFS_GROUP_REPORT       "dialogs.report"
68 #define GNC_PREF_AUTO_DECIMAL_POINT  "auto-decimal-point"
69 #define GNC_PREF_AUTO_DECIMAL_PLACES "auto-decimal-places"
70 
71 /* Default directories **********************************************/
72 
73 gchar *gnc_get_default_directory (const gchar *section);
74 void gnc_set_default_directory (const gchar *section,
75                                 const gchar *directory);
76 
77 /* Engine enhancements & i18n ***************************************/
78 QofBook * gnc_get_current_book (void);
79 
80 /* If there is no current session, there is no book and we must be dealing
81  * with a new book. When gnucash is started with --nofile, there is
82  * initially no session (and no book), but by the time we check, one
83  * could have been created (for example, if an empty account tree tab is
84  * opened, a session is created which creates a new, but empty, book).
85  * A session is created and a book is loaded from a backend when gnucash is
86  * started with a file, but selecting 'new file' keeps a session open. So we
87  * need to check as well for a book with no accounts (root with no children). */
88 gboolean gnc_is_new_book (void);
89 
90 void gnc_set_current_book_tax_name_type (gboolean name_changed,
91                                             const gchar *tax_name,
92                                             gboolean type_changed,
93                                             const gchar *tax_type);
94 const gchar * gnc_get_current_book_tax_name (void);
95 const gchar * gnc_get_current_book_tax_type (void);
96 /** Calls gnc_book_option_num_field_source_change to initiate registered
97   * callbacks when num_field_source book option changes so that
98   * registers/reports can update themselves; sets feature flag */
99 void gnc_book_option_num_field_source_change_cb (gboolean num_action);
100 
101 /** Calls gnc_book_option_book_currency_selected to initiate registered
102   * callbacks when currency accounting book option changes to book-currency so
103   * that registers/reports can update themselves; sets feature flag */
104 void gnc_book_option_book_currency_selected_cb (gboolean use_book_currency);
105 
106 /** Returns TRUE if both book-currency and default gain/loss policy KVPs exist
107   * and are valid and trading accounts are not used */
108 gboolean gnc_book_use_book_currency (QofBook *book);
109 
110 /** Returns pointer to Book Currency name for book or NULL; determines
111   * that both book-currency and default gain/loss policy KVPs exist and that
112   * both are valid, a requirement for the 'book-currency' currency accounting
113   * method to apply. */
114 const gchar * gnc_book_get_book_currency_name (QofBook *book);
115 
116 /** Returns pointer to Book Currency for book or NULL; determines
117   * that both book-currency and default gain/loss policy KVPs exist and that
118   * both are valid, a requirement for the 'book-currency' currency accounting
119   * method to apply. */
120 gnc_commodity * gnc_book_get_book_currency (QofBook *book);
121 
122 /** Returns pointer to default gain/loss policy for book or NULL; determines
123   * that both book-currency and default gain/loss policy KVPs exist and that
124   * both are valid, a requirement for the 'book-currency' currency accounting
125   * method to apply. */
126 const gchar * gnc_book_get_default_gains_policy (QofBook *book);
127 
128 /** Returns pointer to default gain/loss account for book or NULL; determines
129   * that both book-currency and default gain/loss policy KVPs exist and that
130   * both are valid, a requirement for the 'book-currency' currency accounting
131   * method to apply. */
132 Account * gnc_book_get_default_gain_loss_acct (QofBook *book);
133 
134 Account * gnc_get_current_root_account (void);
135 gnc_commodity_table * gnc_get_current_commodities (void);
136 
137 /**
138  * Get either the full name of the account or the simple name, depending on the
139  * configuration parameter general/register/show_leaf_account_names.
140  *
141  * @param account The account to retrieve the name for.
142  * @return A newly allocated string.
143 */
144 gchar *gnc_get_account_name_for_register(const Account *account);
145 
146 /**
147  * Retrieve the account matching the given name starting from the descendants of
148  * base_account.
149  * @a name is either considered to be the name of the leaf in the account tree
150  * or to be the full account path, depending on the configuration parameter
151  * general.register/show_leaf_account_names.
152  *
153  * @param base_account The account to start the search at.
154  * @param name The name to search for.
155  * @return A pointer to the account, or NULL if the account was not found.
156 */
157 Account *gnc_account_lookup_for_register(const Account *base_account, const
158         gchar *name);
159 
160 /**
161  * Get either the full name of the account or the simple name, depending on the
162  * show_leaf_accounts.
163  *
164  * @param account The account to retrieve the name for.
165  * @param show_leaf_accounts Whether the full name will be returned.
166  * @return A newly allocated string.
167 */
168 gchar *gnc_get_account_name_for_split_register(const Account *account,
169         gboolean show_leaf_accounts);
170 
171 /*
172  * This is a wrapper routine around an xaccGetBalanceInCurrency
173  * function that handles additional needs of the gui.
174  *
175  * @param fn        The underlying function in Account.c to call to retrieve
176  *                  a specific balance from the account.
177  * @param account   The account to retrieve data about.
178  * @param recurse   Include all sub-accounts of this account.
179  * @param negative  An indication of whether or not the returned value
180  *                  is negative.  This can be used by the caller to
181  *                  easily decode whether or not to color the output.
182  * @param commodity The commodity in which the account balance should
183  *                  be returned. If NULL, the value will be returned in
184  *                  the commodity of the account. This is normally used
185  *                  to specify a currency, which forces the conversion
186  *                  of things like stock account values from share
187  *                  values to an amount the requested currency.
188  */
189 char *gnc_ui_account_get_tax_info_string (const Account *account);
190 
191 char *gnc_ui_account_get_tax_info_sub_acct_string (const Account *account);
192 
193 const char * gnc_get_reconcile_str (char reconciled_flag);
194 const char * gnc_get_reconcile_valid_flags (void);
195 const char * gnc_get_reconcile_flag_order (void);
196 
197 #define WLINK 'w'
198 #define FLINK 'f'
199 
200 /** Get a string containing documentation link valid flags
201  *
202  *  @return a string containing the list of valid link_flags
203  */
204 const char *gnc_get_doclink_valid_flags (void);
205 
206 /** Get a string containing document link flag order
207  *
208  * @return a string containing the document link flag change order
209  */
210 const char *gnc_get_doclink_flag_order (void);
211 
212 /** Get a string representing the document link type
213  *
214  * @param  link_flag The flag to convert into a string
215  *
216  * @return the i18n'd doclink string
217  */
218 const char *gnc_get_doclink_str (char link_flag);
219 
220 typedef enum
221 {
222     EQUITY_OPENING_BALANCE,
223     EQUITY_RETAINED_EARNINGS,
224     NUM_EQUITY_TYPES
225 } GNCEquityType;
226 
227 Account * gnc_find_or_create_equity_account (Account *root,
228         GNCEquityType equity_type,
229         gnc_commodity *currency);
230 gboolean gnc_account_create_opening_balance (Account *account,
231         gnc_numeric balance,
232         time64 date,
233         QofBook *book);
234 
235 /* Locale functions *************************************************/
236 
237 
238 /**
239  * Returns the default currency of the current locale, or NULL if no
240  * sensible currency could be identified from the locale. */
241 gnc_commodity * gnc_locale_default_currency_nodefault (void);
242 
243 /**
244  * Returns the default currency of the current locale. WATCH OUT: If
245  * no currency could be identified from the locale, this one returns
246  * "USD", but this will have nothing to do with the actual locale. */
247 gnc_commodity * gnc_locale_default_currency (void);
248 
249 
250 /** Return the default currency set by the user.  If the user's
251  *  preference is invalid, then this routine will return the default
252  *  currency for the user's locale.
253  *
254  *  @return A pointer to a currency.
255  */
256 gnc_commodity * gnc_default_currency (void);
257 
258 /** Returns a gnc_commodity that is a currency, suitable for being a
259 Transaction's currency. The gnc_commodity is taken either from the current
260 account, or from the next parent account that has a gnc_commodity that is a
261 currency, or from gnc_default_currency().
262 
263 If the given account or any of its parent account have a commodity that is a
264 currency, it is returned and the gboolean currency_from_account_found is set to
265 TRUE (if non-NULL). If neither this account nor any of its parent accounts have
266 such a commodity, gnc_default_currency() is returned and the gboolean
267 currency_from_account_found is set to FALSE (if non-NULL). This can be used to
268 show an appropriate warning message.
269 
270 If account is NULL, gnc_default_currency() is returned and
271 currency_from_account_found is set to FALSE.
272 
273 @param account The account where the currency should be looked up. May be NULL.
274 
275 @param currency_from_account_found A gboolean pointer that takes the output
276 argument of whether the returned currency was found in the account. May be
277 NULL.
278 
279 @return A currency pointer (and never NULL).
280 */
281 gnc_commodity * gnc_account_or_default_currency(const Account* account, gboolean * currency_from_account_found);
282 
283 /** Return the default currency for use in reports, as set by the
284  *  user.  If the user's preference is invalid, then this routine will
285  *  return the default currency for the user's locale.
286  *
287  *  @return A pointer to a currency.
288  */
289 gnc_commodity * gnc_default_report_currency (void);
290 
291 /* Amount printing and parsing **************************************/
292 
293 
294 typedef struct _GNCPrintAmountInfo
295 {
296     const gnc_commodity *commodity;  /* may be NULL */
297 
298     guint8 max_decimal_places;
299     guint8 min_decimal_places;
300 
301     unsigned int use_separators : 1; /* Print thousands separators */
302     unsigned int use_symbol : 1;     /* Print currency symbol */
303     unsigned int use_locale : 1;     /* Use locale for some positioning */
304     unsigned int monetary : 1;       /* Is a monetary quantity */
305     unsigned int force_fit : 1;      /* Don't print more than max_dp places */
306     unsigned int round : 1;          /* Round at max_dp instead of truncating */
307 } GNCPrintAmountInfo;
308 
309 
310 GNCPrintAmountInfo gnc_default_print_info (gboolean use_symbol);
311 
312 GNCPrintAmountInfo gnc_commodity_print_info (const gnc_commodity *commodity,
313         gboolean use_symbol);
314 
315 GNCPrintAmountInfo gnc_account_print_info (const Account *account,
316         gboolean use_symbol);
317 
318 GNCPrintAmountInfo gnc_split_amount_print_info (Split *split,
319         gboolean use_symbol);
320 
321 GNCPrintAmountInfo gnc_price_print_info (const gnc_commodity *curr,
322         gboolean use_symbol);
323 
324 GNCPrintAmountInfo gnc_share_print_info_places (int decplaces);
325 GNCPrintAmountInfo gnc_default_share_print_info (void);
326 GNCPrintAmountInfo gnc_default_price_print_info (const gnc_commodity *curr);
327 
328 GNCPrintAmountInfo gnc_integral_print_info (void);
329 
330 /* WARNING: Garbage in, garbage out.  You must check the validity of
331    the supplied gnc_numeric.  If it's invalid, the returned string
332    could point to ANYTHING. */
333 /*
334  * The xaccPrintAmount() and xaccSPrintAmount() routines provide
335  *    i18n'ed convenience routines for printing gnc_numerics.
336  *    amounts. Both routines take a gnc_numeric argument and
337  *    a printing information object.
338  *
339  * The xaccPrintAmount() routine returns a pointer to a statically
340  *    allocated buffer, and is therefore not thread-safe.
341  *
342  * The xaccSPrintAmount() routine accepts a pointer to the buffer to be
343  *    printed to.  It returns the length of the printed string.
344  */
345 /**
346  * Make a string representation of a gnc_numeric.  Warning, the
347  * gnc_numeric is not checked for validity and the returned char* may
348  * point to random garbage.
349  */
350 const char * xaccPrintAmount (gnc_numeric val, GNCPrintAmountInfo info);
351 /**
352  * Make a string representation of a gnc_numeric.  Warning, the
353  * gnc_numeric is not checked for validity and the contents of the
354  * buffer will be unchanged. It is up to the calling function to
355  * ensure that buf is large enough for the results.
356  */
357 int xaccSPrintAmount (char *buf, gnc_numeric val, GNCPrintAmountInfo info);
358 
359 const gchar *printable_value(gdouble val, gint denom);
360 gchar *number_to_words(gdouble val, gint64 denom);
361 gchar *numeric_to_words(gnc_numeric val);
362 
363 /**  Parses in_str to obtain a numeric result. The
364  *   routine will parse as much of in_str as it can to obtain a single
365  *   number. The number is parsed using the current locale information
366  *   and the 'monetary' flag. The routine will return TRUE if it
367  *   successfully parsed a number and FALSE otherwise. If TRUE is
368  *   returned and result is non-NULL, the value of the parsed number
369  *   is stored in *result. If FALSE is returned, *result is
370  *   unchanged. If TRUE is returned and endstr is non-NULL, the
371  *   location of the first character in in_str not used by the parser
372  *   will be returned in *endstr. If FALSE is returned and endstr is
373  *   non-NULL, *endstr will point to in_str. */
374 gboolean xaccParseAmount (const char * in_str, gboolean monetary,
375                           gnc_numeric *result, char **endstr);
376 
377 /**
378  * Parses in_str to a gnc_numeric, with a flag to indicate whether the
379  * locale's positive sign (or in absence the '+') character is
380  * ignored. Setting skip to TRUE will cause the function to ignore any
381  * positive sign. Setting it to FALSE, and positive signs will be
382  * treated as unrecognized characters.  xaccParseAmount will run as if
383  * skip is FALSE for compatibility reasons (gnc-expression-parser
384  * depends on this behaviour).
385  */
386 gboolean
387 xaccParseAmountPosSign (const char * in_str, gboolean monetary, gnc_numeric *result,
388                         char **endstr, gboolean skip);
389 
390 /**
391  * Converts a string to a gnc_numeric. The caller must provide all the
392  * locale-specific information.
393  *
394  * ignore_list is a list of characters that are completely ignored
395  * while processing the input string.  If ignore_list is NULL, nothing
396  * is ignored.
397  */
398 gboolean
399 xaccParseAmountExtended (const char * in_str, gboolean monetary,
400                          gunichar negative_sign, gunichar decimal_point,
401                          gunichar group_separator, const char *ignore_list,
402                          gnc_numeric *result, char **endstr);
403 
404 /* Initialization ***************************************************/
405 
406 void gnc_ui_util_init (void);
407 
408 /* Remove callback preferences **************************************/
409 
410 void gnc_ui_util_remove_registered_prefs (void);
411 
412 /** Returns the incoming text removed of control characters
413  *
414  * @param incoming_text The text to filter
415  *
416  * @return The incoming text filtered of control characters to be
417  *         freed by the caller.
418 */
419 gchar * gnc_filter_text_for_control_chars (const gchar *incoming_text);
420 
421 /** Updates cursor_position after removal of currency symbols
422  *
423  * @param incoming_text The text to filter
424  *
425  * @param symbol to remove
426  *
427  * @param cursor_position the posistion of cursor in the incoming text
428  *
429  * @return nothing
430 */
431 void gnc_filter_text_set_cursor_position (const gchar *incoming_text,
432                                           const gchar *symbol,
433                                           gint *cursor_position);
434 
435 /** Returns the incoming text removed of a currency symbol
436  *
437  * @param incoming_text The text to filter
438  *
439  * @param symbol to remove
440  *
441  * @param cursor_position the posistion of cursor in the incoming text
442  *
443  * @return The incoming text with symbol removed to be freed by the caller
444 */
445 gchar * gnc_filter_text_for_currency_symbol (const gchar *incoming_text,
446                                              const gchar *symbol);
447 
448 /** Returns the incoming text removed of currency symbol
449  *
450  * @param comm commodity of entry if known
451  *
452  * @param incoming_text The text to filter
453  *
454  * @param symbol return the symbol used
455  *
456  * @return The incoming text with symbol removed to be freed by the caller
457 */
458 gchar * gnc_filter_text_for_currency_commodity (const gnc_commodity *comm,
459                                                 const gchar *incoming_text,
460                                                 const gchar **symbol);
461 
462 #endif
463 /** @} */
464 /** @} */
465