1 #if defined(HAVE_CONFIG_H) && !defined(GEANYPY_WINDOWS)
2 # include "config.h"
3 #endif
4 
5 #include "geanypy.h"
6 
7 struct _SignalManager
8 {
9 	GeanyPlugin *geany_plugin;
10 	PyObject *py_obj;
11 	GObject *obj;
12 };
13 
14 
15 static void signal_manager_connect_signals(SignalManager *man);
16 
17 static void on_build_start(GObject *geany_object, SignalManager *man);
18 static void on_document_activate(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
19 static void on_document_before_save(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
20 static void on_document_close(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
21 static void on_document_filetype_set(GObject *geany_object, GeanyDocument *doc, GeanyFiletype *filetype_old, SignalManager *man);
22 static void on_document_new(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
23 static void on_document_open(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
24 static void on_document_reload(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
25 static void on_document_save(GObject *geany_object, GeanyDocument *doc, SignalManager *man);
26 static gboolean on_editor_notify(GObject *geany_object, GeanyEditor *editor, SCNotification *nt, SignalManager *man);
27 static void on_geany_startup_complete(GObject *geany_object, SignalManager *man);
28 static void on_project_close(GObject *geany_object, SignalManager *man);
29 static void on_project_dialog_confirmed(GObject *geany_object, GtkWidget *notebook, SignalManager *man);
30 static void on_project_dialog_open(GObject *geany_object, GtkWidget *notebook, SignalManager *man);
31 static void on_project_dialog_close(GObject *geany_object, GtkWidget *notebook, SignalManager *man);
32 static void on_project_open(GObject *geany_object, GKeyFile *config, SignalManager *man);
33 static void on_project_save(GObject *geany_object, GKeyFile *config, SignalManager *man);
34 static void on_update_editor_menu(GObject *geany_object, const gchar *word, gint pos, GeanyDocument *doc, SignalManager *man);
35 
36 
signal_manager_new(GeanyPlugin * geany_plugin)37 SignalManager *signal_manager_new(GeanyPlugin *geany_plugin)
38 {
39 	SignalManager *man;
40 	PyObject *module;
41 
42 	man = g_new0(SignalManager, 1);
43 
44 	man->geany_plugin = geany_plugin;
45 	man->py_obj = NULL;
46 	man->obj = NULL;
47 
48 	module = PyImport_ImportModule("geany");
49 	if (!module)
50 	{
51 		if (PyErr_Occurred())
52 			PyErr_Print();
53 		g_warning("Unable to import 'geany' module");
54 		g_free(man);
55 		return NULL;
56 	}
57 
58 	man->py_obj = PyObject_GetAttrString(module, "signals");
59 	Py_DECREF(module);
60 	if (!man->py_obj)
61 	{
62 		if (PyErr_Occurred())
63 			PyErr_Print();
64 		g_warning("Unable to get 'SignalManager' instance from 'geany' module.");
65 		g_free(man);
66 		return NULL;
67 	}
68 	man->obj = pygobject_get(man->py_obj);
69 
70 	signal_manager_connect_signals(man);
71 
72 	return man;
73 }
74 
75 
signal_manager_free(SignalManager * man)76 void signal_manager_free(SignalManager *man)
77 {
78 	g_return_if_fail(man != NULL);
79 	Py_XDECREF(man->py_obj);
80 	g_free(man);
81 }
82 
signal_manager_get_gobject(SignalManager * signal_manager)83 GObject *signal_manager_get_gobject(SignalManager *signal_manager)
84 {
85 	return G_OBJECT(signal_manager->obj);
86 }
87 
88 
signal_manager_connect_signals(SignalManager * man)89 static void signal_manager_connect_signals(SignalManager *man)
90 {
91 	GeanyPlugin *geany_plugin = man->geany_plugin;
92 	plugin_signal_connect(geany_plugin, NULL, "build-start", TRUE, G_CALLBACK(on_build_start), man);
93 	plugin_signal_connect(geany_plugin, NULL, "document-activate", TRUE, G_CALLBACK(on_document_activate), man);
94 	plugin_signal_connect(geany_plugin, NULL, "document-before-save", TRUE, G_CALLBACK(on_document_before_save), man);
95 	plugin_signal_connect(geany_plugin, NULL, "document-close", TRUE, G_CALLBACK(on_document_close), man);
96 	plugin_signal_connect(geany_plugin, NULL, "document-filetype-set", TRUE, G_CALLBACK(on_document_filetype_set), man);
97 	plugin_signal_connect(geany_plugin, NULL, "document-new", TRUE, G_CALLBACK(on_document_new), man);
98 	plugin_signal_connect(geany_plugin, NULL, "document-open", TRUE, G_CALLBACK(on_document_open), man);
99 	plugin_signal_connect(geany_plugin, NULL, "document-reload", TRUE, G_CALLBACK(on_document_reload), man);
100 	plugin_signal_connect(geany_plugin, NULL, "document-save", TRUE, G_CALLBACK(on_document_save), man);
101 	plugin_signal_connect(geany_plugin, NULL, "editor-notify", TRUE, G_CALLBACK(on_editor_notify), man);
102 	plugin_signal_connect(geany_plugin, NULL, "geany-startup-complete", TRUE, G_CALLBACK(on_geany_startup_complete), man);
103 	plugin_signal_connect(geany_plugin, NULL, "project-close", TRUE, G_CALLBACK(on_project_close), man);
104 	plugin_signal_connect(geany_plugin, NULL, "project-dialog-confirmed", TRUE, G_CALLBACK(on_project_dialog_confirmed), man);
105 	plugin_signal_connect(geany_plugin, NULL, "project-dialog-open", TRUE, G_CALLBACK(on_project_dialog_open), man);
106 	plugin_signal_connect(geany_plugin, NULL, "project-dialog-close", TRUE, G_CALLBACK(on_project_dialog_close), man);
107 	plugin_signal_connect(geany_plugin, NULL, "project-open", TRUE, G_CALLBACK(on_project_open), man);
108 	plugin_signal_connect(geany_plugin, NULL, "project-save", TRUE, G_CALLBACK(on_project_save), man);
109 	plugin_signal_connect(geany_plugin, NULL, "update-editor-menu", TRUE, G_CALLBACK(on_update_editor_menu), man);
110 }
111 
on_build_start(GObject * geany_object,SignalManager * man)112 static void on_build_start(GObject *geany_object, SignalManager *man)
113 {
114 	g_signal_emit_by_name(man->obj, "build-start");
115 }
116 
117 
on_document_event(GObject * geany_object,GeanyDocument * doc,SignalManager * man,const gchar * signal_name)118 static void on_document_event(GObject *geany_object, GeanyDocument *doc, SignalManager *man, const gchar *signal_name)
119 {
120 	PyObject *py_doc = (PyObject *) Document_create_new_from_geany_document(doc);
121 	g_signal_emit_by_name(man->obj, signal_name, py_doc);
122 	Py_XDECREF(py_doc);
123 }
124 
125 
on_document_activate(GObject * geany_object,GeanyDocument * doc,SignalManager * man)126 static void on_document_activate(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
127 {
128 	on_document_event(geany_object, doc, man, "document-activate");
129 }
130 
131 
on_document_before_save(GObject * geany_object,GeanyDocument * doc,SignalManager * man)132 static void on_document_before_save(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
133 {
134 	on_document_event(geany_object, doc, man, "document-before-save");
135 }
136 
137 
on_document_close(GObject * geany_object,GeanyDocument * doc,SignalManager * man)138 static void on_document_close(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
139 {
140 	on_document_event(geany_object, doc, man, "document-close");
141 }
142 
143 
on_document_filetype_set(GObject * geany_object,GeanyDocument * doc,GeanyFiletype * filetype_old,SignalManager * man)144 static void on_document_filetype_set(GObject *geany_object, GeanyDocument *doc, GeanyFiletype *filetype_old, SignalManager *man)
145 {
146 	PyObject *py_doc, *py_ft;
147 	py_doc = (PyObject *) Document_create_new_from_geany_document(doc);
148 	py_ft = (PyObject *) Filetype_create_new_from_geany_filetype(filetype_old);
149 	g_signal_emit_by_name(man->obj, "document-filetype-set", py_doc, py_ft);
150 	Py_XDECREF(py_doc);
151 	Py_XDECREF(py_ft);
152 }
153 
154 
on_document_new(GObject * geany_object,GeanyDocument * doc,SignalManager * man)155 static void on_document_new(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
156 {
157 	on_document_event(geany_object, doc, man, "document-new");
158 }
159 
160 
on_document_open(GObject * geany_object,GeanyDocument * doc,SignalManager * man)161 static void on_document_open(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
162 {
163 	on_document_event(geany_object, doc, man, "document-open");
164 }
165 
166 
on_document_reload(GObject * geany_object,GeanyDocument * doc,SignalManager * man)167 static void on_document_reload(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
168 {
169 	on_document_event(geany_object, doc, man, "document-reload");
170 }
171 
172 
on_document_save(GObject * geany_object,GeanyDocument * doc,SignalManager * man)173 static void on_document_save(GObject *geany_object, GeanyDocument *doc, SignalManager *man)
174 {
175 	on_document_event(geany_object, doc, man, "document-save");
176 }
177 
178 
on_editor_notify(GObject * geany_object,GeanyEditor * editor,SCNotification * nt,SignalManager * man)179 static gboolean on_editor_notify(GObject *geany_object, GeanyEditor *editor, SCNotification *nt, SignalManager *man)
180 {
181 	gboolean res = FALSE;
182 	PyObject *py_ed, *py_notif;
183 	py_ed = (PyObject *) Editor_create_new_from_geany_editor(editor);
184 	py_notif = (PyObject *) Notification_create_new_from_scintilla_notification(nt);
185 	g_signal_emit_by_name(man->obj, "editor-notify", py_ed, py_notif, &res);
186 	Py_XDECREF(py_ed);
187 	Py_XDECREF(py_notif);
188 	return res;
189 }
190 
191 
on_geany_startup_complete(GObject * geany_object,SignalManager * man)192 static void on_geany_startup_complete(GObject *geany_object, SignalManager *man)
193 {
194 	g_signal_emit_by_name(man->obj, "geany-startup-complete");
195 }
196 
197 
on_project_close(GObject * geany_object,SignalManager * man)198 static void on_project_close(GObject *geany_object, SignalManager *man)
199 {
200 	g_signal_emit_by_name(man->obj, "project-close");
201 }
202 
203 
on_project_dialog_confirmed(GObject * geany_object,GtkWidget * notebook,SignalManager * man)204 static void on_project_dialog_confirmed(GObject *geany_object, GtkWidget *notebook, SignalManager *man)
205 {
206 	PyObject *gob = (PyObject *) pygobject_new(G_OBJECT(notebook));
207 	g_signal_emit_by_name(man->obj, "project-dialog-confirmed", gob);
208 	Py_XDECREF(gob);
209 }
210 
211 
on_project_dialog_open(GObject * geany_object,GtkWidget * notebook,SignalManager * man)212 static void on_project_dialog_open(GObject *geany_object, GtkWidget *notebook, SignalManager *man)
213 {
214 	PyObject *gob = (PyObject *) pygobject_new(G_OBJECT(notebook));
215 	g_signal_emit_by_name(man->obj, "project-dialog-open", gob);
216 	Py_XDECREF(gob);
217 }
218 
on_project_dialog_close(GObject * geany_object,GtkWidget * notebook,SignalManager * man)219 static void on_project_dialog_close(GObject *geany_object, GtkWidget *notebook, SignalManager *man)
220 {
221 	PyObject *gob = (PyObject *) pygobject_new(G_OBJECT(notebook));
222 	g_signal_emit_by_name(man->obj, "project-dialog-close", gob);
223 	Py_XDECREF(gob);
224 }
225 
226 
on_project_open(GObject * geany_object,GKeyFile * config,SignalManager * man)227 static void on_project_open(GObject *geany_object, GKeyFile *config, SignalManager *man)
228 {
229 	PyObject *py_proj = (PyObject *) GEANYPY_NEW(Project);
230 	g_signal_emit_by_name(man->obj, "project-open", py_proj);
231 	Py_XDECREF(py_proj);
232 }
233 
234 
on_project_save(GObject * geany_object,GKeyFile * config,SignalManager * man)235 static void on_project_save(GObject *geany_object, GKeyFile *config, SignalManager *man)
236 {
237 	PyObject *py_proj = (PyObject *) GEANYPY_NEW(Project);
238 	g_signal_emit_by_name(man->obj, "project-save", py_proj);
239 	Py_XDECREF(py_proj);
240 }
241 
242 
on_update_editor_menu(GObject * geany_object,const gchar * word,gint pos,GeanyDocument * doc,SignalManager * man)243 static void on_update_editor_menu(GObject *geany_object, const gchar *word, gint pos, GeanyDocument *doc, SignalManager *man)
244 {
245 	PyObject *py_doc = (PyObject *) Document_create_new_from_geany_document(doc);
246 	g_signal_emit_by_name(man->obj, "update-editor-menu", word, pos, py_doc);
247 	Py_XDECREF(py_doc);
248 }
249