1 /*
2  *      geanyobject.c - this file is part of Geany, a fast and lightweight IDE
3  *
4  *      Copyright 2007 The Geany contributors
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License along
17  *      with this program; if not, write to the Free Software Foundation, Inc.,
18  *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 /* A GObject used for connecting and emitting signals when certain events happen,
22  * e.g. opening a document.
23  * Mainly used for plugins - see the API docs.
24  *
25  * Core-only signals:
26  *
27  * signal void save_settings(GObject *obj, GKeyFile *keyfile, gpointer user_data);
28  * Emitted just before saving main keyfile settings.
29 
30  * signal void load_settings(GObject *obj, GKeyFile *keyfile, gpointer user_data);
31  * Emitted just after loading main keyfile settings.
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37 
38 #include "geanyobject.h"
39 
40 /* extern in geany.h */
41 GObject	*geany_object;
42 
43 static guint geany_object_signals[GCB_MAX] = { 0 };
44 
45 
46 typedef struct _GeanyObjectPrivate GeanyObjectPrivate;
47 
48 struct _GeanyObjectPrivate
49 {
50 	/* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
51 	gchar dummy;
52 };
53 
54 /** @gironly
55  * Get the GObject-derived GType for GeanyObject
56  *
57  * @return GeanyObject type */
58 GEANY_API_SYMBOL
59 GType geany_object_get_type(void);
60 
G_DEFINE_TYPE(GeanyObject,geany_object,G_TYPE_OBJECT)61 G_DEFINE_TYPE(GeanyObject, geany_object, G_TYPE_OBJECT)
62 
63 
64 static gboolean boolean_handled_accumulator(GSignalInvocationHint *ihint, GValue *return_accu,
65 											const GValue *handler_return, gpointer dummy)
66 {
67 	gboolean continue_emission, signal_handled;
68 
69 	signal_handled = g_value_get_boolean(handler_return);
70 	g_value_set_boolean(return_accu, signal_handled);
71 	continue_emission = !signal_handled;
72 
73 	return continue_emission;
74 }
75 
76 
create_signals(GObjectClass * g_object_class)77 static void create_signals(GObjectClass *g_object_class)
78 {
79 	/* Document signals */
80 	geany_object_signals[GCB_DOCUMENT_NEW] = g_signal_new (
81 		"document-new",
82 		G_OBJECT_CLASS_TYPE (g_object_class),
83 		G_SIGNAL_RUN_FIRST,
84 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
85 		G_TYPE_NONE, 1,
86 		GEANY_TYPE_DOCUMENT);
87 	geany_object_signals[GCB_DOCUMENT_OPEN] = g_signal_new (
88 		"document-open",
89 		G_OBJECT_CLASS_TYPE (g_object_class),
90 		G_SIGNAL_RUN_FIRST,
91 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
92 		G_TYPE_NONE, 1,
93 		GEANY_TYPE_DOCUMENT);
94 	geany_object_signals[GCB_DOCUMENT_RELOAD] = g_signal_new (
95 		"document-reload",
96 		G_OBJECT_CLASS_TYPE (g_object_class),
97 		G_SIGNAL_RUN_FIRST,
98 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
99 		G_TYPE_NONE, 1,
100 		GEANY_TYPE_DOCUMENT);
101 	geany_object_signals[GCB_DOCUMENT_BEFORE_SAVE] = g_signal_new (
102 		"document-before-save",
103 		G_OBJECT_CLASS_TYPE (g_object_class),
104 		G_SIGNAL_RUN_FIRST,
105 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
106 		G_TYPE_NONE, 1,
107 		GEANY_TYPE_DOCUMENT);
108 	geany_object_signals[GCB_DOCUMENT_SAVE] = g_signal_new (
109 		"document-save",
110 		G_OBJECT_CLASS_TYPE (g_object_class),
111 		G_SIGNAL_RUN_FIRST,
112 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
113 		G_TYPE_NONE, 1,
114 		GEANY_TYPE_DOCUMENT);
115 	geany_object_signals[GCB_DOCUMENT_FILETYPE_SET] = g_signal_new (
116 		"document-filetype-set",
117 		G_OBJECT_CLASS_TYPE (g_object_class),
118 		G_SIGNAL_RUN_FIRST,
119 		0, NULL, NULL, NULL,
120 		G_TYPE_NONE, 2,
121 		GEANY_TYPE_DOCUMENT, GEANY_TYPE_FILETYPE);
122 	geany_object_signals[GCB_DOCUMENT_ACTIVATE] = g_signal_new (
123 		"document-activate",
124 		G_OBJECT_CLASS_TYPE (g_object_class),
125 		G_SIGNAL_RUN_FIRST,
126 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
127 		G_TYPE_NONE, 1,
128 		GEANY_TYPE_DOCUMENT);
129 	geany_object_signals[GCB_DOCUMENT_CLOSE] = g_signal_new (
130 		"document-close",
131 		G_OBJECT_CLASS_TYPE (g_object_class),
132 		G_SIGNAL_RUN_FIRST,
133 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
134 		G_TYPE_NONE, 1,
135 		GEANY_TYPE_DOCUMENT);
136 
137 	/* Project signals */
138 	geany_object_signals[GCB_PROJECT_OPEN] = g_signal_new (
139 		"project-open",
140 		G_OBJECT_CLASS_TYPE (g_object_class),
141 		G_SIGNAL_RUN_FIRST,
142 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
143 		G_TYPE_NONE, 1,
144 		G_TYPE_KEY_FILE);
145 	geany_object_signals[GCB_PROJECT_SAVE] = g_signal_new (
146 		"project-save",
147 		G_OBJECT_CLASS_TYPE (g_object_class),
148 		G_SIGNAL_RUN_FIRST,
149 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
150 		G_TYPE_NONE, 1,
151 		G_TYPE_KEY_FILE);
152 	geany_object_signals[GCB_PROJECT_CLOSE] = g_signal_new (
153 		"project-close",
154 		G_OBJECT_CLASS_TYPE (g_object_class),
155 		G_SIGNAL_RUN_FIRST,
156 		0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
157 		G_TYPE_NONE, 0);
158 	geany_object_signals[GCB_PROJECT_BEFORE_CLOSE] = g_signal_new (
159 		"project-before-close",
160 		G_OBJECT_CLASS_TYPE (g_object_class),
161 		G_SIGNAL_RUN_FIRST,
162 		0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
163 		G_TYPE_NONE, 0);
164 	geany_object_signals[GCB_PROJECT_DIALOG_OPEN] = g_signal_new (
165 		"project-dialog-open",
166 		G_OBJECT_CLASS_TYPE (g_object_class),
167 		G_SIGNAL_RUN_FIRST,
168 		0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
169 		G_TYPE_NONE, 1,
170 		GTK_TYPE_NOTEBOOK);
171 	geany_object_signals[GCB_PROJECT_DIALOG_CONFIRMED] = g_signal_new (
172 		"project-dialog-confirmed",
173 		G_OBJECT_CLASS_TYPE (g_object_class),
174 		G_SIGNAL_RUN_FIRST,
175 		0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
176 		G_TYPE_NONE, 1,
177 		GTK_TYPE_NOTEBOOK);
178 	geany_object_signals[GCB_PROJECT_DIALOG_CLOSE] = g_signal_new (
179 		"project-dialog-close",
180 		G_OBJECT_CLASS_TYPE (g_object_class),
181 		G_SIGNAL_RUN_FIRST,
182 		0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
183 		G_TYPE_NONE, 1,
184 		GTK_TYPE_NOTEBOOK);
185 
186 	/* Editor signals */
187 	geany_object_signals[GCB_UPDATE_EDITOR_MENU] = g_signal_new (
188 		"update-editor-menu",
189 		G_OBJECT_CLASS_TYPE (g_object_class),
190 		G_SIGNAL_RUN_FIRST,
191 		0, NULL, NULL, NULL,
192 		G_TYPE_NONE, 3,
193 		G_TYPE_STRING, G_TYPE_INT, GEANY_TYPE_DOCUMENT);
194 	geany_object_signals[GCB_EDITOR_NOTIFY] = g_signal_new (
195 		"editor-notify",
196 		G_OBJECT_CLASS_TYPE (g_object_class),
197 		G_SIGNAL_RUN_LAST,
198 		0, boolean_handled_accumulator, NULL, NULL,
199 		G_TYPE_BOOLEAN, 2,
200 		GEANY_TYPE_EDITOR, SCINTILLA_TYPE_NOTIFICATION);
201 
202 	/* General signals */
203 	geany_object_signals[GCB_GEANY_STARTUP_COMPLETE] = g_signal_new (
204 		"geany-startup-complete",
205 		G_OBJECT_CLASS_TYPE (g_object_class),
206 		G_SIGNAL_RUN_FIRST,
207 		0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
208 		G_TYPE_NONE, 0);
209 	geany_object_signals[GCB_BUILD_START] = g_signal_new (
210 		"build-start",
211 		G_OBJECT_CLASS_TYPE (g_object_class),
212 		G_SIGNAL_RUN_FIRST,
213 		0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
214 		G_TYPE_NONE, 0);
215 
216 	/* Core-only signals */
217 	geany_object_signals[GCB_SAVE_SETTINGS] = g_signal_new (
218 		"save-settings",
219 		G_OBJECT_CLASS_TYPE (g_object_class),
220 		G_SIGNAL_RUN_FIRST,
221 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
222 		G_TYPE_NONE, 1,
223 		G_TYPE_KEY_FILE);
224 	geany_object_signals[GCB_LOAD_SETTINGS] = g_signal_new (
225 		"load-settings",
226 		G_OBJECT_CLASS_TYPE (g_object_class),
227 		G_SIGNAL_RUN_FIRST,
228 		0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
229 		G_TYPE_NONE, 1,
230 		G_TYPE_KEY_FILE);
231 
232 	/* Key press signal */
233 	geany_object_signals[GCB_KEY_PRESS_NOTIFY] = g_signal_new (
234 		"key-press",
235 		G_OBJECT_CLASS_TYPE (g_object_class),
236 		G_SIGNAL_RUN_LAST,
237 		0, boolean_handled_accumulator, NULL, NULL,
238 		G_TYPE_BOOLEAN, 1,
239 		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
240 }
241 
242 
geany_object_class_init(GeanyObjectClass * klass)243 static void geany_object_class_init(GeanyObjectClass *klass)
244 {
245 	GObjectClass *g_object_class;
246 	g_object_class = G_OBJECT_CLASS(klass);
247 
248 	g_type_class_add_private(klass, sizeof(GeanyObjectPrivate));
249 
250 	create_signals(g_object_class);
251 }
252 
253 
geany_object_init(GeanyObject * self)254 static void geany_object_init(GeanyObject *self)
255 {
256 	/* nothing to do */
257 }
258 
259 
geany_object_new(void)260 GObject *geany_object_new(void)
261 {
262 	return g_object_new(GEANY_OBJECT_TYPE, NULL);
263 }
264