Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / file-loader / plugin.c
blob9eaedebd42934cc40b95427f297f8dfd36cd6880
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2004 Naba Kumar
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 <stdlib.h>
24 #include <unistd.h>
25 #include <glib/gi18n.h>
27 #include <libanjuta/anjuta-shell.h>
28 #include <libanjuta/anjuta-status.h>
29 #include <libanjuta/anjuta-debug.h>
31 #include <libanjuta/interfaces/ianjuta-file.h>
32 #include <libanjuta/interfaces/ianjuta-file-loader.h>
33 #include <libanjuta/interfaces/ianjuta-document-manager.h>
34 #include <libanjuta/interfaces/ianjuta-file-manager.h>
35 #include <libanjuta/interfaces/ianjuta-project-manager.h>
36 #include <libanjuta/interfaces/ianjuta-wizard.h>
38 #include "plugin.h"
39 #include "dnd.h"
40 #include "anjuta-recent-chooser-menu.h"
42 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-loader-plugin.ui"
44 static gpointer parent_class;
46 static int
47 sort_wizards(gconstpointer wizard1, gconstpointer wizard2)
49 gchar* name1 = NULL, *name2 = NULL;
50 gint ret;
51 AnjutaPluginHandle* handle1 = (AnjutaPluginHandle*) wizard1;
52 AnjutaPluginHandle* handle2 = (AnjutaPluginHandle*) wizard2;
53 AnjutaPluginDescription* desc1 = anjuta_plugin_handle_get_description (handle1);
54 AnjutaPluginDescription* desc2 = anjuta_plugin_handle_get_description (handle2);
56 if ((anjuta_plugin_description_get_locale_string (desc1, "Wizard",
57 "Title", &name1) ||
58 anjuta_plugin_description_get_locale_string (desc1, "Anjuta Plugin",
59 "Name", &name1)) &&
60 (anjuta_plugin_description_get_locale_string (desc2, "Wizard",
61 "Title", &name2) ||
62 anjuta_plugin_description_get_locale_string (desc2, "Anjuta Plugin",
63 "Name", &name2)))
65 ret = strcmp(name1, name2);
67 else
68 ret = 0;
70 g_free(name1);
71 g_free(name2);
73 return ret;
76 /* The add argument is here to remember that recent menu items should be removed
77 * when the destination does not exist anymore */
78 static void
79 update_recent_file (AnjutaFileLoaderPlugin *plugin, const gchar *uri,
80 const gchar *mime, gboolean add)
83 if (add)
85 GtkRecentData *recent_data;
87 recent_data = g_slice_new (GtkRecentData);
89 recent_data->display_name = NULL;
90 recent_data->description = NULL;
91 recent_data->mime_type = (gchar *)mime;
92 recent_data->app_name = (gchar *) g_get_application_name ();
93 recent_data->app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
94 recent_data->groups = NULL;
95 recent_data->is_private = FALSE;
97 if (!gtk_recent_manager_add_full (plugin->recent_manager, uri, recent_data))
99 g_warning ("Unable to add '%s' to the list of recently used documents", uri);
102 g_free (recent_data->app_exec);
103 g_slice_free (GtkRecentData, recent_data);
105 else
107 gtk_recent_manager_remove_item (plugin->recent_manager, uri, NULL);
112 static void
113 launch_application_failure (AnjutaFileLoaderPlugin *plugin,
114 const gchar *uri,
115 const gchar *errmsg)
117 GtkWidget *parent;
118 gchar *basename;
120 parent =
121 gtk_widget_get_toplevel (GTK_WIDGET(ANJUTA_PLUGIN (plugin)->shell));
122 basename = g_path_get_basename (uri);
123 anjuta_util_dialog_error (GTK_WINDOW (parent),
124 _("Cannot open \"%s\".\n\n%s"),
125 basename, errmsg);
126 g_free (basename);
129 static GList *
130 get_available_plugins_for_mime (AnjutaPlugin* plugin,
131 const gchar *mime_type)
133 AnjutaPluginManager *plugin_manager;
134 GList *plugin_handles = NULL;
135 gchar *content_type;
137 g_return_val_if_fail (mime_type != NULL, NULL);
139 plugin_manager = anjuta_shell_get_plugin_manager (plugin->shell,
140 NULL);
142 /* Check an exact match */
143 plugin_handles = anjuta_plugin_manager_query (plugin_manager,
144 "Anjuta Plugin",
145 "Interfaces", "IAnjutaFile",
146 "File Loader",
147 "SupportedMimeTypes",
148 mime_type,
149 NULL);
151 /* Check for plugins supporting one supertype */
152 content_type = g_content_type_from_mime_type (mime_type);
153 if (plugin_handles == NULL)
155 GList *node;
156 GList *loader_handles = NULL;
158 loader_handles = anjuta_plugin_manager_query (plugin_manager,
159 "Anjuta Plugin",
160 "Interfaces", "IAnjutaFile",
161 NULL);
162 for (node = g_list_first (loader_handles); node != NULL; node = g_list_next (node))
164 gchar *value;
165 AnjutaPluginHandle *handle;
166 AnjutaPluginDescription *desc;
168 handle = (AnjutaPluginHandle *)node->data;
169 desc = anjuta_plugin_handle_get_description (handle);
170 if (anjuta_plugin_description_get_string (desc,
171 "File Loader", "SupportedMimeTypes", &value))
173 gchar **split_value;
175 split_value = g_strsplit (value, ",", -1);
176 g_free (value);
177 if (split_value)
179 gchar **mime;
181 for (mime = split_value; *mime != NULL; mime++)
183 gchar *supertype = g_content_type_from_mime_type (*mime);
185 if (g_content_type_is_a (content_type, supertype))
187 plugin_handles = g_list_prepend (plugin_handles, handle);
189 g_free (supertype);
191 break;
194 g_free (supertype);
197 g_strfreev (split_value);
200 g_list_free (loader_handles);
201 plugin_handles = g_list_reverse (plugin_handles);
203 g_free (content_type);
205 return plugin_handles;
208 static gboolean
209 RowSeparatorFunc (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
211 int n = GPOINTER_TO_INT(data), k;
212 gchar *path = gtk_tree_model_get_string_from_iter (model, iter);
213 sscanf (path, "%d", &k);
214 g_free (path);
215 return n == k;
218 static void
219 on_value_added_current_doc (AnjutaPlugin *plugin, const gchar *name,
220 const GValue *value, gpointer data)
222 AnjutaFileLoaderPlugin *fplugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
223 IAnjutaDocument* doc = IANJUTA_DOCUMENT(g_value_get_object (value));
224 GFile *file;
226 g_free (fplugin->dm_current_uri);
228 if (IANJUTA_IS_FILE (doc) &&
229 ((file = ianjuta_file_get_file(IANJUTA_FILE (doc), NULL)) != NULL))
231 GFile* parent = g_file_get_parent (file);
232 fplugin->dm_current_uri = g_file_get_uri (parent);
233 g_object_unref (parent);
234 g_object_unref (file);
236 else
239 fplugin->dm_current_uri = NULL;
243 static void
244 on_value_removed_current_doc (AnjutaPlugin *plugin, const gchar *name,
245 gpointer data)
247 AnjutaFileLoaderPlugin *fplugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
248 g_free (fplugin->dm_current_uri);
249 fplugin->dm_current_uri = NULL;
252 static void
253 open_with_dialog (AnjutaFileLoaderPlugin *plugin, const gchar *uri,
254 const gchar *mime_type)
256 GList *plugin_handles, *snode;
257 GList *mime_apps, *node;
258 GAppInfo *mime_app;
260 GtkWidget *dialog, *parent, *hbox, *label;
261 GtkWidget *options;
262 gchar *message;
263 gchar *basename;
264 gint col = -1;
265 AnjutaPluginManager *plugin_manager;
267 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell,
268 NULL);
269 basename = g_path_get_basename (uri);
270 message = g_strdup_printf (_("<b>Cannot open \"%s\"</b>.\n\n"
271 "There is no plugin, default action, or application "
272 "configured to handle this file type.\n"
273 "\n"
274 "MIME type: %s\n"
275 "\n"
276 "You may choose to try opening it with the following "
277 "plugins or applications."),
278 basename, mime_type);
279 g_free (basename);
281 parent =
282 gtk_widget_get_toplevel (GTK_WIDGET(ANJUTA_PLUGIN (plugin)->shell));
283 dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (parent),
284 GTK_DIALOG_DESTROY_WITH_PARENT,
285 GTK_MESSAGE_INFO,
286 GTK_BUTTONS_OK_CANCEL, "%s",
287 message);
288 g_free (message);
290 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
291 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
292 hbox, FALSE, FALSE, 5);
293 label = gtk_label_new (_("Open with:"));
294 options = gtk_combo_box_text_new ();
295 gtk_box_pack_end (GTK_BOX(hbox), options, FALSE, FALSE, 10);
296 gtk_box_pack_end (GTK_BOX(hbox), label, FALSE, FALSE, 10);
298 /* Document manager plugin */
299 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), _("Document Manager"));
300 col ++;
302 /* Open with plugins menu items */
303 plugin_handles = get_available_plugins_for_mime (ANJUTA_PLUGIN (plugin), mime_type);
304 snode = plugin_handles;
305 while (snode)
307 gchar *name;
308 AnjutaPluginHandle *handle;
309 AnjutaPluginDescription *desc;
311 handle = (AnjutaPluginHandle *)(snode->data);
312 desc = anjuta_plugin_handle_get_description (handle);
314 name = NULL;
316 anjuta_plugin_description_get_locale_string (desc, "File Loader",
317 "Title", &name);
319 if (!name)
321 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
322 "Name", &name);
324 if (!name)
326 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
327 "Location", &name);
329 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), name);
330 col ++;
331 g_free (name);
332 snode = g_list_next (snode);
335 /* Open with application menu items */
336 mime_apps = g_app_info_get_all_for_type (mime_type);
337 if (mime_apps)
339 /* Separator */
340 col++;
341 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), "");
342 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (options), RowSeparatorFunc, GINT_TO_POINTER(col), NULL);
344 node = mime_apps;
345 while (node)
347 mime_app = (GAppInfo *)(node->data);
348 if (g_app_info_should_show (mime_app))
350 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), g_app_info_get_name (mime_app));
352 node = g_list_next (node);
354 gtk_combo_box_set_active (GTK_COMBO_BOX (options), 0);
355 gtk_widget_show_all (hbox);
357 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
359 gint option;
361 option = gtk_combo_box_get_active(GTK_COMBO_BOX (options));
362 if (option == 0)
364 IAnjutaDocumentManager *docman;
365 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
366 IAnjutaDocumentManager,
367 NULL);
368 if (docman)
370 GFile* file = g_file_new_for_uri (uri);
371 ianjuta_file_open (IANJUTA_FILE (docman), file, NULL);
372 g_object_unref (file);
374 else
376 g_warning ("No document manager plugin!!");
379 else if (option < (g_list_length (plugin_handles) + 1))
381 AnjutaPluginHandle *handle;
382 GObject *loaded_plugin;
384 option--;
385 handle = (AnjutaPluginHandle *)g_list_nth_data (plugin_handles, option);
387 loaded_plugin =anjuta_plugin_manager_get_plugin_by_handle (plugin_manager,
388 handle);
389 if (loaded_plugin)
391 GFile* file = g_file_new_for_uri (uri);
392 ianjuta_file_open (IANJUTA_FILE (loaded_plugin), file, NULL);
393 update_recent_file (plugin, uri, mime_type, TRUE);
394 g_object_unref (file);
396 else
398 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
399 "Failed to activate plugin: %s",
400 anjuta_plugin_handle_get_name (handle));
403 else
405 GList *uris = NULL;
406 GError *error = NULL;
408 option -= (g_list_length (plugin_handles) + 2);
409 mime_app = g_list_nth_data (mime_apps, option);
410 uris = g_list_prepend (uris, (gpointer)uri);
411 g_app_info_launch_uris(mime_app, uris, NULL, &error);
412 if (error)
414 launch_application_failure (plugin, uri, error->message);
415 g_error_free (error);
417 update_recent_file (plugin, uri, mime_type, error == NULL);
418 g_list_free (uris);
421 g_list_foreach (mime_apps, (GFunc) g_object_unref, NULL);
422 g_list_free (mime_apps);
423 if (plugin_handles)
424 g_list_free (plugin_handles);
425 gtk_widget_destroy (dialog);
428 static void
429 open_file (AnjutaFileLoaderPlugin *plugin, const gchar *uri)
431 GFile* file;
433 file = g_file_new_for_uri (uri);
435 ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin),
436 file, FALSE, NULL);
437 g_object_unref (file);
440 typedef struct
442 AnjutaFileLoaderPlugin *plugin;
443 const gchar *uri;
444 } RecentIdleOpenData;
446 static gboolean
447 on_open_recent_file_idle (gpointer data)
449 RecentIdleOpenData *rdata;
451 rdata = (RecentIdleOpenData*)data;
452 open_file (rdata->plugin, rdata->uri);
453 g_free (rdata);
454 return FALSE;
457 static gboolean
458 on_open_recent_file (GtkRecentChooser *chooser, AnjutaFileLoaderPlugin *plugin)
460 const gchar *uri;
461 gboolean ret = TRUE;
462 RecentIdleOpenData *rdata;
464 uri = gtk_recent_chooser_get_current_uri (chooser);
465 rdata = g_new0 (RecentIdleOpenData, 1);
466 rdata->plugin = plugin;
467 rdata->uri = uri;
468 g_idle_add (on_open_recent_file_idle, rdata);
470 return ret;
473 static void
474 on_open_response_ok (GtkDialog* dialog, gint id,
475 AnjutaFileLoaderPlugin *plugin)
477 GSList *list, *node;
479 if (id != GTK_RESPONSE_ACCEPT)
481 gtk_widget_destroy (GTK_WIDGET (dialog));
482 return;
485 list = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
486 node = list;
487 while (node)
489 if (node->data)
490 open_file (plugin, (gchar *)node->data);
491 g_free (node->data);
492 node = g_slist_next (node);
494 g_slist_free (list);
497 static void
498 setup_file_filters (GtkFileChooser *fc)
500 GtkFileFilter *filter;
502 filter = gtk_file_filter_new ();
503 gtk_file_filter_set_name (filter, _("All files"));
504 gtk_file_filter_add_pattern (filter, "*");
505 gtk_file_chooser_add_filter (fc, filter);
507 filter = gtk_file_filter_new ();
508 gtk_file_filter_set_name (filter, _("Anjuta Projects"));
509 gtk_file_filter_add_pattern (filter, "*.anjuta");
510 gtk_file_filter_add_pattern (filter, "*.prj");
511 gtk_file_chooser_add_filter (fc, filter);
513 filter = gtk_file_filter_new ();
514 gtk_file_filter_set_name (filter, _("C/C++ source files"));
515 gtk_file_filter_add_pattern (filter, "*.c");
516 gtk_file_filter_add_pattern (filter, "*.cc");
517 gtk_file_filter_add_pattern (filter, "*.cpp");
518 gtk_file_filter_add_pattern (filter, "*.cxx");
519 gtk_file_filter_add_pattern (filter, "*.c++");
520 gtk_file_filter_add_pattern (filter, "*.h");
521 gtk_file_filter_add_pattern (filter, "*.hh");
522 gtk_file_filter_add_pattern (filter, "*.hpp");
523 gtk_file_chooser_add_filter (fc, filter);
525 filter = gtk_file_filter_new ();
526 gtk_file_filter_set_name (filter, _("C# source files"));
527 gtk_file_filter_add_pattern (filter, "*.cs");
528 gtk_file_filter_add_pattern (filter, "*.h");
529 gtk_file_chooser_add_filter (fc, filter);
531 filter = gtk_file_filter_new ();
532 gtk_file_filter_set_name (filter, _("Java source files"));
533 gtk_file_filter_add_pattern (filter, "*.java");
534 gtk_file_filter_add_pattern (filter, "*.js");
535 gtk_file_chooser_add_filter (fc, filter);
537 filter = gtk_file_filter_new ();
538 gtk_file_filter_set_name (filter, _("Pascal source files"));
539 gtk_file_filter_add_pattern (filter, "*.pas");
540 gtk_file_chooser_add_filter (fc, filter);
542 filter = gtk_file_filter_new ();
543 gtk_file_filter_set_name (filter, _("PHP source files"));
544 gtk_file_filter_add_pattern (filter, "*.php");
545 gtk_file_filter_add_pattern (filter, "*.php?");
546 gtk_file_filter_add_pattern (filter, "*.phtml");
547 gtk_file_chooser_add_filter (fc, filter);
549 filter = gtk_file_filter_new ();
550 gtk_file_filter_set_name (filter, _("Perl source files"));
551 gtk_file_filter_add_pattern (filter, "*.pl");
552 gtk_file_filter_add_pattern (filter, "*.pm");
553 gtk_file_chooser_add_filter (fc, filter);
555 filter = gtk_file_filter_new ();
556 gtk_file_filter_set_name (filter, _("Python source files"));
557 gtk_file_filter_add_pattern (filter, "*.py");
558 gtk_file_chooser_add_filter (fc, filter);
560 filter = gtk_file_filter_new ();
561 gtk_file_filter_set_name (filter, _("Hypertext markup files"));
562 gtk_file_filter_add_pattern (filter, "*.htm");
563 gtk_file_filter_add_pattern (filter, "*.html");
564 gtk_file_filter_add_pattern (filter, "*.xhtml");
565 gtk_file_filter_add_pattern (filter, "*.dhtml");
566 gtk_file_filter_add_pattern (filter, "*.cs");
567 gtk_file_chooser_add_filter (fc, filter);
569 filter = gtk_file_filter_new ();
570 gtk_file_filter_set_name (filter, _("Shell script files"));
571 gtk_file_filter_add_pattern (filter, "*.sh");
572 gtk_file_chooser_add_filter (fc, filter);
574 filter = gtk_file_filter_new ();
575 gtk_file_filter_set_name (filter, _("Makefiles"));
576 gtk_file_filter_add_pattern (filter, "Makefile*");
577 gtk_file_filter_add_pattern (filter, "makefile*");
578 gtk_file_chooser_add_filter (fc, filter);
580 filter = gtk_file_filter_new ();
581 gtk_file_filter_set_name (filter, _("Lua files"));
582 gtk_file_filter_add_pattern (filter, "*.lua");
583 gtk_file_chooser_add_filter (fc, filter);
585 filter = gtk_file_filter_new ();
586 gtk_file_filter_set_name (filter, _("Diff files"));
587 gtk_file_filter_add_pattern (filter, "*.diff");
588 gtk_file_filter_add_pattern (filter, "*.patch");
589 gtk_file_filter_add_pattern (filter, "*.cvsdiff");
590 gtk_file_chooser_add_filter (fc, filter);
593 static GtkWidget*
594 create_file_open_dialog_gui(GtkWindow* parent, AnjutaFileLoaderPlugin* plugin)
596 GtkWidget* dialog =
597 gtk_file_chooser_dialog_new (_("Open file"),
598 parent,
599 GTK_FILE_CHOOSER_ACTION_OPEN,
600 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
601 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
602 NULL);
603 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
604 if (plugin->dm_current_uri)
606 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
607 plugin->dm_current_uri);
609 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
610 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
611 gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
613 setup_file_filters (GTK_FILE_CHOOSER (dialog));
615 g_signal_connect(G_OBJECT(dialog), "response",
616 G_CALLBACK(on_open_response_ok), plugin);
617 g_signal_connect_swapped (dialog,
618 "response",
619 G_CALLBACK (gtk_widget_destroy),
620 dialog);
621 return dialog;
624 static void
625 on_new_clicked (GtkToolButton *button, AnjutaFileLoaderPlugin *plugin)
627 AnjutaShell* shell = ANJUTA_PLUGIN (plugin)->shell;
628 IAnjutaDocumentManager *docman = anjuta_shell_get_interface (shell,
629 IAnjutaDocumentManager,
630 NULL);
631 if (docman)
632 ianjuta_document_manager_add_buffer (docman, NULL, NULL, NULL);
635 static void
636 on_open_clicked (GtkToolButton *button, AnjutaFileLoaderPlugin *plugin)
638 GtkWidget *dlg;
640 dlg =
641 create_file_open_dialog_gui (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
642 plugin);
643 gtk_widget_show (dlg);
646 static void
647 on_new_activate (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
649 AnjutaShell* shell = ANJUTA_PLUGIN (plugin)->shell;
650 IAnjutaDocumentManager *docman = anjuta_shell_get_interface (shell,
651 IAnjutaDocumentManager,
652 NULL);
653 if (docman)
654 ianjuta_document_manager_add_buffer (docman, NULL, NULL, NULL);
657 static void
658 on_open_activate (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
660 GtkWidget *dlg;
662 dlg =
663 create_file_open_dialog_gui (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
664 plugin);
665 gtk_widget_show (dlg);
668 static void
669 on_activate_wizard (GtkMenuItem *menuitem,
670 AnjutaFileLoaderPlugin *loader)
672 AnjutaPluginManager *plugin_manager;
673 AnjutaPluginHandle *handle;
675 handle = g_object_get_data (G_OBJECT (menuitem), "__plugin_handle");
676 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
677 NULL);
678 if (handle)
680 GObject *plugin;
682 plugin = anjuta_plugin_manager_get_plugin_by_handle (plugin_manager, handle);
683 ianjuta_wizard_activate (IANJUTA_WIZARD (plugin), NULL);
687 static GtkWidget*
688 on_create_submenu (gpointer user_data)
690 AnjutaPluginManager *plugin_manager;
691 AnjutaFileLoaderPlugin *loader;
692 GList *node;
693 gint count;
694 GtkWidget *submenu = NULL;
695 GList *plugin_handles = NULL;
697 loader = ANJUTA_PLUGIN_FILE_LOADER (user_data);
698 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
699 NULL);
700 submenu = gtk_menu_new ();
701 gtk_widget_show (submenu);
703 plugin_handles = anjuta_plugin_manager_query (plugin_manager,
704 "Anjuta Plugin",
705 "Interfaces", "IAnjutaWizard",
706 NULL);
707 plugin_handles = g_list_sort(plugin_handles, sort_wizards);
708 node = plugin_handles;
709 count = 0;
710 while (node)
712 AnjutaPluginHandle *handle;
713 AnjutaPluginDescription *desc;
714 GtkWidget *menuitem;
715 GtkWidget *icon;
716 gchar *str, *icon_path, *name;
718 handle = node->data;
719 desc = anjuta_plugin_handle_get_description (handle);
721 icon = NULL;
722 name = NULL;
723 if (anjuta_plugin_description_get_locale_string (desc, "Wizard",
724 "Title", &str) ||
725 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
726 "Name", &str))
728 count++;
729 if (count < 10)
730 name = g_strdup_printf ("_%d. %s", count, N_(str));
731 else
732 name = g_strdup_printf ("%d. %s", count, N_(str));
733 g_free (str);
735 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
736 "Icon", &str))
738 GdkPixbuf *pixbuf, *scaled_pixbuf;
739 gint height, width;
741 gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (submenu),
742 GTK_ICON_SIZE_MENU,
743 &width, &height);
744 icon_path = g_build_filename (PACKAGE_PIXMAPS_DIR, str, NULL);
745 pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL);
746 if (pixbuf)
748 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, width, height,
749 GDK_INTERP_BILINEAR);
750 icon = gtk_image_new_from_pixbuf (scaled_pixbuf);
751 g_object_unref (pixbuf);
752 g_object_unref (scaled_pixbuf);
754 else
755 icon = gtk_image_new ();
757 gtk_widget_show (icon);
758 g_free (icon_path);
759 g_free (str);
761 if (name)
763 menuitem = gtk_image_menu_item_new_with_mnemonic (name);
764 g_free(name);
765 gtk_widget_show (menuitem);
766 g_object_set_data (G_OBJECT (menuitem), "__plugin_handle", handle);
767 g_signal_connect (G_OBJECT (menuitem), "activate",
768 G_CALLBACK (on_activate_wizard),
769 loader);
770 if (icon)
771 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
772 icon);
773 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
775 node = g_list_next (node);
777 g_list_free (plugin_handles);
778 return submenu;
781 static void
782 open_uri_with (AnjutaFileLoaderPlugin *plugin, GtkMenuItem *menuitem,
783 const gchar *uri)
785 GAppInfo *app;
786 AnjutaPluginHandle *handle;
787 const gchar *mime_type;
789 /* Open with plugin */
790 handle = (AnjutaPluginHandle*) g_object_get_data (G_OBJECT (menuitem),
791 "handle");
792 mime_type = (const gchar*) g_object_get_data (G_OBJECT (menuitem),
793 "mime_type");
794 if (handle)
796 AnjutaPluginManager *plugin_manager;
797 GObject *loaded_plugin;
799 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell,
800 NULL);
803 loaded_plugin = anjuta_plugin_manager_get_plugin_by_handle (plugin_manager,
804 handle);
805 if (loaded_plugin)
807 GFile* file = g_file_new_for_uri (uri);
808 GError *error = NULL;
810 ianjuta_file_open (IANJUTA_FILE (loaded_plugin), file, &error);
811 g_object_unref (file);
812 update_recent_file (plugin, uri, mime_type, error == NULL);
813 g_free (error);
815 else
817 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
818 _("Failed to activate plugin: %s"),
819 anjuta_plugin_handle_get_name (handle));
822 else
824 /* Open with application */
825 app = (GAppInfo *) g_object_get_data (G_OBJECT (menuitem),
826 "app");
827 if (app)
829 GList *uris = NULL;
830 GError *error = NULL;
832 uris = g_list_prepend (uris, (gpointer)uri);
833 g_app_info_launch_uris (app, uris, NULL, &error);
834 g_list_free (uris);
835 if (error)
837 launch_application_failure (plugin, uri, error->message);
838 g_error_free (error);
840 update_recent_file (plugin, uri, mime_type, error == NULL);
845 static void
846 fm_open (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
848 if (plugin->fm_current_uri)
849 open_file (plugin, plugin->fm_current_uri);
852 static void
853 fm_open_with (GtkMenuItem *menuitem, AnjutaFileLoaderPlugin *plugin)
855 if (plugin->fm_current_uri)
856 open_uri_with (plugin, menuitem, plugin->fm_current_uri);
859 static void
860 pm_open (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
862 if (plugin->pm_current_uri)
863 open_file (plugin, plugin->pm_current_uri);
866 static void
867 pm_open_with (GtkMenuItem *menuitem, AnjutaFileLoaderPlugin *plugin)
869 if (plugin->pm_current_uri)
870 open_uri_with (plugin, menuitem, plugin->pm_current_uri);
873 static GtkActionEntry actions_file[] = {
875 "ActionFileNew",
876 GTK_STOCK_NEW,
877 N_("_New"),
878 "<control>n",
879 N_("New empty file"),
880 G_CALLBACK (on_new_activate)
883 "ActionFileOpen",
884 GTK_STOCK_OPEN,
885 N_("_Open…"),
886 "<control>o",
887 N_("Open file"),
888 G_CALLBACK (on_open_activate)
892 static GtkActionEntry popup_actions_file[] = {
894 "ActionPopupOpen",
895 GTK_STOCK_OPEN,
896 N_("_Open"), NULL,
897 N_("Open file"),
898 G_CALLBACK (fm_open)
901 "ActionPopupOpenWith",
902 NULL,
903 N_("Open _With"), NULL,
904 N_("Open with"), NULL
907 "ActionPopupPMOpen",
908 GTK_STOCK_OPEN,
909 N_("_Open"), NULL,
910 N_("Open file"),
911 G_CALLBACK (pm_open)
914 "ActionPopupPMOpenWith",
915 NULL,
916 N_("Open _With"), NULL,
917 N_("Open with"), NULL
921 static gboolean
922 create_open_with_submenu (AnjutaFileLoaderPlugin *plugin, GtkWidget *parentmenu,
923 const gchar *uri, GCallback callback,
924 gpointer callback_data)
926 GList *mime_apps;
927 GList *plugin_handles;
928 GList *node;
929 GtkWidget *menu, *menuitem;
930 gchar *mime_type;
931 GFile *file;
933 g_return_val_if_fail (GTK_IS_MENU_ITEM (parentmenu), FALSE);
935 menu = gtk_menu_new ();
936 gtk_widget_show (menu);
937 gtk_menu_item_set_submenu (GTK_MENU_ITEM (parentmenu), menu);
939 file = g_file_new_for_uri (uri);
940 mime_type = anjuta_util_get_file_mime_type (file);
941 g_object_unref (file);
942 if (mime_type == NULL)
943 return FALSE;
945 /* Open with plugins menu items */
946 plugin_handles = get_available_plugins_for_mime (ANJUTA_PLUGIN (plugin), mime_type);
947 for (node = plugin_handles; node != NULL; node = g_list_next (node))
949 gchar *name;
950 AnjutaPluginHandle *handle;
951 AnjutaPluginDescription *desc;
953 handle = (AnjutaPluginHandle *)(node->data);
954 desc = anjuta_plugin_handle_get_description (handle);
955 name = NULL;
956 anjuta_plugin_description_get_locale_string (desc, "File Loader",
957 "Title", &name);
958 if (!name)
960 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
961 "Name", &name);
963 if (!name)
965 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
966 "Location", &name);
968 menuitem = gtk_menu_item_new_with_label (name);
969 g_object_set_data (G_OBJECT (menuitem), "handle", handle);
970 g_object_set_data (G_OBJECT (menuitem), "mime_type", mime_type);
971 g_signal_connect (G_OBJECT (menuitem), "activate",
972 G_CALLBACK (callback), callback_data);
973 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
974 g_free (name);
976 g_list_free (plugin_handles);
978 /* Open with applications */
979 mime_apps = g_app_info_get_all_for_type (mime_type);
980 if (plugin_handles && mime_apps)
982 menuitem = gtk_menu_item_new ();
983 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
986 for (node = mime_apps; node != NULL; node = g_list_next (node))
988 GAppInfo *mime_app;
990 mime_app = (GAppInfo *)(node->data);
991 if (g_app_info_should_show (mime_app))
993 menuitem = gtk_menu_item_new_with_label ( g_app_info_get_name (mime_app));
994 g_object_set_data_full (G_OBJECT (menuitem), "app", mime_app, g_object_unref);
995 g_object_set_data (G_OBJECT (menuitem), "mime_type", mime_type);
996 g_signal_connect (G_OBJECT (menuitem), "activate",
997 G_CALLBACK (callback), callback_data);
998 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1000 else
1002 g_object_unref (mime_app);
1005 g_list_free (mime_apps);
1007 gtk_widget_show_all (menu);
1009 if ((mime_apps != NULL) || (plugin_handles != NULL))
1011 g_object_set_data_full (G_OBJECT (menu), "mime_type", (gpointer)mime_type, g_free);
1013 return TRUE;
1015 else
1017 g_free (mime_type);
1019 return FALSE;
1023 static void
1024 value_added_fm_current_file (AnjutaPlugin *plugin, const char *name,
1025 const GValue *value, gpointer data)
1027 AnjutaUI *ui;
1028 gchar *uri;
1029 AnjutaFileLoaderPlugin *fl_plugin;
1030 GtkAction *action;
1031 GtkWidget *parentmenu;
1032 GFile* file = G_FILE (g_value_get_object (value));
1034 uri = g_file_get_uri (file);
1035 g_return_if_fail (name != NULL);
1037 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1038 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1040 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupOpen");
1041 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1043 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1044 "ActionPopupOpenWith");
1045 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1047 if (fl_plugin->fm_current_uri)
1048 g_free (fl_plugin->fm_current_uri);
1049 fl_plugin->fm_current_uri = g_strdup (uri);
1051 parentmenu =
1052 gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1053 "/PopupFileManager/PlaceholderPopupFileOpen/OpenWith");
1054 if (!create_open_with_submenu (fl_plugin, parentmenu, uri,
1055 G_CALLBACK (fm_open_with), plugin))
1056 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1058 g_free (uri);
1061 static void
1062 value_removed_fm_current_file (AnjutaPlugin *plugin,
1063 const char *name, gpointer data)
1065 AnjutaUI *ui;
1066 GtkAction *action;
1067 AnjutaFileLoaderPlugin *fl_plugin;
1069 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1071 if (fl_plugin->fm_current_uri)
1072 g_free (fl_plugin->fm_current_uri);
1073 fl_plugin->fm_current_uri = NULL;
1075 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1076 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupOpen");
1077 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1079 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1080 "ActionPopupOpenWith");
1081 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1084 static void
1085 value_added_pm_current_uri (AnjutaPlugin *plugin, const char *name,
1086 const GValue *value, gpointer data)
1088 AnjutaUI *ui;
1089 const gchar *uri;
1090 AnjutaFileLoaderPlugin *fl_plugin;
1091 GtkAction *action;
1092 GtkWidget *parentmenu;
1094 uri = g_value_get_string (value);
1095 g_return_if_fail (name != NULL);
1097 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1098 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1100 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupPMOpen");
1101 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1103 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1104 "ActionPopupPMOpenWith");
1105 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1107 if (fl_plugin->pm_current_uri)
1108 g_free (fl_plugin->pm_current_uri);
1109 fl_plugin->pm_current_uri = g_strdup (uri);
1111 parentmenu =
1112 gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1113 "/PopupProjectManager/PlaceholderPopupProjectOpen/OpenWith");
1114 if (!create_open_with_submenu (fl_plugin, parentmenu, uri,
1115 G_CALLBACK (pm_open_with), plugin))
1116 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1119 static void
1120 value_removed_pm_current_uri (AnjutaPlugin *plugin,
1121 const char *name, gpointer data)
1123 AnjutaUI *ui;
1124 GtkAction *action;
1125 AnjutaFileLoaderPlugin *fl_plugin;
1127 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1129 if (fl_plugin->pm_current_uri)
1130 g_free (fl_plugin->pm_current_uri);
1131 fl_plugin->pm_current_uri = NULL;
1133 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1134 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupPMOpen");
1135 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1137 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1138 "ActionPopupPMOpenWith");
1139 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1142 static void
1143 dnd_dropped (GFile* file, gpointer plugin)
1145 ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin), file, FALSE, NULL);
1148 static void
1149 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
1150 AnjutaSession *session,
1151 AnjutaFileLoaderPlugin *plugin)
1153 GList *files, *node;
1155 /* We want to load the files first before other session loads */
1156 if (phase != ANJUTA_SESSION_PHASE_FIRST)
1157 return;
1159 files = anjuta_session_get_string_list (session, "File Loader", "Files");
1160 if (!files)
1161 return;
1163 /* Open all files except project files */
1164 for (node = g_list_first (files); node != NULL; node = g_list_next (node))
1166 gchar *uri = node->data;
1168 if (uri)
1170 const gchar *fragment = NULL;
1171 GFile* file = anjuta_session_get_file_from_relative_uri (session, uri, &fragment);
1172 GObject *loader = ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin),
1173 file, FALSE, NULL);
1174 if (fragment != NULL)
1176 if (IANJUTA_IS_DOCUMENT_MANAGER (loader))
1178 ianjuta_document_manager_goto_file_line (IANJUTA_DOCUMENT_MANAGER (loader), file, atoi(fragment), NULL);
1181 g_object_unref (file);
1183 g_free (uri);
1185 g_list_free (files);
1188 static void
1189 setup_recent_chooser_menu (GtkRecentChooser* recent_menu, AnjutaFileLoaderPlugin* plugin)
1191 GtkRecentFilter *filter;
1193 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1194 gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1195 gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1196 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (recent_menu), GTK_RECENT_SORT_MRU);
1197 gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (recent_menu), 20);
1199 filter = gtk_recent_filter_new ();
1200 gtk_recent_filter_add_application (filter, g_get_application_name ());
1201 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (recent_menu), filter);
1203 g_signal_connect (recent_menu, "item-activated",
1204 G_CALLBACK (on_open_recent_file), plugin);
1207 static gboolean
1208 activate_plugin (AnjutaPlugin *plugin)
1210 GtkAction *action, *saction;
1211 AnjutaUI *ui;
1212 AnjutaFileLoaderPlugin *loader_plugin;
1213 GtkActionGroup *group;
1214 GtkWidget *widget;
1215 GtkWidget* recent_menu;
1216 GtkWidget* toolbar_menu;
1218 loader_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1220 DEBUG_PRINT ("%s", "AnjutaFileLoaderPlugin: Activating File Loader plugin…");
1222 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1224 /* Recent manager */
1225 loader_plugin->recent_manager = gtk_recent_manager_get_default();
1227 /* Add action group */
1228 loader_plugin->action_group =
1229 anjuta_ui_add_action_group_entries (ui, "ActionGroupLoader",
1230 _("File Loader"),
1231 actions_file,
1232 G_N_ELEMENTS (actions_file),
1233 GETTEXT_PACKAGE, TRUE, plugin);
1234 loader_plugin->popup_action_group =
1235 anjuta_ui_add_action_group_entries (ui, "ActionGroupPopupLoader",
1236 _("File Loader"),
1237 popup_actions_file,
1238 G_N_ELEMENTS (popup_actions_file),
1239 GETTEXT_PACKAGE, FALSE, plugin);
1240 saction = gtk_recent_action_new ("ActionFileWizard", _("New"),
1241 _("New file, project and project components."), NULL);
1242 g_object_set (saction, "stock-id", GTK_STOCK_NEW, NULL);
1243 gtk_action_group_add_action (loader_plugin->action_group,
1244 GTK_ACTION (saction));
1246 /* Set short labels */
1247 action = anjuta_ui_get_action (ui, "ActionGroupLoader", "ActionFileOpen");
1248 g_object_set (G_OBJECT (action), "short-label", _("Open"),
1249 "is-important", TRUE, NULL);
1251 group = gtk_action_group_new ("ActionGroupLoaderRecent");
1252 action = gtk_recent_action_new ("ActionFileOpenRecent", _("Open _Recent"),
1253 _("Open recent file"), NULL);
1254 g_object_set (action, "stock-id", GTK_STOCK_OPEN, NULL);
1255 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (action), loader_plugin);
1257 gtk_action_group_add_action (group, action);
1258 anjuta_ui_add_action_group (ui, "ActionGroupLoaderRecent",
1259 N_("Open recent files"), group, FALSE);
1260 loader_plugin->recent_group = group;
1262 /* Add UI */
1263 loader_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
1265 /* Adding submenus */
1266 recent_menu = anjuta_recent_chooser_menu_new_for_manager (loader_plugin->recent_manager);
1267 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (recent_menu), loader_plugin);
1268 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1269 "/MenuMain/MenuFile/PlaceholderFileMenus/OpenRecent");
1270 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget),
1271 recent_menu);
1273 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1274 "/MenuMain/MenuFile/PlaceholderFileMenus/Wizard");
1275 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), on_create_submenu(loader_plugin));
1277 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1278 "/ToolbarMain/PlaceholderFileToolbar/New");
1279 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), on_create_submenu(loader_plugin));
1280 g_signal_connect (widget, "clicked", G_CALLBACK (on_new_clicked), loader_plugin);
1282 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1283 "/ToolbarMain/PlaceholderFileToolbar/Open");
1284 toolbar_menu = anjuta_recent_chooser_menu_new_for_manager (loader_plugin->recent_manager);
1285 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (toolbar_menu), loader_plugin);
1286 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget),
1287 toolbar_menu);
1288 gtk_tool_button_set_label (GTK_TOOL_BUTTON (widget), _("Open"));
1289 gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (widget), _("Open a file"));
1290 gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (widget), _("Open recent file"));
1291 g_signal_connect (widget, "clicked", G_CALLBACK (on_open_clicked), loader_plugin);
1293 /* Install drag n drop handler */
1294 dnd_drop_init (GTK_WIDGET (plugin->shell), dnd_dropped, plugin);
1296 /* Add watches */
1297 loader_plugin->fm_watch_id =
1298 anjuta_plugin_add_watch (plugin, IANJUTA_FILE_MANAGER_SELECTED_FILE,
1299 value_added_fm_current_file,
1300 value_removed_fm_current_file, NULL);
1301 loader_plugin->pm_watch_id =
1302 anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_CURRENT_URI,
1303 value_added_pm_current_uri,
1304 value_removed_pm_current_uri, NULL);
1305 loader_plugin->dm_watch_id =
1306 anjuta_plugin_add_watch (plugin,
1307 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1308 on_value_added_current_doc,
1309 on_value_removed_current_doc,
1310 plugin);
1312 /* Connect to session */
1313 g_signal_connect (G_OBJECT (plugin->shell), "load_session",
1314 G_CALLBACK (on_session_load), plugin);
1315 return TRUE;
1318 static gboolean
1319 deactivate_plugin (AnjutaPlugin *plugin)
1321 AnjutaUI *ui;
1322 AnjutaFileLoaderPlugin *loader_plugin;
1324 loader_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1326 DEBUG_PRINT ("%s", "AnjutaFileLoaderPlugin: Deactivating File Loader plugin…");
1328 /* Disconnect session */
1329 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1330 G_CALLBACK (on_session_load), plugin);
1332 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1333 /* Remove watches */
1334 anjuta_plugin_remove_watch (plugin, loader_plugin->fm_watch_id, TRUE);
1335 anjuta_plugin_remove_watch (plugin, loader_plugin->pm_watch_id, TRUE);
1336 /* Uninstall dnd */
1337 dnd_drop_finalize (GTK_WIDGET (plugin->shell), plugin);
1338 /* Remove UI */
1339 anjuta_ui_unmerge (ui, loader_plugin->uiid);
1340 /* Remove action group */
1341 anjuta_ui_remove_action_group (ui, loader_plugin->action_group);
1342 anjuta_ui_remove_action_group (ui, loader_plugin->popup_action_group);
1343 anjuta_ui_remove_action_group (ui, loader_plugin->recent_group);
1344 return TRUE;
1347 static void
1348 dispose (GObject *obj)
1350 G_OBJECT_CLASS (parent_class)->dispose (obj);
1353 static void
1354 finalize (GObject *obj)
1356 /* Finalization codes here */
1357 G_OBJECT_CLASS (parent_class)->finalize (obj);
1360 static void
1361 anjuta_file_loader_plugin_instance_init (GObject *obj)
1363 AnjutaFileLoaderPlugin *plugin = ANJUTA_PLUGIN_FILE_LOADER (obj);
1365 plugin->fm_current_uri = NULL;
1366 plugin->pm_current_uri = NULL;
1367 plugin->dm_current_uri = NULL;
1370 static void
1371 anjuta_file_loader_plugin_class_init (GObjectClass *klass)
1373 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1375 parent_class = g_type_class_peek_parent (klass);
1377 plugin_class->activate = activate_plugin;
1378 plugin_class->deactivate = deactivate_plugin;
1379 klass->dispose = dispose;
1380 klass->finalize = finalize;
1383 static GObject*
1384 iloader_load (IAnjutaFileLoader *loader, GFile* file,
1385 gboolean read_only, GError **err)
1387 gchar *mime_type;
1388 AnjutaStatus *status;
1389 AnjutaPluginManager *plugin_manager;
1390 GList *plugin_handles = NULL;
1391 GObject *plugin = NULL;
1392 gchar *uri = g_file_get_uri (file);
1394 g_return_val_if_fail (uri != NULL, NULL);
1396 mime_type = anjuta_util_get_file_mime_type (file);
1398 if (mime_type == NULL)
1400 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, NULL, FALSE);
1402 if (err == NULL)
1403 launch_application_failure (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, _("File not found"));
1405 g_set_error (err, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("File not found"));
1407 g_free (uri);
1408 return NULL;
1411 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
1412 NULL);
1413 status = anjuta_shell_get_status (ANJUTA_PLUGIN (loader)->shell, NULL);
1414 anjuta_status_busy_push (status);
1416 DEBUG_PRINT ("Opening URI: %s", uri);
1418 plugin_handles = get_available_plugins_for_mime (ANJUTA_PLUGIN (loader), mime_type);
1420 if (g_list_length (plugin_handles) > 1)
1422 gchar* basename = g_path_get_basename (uri);
1423 /* %s is name of file that will be opened */
1424 gchar* message = g_strdup_printf (_("Please select a plugin to open <b>%s</b>."),
1425 basename);
1426 plugin =
1427 anjuta_plugin_manager_select_and_activate (plugin_manager,
1428 _("Open With"),
1429 message,
1430 plugin_handles);
1431 g_free (basename);
1432 g_free (message);
1434 else if (g_list_length (plugin_handles) == 1)
1436 AnjutaPluginHandle *handle = plugin_handles->data;
1437 plugin = anjuta_plugin_manager_get_plugin_by_handle (plugin_manager,
1438 handle);
1440 else
1442 GAppInfo *appinfo;
1443 GList *uris = NULL;
1445 uris = g_list_prepend (uris, (gpointer)uri);
1447 appinfo = g_app_info_get_default_for_type (mime_type, TRUE);
1448 if (appinfo)
1450 GError *error = NULL;
1451 if (!g_app_info_launch_uris (appinfo, uris, NULL, &error))
1453 open_with_dialog (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type);
1455 else
1457 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type, error == NULL);
1459 g_object_unref (G_OBJECT (appinfo));
1461 g_list_free (uris);
1464 if (plugin)
1466 GError *error = NULL;
1468 ianjuta_file_open (IANJUTA_FILE(plugin), file, &error);
1469 if (error != NULL)
1472 if (err == NULL)
1473 launch_application_failure (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, error->message);
1474 g_propagate_error (err, error);
1476 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type, error == NULL);
1479 if (plugin_handles)
1480 g_list_free (plugin_handles);
1482 g_free (mime_type);
1483 g_free (uri);
1484 anjuta_status_busy_pop (status);
1486 return plugin;
1489 static void
1490 iloader_iface_init(IAnjutaLoaderIface *iface)
1492 iface->find_plugins = NULL;
1495 static void
1496 iloader_file_iface_init(IAnjutaFileLoaderIface *iface)
1498 iface->load = iloader_load;
1501 ANJUTA_PLUGIN_BEGIN (AnjutaFileLoaderPlugin, anjuta_file_loader_plugin);
1502 ANJUTA_PLUGIN_ADD_INTERFACE (iloader, IANJUTA_TYPE_LOADER);
1503 ANJUTA_PLUGIN_ADD_INTERFACE (iloader_file, IANJUTA_TYPE_FILE_LOADER);
1504 ANJUTA_PLUGIN_END;
1506 ANJUTA_SIMPLE_PLUGIN (AnjutaFileLoaderPlugin, anjuta_file_loader_plugin);