[gnome-builder] libide/editor: add print support back



commit 71bfd58a805aaa583da9860c6adcbed8d16500ea
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jul 28 11:09:37 2022 -0700

    libide/editor: add print support back

 src/libide/editor/ide-editor-page.c            |  79 ++++++++++
 src/libide/editor/ide-editor-print-operation.c | 210 +++++++++++++++++++++++++
 src/libide/editor/ide-editor-print-operation.h |  33 ++++
 src/libide/editor/meson.build                  |   4 +-
 4 files changed, 325 insertions(+), 1 deletion(-)
---
diff --git a/src/libide/editor/ide-editor-page.c b/src/libide/editor/ide-editor-page.c
index dab4bcdf7..e56340de5 100644
--- a/src/libide/editor/ide-editor-page.c
+++ b/src/libide/editor/ide-editor-page.c
@@ -29,6 +29,7 @@
 
 #include "ide-editor-page-addin.h"
 #include "ide-editor-page-private.h"
+#include "ide-editor-print-operation.h"
 #include "ide-editor-save-delegate.h"
 
 enum {
@@ -372,6 +373,83 @@ search_begin_replace_action (GtkWidget  *widget,
   set_search_visible (IDE_EDITOR_PAGE (widget), TRUE, IDE_EDITOR_SEARCH_BAR_MODE_REPLACE);
 }
 
+static void
+handle_print_result (IdeEditorPage           *self,
+                     GtkPrintOperation       *operation,
+                     GtkPrintOperationResult  result)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_EDITOR_PAGE (self));
+  g_assert (GTK_IS_PRINT_OPERATION (operation));
+
+  if (result == GTK_PRINT_OPERATION_RESULT_ERROR)
+    {
+      g_autoptr(GError) error = NULL;
+
+      gtk_print_operation_get_error (operation, &error);
+
+      g_warning ("%s", error->message);
+      ide_page_report_error (IDE_PAGE (self),
+                             /* translators: %s is the error message */
+                             _("Print failed: %s"), error->message);
+    }
+
+  IDE_EXIT;
+}
+
+static void
+print_done (GtkPrintOperation       *operation,
+            GtkPrintOperationResult  result,
+            gpointer                 user_data)
+{
+  IdeEditorPage *self = user_data;
+
+  IDE_ENTRY;
+
+  g_assert (GTK_IS_PRINT_OPERATION (operation));
+  g_assert (IDE_IS_EDITOR_PAGE (self));
+
+  handle_print_result (self, operation, result);
+
+  g_object_unref (operation);
+  g_object_unref (self);
+
+  IDE_EXIT;
+}
+
+static void
+print_action (GtkWidget  *widget,
+              const char *action_name,
+              GVariant   *param)
+{
+  IdeEditorPage *self = (IdeEditorPage *)widget;
+  g_autoptr(IdeEditorPrintOperation) operation = NULL;
+  GtkPrintOperationResult result;
+  IdeSourceView *view;
+  GtkRoot *root;
+
+  g_assert (IDE_IS_EDITOR_PAGE (self));
+
+  root = gtk_widget_get_root (GTK_WIDGET (self));
+  view = ide_editor_page_get_view (self);
+  operation = ide_editor_print_operation_new (view);
+
+  /* keep a ref until "done" is emitted */
+  g_object_ref (operation);
+  g_signal_connect_after (g_object_ref (operation),
+                          "done",
+                          G_CALLBACK (print_done),
+                          g_object_ref (self));
+
+  result = gtk_print_operation_run (GTK_PRINT_OPERATION (operation),
+                                    GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+                                    GTK_WINDOW (root),
+                                    NULL);
+
+  handle_print_result (self, GTK_PRINT_OPERATION (operation), result);
+}
+
 static void
 ide_editor_page_constructed (GObject *object)
 {
@@ -526,6 +604,7 @@ ide_editor_page_class_init (IdeEditorPageClass *klass)
   panel_widget_class_install_action (panel_widget_class, "search.hide", NULL, search_hide_action);
   panel_widget_class_install_action (panel_widget_class, "search.begin-find", NULL, 
search_begin_find_action);
   panel_widget_class_install_action (panel_widget_class, "search.begin-replace", NULL, 
search_begin_replace_action);
+  panel_widget_class_install_action (panel_widget_class, "print", NULL, print_action);
 
   g_type_ensure (IDE_TYPE_EDITOR_SEARCH_BAR);
 }
