501 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			501 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2013 Intel Corporation
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
						|
 * copy of this software and associated documentation files (the "Software"),
 | 
						|
 * to deal in the Software without restriction, including without limitation
 | 
						|
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
						|
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
						|
 * Software is furnished to do so, subject to the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice shall be included
 | 
						|
 * in all copies or substantial portions of the Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
						|
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
						|
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
						|
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
						|
 * THE SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
#include <glib/gi18n-lib.h>
 | 
						|
 | 
						|
#include "css-editor.h"
 | 
						|
 | 
						|
#include "gtkcssprovider.h"
 | 
						|
#include "gtkstyleprovider.h"
 | 
						|
#include "gtkstylecontext.h"
 | 
						|
#include "gtktextview.h"
 | 
						|
#include "gtkmessagedialog.h"
 | 
						|
#include "gtkfilechooserdialog.h"
 | 
						|
#include "gtktoggletoolbutton.h"
 | 
						|
 | 
						|
#define GTK_INSPECTOR_CSS_EDITOR_TEXT "inspector-css-editor-text"
 | 
						|
#define GTK_INSPECTOR_CSS_EDITOR_PROVIDER "inspector-css-editor-provider"
 | 
						|
 | 
						|
enum
 | 
						|
{
 | 
						|
  COLUMN_ENABLED,
 | 
						|
  COLUMN_NAME,
 | 
						|
  COLUMN_USER
 | 
						|
};
 | 
						|
 | 
						|
enum
 | 
						|
{
 | 
						|
  PROP_0,
 | 
						|
  PROP_GLOBAL
 | 
						|
};
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  gboolean enabled;
 | 
						|
  gboolean user;
 | 
						|
} GtkInspectorCssEditorByContext;
 | 
						|
 | 
						|
struct _GtkInspectorCssEditorPrivate
 | 
						|
{
 | 
						|
  GtkWidget *toolbar;
 | 
						|
  GtkWidget *view;
 | 
						|
  GtkTextBuffer *text;
 | 
						|
  GtkCssProvider *provider;
 | 
						|
  gboolean global;
 | 
						|
  GtkStyleContext *context;
 | 
						|
  GtkToggleToolButton *disable_button;
 | 
						|
  guint timeout;
 | 
						|
};
 | 
						|
 | 
						|
static void gtk_inspector_css_editor_remove_dead_object (gpointer  data,
 | 
						|
                                                         GObject  *dead_object);
 | 
						|
 | 
						|
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorCssEditor, gtk_inspector_css_editor, GTK_TYPE_BOX)
 | 
						|
 | 
						|
static void
 | 
						|
