1 /*
2  * gedit-modeline-plugin.c
3  * Emacs, Kate and Vim-style modelines support for gedit.
4  *
5  * Copyright (C) 2005-2010 - 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, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include <glib/gi18n-lib.h>
24 #include <gmodule.h>
25 #include "gedit-modeline-plugin.h"
26 #include "modeline-parser.h"
27 
28 #include <gedit/gedit-debug.h>
29 #include <gedit/gedit-view-activatable.h>
30 #include <gedit/gedit-view.h>
31 
32 struct _GeditModelinePluginPrivate
33 {
34 	GeditView *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	gedit_view_activatable_iface_init (GeditViewActivatableInterface *iface);
47 
48 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GeditModelinePlugin,
49 				gedit_modeline_plugin,
50 				PEAS_TYPE_EXTENSION_BASE,
51 				0,
52 				G_IMPLEMENT_INTERFACE_DYNAMIC (GEDIT_TYPE_VIEW_ACTIVATABLE,
53 							       gedit_view_activatable_iface_init)
54 				G_ADD_PRIVATE_DYNAMIC (GeditModelinePlugin))
55 
56 static void
gedit_modeline_plugin_constructed(GObject * object)57 gedit_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 (gedit_modeline_plugin_parent_class)->constructed (object);
68 }
69 
70 static void
gedit_modeline_plugin_init(GeditModelinePlugin * plugin)71 gedit_modeline_plugin_init (GeditModelinePlugin *plugin)
72 {
73 	gedit_debug_message (DEBUG_PLUGINS, "GeditModelinePlugin initializing");
74 
75 	plugin->priv = gedit_modeline_plugin_get_instance_private (plugin);
76 
77 }
78 
79 static void
gedit_modeline_plugin_dispose(GObject * object)80 gedit_modeline_plugin_dispose (GObject *object)
81 {
82 	GeditModelinePlugin *plugin = GEDIT_MODELINE_PLUGIN (object);
83 
84 	gedit_debug_message (DEBUG_PLUGINS, "GeditModelinePlugin disposing");
85 
86 	g_clear_object (&plugin->priv->view);
87 
88 	G_OBJECT_CLASS (gedit_modeline_plugin_parent_class)->dispose (object);
89 }
90 
91 static void
gedit_modeline_plugin_finalize(GObject * object)92 gedit_modeline_plugin_finalize (GObject *object)
93 {
94 	gedit_debug_message (DEBUG_PLUGINS, "GeditModelinePlugin finalizing");
95 
96 	modeline_parser_shutdown ();
97 
98 	G_OBJECT_CLASS (gedit_modeline_plugin_parent_class)->finalize (object);
99 }
100 
101 static void
gedit_modeline_plugin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)102 gedit_modeline_plugin_set_property (GObject      *object,
103                                     guint         prop_id,
104                                     const GValue *value,
105                                     GParamSpec   *pspec)
106 {
107 	GeditModelinePlugin *plugin = GEDIT_MODELINE_PLUGIN (object);
108 
109 	switch (prop_id)
110 	{
111 		case PROP_VIEW:
112 			plugin->priv->view = GEDIT_VIEW (g_value_dup_object (value));
113 			break;
114 
115 		default:
116 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
117 			break;
118 	}
119 }
120 
121 static void
gedit_modeline_plugin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)122 gedit_modeline_plugin_get_property (GObject    *object,
123                                     guint       prop_id,
124                                     GValue     *value,
125                                     GParamSpec *pspec)
126 {
127 	GeditModelinePlugin *plugin = GEDIT_MODELINE_PLUGIN (object);
128 
129 	switch (prop_id)
130 	{
131 		case PROP_VIEW:
132 			g_value_set_object (value, plugin->priv->view);
133 			break;
134 
135 		default:
136 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
137 			break;
138 	}
139 }
140 
141 static void
on_document_loaded_or_saved(GeditDocument * document,GtkSourceView * view)142 on_document_loaded_or_saved (GeditDocument *document,
143 			     GtkSourceView *view)
144 {
145 	modeline_parser_apply_modeline (view);
146 }
147 
148 static void
gedit_modeline_plugin_activate(GeditViewActivatable * activatable)149 gedit_modeline_plugin_activate (GeditViewActivatable *activatable)
150 {
151 	GeditModelinePlugin *plugin;
152 	GtkTextBuffer *doc;
153 
154 	gedit_debug (DEBUG_PLUGINS);
155 
156 	plugin = GEDIT_MODELINE_PLUGIN (activatable);
157 
158 	modeline_parser_apply_modeline (GTK_SOURCE_VIEW (plugin->priv->view));
159 
160 	doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view));
161 
162 	plugin->priv->document_loaded_handler_id =
163 		g_signal_connect (doc, "loaded",
164 				  G_CALLBACK (on_document_loaded_or_saved),
165 				  plugin->priv->view);
166 	plugin->priv->document_saved_handler_id =
167 		g_signal_connect (doc, "saved",
168 				  G_CALLBACK (on_document_loaded_or_saved),
169 				  plugin->priv->view);
170 }
171 
172 static void
gedit_modeline_plugin_deactivate(GeditViewActivatable * activatable)173 gedit_modeline_plugin_deactivate (GeditViewActivatable *activatable)
174 {
175 	GeditModelinePlugin *plugin;
176 	GtkTextBuffer *doc;
177 
178 	gedit_debug (DEBUG_PLUGINS);
179 
180 	plugin = GEDIT_MODELINE_PLUGIN (activatable);
181 
182 	doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (plugin->priv->view));
183 
184 	g_signal_handler_disconnect (doc, plugin->priv->document_loaded_handler_id);
185 	g_signal_handler_disconnect (doc, plugin->priv->document_saved_handler_id);
186 }
187 
188 static void
gedit_modeline_plugin_class_init(GeditModelinePluginClass * klass)189 gedit_modeline_plugin_class_init (GeditModelinePluginClass *klass)
190 {
191 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
192 
193 	object_class->constructed = gedit_modeline_plugin_constructed;
194 	object_class->dispose = gedit_modeline_plugin_dispose;
195 	object_class->finalize = gedit_modeline_plugin_finalize;
196 	object_class->set_property = gedit_modeline_plugin_set_property;
197 	object_class->get_property = gedit_modeline_plugin_get_property;
198 
199 	g_object_class_override_property (object_class, PROP_VIEW, "view");
200 }
201 
202 static void
gedit_view_activatable_iface_init(GeditViewActivatableInterface * iface)203 gedit_view_activatable_iface_init (GeditViewActivatableInterface *iface)
204 {
205 	iface->activate = gedit_modeline_plugin_activate;
206 	iface->deactivate = gedit_modeline_plugin_deactivate;
207 }
208 
209 static void
gedit_modeline_plugin_class_finalize(GeditModelinePluginClass * klass)210 gedit_modeline_plugin_class_finalize (GeditModelinePluginClass *klass)
211 {
212 }
213 
214 
215 G_MODULE_EXPORT void
peas_register_types(PeasObjectModule * module)216 peas_register_types (PeasObjectModule *module)
217 {
218 	gedit_modeline_plugin_register_type (G_TYPE_MODULE (module));
219 
220 	peas_object_module_register_extension_type (module,
221 						    GEDIT_TYPE_VIEW_ACTIVATABLE,
222 						    GEDIT_TYPE_MODELINE_PLUGIN);
223 }
224 
225 /* ex:set ts=8 noet: */
226