file-loader: bgo #700615 - Remove markup from title of Open With dialog
[anjuta.git] / plugins / file-loader / plugin.c
blobde60d70171a51847637e13d577b7a099417aaa41
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 AnjutaPluginDescription* desc1 = (AnjutaPluginDescription*) wizard1;
52 AnjutaPluginDescription* desc2 = (AnjutaPluginDescription*) wizard2;
54 if ((anjuta_plugin_description_get_locale_string (desc1, "Wizard",
55 "Title", &name1) ||
56 anjuta_plugin_description_get_locale_string (desc1, "Anjuta Plugin",
57 "Name", &name1)) &&
58 (anjuta_plugin_description_get_locale_string (desc2, "Wizard",
59 "Title", &name2) ||
60 anjuta_plugin_description_get_locale_string (desc2, "Anjuta Plugin",
61 "Name", &name2)))
63 ret = strcmp(name1, name2);
65 else
66 ret = 0;
68 g_free(name1);
69 g_free(name2);
71 return ret;
74 /* The add argument is here to remember that recent menu items should be removed
75 * when the destination does not exist anymore */
76 static void
77 update_recent_file (AnjutaFileLoaderPlugin *plugin, const gchar *uri,
78 const gchar *mime, gboolean add)
81 if (add)
83 GtkRecentData *recent_data;
85 recent_data = g_slice_new (GtkRecentData);
87 recent_data->display_name = NULL;
88 recent_data->description = NULL;
89 recent_data->mime_type = (gchar *)mime;
90 recent_data->app_name = (gchar *) g_get_application_name ();
91 recent_data->app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
92 recent_data->groups = NULL;
93 recent_data->is_private = FALSE;
95 if (!gtk_recent_manager_add_full (plugin->recent_manager, uri, recent_data))
97 g_warning ("Unable to add '%s' to the list of recently used documents", uri);
100 g_free (recent_data->app_exec);
101 g_slice_free (GtkRecentData, recent_data);
103 else
105 gtk_recent_manager_remove_item (plugin->recent_manager, uri, NULL);
110 static void
111 launch_application_failure (AnjutaFileLoaderPlugin *plugin,
112 const gchar *uri,
113 const gchar *errmsg)
115 GtkWidget *parent;
116 gchar *basename;
118 parent =
119 gtk_widget_get_toplevel (GTK_WIDGET(ANJUTA_PLUGIN (plugin)->shell));
120 basename = g_path_get_basename (uri);
121 anjuta_util_dialog_error (GTK_WINDOW (parent),
122 _("Cannot open \"%s\".\n\n%s"),
123 basename, errmsg);
124 g_free (basename);
127 static GList *
128 get_available_plugins_for_mime (AnjutaPlugin* plugin,
129 const gchar *mime_type)
131 AnjutaPluginManager *plugin_manager;
132 GList *plugin_descs = NULL;
133 gchar *content_type;
135 g_return_val_if_fail (mime_type != NULL, NULL);
137 plugin_manager = anjuta_shell_get_plugin_manager (plugin->shell,
138 NULL);
140 /* Check an exact match */
141 plugin_descs = anjuta_plugin_manager_query (plugin_manager,
142 "Anjuta Plugin",
143 "Interfaces", "IAnjutaFile",
144 "File Loader",
145 "SupportedMimeTypes",
146 mime_type,
147 NULL);
149 /* Check for plugins supporting one supertype */
150 content_type = g_content_type_from_mime_type (mime_type);
151 if (plugin_descs == NULL)
153 GList *node;
154 GList *loader_descs = NULL;
156 loader_descs = anjuta_plugin_manager_query (plugin_manager,
157 "Anjuta Plugin",
158 "Interfaces", "IAnjutaFile",
159 NULL);
160 for (node = g_list_first (loader_descs); node != NULL; node = g_list_next (node))
162 gchar *value;
164 if (anjuta_plugin_description_get_string ((AnjutaPluginDescription *)node->data,
165 "File Loader", "SupportedMimeTypes", &value))
167 gchar **split_value;
169 split_value = g_strsplit (value, ",", -1);
170 g_free (value);
171 if (split_value)
173 gchar **mime;
175 for (mime = split_value; *mime != NULL; mime++)
177 gchar *supertype = g_content_type_from_mime_type (*mime);
179 if (g_content_type_is_a (content_type, supertype))
181 gchar *loc;
182 anjuta_plugin_description_get_string ((AnjutaPluginDescription *)node->data,
183 "Anjuta Plugin", "Location", &loc);
185 plugin_descs = g_list_prepend (plugin_descs, node->data);
187 g_free (supertype);
189 break;
192 g_free (supertype);
195 g_strfreev (split_value);
198 g_list_free (loader_descs);
199 plugin_descs = g_list_reverse (plugin_descs);
201 g_free (content_type);
203 return plugin_descs;
206 static gboolean
207 RowSeparatorFunc (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
209 int n = GPOINTER_TO_INT(data), k;
210 gchar *path = gtk_tree_model_get_string_from_iter (model, iter);
211 sscanf (path, "%d", &k);
212 g_free (path);
213 return n == k;
216 static void
217 on_value_added_current_doc (AnjutaPlugin *plugin, const gchar *name,
218 const GValue *value, gpointer data)
220 AnjutaFileLoaderPlugin *fplugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
221 IAnjutaDocument* doc = IANJUTA_DOCUMENT(g_value_get_object (value));
222 GFile *file;
224 g_free (fplugin->dm_current_uri);
226 if (IANJUTA_IS_FILE (doc) &&
227 ((file = ianjuta_file_get_file(IANJUTA_FILE (doc), NULL)) != NULL))
229 GFile* parent = g_file_get_parent (file);
230 fplugin->dm_current_uri = g_file_get_uri (parent);
231 g_object_unref (parent);
232 g_object_unref (file);
234 else
237 fplugin->dm_current_uri = NULL;
241 static void
242 on_value_removed_current_doc (AnjutaPlugin *plugin, const gchar *name,
243 gpointer data)
245 AnjutaFileLoaderPlugin *fplugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
246 g_free (fplugin->dm_current_uri);
247 fplugin->dm_current_uri = NULL;
250 static void
251 open_with_dialog (AnjutaFileLoaderPlugin *plugin, const gchar *uri,
252 const gchar *mime_type)
254 GList *plugin_descs, *snode;
255 GList *mime_apps, *node;
256 GAppInfo *mime_app;
258 GtkWidget *dialog, *parent, *hbox, *label;
259 GtkWidget *options;
260 gchar *message;
261 gchar *basename;
262 gint col = -1;
263 AnjutaPluginManager *plugin_manager;
265 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell,
266 NULL);
267 basename = g_path_get_basename (uri);
268 message = g_strdup_printf (_("<b>Cannot open \"%s\"</b>.\n\n"
269 "There is no plugin, default action, or application "
270 "configured to handle this file type.\n"
271 "\n"
272 "MIME type: %s\n"
273 "\n"
274 "You may choose to try opening it with the following "
275 "plugins or applications."),
276 basename, mime_type);
277 g_free (basename);
279 parent =
280 gtk_widget_get_toplevel (GTK_WIDGET(ANJUTA_PLUGIN (plugin)->shell));
281 dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (parent),
282 GTK_DIALOG_DESTROY_WITH_PARENT,
283 GTK_MESSAGE_INFO,
284 GTK_BUTTONS_OK_CANCEL, "%s",
285 message);
286 g_free (message);
288 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
289 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
290 hbox, FALSE, FALSE, 5);
291 label = gtk_label_new (_("Open with:"));
292 options = gtk_combo_box_text_new ();
293 gtk_box_pack_end (GTK_BOX(hbox), options, FALSE, FALSE, 10);
294 gtk_box_pack_end (GTK_BOX(hbox), label, FALSE, FALSE, 10);
296 /* Document manager plugin */
297 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), _("Document Manager"));
298 col ++;
300 /* Open with plugins menu items */
301 plugin_descs = get_available_plugins_for_mime (ANJUTA_PLUGIN (plugin), mime_type);
302 snode = plugin_descs;
303 while (snode)
305 gchar *name;
306 AnjutaPluginDescription *desc;
308 desc = (AnjutaPluginDescription *)(snode->data);
310 name = NULL;
312 anjuta_plugin_description_get_locale_string (desc, "File Loader",
313 "Title", &name);
315 if (!name)
317 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
318 "Name", &name);
320 if (!name)
322 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
323 "Location", &name);
325 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), name);
326 col ++;
327 g_free (name);
328 snode = g_list_next (snode);
331 /* Open with application menu items */
332 mime_apps = g_app_info_get_all_for_type (mime_type);
333 if (mime_apps)
335 /* Separator */
336 col++;
337 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), "");
338 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (options), RowSeparatorFunc, GINT_TO_POINTER(col), NULL);
340 node = mime_apps;
341 while (node)
343 mime_app = (GAppInfo *)(node->data);
344 if (g_app_info_should_show (mime_app))
346 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (options), g_app_info_get_name (mime_app));
348 node = g_list_next (node);
350 gtk_combo_box_set_active (GTK_COMBO_BOX (options), 0);
351 gtk_widget_show_all (hbox);
353 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
355 gint option;
357 option = gtk_combo_box_get_active(GTK_COMBO_BOX (options));
358 if (option == 0)
360 IAnjutaDocumentManager *docman;
361 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
362 IAnjutaDocumentManager,
363 NULL);
364 if (docman)
366 GFile* file = g_file_new_for_uri (uri);
367 ianjuta_file_open (IANJUTA_FILE (docman), file, NULL);
368 g_object_unref (file);
370 else
372 g_warning ("No document manager plugin!!");
375 else if (option < (g_list_length (plugin_descs) + 1))
377 AnjutaPluginDescription *desc;
378 gchar *location = NULL;
380 option--;
381 desc = g_list_nth_data (plugin_descs, option);
382 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
383 "Location", &location);
384 g_assert (location != NULL);
385 if (location != NULL)
387 GObject *loaded_plugin;
389 loaded_plugin =
390 anjuta_plugin_manager_get_plugin_by_id (plugin_manager,
391 location);
392 if (loaded_plugin)
394 GFile* file = g_file_new_for_uri (uri);
395 ianjuta_file_open (IANJUTA_FILE (loaded_plugin), file, NULL);
396 update_recent_file (plugin, uri, mime_type, TRUE);
397 g_object_unref (file);
399 else
401 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
402 "Failed to activate plugin: %s",
403 location);
405 g_free (location);
408 else
410 GList *uris = NULL;
411 GError *error = NULL;
413 option -= (g_list_length (plugin_descs) + 2);
414 mime_app = g_list_nth_data (mime_apps, option);
415 uris = g_list_prepend (uris, (gpointer)uri);
416 g_app_info_launch_uris(mime_app, uris, NULL, &error);
417 if (error)
419 launch_application_failure (plugin, uri, error->message);
420 g_error_free (error);
422 update_recent_file (plugin, uri, mime_type, error == NULL);
423 g_list_free (uris);
426 g_list_foreach (mime_apps, (GFunc) g_object_unref, NULL);
427 g_list_free (mime_apps);
428 if (plugin_descs)
429 g_list_free (plugin_descs);
430 gtk_widget_destroy (dialog);
433 static void
434 open_file (AnjutaFileLoaderPlugin *plugin, const gchar *uri)
436 GFile* file;
438 file = g_file_new_for_uri (uri);
440 ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin),
441 file, FALSE, NULL);
442 g_object_unref (file);
445 typedef struct
447 AnjutaFileLoaderPlugin *plugin;
448 const gchar *uri;
449 } RecentIdleOpenData;
451 static gboolean
452 on_open_recent_file_idle (gpointer data)
454 RecentIdleOpenData *rdata;
456 rdata = (RecentIdleOpenData*)data;
457 open_file (rdata->plugin, rdata->uri);
458 g_free (rdata);
459 return FALSE;
462 static gboolean
463 on_open_recent_file (GtkRecentChooser *chooser, AnjutaFileLoaderPlugin *plugin)
465 const gchar *uri;
466 gboolean ret = TRUE;
467 RecentIdleOpenData *rdata;
469 uri = gtk_recent_chooser_get_current_uri (chooser);
470 rdata = g_new0 (RecentIdleOpenData, 1);
471 rdata->plugin = plugin;
472 rdata->uri = uri;
473 g_idle_add (on_open_recent_file_idle, rdata);
475 return ret;
478 static void
479 on_open_response_ok (GtkDialog* dialog, gint id,
480 AnjutaFileLoaderPlugin *plugin)
482 GSList *list, *node;
484 if (id != GTK_RESPONSE_ACCEPT)
486 gtk_widget_destroy (GTK_WIDGET (dialog));
487 return;
490 list = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
491 node = list;
492 while (node)
494 if (node->data)
495 open_file (plugin, (gchar *)node->data);
496 g_free (node->data);
497 node = g_slist_next (node);
499 g_slist_free (list);
502 static void
503 setup_file_filters (GtkFileChooser *fc)
505 GtkFileFilter *filter;
507 filter = gtk_file_filter_new ();
508 gtk_file_filter_set_name (filter, _("All files"));
509 gtk_file_filter_add_pattern (filter, "*");
510 gtk_file_chooser_add_filter (fc, filter);
512 filter = gtk_file_filter_new ();
513 gtk_file_filter_set_name (filter, _("Anjuta Projects"));
514 gtk_file_filter_add_pattern (filter, "*.anjuta");
515 gtk_file_filter_add_pattern (filter, "*.prj");
516 gtk_file_chooser_add_filter (fc, filter);
518 filter = gtk_file_filter_new ();
519 gtk_file_filter_set_name (filter, _("C/C++ source files"));
520 gtk_file_filter_add_pattern (filter, "*.c");
521 gtk_file_filter_add_pattern (filter, "*.cc");
522 gtk_file_filter_add_pattern (filter, "*.cpp");
523 gtk_file_filter_add_pattern (filter, "*.cxx");
524 gtk_file_filter_add_pattern (filter, "*.c++");
525 gtk_file_filter_add_pattern (filter, "*.h");
526 gtk_file_filter_add_pattern (filter, "*.hh");
527 gtk_file_filter_add_pattern (filter, "*.hpp");
528 gtk_file_chooser_add_filter (fc, filter);
530 filter = gtk_file_filter_new ();
531 gtk_file_filter_set_name (filter, _("C# source files"));
532 gtk_file_filter_add_pattern (filter, "*.cs");
533 gtk_file_filter_add_pattern (filter, "*.h");
534 gtk_file_chooser_add_filter (fc, filter);
536 filter = gtk_file_filter_new ();
537 gtk_file_filter_set_name (filter, _("Java source files"));
538 gtk_file_filter_add_pattern (filter, "*.java");
539 gtk_file_filter_add_pattern (filter, "*.js");
540 gtk_file_chooser_add_filter (fc, filter);
542 filter = gtk_file_filter_new ();
543 gtk_file_filter_set_name (filter, _("Pascal source files"));
544 gtk_file_filter_add_pattern (filter, "*.pas");
545 gtk_file_chooser_add_filter (fc, filter);
547 filter = gtk_file_filter_new ();
548 gtk_file_filter_set_name (filter, _("PHP source files"));
549 gtk_file_filter_add_pattern (filter, "*.php");
550 gtk_file_filter_add_pattern (filter, "*.php?");
551 gtk_file_filter_add_pattern (filter, "*.phtml");
552 gtk_file_chooser_add_filter (fc, filter);
554 filter = gtk_file_filter_new ();
555 gtk_file_filter_set_name (filter, _("Perl source files"));
556 gtk_file_filter_add_pattern (filter, "*.pl");
557 gtk_file_filter_add_pattern (filter, "*.pm");
558 gtk_file_chooser_add_filter (fc, filter);
560 filter = gtk_file_filter_new ();
561 gtk_file_filter_set_name (filter, _("Python source files"));
562 gtk_file_filter_add_pattern (filter, "*.py");
563 gtk_file_chooser_add_filter (fc, filter);
565 filter = gtk_file_filter_new ();
566 gtk_file_filter_set_name (filter, _("Hypertext markup files"));
567 gtk_file_filter_add_pattern (filter, "*.htm");
568 gtk_file_filter_add_pattern (filter, "*.html");
569 gtk_file_filter_add_pattern (filter, "*.xhtml");
570 gtk_file_filter_add_pattern (filter, "*.dhtml");
571 gtk_file_filter_add_pattern (filter, "*.cs");
572 gtk_file_chooser_add_filter (fc, filter);
574 filter = gtk_file_filter_new ();
575 gtk_file_filter_set_name (filter, _("Shell script files"));
576 gtk_file_filter_add_pattern (filter, "*.sh");
577 gtk_file_chooser_add_filter (fc, filter);
579 filter = gtk_file_filter_new ();
580 gtk_file_filter_set_name (filter, _("Makefiles"));
581 gtk_file_filter_add_pattern (filter, "Makefile*");
582 gtk_file_filter_add_pattern (filter, "makefile*");
583 gtk_file_chooser_add_filter (fc, filter);
585 filter = gtk_file_filter_new ();
586 gtk_file_filter_set_name (filter, _("Lua files"));
587 gtk_file_filter_add_pattern (filter, "*.lua");
588 gtk_file_chooser_add_filter (fc, filter);
590 filter = gtk_file_filter_new ();
591 gtk_file_filter_set_name (filter, _("Diff files"));
592 gtk_file_filter_add_pattern (filter, "*.diff");
593 gtk_file_filter_add_pattern (filter, "*.patch");
594 gtk_file_filter_add_pattern (filter, "*.cvsdiff");
595 gtk_file_chooser_add_filter (fc, filter);
598 static GtkWidget*
599 create_file_open_dialog_gui(GtkWindow* parent, AnjutaFileLoaderPlugin* plugin)
601 GtkWidget* dialog =
602 gtk_file_chooser_dialog_new (_("Open file"),
603 parent,
604 GTK_FILE_CHOOSER_ACTION_OPEN,
605 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
606 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
607 NULL);
608 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
609 if (plugin->dm_current_uri)
611 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
612 plugin->dm_current_uri);
614 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
615 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
616 gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
618 setup_file_filters (GTK_FILE_CHOOSER (dialog));
620 g_signal_connect(G_OBJECT(dialog), "response",
621 G_CALLBACK(on_open_response_ok), plugin);
622 g_signal_connect_swapped (dialog,
623 "response",
624 G_CALLBACK (gtk_widget_destroy),
625 dialog);
626 return dialog;
629 static void
630 on_new_clicked (GtkToolButton *button, AnjutaFileLoaderPlugin *plugin)
632 AnjutaShell* shell = ANJUTA_PLUGIN (plugin)->shell;
633 IAnjutaDocumentManager *docman = anjuta_shell_get_interface (shell,
634 IAnjutaDocumentManager,
635 NULL);
636 if (docman)
637 ianjuta_document_manager_add_buffer (docman, NULL, NULL, NULL);
640 static void
641 on_open_clicked (GtkToolButton *button, AnjutaFileLoaderPlugin *plugin)
643 GtkWidget *dlg;
645 dlg =
646 create_file_open_dialog_gui (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
647 plugin);
648 gtk_widget_show (dlg);
651 static void
652 on_new_activate (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
654 AnjutaShell* shell = ANJUTA_PLUGIN (plugin)->shell;
655 IAnjutaDocumentManager *docman = anjuta_shell_get_interface (shell,
656 IAnjutaDocumentManager,
657 NULL);
658 if (docman)
659 ianjuta_document_manager_add_buffer (docman, NULL, NULL, NULL);
662 static void
663 on_open_activate (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
665 GtkWidget *dlg;
667 dlg =
668 create_file_open_dialog_gui (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
669 plugin);
670 gtk_widget_show (dlg);
673 static void
674 on_activate_wizard (GtkMenuItem *menuitem,
675 AnjutaFileLoaderPlugin *loader)
677 AnjutaPluginManager *plugin_manager;
678 AnjutaPluginDescription *desc;
680 desc = g_object_get_data (G_OBJECT (menuitem), "__plugin_desc");
681 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
682 NULL);
683 if (desc)
685 gchar *id;
686 GObject *plugin;
688 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
689 "Location", &id))
691 plugin =
692 anjuta_plugin_manager_get_plugin_by_id (plugin_manager, id);
693 ianjuta_wizard_activate (IANJUTA_WIZARD (plugin), NULL);
698 static GtkWidget*
699 on_create_submenu (gpointer user_data)
701 AnjutaPluginManager *plugin_manager;
702 AnjutaFileLoaderPlugin *loader;
703 GList *node;
704 gint count;
705 GtkWidget *submenu = NULL;
706 GList *plugin_descs = NULL;
708 loader = ANJUTA_PLUGIN_FILE_LOADER (user_data);
709 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
710 NULL);
711 submenu = gtk_menu_new ();
712 gtk_widget_show (submenu);
714 plugin_descs = anjuta_plugin_manager_query (plugin_manager,
715 "Anjuta Plugin",
716 "Interfaces", "IAnjutaWizard",
717 NULL);
718 plugin_descs = g_list_sort(plugin_descs, sort_wizards);
719 node = plugin_descs;
720 count = 0;
721 while (node)
723 AnjutaPluginDescription *desc;
724 GtkWidget *menuitem;
725 GtkWidget *icon;
726 gchar *str, *icon_path, *name;
728 desc = node->data;
730 icon = NULL;
731 name = NULL;
732 if (anjuta_plugin_description_get_locale_string (desc, "Wizard",
733 "Title", &str) ||
734 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
735 "Name", &str))
737 count++;
738 if (count < 10)
739 name = g_strdup_printf ("_%d. %s", count, N_(str));
740 else
741 name = g_strdup_printf ("%d. %s", count, N_(str));
742 g_free (str);
744 if (anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
745 "Icon", &str))
747 GdkPixbuf *pixbuf, *scaled_pixbuf;
748 gint height, width;
750 gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (submenu),
751 GTK_ICON_SIZE_MENU,
752 &width, &height);
753 icon_path = g_build_filename (PACKAGE_PIXMAPS_DIR, str, NULL);
754 pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL);
755 if (pixbuf)
757 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, width, height,
758 GDK_INTERP_BILINEAR);
759 icon = gtk_image_new_from_pixbuf (scaled_pixbuf);
760 g_object_unref (pixbuf);
761 g_object_unref (scaled_pixbuf);
763 else
764 icon = gtk_image_new ();
766 gtk_widget_show (icon);
767 g_free (icon_path);
768 g_free (str);
770 if (name)
772 menuitem = gtk_image_menu_item_new_with_mnemonic (name);
773 g_free(name);
774 gtk_widget_show (menuitem);
775 g_object_set_data (G_OBJECT (menuitem), "__plugin_desc", desc);
776 g_signal_connect (G_OBJECT (menuitem), "activate",
777 G_CALLBACK (on_activate_wizard),
778 loader);
779 if (icon)
780 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
781 icon);
782 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
784 node = g_list_next (node);
786 g_list_free (plugin_descs);
787 return submenu;
790 static void
791 open_uri_with (AnjutaFileLoaderPlugin *plugin, GtkMenuItem *menuitem,
792 const gchar *uri)
794 GAppInfo *app;
795 AnjutaPluginDescription *desc;
796 const gchar *mime_type;
798 /* Open with plugin */
799 desc = (AnjutaPluginDescription*) g_object_get_data (G_OBJECT (menuitem),
800 "desc");
801 mime_type = (const gchar*) g_object_get_data (G_OBJECT (menuitem),
802 "mime_type");
803 if (desc)
805 AnjutaPluginManager *plugin_manager;
806 gchar *location = NULL;
808 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell,
809 NULL);
811 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
812 "Location", &location);
813 g_assert (location != NULL);
814 if (location != NULL)
816 GObject *loaded_plugin;
818 loaded_plugin =
819 anjuta_plugin_manager_get_plugin_by_id (plugin_manager,
820 location);
821 if (loaded_plugin)
823 GFile* file = g_file_new_for_uri (uri);
824 GError *error = NULL;
826 ianjuta_file_open (IANJUTA_FILE (loaded_plugin), file, &error);
827 g_object_unref (file);
828 update_recent_file (plugin, uri, mime_type, error == NULL);
829 g_free (error);
831 else
833 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
834 _("Failed to activate plugin: %s"),
835 location);
837 g_free (location);
840 else
842 /* Open with application */
843 app = (GAppInfo *) g_object_get_data (G_OBJECT (menuitem),
844 "app");
845 if (app)
847 GList *uris = NULL;
848 GError *error = NULL;
850 uris = g_list_prepend (uris, (gpointer)uri);
851 g_app_info_launch_uris (app, uris, NULL, &error);
852 g_list_free (uris);
853 if (error)
855 launch_application_failure (plugin, uri, error->message);
856 g_error_free (error);
858 update_recent_file (plugin, uri, mime_type, error == NULL);
863 static void
864 fm_open (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
866 if (plugin->fm_current_uri)
867 open_file (plugin, plugin->fm_current_uri);
870 static void
871 fm_open_with (GtkMenuItem *menuitem, AnjutaFileLoaderPlugin *plugin)
873 if (plugin->fm_current_uri)
874 open_uri_with (plugin, menuitem, plugin->fm_current_uri);
877 static void
878 pm_open (GtkAction *action, AnjutaFileLoaderPlugin *plugin)
880 if (plugin->pm_current_uri)
881 open_file (plugin, plugin->pm_current_uri);
884 static void
885 pm_open_with (GtkMenuItem *menuitem, AnjutaFileLoaderPlugin *plugin)
887 if (plugin->pm_current_uri)
888 open_uri_with (plugin, menuitem, plugin->pm_current_uri);
891 static GtkActionEntry actions_file[] = {
893 "ActionFileNew",
894 GTK_STOCK_NEW,
895 N_("_New"),
896 "<control>n",
897 N_("New empty file"),
898 G_CALLBACK (on_new_activate)
901 "ActionFileOpen",
902 GTK_STOCK_OPEN,
903 N_("_Open…"),
904 "<control>o",
905 N_("Open file"),
906 G_CALLBACK (on_open_activate)
910 static GtkActionEntry popup_actions_file[] = {
912 "ActionPopupOpen",
913 GTK_STOCK_OPEN,
914 N_("_Open"), NULL,
915 N_("Open file"),
916 G_CALLBACK (fm_open)
919 "ActionPopupOpenWith",
920 NULL,
921 N_("Open _With"), NULL,
922 N_("Open with"), NULL
925 "ActionPopupPMOpen",
926 GTK_STOCK_OPEN,
927 N_("_Open"), NULL,
928 N_("Open file"),
929 G_CALLBACK (pm_open)
932 "ActionPopupPMOpenWith",
933 NULL,
934 N_("Open _With"), NULL,
935 N_("Open with"), NULL
939 static gboolean
940 create_open_with_submenu (AnjutaFileLoaderPlugin *plugin, GtkWidget *parentmenu,
941 const gchar *uri, GCallback callback,
942 gpointer callback_data)
944 GList *mime_apps;
945 GList *plugin_descs;
946 GList *node;
947 GtkWidget *menu, *menuitem;
948 gchar *mime_type;
949 GFile *file;
951 g_return_val_if_fail (GTK_IS_MENU_ITEM (parentmenu), FALSE);
953 menu = gtk_menu_new ();
954 gtk_widget_show (menu);
955 gtk_menu_item_set_submenu (GTK_MENU_ITEM (parentmenu), menu);
957 file = g_file_new_for_uri (uri);
958 mime_type = anjuta_util_get_file_mime_type (file);
959 g_object_unref (file);
960 if (mime_type == NULL)
961 return FALSE;
963 /* Open with plugins menu items */
964 plugin_descs = get_available_plugins_for_mime (ANJUTA_PLUGIN (plugin), mime_type);
965 for (node = plugin_descs; node != NULL; node = g_list_next (node))
967 gchar *name;
968 AnjutaPluginDescription *desc;
970 desc = (AnjutaPluginDescription *)(node->data);
971 name = NULL;
972 anjuta_plugin_description_get_locale_string (desc, "File Loader",
973 "Title", &name);
974 if (!name)
976 anjuta_plugin_description_get_locale_string (desc, "Anjuta Plugin",
977 "Name", &name);
979 if (!name)
981 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
982 "Location", &name);
984 menuitem = gtk_menu_item_new_with_label (name);
985 g_object_set_data (G_OBJECT (menuitem), "desc", (gpointer)(desc));
986 g_object_set_data (G_OBJECT (menuitem), "mime_type", mime_type);
987 g_signal_connect (G_OBJECT (menuitem), "activate",
988 G_CALLBACK (callback), callback_data);
989 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
990 g_free (name);
992 g_list_free (plugin_descs);
994 /* Open with applications */
995 mime_apps = g_app_info_get_all_for_type (mime_type);
996 if (plugin_descs && mime_apps)
998 menuitem = gtk_menu_item_new ();
999 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1002 for (node = mime_apps; node != NULL; node = g_list_next (node))
1004 GAppInfo *mime_app;
1006 mime_app = (GAppInfo *)(node->data);
1007 if (g_app_info_should_show (mime_app))
1009 menuitem = gtk_menu_item_new_with_label ( g_app_info_get_name (mime_app));
1010 g_object_set_data_full (G_OBJECT (menuitem), "app", mime_app, g_object_unref);
1011 g_object_set_data (G_OBJECT (menuitem), "mime_type", mime_type);
1012 g_signal_connect (G_OBJECT (menuitem), "activate",
1013 G_CALLBACK (callback), callback_data);
1014 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1016 else
1018 g_object_unref (mime_app);
1021 g_list_free (mime_apps);
1023 gtk_widget_show_all (menu);
1025 if ((mime_apps != NULL) || (plugin_descs != NULL))
1027 g_object_set_data_full (G_OBJECT (menu), "mime_type", (gpointer)mime_type, g_free);
1029 return TRUE;
1031 else
1033 g_free (mime_type);
1035 return FALSE;
1039 static void
1040 value_added_fm_current_file (AnjutaPlugin *plugin, const char *name,
1041 const GValue *value, gpointer data)
1043 AnjutaUI *ui;
1044 gchar *uri;
1045 AnjutaFileLoaderPlugin *fl_plugin;
1046 GtkAction *action;
1047 GtkWidget *parentmenu;
1048 GFile* file = G_FILE (g_value_get_object (value));
1050 uri = g_file_get_uri (file);
1051 g_return_if_fail (name != NULL);
1053 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1054 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1056 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupOpen");
1057 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1059 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1060 "ActionPopupOpenWith");
1061 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1063 if (fl_plugin->fm_current_uri)
1064 g_free (fl_plugin->fm_current_uri);
1065 fl_plugin->fm_current_uri = g_strdup (uri);
1067 parentmenu =
1068 gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1069 "/PopupFileManager/PlaceholderPopupFileOpen/OpenWith");
1070 if (!create_open_with_submenu (fl_plugin, parentmenu, uri,
1071 G_CALLBACK (fm_open_with), plugin))
1072 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1074 g_free (uri);
1077 static void
1078 value_removed_fm_current_file (AnjutaPlugin *plugin,
1079 const char *name, gpointer data)
1081 AnjutaUI *ui;
1082 GtkAction *action;
1083 AnjutaFileLoaderPlugin *fl_plugin;
1085 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1087 if (fl_plugin->fm_current_uri)
1088 g_free (fl_plugin->fm_current_uri);
1089 fl_plugin->fm_current_uri = NULL;
1091 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1092 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupOpen");
1093 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1095 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1096 "ActionPopupOpenWith");
1097 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1100 static void
1101 value_added_pm_current_uri (AnjutaPlugin *plugin, const char *name,
1102 const GValue *value, gpointer data)
1104 AnjutaUI *ui;
1105 const gchar *uri;
1106 AnjutaFileLoaderPlugin *fl_plugin;
1107 GtkAction *action;
1108 GtkWidget *parentmenu;
1110 uri = g_value_get_string (value);
1111 g_return_if_fail (name != NULL);
1113 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1114 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1116 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupPMOpen");
1117 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1119 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1120 "ActionPopupPMOpenWith");
1121 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1123 if (fl_plugin->pm_current_uri)
1124 g_free (fl_plugin->pm_current_uri);
1125 fl_plugin->pm_current_uri = g_strdup (uri);
1127 parentmenu =
1128 gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1129 "/PopupProjectManager/PlaceholderPopupProjectOpen/OpenWith");
1130 if (!create_open_with_submenu (fl_plugin, parentmenu, uri,
1131 G_CALLBACK (pm_open_with), plugin))
1132 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1135 static void
1136 value_removed_pm_current_uri (AnjutaPlugin *plugin,
1137 const char *name, gpointer data)
1139 AnjutaUI *ui;
1140 GtkAction *action;
1141 AnjutaFileLoaderPlugin *fl_plugin;
1143 fl_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1145 if (fl_plugin->pm_current_uri)
1146 g_free (fl_plugin->pm_current_uri);
1147 fl_plugin->pm_current_uri = NULL;
1149 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1150 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader", "ActionPopupPMOpen");
1151 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1153 action = anjuta_ui_get_action (ui, "ActionGroupPopupLoader",
1154 "ActionPopupPMOpenWith");
1155 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1158 static void
1159 dnd_dropped (GFile* file, gpointer plugin)
1161 ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin), file, FALSE, NULL);
1164 static void
1165 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
1166 AnjutaSession *session,
1167 AnjutaFileLoaderPlugin *plugin)
1169 GList *files, *node;
1171 /* We want to load the files first before other session loads */
1172 if (phase != ANJUTA_SESSION_PHASE_FIRST)
1173 return;
1175 files = anjuta_session_get_string_list (session, "File Loader", "Files");
1176 if (!files)
1177 return;
1179 /* Open all files except project files */
1180 for (node = g_list_first (files); node != NULL; node = g_list_next (node))
1182 gchar *uri = node->data;
1184 if (uri)
1186 const gchar *fragment = NULL;
1187 GFile* file = anjuta_session_get_file_from_relative_uri (session, uri, &fragment);
1188 GObject *loader = ianjuta_file_loader_load (IANJUTA_FILE_LOADER (plugin),
1189 file, FALSE, NULL);
1190 if (fragment != NULL)
1192 if (IANJUTA_IS_DOCUMENT_MANAGER (loader))
1194 ianjuta_document_manager_goto_file_line (IANJUTA_DOCUMENT_MANAGER (loader), file, atoi(fragment), NULL);
1197 g_object_unref (file);
1199 g_free (uri);
1201 g_list_free (files);
1204 static void
1205 setup_recent_chooser_menu (GtkRecentChooser* recent_menu, AnjutaFileLoaderPlugin* plugin)
1207 GtkRecentFilter *filter;
1209 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1210 gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1211 gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER (recent_menu), TRUE);
1212 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (recent_menu), GTK_RECENT_SORT_MRU);
1213 gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (recent_menu), 20);
1215 filter = gtk_recent_filter_new ();
1216 gtk_recent_filter_add_application (filter, g_get_application_name ());
1217 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (recent_menu), filter);
1219 g_signal_connect (recent_menu, "item-activated",
1220 G_CALLBACK (on_open_recent_file), plugin);
1223 static gboolean
1224 activate_plugin (AnjutaPlugin *plugin)
1226 GtkAction *action, *saction;
1227 AnjutaUI *ui;
1228 AnjutaFileLoaderPlugin *loader_plugin;
1229 GtkActionGroup *group;
1230 GtkWidget *widget;
1231 GtkWidget* recent_menu;
1232 GtkWidget* toolbar_menu;
1234 loader_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1236 DEBUG_PRINT ("%s", "AnjutaFileLoaderPlugin: Activating File Loader plugin…");
1238 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1240 /* Recent manager */
1241 loader_plugin->recent_manager = gtk_recent_manager_get_default();
1243 /* Add action group */
1244 loader_plugin->action_group =
1245 anjuta_ui_add_action_group_entries (ui, "ActionGroupLoader",
1246 _("File Loader"),
1247 actions_file,
1248 G_N_ELEMENTS (actions_file),
1249 GETTEXT_PACKAGE, TRUE, plugin);
1250 loader_plugin->popup_action_group =
1251 anjuta_ui_add_action_group_entries (ui, "ActionGroupPopupLoader",
1252 _("File Loader"),
1253 popup_actions_file,
1254 G_N_ELEMENTS (popup_actions_file),
1255 GETTEXT_PACKAGE, FALSE, plugin);
1256 saction = gtk_recent_action_new ("ActionFileWizard", _("New"),
1257 _("New file, project and project components."), NULL);
1258 g_object_set (saction, "stock-id", GTK_STOCK_NEW, NULL);
1259 gtk_action_group_add_action (loader_plugin->action_group,
1260 GTK_ACTION (saction));
1262 /* Set short labels */
1263 action = anjuta_ui_get_action (ui, "ActionGroupLoader", "ActionFileOpen");
1264 g_object_set (G_OBJECT (action), "short-label", _("Open"),
1265 "is-important", TRUE, NULL);
1267 group = gtk_action_group_new ("ActionGroupLoaderRecent");
1268 action = gtk_recent_action_new ("ActionFileOpenRecent", _("Open _Recent"),
1269 _("Open recent file"), NULL);
1270 g_object_set (action, "stock-id", GTK_STOCK_OPEN, NULL);
1271 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (action), loader_plugin);
1273 gtk_action_group_add_action (group, action);
1274 anjuta_ui_add_action_group (ui, "ActionGroupLoaderRecent",
1275 N_("Open recent files"), group, FALSE);
1276 loader_plugin->recent_group = group;
1278 /* Add UI */
1279 loader_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
1281 /* Adding submenus */
1282 recent_menu = anjuta_recent_chooser_menu_new_for_manager (loader_plugin->recent_manager);
1283 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (recent_menu), loader_plugin);
1284 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1285 "/MenuMain/MenuFile/PlaceholderFileMenus/OpenRecent");
1286 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget),
1287 recent_menu);
1289 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1290 "/MenuMain/MenuFile/PlaceholderFileMenus/Wizard");
1291 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), on_create_submenu(loader_plugin));
1293 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1294 "/ToolbarMain/PlaceholderFileToolbar/New");
1295 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), on_create_submenu(loader_plugin));
1296 g_signal_connect (widget, "clicked", G_CALLBACK (on_new_clicked), loader_plugin);
1298 widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
1299 "/ToolbarMain/PlaceholderFileToolbar/Open");
1300 toolbar_menu = anjuta_recent_chooser_menu_new_for_manager (loader_plugin->recent_manager);
1301 setup_recent_chooser_menu (GTK_RECENT_CHOOSER (toolbar_menu), loader_plugin);
1302 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget),
1303 toolbar_menu);
1304 gtk_tool_button_set_label (GTK_TOOL_BUTTON (widget), _("Open"));
1305 gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (widget), _("Open a file"));
1306 gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (widget), _("Open recent file"));
1307 g_signal_connect (widget, "clicked", G_CALLBACK (on_open_clicked), loader_plugin);
1309 /* Install drag n drop handler */
1310 dnd_drop_init (GTK_WIDGET (plugin->shell), dnd_dropped, plugin);
1312 /* Add watches */
1313 loader_plugin->fm_watch_id =
1314 anjuta_plugin_add_watch (plugin, IANJUTA_FILE_MANAGER_SELECTED_FILE,
1315 value_added_fm_current_file,
1316 value_removed_fm_current_file, NULL);
1317 loader_plugin->pm_watch_id =
1318 anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_CURRENT_URI,
1319 value_added_pm_current_uri,
1320 value_removed_pm_current_uri, NULL);
1321 loader_plugin->dm_watch_id =
1322 anjuta_plugin_add_watch (plugin,
1323 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1324 on_value_added_current_doc,
1325 on_value_removed_current_doc,
1326 plugin);
1328 /* Connect to session */
1329 g_signal_connect (G_OBJECT (plugin->shell), "load_session",
1330 G_CALLBACK (on_session_load), plugin);
1331 return TRUE;
1334 static gboolean
1335 deactivate_plugin (AnjutaPlugin *plugin)
1337 AnjutaUI *ui;
1338 AnjutaFileLoaderPlugin *loader_plugin;
1340 loader_plugin = ANJUTA_PLUGIN_FILE_LOADER (plugin);
1342 DEBUG_PRINT ("%s", "AnjutaFileLoaderPlugin: Deactivating File Loader plugin…");
1344 /* Disconnect session */
1345 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1346 G_CALLBACK (on_session_load), plugin);
1348 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1349 /* Remove watches */
1350 anjuta_plugin_remove_watch (plugin, loader_plugin->fm_watch_id, TRUE);
1351 anjuta_plugin_remove_watch (plugin, loader_plugin->pm_watch_id, TRUE);
1352 /* Uninstall dnd */
1353 dnd_drop_finalize (GTK_WIDGET (plugin->shell), plugin);
1354 /* Remove UI */
1355 anjuta_ui_unmerge (ui, loader_plugin->uiid);
1356 /* Remove action group */
1357 anjuta_ui_remove_action_group (ui, loader_plugin->action_group);
1358 anjuta_ui_remove_action_group (ui, loader_plugin->popup_action_group);
1359 anjuta_ui_remove_action_group (ui, loader_plugin->recent_group);
1360 return TRUE;
1363 static void
1364 dispose (GObject *obj)
1366 G_OBJECT_CLASS (parent_class)->dispose (obj);
1369 static void
1370 finalize (GObject *obj)
1372 /* Finalization codes here */
1373 G_OBJECT_CLASS (parent_class)->finalize (obj);
1376 static void
1377 anjuta_file_loader_plugin_instance_init (GObject *obj)
1379 AnjutaFileLoaderPlugin *plugin = ANJUTA_PLUGIN_FILE_LOADER (obj);
1381 plugin->fm_current_uri = NULL;
1382 plugin->pm_current_uri = NULL;
1383 plugin->dm_current_uri = NULL;
1386 static void
1387 anjuta_file_loader_plugin_class_init (GObjectClass *klass)
1389 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1391 parent_class = g_type_class_peek_parent (klass);
1393 plugin_class->activate = activate_plugin;
1394 plugin_class->deactivate = deactivate_plugin;
1395 klass->dispose = dispose;
1396 klass->finalize = finalize;
1399 static GObject*
1400 iloader_load (IAnjutaFileLoader *loader, GFile* file,
1401 gboolean read_only, GError **err)
1403 gchar *mime_type;
1404 AnjutaStatus *status;
1405 AnjutaPluginManager *plugin_manager;
1406 GList *plugin_descs = NULL;
1407 GObject *plugin = NULL;
1408 gchar *uri = g_file_get_uri (file);
1410 g_return_val_if_fail (uri != NULL, NULL);
1412 mime_type = anjuta_util_get_file_mime_type (file);
1414 if (mime_type == NULL)
1416 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, NULL, FALSE);
1418 if (err == NULL)
1419 launch_application_failure (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, _("File not found"));
1421 g_set_error (err, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("File not found"));
1423 g_free (uri);
1424 return NULL;
1427 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (loader)->shell,
1428 NULL);
1429 status = anjuta_shell_get_status (ANJUTA_PLUGIN (loader)->shell, NULL);
1430 anjuta_status_busy_push (status);
1432 DEBUG_PRINT ("Opening URI: %s", uri);
1434 plugin_descs = get_available_plugins_for_mime (ANJUTA_PLUGIN (loader), mime_type);
1436 if (g_list_length (plugin_descs) > 1)
1438 gchar* basename = g_path_get_basename (uri);
1439 /* %s is name of file that will be opened */
1440 gchar* message = g_strdup_printf (_("Please select a plugin to open <b>%s</b>."),
1441 basename);
1442 plugin =
1443 anjuta_plugin_manager_select_and_activate (plugin_manager,
1444 _("Open With"),
1445 message,
1446 plugin_descs);
1447 g_free (basename);
1448 g_free (message);
1450 else if (g_list_length (plugin_descs) == 1)
1452 gchar *location = NULL;
1454 AnjutaPluginDescription *desc = plugin_descs->data;
1455 anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
1456 "Location", &location);
1457 g_return_val_if_fail (location != NULL, NULL);
1458 plugin =
1459 anjuta_plugin_manager_get_plugin_by_id (plugin_manager,
1460 location);
1461 g_free (location);
1463 else
1465 GAppInfo *appinfo;
1466 GList *uris = NULL;
1468 uris = g_list_prepend (uris, (gpointer)uri);
1470 appinfo = g_app_info_get_default_for_type (mime_type, TRUE);
1471 if (appinfo)
1473 GError *error = NULL;
1474 if (!g_app_info_launch_uris (appinfo, uris, NULL, &error))
1476 open_with_dialog (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type);
1478 else
1480 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type, error == NULL);
1482 g_object_unref (G_OBJECT (appinfo));
1484 g_list_free (uris);
1487 if (plugin)
1489 GError *error = NULL;
1491 ianjuta_file_open (IANJUTA_FILE(plugin), file, &error);
1492 if (error != NULL)
1495 if (err == NULL)
1496 launch_application_failure (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, error->message);
1497 g_propagate_error (err, error);
1499 update_recent_file (ANJUTA_PLUGIN_FILE_LOADER (loader), uri, mime_type, error == NULL);
1502 if (plugin_descs)
1503 g_list_free (plugin_descs);
1505 g_free (mime_type);
1506 g_free (uri);
1507 anjuta_status_busy_pop (status);
1509 return plugin;
1512 static void
1513 iloader_iface_init(IAnjutaLoaderIface *iface)
1515 iface->find_plugins = NULL;
1518 static void
1519 iloader_file_iface_init(IAnjutaFileLoaderIface *iface)
1521 iface->load = iloader_load;
1524 ANJUTA_PLUGIN_BEGIN (AnjutaFileLoaderPlugin, anjuta_file_loader_plugin);
1525 ANJUTA_PLUGIN_ADD_INTERFACE (iloader, IANJUTA_TYPE_LOADER);
1526 ANJUTA_PLUGIN_ADD_INTERFACE (iloader_file, IANJUTA_TYPE_FILE_LOADER);
1527 ANJUTA_PLUGIN_END;
1529 ANJUTA_SIMPLE_PLUGIN (AnjutaFileLoaderPlugin, anjuta_file_loader_plugin);