set_initial_text (GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  const gchar *text = NULL;
 | 
						|
 | 
						|
  if (ce->priv->context)
 | 
						|
    text = g_object_get_data (G_OBJECT (ce->priv->context), GTK_INSPECTOR_CSS_EDITOR_TEXT);
 | 
						|
  if (text)
 | 
						|
    gtk_text_buffer_set_text (GTK_TEXT_BUFFER (ce->priv->text), text, -1);
 | 
						|
  else
 | 
						|
    {
 | 
						|
      gchar *initial_text;
 | 
						|
      if (ce->priv->global)
 | 
						|
        initial_text = g_strconcat ("/*\n",
 | 
						|
                                    _("You can type here any CSS rule recognized by GTK+."), "\n",
 | 
						|
                                    _("You can temporarily disable this custom CSS by clicking on the “Pause” button above."), "\n\n",
 | 
						|
                                    _("Changes are applied instantly and globally, for the whole application."), "\n",
 | 
						|
                                    "*/\n\n", NULL);
 | 
						|
      else
 | 
						|
        initial_text = g_strconcat ("/*\n",
 | 
						|
                                    _("You can type here any CSS rule recognized by GTK+."), "\n",
 | 
						|
                                    _("You can temporarily disable this custom CSS by clicking on the “Pause” button above."), "\n\n",
 | 
						|
                                    _("Changes are applied instantly, only for this selected widget."), "\n",
 | 
						|
                                    "*/\n\n", NULL);
 | 
						|
      gtk_text_buffer_set_text (GTK_TEXT_BUFFER (ce->priv->text), initial_text, -1);
 | 
						|
      g_free (initial_text);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
disable_toggled (GtkToggleToolButton   *button,
 | 
						|
                 GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  if (gtk_toggle_tool_button_get_active (button))
 | 
						|
    {
 | 
						|
      if (ce->priv->global)
 | 
						|
        gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
 | 
						|
                                                      GTK_STYLE_PROVIDER (ce->priv->provider));
 | 
						|
      else if (ce->priv->context)
 | 
						|
        gtk_style_context_remove_provider (ce->priv->context,
 | 
						|
                                           GTK_STYLE_PROVIDER (g_object_get_data (G_OBJECT (ce->priv->context), GTK_INSPECTOR_CSS_EDITOR_PROVIDER)));
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      if (ce->priv->global)
 | 
						|
        gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
 | 
						|
                                                   GTK_STYLE_PROVIDER (ce->priv->provider),
 | 
						|
                                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
						|
      else if (ce->priv->context)
 | 
						|
        gtk_style_context_add_provider (ce->priv->context,
 | 
						|
                                        GTK_STYLE_PROVIDER (g_object_get_data (G_OBJECT (ce->priv->context), GTK_INSPECTOR_CSS_EDITOR_PROVIDER)),
 | 
						|
                                        G_MAXUINT);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
get_current_text (GtkTextBuffer *buffer)
 | 
						|
{
 | 
						|
  GtkTextIter start, end;
 | 
						|
 | 
						|
  gtk_text_buffer_get_start_iter (buffer, &start);
 | 
						|
  gtk_text_buffer_get_end_iter (buffer, &end);
 | 
						|
  gtk_text_buffer_remove_all_tags (buffer, &start, &end);
 | 
						|
 | 
						|
  return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
save_to_file (GtkInspectorCssEditor *ce,
 | 
						|
              const gchar           *filename)
 | 
						|
{
 | 
						|
  gchar *text;
 | 
						|
  GError *error = NULL;
 | 
						|
 | 
						|
  text = get_current_text (ce->priv->text);
 | 
						|
 | 
						|
  if (!g_file_set_contents (filename, text, -1, &error))
 | 
						|
    {
 | 
						|
      GtkWidget *dialog;
 | 
						|
 | 
						|
      dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (ce))),
 | 
						|
                                       GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
 | 
						|
                                       GTK_MESSAGE_INFO,
 | 
						|
                                       GTK_BUTTONS_OK,
 | 
						|
                                       _("Saving CSS failed"));
 | 
						|
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
 | 
						|
                                                "%s", error->message);
 | 
						|
      g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
 | 
						|
      gtk_widget_show (dialog);
 | 
						|
      g_error_free (error);
 | 
						|
    }
 | 
						|
 | 
						|
  g_free (text);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
save_response (GtkWidget             *dialog,
 | 
						|
               gint                   response,
 | 
						|
               GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  gtk_widget_hide (dialog);
 | 
						|
 | 
						|
  if (response == GTK_RESPONSE_ACCEPT)
 | 
						|
    {
 | 
						|
      gchar *filename;
 | 
						|
 | 
						|
      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 | 
						|
      save_to_file (ce, filename);
 | 
						|
      g_free (filename);
 | 
						|
    }
 | 
						|
 | 
						|
  gtk_widget_destroy (dialog);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
save_clicked (GtkToolButton         *button,
 | 
						|
              GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  GtkWidget *dialog;
 | 
						|
 | 
						|
  dialog = gtk_file_chooser_dialog_new ("",
 | 
						|
                                        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (ce))),
 | 
						|
                                        GTK_FILE_CHOOSER_ACTION_SAVE,
 | 
						|
                                        _("_Cancel"), GTK_RESPONSE_CANCEL,
 | 
						|
                                        _("_Save"), GTK_RESPONSE_ACCEPT,
 | 
						|
                                        NULL);
 | 
						|
  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "custom.css");
 | 
						|
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
 | 
						|
  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 | 
						|
  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
 | 
						|
  g_signal_connect (dialog, "response", G_CALLBACK (save_response), ce);
 | 
						|
  gtk_widget_show (dialog);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
