30 #include <glib/gi18n.h>
31 #include <glib/gstdio.h>
32 #include <sys/types.h>
42 #include <webkit/webkit.h>
45 #include "gnc-gui-query.h"
48 #include "gnc-html-webkit.h"
49 #include "gnc-html-history.h"
54 static
void gnc_html_webkit_dispose( GObject* obj );
55 static
void gnc_html_webkit_finalize( GObject* obj );
59 #define GNC_HTML_WEBKIT_GET_PRIVATE(o) (GNC_HTML_WEBKIT(o)->priv)
61 #include "gnc-html-webkit-p.h"
71 extern GHashTable* gnc_html_object_handlers;
74 extern GHashTable* gnc_html_stream_handlers;
77 extern GHashTable* gnc_html_url_handlers;
79 static char error_404_format[] =
"<html><body><h3>%s</h3><p>%s</body></html>";
80 static char error_404_title[] = N_(
"Not found");
81 static char error_404_body[] = N_(
"The specified URL could not be loaded.");
83 #define BASE_URI_NAME "base-uri"
85 static WebKitNavigationResponse webkit_navigation_requested_cb(
86 WebKitWebView* web_view,
87 WebKitWebFrame* frame,
88 WebKitNetworkRequest* request,
90 static void webkit_on_url_cb( WebKitWebView* web_view, gchar* title, gchar* url,
92 static gchar* handle_embedded_object(
GncHtmlWebkit*
self, gchar* html_str );
94 static void gnc_html_set_base_cb( GtkHTML* gtkhtml,
const gchar* base, gpointer data );
95 static void gnc_html_link_clicked_cb( GtkHTML* html,
const gchar* url, gpointer data );
96 static gboolean gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
100 static int gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
101 gpointer user_data );
103 static void impl_webkit_show_url(
GncHtml*
self, URLType type,
104 const gchar* location,
const gchar* label,
105 gboolean new_window_hint );
106 static void impl_webkit_show_data(
GncHtml*
self,
const gchar* data,
int datalen );
107 static void impl_webkit_reload(
GncHtml*
self );
108 static void impl_webkit_copy_to_clipboard(
GncHtml*
self );
109 static gboolean impl_webkit_export_to_file(
GncHtml*
self,
const gchar* filepath );
110 static void impl_webkit_print(
GncHtml*
self,
const gchar* jobname, gboolean export_pdf );
111 static void impl_webkit_cancel(
GncHtml*
self );
112 static void impl_webkit_set_parent(
GncHtml*
self, GtkWindow* parent );
120 WebKitWebSettings* webkit_settings = NULL;
121 const char* default_font_family = NULL;
124 priv =
self->priv = new_priv;
127 priv->html_string = NULL;
128 priv->web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
131 default_font_family = pango_font_description_get_family( gtk_rc_get_style(GTK_WIDGET(priv->web_view))->font_desc );
134 webkit_settings = webkit_web_view_get_settings (priv->web_view);
135 g_object_set (G_OBJECT(webkit_settings),
"default-encoding",
"utf-8", NULL);
136 if (default_font_family == NULL)
138 PWARN(
"webkit_settings: Cannot get default font family.");
142 g_object_set (G_OBJECT(webkit_settings),
143 "default-font-family", default_font_family,
145 PINFO(
"webkit_settings: Set default font to [%s]", default_font_family);
148 gtk_container_add( GTK_CONTAINER(priv->base.container),
149 GTK_WIDGET(priv->web_view) );
151 g_object_ref_sink( priv->base.container );
154 g_signal_connect( priv->web_view,
"navigation-requested",
155 G_CALLBACK(webkit_navigation_requested_cb),
158 g_signal_connect( priv->web_view,
"hovering-over-link",
159 G_CALLBACK(webkit_on_url_cb),
163 g_signal_connect( priv->html,
"set_base",
164 G_CALLBACK(gnc_html_set_base_cb),
167 g_signal_connect(priv->html,
"link_clicked",
168 G_CALLBACK(gnc_html_link_clicked_cb),
171 g_signal_connect (priv->html,
"object_requested",
172 G_CALLBACK (gnc_html_object_requested_cb),
175 g_signal_connect (priv->html,
"button_press_event",
176 G_CALLBACK (gnc_html_button_press_cb),
179 g_signal_connect (priv->html,
"submit",
180 G_CALLBACK(gnc_html_submit_cb),
184 LEAVE(
"retval %p",
self);
190 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
193 gobject_class->dispose = gnc_html_webkit_dispose;
194 gobject_class->finalize = gnc_html_webkit_finalize;
196 html_class->show_url = impl_webkit_show_url;
197 html_class->show_data = impl_webkit_show_data;
198 html_class->reload = impl_webkit_reload;
199 html_class->copy_to_clipboard = impl_webkit_copy_to_clipboard;
200 html_class->export_to_file = impl_webkit_export_to_file;
201 html_class->print = impl_webkit_print;
202 html_class->cancel = impl_webkit_cancel;
203 html_class->set_parent = impl_webkit_set_parent;
207 gnc_html_webkit_dispose( GObject* obj )
212 if ( priv->web_view != NULL )
214 gtk_container_remove( GTK_CONTAINER(priv->base.container),
215 GTK_WIDGET(priv->web_view) );
216 priv->web_view = NULL;
219 if ( priv->html_string != NULL )
221 g_free( priv->html_string );
222 priv->html_string = NULL;
225 G_OBJECT_CLASS(gnc_html_webkit_parent_class)->dispose( obj );
229 gnc_html_webkit_finalize( GObject* obj )
238 G_OBJECT_CLASS(gnc_html_webkit_parent_class)->finalize( obj );
244 extract_base_name(URLType type,
const gchar* path)
246 gchar machine_rexp[] =
"^(//[^/]*)/*(/.*)?$";
247 gchar path_rexp[] =
"^/*(.*)/+([^/]*)$";
248 regex_t compiled_m, compiled_p;
250 gchar * machine = NULL, * location = NULL, * base = NULL;
251 gchar * basename = NULL;
254 if (!path)
return NULL;
256 regcomp(&compiled_m, machine_rexp, REG_EXTENDED);
257 regcomp(&compiled_p, path_rexp, REG_EXTENDED);
259 if (!g_strcmp0 (type, URL_TYPE_HTTP) ||
260 !g_strcmp0 (type, URL_TYPE_SECURE) ||
261 !g_strcmp0 (type, URL_TYPE_FTP))
266 if (!regexec(&compiled_m, path, 4, match, 0))
269 if (match[1].rm_so != -1)
271 machine = g_strndup(path + match[1].rm_so,
272 match[1].rm_eo - match[1].rm_so);
275 if (match[2].rm_so != -1)
277 location = g_strndup(path + match[2].rm_so,
278 match[2].rm_eo - match[2].rm_so);
285 location = g_strdup(path);
290 if (!regexec(&compiled_p, location, 4, match, 0))
292 if (match[1].rm_so != -1)
294 base = g_strndup(location + match[1].rm_so,
295 match[1].rm_eo - match[1].rm_so);
304 regfree(&compiled_m);
305 regfree(&compiled_p);
309 if (base && (strlen(base) > 0))
311 basename = g_strconcat(machine,
"/", base,
"/", NULL);
315 basename = g_strconcat(machine,
"/", NULL);
320 if (base && (strlen(base) > 0))
322 basename = g_strdup(base);
349 handle_embedded_object(
GncHtmlWebkit*
self, gchar* html_str )
354 gchar* remainder_str = html_str;
356 gchar* end_object_tag;
357 gchar* object_contents;
358 gchar* html_str_start = NULL;
359 gchar* html_str_middle;
360 gchar* html_str_result = NULL;
361 gchar* classid_start;
367 object_tag = g_strstr_len( remainder_str, -1,
"<object classid=" );
371 classid_start = object_tag + strlen(
"<object classid=" ) + 1;
372 classid_end = g_strstr_len( classid_start, -1,
"\"" );
373 classid_str = g_strndup( classid_start, (classid_end - classid_start) );
375 end_object_tag = g_strstr_len( object_tag, -1,
"</object>" );
376 if ( end_object_tag == NULL )
380 g_free (classid_str);
381 g_free (html_str_result);
382 return g_strdup (html_str);
384 end_object_tag += strlen(
"</object>" );
385 object_contents = g_strndup( object_tag, (end_object_tag - object_tag) );
387 h = g_hash_table_lookup( gnc_html_object_handlers, classid_str );
390 (void)h( GNC_HTML(
self), object_contents, &html_str_middle );
394 html_str_middle = g_strdup_printf(
"No handler found for classid \"%s\"", classid_str );
397 html_str_start = html_str_result;
398 new_chunk = g_strndup (remainder_str, (object_tag - remainder_str));
400 html_str_result = g_strconcat (new_chunk, html_str_middle, NULL);
402 html_str_result = g_strconcat (html_str_start, new_chunk, html_str_middle, NULL);
404 g_free( html_str_start );
406 g_free( html_str_middle );
408 remainder_str = end_object_tag;
409 object_tag = g_strstr_len( remainder_str, -1,
"<object classid=" );
414 html_str_start = html_str_result;
415 html_str_result = g_strconcat (html_str_start, remainder_str, NULL);
416 g_free (html_str_start);
419 html_str_result = g_strdup (remainder_str);
421 return html_str_result;
432 const gchar* location,
const gchar* label )
438 DEBUG(
"type %s, location %s, label %s", type ? type :
"(null)",
439 location ? location :
"(null)", label ? label :
"(null)");
441 g_return_if_fail(
self != NULL );
443 if ( gnc_html_stream_handlers != NULL )
445 GncHTMLStreamCB stream_handler;
447 stream_handler = g_hash_table_lookup( gnc_html_stream_handlers, type );
448 if ( stream_handler )
450 gboolean ok = stream_handler( location, &fdata, &fdata_len );
454 fdata = fdata ? fdata : g_strdup(
"" );
458 if ( g_strstr_len( fdata, -1,
"<object classid=" ) != NULL )
461 new_fdata = handle_embedded_object(
self, fdata );
467 if ( priv->html_string != NULL )
469 g_free( priv->html_string );
471 priv->html_string = g_strdup( fdata );
472 impl_webkit_show_data( GNC_HTML(
self), fdata, strlen(fdata) );
477 fdata = fdata ? fdata :
478 g_strdup_printf( error_404_format,
479 _(error_404_title), _(error_404_body) );
480 webkit_web_view_load_html_string( priv->web_view, fdata, BASE_URI_NAME );
487 while ( gtk_events_pending() )
489 gtk_main_iteration();
500 if ( !g_strcmp0( type, URL_TYPE_SECURE ) ||
501 !g_strcmp0( type, URL_TYPE_HTTP ) )
504 if ( !g_strcmp0( type, URL_TYPE_SECURE ) )
506 if ( !https_allowed() )
508 gnc_error_dialog( priv->base.parent,
"%s",
509 _(
"Secure HTTP access is disabled. "
510 "You can enable it in the Network section of "
511 "the Preferences dialog."));
516 if ( !http_allowed() )
518 gnc_error_dialog( priv->base.parent,
"%s",
519 _(
"Network HTTP access is disabled. "
520 "You can enable it in the Network section of "
521 "the Preferences dialog."));
525 gnc_build_url( type, location, label );
531 PWARN(
"load_to_stream for inappropriate type\n"
533 location ? location :
"(null)",
534 label ? label :
"(null)" );
535 fdata = g_strdup_printf( error_404_format,
536 _(error_404_title), _(error_404_body) );
537 webkit_web_view_load_html_string( priv->web_view, fdata, BASE_URI_NAME );
552 gnc_html_link_clicked_cb( GtkHTML* html,
const gchar* url, gpointer data )
555 gchar* location = NULL;
559 DEBUG(
"Clicked %s", url);
560 type = gnc_html_parse_url( GNC_HTML(
self), url, &location, &label );
561 gnc_html_show_url( GNC_HTML(
self), type, location, label, 0 );
572 static WebKitNavigationResponse
573 webkit_navigation_requested_cb( WebKitWebView* web_view, WebKitWebFrame* frame,
574 WebKitNetworkRequest* request,
578 gchar* location = NULL;
581 const gchar* url = webkit_network_request_get_uri( request );
583 ENTER(
"requesting %s", url );
584 if ( strcmp( url, BASE_URI_NAME ) == 0 )
586 LEAVE(
"URI is %s", BASE_URI_NAME);
587 return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
590 type = gnc_html_parse_url( GNC_HTML(
self), url, &location, &label );
591 if ( strcmp( type,
"file" ) == 0 )
593 LEAVE(
"URI type is 'file'");
594 return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
596 gnc_html_show_url( GNC_HTML(
self), type, location, label, 0 );
602 return WEBKIT_NAVIGATION_RESPONSE_IGNORE;
612 gnc_html_object_requested_cb( GtkHTML* html, GtkHTMLEmbedded* eb,
619 if ( !eb || !(eb->classid) || !gnc_html_object_handlers )
return FALSE;
621 h = g_hash_table_lookup( gnc_html_object_handlers, eb->classid );
624 return h( GNC_HTML(
self), eb, data );
638 webkit_on_url_cb( WebKitWebView* web_view, gchar* title, gchar* url, gpointer data )
643 DEBUG(
"Rollover %s", url ? url :
"(null)" );
644 g_free( priv->base.current_link );
645 priv->base.current_link = g_strdup( url );
646 if ( priv->base.flyover_cb )
648 (priv->base.flyover_cb)( GNC_HTML(
self), url, priv->base.flyover_cb_data );
658 gnc_html_set_base_cb( GtkHTML* gtkhtml,
const gchar* base,
664 gchar* location = NULL;
667 DEBUG(
"Setting base location to %s", base );
668 type = gnc_html_parse_url( GNC_HTML(
self), base, &location, &label );
670 g_free( priv->base.base_location );
673 priv->base.base_type = type;
674 priv->base.base_location = location;
685 gnc_html_button_press_cb( GtkWidget* widg, GdkEventButton* event,
691 DEBUG(
"Button Press" );
692 if ( priv->base.button_cb != NULL )
694 (priv->base.button_cb)( GNC_HTML(
self), event, priv->base.button_cb_data );
710 gnc_html_open_scm(
GncHtmlWebkit*
self,
const gchar * location,
711 const gchar * label,
int newwin )
713 PINFO(
"location='%s'", location ? location :
"(null)");
724 impl_webkit_show_data(
GncHtml*
self,
const gchar* data,
int datalen )
727 #if HAVE(WEBKIT_WEB_VIEW_LOAD_URI)
728 #define TEMPLATE_REPORT_FILE_NAME "gnc-report-XXXXXX.html"
734 g_return_if_fail(
self != NULL );
735 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
737 ENTER(
"datalen %d, data %20.20s", datalen, data );
739 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
741 #if HAVE(WEBKIT_WEB_VIEW_LOAD_URI)
747 filename = g_build_filename(g_get_tmp_dir(), TEMPLATE_REPORT_FILE_NAME, (gchar *)NULL);
748 fd = g_mkstemp( filename );
749 impl_webkit_export_to_file(
self, filename );
751 uri = g_strdup_printf(
"file:///%s", filename );
753 DEBUG(
"Loading uri '%s'", uri);
754 webkit_web_view_load_uri( priv->web_view, uri );
757 webkit_web_view_load_html_string( priv->web_view, data, BASE_URI_NAME );
772 impl_webkit_show_url(
GncHtml*
self, URLType type,
773 const gchar* location,
const gchar* label,
774 gboolean new_window_hint )
776 GncHTMLUrlCB url_handler;
780 g_return_if_fail(
self != NULL );
781 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
782 g_return_if_fail( location != NULL );
784 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
787 if ( new_window_hint == 0 )
789 if ( priv->base.urltype_cb )
791 new_window = !((priv->base.urltype_cb)( type ));
805 gnc_html_cancel( GNC_HTML(
self) );
808 if ( gnc_html_url_handlers )
810 url_handler = g_hash_table_lookup( gnc_html_url_handlers, type );
822 result.load_to_stream = FALSE;
823 result.url_type = type;
824 result.location = NULL;
826 result.base_type = URL_TYPE_FILE;
827 result.base_location = NULL;
828 result.error_message = NULL;
830 ok = url_handler( location, label, new_window, &result );
833 if ( result.error_message )
835 gnc_error_dialog( priv->base.parent,
"%s", result.error_message );
840 gnc_error_dialog( priv->base.parent, _(
"There was an error accessing %s."), location );
843 if ( priv->base.load_cb )
845 priv->base.load_cb( GNC_HTML(
self), result.url_type,
846 location, label, priv->base.load_cb_data );
849 else if ( result.load_to_stream )
852 const char *new_location;
853 const char *new_label;
855 new_location = result.location ? result.location : location;
856 new_label = result.label ? result.label : label;
857 hnode = gnc_html_history_node_new( result.url_type, new_location, new_label );
859 gnc_html_history_append( priv->base.history, hnode );
861 g_free( priv->base.base_location );
862 priv->base.base_type = result.base_type;
863 priv->base.base_location =
864 g_strdup( extract_base_name( result.base_type, new_location ) );
865 DEBUG(
"resetting base location to %s",
866 priv->base.base_location ? priv->base.base_location :
"(null)" );
868 load_to_stream( GNC_HTML_WEBKIT(
self), result.url_type,
869 new_location, new_label );
871 if ( priv->base.load_cb != NULL )
873 priv->base.load_cb( GNC_HTML(
self), result.url_type,
874 new_location, new_label, priv->base.load_cb_data );
878 g_free( result.location );
879 g_free( result.label );
880 g_free( result.base_location );
881 g_free( result.error_message );
886 if ( g_strcmp0( type, URL_TYPE_SCHEME ) == 0 )
888 gnc_html_open_scm( GNC_HTML_WEBKIT(
self), location, label, new_window );
891 else if ( g_strcmp0( type, URL_TYPE_JUMP ) == 0 )
895 else if ( g_strcmp0( type, URL_TYPE_SECURE ) == 0 ||
896 g_strcmp0( type, URL_TYPE_HTTP ) == 0 ||
897 g_strcmp0( type, URL_TYPE_FILE ) == 0 )
902 if ( g_strcmp0( type, URL_TYPE_SECURE ) == 0 )
904 if ( !https_allowed() )
906 gnc_error_dialog( priv->base.parent,
"%s",
907 _(
"Secure HTTP access is disabled. "
908 "You can enable it in the Network section of "
909 "the Preferences dialog.") );
914 if ( g_strcmp0( type, URL_TYPE_HTTP ) == 0 )
916 if ( !http_allowed() )
918 gnc_error_dialog( priv->base.parent,
"%s",
919 _(
"Network HTTP access is disabled. "
920 "You can enable it in the Network section of "
921 "the Preferences dialog.") );
926 priv->base.base_type = type;
928 if ( priv->base.base_location != NULL ) g_free( priv->base.base_location );
929 priv->base.base_location = extract_base_name( type, location );
932 gnc_html_history_append( priv->base.history,
933 gnc_html_history_node_new( type, location, label ) );
934 load_to_stream( GNC_HTML_WEBKIT(
self), type, location, label );
942 PERR(
"URLType %s not supported.", type );
945 if ( priv->base.load_cb != NULL )
947 (priv->base.load_cb)( GNC_HTML(
self), type, location, label, priv->base.load_cb_data );
958 impl_webkit_reload(
GncHtml*
self )
963 g_return_if_fail(
self != NULL );
964 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
966 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
967 n = gnc_html_history_get_current( priv->base.history );
970 gnc_html_show_url(
self, n->type, n->location, n->label, 0 );
981 gnc_html_webkit_new(
void )
983 GncHtmlWebkit*
self = g_object_new( GNC_TYPE_HTML_WEBKIT, NULL );
984 return GNC_HTML(
self);
993 webkit_cancel_helper(gpointer key, gpointer value, gpointer user_data)
996 g_list_free((GList *)value);
1001 impl_webkit_cancel(
GncHtml*
self )
1005 g_return_if_fail(
self != NULL );
1006 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
1008 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
1013 g_hash_table_foreach_remove( priv->base.request_info, webkit_cancel_helper, NULL );
1017 impl_webkit_copy_to_clipboard(
GncHtml*
self )
1021 g_return_if_fail(
self != NULL );
1022 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
1024 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
1025 if ( webkit_web_view_can_copy_clipboard( priv->web_view ) )
1027 webkit_web_view_copy_clipboard( priv->web_view );
1039 impl_webkit_export_to_file(
GncHtml*
self,
const char *filepath )
1044 g_return_val_if_fail(
self != NULL, FALSE );
1045 g_return_val_if_fail( GNC_IS_HTML_WEBKIT(
self), FALSE );
1046 g_return_val_if_fail( filepath != NULL, FALSE );
1048 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
1049 if ( priv->html_string == NULL )
1053 fh = g_fopen( filepath,
"w" );
1057 gint len = strlen( priv->html_string );
1059 written = fwrite( priv->html_string, 1, len, fh );
1062 if ( written != len )
1088 impl_webkit_print(
GncHtml*
self,
const gchar* jobname, gboolean export_pdf )
1090 #if !HAVE(WEBKIT_WEB_FRAME_PRINT_FULL)
1091 extern void webkit_web_frame_print( WebKitWebFrame * frame );
1094 gchar *export_filename = NULL;
1096 WebKitWebFrame* frame;
1097 #if HAVE(WEBKIT_WEB_FRAME_PRINT_FULL)
1098 GtkPrintOperation* op = gtk_print_operation_new();
1099 GError* error = NULL;
1100 GtkPrintSettings *print_settings;
1103 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
1104 frame = webkit_web_view_get_main_frame( priv->web_view );
1106 #if HAVE(WEBKIT_WEB_FRAME_PRINT_FULL)
1108 print_settings = gtk_print_operation_get_print_settings (op);
1109 if (!print_settings)
1111 print_settings = gtk_print_settings_new();
1112 gtk_print_operation_set_print_settings(op, print_settings);
1115 gtk_print_operation_set_unit( op, GTK_UNIT_POINTS );
1119 if (g_str_has_suffix(jobname,
".pdf"))
1121 export_filename = g_strdup(jobname);
1125 export_filename = g_strconcat(jobname,
".pdf", NULL);
1134 gchar *export_dirname = NULL;
1140 dialog = gtk_file_chooser_dialog_new (_(
"Export to PDF File"),
1142 GTK_FILE_CHOOSER_ACTION_SAVE,
1143 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1144 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
1146 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
1149 basename = g_path_get_basename(jobname);
1150 if (strcmp(basename, jobname) != 0)
1152 gchar *tmp_basename;
1153 gchar *tmp_dirname = g_path_get_dirname(jobname);
1155 if (g_file_test(tmp_dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
1159 export_dirname = tmp_dirname;
1164 tmp_basename = g_path_get_basename(export_filename);
1165 g_free(export_filename);
1166 export_filename = tmp_basename;
1168 g_free(tmp_dirname);
1173 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog), export_filename);
1178 const char* tmp_dirname = gtk_print_settings_get(print_settings,
1181 if (g_file_test(tmp_dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
1183 export_dirname = g_strdup(tmp_dirname);
1190 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), export_dirname);
1192 g_free(export_dirname);
1194 result = gtk_dialog_run (GTK_DIALOG (dialog));
1200 if (result == GTK_RESPONSE_ACCEPT)
1204 char *tmp = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1205 g_free(export_filename);
1206 export_filename = tmp;
1209 dirname = g_path_get_dirname(export_filename);
1210 if (g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
1216 gtk_widget_destroy (dialog);
1218 if (result != GTK_RESPONSE_ACCEPT)
1221 g_free(export_filename);
1222 g_object_unref( op );
1227 gtk_print_operation_set_export_filename(op, export_filename);
1230 webkit_web_frame_print_full( frame, op, GTK_PRINT_OPERATION_ACTION_EXPORT, &error );
1236 if (gtk_print_settings_has_key(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI))
1240 const gchar *olduri = gtk_print_settings_get(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI);
1241 gchar *dirname = g_path_get_dirname(olduri);
1242 gchar *newuri = (g_strcmp0(dirname,
".") == 0)
1243 ? g_strdup(export_filename)
1244 : g_build_filename(dirname, export_filename, NULL);
1248 gtk_print_settings_set(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI, newuri);
1256 gtk_print_settings_set(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI, export_filename);
1260 webkit_web_frame_print_full( frame, op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error );
1263 if ( error != NULL )
1265 GtkWidget* window = gtk_widget_get_toplevel( GTK_WIDGET(priv->web_view) );
1266 GtkWidget* dialog = gtk_message_dialog_new( gtk_widget_is_toplevel(window) ? GTK_WINDOW(window) : NULL,
1267 GTK_DIALOG_DESTROY_WITH_PARENT,
1270 "%s", error->message );
1271 g_error_free( error );
1273 g_signal_connect( dialog,
"response", G_CALLBACK(gtk_widget_destroy), NULL);
1274 gtk_widget_show( dialog );
1279 g_object_unref( op );
1280 g_free(export_filename);
1283 webkit_web_frame_print( frame );
1288 impl_webkit_set_parent(
GncHtml*
self, GtkWindow* parent )
1292 g_return_if_fail(
self != NULL );
1293 g_return_if_fail( GNC_IS_HTML_WEBKIT(
self) );
1295 priv = GNC_HTML_WEBKIT_GET_PRIVATE(
self);
1296 priv->base.parent = GTK_WIDGET(parent);
#define GNC_GTK_PRINT_SETTINGS_EXPORT_DIR
#define PINFO(format, args...)
#define DEBUG(format, args...)
void gnc_print_operation_save_print_settings(GtkPrintOperation *op)
#define PERR(format, args...)
#define ENTER(format, args...)
#define PWARN(format, args...)
Account handling public routines.
void gnc_print_operation_init(GtkPrintOperation *op, const gchar *jobname)
All type declarations for the whole Gnucash engine.
#define LEAVE(format, args...)
const gchar * QofLogModule