Merge branch 'print-dialog-revision' into 'main'

print dialog: Some API revisions

See merge request GNOME/gtk!6443
This commit is contained in:
Matthias Clasen 2023-10-01 14:01:33 +00:00
commit 6e0ac83d99
5 changed files with 825 additions and 340 deletions

View File

@ -2,10 +2,13 @@
*
* This demo shows how to use GskPath to draw shapes that are (a bit)
* more complex than a rounded rectangle.
*
* It also demonstrates printing to a stream with GtkPrintDialog.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>
#include "paintable.h"
@ -165,6 +168,89 @@ gtk_logo_paintable_new (void)
return GDK_PAINTABLE (self);
}
static cairo_status_t
write_cairo (void *closure,
const unsigned char *data,
unsigned int length)
{
GOutputStream *stream = closure;
gsize written;
GError *error = NULL;
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
{
g_print ("Error writing pdf stream: %s\n", error->message);
g_error_free (error);
return CAIRO_STATUS_WRITE_ERROR;
}
return CAIRO_STATUS_SUCCESS;
}
static void
print_ready (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GOutputStream *stream;
GtkSnapshot *snapshot;
GdkPaintable *paintable;
GskRenderNode *node;
cairo_surface_t *surface;
cairo_t *cr;
stream = gtk_print_dialog_print_finish (dialog, result, &error);
if (stream == NULL)
{
g_print ("Failed to get output stream: %s\n", error->message);
g_error_free (error);
return;
}
snapshot = gtk_snapshot_new ();
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
node = gtk_snapshot_free_to_node (snapshot);
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_destroy (surface);
gsk_render_node_unref (node);
if (!g_output_stream_close (stream, NULL, &error))
{
g_print ("Error from close: %s\n", error->message);
g_error_free (error);
}
g_object_unref (stream);
}
static void
print (GtkButton *button,
gpointer data)
{
GtkWidget *picture = data;
GtkPrintDialog *dialog;
dialog = gtk_print_dialog_new ();
gtk_print_dialog_print (dialog,
GTK_WINDOW (gtk_widget_get_root (picture)),
NULL,
NULL,
print_ready,
picture);
g_object_unref (dialog);
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
@ -172,12 +258,21 @@ do_path_fill (GtkWidget *do_widget)
if (!window)
{
GtkWidget *header, *button, *label;
GtkWidget *picture;
GdkPaintable *paintable;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("Fill and Stroke");
gtk_widget_add_css_class (label, "title");
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();
@ -186,6 +281,8 @@ do_path_fill (GtkWidget *do_widget)
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
gtk_window_set_child (GTK_WINDOW (window), picture);
}

View File

@ -1,8 +1,9 @@
/* Pickers and Launchers
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
*
* The dialogs are mainly intended for use in preference dialogs.
* They allow to select colors, fonts and applications.
* They allow to select colors, fonts and files. There is also a
* print dialog.
*
* The launchers let you open files or URIs in applications that
* can handle them.
@ -168,7 +169,7 @@ print_file (GtkButton *picker)
abort_mission, g_object_ref (cancellable), g_object_unref);
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
gtk_print_dialog_print_file (dialog, parent, file, cancellable, print_file_done, NULL);
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
g_object_unref (cancellable);
g_object_unref (dialog);

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,27 @@
G_BEGIN_DECLS
typedef struct _GtkPrintSetup GtkPrintSetup;
#define GTK_TYPE_PRINT_SETUP (gtk_print_setup_get_type ())
GDK_AVAILABLE_IN_4_14
GType gtk_print_setup_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GtkPrintSetup *gtk_print_setup_ref (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
void gtk_print_setup_unref (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
GtkPrintSettings *
gtk_print_setup_get_print_settings (GtkPrintSetup *setup);
GDK_AVAILABLE_IN_4_14
GtkPageSetup * gtk_print_setup_get_page_setup (GtkPrintSetup *setup);
#define GTK_TYPE_PRINT_DIALOG (gtk_print_dialog_get_type ())
GDK_AVAILABLE_IN_4_14
@ -59,11 +80,11 @@ void gtk_print_dialog_set_modal (GtkPrintDialog *s
gboolean modal);
GDK_AVAILABLE_IN_4_14
GtkPageSetup * gtk_print_dialog_get_default_page_setup (GtkPrintDialog *self);
GtkPageSetup * gtk_print_dialog_get_page_setup (GtkPrintDialog *self);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_set_default_page_setup (GtkPrintDialog *self,
GtkPageSetup *default_page_setup);
void gtk_print_dialog_set_page_setup (GtkPrintDialog *self,
GtkPageSetup *page_setup);
GDK_AVAILABLE_IN_4_14
GtkPrintSettings * gtk_print_dialog_get_print_settings (GtkPrintDialog *self);
@ -73,33 +94,34 @@ void gtk_print_dialog_set_print_settings (GtkPrintDialog *s
GtkPrintSettings *print_settings);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_prepare_print (GtkPrintDialog *self,
void gtk_print_dialog_setup (GtkPrintDialog *self,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
gboolean gtk_print_dialog_prepare_print_finish (GtkPrintDialog *self,
GtkPrintSetup *gtk_print_dialog_setup_finish (GtkPrintDialog *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_print_stream (GtkPrintDialog *self,
void gtk_print_dialog_print (GtkPrintDialog *self,
GtkWindow *parent,
GInputStream *content,
GtkPrintSetup *setup,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDK_AVAILABLE_IN_4_14
gboolean gtk_print_dialog_print_stream_finish (GtkPrintDialog *self,
GOutputStream * gtk_print_dialog_print_finish (GtkPrintDialog *self,
GAsyncResult *result,
GError **error);
GDK_AVAILABLE_IN_4_14
void gtk_print_dialog_print_file (GtkPrintDialog *self,
GtkWindow *parent,
GtkPrintSetup *setup,
GFile *file,
GCancellable *cancellable,
GAsyncReadyCallback callback,

View File

@ -699,8 +699,9 @@ gtk_print_job_send (GtkPrintJob *job,
g_return_if_fail (job->spool_io != NULL);
gtk_print_job_set_status (job, GTK_PRINT_STATUS_SENDING_DATA);
g_io_channel_seek_position (job->spool_io, 0, G_SEEK_SET, NULL);
if (g_io_channel_get_flags (job->spool_io) & G_IO_FLAG_IS_SEEKABLE)
g_io_channel_seek_position (job->spool_io, 0, G_SEEK_SET, NULL);
gtk_print_backend_print_stream (job->backend, job,
job->spool_io,