update_style (GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  GtkCssProvider *provider;
 | 
						|
  gchar *text;
 | 
						|
 | 
						|
  if (ce->priv->global)
 | 
						|
    provider = ce->priv->provider;
 | 
						|
  else if (ce->priv->context)
 | 
						|
    provider = g_object_get_data (G_OBJECT (ce->priv->context), GTK_INSPECTOR_CSS_EDITOR_PROVIDER);
 | 
						|
  else
 | 
						|
    return;
 | 
						|
 | 
						|
  text = get_current_text (ce->priv->text);
 | 
						|
  gtk_css_provider_load_from_data (provider, text, -1, NULL);
 | 
						|
  g_free (text);
 | 
						|
 | 
						|
  gtk_style_context_reset_widgets (gdk_screen_get_default ());
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
update_timeout (gpointer data)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = data;
 | 
						|
 | 
						|
  ce->priv->timeout = 0;
 | 
						|
 | 
						|
  update_style (ce);
 | 
						|
 | 
						|
  return G_SOURCE_REMOVE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
text_changed (GtkTextBuffer         *buffer,
 | 
						|
              GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  if (ce->priv->timeout != 0)
 | 
						|
    g_source_remove (ce->priv->timeout);
 | 
						|
 | 
						|
  ce->priv->timeout = g_timeout_add (100, update_timeout, ce); 
 | 
						|
}
 | 
						|
 | 
						|
/* Safe version of gtk_text_buffer_get_iter_at_line_index(). */
 | 
						|
static void
 | 
						|
safe_get_iter_at_line_index (GtkTextBuffer *buffer,
 | 
						|
                             GtkTextIter   *iter,
 | 
						|
                             gint           line_number,
 | 
						|
                             gint           byte_index)
 | 
						|
{
 | 
						|
  if (line_number >= gtk_text_buffer_get_line_count (buffer))
 | 
						|
    {
 | 
						|
      gtk_text_buffer_get_end_iter (buffer, iter);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  gtk_text_buffer_get_iter_at_line (buffer, iter, line_number);
 | 
						|
 | 
						|
  if (byte_index < gtk_text_iter_get_bytes_in_line (iter))
 | 
						|
    gtk_text_iter_set_line_index (iter, byte_index);
 | 
						|
  else
 | 
						|
    gtk_text_iter_forward_to_line_end (iter);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
show_parsing_error (GtkCssProvider        *provider,
 | 
						|
                    GtkCssSection         *section,
 | 
						|
                    const GError          *error,
 | 
						|
                    GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  GtkTextIter start, end;
 | 
						|
  const char *tag_name;
 | 
						|
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (ce->priv->text);
 | 
						|
 | 
						|
  safe_get_iter_at_line_index (buffer,
 | 
						|
                               &start,
 | 
						|
                               gtk_css_section_get_start_line (section),
 | 
						|
                               gtk_css_section_get_start_position (section));
 | 
						|
  safe_get_iter_at_line_index (buffer,
 | 
						|
                               &end,
 | 
						|
                               gtk_css_section_get_end_line (section),
 | 
						|
                               gtk_css_section_get_end_position (section));
 | 
						|
 | 
						|
  if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
 | 
						|
    tag_name = "warning";
 | 
						|
  else
 | 
						|
    tag_name = "error";
 | 
						|
 | 
						|
  gtk_text_buffer_apply_tag_by_name (buffer, tag_name, &start, &end);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
create_provider (GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  GtkCssProvider *provider = gtk_css_provider_new ();
 | 
						|
 | 
						|
  if (ce->priv->global)
 | 
						|
    {
 | 
						|
      ce->priv->provider = provider;
 | 
						|
      gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
 | 
						|
                                                 GTK_STYLE_PROVIDER (ce->priv->provider),
 | 
						|
                                                 GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
						|
    }
 | 
						|
  else if (ce->priv->context)
 | 
						|
    {
 | 
						|
      gtk_style_context_add_provider (ce->priv->context,
 | 
						|
                                      GTK_STYLE_PROVIDER (provider),
 | 
						|
                                      G_MAXUINT);
 | 
						|
      g_object_set_data_full (G_OBJECT (ce->priv->context),
 | 
						|
                              GTK_INSPECTOR_CSS_EDITOR_PROVIDER, provider,
 | 
						|
                              g_object_unref);
 | 
						|
    }
 | 
						|
 | 
						|
  g_signal_connect (provider, "parsing-error",
 | 
						|
                    G_CALLBACK (show_parsing_error), ce);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
destroy_provider (GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  if (ce->priv->global)
 | 
						|
    {
 | 
						|
      gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
 | 
						|
                                                    GTK_STYLE_PROVIDER (ce->priv->provider));
 | 
						|
      g_object_unref (ce->priv->provider);
 | 
						|
      ce->priv->provider = NULL;
 | 
						|
    }
 | 
						|
  else if (ce->priv->context)
 | 
						|
    {
 | 
						|
      GtkStyleProvider *provider;
 | 
						|
 | 
						|
      provider = g_object_get_data (G_OBJECT (ce->priv->context),
 | 
						|
                                    GTK_INSPECTOR_CSS_EDITOR_PROVIDER);
 | 
						|
      gtk_style_context_remove_provider (ce->priv->context, provider);
 | 
						|
      g_object_set_data (G_OBJECT (ce->priv->context),
 | 
						|
                         GTK_INSPECTOR_CSS_EDITOR_PROVIDER,
 | 
						|
                         NULL);
 | 
						|
    }
 | 
						|
}
 | 
						|
  
 | 
						|
 | 
						|
static void
 | 
						|
gtk_inspector_css_editor_init (GtkInspectorCssEditor *ce)
 | 
						|
{
 | 
						|
  ce->priv = gtk_inspector_css_editor_get_instance_private (ce);
 | 
						|
  gtk_widget_init_template (GTK_WIDGET (ce));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
constructed (GObject *object)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = GTK_INSPECTOR_CSS_EDITOR (object);
 | 
						|
 | 
						|
  create_provider (ce);
 | 
						|
  set_initial_text (ce);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
get_property (GObject    *object,
 | 
						|
              guint       param_id,
 | 
						|
              GValue     *value,
 | 
						|
              GParamSpec *pspec)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = GTK_INSPECTOR_CSS_EDITOR (object);
 | 
						|
 | 
						|
  switch (param_id)
 | 
						|
    {
 | 
						|
      case PROP_GLOBAL:
 | 
						|
        g_value_set_boolean (value, ce->priv->global);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
set_property (GObject      *object,
 | 
						|
              guint         param_id,
 | 
						|
              const GValue *value,
 | 
						|
              GParamSpec   *pspec)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = GTK_INSPECTOR_CSS_EDITOR (object);
 | 
						|
 | 
						|
  switch (param_id)
 | 
						|
    {
 | 
						|
      case PROP_GLOBAL:
 | 
						|
        ce->priv->global = g_value_get_boolean (value);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
finalize (GObject *object)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = GTK_INSPECTOR_CSS_EDITOR (object);
 | 
						|
 | 
						|
  if (ce->priv->timeout != 0)
 | 
						|
    g_source_remove (ce->priv->timeout);
 | 
						|
 | 
						|
  destroy_provider (ce);
 | 
						|
  if (ce->priv->context)
 | 
						|
    {
 | 
						|
      g_object_weak_unref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
 | 
						|
      g_object_set_data (G_OBJECT (ce->priv->context),
 | 
						|
                         GTK_INSPECTOR_CSS_EDITOR_TEXT,
 | 
						|
                         NULL);
 | 
						|
      ce->priv->context = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  G_OBJECT_CLASS (gtk_inspector_css_editor_parent_class)->finalize (object);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gtk_inspector_css_editor_class_init (GtkInspectorCssEditorClass *klass)
 | 
						|
{
 | 
						|
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
						|
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
						|
 | 
						|
  object_class->get_property = get_property;
 | 
						|
  object_class->set_property = set_property;
 | 
						|
  object_class->constructed = constructed;
 | 
						|
  object_class->finalize = finalize;
 | 
						|
 | 
						|
  g_object_class_install_property (object_class, PROP_GLOBAL,
 | 
						|
      g_param_spec_boolean ("global", "Global", "Whether this editor changes the whole application or just the selected widget",
 | 
						|
                            TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 | 
						|
 | 
						|
  gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/css-editor.ui");
 | 
						|
  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssEditor, toolbar);
 | 
						|
  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssEditor, text);
 | 
						|
  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssEditor, view);
 | 
						|
  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssEditor, disable_button);
 | 
						|
  gtk_widget_class_bind_template_callback (widget_class, disable_toggled);
 | 
						|
  gtk_widget_class_bind_template_callback (widget_class, save_clicked);
 | 
						|
  gtk_widget_class_bind_template_callback (widget_class, text_changed);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gtk_inspector_css_editor_remove_dead_object (gpointer data, GObject *dead_object)
 | 
						|
{
 | 
						|
  GtkInspectorCssEditor *ce = data;
 | 
						|
 | 
						|
  ce->priv->context = NULL;
 | 
						|
  gtk_widget_hide (GTK_WIDGET (ce));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
gtk_inspector_css_editor_set_object (GtkInspectorCssEditor *ce,
 | 
						|
                                     GObject               *object)
 | 
						|
{
 | 
						|
  gchar *text;
 | 
						|
  GtkCssProvider *provider;
 | 
						|
 | 
						|
  g_return_if_fail (GTK_INSPECTOR_IS_CSS_EDITOR (ce));
 | 
						|
  g_return_if_fail (!ce->priv->global);
 | 
						|
 | 
						|
  if (ce->priv->context)
 | 
						|
    {
 | 
						|
      g_object_weak_unref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
 | 
						|
      text = get_current_text (GTK_TEXT_BUFFER (ce->priv->text));
 | 
						|
      g_object_set_data_full (G_OBJECT (ce->priv->context),
 | 
						|
                              GTK_INSPECTOR_CSS_EDITOR_TEXT,
 | 
						|
                              text, g_free);
 | 
						|
      ce->priv->context = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!GTK_IS_WIDGET (object))
 | 
						|
    {
 | 
						|
      gtk_widget_hide (GTK_WIDGET (ce));
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  gtk_widget_show (GTK_WIDGET (ce));
 | 
						|
 | 
						|
  ce->priv->context = gtk_widget_get_style_context (GTK_WIDGET (object));
 | 
						|
 | 
						|
  provider = g_object_get_data (G_OBJECT (ce->priv->context), GTK_INSPECTOR_CSS_EDITOR_PROVIDER);
 | 
						|
  if (!provider)
 | 
						|
    create_provider (ce);
 | 
						|
 | 
						|
  set_initial_text (ce);
 | 
						|
  disable_toggled (ce->priv->disable_button, ce);
 | 
						|
 | 
						|
  g_object_weak_ref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
 | 
						|
}
 | 
						|
 | 
						|
// vim: set et sw=2 ts=2:
 |