|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* glade-previewer.c
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Copyright (C) 2013-2016 Juan Pablo Ugarte
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Author: Juan Pablo Ugarte <juanpablougarte@gmail.com>
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is free software; you can redistribute it and/or modify it
|
|
Packit |
1e8aac |
* under the terms of the GNU Lesser General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
1e8aac |
* the License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
1e8aac |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
1e8aac |
* Lesser General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
1e8aac |
* License along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
#include <config.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade-previewer.h"
|
|
Packit |
1e8aac |
#include <glib/gi18n-lib.h>
|
|
Packit |
1e8aac |
#include <glib/gprintf.h>
|
|
Packit |
1e8aac |
#include <cairo-pdf.h>
|
|
Packit |
1e8aac |
#include <cairo-svg.h>
|
|
Packit |
1e8aac |
#include <cairo-ps.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
struct _GladePreviewerPrivate
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *widget; /* Preview widget */
|
|
Packit |
1e8aac |
GList *objects; /* SlideShow objects */
|
|
Packit |
1e8aac |
GtkWidget *dialog; /* Dialog to show messages */
|
|
Packit |
1e8aac |
GtkWidget *textview;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GtkCssProvider *css_provider;
|
|
Packit |
1e8aac |
GFileMonitor *css_monitor;
|
|
Packit |
1e8aac |
gchar *css_file;
|
|
Packit |
1e8aac |
gchar *extension;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean print_handlers;
|
|
Packit |
1e8aac |
};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_DEFINE_TYPE_WITH_PRIVATE (GladePreviewer, glade_previewer, G_TYPE_OBJECT);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_init (GladePreviewer *preview)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv = glade_previewer_get_instance_private (preview);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
preview->priv = priv;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_dispose (GObject *object)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv = GLADE_PREVIEWER (object)->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free (priv->objects);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->objects = NULL;
|
|
Packit |
1e8aac |
priv->dialog = NULL;
|
|
Packit |
1e8aac |
g_clear_object (&priv->css_provider);
|
|
Packit |
1e8aac |
g_clear_object (&priv->css_monitor);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_OBJECT_CLASS (glade_previewer_parent_class)->dispose (object);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_finalize (GObject *object)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv = GLADE_PREVIEWER (object)->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (priv->css_file);
|
|
Packit |
1e8aac |
g_free (priv->extension);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_OBJECT_CLASS (glade_previewer_parent_class)->finalize (object);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
on_widget_key_press_event (GtkWidget *widget,
|
|
Packit |
1e8aac |
GdkEventKey *event,
|
|
Packit |
1e8aac |
GladePreviewer *preview)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv = preview->priv;
|
|
Packit |
1e8aac |
GList *node = NULL;
|
|
Packit |
1e8aac |
GtkStack *stack;
|
|
Packit |
1e8aac |
gchar *extension;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (priv->objects)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
stack = GTK_STACK (gtk_bin_get_child (GTK_BIN (priv->widget)));
|
|
Packit |
1e8aac |
node = g_list_find (priv->objects, gtk_stack_get_visible_child (stack));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
switch (event->keyval)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case GDK_KEY_Page_Up:
|
|
Packit |
1e8aac |
if (node && node->prev)
|
|
Packit |
1e8aac |
gtk_stack_set_visible_child (stack, node->prev->data);
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_Page_Down:
|
|
Packit |
1e8aac |
if (node && node->next)
|
|
Packit |
1e8aac |
gtk_stack_set_visible_child (stack, node->next->data);
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_F5:
|
|
Packit |
1e8aac |
extension = "svg";
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_F6:
|
|
Packit |
1e8aac |
extension = "ps";
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_F7:
|
|
Packit |
1e8aac |
extension = "pdf";
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_F8:
|
|
Packit |
1e8aac |
extension = priv->extension ? priv->extension : "png";
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GDK_KEY_F11:
|
|
Packit |
1e8aac |
if (gdk_window_get_state (gtk_widget_get_window (widget)) & GDK_WINDOW_STATE_FULLSCREEN)
|
|
Packit |
1e8aac |
gtk_window_unfullscreen (GTK_WINDOW (widget));
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
gtk_window_fullscreen (GTK_WINDOW (widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (extension)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *tmp_file = g_strdup_printf ("glade-screenshot-XXXXXX.%s", extension);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_mkstemp (tmp_file);
|
|
Packit |
1e8aac |
glade_previewer_screenshot (preview, FALSE, tmp_file);
|
|
Packit |
1e8aac |
g_free (tmp_file);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_class_init (GladePreviewerClass *klass)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
object_class->dispose = glade_previewer_dispose;
|
|
Packit |
1e8aac |
object_class->finalize = glade_previewer_finalize;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GObject *
|
|
Packit |
1e8aac |
glade_previewer_new (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return g_object_new (GLADE_TYPE_PREVIEWER, NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_present (GladePreviewer *preview)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
gtk_window_present (GTK_WINDOW (preview->priv->widget));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_widget (GladePreviewer *preview, GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
GtkWidget *sw;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (priv->widget)
|
|
Packit |
1e8aac |
gtk_widget_destroy (priv->widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!gtk_widget_is_toplevel (widget))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (window), widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->widget = window;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
priv->widget = widget;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Create dialog to display messages */
|
|
Packit |
1e8aac |
priv->dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
Packit |
1e8aac |
gtk_window_set_default_size (GTK_WINDOW (priv->dialog), 640, 320);
|
|
Packit |
1e8aac |
gtk_window_set_title (GTK_WINDOW (priv->dialog), _("Glade Previewer log"));
|
|
Packit |
1e8aac |
gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (priv->widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->textview = gtk_text_view_new ();
|
|
Packit |
1e8aac |
gtk_widget_show (priv->textview);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
sw = gtk_scrolled_window_new (NULL, NULL);
|
|
Packit |
1e8aac |
gtk_widget_show (sw);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (sw), priv->textview);
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (priv->dialog), sw);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Hide dialog on delete event */
|
|
Packit |
1e8aac |
g_signal_connect (priv->dialog, "delete-event",
|
|
Packit |
1e8aac |
G_CALLBACK (gtk_widget_hide),
|
|
Packit |
1e8aac |
NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Quit on delete event */
|
|
Packit |
1e8aac |
g_signal_connect (priv->widget, "delete-event",
|
|
Packit |
1e8aac |
G_CALLBACK (gtk_main_quit),
|
|
Packit |
1e8aac |
NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Make sure we get press events */
|
|
Packit |
1e8aac |
gtk_widget_add_events (priv->widget, GDK_KEY_PRESS_MASK);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Handle key presses for screenshot feature */
|
|
Packit |
1e8aac |
g_signal_connect_object (priv->widget, "key-press-event",
|
|
Packit |
1e8aac |
G_CALLBACK (on_widget_key_press_event),
|
|
Packit |
1e8aac |
preview, 0);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_message (GladePreviewer *preview,
|
|
Packit |
1e8aac |
GtkMessageType type,
|
|
Packit |
1e8aac |
const gchar *message)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
GtkTextBuffer *buffer;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!priv->textview)
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->textview));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (message)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTextIter iter;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* TODO: use message type to color text */
|
|
Packit |
1e8aac |
gtk_text_buffer_get_start_iter (buffer, &iter);
|
|
Packit |
1e8aac |
gtk_text_buffer_insert (buffer, &iter, "\n", -1);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_text_buffer_get_start_iter (buffer, &iter);
|
|
Packit |
1e8aac |
gtk_text_buffer_insert (buffer, &iter, message, -1);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_window_present (GTK_WINDOW (priv->dialog));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
on_css_monitor_changed (GFileMonitor *monitor,
|
|
Packit |
1e8aac |
GFile *file,
|
|
Packit |
1e8aac |
GFile *other_file,
|
|
Packit |
1e8aac |
GFileMonitorEvent event_type,
|
|
Packit |
1e8aac |
GladePreviewer *preview)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv = preview->priv;
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_css_provider_load_from_file (priv->css_provider, file, &error);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (error)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_previewer_set_message (preview, GTK_MESSAGE_WARNING, error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
glade_previewer_set_message (preview, GTK_MESSAGE_OTHER, NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_css_file (GladePreviewer *preview,
|
|
Packit |
1e8aac |
const gchar *css_file)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
GFile *file;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (priv->css_file);
|
|
Packit |
1e8aac |
g_clear_object (&priv->css_monitor);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->css_file = g_strdup (css_file);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
file = g_file_new_for_path (css_file);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!priv->css_provider)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
priv->css_provider = gtk_css_provider_new ();
|
|
Packit |
1e8aac |
g_object_ref_sink (priv->css_provider);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Set provider for default screen once */
|
|
Packit |
1e8aac |
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
|
Packit |
1e8aac |
GTK_STYLE_PROVIDER (priv->css_provider),
|
|
Packit |
1e8aac |
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->css_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
|
|
Packit |
1e8aac |
if (error)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Cant monitor CSS file %s: %s", css_file, error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_object_ref_sink (priv->css_monitor);
|
|
Packit |
1e8aac |
g_signal_connect (priv->css_monitor, "changed",
|
|
Packit |
1e8aac |
G_CALLBACK (on_css_monitor_changed), preview);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* load CSS */
|
|
Packit |
1e8aac |
gtk_css_provider_load_from_file (priv->css_provider, file, &error);
|
|
Packit |
1e8aac |
if (error)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_previewer_set_message (preview, GTK_MESSAGE_INFO, error->message);
|
|
Packit |
1e8aac |
g_message ("%s CSS parsing failed: %s", css_file, error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_unref (file);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_screenshot_extension (GladePreviewer *preview,
|
|
Packit |
1e8aac |
const gchar *extension)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (priv->extension);
|
|
Packit |
1e8aac |
priv->extension = g_strdup (extension);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
quit_when_idle (gpointer loop)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_main_loop_quit (loop);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return G_SOURCE_REMOVE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
check_for_draw (GdkEvent *event, gpointer loop)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (event->type == GDK_EXPOSE)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_idle_add (quit_when_idle, loop);
|
|
Packit |
1e8aac |
gdk_event_handler_set ((GdkEventFunc) gtk_main_do_event, NULL, NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_main_do_event (event);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Taken from Gtk sources gtk-reftest.c */
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_wait_for_drawing (GdkWindow *window)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GMainLoop *loop;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
loop = g_main_loop_new (NULL, FALSE);
|
|
Packit |
1e8aac |
/* We wait until the widget is drawn for the first time.
|
|
Packit |
1e8aac |
* We can not wait for a GtkWidget::draw event, because that might not
|
|
Packit |
1e8aac |
* happen if the window is fully obscured by windowed child widgets.
|
|
Packit |
1e8aac |
* Alternatively, we could wait for an expose event on widget's window.
|
|
Packit |
1e8aac |
* Both of these are rather hairy, not sure what's best. */
|
|
Packit |
1e8aac |
gdk_event_handler_set (check_for_draw, loop, NULL);
|
|
Packit |
1e8aac |
g_main_loop_run (loop);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* give the WM/server some time to sync. They need it.
|
|
Packit |
1e8aac |
* Also, do use popups instead of toplevls in your tests
|
|
Packit |
1e8aac |
* whenever you can. */
|
|
Packit |
1e8aac |
gdk_display_sync (gdk_window_get_display (window));
|
|
Packit |
1e8aac |
g_timeout_add (500, quit_when_idle, loop);
|
|
Packit |
1e8aac |
g_main_loop_run (loop);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static const gchar *
|
|
Packit |
1e8aac |
glade_previewer_get_extension (const gchar *filename)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *extension;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (filename != NULL, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
extension = g_strrstr (filename,".");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (extension)
|
|
Packit |
1e8aac |
extension++;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!extension)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("%s has no extension!", filename);
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return extension;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_previewer_get_scale (GdkScreen *screen, gdouble *sx, gdouble *sy)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (sx)
|
|
Packit |
1e8aac |
*sx = 72.0 / (gdk_screen_get_width (screen) / (gdk_screen_get_width_mm (screen) * 0.03937008));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (sy)
|
|
Packit |
1e8aac |
*sy = 72.0 / (gdk_screen_get_height (screen) / (gdk_screen_get_height_mm (screen) * 0.03937008));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static cairo_surface_t *
|
|
Packit |
1e8aac |
glade_previewer_surface_from_file (const gchar *filename, gdouble w, gdouble h)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_surface_t *surface;
|
|
Packit |
1e8aac |
const gchar *extension;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
extension = glade_previewer_get_extension (filename);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (extension == NULL)
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_strcmp0 (extension, "svg") == 0)
|
|
Packit |
1e8aac |
#if CAIRO_HAS_SVG_SURFACE
|
|
Packit |
1e8aac |
surface = cairo_svg_surface_create (filename, w, h);
|
|
Packit |
1e8aac |
#else
|
|
Packit |
1e8aac |
g_warning ("PDF not supported by the cairo version used");
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
else if (g_strcmp0 (extension, "ps") == 0)
|
|
Packit |
1e8aac |
#if CAIRO_HAS_PS_SURFACE
|
|
Packit |
1e8aac |
surface = cairo_ps_surface_create (filename, w, h);
|
|
Packit |
1e8aac |
#else
|
|
Packit |
1e8aac |
g_warning ("PS not supported by the cairo version used");
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
else if (g_strcmp0 (extension, "pdf") == 0)
|
|
Packit |
1e8aac |
#if CAIRO_HAS_PDF_SURFACE
|
|
Packit |
1e8aac |
surface = cairo_pdf_surface_create (filename, w, h);
|
|
Packit |
1e8aac |
#else
|
|
Packit |
1e8aac |
g_warning ("PDF not supported by the cairo version used");
|
|
Packit |
1e8aac |
#endif
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
return NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return surface;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_previewer_screenshot:
|
|
Packit |
1e8aac |
* @preview: A GladePreviewer
|
|
Packit |
1e8aac |
* @wait: True if it should wait for widget to draw.
|
|
Packit |
1e8aac |
* @filename: a filename to save the image.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Takes a screenshot of the current widget @window is showing and save it to @filename
|
|
Packit |
1e8aac |
* Supported extension are svg, ps, pdf and wahtever gdk-pixbuf supports
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_screenshot (GladePreviewer *preview,
|
|
Packit |
1e8aac |
gboolean wait,
|
|
Packit |
1e8aac |
const gchar *filename)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
cairo_surface_t *surface;
|
|
Packit |
1e8aac |
GdkWindow *gdkwindow;
|
|
Packit |
1e8aac |
GdkScreen *screen;
|
|
Packit |
1e8aac |
gdouble sx, sy;
|
|
Packit |
1e8aac |
gint w, h;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
g_return_if_fail (filename != NULL);
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!priv->widget)
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gdkwindow = gtk_widget_get_window (priv->widget);
|
|
Packit |
1e8aac |
screen = gdk_window_get_screen (gdkwindow);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (wait)
|
|
Packit |
1e8aac |
glade_previewer_wait_for_drawing (gdkwindow);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
w = gtk_widget_get_allocated_width (priv->widget);
|
|
Packit |
1e8aac |
h = gtk_widget_get_allocated_height (priv->widget);
|
|
Packit |
1e8aac |
glade_previewer_get_scale (screen, &sx, &sy;;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
surface = glade_previewer_surface_from_file (filename, w*sx, h*sy);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (surface)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_t *cr = cairo_create (surface);
|
|
Packit |
1e8aac |
cairo_scale (cr, sx, sy);
|
|
Packit |
1e8aac |
gtk_widget_draw (priv->widget, cr);
|
|
Packit |
1e8aac |
cairo_destroy (cr);
|
|
Packit |
1e8aac |
cairo_surface_destroy(surface);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GdkPixbuf *pix = gdk_pixbuf_get_from_window (gdkwindow, 0, 0, w, h);
|
|
Packit |
1e8aac |
const gchar *ext = glade_previewer_get_extension (filename);
|
|
Packit |
1e8aac |
GError *error = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!gdk_pixbuf_save (pix, filename, ext ? ext : "png", &error, NULL))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_warning ("Could not save screenshot to %s because %s", filename, error->message);
|
|
Packit |
1e8aac |
g_error_free (error);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_unref (pix);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gint
|
|
Packit |
1e8aac |
objects_cmp_func (gconstpointer a, gconstpointer b)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
const gchar *name_a, *name_b;
|
|
Packit |
1e8aac |
name_a = gtk_buildable_get_name (GTK_BUILDABLE (a));
|
|
Packit |
1e8aac |
name_b = gtk_buildable_get_name (GTK_BUILDABLE (b));
|
|
Packit |
1e8aac |
return g_strcmp0 (name_a, name_b);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_previewer_set_slideshow_widgets:
|
|
Packit |
1e8aac |
* @preview: A GladePreviewer
|
|
Packit |
1e8aac |
* @objects: GSlist of GObject
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Add a list of objects to slideshow
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_slideshow_widgets (GladePreviewer *preview,
|
|
Packit |
1e8aac |
GSList *objects)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
GtkStack *stack;
|
|
Packit |
1e8aac |
GSList *l;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
stack = GTK_STACK (gtk_stack_new ());
|
|
Packit |
1e8aac |
gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_CROSSFADE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
objects = g_slist_sort (g_slist_copy (objects), objects_cmp_func);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (l = objects; l; l = g_slist_next (l))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GObject *obj = l->data;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!GTK_IS_WIDGET (obj) || gtk_widget_get_parent (GTK_WIDGET (obj)))
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* TODO: make sure we can add a toplevel inside a stack */
|
|
Packit |
1e8aac |
if (GTK_IS_WINDOW (obj))
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->objects = g_list_prepend (priv->objects, obj);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_stack_add_named (stack, GTK_WIDGET (obj),
|
|
Packit |
1e8aac |
gtk_buildable_get_name (GTK_BUILDABLE (obj)));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->objects = g_list_reverse (priv->objects);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_previewer_set_widget (preview, GTK_WIDGET (stack));
|
|
Packit |
1e8aac |
gtk_widget_show (GTK_WIDGET (stack));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_slist_free (objects);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_previewer_slideshow_save:
|
|
Packit |
1e8aac |
* @preview: A GladePreviewer
|
|
Packit |
1e8aac |
* @filename: a filename to save the slideshow.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Takes a screenshot of every widget GtkStack children and save it to @filename
|
|
Packit |
1e8aac |
* each in a different page
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_slideshow_save (GladePreviewer *preview,
|
|
Packit |
1e8aac |
const gchar *filename)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewerPrivate *priv;
|
|
Packit |
1e8aac |
cairo_surface_t *surface;
|
|
Packit |
1e8aac |
GdkWindow *gdkwindow;
|
|
Packit |
1e8aac |
GtkWidget *child;
|
|
Packit |
1e8aac |
GtkStack *stack;
|
|
Packit |
1e8aac |
gdouble sx, sy;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
g_return_if_fail (filename != NULL);
|
|
Packit |
1e8aac |
priv = preview->priv;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GTK_IS_BIN (priv->widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
child = gtk_bin_get_child (GTK_BIN (priv->widget));
|
|
Packit |
1e8aac |
g_return_if_fail (GTK_IS_STACK (child));
|
|
Packit |
1e8aac |
stack = GTK_STACK (child);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_NONE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gdkwindow = gtk_widget_get_window (priv->widget);
|
|
Packit |
1e8aac |
glade_previewer_wait_for_drawing (gdkwindow);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_previewer_get_scale (gtk_widget_get_screen (GTK_WIDGET (priv->widget)), &sx, &sy;;
|
|
Packit |
1e8aac |
surface = glade_previewer_surface_from_file (filename,
|
|
Packit |
1e8aac |
gtk_widget_get_allocated_width (GTK_WIDGET (stack))*sx,
|
|
Packit |
1e8aac |
gtk_widget_get_allocated_height (GTK_WIDGET (stack))*sy);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (surface)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *l, *children = gtk_container_get_children (GTK_CONTAINER (stack));
|
|
Packit |
1e8aac |
cairo_t *cr= cairo_create (surface);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_scale (cr, sx, sy);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (l = children; l; l = g_list_next (l))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *child = l->data;
|
|
Packit |
1e8aac |
gtk_stack_set_visible_child (stack, child);
|
|
Packit |
1e8aac |
glade_previewer_wait_for_drawing (gdkwindow);
|
|
Packit |
1e8aac |
gtk_widget_draw (child, cr);
|
|
Packit |
1e8aac |
cairo_show_page (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (children)
|
|
Packit |
1e8aac |
gtk_stack_set_visible_child (stack, children->data);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
cairo_destroy (cr);
|
|
Packit |
1e8aac |
cairo_surface_destroy(surface);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
g_warning ("Could not save slideshow to %s", filename);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_previewer_set_print_handlers:
|
|
Packit |
1e8aac |
* @preview: A GladePreviewer
|
|
Packit |
1e8aac |
* @print: whether to print handlers or not
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Set whether to print handlers when they are activated or not.
|
|
Packit |
1e8aac |
* It only works if you use glade_previewer_connect_function() as the
|
|
Packit |
1e8aac |
* connect funtion.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_set_print_handlers (GladePreviewer *preview,
|
|
Packit |
1e8aac |
gboolean print)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (preview));
|
|
Packit |
1e8aac |
preview->priv->print_handlers = print;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef struct
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gchar *handler_name;
|
|
Packit |
1e8aac |
GObject *connect_object;
|
|
Packit |
1e8aac |
GConnectFlags flags;
|
|
Packit |
1e8aac |
} HandlerData;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef struct
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePreviewer *window;
|
|
Packit |
1e8aac |
gint n_invocations;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GSignalQuery query;
|
|
Packit |
1e8aac |
GObject *object;
|
|
Packit |
1e8aac |
GList *handlers;
|
|
Packit |
1e8aac |
} SignalData;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
handler_data_free (gpointer udata)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
HandlerData *hd = udata;
|
|
Packit |
1e8aac |
g_clear_object (&hd->connect_object);
|
|
Packit |
1e8aac |
g_free (hd->handler_name);
|
|
Packit |
1e8aac |
g_free (hd);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
signal_data_free (gpointer udata, GClosure *closure)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
SignalData *data = udata;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free_full (data->handlers, handler_data_free);
|
|
Packit |
1e8aac |
data->handlers = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_clear_object (&data->window);
|
|
Packit |
1e8aac |
g_clear_object (&data->object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (data);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static inline const gchar *
|
|
Packit |
1e8aac |
object_get_name (GObject *object)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (GTK_IS_BUILDABLE (object))
|
|
Packit |
1e8aac |
return gtk_buildable_get_name (GTK_BUILDABLE (object));
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
return g_object_get_data (object, "gtk-builder-name");
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_handler_append (GString *message,
|
|
Packit |
1e8aac |
GSignalQuery *query,
|
|
Packit |
1e8aac |
const gchar *object,
|
|
Packit |
1e8aac |
GList *handlers,
|
|
Packit |
1e8aac |
gboolean after)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *l;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (l = handlers; l; l = g_list_next (l))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
HandlerData *hd = l->data;
|
|
Packit |
1e8aac |
gboolean handler_after = (hd->flags & G_CONNECT_AFTER);
|
|
Packit |
1e8aac |
gboolean swapped = (hd->flags & G_CONNECT_SWAPPED);
|
|
Packit |
1e8aac |
GObject *obj = hd->connect_object;
|
|
Packit |
1e8aac |
gint i;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((after && !handler_after) || (!after && handler_after))
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_append_printf (message, "\n\t-> %s%s %s (%s%s%s",
|
|
Packit |
1e8aac |
g_type_name (query->return_type),
|
|
Packit |
1e8aac |
g_type_is_a (query->return_type, G_TYPE_OBJECT) ? " *" : "",
|
|
Packit |
1e8aac |
hd->handler_name,
|
|
Packit |
1e8aac |
(swapped) ? ((obj) ? G_OBJECT_TYPE_NAME (obj) : "") : g_type_name (query->itype),
|
|
Packit |
1e8aac |
(swapped) ? ((obj) ? " *" : "") : " *",
|
|
Packit |
1e8aac |
(swapped) ? ((obj) ? object_get_name (obj) : _("user_data")) : object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (i = 1; i < query->n_params; i++)
|
|
Packit |
1e8aac |
g_string_append_printf (message, ", %s%s",
|
|
Packit |
1e8aac |
g_type_name (query->param_types[i]),
|
|
Packit |
1e8aac |
g_type_is_a (query->param_types[i], G_TYPE_OBJECT) ? " *" : "");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_append_printf (message, ", %s%s%s); ",
|
|
Packit |
1e8aac |
(swapped) ? g_type_name (query->itype) : ((obj) ? G_OBJECT_TYPE_NAME (obj) : ""),
|
|
Packit |
1e8aac |
(swapped) ? " *" : ((obj) ? " *" : ""),
|
|
Packit |
1e8aac |
(swapped) ? object : ((obj) ? object_get_name (obj) : _("user_data")));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (swapped && after)
|
|
Packit |
1e8aac |
/* translators: GConnectFlags values */
|
|
Packit |
1e8aac |
g_string_append (message, _("Swapped | After"));
|
|
Packit |
1e8aac |
else if (swapped)
|
|
Packit |
1e8aac |
/* translators: GConnectFlags value */
|
|
Packit |
1e8aac |
g_string_append (message, _("Swapped"));
|
|
Packit |
1e8aac |
else if (after)
|
|
Packit |
1e8aac |
/* translators: GConnectFlags value */
|
|
Packit |
1e8aac |
g_string_append (message, _("After"));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static inline void
|
|
Packit |
1e8aac |
glade_handler_method_append (GString *msg, GSignalQuery *q, const gchar *flags)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_string_append_printf (msg, "\n\t%sClass->%s(); %s", g_type_name (q->itype),
|
|
Packit |
1e8aac |
q->signal_name, flags);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
on_handler_called (SignalData *data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GSignalQuery *query = &data->query;
|
|
Packit |
1e8aac |
GObject *object = data->object;
|
|
Packit |
1e8aac |
const gchar *object_name = object_get_name (object);
|
|
Packit |
1e8aac |
GString *message = g_string_new ("");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
data->n_invocations++;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (data->n_invocations == 1)
|
|
Packit |
1e8aac |
/* translators: this will be shown in glade previewer when a signal %s::%s is emited one time */
|
|
Packit |
1e8aac |
g_string_append_printf (message, _("%s::%s emitted one time"),
|
|
Packit |
1e8aac |
G_OBJECT_TYPE_NAME (object), query->signal_name);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
/* translators: this will be shown in glade previewer when a signal %s::%s is emited %d times */
|
|
Packit |
1e8aac |
g_string_append_printf (message, _("%s::%s emitted %d times"),
|
|
Packit |
1e8aac |
G_OBJECT_TYPE_NAME (object), query->signal_name,
|
|
Packit |
1e8aac |
data->n_invocations);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (query->signal_flags & G_SIGNAL_RUN_FIRST)
|
|
Packit |
1e8aac |
glade_handler_method_append (message, query, _("Run First"));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_handler_append (message, query, object_name, data->handlers, FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (query->signal_flags & G_SIGNAL_RUN_LAST)
|
|
Packit |
1e8aac |
glade_handler_method_append (message, query, _("Run Last"));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_handler_append (message, query, object_name, data->handlers, TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (query->signal_flags & G_SIGNAL_RUN_CLEANUP)
|
|
Packit |
1e8aac |
glade_handler_method_append (message, query, _("Run Cleanup"));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_previewer_set_message (data->window, GTK_MESSAGE_INFO, message->str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (data->window->priv->print_handlers)
|
|
Packit |
1e8aac |
g_printf ("\n%s\n", message->str);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_string_free (message, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_previewer_connect_function:
|
|
Packit |
1e8aac |
* @builder:
|
|
Packit |
1e8aac |
* @object:
|
|
Packit |
1e8aac |
* @signal_name:
|
|
Packit |
1e8aac |
* @handler_name:
|
|
Packit |
1e8aac |
* @connect_object:
|
|
Packit |
1e8aac |
* @flags:
|
|
Packit |
1e8aac |
* @window: a #GladePreviewer
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Function that collects every signal handler in @builder and shows them
|
|
Packit |
1e8aac |
* in @window info bar when the callback is activated
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_previewer_connect_function (GtkBuilder *builder,
|
|
Packit |
1e8aac |
GObject *object,
|
|
Packit |
1e8aac |
const gchar *signal_name,
|
|
Packit |
1e8aac |
const gchar *handler_name,
|
|
Packit |
1e8aac |
GObject *connect_object,
|
|
Packit |
1e8aac |
GConnectFlags flags,
|
|
Packit |
1e8aac |
gpointer window)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
SignalData *data;
|
|
Packit |
1e8aac |
HandlerData *hd;
|
|
Packit |
1e8aac |
guint signal_id;
|
|
Packit |
1e8aac |
gchar *key;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PREVIEWER (window));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!(signal_id = g_signal_lookup (signal_name, G_OBJECT_TYPE (object))))
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
key = g_strconcat ("glade-signal-data-", signal_name, NULL);
|
|
Packit |
1e8aac |
data = g_object_get_data (object, key);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
data = g_new0 (SignalData, 1);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
data->window = g_object_ref (window);
|
|
Packit |
1e8aac |
g_signal_query (signal_id, &data->query);
|
|
Packit |
1e8aac |
data->object = g_object_ref (object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_signal_connect_data (object, signal_name,
|
|
Packit |
1e8aac |
G_CALLBACK (on_handler_called),
|
|
Packit |
1e8aac |
data, signal_data_free, G_CONNECT_SWAPPED);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_set_data (object, key, data);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
hd = g_new0 (HandlerData, 1);
|
|
Packit |
1e8aac |
hd->handler_name = g_strdup (handler_name);
|
|
Packit |
1e8aac |
hd->connect_object = connect_object ? g_object_ref (connect_object) : NULL;
|
|
Packit |
1e8aac |
hd->flags = flags;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
data->handlers = g_list_append (data->handlers, hd);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_free (key);
|
|
Packit |
1e8aac |
}
|