diff --git a/src/libide/editor/ide-editor-print-operation.c b/src/libide/editor/ide-editor-print-operation.c
new file mode 100644
index 000000000..d25253934
--- /dev/null
+++ b/src/libide/editor/ide-editor-print-operation.c
@@ -0,0 +1,210 @@
+/* ide-editor-print-operation.c
+ *
+ * Copyright 2015 Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-editor-print-operation"
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtksourceview/gtksource.h>
+
+#include "ide-editor-print-operation.h"
+#include "ide-editor-page.h"
+
+struct _IdeEditorPrintOperation
+{
+  GtkPrintOperation         parent_instance;
+
+  IdeSourceView            *view;
+  GtkSourcePrintCompositor *compositor;
+};
+
+G_DEFINE_FINAL_TYPE (IdeEditorPrintOperation, ide_editor_print_operation, GTK_TYPE_PRINT_OPERATION)
+
+enum {
+  PROP_0,
+  PROP_VIEW,
+  LAST_PROP
+};
+
+static GParamSpec *properties [LAST_PROP];
+
+static void
+ide_editor_print_operation_dispose (GObject *object)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (object);
+
+  g_clear_object (&self->compositor);
+
+  G_OBJECT_CLASS (ide_editor_print_operation_parent_class)->dispose (object);
+}
+
+static void
+ide_editor_view_print_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_VIEW:
+      g_value_set_object (value, self->view);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_editor_view_print_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_VIEW:
+      self->view = g_value_get_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_editor_print_operation_begin_print (GtkPrintOperation *operation,
+                                       GtkPrintContext   *context)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (operation);
+  GtkSourceBuffer *buffer;
+  guint tab_width;
+  gboolean syntax_hl;
+
+  buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view)));
+
+  tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (self->view));
+  syntax_hl = gtk_source_buffer_get_highlight_syntax (buffer);
+
+  self->compositor = GTK_SOURCE_PRINT_COMPOSITOR (
+    g_object_new (GTK_SOURCE_TYPE_PRINT_COMPOSITOR,
+                  "buffer", buffer,
+                  "tab-width", tab_width,
+                  "highlight-syntax", syntax_hl,
+                  NULL));
+}
+
+static gboolean
+ide_editor_print_operation_paginate (GtkPrintOperation *operation,
+                                     GtkPrintContext   *context)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (operation);
+  gboolean finished;
+
+  finished = gtk_source_print_compositor_paginate (self->compositor, context);
+
+  if (finished)
+    {
+      gint n_pages;
+
+      n_pages = gtk_source_print_compositor_get_n_pages (self->compositor);
+      gtk_print_operation_set_n_pages (operation, n_pages);
+    }
+
+  return finished;
+}
+
+static void
+ide_editor_print_operation_draw_page (GtkPrintOperation *operation,
+                                      GtkPrintContext   *context,
+                                      gint               page_nr)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (operation);
+
+  gtk_source_print_compositor_draw_page (self->compositor, context, page_nr);
+}
+
+static void
+ide_editor_print_operation_end_print (GtkPrintOperation *operation,
+                                      GtkPrintContext   *context)
+{
+  IdeEditorPrintOperation *self = IDE_EDITOR_PRINT_OPERATION (operation);
+
+  g_clear_object (&self->compositor);
+}
+
+static void
+ide_editor_print_operation_class_init (IdeEditorPrintOperationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkPrintOperationClass *operation_class = GTK_PRINT_OPERATION_CLASS (klass);
+
+  object_class->dispose = ide_editor_print_operation_dispose;
+  object_class->get_property = ide_editor_view_print_get_property;
+  object_class->set_property = ide_editor_view_print_set_property;
+
+  operation_class->begin_print = ide_editor_print_operation_begin_print;
+  operation_class->draw_page = ide_editor_print_operation_draw_page;
+  operation_class->end_print = ide_editor_print_operation_end_print;
+
+  properties [PROP_VIEW] =
+    g_param_spec_object ("view",
+                         "View",
+                         "The source view.",
+                         IDE_TYPE_SOURCE_VIEW,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
+
+static gboolean
+paginate_cb (GtkPrintOperation *operation,
+             GtkPrintContext   *context,
+             gpointer           user_data)
+{
+  return ide_editor_print_operation_paginate (operation, context);
+}
+
+static void
+ide_editor_print_operation_init (IdeEditorPrintOperation *self)
+{
+  /* FIXME: gtk decides to call paginate only if it sees a pending signal
+   * handler, even if we override the default handler.
+   * So for now we connect to the signal instead of overriding the vfunc
+   * See https://bugzilla.gnome.org/show_bug.cgi?id=345345
+   */
+  g_signal_connect (self, "paginate", G_CALLBACK (paginate_cb), NULL);
+}
+
+IdeEditorPrintOperation *
+ide_editor_print_operation_new (IdeSourceView *view)
+{
+  g_assert (IDE_IS_SOURCE_VIEW (view));
+
+  return g_object_new (IDE_TYPE_EDITOR_PRINT_OPERATION,
+                       "view", view,
+                       "allow-async", TRUE,
+                       NULL);
+}
diff --git a/src/libide/editor/ide-editor-print-operation.h b/src/libide/editor/ide-editor-print-operation.h
new file mode 100644
index 000000000..3e95e8388
--- /dev/null
+++ b/src/libide/editor/ide-editor-print-operation.h
@@ -0,0 +1,33 @@
+/* ide-editor-print-operation.h
+ *
+ * Copyright 2015 Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ide-editor-page.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_PRINT_OPERATION (ide_editor_print_operation_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeEditorPrintOperation, ide_editor_print_operation, IDE, EDITOR_PRINT_OPERATION, 
GtkPrintOperation)
+
+IdeEditorPrintOperation *ide_editor_print_operation_new (IdeSourceView *view);
+
+G_END_DECLS
diff --git a/src/libide/editor/meson.build b/src/libide/editor/meson.build
index f0f1959a0..d4487cfa6 100644
--- a/src/libide/editor/meson.build
+++ b/src/libide/editor/meson.build
@@ -20,8 +20,9 @@ libide_editor_public_headers = [
 ]
 
 libide_editor_private_headers = [
-  'ide-editor-save-delegate.h',
   'ide-editor-page-private.h',
+  'ide-editor-print-operation.h',
+  'ide-editor-save-delegate.h',
 ]
 
 install_headers(libide_editor_public_headers, subdir: libide_editor_header_subdir)
@@ -42,6 +43,7 @@ libide_editor_public_sources = [
 libide_editor_private_sources = [
   'ide-editor-init.c',
   'ide-editor-page-settings.c',
+  'ide-editor-print-operation.c',
   'ide-editor-save-delegate.c',
   'ide-editor-search-bar.c',
 ]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]