diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-07-24 16:51:33 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-09-25 15:49:55 -0300 |
commit | f7746a88f7da0db0d9162a6defe03d7d13272440 (patch) | |
tree | d41b18974ba530cd13e3b1c89d990df50c23a628 | |
parent | 5707612d9d0c52ffb7441114796b50a2186c58a2 (diff) | |
download | glade-f7746a88f7da0db0d9162a6defe03d7d13272440.tar.gz |
Added css-provider-path property
-rw-r--r-- | gladeui/glade-project.c | 245 | ||||
-rw-r--r-- | gladeui/glade-project.h | 5 |
2 files changed, 249 insertions, 1 deletions
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c index a2d4482c..0553a2ec 100644 --- a/gladeui/glade-project.c +++ b/gladeui/glade-project.c @@ -134,6 +134,10 @@ struct _GladeProjectPrivate * (full or relative path, null means project directory). */ + gchar *css_provider_path; /* The custom css to use for this project */ + GtkCssProvider *css_provider; + GFileMonitor *css_monitor; + GList *unknown_catalogs; /* List of CatalogInfo catalogs */ GtkWidget *prefs_dialog; @@ -195,6 +199,7 @@ enum PROP_TEMPLATE, PROP_RESOURCE_PATH, PROP_LICENSE, + PROP_CSS_PROVIDER_PATH, N_PROPERTIES }; @@ -284,6 +289,9 @@ glade_project_dispose (GObject *object) glade_project_selection_clear (project, TRUE); + g_clear_object (&priv->css_provider); + g_clear_object (&priv->css_monitor); + glade_project_list_unref (priv->undo_stack); priv->undo_stack = NULL; @@ -334,6 +342,7 @@ glade_project_finalize (GObject *object) g_free (priv->path); g_free (priv->license); + g_free (priv->css_provider_path); if (priv->comments) { @@ -393,6 +402,9 @@ glade_project_get_property (GObject *object, case PROP_LICENSE: g_value_set_string (value, project->priv->license); break; + case PROP_CSS_PROVIDER_PATH: + g_value_set_string (value, project->priv->css_provider_path); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -423,6 +435,10 @@ glade_project_set_property (GObject *object, glade_project_set_license (GLADE_PROJECT (object), g_value_get_string (value)); break; + case PROP_CSS_PROVIDER_PATH: + glade_project_set_css_provider_path (GLADE_PROJECT (object), + g_value_get_string (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -645,6 +661,32 @@ glade_project_changed_impl (GladeProject *project, } } +static void +glade_project_set_css_provider_forall (GtkWidget *widget, gpointer data) +{ + if (GLADE_IS_PLACEHOLDER (widget) || GLADE_IS_OBJECT_STUB (widget)) + return; + + gtk_style_context_add_provider (gtk_widget_get_style_context (widget), + GTK_STYLE_PROVIDER (data), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + if (GTK_IS_CONTAINER (widget)) + gtk_container_forall (GTK_CONTAINER (widget), glade_project_set_css_provider_forall, data); +} + +static void +glade_project_add_object_impl (GladeProject *project, GladeWidget *gwidget) +{ + GladeProjectPrivate *priv = project->priv; + GObject *widget = glade_widget_get_object (gwidget); + + if (!priv->css_provider || !GTK_IS_WIDGET (widget)) + return; + + glade_project_set_css_provider_forall (GTK_WIDGET (widget), priv->css_provider); +} + /******************************************************************* Class Initializers *******************************************************************/ @@ -720,7 +762,7 @@ glade_project_class_init (GladeProjectClass *klass) object_class->finalize = glade_project_finalize; object_class->dispose = glade_project_dispose; - klass->add_object = NULL; + klass->add_object = glade_project_add_object_impl; klass->remove_object = NULL; klass->undo = glade_project_undo_impl; klass->redo = glade_project_redo_impl; @@ -970,6 +1012,13 @@ glade_project_class_init (GladeProjectClass *klass) NULL, G_PARAM_READWRITE); + glade_project_props[PROP_CSS_PROVIDER_PATH] = + g_param_spec_string ("css-provider-path", + _("Css Provider Path"), + _("Path to use as the custom css provider for this project."), + NULL, + G_PARAM_READWRITE); + /* Install all properties */ g_object_class_install_properties (object_class, N_PROPERTIES, glade_project_props); @@ -1841,6 +1890,46 @@ glade_project_read_resource_path (GladeProject *project, g_free (path); } +static void +glade_project_read_css_provider_path (GladeProject *project, + GladeXmlNode *root_node) +{ + GladeXmlNode *node; + + for (node = glade_xml_node_get_children_with_comments (root_node); + node; node = glade_xml_node_next_with_comments (node)) + { + gchar *value; + + if (glade_xml_node_is_comment (node) && + (value = glade_xml_get_content (node))) + { + gchar **tokens = g_strsplit (g_strstrip (value), " ", 2); + + if (tokens[0] && !g_strcmp0 (tokens[0], "interface-css-provider-path")) + { + gchar *path = tokens[1]; + + if (g_path_is_absolute (path)) + glade_project_set_css_provider_path (project, path); + else + { + gchar *dirname = g_path_get_dirname (project->priv->path); + gchar *full_path = g_build_filename (dirname, path, NULL); + + glade_project_set_css_provider_path (project, full_path); + + g_free (dirname); + g_free (full_path); + } + } + + g_strfreev (tokens); + g_free (value); + } + } +} + static inline void glade_project_read_comments (GladeProject *project, GladeXmlNode *root) { @@ -2236,6 +2325,8 @@ glade_project_load_internal (GladeProject *project) glade_project_read_resource_path (project, root); + glade_project_read_css_provider_path (project, root); + /* Launch a dialog if it's going to take enough time to be * worth showing at all */ count = glade_project_count_xml_objects (project, root, 0); @@ -2440,6 +2531,42 @@ glade_project_write_resource_path (GladeProject *project, } } +static void +glade_project_write_css_provider_path (GladeProject *project, + GladeXmlContext *context, + GladeXmlNode *root) +{ + GladeProjectPrivate *priv = project->priv; + GladeXmlNode *path_node; + gchar *dirname; + + if (priv->css_provider_path && priv->path && + (dirname = g_path_get_dirname (priv->path))) + { + GFile *project_path = g_file_new_for_path (dirname); + GFile *file_path = g_file_new_for_path (priv->css_provider_path); + gchar *css_provider_path; + + css_provider_path = g_file_get_relative_path (project_path, file_path); + + if (css_provider_path) + { + gchar *comment = g_strdup_printf (" interface-css-provider-path %s ", + css_provider_path); + path_node = glade_xml_node_new_comment (context, comment); + glade_xml_node_append_child (root, path_node); + g_free (comment); + } + else + g_warning ("g_file_get_relative_path () return NULL"); + + g_object_unref (project_path); + g_object_unref (file_path); + g_free (css_provider_path); + g_free (dirname); + } +} + static gint sort_project_dependancies (GObject *a, GObject *b) { @@ -2511,6 +2638,8 @@ glade_project_write (GladeProject *project) glade_project_write_resource_path (project, context, root); + glade_project_write_css_provider_path (project, context, root); + /* Sort the toplevels */ toplevels = g_list_copy (project->priv->tree); toplevels = g_list_sort (toplevels, (GCompareFunc)sort_project_dependancies); @@ -4789,6 +4918,120 @@ glade_project_get_translation_domain (GladeProject *project) return project->priv->translation_domain; } +static void +glade_project_css_provider_remove_forall (GtkWidget *widget, gpointer data) +{ + gtk_style_context_remove_provider (gtk_widget_get_style_context (widget), + GTK_STYLE_PROVIDER (data)); + + if (GTK_IS_CONTAINER (widget)) + gtk_container_forall (GTK_CONTAINER (widget), glade_project_css_provider_remove_forall, data); +} + +static inline void +glade_project_css_provider_refresh (GladeProject *project, gboolean remove) +{ + GladeProjectPrivate *priv = project->priv; + GtkCssProvider *provider = priv->css_provider; + const GList *l; + + for (l = priv->tree; l; l = g_list_next (l)) + { + GObject *object = l->data; + + if (!GTK_IS_WIDGET (object) || GLADE_IS_OBJECT_STUB (object)) + continue; + + if (remove) + glade_project_css_provider_remove_forall (GTK_WIDGET (object), provider); + else + glade_project_set_css_provider_forall (GTK_WIDGET (object), provider); + } +} + +static void +on_css_monitor_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + GladeProject *project) +{ + GError *error = NULL; + + gtk_css_provider_load_from_file (project->priv->css_provider, file, &error); + + if (error) + { + g_message ("CSS parsing failed: %s", error->message); + g_error_free (error); + } +} + +/** + * glade_project_set_css_provider_path: + * @project: a #GladeProject + * @path: a CSS file path + * + * Set the custom CSS provider path to use in @project + */ +void +glade_project_set_css_provider_path (GladeProject *project, const gchar *path) +{ + GladeProjectPrivate *priv; + + g_return_if_fail (GLADE_IS_PROJECT (project)); + priv = project->priv; + + if (g_strcmp0 (priv->css_provider_path, path) != 0) + { + g_free (priv->css_provider_path); + priv->css_provider_path = g_strdup (path); + + g_clear_object (&priv->css_monitor); + + if (priv->css_provider) + { + glade_project_css_provider_refresh (project, TRUE); + g_clear_object (&priv->css_provider); + } + + if (priv->css_provider_path && + g_file_test (priv->css_provider_path, G_FILE_TEST_IS_REGULAR)) + { + GFile *file = g_file_new_for_path (priv->css_provider_path); + + priv->css_provider = GTK_CSS_PROVIDER (gtk_css_provider_new ()); + g_object_ref_sink (priv->css_provider); + gtk_css_provider_load_from_file (priv->css_provider, file, NULL); + + g_clear_object (&priv->css_monitor); + priv->css_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_ref_sink (priv->css_monitor); + g_signal_connect_object (priv->css_monitor, "changed", + G_CALLBACK (on_css_monitor_changed), project, 0); + + glade_project_css_provider_refresh (project, FALSE); + g_object_unref (file); + } + + g_object_notify_by_pspec (G_OBJECT (project), glade_project_props[PROP_CSS_PROVIDER_PATH]); + } +} + +/** + * glade_project_get_css_provider_path: + * @project: a #GladeProject + * + * Returns: the CSS path of the custom provider used for @project + */ +const gchar * +glade_project_get_css_provider_path (GladeProject *project) +{ + g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL); + + return project->priv->css_provider_path; +} + /************************************************* * Command Central * *************************************************/ diff --git a/gladeui/glade-project.h b/gladeui/glade-project.h index f9a9518a..5a4fe6a6 100644 --- a/gladeui/glade-project.h +++ b/gladeui/glade-project.h @@ -258,6 +258,11 @@ void glade_project_set_translation_domain (GladeProject *project, const gchar *domain); const gchar *glade_project_get_translation_domain (GladeProject *project); +void glade_project_set_css_provider_path (GladeProject *project, + const gchar *path); + +const gchar *glade_project_get_css_provider_path (GladeProject *project); + /* Verifications */ gboolean glade_project_verify (GladeProject *project, gboolean saving, |