GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
top-level.c
1 /********************************************************************\
2  * top-level.c -- Gnome GUI main for GnuCash *
3  * Copyright (C) 1997 Robin D. Clark *
4  * Copyright (C) 1998-2000 Linas Vepstas *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA [email protected] *
22  * *
23 \********************************************************************/
24 
25 #include "config.h"
26 
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29 #include <stdlib.h>
30 
31 #include "TransLog.h"
32 #include "combocell.h"
33 #include "dialog-account.h"
34 #include "dialog-commodity.h"
35 #include "dialog-options.h"
36 #include "dialog-sx-editor.h"
37 #include "dialog-transfer.h"
38 #include "dialog-totd.h"
39 #include "assistant-hierarchy.h"
40 #include "file-utils.h"
41 #include "gnc-component-manager.h"
42 #include "gnc-engine.h"
43 #include "gnc-file.h"
44 #include "gnc-hooks.h"
45 #include "gfec.h"
46 #include "gnc-main-window.h"
47 #include "gnc-menu-extensions.h"
48 #include "gnc-plugin-menu-additions.h" /* FIXME Remove this line*/
49 #include "gnc-plugin-account-tree.h" /* FIXME Remove this line*/
50 #include "gnc-plugin-basic-commands.h" /* FIXME Remove this line*/
51 #include "gnc-plugin-file-history.h" /* FIXME Remove this line*/
52 #include "gnc-plugin-register.h" /* FIXME Remove this line*/
53 #include "gnc-plugin-register2.h" /* FIXME Remove this line*/
54 #include "gnc-plugin-budget.h"
56 #include "gnc-plugin-page-register2.h"
57 #include "gnc-plugin-manager.h" /* FIXME Remove this line*/
58 #include "gnc-html.h"
59 #include "gnc-gnome-utils.h"
60 #include "gnc-report.h"
61 #include "gnc-split-reg.h"
62 #include "gnc-state.h"
63 #include "gnc-ui.h"
64 #include "gnc-ui-util.h"
65 #include "gnucash-color.h"
66 #include "gnucash-sheet.h"
67 #include "gnucash-style.h"
68 #include "guile-util.h"
69 #include "top-level.h"
70 #include "window-report.h"
71 #include "gnc-window.h"
72 #include "gnc-gkeyfile-utils.h"
73 
74 
76 /* This static indicates the debugging module that this .o belongs to. */
77 static QofLogModule log_module = GNC_MOD_GUI;
78 
79 /* ============================================================== */
80 /* HTML Handler for reports. */
81 
82 static gboolean
83 validate_type(const char *url_type, const char *location,
84  const char *entity_type, GNCURLResult *result,
85  GncGUID *guid, QofInstance **entity)
86 {
87  QofCollection *col;
88  QofBook * book = gnc_get_current_book();
89  if (!string_to_guid (location + strlen(url_type), guid))
90  {
91  result->error_message = g_strdup_printf (_("Bad URL: %s"), location);
92  return FALSE;
93  }
94  col = qof_book_get_collection (book, entity_type);
95  *entity = qof_collection_lookup_entity (col, guid);
96  if (NULL == *entity)
97  {
98  result->error_message = g_strdup_printf (_("Entity Not Found: %s"),
99  location);
100  return FALSE;
101  }
102 
103  return TRUE;
104 }
105 
106 
107 static gboolean
108 gnc_html_register_url_cb (const char *location, const char *label,
109  gboolean new_window, GNCURLResult *result)
110 {
111  GncPluginPage *page = NULL;
112  GNCSplitReg * gsr = NULL;
113  Split * split = NULL;
114  Account * account = NULL;
115  Transaction * trans;
116  GList * node;
117  GncGUID guid;
118  QofInstance * entity = NULL;
119 
120  g_return_val_if_fail (location != NULL, FALSE);
121  g_return_val_if_fail (result != NULL, FALSE);
122 
123  result->load_to_stream = FALSE;
124 
125  /* href="gnc-register:account=My Bank Account" */
126  if (strncmp("account=", location, 8) == 0)
127  {
128  account = gnc_account_lookup_by_full_name (gnc_get_current_root_account (),
129  location + 8);
130  }
131 
132  /* href="gnc-register:guid=12345678901234567890123456789012" */
133  else if (strncmp ("acct-guid=", location, strlen ("acct-guid=")) == 0)
134  {
135  if (!validate_type("acct-guid=", location, GNC_ID_ACCOUNT, result, &guid, &entity))
136  return FALSE;
137 
138  account = GNC_ACCOUNT(entity);
139  }
140 
141  else if (strncmp ("trans-guid=", location, strlen ("trans-guid=")) == 0)
142  {
143  if (!validate_type("trans-guid=", location, GNC_ID_TRANS, result, &guid, &entity))
144  return FALSE;
145 
146  trans = (Transaction *) entity;
147 
148  for (node = xaccTransGetSplitList (trans); node; node = node->next)
149  {
150  split = node->data;
151  account = xaccSplitGetAccount(split);
152  if (account) break;
153  }
154 
155  if (!account)
156  {
157  result->error_message =
158  g_strdup_printf (_("Transaction with no Accounts: %s"), location);
159  return FALSE;
160  }
161  }
162 
163  else if (strncmp ("split-guid=", location, strlen ("split-guid=")) == 0)
164  {
165  if (!validate_type("split-guid=", location, GNC_ID_SPLIT, result, &guid, &entity))
166  return FALSE;
167 
168  split = (Split *) entity;
169  account = xaccSplitGetAccount(split);
170  }
171  else
172  {
173  result->error_message =
174  g_strdup_printf (_("Unsupported entity type: %s"), location);
175  return FALSE;
176  }
177 
178  page = gnc_plugin_page_register_new (account, FALSE);
179  gnc_main_window_open_page (NULL, page);
180  if (split)
181  {
183  gnc_split_reg_jump_to_split( gsr, split );
184  }
185 
186  return TRUE;
187 }
188 
189 /* ============================================================== */
190 
191 static gboolean
192 gnc_html_price_url_cb (const char *location, const char *label,
193  gboolean new_window, GNCURLResult *result)
194 {
195  GncGUID guid;
196  QofInstance * entity = NULL;
197 
198  g_return_val_if_fail (location != NULL, FALSE);
199  g_return_val_if_fail (result != NULL, FALSE);
200 
201  result->load_to_stream = FALSE;
202 
203  /* href="gnc-register:guid=12345678901234567890123456789012" */
204  if (strncmp ("price-guid=", location, strlen ("price-guid=")) == 0)
205  {
206  if (!validate_type("price-guid=", location, GNC_ID_PRICE, result, &guid, &entity))
207  return FALSE;
208 
209  if (!gnc_price_edit_by_guid (NULL, &guid))
210  {
211  result->error_message = g_strdup_printf (_("No such price: %s"),
212  location);
213  return FALSE;
214  }
215  }
216  else
217  {
218  result->error_message = g_strdup_printf (_("Badly formed URL %s"),
219  location);
220  return FALSE;
221  }
222 
223  return TRUE;
224 }
225 
240 static void
241 gnc_restore_all_state (gpointer session, gpointer unused)
242 {
243  GKeyFile *keyfile = NULL;
244  gchar *file_guid = NULL;
245  GError *error = NULL;
246 
247  keyfile = gnc_state_load (session);
248 
249 #ifdef DEBUG
250  /* Debugging: dump a copy to the trace log */
251  {
252  gchar *file_data;
253  gsize file_length;
254  file_data = g_key_file_to_data(keyfile, &file_length, NULL);
255  DEBUG("=== File Data Read===\n%s\n=== File End ===\n", file_data);
256  g_free(file_data);
257  }
258 #endif
259 
260  /* If no state file was found, keyfile will be empty
261  * In that case, let's load the default state */
262  if (!g_key_file_has_group (keyfile, STATE_FILE_TOP))
263  {
265  LEAVE("no state file");
266  goto cleanup;
267  }
268 
269  /* report any other keyfile read error as a warning
270  * but still load default state */
271  file_guid = g_key_file_get_string(keyfile, STATE_FILE_TOP,
272  STATE_FILE_BOOK_GUID, &error);
273  if (error)
274  {
276  g_warning("error reading group %s key %s: %s",
277  STATE_FILE_TOP, STATE_FILE_BOOK_GUID, error->message);
278  LEAVE("no guid in state file");
279  goto cleanup;
280  }
281 
283 
284  /* Clean up */
285  LEAVE("ok");
286 cleanup:
287  if (error)
288  g_error_free(error);
289  if (file_guid)
290  g_free(file_guid);
291 }
292 
293 
308 static void
309 gnc_save_all_state (gpointer session, gpointer unused)
310 {
311  QofBook *book;
312  gchar guid_string[GUID_ENCODING_LENGTH+1];
313  const GncGUID *guid;
314  GError *error = NULL;
315  GKeyFile *keyfile = NULL;
316 
317  keyfile = gnc_state_get_current ();
318  if (keyfile)
319  {
320  /* Remove existing Window and Page groups from the keyfile
321  * They will be regenerated.
322  */
323  gsize num_groups, curr;
324  gchar **groups = g_key_file_get_groups (keyfile, &num_groups);
325  gchar *group = NULL;
326  for (curr=0; curr < num_groups; curr++)
327  {
328  if (g_str_has_prefix (groups[curr], "Window ") ||
329  g_str_has_prefix (groups[curr], "Page "))
330  {
331  DEBUG ("Removing state group %s", groups[curr]);
332  g_key_file_remove_group (keyfile, groups[curr], NULL);
333  }
334  }
335  g_strfreev (groups);
336  }
337 
338  /* Store the book's GncGUID in the top level group */
339  book = qof_session_get_book(session);
340  guid = qof_entity_get_guid(QOF_INSTANCE(book));
341  guid_to_string_buff(guid, guid_string);
342  g_key_file_set_string(keyfile, STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
343  guid_string);
344 
346 
347 #ifdef DEBUG
348  /* Debugging: dump a copy to the trace log */
349  {
350  gchar *file_data;
351  gsize file_length;
352  file_data = g_key_file_to_data(keyfile, &file_length, NULL);
353  DEBUG("=== File Data Written===\n%s\n=== File End ===\n", file_data);
354  g_free(file_data);
355  }
356 #endif
357  LEAVE("");
358 }
359 
360 void
361 gnc_main_gui_init (void)
362 {
363  ENTER(" ");
364 
365  if (!gnucash_style_init())
366  gnc_shutdown(1);
367  gnucash_color_init();
368 
369  gnc_html_register_url_handler (URL_TYPE_REGISTER,
370  gnc_html_register_url_cb);
371 
372  gnc_html_register_url_handler (URL_TYPE_PRICE,
373  gnc_html_price_url_cb);
374 
375  gnc_ui_sx_initialize();
376 
377  /* FIXME Remove this test code */
387  gnc_plugin_manager_get (), gnc_plugin_register_new ());
389  gnc_plugin_manager_get (), gnc_plugin_register2_new ());
390  /* I'm not sure why the FIXME note says to remove this. Maybe
391  each module should be adding its own plugin to the manager?
392  Anyway... Oh, maybe... nah */
394  gnc_plugin_budget_new ());
395  gnc_ui_hierarchy_assistant_initialize();
396 
397  /* Run the ui startup hooks. */
398  gnc_hook_run(HOOK_UI_STARTUP, NULL);
399 
400  gnc_hook_add_dangler(HOOK_BOOK_OPENED,
401  gnc_restore_all_state, NULL);
402  gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
403  gnc_save_all_state, NULL);
404  gnc_hook_add_dangler(HOOK_BOOK_CLOSED,
405  (GFunc)gnc_reports_flush_global, NULL);
406 
407 
408  LEAVE(" ");
409  return;
410 }
411 
412 /****************** END OF FILE **********************/
GncPluginPage * gnc_plugin_page_register_new(Account *account, gboolean subaccounts)
Functions to load, save and get gui state.
void gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
Dialog for create/edit an account.
utility functions for the GnuCash UI
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
#define DEBUG(format, args...)
Definition: qoflog.h:255
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Functions that are supported by all types of windows.
GncPlugin * gnc_plugin_file_history_new(void)
GKeyFile helper routines.
Plugin management functions for the GnuCash UI.
void gnc_plugin_manager_add_plugin(GncPluginManager *manager, GncPlugin *plugin)
void gnc_shutdown(int exit_status)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
#define ENTER(format, args...)
Definition: qoflog.h:261
GKeyFile * gnc_state_get_current(void)
Definition: gnc-state.c:252
void gnc_main_window_save_all_windows(GKeyFile *keyfile)
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Functions for adding content to a window.
Definition: guid.h:65
QofBook * qof_session_get_book(const QofSession *session)
Functions providing a register page for the GnuCash UI.
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
Functions providing the file history menu.
Functions providing menu items from scheme code.
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
Definition: Account.c:2915
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
GncPluginManager * gnc_plugin_manager_get(void)
Gnome specific utility functions.
GncPlugin * gnc_plugin_basic_commands_new(void)
GncPlugin * gnc_plugin_menu_additions_new(void)
All type declarations for the whole Gnucash engine.
const GncGUID * qof_entity_get_guid(gconstpointer)
Utility functions for file access.
API for the transaction logger.
Definition: SplitP.h:71
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
GncPlugin * gnc_plugin_account_tree_new(void)
Provide the menus to create a chart of account page.
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
void gnc_main_window_restore_default_state(GncMainWindow *window)
GKeyFile * gnc_state_load(const QofSession *session)
Definition: gnc-state.c:200
GNCSplitReg * gnc_plugin_page_register_get_gsr(GncPluginPage *plugin_page)
"select" and "new" commodity windows
Functions providing a basic set of menu items.
SplitList * xaccTransGetSplitList(const Transaction *trans)
Definition: Transaction.c:2164
const gchar * QofLogModule
Definition: qofid.h:89