GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
window-report.c
1 /********************************************************************
2  * window-report.c *
3  * Copyright (C) 1997 Robin D. Clark *
4  * Copyright (C) 1998 Linas Vepstas *
5  * Copyright (C) 1999 Jeremy Collins ( gtk-xmhtml port ) *
6  * Copyright (C) 2000 Dave Peticolas *
7  * Copyright (C) 2000 Bill Gribble *
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 [email protected] *
25  * *
26  ********************************************************************/
27 
28 #include "config.h"
29 
30 #include <glib/gi18n.h>
31 #include <errno.h>
32 #include <libguile.h>
33 #include <sys/stat.h>
34 
35 #include "swig-runtime.h"
36 #include "dialog-options.h"
37 #include "dialog-report-column-view.h"
38 #include "file-utils.h"
39 #include "gnc-gkeyfile-utils.h"
40 #include "gnc-guile-utils.h"
41 #include "gnc-report.h"
42 #include "gnc-ui.h"
43 #include "option-util.h"
44 #include "gnc-html.h"
45 #include "window-report.h"
46 #include "guile-mappings.h"
47 
48 #include "gnc-plugin-page-report.h"
49 #include "gnc-report.h"
50 
51 #define WINDOW_REPORT_CM_CLASS "window-report"
52 #define MDI_CHILD_CONFIG "mdi_child_config"
53 
54 /********************************************************************
55  *
56  ********************************************************************/
57 
58 void
59 reportWindow(int report_id)
60 {
61  gnc_set_busy_cursor (NULL, TRUE);
62  gnc_main_window_open_report(report_id, NULL);
63  gnc_unset_busy_cursor (NULL);
64 }
65 
66 /********************************************************************
67  * default parameters editor handling
68  ********************************************************************/
69 
71 {
72  GNCOptionWin * win;
73  GNCOptionDB * db;
74  SCM scm_options;
75  SCM cur_report;
76 };
77 
78 
79 static void
80 gnc_options_dialog_apply_cb(GNCOptionWin * propertybox,
81  gpointer user_data)
82 {
83  SCM dirty_report = scm_c_eval_string("gnc:report-set-dirty?!");
84  struct report_default_params_data * win = user_data;
85 
86  if (!win) return;
87  gnc_option_db_commit(win->db);
88  scm_call_2(dirty_report, win->cur_report, SCM_BOOL_T);
89 }
90 
91 static void
92 gnc_options_dialog_help_cb(GNCOptionWin * propertybox,
93  gpointer user_data)
94 {
95  GtkWidget *dialog, *parent;
96  struct report_default_params_data * prm = user_data;
97 
98  parent = gnc_options_dialog_widget(prm->win);
99  dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
100  GTK_DIALOG_DESTROY_WITH_PARENT,
101  GTK_MESSAGE_INFO,
102  GTK_BUTTONS_OK,
103  "%s",
104  _("Set the report options you want using this dialog."));
105  g_signal_connect(G_OBJECT(dialog), "response",
106  (GCallback)gtk_widget_destroy, NULL);
107  gtk_widget_show(dialog);
108 }
109 
110 static void
111 gnc_options_dialog_close_cb(GNCOptionWin * propertybox,
112  gpointer user_data)
113 {
114  struct report_default_params_data * win = user_data;
115  SCM set_editor = scm_c_eval_string("gnc:report-set-editor-widget!");
116 
117  scm_call_2(set_editor, win->cur_report, SCM_BOOL_F);
118  gnc_options_dialog_destroy(win->win);
119  gnc_option_db_destroy(win->db);
120  scm_gc_unprotect_object(win->scm_options);
121  g_free(win);
122 }
123 
124 static gboolean
125 gnc_report_raise_editor(SCM report)
126 {
127  SCM get_editor = scm_c_eval_string("gnc:report-editor-widget");
128  SCM editor = scm_call_1(get_editor, report);
129  if (editor != SCM_BOOL_F)
130  {
131 #define FUNC_NAME "gnc-report-raise-editor"
132  GtkWidget *w = SWIG_MustGetPtr(editor,
133  SWIG_TypeQuery("_p_GtkWidget"), 1, 0);
134 #undef FUNC_NAME
135  gtk_window_present(GTK_WINDOW(w));
136  return TRUE;
137  }
138  else
139  return FALSE;
140 }
141 
142 
143 GtkWidget *
144 gnc_report_window_default_params_editor(SCM options, SCM report)
145 {
146  SCM get_report_type = scm_c_eval_string("gnc:report-type");
147  SCM get_template = scm_c_eval_string("gnc:find-report-template");
148  SCM get_template_name = scm_c_eval_string("gnc:report-template-name");
149  SCM ptr;
150 
151  const gchar *title = NULL;
152 
153  if (gnc_report_raise_editor (report))
154  return NULL;
155  else
156  {
157  struct report_default_params_data * prm =
158  g_new0(struct report_default_params_data, 1);
159 
160  prm->scm_options = options;
161  prm->cur_report = report;
162  prm->db = gnc_option_db_new(prm->scm_options);
163 
164  /* Get the title of the report's template. */
165  ptr = scm_call_1(get_report_type, report);
166  if (ptr != SCM_BOOL_F)
167  {
168  ptr = scm_call_1(get_template, ptr);
169  if (ptr != SCM_BOOL_F)
170  {
171  ptr = scm_call_1(get_template_name, ptr);
172  if (scm_is_string(ptr))
173  title = gnc_scm_to_utf8_string (ptr);
174  }
175  }
176 
177  /* Don't forget to translate the window title */
178  prm->win = gnc_options_dialog_new((gchar*) (title && *title ? _(title) : ""));
179 
180  g_free ((gpointer *) title);
181 
182  scm_gc_protect_object(prm->scm_options);
183  scm_gc_protect_object(prm->cur_report);
184 
185  gnc_options_dialog_build_contents(prm->win, prm->db);
186  gnc_option_db_clean(prm->db);
187 
188  gnc_options_dialog_set_apply_cb(prm->win,
189  gnc_options_dialog_apply_cb,
190  (gpointer)prm);
191  gnc_options_dialog_set_help_cb(prm->win,
192  gnc_options_dialog_help_cb,
193  (gpointer)prm);
194  gnc_options_dialog_set_close_cb(prm->win,
195  gnc_options_dialog_close_cb,
196  (gpointer)prm);
197  return gnc_options_dialog_widget(prm->win);
198  }
199 }
200 
201 gboolean
202 gnc_report_edit_options(SCM report)
203 {
204  SCM set_editor = scm_c_eval_string("gnc:report-set-editor-widget!");
205  SCM get_options = scm_c_eval_string("gnc:report-options");
206  SCM get_report_type = scm_c_eval_string("gnc:report-type");
207  SCM ptr;
208  SCM options;
209  GtkWidget *options_widget = NULL;
210 
211  /* If the options editor widget already exists we simply raise it */
212  if (gnc_report_raise_editor (report))
213  return TRUE;
214 
215  /* Check if this report has options to edit */
216  options = scm_call_1(get_options, report);
217  if (options == SCM_BOOL_F)
218  {
219  gnc_warning_dialog(GTK_WIDGET(gnc_ui_get_toplevel()), "%s",
220  _("There are no options for this report."));
221  return FALSE;
222  }
223 
224  /* Multi-column type reports need a special options dialog */
225  ptr = scm_call_1(get_report_type, report);
226  if (scm_is_string(ptr))
227  {
228  gchar *rpt_type = gnc_scm_to_utf8_string (ptr);
229  if (g_strcmp0 (rpt_type, "d8ba4a2e89e8479ca9f6eccdeb164588") == 0)
230  options_widget = gnc_column_view_edit_options (options, report);
231  else
232  options_widget = gnc_report_window_default_params_editor (options, report);
233  g_free (rpt_type);
234  }
235 
236  /* Store the options editor widget for future reuse */
237 #define FUNC_NAME "gnc-report-edit-options"
238  ptr = SWIG_NewPointerObj (options_widget, SWIG_TypeQuery("_p_GtkWidget"), 0);
239 #undef FUNC_NAME
240  scm_call_2 (set_editor, report, ptr);
241 
242  return TRUE;
243 }
244 
245 static gboolean
246 gnc_html_file_stream_cb (const char *location, char ** data, int *len)
247 {
248  *len = gncReadFile (location, data);
249  return (*len > 0);
250 }
251 
252 static gboolean
253 gnc_html_report_stream_cb (const char *location, char ** data, int *len)
254 {
255  gboolean ok;
256 
257  ok = gnc_run_report_id_string (location, data);
258 
259  if (!ok)
260  {
261  *data = g_strdup_printf ("<html><body><h3>%s</h3>"
262  "<p>%s</p></body></html>",
263  _("Report error"),
264  _("An error occurred while running the report."));
265 
266  /* Make sure the progress bar is finished, which will also
267  make the GUI sensitive again. Easier to do this via guile
268  because otherwise we would need to link against gnome-utils
269  and a lot more. */
270  scm_c_eval_string("(gnc:report-finished)");
271  }
272 
273  *len = strlen(*data);
274  return ok;
275 }
276 
277 /* TODO: unroll start_editor */
278 static gboolean
279 gnc_html_options_url_cb (const char *location, const char *label,
280  gboolean new_window, GNCURLResult *result)
281 {
282  SCM report;
283  int report_id;
284 
285  g_return_val_if_fail (location != NULL, FALSE);
286  g_return_val_if_fail (result != NULL, FALSE);
287 
288  result->load_to_stream = FALSE;
289 
290  /* href="gnc-options:report-id=2676" */
291  if (strncmp ("report-id=", location, 10) == 0)
292  {
293  if (sscanf (location + 10, "%d", &report_id) != 1)
294  {
295  result->error_message =
296  g_strdup_printf (_("Badly formed options URL: %s"), location);
297 
298  return FALSE;
299  }
300 
301  report = gnc_report_find(report_id);
302  if (report == SCM_UNDEFINED ||
303  report == SCM_BOOL_F)
304  {
305  result->error_message =
306  g_strdup_printf (_("Badly-formed report id: %s"), location);
307 
308  return FALSE;
309  }
310 
311  gnc_report_edit_options (report);
312 
313  return TRUE;
314  }
315  else
316  {
317  result->error_message =
318  g_strdup_printf (_("Badly formed options URL: %s"), location);
319 
320  return FALSE;
321  }
322 }
323 
324 static gboolean
325 gnc_html_report_url_cb (const char *location, const char *label,
326  gboolean new_window, GNCURLResult *result)
327 {
328  g_return_val_if_fail (location != NULL, FALSE);
329  g_return_val_if_fail (result != NULL, FALSE);
330 
331  /* make a new window if necessary */
332  if (new_window)
333  {
334  char *url;
335 
336  url = gnc_build_url (URL_TYPE_REPORT, location, label);
337  gnc_main_window_open_report_url (url, NULL);
338  g_free (url);
339 
340  result->load_to_stream = FALSE;
341  }
342  else
343  {
344  result->load_to_stream = TRUE;
345  }
346 
347  return TRUE;
348 }
349 
350 static gboolean
351 gnc_html_help_url_cb (const char *location, const char *label,
352  gboolean new_window, GNCURLResult *result)
353 {
354  g_return_val_if_fail (location != NULL, FALSE);
355 
356  if (label && (*label != '\0'))
357  gnc_gnome_help (location, label);
358  else
359  gnc_gnome_help (location, NULL);
360  return TRUE;
361 }
362 
363 void
364 gnc_report_init (void)
365 {
366  /* Reference the report page plugin to ensure it exists in the gtk
367  * type system. */
368  GNC_TYPE_PLUGIN_PAGE_REPORT;
369 
370  gnc_html_register_stream_handler (URL_TYPE_HELP, gnc_html_file_stream_cb);
371  gnc_html_register_stream_handler (URL_TYPE_FILE, gnc_html_file_stream_cb);
372  gnc_html_register_stream_handler (URL_TYPE_REPORT, gnc_html_report_stream_cb);
373 
374  gnc_html_register_url_handler (URL_TYPE_OPTIONS, gnc_html_options_url_cb);
375  gnc_html_register_url_handler (URL_TYPE_REPORT, gnc_html_report_url_cb);
376  gnc_html_register_url_handler (URL_TYPE_HELP, gnc_html_help_url_cb);
377 }
GKeyFile helper routines.
void gnc_gnome_help(const char *file_name, const char *anchor)
Utility functions for file access.
GtkWidget * gnc_ui_get_toplevel(void)
int gncReadFile(const char *filename, char **data)
Definition: file-utils.c:61