[glade3] 2010-10-12 Marco Diego Aurélio Mesquita <marcodiegomesquita gmail com>
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade3] 2010-10-12 Marco Diego Aurélio Mesquita <marcodiegomesquita gmail com>
- Date: Tue, 12 Oct 2010 08:47:56 +0000 (UTC)
commit 0b6f713fbbddbc51c556418b3145b6c46a5df23c
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Tue Oct 12 17:49:14 2010 +0900
2010-10-12 Marco Diego Aurélio Mesquita <marcodiegomesquita gmail com>
Implemented preview feature for Glade.
* gladeui/Makefile.am, gladeui/glade-previewer.c: Added program to preview
glade files.
* gladeui/glade-project.[ch]: Implemented glade_project_preview() to spawn a
child preview process, reap it when it dies and close all previews when
project closes.
* src/glade-window.c: Added toolbar button to spawn the preview.
* gladeui/glade-xml-utils.[ch]: Added glade_xml_dump_from_context().
* plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Added actions to preview a widget.
* gladeui/glade-app.[ch]: Added glade_app_get_bin_dir() for resolving of previewer path.
ChangeLog | 19 ++++
gladeui/.gitignore | 2 +
gladeui/Makefile.am | 39 +++++++-
gladeui/glade-app.c | 13 +++
gladeui/glade-app.h | 2 +
gladeui/glade-project.c | 247 ++++++++++++++++++++++++++++++++++++++++++++-
gladeui/glade-project.h | 8 +-
gladeui/glade-xml-utils.c | 16 +++
gladeui/glade-xml-utils.h | 3 +
plugins/gtk+/glade-gtk.c | 10 ++-
plugins/gtk+/gtk+.xml.in | 1 +
src/glade-window.c | 87 ++++++++++++++++-
12 files changed, 436 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 33fad2c..108f2f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2010-10-12 Marco Diego Aurélio Mesquita <marcodiegomesquita gmail com>
+
+ Implemented preview feature for Glade.
+
+ * gladeui/Makefile.am, gladeui/glade-previewer.c: Added program to preview
+ glade files.
+
+ * gladeui/glade-project.[ch]: Implemented glade_project_preview() to spawn a
+ child preview process, reap it when it dies and close all previews when
+ project closes.
+
+ * src/glade-window.c: Added toolbar button to spawn the preview.
+
+ * gladeui/glade-xml-utils.[ch]: Added glade_xml_dump_from_context().
+
+ * plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Added actions to preview a widget.
+
+ * gladeui/glade-app.[ch]: Added glade_app_get_bin_dir() for resolving of previewer path.
+
2010-10-11 Tristan Van Berkom <tristanvb openismus com>
* gladeui/glade-inspector.c: Fixed project leakage at dispose time.
diff --git a/gladeui/.gitignore b/gladeui/.gitignore
index b0093fe..797b4d8 100644
--- a/gladeui/.gitignore
+++ b/gladeui/.gitignore
@@ -1,3 +1,5 @@
/glade-marshallers.c
/glade-marshallers.h
/gladeui.rc
+
+/glade-previewer
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index 3db8f91..df0e4b6 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -1,16 +1,51 @@
+## Previewer
+
+bin_PROGRAMS = glade-previewer
+
+glade_previewer_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -DGLADE_GNOMEHELPDIR="\"$(HELP_DIR)\""
+ $(AM_CPPFLAGS)
+
+glade_previewer_CFLAGS = \
+ $(GTK_CFLAGS) \
+ $(IGE_MAC_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(AM_CFLAGS)
+
+glade_previewer_LDFLAGS = $(AM_LDFLAGS)
+
+glade_previewer_LDADD = $(top_builddir)/gladeui/libgladeui-2.la $(IGE_MAC_LIBS)
+
+glade_previewer_SOURCES = \
+ glade-previewer.c
+
+if NATIVE_WIN32
+glade_previewer_LDADD += glade-win32-res.o
+if !GLADE_UNSTABLE
+glade_previewer_LDFLAGS += -mwindows
+endif
+endif
+
+glade-win32-res.o: glade-previewer.rc
+ $(WINDRES) $< $@
+
+## Rest of the UI ;)
common_defines = \
-DG_LOG_DOMAIN=\"GladeUI\" \
-DGLADE_CATALOGSDIR="\"$(pkgdatadir)/catalogs\""\
-DGLADE_MODULESDIR="\"$(pkglibdir)/modules\"" \
-DGLADE_PIXMAPSDIR="\"$(pkgdatadir)/pixmaps\"" \
- -DGLADE_LOCALEDIR="\"$(datadir)/locale\""
+ -DGLADE_LOCALEDIR="\"$(datadir)/locale\""\
+ -DGLADE_BINDIR="\"$(bindir)\""
lib_LTLIBRARIES = libgladeui-2.la
BUILT_SOURCES = glade-marshallers.c glade-marshallers.h
-EXTRA_DIST = glade-marshallers.list gladeui.rc.in icon-naming-spec.c
+EXTRA_DIST = glade-marshallers.list gladeui.rc.in icon-naming-spec.c glade-previewer.rc.in
# The glade-3 core library
libgladeui_2_la_SOURCES = \
diff --git a/gladeui/glade-app.c b/gladeui/glade-app.c
index 81259b9..363d0ee 100644
--- a/gladeui/glade-app.c
+++ b/gladeui/glade-app.c
@@ -103,6 +103,7 @@ static gchar *catalogs_dir = NULL;
static gchar *modules_dir = NULL;
static gchar *pixmaps_dir = NULL;
static gchar *locale_dir = NULL;
+static gchar *bin_dir = NULL;
static GladeApp *singleton_app = NULL;
static gboolean check_initialised = FALSE;
@@ -199,6 +200,7 @@ glade_app_finalize (GObject *app)
g_free (modules_dir);
g_free (pixmaps_dir);
g_free (locale_dir);
+ g_free (bin_dir);
singleton_app = NULL;
check_initialised = FALSE;
@@ -354,6 +356,15 @@ glade_app_get_locale_dir (void)
return locale_dir;
}
+const gchar *
+glade_app_get_bin_dir (void)
+{
+ glade_init_check ();
+
+ return bin_dir;
+}
+
+
/* build package paths at runtime */
static void
build_package_paths (void)
@@ -374,6 +385,7 @@ build_package_paths (void)
catalogs_dir = g_build_filename (prefix, "share", PACKAGE, "catalogs", NULL);
modules_dir = g_build_filename (prefix, "lib", PACKAGE, "modules", NULL);
locale_dir = g_build_filename (prefix, "share", "locale", NULL);
+ bin_dir = g_build_filename (prefix, "bin", NULL);
g_free (prefix);
#else
@@ -381,6 +393,7 @@ build_package_paths (void)
modules_dir = g_strdup (GLADE_MODULESDIR);
pixmaps_dir = g_strdup (GLADE_PIXMAPSDIR);
locale_dir = g_strdup (GLADE_LOCALEDIR);
+ bin_dir = g_strdup (GLADE_BINDIR);
#endif
}
diff --git a/gladeui/glade-app.h b/gladeui/glade-app.h
index 6892416..b5f2e04 100644
--- a/gladeui/glade-app.h
+++ b/gladeui/glade-app.h
@@ -208,6 +208,8 @@ const gchar *glade_app_get_pixmaps_dir (void) G_GNUC_CONST;
const gchar *glade_app_get_locale_dir (void) G_GNUC_CONST;
+const gchar *glade_app_get_bin_dir (void) G_GNUC_CONST;
+
G_END_DECLS
#endif /* __GLADE_APP_H__ */
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index dd7d162..317bb20 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -74,7 +74,8 @@ enum
PROP_HAS_SELECTION,
PROP_PATH,
PROP_READ_ONLY,
- PROP_FORMAT
+ PROP_FORMAT,
+ PROP_PREVIEWABLE
};
struct _GladeProjectPrivate
@@ -95,6 +96,8 @@ struct _GladeProjectPrivate
* requested
*/
+ gboolean previewable;
+
gint stamp; /* A a random int per instance of project used to stamp/check the
* GtkTreeIter->stamps */
GList *tree; /* List of toplevel Objects in this projects */
@@ -155,6 +158,9 @@ struct _GladeProjectPrivate
GtkWidget *resource_fullpath_radio;
GtkWidget *relative_path_entry;
GtkWidget *full_path_button;
+
+ /* Store preview processes, so we can kill them on close */
+ GHashTable *preview_channels;
};
typedef struct {
@@ -167,6 +173,11 @@ typedef struct {
gchar *filename;
} StockFilePair;
+typedef struct {
+ GIOChannel *channel;
+ guint watch;
+} ChannelWatchPair;
+
static void glade_project_set_target_version (GladeProject *project,
const gchar *catalog,
@@ -362,6 +373,9 @@ glade_project_get_property (GObject *object,
case PROP_FORMAT:
g_value_set_int (value, project->priv->format);
break;
+ case PROP_PREVIEWABLE:
+ g_value_set_boolean (value, project->priv->previewable);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -570,6 +584,70 @@ glade_project_push_undo_impl (GladeProject *project, GladeCommand *cmd)
}
static void
+glade_project_preview_exits (GPid pid, gint status, gpointer data)
+{
+ GladeProject *project = (GladeProject *)data;
+ ChannelWatchPair *channel_watch;
+ GIOChannel *channel;
+ gchar *pidstr = g_strdup_printf ("%d", pid);
+
+ channel_watch = g_hash_table_lookup (project->priv->preview_channels, pidstr);
+ channel = channel_watch->channel;
+ g_io_channel_unref (channel);
+ g_hash_table_remove (project->priv->preview_channels, pidstr);
+
+ g_free (pidstr);
+ g_free (channel_watch);
+}
+
+static void
+glade_project_kill_previews (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ const gchar *quit = "<quit>";
+ GIOChannel *channel;
+ ChannelWatchPair *channel_watch = (ChannelWatchPair *) value;
+ GError *error = NULL;
+ gsize size;
+
+ channel = channel_watch->channel;
+ /* Removing watch, since the child will commit suicide */
+ g_source_remove (channel_watch->watch);
+ g_io_channel_write_chars (channel, quit, strlen (quit), &size, &error);
+
+ if (size != strlen (quit) && error != NULL)
+ {
+ g_printerr ("Error passing quit signal trough pipe: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_io_channel_flush (channel, &error);
+ if (error != NULL)
+ {
+ g_printerr ("Error flushing channel: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_io_channel_shutdown (channel, TRUE, &error);
+ if (error != NULL)
+ {
+ g_printerr ("Error shutting down channel: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_io_channel_unref (channel);
+ g_free (channel_watch);
+}
+
+static void
+glade_project_close_impl (GladeProject *project)
+{
+ g_hash_table_foreach (project->priv->preview_channels, glade_project_kill_previews, project);
+ g_hash_table_unref (project->priv->preview_channels);
+}
+
+static void
glade_project_changed_impl (GladeProject *project,
GladeCommand *command,
gboolean forward)
@@ -612,6 +690,8 @@ glade_project_init (GladeProject *project)
priv->first_modification = NULL;
priv->first_modification_is_na = FALSE;
+ priv->preview_channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ priv->previewable = FALSE;
priv->toplevel_names = glade_name_context_new ();
priv->naming_policy = GLADE_POLICY_PROJECT_WIDE;
@@ -672,9 +752,9 @@ glade_project_class_init (GladeProjectClass *klass)
klass->widget_name_changed = NULL;
klass->selection_changed = NULL;
- klass->close = NULL;
+ klass->close = glade_project_close_impl;
klass->changed = glade_project_changed_impl;
-
+
/**
* GladeProject::add-widget:
* @gladeproject: the #GladeProject which received the signal.
@@ -879,6 +959,16 @@ glade_project_class_init (GladeProjectClass *klass)
GLADE_PROJECT_FORMAT_GTKBUILDER,
G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_PREVIEWABLE,
+ g_param_spec_boolean ("previewable",
+ _("Previewable"),
+ _("Wether the project can be previewed"),
+ FALSE,
+ G_PARAM_READABLE));
+
+
+
g_type_class_add_private (klass, sizeof (GladeProjectPrivate));
}
@@ -1721,6 +1811,118 @@ glade_project_save (GladeProject *project, const gchar *path, GError **error)
return ret > 0;
}
+static GPid
+glade_project_launch_preview (GladeProject *project, gchar *buffer, GtkWidget *widget)
+{
+ GPid pid;
+ GError *error = NULL;
+ gchar *argv[4];
+ gint child_stdin;
+ GIOChannel *output;
+ guint watch;
+ ChannelWatchPair *channel_watch;
+ GladeWidget *glade_widget;
+
+
+ #ifdef WINDOWS
+ argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer.exe", NULL);
+ #else
+ argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer", NULL);
+ #endif
+
+
+ argv[1] = "--listen";
+
+ if (widget != NULL)
+ {
+ glade_widget = glade_widget_get_from_gobject (G_OBJECT (widget));
+ argv[2] = g_strdup_printf ("--toplevel=%s", glade_widget->name);
+ argv[3] = NULL;
+ }
+
+ if (g_spawn_async_with_pipes (NULL,
+ argv,
+ NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
+ &pid, &child_stdin, NULL, NULL, &error) == FALSE)
+ {
+ g_printerr (_("Error launching previewer: %s\n"), error->message);
+ glade_util_ui_message (glade_app_get_window(),
+ GLADE_UI_ERROR, NULL,
+ _("Failed to launch preview: %s.\n"),
+ error->message);
+ g_error_free (error);
+ pid = 0;
+ goto end;
+ }
+
+ /* Store watch so we can remove it later */
+ watch = g_child_watch_add (pid, glade_project_preview_exits, project);
+
+ #ifdef WINDOWS
+ output = g_io_channel_win32_new_fd (child_stdin);
+ #else
+ output = g_io_channel_unix_new (child_stdin);
+ #endif
+
+ gsize bytes_written;
+ g_io_channel_write_chars (output, buffer, strlen (buffer), &bytes_written, &error);
+
+ if (bytes_written != strlen (buffer) && error != NULL)
+ {
+ g_printerr ("Error passing UI trough pipe: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_io_channel_flush (output, &error);
+ if (error != NULL)
+ {
+ g_printerr ("Error flushing UI trough pipe: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (widget != NULL) g_free (argv[2]);
+
+ /* Adding channel to list of channels */
+ channel_watch = g_new (ChannelWatchPair, 1);
+ channel_watch->channel = output;
+ channel_watch->watch = watch;
+ g_hash_table_insert (project->priv->preview_channels, g_strdup_printf("%d", pid),
+ channel_watch);
+
+ end:
+ g_free (argv[0]);
+ return pid;
+}
+
+/**
+ * glade_project_preview:
+ * @project: a #GladeProject
+ * @gwidget: a #GladeWidget
+ *
+ * Creates and displays a preview window holding a snapshot of @gwidget's
+ * toplevel window in @project. Note that the preview window is only a snapshot
+ * of the current state of the project, there is no limit on how many preview
+ * snapshots can be taken.
+ */
+void
+glade_project_preview (GladeProject *project, GladeWidget *gwidget)
+{
+ GladeXmlContext *context;
+ gchar *text;
+ GtkWidget *widget = GTK_WIDGET (gwidget->object);
+
+ g_return_if_fail (GTK_WIDGET (widget));
+ g_return_if_fail (GLADE_IS_PROJECT (project));
+
+ context = glade_project_write (project);
+
+ text = glade_xml_dump_from_context (context);
+
+ glade_project_launch_preview (project, text, widget);
+
+ g_free(text);
+}
+
/*******************************************************************
Verify code here (versioning, incompatability checks)
*******************************************************************/
@@ -2648,6 +2850,34 @@ sort_project_dependancies (GObject *a, GObject *b)
return 1;
}
+static gboolean
+glade_project_has_widget (GladeProject *project)
+{
+ GtkWidget *widget = NULL;
+ const GList *objects;
+
+ objects = glade_project_get_objects (project);
+
+ while (objects != NULL)
+ {
+ if (GTK_IS_WIDGET (objects->data))
+ {
+ widget = GTK_WIDGET(objects->data);
+ break;
+ }
+ objects = objects->next;
+ }
+
+ return widget != NULL;
+}
+
+static void
+glade_project_update_previewable (GladeProject *project)
+{
+ project->priv->previewable = glade_project_has_widget (project);
+ g_object_notify (G_OBJECT (project), "previewable");
+}
+
/**
* glade_project_add_object:
* @project: the #GladeProject the widget is added to
@@ -2742,8 +2972,9 @@ glade_project_add_object (GladeProject *project,
g_list_free (children);
}
- /* Update user visible compatability info */
+ /* Update user visible compatibility info */
glade_project_verify_properties (gwidget);
+ glade_project_update_previewable (project);
g_signal_emit (G_OBJECT (project),
glade_project_signals [ADD_WIDGET],
@@ -2833,6 +3064,8 @@ glade_project_remove_object (GladeProject *project, GObject *object)
gwidget);
gtk_tree_iter_free (iter);
}
+
+ glade_project_update_previewable (project);
}
static void
@@ -3609,6 +3842,12 @@ glade_project_set_naming_policy (GladeProject *project,
}
+gboolean
+glade_project_get_previewable (GladeProject *project)
+{
+ return project->priv->previewable;
+}
+
GladeNamingPolicy
glade_project_get_naming_policy (GladeProject *project)
{
diff --git a/gladeui/glade-project.h b/gladeui/glade-project.h
index ebffbb8..b8cf55b 100644
--- a/gladeui/glade-project.h
+++ b/gladeui/glade-project.h
@@ -95,8 +95,10 @@ GladeProject *glade_project_load (const gchar *path);
gboolean glade_project_save (GladeProject *project,
const gchar *path,
GError **error);
-
-const gchar *glade_project_get_path (GladeProject *project);
+
+void glade_project_preview (GladeProject *project, GladeWidget *gwidget);
+
+const gchar *glade_project_get_path (GladeProject *project);
gchar *glade_project_get_name (GladeProject *project);
@@ -186,6 +188,8 @@ void glade_project_set_instance_count (GladeProject *project, guint
gboolean glade_project_get_modified (GladeProject *project);
+gboolean glade_project_get_previewable (GladeProject *project);
+
void glade_project_set_format (GladeProject *project, GladeProjectFormat format);
GladeProjectFormat glade_project_get_format (GladeProject *project);
diff --git a/gladeui/glade-xml-utils.c b/gladeui/glade-xml-utils.c
index e0bdeb0..c280c8f 100644
--- a/gladeui/glade-xml-utils.c
+++ b/gladeui/glade-xml-utils.c
@@ -758,6 +758,22 @@ glade_xml_context_get_doc (GladeXmlContext *context)
return context->doc;
}
+gchar *
+glade_xml_dump_from_context (GladeXmlContext *context)
+{
+ GladeXmlDoc *doc;
+ xmlChar *string = NULL;
+ gchar *text;
+ int size;
+
+ doc = glade_xml_context_get_doc (context);
+ xmlDocDumpFormatMemory(&(doc->doc), &string, &size, 1);
+
+ text = claim_string (string);
+
+ return text;
+}
+
gboolean
glade_xml_node_is_comment (GladeXmlNode *node_in)
{
diff --git a/gladeui/glade-xml-utils.h b/gladeui/glade-xml-utils.h
index df12ba8..9fda0c8 100644
--- a/gladeui/glade-xml-utils.h
+++ b/gladeui/glade-xml-utils.h
@@ -281,6 +281,9 @@ GladeXmlContext * glade_xml_context_new_from_path (const gchar *full_path,
const gchar *root_name);
GladeXmlDoc * glade_xml_context_get_doc (GladeXmlContext *context);
+/* Dumps an xml string from a context */
+gchar * glade_xml_dump_from_context (GladeXmlContext *context);
+
gboolean glade_xml_load_sym_from_node (GladeXmlNode *node_in,
GModule *module,
gchar *tagname,
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index 3342e3d..2e33c3c 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -1029,13 +1029,21 @@ glade_gtk_widget_action_activate (GladeWidgetAdaptor *adaptor,
GladeWidget *gwidget = glade_widget_get_from_gobject (object), *gparent;
GList this_widget = { 0, }, that_widget = { 0, };
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (object));
+ GladeProject *project;
if (parent)
gparent = glade_widget_get_from_gobject (parent);
else
gparent = NULL;
- if (strcmp (action_path, "edit_separate") == 0)
+ if (strcmp (action_path, "preview") == 0)
+ {
+ project = glade_widget_get_project (gwidget);
+ glade_project_preview (project,
+ glade_widget_get_from_gobject((gpointer)object)
+ );
+ }
+ else if (strcmp (action_path, "edit_separate") == 0)
{
GtkWidget *dialog =
glade_editor_dialog_for_widget (gwidget);
diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in
index 4db98cf..30fdb07 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -30,6 +30,7 @@
</signals>
<actions>
+ <action id="preview" _name="Preview snapshot"/>
<action id="edit_separate" _name="Edit Separately" stock="gtk-edit"/>
<action id="remove_parent" _name="Remove Parent" stock="gtk-remove"/>
<action id="add_parent" _name="Add Parent" stock="gtk-add">
diff --git a/src/glade-window.c b/src/glade-window.c
index f88c55e..2ddfdbc 100644
--- a/src/glade-window.c
+++ b/src/glade-window.c
@@ -33,6 +33,8 @@
#include <gladeui/glade-popup.h>
#include <gladeui/glade-inspector.h>
+#include <gladeui/glade-project.h>
+
#include <string.h>
#include <glib/gstdio.h>
#include <glib/gi18n.h>
@@ -117,6 +119,7 @@ struct _GladeWindowPrivate
gchar *default_path; /* the default path for open/save operations */
GtkToggleToolButton *selector_button; /* the widget selector button (replaces the one in the palette) */
+ GtkToolButton *preview_button; /* the project preview button (replaces the one in the palette) */
GtkToggleToolButton *drag_resize_button; /* sets the pointer to drag/resize mode */
gboolean setting_pointer_mode; /* avoid feedback signal loops */
@@ -782,6 +785,50 @@ on_selector_button_toggled (GtkToggleToolButton *button, GladeWindow *window)
}
static void
+on_preview_button_clicked (GtkToggleToolButton *button, GladeWindow *window)
+{
+ GladeProject *project;
+
+ const GList *objects;
+
+ GtkWidget *widget = NULL;
+ GtkWidget *window_to_preview = NULL;
+ GladeWidget *glade_widget = NULL;
+
+ project = glade_design_view_get_project (window->priv->active_view);
+
+ if (project == NULL)
+ return;
+
+ objects = glade_project_get_objects (project);
+
+ while (objects != NULL)
+ {
+ if (GTK_IS_WIDGET (objects->data))
+ {
+ widget = GTK_WIDGET(objects->data);
+ if (GTK_IS_WINDOW (widget))
+ {
+ window_to_preview = widget;
+ break;
+ }
+ }
+ objects = objects->next;
+ }
+
+ if (widget != NULL)
+ {
+ glade_widget = glade_widget_get_from_gobject (G_OBJECT (widget));
+ }
+
+ if (window_to_preview != NULL) widget = window_to_preview;
+ glade_project_preview (project,
+ glade_widget_get_from_gobject((gpointer)widget)
+ );
+}
+
+
+static void
on_drag_resize_button_toggled (GtkToggleToolButton *button, GladeWindow *window)
{
if (window->priv->setting_pointer_mode)
@@ -2355,6 +2402,24 @@ create_selector_tool_button (GtkToolbar *toolbar)
}
static GtkWidget *
+create_preview_tool_button (GtkToolbar *toolbar)
+{
+ GtkToolItem *button;
+ button = gtk_tool_button_new_from_stock (GTK_STOCK_EXECUTE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON(button), _("Preview snapshot"));
+
+ gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (button),
+ toolbar->tooltips,
+ _("Previews snapshot of project"),
+ NULL);
+
+ gtk_widget_show (GTK_WIDGET (button));
+
+ return GTK_WIDGET (button);
+}
+
+
+static GtkWidget *
create_drag_resize_tool_button (GtkToolbar *toolbar)
{
GtkToolItem *button;
@@ -2466,6 +2531,10 @@ add_project (GladeWindow *window, GladeProject *project)
/* Kick the inspector in the balls here... */
glade_project_selection_changed (project);
+
+ /* Update preview button */
+ gtk_widget_set_sensitive ( GTK_WIDGET (window->priv->preview_button),
+ glade_project_get_previewable (project));
}
void
@@ -2704,9 +2773,15 @@ refresh_undo_redo (GladeWindow *window)
static void
update_ui (GladeApp *app, GladeWindow *window)
-{
+{
+ GladeProject *project;
if (window->priv->active_view)
+ {
+ project = glade_design_view_get_project (window->priv->active_view);
+ gtk_widget_set_sensitive ( GTK_WIDGET (window->priv->preview_button),
+ glade_project_get_previewable (project));
gtk_widget_queue_draw (GTK_WIDGET (window->priv->active_view));
+ }
refresh_undo_redo (window);
@@ -3267,10 +3342,16 @@ glade_window_init (GladeWindow *window)
gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), GTK_TOOL_ITEM (sep), -1);
priv->selector_button =
- GTK_TOGGLE_TOOL_BUTTON (create_selector_tool_button (GTK_TOOLBAR (priv->toolbar)));
+ GTK_TOGGLE_TOOL_BUTTON (create_selector_tool_button (GTK_TOOLBAR (priv->toolbar)));
gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar),
GTK_TOOL_ITEM (priv->selector_button), -1);
+ priv->preview_button =
+ GTK_TOOL_BUTTON (create_preview_tool_button (GTK_TOOLBAR (priv->toolbar)));
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar),
+ GTK_TOOL_ITEM (priv->preview_button), -1);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->preview_button), FALSE);
+
priv->drag_resize_button =
GTK_TOGGLE_TOOL_BUTTON (create_drag_resize_tool_button
(GTK_TOOLBAR (priv->toolbar)));
@@ -3282,6 +3363,8 @@ glade_window_init (GladeWindow *window)
g_signal_connect (G_OBJECT (priv->selector_button), "toggled",
G_CALLBACK (on_selector_button_toggled), window);
+ g_signal_connect (G_OBJECT (priv->preview_button), "clicked",
+ G_CALLBACK (on_preview_button_clicked), window);
g_signal_connect (G_OBJECT (priv->drag_resize_button), "toggled",
G_CALLBACK (on_drag_resize_button_toggled), window);
g_signal_connect (G_OBJECT (glade_app_get()), "notify::pointer-mode",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]