1 /*
2  * xed-modeline-plugin.c
3  * Emacs, Kate and Vim-style modelines support for xed.
4  *
5  * Copyright (C) 2005-2007 - Steve Frécinaux <code@istique.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include <config.h>
23 #include <glib/gi18n-lib.h>
24 #include <gmodule.h>
25 #include <xed/xed-debug.h>
26 #include <xed/xed-view-activatable.h>
27 #include <xed/xed-view.h>
28 
29 #include "xed-modeline-plugin.h"
30 #include "modeline-parser.h"
31 
32 struct _XedModelinePluginPrivate
33 {
34     XedView *view;
35 
36     gulong document_loaded_handler_id;
37     gulong document_saved_handler_id;
38 };
39 
40 enum
41 {
42     PROP_0,
43     PROP_VIEW
44 };
45 
46 static void xed_view_activatable_iface_init (XedViewActivatableInterface *iface);
47 
48 G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedModelinePlugin,
49                                 xed_modeline_plugin,
50                                 PEAS_TYPE_EXTENSION_BASE,
51                                 0,
52                                 G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_VIEW_ACTIVATABLE,
53                                                                xed_view_activatable_iface_init)
54                                 G_ADD_PRIVATE_DYNAMIC (XedModelinePlugin))
55 
56 static void
xed_modeline_plugin_constructed(GObject * object)57 xed_modeline_plugin_constructed (GObject *object)
58 {
59     gchar *data_dir;
60 
61     data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (object));
62 
63     modeline_parser_init (data_dir);
64 
65     g_free (data_dir);
66 
67     G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->constructed (object);
68 }
69 
70 static void
xed_modeline_plugin_init(XedModelinePlugin * plugin)71 xed_modeline_plugin_init (XedModelinePlugin *plugin)
72 {
73     xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin initializing");
74 
75     plugin->priv = xed_modeline_plugin_get_instance_private (plugin);
76 }
77 
78 static void
xed_modeline_plugin_dispose(GObject * object)79 xed_modeline_plugin_dispose (GObject *object)
80 {
81     XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object);
82 
83     xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin disposing");
84 
85     g_clear_object (&plugin->priv->view);
86 
87     G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->dispose (object);
88 }
89 
90 static void
xed_modeline_plugin_finalize(GObject * object)91 xed_modeline_plugin_finalize (GObject *object)
92 {
93     xed_debug_message (DEBUG_PLUGINS, "XedModelinePlugin finalizing");
94 
95     modeline_parser_shutdown ();
96 
97     G_OBJECT_CLASS (xed_modeline_plugin_parent_class)->finalize (object);
98 }
99 
100 static void
xed_modeline_plugin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)101 xed_modeline_plugin_set_property (GObject      *object,
102                                   guint         prop_id,
103                                   const GValue *value,
104                                   GParamSpec   *pspec)
105 {
106     XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object);
107 
108     switch (prop_id)
109     {
110         case PROP_VIEW:
111             plugin->priv->view = XED_VIEW (g_value_dup_object (value));
112             break;
113         default:
114             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
115             break;
116     }
117 }
118 
119 static void
xed_modeline_plugin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)120 xed_modeline_plugin_get_property (GObject    *object,
121                                   guint       prop_id,
122                                   GValue     *value,
123                                   GParamSpec *pspec)
124 {
125     XedModelinePlugin *plugin = XED_MODELINE_PLUGIN (object);
126 
127     switch (prop_id)
128     {
129         case PROP_VIEW:
130             g_value_set_object (value, plugin->priv->view);
131             break;
132         default:
133             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
134             break;
135     }
136 }
137 
138 static void
on_document_loaded_or_saved(XedDocument * document,GtkSourceView * view)139 on_document_loaded_or_saved (XedDocument   *document,
140                              GtkSourceView *view)
141 {
142     modeline_parser_apply_modeline (view);
143 }
144 
145 static void
xed_modeline_plugin_activate(XedViewActivatable * activatable)146 xed_modeline_plugin_activate (XedViewActivatable *activatable)
147 {
148     XedModelinePlugin *plugin;
149     GtkTextBuffer *doc;
150 
151     xed_debug (DEBUG_PLUGINS);
152 
153     plugin = XED_MODELINE_PLUGIN (activatable);
154 
155     modeline_parser_apply_modeline (GTK_SOURCE_VIEW (plugin->priv->view));
156 
157     doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view));
158 
159     plugin->priv->document_loaded_handler_id =
160         g_signal_connect (doc, "loaded",
161                           G_CALLBACK (on_document_loaded_or_saved), plugin->priv->view);
162     plugin->priv->document_saved_handler_id =
163         g_signal_connect (doc, "saved",
164                           G_CALLBACK (on_document_loaded_or_saved), plugin->priv->view);
165 }
166 
167 static void
xed_modeline_plugin_deactivate(XedViewActivatable * activatable)168 xed_modeline_plugin_deactivate (XedViewActivatable *activatable)
169 {
170     XedModelinePlugin *plugin;
171     GtkTextBuffer *doc;
172 
173     xed_debug (DEBUG_PLUGINS);
174 
175     plugin = XED_MODELINE_PLUGIN (activatable);
176 
177     doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view));
178 
179     g_signal_handler_disconnect (doc, plugin->priv->document_loaded_handler_id);
180     g_signal_handler_disconnect (doc, plugin->priv->document_saved_handler_id);
181 }
182 
183 static void
xed_modeline_plugin_class_init(XedModelinePluginClass * klass)184 xed_modeline_plugin_class_init (XedModelinePluginClass *klass)
185 {
186     GObjectClass *object_class = G_OBJECT_CLASS (klass);
187 
188     object_class->constructed = xed_modeline_plugin_constructed;
189     object_class->dispose = xed_modeline_plugin_dispose;
190     object_class->finalize = xed_modeline_plugin_finalize;
191     object_class->set_property = xed_modeline_plugin_set_property;
192     object_class->get_property = xed_modeline_plugin_get_property;
193 
194     g_object_class_override_property (object_class, PROP_VIEW, "view");
195 }
196 
197 static void
xed_view_activatable_iface_init(XedViewActivatableInterface * iface)198 xed_view_activatable_iface_init (XedViewActivatableInterface *iface)
199 {
200     iface->activate = xed_modeline_plugin_activate;
201     iface->deactivate = xed_modeline_plugin_deactivate;
202 }
203 
204 static void
xed_modeline_plugin_class_finalize(XedModelinePluginClass * klass)205 xed_modeline_plugin_class_finalize (XedModelinePluginClass *klass)
206 {
207    /* dummy function - used by G_DEFINE_DYNAMIC_TYPE_EXTENDED */
208 }
209 
210 G_MODULE_EXPORT void
peas_register_types(PeasObjectModule * module)211 peas_register_types (PeasObjectModule *module)
212 {
213    xed_modeline_plugin_register_type (G_TYPE_MODULE (module));
214 
215    peas_object_module_register_extension_type (module,
216                                                XED_TYPE_VIEW_ACTIVATABLE,
217                                                XED_TYPE_MODELINE_PLUGIN);
218 }
219