38#include <glib/gi18n.h>
39#include <glib/gstdio.h>
49#include <webkit2/webkit2.h>
53#include "gnc-gui-query.h"
56#include "gnc-html-webkit.hpp"
57#include "gnc-html-history.h"
63static void gnc_html_webkit_dispose( GObject* obj );
64static void gnc_html_webkit_finalize( GObject* obj );
66#define GNC_HTML_WEBKIT_GET_PRIVATE(o) (GNC_HTML_WEBKIT(o)->priv)
68#include "gnc-html-webkit-p.hpp"
71static QofLogModule log_module = GNC_MOD_HTML;
74extern GHashTable* gnc_html_object_handlers;
77extern GHashTable* gnc_html_stream_handlers;
80extern GHashTable* gnc_html_url_handlers;
82static char error_404_format[] =
"<html><body><h3>%s</h3><p>%s</body></html>";
83static char error_404_title[] = N_(
"Not found");
84static char error_404_body[] = N_(
"The specified URL could not be loaded.");
86#define BASE_URI_NAME "base-uri"
87#define GNC_PREF_RPT_DFLT_ZOOM "default-zoom"
89static gboolean webkit_decide_policy_cb (WebKitWebView* web_view,
90 WebKitPolicyDecision *decision,
91 WebKitPolicyDecisionType decision_type,
93static void webkit_mouse_target_cb (WebKitWebView* web_view,
94 WebKitHitTestResult *hit,
95 guint modifiers, gpointer data);
96static gboolean webkit_notification_cb (WebKitWebView *web_view,
97 WebKitNotification *note,
99static gboolean webkit_load_failed_cb (WebKitWebView *web_view,
100 WebKitLoadEvent event,
101 gchar *uri, GError *error,
103static void webkit_resource_load_started_cb (WebKitWebView *web_view,
104 WebKitWebResource *resource,
105 WebKitURIRequest *request,
107static gchar* handle_embedded_object(
GncHtmlWebkit* self, gchar* html_str );
108static void impl_webkit_show_url( GncHtml* self, URLType type,
109 const gchar* location,
const gchar* label,
110 gboolean new_window_hint );
111static void impl_webkit_show_data( GncHtml* self,
const gchar* data,
int datalen );
112static void impl_webkit_reload( GncHtml* self, gboolean force_rebuild );
113static void impl_webkit_copy_to_clipboard( GncHtml* self );
114static gboolean impl_webkit_export_to_file( GncHtml* self,
const gchar* filepath );
115static void impl_webkit_print (GncHtml* self,
const gchar* jobname);
116static void impl_webkit_cancel( GncHtml* self );
117static void impl_webkit_set_parent( GncHtml* self, GtkWindow* parent );
118static void impl_webkit_default_zoom_changed(gpointer prefs, gchar *pref, gpointer user_data);
121gnc_html_webkit_webview_new (
void)
123 GtkWidget *view = webkit_web_view_new ();
124 WebKitSettings *webkit_settings =
nullptr;
125 const char *default_font_family =
nullptr;
126 GtkStyleContext *style = gtk_widget_get_style_context (view);
127 GValue val = G_VALUE_INIT;
128 GtkStateFlags state = gtk_style_context_get_state (style);
129 gtk_style_context_get_property (style, GTK_STYLE_PROPERTY_FONT,
132 if (G_VALUE_HOLDS_BOXED (&val))
134 const PangoFontDescription *font =
135 (
const PangoFontDescription*)g_value_get_boxed (&val);
136 default_font_family = pango_font_description_get_family (font);
139 webkit_settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view));
140 g_object_set (G_OBJECT(webkit_settings),
141 "default-charset",
"utf-8",
142 "allow-file-access-from-file-urls", TRUE,
143 "allow-universal-access-from-file-urls", TRUE,
144 "enable-java", FALSE,
145 "enable-page-cache", FALSE,
146 "enable-plugins", FALSE,
147 "enable-site-specific-quirks", FALSE,
148 "enable-xss-auditor", FALSE,
149 "enable-developer-extras", TRUE,
151 if (default_font_family !=
nullptr)
153 g_object_set (G_OBJECT (webkit_settings),
154 "default-font-family", default_font_family,
nullptr);
156 g_value_unset (&val);
165 auto priv = self->priv = new_priv;
166 GNC_HTML(self)->priv = (GncHtmlPrivate*)priv;
168 priv->html_string =
nullptr;
169 priv->web_view = WEBKIT_WEB_VIEW (gnc_html_webkit_webview_new ());
174 GNC_PREF_RPT_DFLT_ZOOM);
175 webkit_web_view_set_zoom_level (priv->web_view, zoom);
178 gtk_container_add( GTK_CONTAINER(priv->base.container),
179 GTK_WIDGET(priv->web_view) );
181 g_object_ref_sink( priv->base.container );
184 g_signal_connect (priv->web_view,
"decide-policy",
185 G_CALLBACK (webkit_decide_policy_cb),
188 g_signal_connect (priv->web_view,
"mouse-target-changed",
189 G_CALLBACK (webkit_mouse_target_cb),
192 g_signal_connect (priv->web_view,
"show-notification",
193 G_CALLBACK (webkit_notification_cb),
196 g_signal_connect (priv->web_view,
"load-failed",
197 G_CALLBACK (webkit_load_failed_cb),
199 g_signal_connect (priv->web_view,
"resource-load-started",
200 G_CALLBACK (webkit_resource_load_started_cb),
203 GNC_PREF_RPT_DFLT_ZOOM,
204 reinterpret_cast<gpointer
>(impl_webkit_default_zoom_changed),
207 LEAVE(
"retval %p", self);
213 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
214 GncHtmlClass* html_class = GNC_HTML_CLASS(klass);
216 gobject_class->dispose = gnc_html_webkit_dispose;
217 gobject_class->finalize = gnc_html_webkit_finalize;
219 html_class->show_url = impl_webkit_show_url;
220 html_class->show_data = impl_webkit_show_data;
221 html_class->reload = impl_webkit_reload;
222 html_class->copy_to_clipboard = impl_webkit_copy_to_clipboard;
223 html_class->export_to_file = impl_webkit_export_to_file;
224 html_class->print = impl_webkit_print;
225 html_class->cancel = impl_webkit_cancel;
226 html_class->set_parent = impl_webkit_set_parent;
230gnc_html_webkit_dispose( GObject* obj )
235 if ( priv->web_view !=
nullptr )
237 gtk_container_remove (GTK_CONTAINER(priv->base.container),
238 GTK_WIDGET(priv->web_view));
240 priv->web_view =
nullptr;
243 if ( priv->html_string !=
nullptr )
245 g_free( priv->html_string );
246 priv->html_string =
nullptr;
250 GNC_PREF_RPT_DFLT_ZOOM,
251 reinterpret_cast<gpointer
>(impl_webkit_default_zoom_changed),
254 G_OBJECT_CLASS(gnc_html_webkit_parent_class)->dispose( obj );
258gnc_html_webkit_finalize( GObject* obj )
262 self->priv =
nullptr;
264 G_OBJECT_CLASS(gnc_html_webkit_parent_class)->finalize( obj );
270extract_base_name(URLType type,
const gchar* path)
272 constexpr gchar machine_rexp[] =
"^(//[^/]*)/*(/.*)?$";
273 constexpr gchar path_rexp[] =
"^/*(.*)/+([^/]*)$";
274 regex_t compiled_m, compiled_p;
275 constexpr size_t MATCH_LEN = 4;
276 regmatch_t match[MATCH_LEN];
277 gchar * machine =
nullptr, * location =
nullptr, * base =
nullptr;
278 gchar * basename =
nullptr;
281 if (!path)
return nullptr;
283 regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
284 regcomp(&compiled_p, path_rexp, REG_EXTENDED);
286 if (!g_strcmp0 (type, URL_TYPE_HTTP) ||
287 !g_strcmp0 (type, URL_TYPE_SECURE) ||
288 !g_strcmp0 (type, URL_TYPE_FTP))
293 if (!regexec(&compiled_m, path, MATCH_LEN, match, 0))
296 if (match[1].rm_so != -1)
298 machine = g_strndup(path + match[1].rm_so,
299 match[1].rm_eo - match[1].rm_so);
302 if (match[2].rm_so != -1)
304 location = g_strndup(path + match[2].rm_so,
305 match[2].rm_eo - match[2].rm_so);
311 location = g_strdup(path);
316 if (!regexec(&compiled_p, location, 4, match, 0))
318 if (match[1].rm_so != -1)
320 base = g_strndup(location + match[1].rm_so,
321 match[1].rm_eo - match[1].rm_so);
326 regfree(&compiled_m);
327 regfree(&compiled_p);
331 if (base && (strlen(base) > 0))
333 basename = g_strconcat(machine,
"/", base,
"/",
nullptr);
337 basename = g_strconcat(machine,
"/",
nullptr);
342 if (base && (strlen(base) > 0))
344 basename = g_strdup(base);
367handle_embedded_object(
GncHtmlWebkit* self, gchar* html_str )
372 gchar* remainder_str = html_str;
374 gchar* end_object_tag;
375 gchar* object_contents;
376 gchar* html_str_start =
nullptr;
377 gchar* html_str_middle;
378 gchar* html_str_result =
nullptr;
379 gchar* classid_start;
385 object_tag = g_strstr_len( remainder_str, -1,
"<object classid=" );
389 classid_start = object_tag + strlen(
"<object classid=" ) + 1;
390 classid_end = g_strstr_len( classid_start, -1,
"\"" );
391 classid_str = g_strndup( classid_start, (classid_end - classid_start) );
393 end_object_tag = g_strstr_len( object_tag, -1,
"</object>" );
394 if ( end_object_tag ==
nullptr )
398 g_free (classid_str);
399 g_free (html_str_result);
400 return g_strdup (html_str);
402 end_object_tag += strlen(
"</object>" );
403 object_contents = g_strndup( object_tag, (end_object_tag - object_tag) );
405 const gpointer p = g_hash_table_lookup( gnc_html_object_handlers, classid_str );
406 h =
reinterpret_cast<GncHTMLObjectCB
>(p);
409 (void)h( GNC_HTML(self), object_contents, &html_str_middle );
413 html_str_middle = g_strdup_printf(
"No handler found for classid \"%s\"", classid_str );
416 html_str_start = html_str_result;
417 new_chunk = g_strndup (remainder_str, (object_tag - remainder_str));
419 html_str_result = g_strconcat (new_chunk, html_str_middle,
nullptr);
421 html_str_result = g_strconcat (html_str_start, new_chunk, html_str_middle,
nullptr);
423 g_free( html_str_start );
425 g_free( html_str_middle );
427 remainder_str = end_object_tag;
428 object_tag = g_strstr_len( remainder_str, -1,
"<object classid=" );
433 html_str_start = html_str_result;
434 html_str_result = g_strconcat (html_str_start, remainder_str,
nullptr);
435 g_free (html_str_start);
438 html_str_result = g_strdup (remainder_str);
440 return html_str_result;
451 const gchar* location,
const gchar* label )
453 gchar* fdata =
nullptr;
457 DEBUG(
"type %s, location %s, label %s", type ? type :
"(null)",
458 location ? location :
"(null)", label ? label :
"(null)");
460 g_return_val_if_fail( self !=
nullptr, FALSE );
462 if ( gnc_html_stream_handlers !=
nullptr )
464 const gpointer p = g_hash_table_lookup( gnc_html_stream_handlers, type );
465 GncHTMLStreamCB stream_handler =
reinterpret_cast<GncHTMLStreamCB
>(p);
466 if ( stream_handler )
468 GncHtml *weak_html = GNC_HTML(self);
470 g_object_add_weak_pointer(G_OBJECT(self),
471 (gpointer*)(&weak_html));
472 bool ok = stream_handler( location, &fdata, &fdata_len );
481 g_object_remove_weak_pointer(G_OBJECT(self),
482 (gpointer*)(&weak_html));
487 fdata = fdata ? fdata : g_strdup(
"" );
493 if ( g_strstr_len( fdata, -1,
"<object classid=" ) !=
nullptr )
495 gchar *new_fdata = handle_embedded_object( self, fdata );
501 if ( priv->html_string !=
nullptr )
503 g_free( priv->html_string );
505 priv->html_string = g_strdup( fdata );
506 impl_webkit_show_data( GNC_HTML(self), fdata, strlen(fdata) );
510 fdata = fdata ? fdata :
511 g_strdup_printf( error_404_format,
512 _(error_404_title),
_(error_404_body) );
513 webkit_web_view_load_html (priv->web_view, fdata,
521 while ( gtk_events_pending() )
523 gtk_main_iteration();
533 if ( !g_strcmp0( type, URL_TYPE_SECURE ) ||
534 !g_strcmp0( type, URL_TYPE_HTTP ) )
537 if ( !g_strcmp0( type, URL_TYPE_SECURE ) )
539 if ( !https_allowed() )
541 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
"%s",
542 _(
"Secure HTTP access is disabled. "
543 "You can enable it in the Network section of "
544 "the Preferences dialog."));
549 if ( !http_allowed() )
551 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
"%s",
552 _(
"Network HTTP access is disabled. "
553 "You can enable it in the Network section of "
554 "the Preferences dialog."));
558 gnc_build_url( type, location, label );
563 PWARN(
"load_to_stream for inappropriate type\n"
565 location ? location :
"(null)",
566 label ? label :
"(null)" );
567 fdata = g_strdup_printf( error_404_format,
568 _(error_404_title),
_(error_404_body) );
569 webkit_web_view_load_html (priv->web_view, fdata, BASE_URI_NAME);
578perform_navigation_policy (WebKitWebView *web_view,
579 WebKitNavigationPolicyDecision *decision,
582 gchar *location =
nullptr, *label =
nullptr;
584 WebKitNavigationAction *action =
585 webkit_navigation_policy_decision_get_navigation_action (decision);
586 if (webkit_navigation_action_get_navigation_type (action) !=
587 WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
589 webkit_policy_decision_use ((WebKitPolicyDecision*)decision);
592 auto req = webkit_navigation_action_get_request (action);
593 const gchar *uri = webkit_uri_request_get_uri (req);
594 const gchar *scheme = gnc_html_parse_url (self, uri, &location, &label);
595 if (strcmp (scheme, URL_TYPE_FILE) != 0)
597 impl_webkit_show_url (self, scheme, location, label, FALSE);
603 webkit_policy_decision_ignore ((WebKitPolicyDecision*)decision);
605 webkit_policy_decision_use ((WebKitPolicyDecision*)decision);
610webkit_decide_policy_cb (WebKitWebView *web_view,
611 WebKitPolicyDecision *decision,
612 WebKitPolicyDecisionType decision_type,
616 if (decision_type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
618 webkit_policy_decision_use (decision);
621 return perform_navigation_policy (
622 web_view, (WebKitNavigationPolicyDecision*) decision,
623 GNC_HTML (user_data));
627webkit_mouse_target_cb (WebKitWebView *web_view, WebKitHitTestResult *hit,
628 guint modifiers, gpointer user_data)
630 if (!webkit_hit_test_result_context_is_link (hit))
634 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE (self);
635 gchar *uri = g_strdup (webkit_hit_test_result_get_link_uri (hit));
636 g_free (priv->base.current_link);
637 priv->base.current_link = uri;
638 if (priv->base.flyover_cb)
640 (priv->base.flyover_cb) (GNC_HTML (self), uri,
641 priv->base.flyover_cb_data);
646webkit_notification_cb (WebKitWebView* web_view, WebKitNotification *note,
650 g_return_val_if_fail (self !=
nullptr, FALSE);
651 g_return_val_if_fail (note !=
nullptr, FALSE);
653 auto top = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (web_view)));
654 auto dialog = gtk_message_dialog_new (top, GTK_DIALOG_MODAL,
655 GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
657 webkit_notification_get_title (note),
658 webkit_notification_get_body (note));
659 gtk_dialog_run (GTK_DIALOG (dialog));
660 gtk_widget_destroy (dialog);
665webkit_load_failed_cb (WebKitWebView *web_view, WebKitLoadEvent event,
666 gchar *uri, GError *error, gpointer user_data)
668 PERR (
"WebKit load of %s failed due to %s\n", uri, error->message);
673webkit_resource_load_failed_cb (WebKitWebResource *resource,
677 WebKitURIResponse *response = webkit_web_resource_get_response (resource);
678 const gchar * uri = webkit_web_resource_get_uri (resource);
679 PERR (
"Load of resource at %s failed with error %s and status code %d.\n",
680 uri, error->message, webkit_uri_response_get_status_code (response));
684webkit_resource_load_finished_cb (WebKitWebResource *resource, gpointer data)
686 DEBUG (
"Load of resource %s completed.\n", webkit_web_resource_get_uri(resource));
690webkit_resource_load_started_cb (WebKitWebView *web_view,
691 WebKitWebResource *resource,
692 WebKitURIRequest *request,
695 DEBUG (
"Load of resource %s begun.\n", webkit_web_resource_get_uri(resource));
696 g_signal_connect (resource,
"failed",
697 G_CALLBACK (webkit_resource_load_failed_cb),
699 g_signal_connect (resource,
"finished",
700 G_CALLBACK (webkit_resource_load_finished_cb),
710gnc_html_open_scm(
GncHtmlWebkit* self,
const gchar * location,
711 const gchar * label,
int newwin )
713 PINFO(
"location='%s'", location ? location :
"(null)");
724impl_webkit_show_data( GncHtml* self,
const gchar* data,
int datalen )
726 constexpr char TEMPLATE_REPORT_FILE_NAME[] =
"gnc-report-XXXXXX.html";
727 g_return_if_fail( self !=
nullptr );
728 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
730 ENTER(
"datalen %d, data %20.20s", datalen, data );
732 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
739 gchar *filename = g_build_filename(g_get_tmp_dir(), TEMPLATE_REPORT_FILE_NAME, (gchar *)
nullptr);
740 int fd = g_mkstemp( filename );
741 impl_webkit_export_to_file( self, filename );
743 gchar *uri = g_strdup_printf(
"file://%s", filename );
745 DEBUG(
"Loading uri '%s'", uri);
746 webkit_web_view_load_uri( priv->web_view, uri );
761impl_webkit_show_url( GncHtml* self, URLType type,
762 const gchar* location,
const gchar* label,
763 gboolean new_window_hint )
765 GncHTMLUrlCB url_handler =
nullptr;
766 bool new_window =
false;
767 bool stream_loaded =
false;
769 g_return_if_fail( self !=
nullptr );
770 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
771 g_return_if_fail( location !=
nullptr );
773 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
776 if ( new_window_hint == 0 )
778 if ( priv->base.urltype_cb )
780 new_window = !((priv->base.urltype_cb)( type ));
790 gnc_html_cancel( GNC_HTML(self) );
793 if ( gnc_html_url_handlers )
795 const gpointer p = g_hash_table_lookup( gnc_html_url_handlers, type );
796 url_handler =
reinterpret_cast<GncHTMLUrlCB
>(p);
803 result.load_to_stream = FALSE;
804 result.url_type = type;
805 result.location =
nullptr;
806 result.label =
nullptr;
807 result.base_type = URL_TYPE_FILE;
808 result.base_location =
nullptr;
809 result.error_message =
nullptr;
810 result.parent = GTK_WINDOW (priv->base.parent);
812 bool ok = url_handler( location, label, new_window, &result );
815 if ( result.error_message )
817 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
"%s", result.error_message );
822 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
_(
"There was an error accessing %s."), location );
825 if ( priv->base.load_cb )
827 priv->base.load_cb( GNC_HTML(self), result.url_type,
828 location, label, priv->base.load_cb_data );
831 else if ( result.load_to_stream )
833 const char *new_location = result.location ? result.location : location;
834 const char *new_label = result.label ? result.label : label;
835 auto hnode = gnc_html_history_node_new( result.url_type, new_location, new_label );
837 gnc_html_history_append( priv->base.history, hnode );
839 g_free( priv->base.base_location );
840 priv->base.base_type = result.base_type;
841 priv->base.base_location =
842 g_strdup( extract_base_name( result.base_type, new_location ) );
843 DEBUG(
"resetting base location to %s",
844 priv->base.base_location ? priv->base.base_location :
"(null)" );
846 stream_loaded = load_to_stream( GNC_HTML_WEBKIT(self),
848 new_location, new_label );
850 if ( stream_loaded && priv->base.load_cb !=
nullptr )
852 priv->base.load_cb( GNC_HTML(self), result.url_type,
853 new_location, new_label, priv->base.load_cb_data );
857 g_free( result.location );
858 g_free( result.label );
859 g_free( result.base_location );
860 g_free( result.error_message );
865 if ( g_strcmp0( type, URL_TYPE_SCHEME ) == 0 )
867 gnc_html_open_scm( GNC_HTML_WEBKIT(self), location, label, new_window );
870 else if ( g_strcmp0( type, URL_TYPE_JUMP ) == 0 )
874 else if ( g_strcmp0( type, URL_TYPE_SECURE ) == 0 ||
875 g_strcmp0( type, URL_TYPE_HTTP ) == 0 ||
876 g_strcmp0( type, URL_TYPE_FILE ) == 0 )
881 if ( g_strcmp0( type, URL_TYPE_SECURE ) == 0 )
883 if ( !https_allowed() )
885 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
"%s",
886 _(
"Secure HTTP access is disabled. "
887 "You can enable it in the Network section of "
888 "the Preferences dialog.") );
893 if ( g_strcmp0( type, URL_TYPE_HTTP ) == 0 )
895 if ( !http_allowed() )
897 gnc_error_dialog (GTK_WINDOW (priv->base.parent),
"%s",
898 _(
"Network HTTP access is disabled. "
899 "You can enable it in the Network section of "
900 "the Preferences dialog.") );
905 priv->base.base_type = type;
907 if ( priv->base.base_location !=
nullptr ) g_free( priv->base.base_location );
908 priv->base.base_location = extract_base_name( type, location );
911 gnc_html_history_append( priv->base.history,
912 gnc_html_history_node_new( type, location, label ) );
913 stream_loaded = load_to_stream( GNC_HTML_WEBKIT(self),
914 type, location, label );
921 PERR(
"URLType %s not supported.", type );
924 if ( stream_loaded && priv->base.load_cb !=
nullptr )
926 (priv->base.load_cb)( GNC_HTML(self), type, location, label, priv->base.load_cb_data );
939impl_webkit_reload( GncHtml* self, gboolean force_rebuild )
941 g_return_if_fail( self !=
nullptr );
942 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
944 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
948 gnc_html_history_node *n = gnc_html_history_get_current( priv->base.history );
950 gnc_html_show_url( self, n->type, n->location, n->label, 0 );
953 webkit_web_view_reload( priv->web_view );
963gnc_html_webkit_new(
void )
noexcept
965 auto self =
static_cast<GncHtmlWebkit*
>(g_object_new( GNC_TYPE_HTML_WEBKIT,
nullptr ));
966 return GNC_HTML(self);
975webkit_cancel_helper(gpointer key, gpointer value, gpointer user_data)
978 g_list_free((GList *)value);
983impl_webkit_cancel( GncHtml* self )
985 g_return_if_fail( self !=
nullptr );
986 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
988 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
990 g_hash_table_foreach_remove( priv->base.request_info, webkit_cancel_helper,
nullptr );
994impl_webkit_copy_to_clipboard( GncHtml* self )
996 g_return_if_fail( self !=
nullptr );
997 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
999 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
1000 webkit_web_view_execute_editing_command (priv->web_view,
1001 WEBKIT_EDITING_COMMAND_COPY);
1012impl_webkit_export_to_file( GncHtml* self,
const char *filepath )
1014 g_return_val_if_fail( self !=
nullptr, FALSE );
1015 g_return_val_if_fail( GNC_IS_HTML_WEBKIT(self), FALSE );
1016 g_return_val_if_fail( filepath !=
nullptr, FALSE );
1018 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
1019 if ( priv->html_string ==
nullptr )
1023 FILE *fh = g_fopen( filepath,
"w" );
1024 if ( fh !=
nullptr )
1026 gint len = strlen( priv->html_string );
1027 gint written = fwrite( priv->html_string, 1, len, fh );
1030 if ( written != len )
1058impl_webkit_print (GncHtml* self,
const gchar* jobname)
1060 g_return_if_fail (self !=
nullptr);
1061 g_return_if_fail (GNC_IS_HTML_WEBKIT (self));
1063 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE (self);
1064 auto op = webkit_print_operation_new (priv->web_view);
1065 gchar *basename = g_path_get_basename(jobname);
1066 auto print_settings = gtk_print_settings_new();
1067 webkit_print_operation_set_print_settings(op, print_settings);
1068 gchar *export_filename = g_strdup(jobname);
1070 gtk_print_settings_set(print_settings,
1071 GTK_PRINT_SETTINGS_OUTPUT_BASENAME,
1073 webkit_print_operation_set_print_settings(op, print_settings);
1075 auto top = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (priv->web_view)));
1076 auto print_response = webkit_print_operation_run_dialog (op, top);
1077 if (print_response == WEBKIT_PRINT_OPERATION_RESPONSE_PRINT)
1080 g_object_unref(print_settings);
1081 print_settings = g_object_ref(webkit_print_operation_get_print_settings(op));
1083 g_free(export_filename);
1084 g_object_unref (op);
1085 g_object_unref (print_settings);
1089impl_webkit_set_parent( GncHtml* self, GtkWindow* parent )
1091 g_return_if_fail( self !=
nullptr );
1092 g_return_if_fail( GNC_IS_HTML_WEBKIT(self) );
1094 auto priv = GNC_HTML_WEBKIT_GET_PRIVATE(self);
1095 priv->base.parent = GTK_WIDGET(parent);
1099impl_webkit_default_zoom_changed(gpointer prefs, gchar *pref, gpointer user_data)
1101 g_return_if_fail(user_data !=
nullptr);
1105 gdouble zoom =
gnc_prefs_get_float (GNC_PREFS_GROUP_GENERAL_REPORT, GNC_PREF_RPT_DFLT_ZOOM);
1106 webkit_web_view_set_zoom_level (priv->web_view, zoom);
Account handling public routines.
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
#define PINFO(format, args...)
Print an informational note.
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.