GnuCash  5.6-150-g038405b370+
gnc-plugin-report-system.c
1 /*
2  * gnc-plugin-report-system.c --
3  * Copyright (C) 2003 David Hampton <hampton@employees.org>
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 #include <config.h>
24 
25 #include <gtk/gtk.h>
26 #include <glib/gi18n.h>
27 
28 #include "dialog-report-style-sheet.h"
29 #include "file-utils.h"
30 #include "gnc-gnome-utils.h"
31 #include "gnc-html.h"
32 #include "gnc-guile-utils.h"
33 #include "gnc-plugin-page-report.h"
34 #include "gnc-plugin-report-system.h"
35 #include "gnc-plugin-manager.h"
36 #include "gnc-report.h"
37 #include "gnc-engine.h"
38 #include "window-report.h"
39 
40 static void gnc_plugin_report_system_finalize (GObject *object);
41 
42 
43 /* Command callbacks */
44 static void gnc_plugin_report_system_cmd_edit_style_sheet (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
45 
46 
47 #define PLUGIN_ACTIONS_NAME "gnc-plugin-report-system-actions"
48 #define PLUGIN_UI_FILENAME "gnc-plugin-report-system.ui"
49 
50 static GActionEntry gnc_plugin_actions [] =
51 {
52  { "EditStyleSheetsAction", gnc_plugin_report_system_cmd_edit_style_sheet, NULL, NULL, NULL },
53 };
55 static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions);
56 
58 static const gchar *gnc_plugin_load_ui_items [] =
59 {
60  "EditPlaceholder4",
61  NULL,
62 };
63 
65 {
66  GncPlugin gnc_plugin;
67 };
68 
69 G_DEFINE_TYPE(GncPluginReportSystem, gnc_plugin_report_system, GNC_TYPE_PLUGIN)
70 
71 /************************************************************
72  * Object Implementation *
73  ************************************************************/
74 
75 static void
76 gnc_plugin_report_system_class_init (GncPluginReportSystemClass *klass)
77 {
78  GObjectClass *object_class = G_OBJECT_CLASS (klass);
79  GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass);
80 
81  object_class->finalize = gnc_plugin_report_system_finalize;
82 
83  /* plugin info */
84  plugin_class->plugin_name = GNC_PLUGIN_REPORT_SYSTEM_NAME;
85 
86  /* widget addition/removal */
87  plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
88  plugin_class->actions = gnc_plugin_actions;
89  plugin_class->n_actions = gnc_plugin_n_actions;
90  plugin_class->ui_filename = PLUGIN_UI_FILENAME;
91  plugin_class->ui_updates = gnc_plugin_load_ui_items;
92 }
93 
94 static void
95 gnc_plugin_report_system_init (GncPluginReportSystem *plugin)
96 {
97 }
98 
99 static void
100 gnc_plugin_report_system_finalize (GObject *object)
101 {
102  g_return_if_fail (GNC_IS_PLUGIN_REPORT_SYSTEM (object));
103 
104  G_OBJECT_CLASS (gnc_plugin_report_system_parent_class)->finalize (object);
105 }
106 
107 /************************************************************
108  * Command Callbacks *
109  ************************************************************/
110 
111 static void
112 gnc_plugin_report_system_cmd_edit_style_sheet (GSimpleAction *simple,
113  GVariant *parameter,
114  gpointer user_data)
115 {
116  GncMainWindowActionData *data = user_data;
117  gnc_style_sheet_dialog_open (GTK_WINDOW(data->window));
118 }
119 
120 /************************************************************
121  * Html url and stream handlers *
122  ************************************************************/
123 
124 static gboolean
125 gnc_report_system_file_stream_cb (const char *location, char ** data, int *len)
126 {
127  *len = gncReadFile (location, data);
128  return (*len > 0);
129 }
130 
131 static char *
132 html_sanitize (const char *str)
133 {
134  g_return_val_if_fail (str, NULL);
135  GString *gs = g_string_sized_new (strlen (str));
136  for (const char *c = str; *c; c++)
137  {
138  if (*c == '&')
139  gs = g_string_append (gs, "&amp;");
140  else if (*c == '<')
141  gs = g_string_append (gs, "&lt;");
142  else if (*c == '>')
143  gs = g_string_append (gs, "&gt;");
144  else
145  gs = g_string_append_c (gs, *c);
146  }
147  return g_string_free (gs, FALSE);
148 }
149 
150 static gboolean
151 gnc_report_system_report_stream_cb (const char *location, char ** data, int *len)
152 {
153  gchar *captured_str = NULL;
154  gboolean ok =
155  gnc_run_report_id_string_with_error_handling (location, data,
156  &captured_str);
157 
158  if (!ok)
159  {
160  char *sanitized = html_sanitize (captured_str);
161  *data = g_strdup_printf ("<html><body><h3>%s</h3>"
162  "<p>%s</p><pre>%s</pre></body></html>",
163  _("Report error"),
164  _("An error occurred while running the report."),
165  sanitized);
166 
167  g_free (sanitized);
168  g_free(captured_str);
169 
170  /* Make sure the progress bar is finished, which will also
171  * make the GUI sensitive again. Easier to do this via guile
172  * because otherwise we would need to link against gnome-utils
173  * and a lot more. */
174  scm_c_eval_string("(gnc:report-finished)");
175  }
176 
177  *len = strlen(*data);
178  return ok;
179 }
180 
181 /* TODO: unroll start_editor */
182 static gboolean
183 gnc_report_system_options_url_cb (const char *location, const char *label,
184  gboolean new_window, GNCURLResult *result)
185 {
186  SCM report;
187  int report_id;
188 
189  g_return_val_if_fail (location != NULL, FALSE);
190  g_return_val_if_fail (result != NULL, FALSE);
191 
192  result->load_to_stream = FALSE;
193 
194  /* href="gnc-options:report-id=2676" */
195  if (strncmp ("report-id=", location, 10) == 0)
196  {
197  if (sscanf (location + 10, "%d", &report_id) != 1)
198  {
199  result->error_message =
200  g_strdup_printf (_("Badly formed options URL: %s"), location);
201 
202  return FALSE;
203  }
204 
205  report = gnc_report_find(report_id);
206  if (report == SCM_UNDEFINED ||
207  report == SCM_BOOL_F)
208  {
209  result->error_message =
210  g_strdup_printf (_("Badly-formed report id: %s"), location);
211 
212  return FALSE;
213  }
214 
215  gnc_report_edit_options (report, GTK_WINDOW(result->parent));
216 
217  return TRUE;
218  }
219  else
220  {
221  result->error_message =
222  g_strdup_printf (_("Badly formed options URL: %s"), location);
223 
224  return FALSE;
225  }
226 }
227 
228 static gboolean
229 gnc_report_system_report_url_cb (const char *location, const char *label,
230  gboolean new_window, GNCURLResult *result)
231 {
232  g_return_val_if_fail (location != NULL, FALSE);
233  g_return_val_if_fail (result != NULL, FALSE);
234 
235  /* make a new window if necessary */
236  if (new_window)
237  {
238  char *url;
239 
240  url = gnc_build_url (URL_TYPE_REPORT, location, label);
241  gnc_main_window_open_report_url (url, GNC_MAIN_WINDOW(result->parent));
242  g_free (url);
243 
244  result->load_to_stream = FALSE;
245  }
246  else
247  {
248  result->load_to_stream = TRUE;
249  }
250 
251  return TRUE;
252 }
253 
254 static gboolean
255 gnc_report_system_help_url_cb (const char *location, const char *label,
256  gboolean new_window, GNCURLResult *result)
257 {
258  g_return_val_if_fail (location != NULL, FALSE);
259 
260  if (label && (*label != '\0'))
261  gnc_gnome_help (GTK_WINDOW(result->parent), location, label);
262  else
263  gnc_gnome_help (GTK_WINDOW(result->parent), location, NULL);
264  return TRUE;
265 }
266 
267 
268 /************************************************************
269  * Plugin Bootstrapping *
270  ************************************************************/
271 
272 void
273 gnc_plugin_report_system_new (void)
274 {
275  GncPlugin *plugin;
276 
277  /* Reference the report page plugin to ensure it exists in the gtk
278  * type system. */
279  GNC_TYPE_PLUGIN_PAGE_REPORT;
280 
281  /* Register html handlers */
282  gnc_html_register_stream_handler (URL_TYPE_HELP, gnc_report_system_file_stream_cb);
283  gnc_html_register_stream_handler (URL_TYPE_FILE, gnc_report_system_file_stream_cb);
284  gnc_html_register_stream_handler (URL_TYPE_REPORT, gnc_report_system_report_stream_cb);
285 
286  gnc_html_register_url_handler (URL_TYPE_OPTIONS, gnc_report_system_options_url_cb);
287  gnc_html_register_url_handler (URL_TYPE_REPORT, gnc_report_system_report_url_cb);
288  gnc_html_register_url_handler (URL_TYPE_HELP, gnc_report_system_help_url_cb);
289 
290  scm_c_use_module("gnucash reports");
291  scm_c_use_module("gnucash report-menus");
292  scm_c_eval_string("(gnc:report-menu-setup)");
293 
294  plugin = GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_REPORT_SYSTEM, NULL));
296 }
Plugin management functions for the GnuCash UI.
void gnc_plugin_manager_add_plugin(GncPluginManager *manager, GncPlugin *plugin)
Add a plugin to the list maintained by the plugin manager.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome&#39;s yelp for linux, and open to a given link within a gi...
GncPluginManager * gnc_plugin_manager_get(void)
Retrieve a pointer to the plugin manager.
Gnome specific utility functions.
All type declarations for the whole Gnucash engine.
Utility functions for file access.
#define PLUGIN_ACTIONS_NAME
The label given to the main window for this plugin.
#define PLUGIN_UI_FILENAME
The name of the UI description file for this plugin.
int gncReadFile(const char *filename, char **data)
Reads the contents of a file into a buffer for further processing.
Definition: file-utils.c:61