static gboolean print_to_pdf (WebKitWebFrame *frame, GError **err) { GtkPrintOperation *op; GtkPrintOperationResult res; char *path; gboolean rv; path = g_strdup_printf ("%s%c%x.pdf",mu_util_cache_dir(), G_DIR_SEPARATOR, (unsigned)random()); if (!mu_util_create_dir_maybe (mu_util_cache_dir(),0700,FALSE)) { g_warning ("Couldn't create tempdir"); return FALSE; } op = gtk_print_operation_new (); gtk_print_operation_set_export_filename (GTK_PRINT_OPERATION(op), path); res = webkit_web_frame_print_full (frame, op, GTK_PRINT_OPERATION_ACTION_EXPORT, err); g_object_unref (op); rv = (res != GTK_PRINT_OPERATION_RESULT_ERROR); if (rv) g_print ("%s\n", path); g_free (path); return rv; }
static GtkPrintOperationResult print(WebKitWebView *html, GtkPrintOperationAction action) { GtkPrintOperation *operation; GtkPrintOperationResult result; GError *error = NULL; WebKitWebFrame *frame; frame = webkit_web_view_get_main_frame(html); operation = gtk_print_operation_new(); result = webkit_web_frame_print_full(frame, operation, action, &error); g_object_unref(operation); handle_error(&error); return result; }
/** * Prints the current page. * * If printing on WIN32, in order to prevent the font from being tiny, (see bug #591177), * A GtkPrintOperation object needs to be created so that the unit can be set, and then * webkit_web_frame_print_full() needs to be called to use that GtkPrintOperation. On * other platforms (specifically linux - not sure about MacOSX), the version of webkit may * not contain the function webkit_web_frame_print_full(), so webkit_web_frame_print() is * called instead (the font size problem doesn't show up on linux). * * @param self HTML renderer object */ static void impl_webkit_print( GncHtml* self, const gchar* jobname, gboolean export_pdf ) { #if !HAVE(WEBKIT_WEB_FRAME_PRINT_FULL) extern void webkit_web_frame_print( WebKitWebFrame * frame ); #endif gchar *export_filename = NULL; GncHtmlWebkitPrivate* priv; WebKitWebFrame* frame; #if HAVE(WEBKIT_WEB_FRAME_PRINT_FULL) GtkPrintOperation* op = gtk_print_operation_new(); GError* error = NULL; GtkPrintSettings *print_settings; #endif priv = GNC_HTML_WEBKIT_GET_PRIVATE(self); frame = webkit_web_view_get_main_frame( priv->web_view ); #if HAVE(WEBKIT_WEB_FRAME_PRINT_FULL) gnc_print_operation_init( op, jobname ); print_settings = gtk_print_operation_get_print_settings (op); if (!print_settings) { print_settings = gtk_print_settings_new(); gtk_print_operation_set_print_settings(op, print_settings); } #ifdef G_OS_WIN32 gtk_print_operation_set_unit( op, GTK_UNIT_POINTS ); #endif // Make sure to generate a full export filename if (g_str_has_suffix(jobname, ".pdf")) { export_filename = g_strdup(jobname); } else { export_filename = g_strconcat(jobname, ".pdf", NULL); } // Two different modes of operation. Either export to PDF, or run the // normal print dialog if (export_pdf) { GtkWidget *dialog; gint result; gchar *export_dirname = NULL; gchar* basename; // Before we save the PDF file, we always as the user for the export // file name. We will store the chosen directory in the gtk print settings // as well. dialog = gtk_file_chooser_dialog_new (_("Export to PDF File"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); // Does the jobname look like a valid full file path? basename = g_path_get_basename(jobname); if (strcmp(basename, jobname) != 0) { gchar *tmp_basename; gchar *tmp_dirname = g_path_get_dirname(jobname); if (g_file_test(tmp_dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { // Yes, the jobname starts with a directory name that actually // exists. Hence we use this as output directory. export_dirname = tmp_dirname; tmp_dirname = NULL; // As the prefix part of the "jobname" is the directory path, we // need to extract the suffix part for the filename. tmp_basename = g_path_get_basename(export_filename); g_free(export_filename); export_filename = tmp_basename; } g_free(tmp_dirname); } g_free(basename); // Set the output file name from the given jobname gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog), export_filename); // Do we have a stored output directory? if (!export_dirname && gtk_print_settings_has_key(print_settings, GNC_GTK_PRINT_SETTINGS_EXPORT_DIR)) { const char* tmp_dirname = gtk_print_settings_get(print_settings, GNC_GTK_PRINT_SETTINGS_EXPORT_DIR); // Only use the directory subsequently if it exists. if (g_file_test(tmp_dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { export_dirname = g_strdup(tmp_dirname); } } // If we have an already existing directory, propose it now. if (export_dirname) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), export_dirname); } g_free(export_dirname); result = gtk_dialog_run (GTK_DIALOG (dialog)); // Weird. In gtk_dialog_run, the gtk code will run a fstat() on the // proposed new output filename, which of course fails with "file not // found" as this file doesn't exist. It will still show a warning output // in the trace file, though. if (result == GTK_RESPONSE_ACCEPT) { // The user pressed "Ok", so use the file name for the actual file output. gchar *dirname; char *tmp = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); g_free(export_filename); export_filename = tmp; // Store the directory part of the file for later dirname = g_path_get_dirname(export_filename); if (g_file_test(dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { gtk_print_settings_set(print_settings, GNC_GTK_PRINT_SETTINGS_EXPORT_DIR, dirname); } g_free(dirname); } gtk_widget_destroy (dialog); if (result != GTK_RESPONSE_ACCEPT) { // User pressed cancel - no saving of the PDF file here. g_free(export_filename); g_object_unref( op ); return; } // This function expects the full filename including (absolute?) path gtk_print_operation_set_export_filename(op, export_filename); // Run the "Export to PDF" print operation webkit_web_frame_print_full( frame, op, GTK_PRINT_OPERATION_ACTION_EXPORT, &error ); } else { // Also store this export file name as output URI in the settings if (gtk_print_settings_has_key(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI)) { // Get the previous output URI, extract the directory part, and // append the current filename. const gchar *olduri = gtk_print_settings_get(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI); gchar *dirname = g_path_get_dirname(olduri); gchar *newuri = (g_strcmp0(dirname, ".") == 0) ? g_strdup(export_filename) : g_build_filename(dirname, export_filename, NULL); //g_warning("olduri=%s newuri=%s", olduri, newuri); // This function expects the full filename including protocol, path, and name gtk_print_settings_set(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI, newuri); g_free(newuri); g_free(dirname); } else { // No stored output URI from the print settings, so just set our export filename gtk_print_settings_set(print_settings, GTK_PRINT_SETTINGS_OUTPUT_URI, export_filename); } // Run the normal printing dialog webkit_web_frame_print_full( frame, op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error ); } if ( error != NULL ) { GtkWidget* window = gtk_widget_get_toplevel( GTK_WIDGET(priv->web_view) ); GtkWidget* dialog = gtk_message_dialog_new( gtk_widget_is_toplevel(window) ? GTK_WINDOW(window) : NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error->message ); g_error_free( error ); g_signal_connect( dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); gtk_widget_show( dialog ); } // Remember to save the printing settings after this print job gnc_print_operation_save_print_settings(op); g_object_unref( op ); g_free(export_filename); #else webkit_web_frame_print( frame ); #endif }
static gboolean mail_printer_print_timeout_cb (gpointer user_data) { GSimpleAsyncResult *simple; AsyncContext *async_context; GCancellable *cancellable; GtkPrintOperation *print_operation; GtkPrintOperationAction print_action; EMailPrinter *printer; WebKitWebFrame *web_frame; gulong create_custom_widget_handler_id; gulong custom_widget_apply_handler_id; gulong draw_page_handler_id; GError *error = NULL; simple = G_SIMPLE_ASYNC_RESULT (user_data); async_context = g_simple_async_result_get_op_res_gpointer (simple); cancellable = async_context->cancellable; print_action = async_context->print_action; /* Check for cancellation one last time before printing. */ if (g_cancellable_set_error_if_cancelled (cancellable, &error)) goto exit; /* This returns a new reference. */ printer = (EMailPrinter *) g_async_result_get_source_object ( G_ASYNC_RESULT (simple)); print_operation = e_print_operation_new (); gtk_print_operation_set_show_progress (print_operation, TRUE); gtk_print_operation_set_unit (print_operation, GTK_UNIT_PIXEL); if (async_context->print_action == GTK_PRINT_OPERATION_ACTION_EXPORT) { const gchar *export_filename; export_filename = e_mail_printer_get_export_filename (printer); gtk_print_operation_set_export_filename ( print_operation, export_filename); } create_custom_widget_handler_id = g_signal_connect ( print_operation, "create-custom-widget", G_CALLBACK (mail_printer_create_custom_widget_cb), async_context); custom_widget_apply_handler_id = g_signal_connect ( print_operation, "custom-widget-apply", G_CALLBACK (mail_printer_custom_widget_apply_cb), async_context); draw_page_handler_id = g_signal_connect ( print_operation, "draw-page", G_CALLBACK (mail_printer_draw_footer_cb), async_context->cancellable); web_frame = webkit_web_view_get_main_frame (async_context->web_view); async_context->print_result = webkit_web_frame_print_full ( web_frame, print_operation, print_action, &error); /* Sanity check. */ switch (async_context->print_result) { case GTK_PRINT_OPERATION_RESULT_ERROR: if (error == NULL) g_warning ( "WebKit print operation returned " "ERROR result without setting a " "GError"); break; case GTK_PRINT_OPERATION_RESULT_APPLY: if (error != NULL) g_warning ( "WebKit print operation returned " "APPLY result but also set a GError"); break; case GTK_PRINT_OPERATION_RESULT_CANCEL: if (error != NULL) g_warning ( "WebKit print operation returned " "CANCEL result but also set a GError"); break; default: g_warn_if_reached (); } g_signal_handler_disconnect ( print_operation, create_custom_widget_handler_id); g_signal_handler_disconnect ( print_operation, custom_widget_apply_handler_id); g_signal_handler_disconnect ( print_operation, draw_page_handler_id); g_object_unref (print_operation); g_object_unref (printer); exit: if (error != NULL) g_simple_async_result_take_error (simple, error); g_simple_async_result_complete_in_idle (simple); return FALSE; }