quick-open: Remove weak pointer on deactivation
[anjuta.git] / plugins / quick-open / plugin.c
blob5dfe0aaf09bec96f0e083976521c9a27a21f4194
1 /* -*- Mode: C; indent-spaces-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * plugin.c
4 * Copyright (C) 2012 Carl-Anton Ingmarsson <carlantoni@src.gnome.org>
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.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
23 #include "plugin.h"
25 #include <libanjuta/anjuta-debug.h>
26 #include <libanjuta/interfaces/ianjuta-file.h>
27 #include <libanjuta/interfaces/ianjuta-file-loader.h>
29 #include <signal.h>
31 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-quick-open.xml"
33 struct _QuickOpenPluginClass
35 AnjutaPluginClass parent_class;
38 static void
39 on_dialog_response(GtkDialog* dialog, gint response_id, gpointer user_data)
41 QuickOpenPlugin* self = user_data;
43 gtk_widget_hide(GTK_WIDGET(dialog));
45 if (response_id == GTK_RESPONSE_ACCEPT)
47 GObject* object;
49 object = quick_open_dialog_get_selected_object(self->dialog);
50 if (!object)
51 return;
53 if (IANJUTA_IS_DOCUMENT(object))
55 ianjuta_document_manager_set_current_document(self->docman,
56 IANJUTA_DOCUMENT(object), NULL);
58 else if (G_IS_FILE(object))
60 IAnjutaFileLoader* loader;
62 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (self)->shell,
63 IAnjutaFileLoader, NULL);
64 g_return_if_fail (loader != NULL);
66 ianjuta_file_loader_load (loader, G_FILE(object), FALSE, NULL);
69 g_object_unref(object);
73 static void
74 on_quick_open_activate(GtkAction *action, QuickOpenPlugin *self)
76 gtk_widget_show(GTK_WIDGET(self->dialog));
79 static void
80 project_node_foreach_func(AnjutaProjectNode *node, gpointer data)
82 GSList** project_files = data;
83 AnjutaProjectNodeType type;
85 type = anjuta_project_node_get_node_type(node);
87 if (type == ANJUTA_PROJECT_SOURCE)
89 GFile* file;
91 file = anjuta_project_node_get_file(node);
92 *project_files = g_slist_prepend(*project_files, file);
96 static void
97 quick_open_plugin_load_project_files(QuickOpenPlugin* self, IAnjutaProject* project)
99 AnjutaProjectNode* root;
100 GSList* project_files = NULL;
102 root = ianjuta_project_get_root (project, NULL);
104 anjuta_project_node_foreach(root, G_POST_ORDER, project_node_foreach_func, &project_files);
105 quick_open_dialog_add_project_files(self->dialog, project_files);
106 g_slist_free(project_files);
109 static void
110 on_project_loaded(IAnjutaProjectManager *project_manager, GError *error, gpointer user_data)
112 QuickOpenPlugin* self = user_data;
114 IAnjutaProject* project;
116 project = ianjuta_project_manager_get_current_project(project_manager, NULL);
117 quick_open_plugin_load_project_files(self, project);
120 static void
121 quick_open_plugin_project_added(QuickOpenPlugin* self, IAnjutaProject* project)
123 AnjutaProjectNode* root;
124 GFile* project_root;
126 root = ianjuta_project_get_root(project, NULL);
127 project_root = anjuta_project_node_get_file(root);
128 quick_open_dialog_set_project_root(self->dialog, project_root);
130 if (ianjuta_project_is_loaded(project, NULL))
131 quick_open_plugin_load_project_files(self, project);
134 static void
135 current_project_added(AnjutaPlugin *plugin, const char *name, const GValue *value, gpointer user_data)
137 QuickOpenPlugin* self = ANJUTA_PLUGIN_QUICK_OPEN(plugin);
139 IAnjutaProject* project = g_value_get_object(value);
140 quick_open_plugin_project_added(self, project);
143 static void
144 current_project_removed(AnjutaPlugin *plugin, const char *name, gpointer user_data)
146 QuickOpenPlugin* self = ANJUTA_PLUGIN_QUICK_OPEN(plugin);
148 quick_open_dialog_set_project_root(self->dialog, NULL);
151 static void
152 quick_open_plugin_setup_project_handling(QuickOpenPlugin* self)
154 IAnjutaProject* project;
156 self->project_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN(self)->shell,
157 IAnjutaProjectManager, NULL);
158 g_return_if_fail(self->project_manager);
160 g_object_add_weak_pointer(G_OBJECT(self->project_manager), (void**)&self->project_manager);
162 /* Connect to project manager events. */
163 self->project_watch_id = anjuta_plugin_add_watch(ANJUTA_PLUGIN(self),
164 IANJUTA_PROJECT_MANAGER_CURRENT_PROJECT,
165 current_project_added, current_project_removed, self);
167 g_signal_connect(self->project_manager, "project-loaded",
168 G_CALLBACK (on_project_loaded), self);
170 project = ianjuta_project_manager_get_current_project (self->project_manager, NULL);
171 if (project)
172 quick_open_plugin_project_added(self, project);
175 static void
176 on_document_removed(IAnjutaDocumentManager* docman, IAnjutaDocument* doc, gpointer user_data)
178 QuickOpenPlugin* self = user_data;
180 quick_open_dialog_remove_document(self->dialog, doc);
183 static void
184 on_document_added(IAnjutaDocumentManager* docman, IAnjutaDocument* doc, gpointer user_data)
186 QuickOpenPlugin* self = user_data;
188 quick_open_dialog_add_document(self->dialog, doc);
191 static void
192 quick_open_plugin_setup_document_handling(QuickOpenPlugin* self)
194 GList* documents, *l;
196 self->docman = anjuta_shell_get_interface(ANJUTA_PLUGIN(self)->shell,
197 IAnjutaDocumentManager, NULL);
198 g_return_if_fail(self->docman);
200 g_object_add_weak_pointer(G_OBJECT(self->docman), (void**)&self->docman);
202 documents = ianjuta_document_manager_get_doc_widgets(self->docman, NULL);
203 for (l = documents; l; l = l->next)
205 IAnjutaDocument* doc = IANJUTA_DOCUMENT(l->data);
206 quick_open_dialog_add_document(self->dialog, doc);
208 g_list_free(documents);
210 g_signal_connect(self->docman, "document-added", G_CALLBACK(on_document_added), self);
211 g_signal_connect(self->docman, "document-removed", G_CALLBACK(on_document_removed), self);
214 /* Actions table
215 *---------------------------------------------------------------------------*/
217 static GtkActionEntry actions_quick_open[] = {
219 "ActionQuickOpen",
220 GTK_STOCK_OPEN,
221 N_("Quick open"),
222 "<Control><Alt>o",
223 N_("Quickly open a file in the current project."),
224 G_CALLBACK(on_quick_open_activate)
228 /* AnjutaPlugin functions
229 *---------------------------------------------------------------------------*/
231 static gboolean
232 quick_open_plugin_activate(AnjutaPlugin *plugin)
234 QuickOpenPlugin *self = ANJUTA_PLUGIN_QUICK_OPEN(plugin);
236 AnjutaUI* ui;
238 DEBUG_PRINT("%s", "Quick Open Plugin: Activating plugin…");
240 /* Add actions */
241 ui = anjuta_shell_get_ui(plugin->shell, NULL);
242 self->action_group = anjuta_ui_add_action_group_entries(ui,
243 "ActionsQuickOpen", _("Quick open operations"),
244 actions_quick_open, G_N_ELEMENTS(actions_quick_open),
245 GETTEXT_PACKAGE, TRUE, self);
247 self->uiid = anjuta_ui_merge(ui, UI_FILE);
250 /* Create the dialog. */
251 self->dialog = quick_open_dialog_new();
252 gtk_window_set_transient_for(GTK_WINDOW(self->dialog), GTK_WINDOW(plugin->shell));
254 g_signal_connect(self->dialog, "delete-event",
255 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
256 g_signal_connect(self->dialog, "response",
257 G_CALLBACK(on_dialog_response), self);
259 quick_open_plugin_setup_project_handling(self);
260 quick_open_plugin_setup_document_handling(self);
263 return TRUE;
266 static gboolean
267 quick_open_plugin_deactivate(AnjutaPlugin *plugin)
269 QuickOpenPlugin *self = ANJUTA_PLUGIN_QUICK_OPEN(plugin);
271 AnjutaUI *ui;
273 DEBUG_PRINT("%s", "Quick Open Plugin: Deactivating plugin…");
275 ui = anjuta_shell_get_ui(plugin->shell, NULL);
276 anjuta_ui_remove_action_group(ui, self->action_group);
278 anjuta_ui_unmerge(ui, self->uiid);
280 anjuta_plugin_remove_watch(plugin, self->project_watch_id, FALSE);
282 /* Disconnect signals. */
283 if (self->project_manager)
285 g_signal_handlers_disconnect_by_func(self->project_manager, on_project_loaded, self);
286 g_object_remove_weak_pointer(G_OBJECT(self->project_manager), (void**)&self->project_manager);
287 self->project_manager = NULL;
290 if (self->docman)
292 g_signal_handlers_disconnect_by_func(self->docman, on_document_added, self);
293 g_signal_handlers_disconnect_by_func(self->docman, on_document_removed, self);
294 g_object_remove_weak_pointer(G_OBJECT(self->docman), (void**)&self->docman);
295 self->docman = NULL;
298 gtk_widget_destroy(GTK_WIDGET(self->dialog));
300 return TRUE;
303 /* GObject functions
304 *---------------------------------------------------------------------------*/
306 /* Used in dispose and finalize */
307 static gpointer parent_class;
309 static void
310 quick_open_plugin_instance_init(GObject *obj)
314 static void
315 quick_open_plugin_finalize(GObject *obj)
317 G_OBJECT_CLASS(parent_class)->finalize(obj);
320 static void
321 quick_open_plugin_class_init(GObjectClass *klass)
323 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS(klass);
325 parent_class = g_type_class_peek_parent(klass);
327 plugin_class->activate = quick_open_plugin_activate;
328 plugin_class->deactivate = quick_open_plugin_deactivate;
329 klass->finalize = quick_open_plugin_finalize;
332 /* AnjutaPlugin declaration
333 *---------------------------------------------------------------------------*/
335 ANJUTA_PLUGIN_BEGIN(QuickOpenPlugin, quick_open_plugin);
336 ANJUTA_PLUGIN_END;
338 ANJUTA_SIMPLE_PLUGIN(QuickOpenPlugin, quick_open_plugin);