Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / file-manager / plugin.c
blob6436fc2729963178f9bebf472490840025f7c3bd
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * plugin.c
4 * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
5 *
6 * plugin.c is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
13 * plugin.c is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with plugin.c. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
25 #include <config.h>
26 #include <gio/gio.h>
27 #include <libanjuta/anjuta-shell.h>
28 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/anjuta-preferences.h>
30 #include <libanjuta/interfaces/ianjuta-file-loader.h>
31 #include <libanjuta/interfaces/ianjuta-file-manager.h>
32 #include <libanjuta/interfaces/ianjuta-vcs.h>
33 #include <libanjuta/interfaces/ianjuta-project-manager.h>
34 #include <libanjuta/interfaces/ianjuta-preferences.h>
35 #include <libanjuta/interfaces/ianjuta-document.h>
36 #include <libanjuta/interfaces/ianjuta-document-manager.h>
37 #include <libanjuta/interfaces/ianjuta-file.h>
38 #include "plugin.h"
40 #define UI_FILE PACKAGE_DATA_DIR"/ui/file-manager.xml"
41 #define ICON_FILE "anjuta-file-manager-plugin-48.png"
42 #define FILE_MANAGER_BUILDER PACKAGE_DATA_DIR"/glade/file-manager.ui"
43 #define FILE_MANAGER_BUILDER_ROOT "filemanager_prefs"
45 #define PREF_SCHEMA "org.gnome.anjuta.file-manager"
46 #define PREF_ROOT "filemanager-root"
47 #define PREF_FILTER_BINARY "filemanager-filter-binary"
48 #define PREF_FILTER_HIDDEN "filemanager-filter-hidden"
49 #define PREF_FILTER_BACKUP "filemanager-filter-backup"
50 #define PREF_FILTER_UNVERSIONED "filemanager-filter-unversioned"
51 #define PREF_SELECT_CURRENT_DOCUMENT "filemanager-select-current-document"
53 #define REGISTER_NOTIFY(key, func) \
54 notify_id = anjuta_preferences_notify_add (prefs, \
55 key, func, file_manager); \
56 file_manager->notify_ids = g_list_prepend (file_manager->notify_ids, \
57 GUINT_TO_POINTER(notify_id));
59 static gpointer parent_class;
61 typedef struct _ScrollPosition ScrollPosition;
62 struct _ScrollPosition
64 GtkWidget* window;
65 gdouble hvalue;
66 gdouble vvalue;
69 static void
70 on_show_in_file_manager (GtkAction* action, AnjutaFileManager* file_manager)
72 IAnjutaDocumentManager* docman;
73 IAnjutaDocument* document;
74 GFile* file;
76 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (file_manager)->shell,
77 IAnjutaDocumentManager, NULL);
78 g_return_if_fail (docman);
80 document = ianjuta_document_manager_get_current_document (docman, NULL);
81 if (!IANJUTA_IS_FILE (document))
82 return;
84 file = ianjuta_file_get_file (IANJUTA_FILE (document), NULL);
85 if (!file)
86 return;
88 file_view_set_selected (file_manager->fv, file);
89 g_object_unref (file);
91 anjuta_shell_present_widget (ANJUTA_PLUGIN (file_manager)->shell,
92 file_manager->sw, NULL);
95 static void
96 on_file_manager_rename (GtkAction* action, AnjutaFileManager* file_manager)
98 file_view_rename (file_manager->fv);
101 static GtkActionEntry popup_actions[] =
104 "ActionPopupFileManagerRename", NULL,
105 N_("_Rename"), NULL, N_("Rename file or directory"),
106 G_CALLBACK (on_file_manager_rename)
109 "ActionPopupShowInFileManager", NULL,
110 N_("_Show in File manager"), NULL, N_("Show in File manager"),
111 G_CALLBACK (on_show_in_file_manager)
115 static void
116 file_manager_set_default_uri (AnjutaFileManager* file_manager)
118 gchar* path = g_settings_get_string (file_manager->settings, PREF_ROOT);
120 if (path)
122 GFile *base_path;
124 base_path = g_file_new_for_path (path);
125 g_object_set (G_OBJECT (file_manager->fv), "base-path", base_path, NULL);
126 g_object_unref (base_path);
128 file_manager->have_project = FALSE;
130 g_free(path);
133 static void
134 refresh_signal_cb(IAnjutaVcs* ivcs, gpointer data)
136 AnjutaFileManager* file_manager = ANJUTA_FILE_MANAGER(data);
137 file_view_refresh_vcs (file_manager->fv);
140 static IAnjutaVcs*
141 get_vcs_plugin(AnjutaFileManager* file_manager, const gchar* root_uri)
143 typedef struct
145 const gchar* file;
146 const gchar* name;
147 } VcsSystem;
148 VcsSystem vcs_systems[] = {
149 {".svn", "Subversion"},
150 {".git", "Git"},
151 {NULL, NULL}
154 gint i;
155 const gchar* vcs_system = NULL;
156 IAnjutaVcs* ivcs = NULL;
157 for (i = 0; vcs_systems[i].name != NULL; i++)
159 gchar* vcs_uri = g_build_filename (root_uri, vcs_systems[i].file, NULL);
160 GFile* vcs_file = g_file_new_for_uri (vcs_uri);
161 if (g_file_query_exists(vcs_file, NULL))
163 vcs_system = vcs_systems[i].name;
165 g_free (vcs_uri);
166 g_object_unref (vcs_file);
167 if (vcs_system)
168 break;
171 if (vcs_system)
173 /* Load current language editor support plugins */
174 AnjutaPluginManager* plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN(file_manager)->shell, NULL);
175 GList* plugin_handles = anjuta_plugin_manager_query (plugin_manager,
176 "Anjuta Plugin",
177 "Interfaces",
178 "IAnjutaVcs",
179 "Vcs",
180 "System",
181 vcs_system, NULL);
182 if (plugin_handles)
184 ivcs = IANJUTA_VCS(anjuta_plugin_manager_get_plugin_by_handle (plugin_manager,
185 (AnjutaPluginHandle *)plugin_handles->data));
187 g_signal_connect (G_OBJECT (ivcs), "status_changed",
188 G_CALLBACK (refresh_signal_cb),
189 file_manager);
191 g_list_free (plugin_handles);
194 return ivcs;
197 static void
198 current_document_added (AnjutaPlugin *plugin, const gchar *name,
199 const GValue *value, gpointer user_data)
201 AnjutaFileManager* file_manager = (AnjutaFileManager*) plugin;
202 IAnjutaDocument *current_document;
203 GFile *file;
205 if (!g_settings_get_boolean (file_manager->settings, PREF_SELECT_CURRENT_DOCUMENT))
206 return;
208 current_document = g_value_get_object (value);
209 if (!IANJUTA_IS_FILE (current_document))
210 return;
212 file = ianjuta_file_get_file (IANJUTA_FILE (current_document), NULL);
213 if (!file)
214 return;
216 ianjuta_file_manager_set_selected (IANJUTA_FILE_MANAGER (plugin), file, NULL);
217 g_object_unref (file);
220 static void
221 current_document_removed (AnjutaPlugin *plugin, const gchar *name,
222 gpointer user_data)
226 static void
227 project_root_added (AnjutaPlugin *plugin, const gchar *name,
228 const GValue *value, gpointer user_data)
230 AnjutaFileManager* file_manager;
231 GtkTreeModelSort *tree_model;
232 FileModel *file_model;
233 const gchar *root_uri;
235 file_manager = (AnjutaFileManager*) plugin;
236 tree_model = GTK_TREE_MODEL_SORT (
237 gtk_tree_view_get_model (GTK_TREE_VIEW (file_manager->fv)));
238 file_model = FILE_MODEL (gtk_tree_model_sort_get_model (tree_model));
240 root_uri = g_value_get_string (value);
241 if (root_uri)
243 GFile *base_path;
245 base_path = g_file_new_for_uri (root_uri);
246 g_object_set (G_OBJECT(file_manager->fv), "base-path", base_path, NULL);
247 g_object_unref (base_path);
249 file_model_set_ivcs (file_model, get_vcs_plugin (file_manager,
250 root_uri));
252 file_view_refresh (file_manager->fv);
253 file_manager->have_project = TRUE;
255 else
257 file_model_set_ivcs(file_model, NULL);
258 file_manager_set_default_uri (file_manager);
259 file_view_refresh (file_manager->fv);
263 static void
264 project_root_removed (AnjutaPlugin *plugin, const gchar *name,
265 gpointer user_data)
267 AnjutaFileManager* file_manager = (AnjutaFileManager*) plugin;
268 file_manager_set_default_uri (file_manager);
269 file_view_refresh (file_manager->fv);
272 static void
273 on_file_view_current_file_changed (AnjutaFileView* view, GFile* file,
274 AnjutaFileManager* file_manager)
276 if (file)
278 GValue* value;
279 value = g_new0 (GValue, 1);
280 g_value_init (value, G_TYPE_FILE);
281 g_value_set_object (value, file);
282 anjuta_shell_add_value (ANJUTA_PLUGIN (file_manager)->shell,
283 IANJUTA_FILE_MANAGER_SELECTED_FILE, value, NULL);
284 g_value_unset (value);
286 else
288 anjuta_shell_remove_value (ANJUTA_PLUGIN(file_manager)->shell,
289 IANJUTA_FILE_MANAGER_SELECTED_FILE, NULL);
293 static void
294 on_file_view_open_file (AnjutaFileView* view, GFile* file,
295 AnjutaFileManager* file_manager)
297 IAnjutaFileLoader *loader;
298 g_return_if_fail (file != NULL);
299 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (file_manager)->shell,
300 IAnjutaFileLoader, NULL);
301 g_return_if_fail (loader != NULL);
303 ianjuta_file_loader_load (loader, file, FALSE, NULL);
306 static void
307 on_file_view_show_popup_menu (AnjutaFileView* view, GFile* file,
308 gboolean is_dir, guint button,
309 guint32 time, AnjutaFileManager* file_manager)
311 GtkWidget *popup;
312 AnjutaUI* ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(file_manager)->shell,
313 NULL);
314 popup = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
315 "/PopupFileManager");
317 g_return_if_fail (GTK_IS_WIDGET (popup));
318 gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, button, time);
321 static void
322 on_notify_root(GSettings* settings,
323 const gchar* key,
324 gpointer user_data)
326 AnjutaFileManager* file_manager = (AnjutaFileManager*) user_data;
327 if (!file_manager->have_project)
329 file_manager_set_default_uri (file_manager);
330 file_view_refresh (file_manager->fv);
334 static void
335 on_notify(GSettings* settings,
336 const gchar* key,
337 gpointer user_data)
339 AnjutaFileManager* file_manager = (AnjutaFileManager*) user_data;
340 GtkTreeModel* sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (file_manager->fv));
341 GtkTreeModel* file_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
343 g_object_set (G_OBJECT (file_model),
344 "filter_binary", g_settings_get_boolean (settings, PREF_FILTER_BINARY),
345 "filter_hidden", g_settings_get_boolean (settings, PREF_FILTER_HIDDEN),
346 "filter_backup", g_settings_get_boolean (settings, PREF_FILTER_BACKUP),
347 "filter_unversioned", g_settings_get_boolean (settings, PREF_FILTER_UNVERSIONED), NULL);
348 file_view_refresh (file_manager->fv);
351 static gboolean
352 file_manager_activate (AnjutaPlugin *plugin)
354 AnjutaUI *ui;
355 AnjutaFileManager *file_manager;
357 DEBUG_PRINT ("%s", "AnjutaFileManager: Activating AnjutaFileManager plugin ...");
358 file_manager = (AnjutaFileManager*) plugin;
360 /* Add all UI actions and merge UI */
361 ui = anjuta_shell_get_ui (plugin->shell, NULL);
363 /* Add action group */
364 file_manager->action_group =
365 anjuta_ui_add_action_group_entries (ui, "ActionGroupFileManager",
366 _("File manager popup actions"),
367 popup_actions, G_N_ELEMENTS (popup_actions),
368 GETTEXT_PACKAGE, FALSE,
369 plugin);
371 file_manager->uiid = anjuta_ui_merge (ui, UI_FILE);
373 file_manager->sw = gtk_scrolled_window_new (NULL, NULL);
374 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (file_manager->sw),
375 GTK_POLICY_AUTOMATIC,
376 GTK_POLICY_AUTOMATIC);
377 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (file_manager->sw),
378 GTK_SHADOW_IN);
380 file_manager->fv = ANJUTA_FILE_VIEW (file_view_new ());
382 g_signal_connect (G_OBJECT (file_manager->fv), "file-open",
383 G_CALLBACK (on_file_view_open_file), file_manager);
384 g_signal_connect (G_OBJECT(file_manager->fv), "show-popup-menu",
385 G_CALLBACK (on_file_view_show_popup_menu), file_manager);
386 g_signal_connect (G_OBJECT(file_manager->fv), "current-file-changed",
387 G_CALLBACK (on_file_view_current_file_changed),
388 file_manager);
389 file_manager_set_default_uri (file_manager);
390 file_view_refresh (file_manager->fv);
392 gtk_container_add (GTK_CONTAINER (file_manager->sw),
393 GTK_WIDGET (file_manager->fv));
395 gtk_widget_show_all (file_manager->sw);
397 anjuta_shell_add_widget (plugin->shell, file_manager->sw,
398 "AnjutaFileManager",
399 _("Files"), GTK_STOCK_OPEN,
400 ANJUTA_SHELL_PLACEMENT_LEFT, NULL);
402 file_manager->root_watch_id =
403 anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
404 project_root_added,
405 project_root_removed, NULL);
407 file_manager->current_document_watch_id =
408 anjuta_plugin_add_watch (plugin, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
409 current_document_added, current_document_removed, NULL);
412 g_signal_connect (file_manager->settings, "changed::" PREF_ROOT,
413 G_CALLBACK (on_notify_root), file_manager);
414 g_signal_connect (file_manager->settings, "changed::" PREF_FILTER_BINARY,
415 G_CALLBACK (on_notify), file_manager);
416 g_signal_connect (file_manager->settings, "changed::" PREF_FILTER_HIDDEN,
417 G_CALLBACK (on_notify), file_manager);
418 g_signal_connect (file_manager->settings, "changed::" PREF_FILTER_BACKUP,
419 G_CALLBACK (on_notify), file_manager);
420 g_signal_connect (file_manager->settings, "changed::" PREF_FILTER_UNVERSIONED,
421 G_CALLBACK (on_notify), file_manager);
422 on_notify (file_manager->settings, NULL, file_manager);
424 return TRUE;
427 static gboolean
428 file_manager_deactivate (AnjutaPlugin *plugin)
430 AnjutaUI *ui;
431 AnjutaFileManager *file_manager;
433 DEBUG_PRINT ("%s", "AnjutaFileManager: Dectivating AnjutaFileManager plugin ...");
435 file_manager = (AnjutaFileManager*) plugin;
436 ui = anjuta_shell_get_ui (plugin->shell, NULL);
438 anjuta_plugin_remove_watch (plugin, file_manager->root_watch_id, TRUE);
439 anjuta_plugin_remove_watch (plugin, file_manager->current_document_watch_id, FALSE);
440 anjuta_ui_remove_action_group (ui, ((AnjutaFileManager*)plugin)->action_group);
441 anjuta_ui_unmerge (ui, ((AnjutaFileManager*)plugin)->uiid);
443 anjuta_shell_remove_widget (plugin->shell, file_manager->sw, NULL);
444 return TRUE;
447 static void
448 file_manager_finalize (GObject *obj)
450 /* Finalization codes here */
451 G_OBJECT_CLASS (parent_class)->finalize (obj);
454 static void
455 file_manager_dispose (GObject *obj)
457 AnjutaFileManager *plugin = (AnjutaFileManager*)obj;
458 g_object_unref (plugin->settings);
460 /* Disposition codes */
461 G_OBJECT_CLASS (parent_class)->dispose (obj);
464 static void
465 file_manager_instance_init (GObject *obj)
467 AnjutaFileManager *plugin = (AnjutaFileManager*)obj;
469 plugin->settings = g_settings_new (PREF_SCHEMA);
470 plugin->have_project = FALSE;
472 plugin->uiid = 0;
475 static void
476 file_manager_class_init (GObjectClass *klass)
478 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
480 parent_class = g_type_class_peek_parent (klass);
482 plugin_class->activate = file_manager_activate;
483 plugin_class->deactivate = file_manager_deactivate;
485 klass->finalize = file_manager_finalize;
486 klass->dispose = file_manager_dispose;
489 static void
490 ifile_manager_set_root (IAnjutaFileManager *ifile_manager, const gchar *root,
491 GError **err)
493 AnjutaFileManager* file_manager = (AnjutaFileManager*) ifile_manager;
494 GFile *base_path = g_file_new_for_uri (root);
495 g_object_set (G_OBJECT(file_manager->fv), "base-path", base_path, NULL);
496 g_object_unref (base_path);
499 static void
500 ifile_manager_set_selected (IAnjutaFileManager *ifile_manager,
501 GFile* selected, GError **err)
503 AnjutaFileManager* file_manager = (AnjutaFileManager*) ifile_manager;
505 file_view_set_selected (file_manager->fv, selected);
508 static GFile*
509 ifile_manager_get_selected (IAnjutaFileManager *ifile_manager, GError **err)
511 AnjutaFileManager* file_manager = (AnjutaFileManager*) ifile_manager;
512 return file_view_get_selected (file_manager->fv);
515 static void
516 ifile_manager_iface_init (IAnjutaFileManagerIface *iface)
518 iface->set_root = ifile_manager_set_root;
519 iface->get_selected = ifile_manager_get_selected;
520 iface->set_selected = ifile_manager_set_selected;
523 static void
524 ipreferences_merge (IAnjutaPreferences* ipref,
525 AnjutaPreferences* prefs,
526 GError** e)
528 GError* error = NULL;
529 GtkBuilder* bxml = gtk_builder_new ();
530 AnjutaFileManager* fm = (AnjutaFileManager*) ipref;
532 if (!gtk_builder_add_from_file (bxml, FILE_MANAGER_BUILDER, &error))
534 g_warning ("Couldn't load builder file: %s", error->message);
535 g_error_free (error);
538 anjuta_preferences_add_from_builder (prefs, bxml, fm->settings, FILE_MANAGER_BUILDER_ROOT, _("File Manager"),
539 ICON_FILE);
542 static void
543 ipreferences_unmerge (IAnjutaPreferences* ipref,
544 AnjutaPreferences* prefs,
545 GError** e)
547 anjuta_preferences_remove_page (prefs, _("File Manager"));
550 static void
551 ipreferences_iface_init (IAnjutaPreferencesIface* iface)
553 iface->merge = ipreferences_merge;
554 iface->unmerge = ipreferences_unmerge;
557 ANJUTA_PLUGIN_BEGIN (AnjutaFileManager, file_manager);
558 ANJUTA_PLUGIN_ADD_INTERFACE (ifile_manager, IANJUTA_TYPE_FILE_MANAGER);
559 ANJUTA_PLUGIN_ADD_INTERFACE (ipreferences, IANJUTA_TYPE_PREFERENCES);
560 ANJUTA_PLUGIN_END
562 ANJUTA_SIMPLE_PLUGIN (AnjutaFileManager, file_manager);