Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / starter / plugin.c
blob178fc8ad8139d57418874d7cbc92523dc857b59e
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2008 Ignacio Casal Quinteiro
5 Copyright (C) 2014 Tristian Celestin
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <config.h>
23 #include <libanjuta/anjuta-shell.h>
24 #include <libanjuta/anjuta-debug.h>
25 #include <libanjuta/anjuta-encodings.h>
26 #include <libanjuta/interfaces/ianjuta-document-manager.h>
27 #include <libanjuta/interfaces/ianjuta-project-manager.h>
28 #include <libanjuta/interfaces/ianjuta-file-loader.h>
29 #include <libanjuta/interfaces/ianjuta-wizard.h>
30 #include <gtk/gtk.h>
31 #include "plugin.h"
33 #define PREF_SCHEMA "org.gnome.anjuta.starter"
34 #define RECENT_LIMIT "recent-limit"
35 #define STARTER_BOX "starter_box"
36 #define SWITCHER_BOX "switcher_box"
37 #define ACTIONS_LISTBOX "actions_listbox"
38 #define ACTIONS_FRAME "actions_frame"
39 #define RECENT_PROJECTS_BOX "recent_projects_box"
40 #define RECENT_LISTBOX "recent_listbox"
41 #define IMPORT_ROW "import_row"
42 #define ANJUTA_DOC_ROW "anjuta_doc_row"
43 #define ANJUTA_FAQ_ROW "anjuta_faq_row"
44 #define ONLINE_DOC_ROW "gtk_doc_row"
45 #define RECENT_ROW "recent_row"
46 #define CREATE_ROW "create_row"
47 #define CODE_ROW "code_row"
48 #define PROJECT_LABEL "project_label"
49 #define PATH_LABEL "path_label"
50 #define TRANSITION_TIME 90
51 #define URI_KEY "uri"
52 #define REMOVE_PROJECT_BUTTON "remove_project_button"
53 #define ACTIONS_ID "actions"
54 #define RECENT_PROJECTS_ID "recent_projects"
55 #define PROJECT_WIZARD_ID "anjuta-project-wizard:NPWPlugin"
56 #define PROJECT_IMPORT_ID "anjuta-project-import:AnjutaProjectImportPlugin"
58 struct _StarterPluginPrivate {
59 GtkWidget *starter;
60 gint editor_watch_id;
61 gint project_watch_id;
64 void
65 on_recent_project_activated (GtkListBox *box, GtkListBoxRow *row, gpointer user_data)
67 GFile *file;
68 IAnjutaFileLoader *loader;
70 loader = anjuta_shell_get_interface (anjuta_plugin_get_shell (ANJUTA_PLUGIN (user_data)), IAnjutaFileLoader, NULL);
71 file = g_file_new_for_uri ((const char*) g_object_get_data (G_OBJECT (row), URI_KEY));
72 ianjuta_file_loader_load (IANJUTA_FILE_LOADER (loader), file, FALSE, NULL);
75 static void
76 on_new_project_activated (GtkListBoxRow *row, gpointer user_data)
78 AnjutaPlugin *plugin = ANJUTA_PLUGIN (user_data);
79 AnjutaPluginManager *plugin_manager =
80 anjuta_shell_get_plugin_manager (anjuta_plugin_get_shell (plugin),
81 NULL);
82 GList *plugin_handles = NULL;
85 plugin_handles = anjuta_plugin_manager_query (plugin_manager,
86 "Anjuta Plugin",
87 "Location",
88 PROJECT_WIZARD_ID,
89 NULL);
90 if (plugin_handles != NULL)
92 GObject* wizard =
93 anjuta_plugin_manager_get_plugin_by_handle (plugin_manager, (AnjutaPluginHandle *)plugin_handles->data);
94 if (wizard)
95 ianjuta_wizard_activate (IANJUTA_WIZARD (wizard), NULL);
97 g_list_free (plugin_handles);
100 static void
101 on_local_doc_activated (GtkListBoxRow *row, gpointer user_data)
103 gtk_show_uri (NULL, "help:anjuta-manual", GDK_CURRENT_TIME, NULL);
106 static void
107 on_local_faq_activated (GtkListBoxRow *row, gpointer user_data)
109 gtk_show_uri (NULL, "help:anjuta-faqs", GDK_CURRENT_TIME, NULL);
112 static void
113 on_online_doc_activated (GtkListBoxRow *row, gpointer user_data)
115 gtk_show_uri (NULL, "https://developer.gnome.org/references", GDK_CURRENT_TIME, NULL);
118 static void
119 on_search_example_code_activated (GtkListBoxRow *row, gpointer user_data)
121 gtk_show_uri (NULL, "http://www.softwareheritage.org/archive", GDK_CURRENT_TIME, NULL);
124 static void
125 on_import_project_activated (GtkListBoxRow *row, gpointer user_data)
127 AnjutaPlugin* plugin = ANJUTA_PLUGIN (user_data);
128 AnjutaPluginManager* plugin_manager =
129 anjuta_shell_get_plugin_manager (anjuta_plugin_get_shell (plugin),
130 NULL);
131 GList *plugin_handles = NULL;
133 plugin_handles = anjuta_plugin_manager_query (plugin_manager,
134 "Anjuta Plugin",
135 "Location",
136 PROJECT_IMPORT_ID,
137 NULL);
139 if (plugin_handles != NULL)
141 GObject* wizard =
142 anjuta_plugin_manager_get_plugin_by_handle (plugin_manager, (AnjutaPluginHandle *)plugin_handles->data);
143 if (wizard)
144 ianjuta_wizard_activate (IANJUTA_WIZARD (wizard), NULL);
146 g_list_free (plugin_handles);
149 void
150 on_row_activated (GtkListBox *box, GtkListBoxRow *row, gpointer user_data)
152 gchar *name;
154 if (row != NULL)
156 name = gtk_widget_get_name (row);
157 if (name != NULL) {
158 if (g_strcmp0 (name, CREATE_ROW) == 0)
159 on_new_project_activated (row, user_data);
160 else if (g_strcmp0 (name, IMPORT_ROW) == 0)
161 on_import_project_activated (row, user_data);
162 else if (g_strcmp0 (name, ANJUTA_DOC_ROW) == 0)
163 on_local_doc_activated (row, user_data);
164 else if (g_strcmp0 (name, ANJUTA_FAQ_ROW) == 0)
165 on_local_faq_activated (row, user_data);
166 else if (g_strcmp0 (name, ONLINE_DOC_ROW) == 0)
167 on_online_doc_activated (row, user_data);
168 else if (g_strcmp0 (name, CODE_ROW) == 0)
169 on_search_example_code_activated (row, user_data);
174 static void
175 add_recent_project_row (GtkListBox *recent_project_box, GtkRecentData *recent_project)
177 GtkBuilder *builder;
178 GFile *file;
179 GtkWidget *recent_row;
180 GtkLabel *project_label, *path_label;
181 GError *error;
183 error = NULL;
184 builder = gtk_builder_new ();
185 if (!gtk_builder_add_from_resource (builder, "/org/gnome/anjuta/ui/starter.ui", &error))
187 DEBUG_PRINT ("Could not load starter.ui! %s", error->message);
188 g_error_free (error);
190 else
192 file = g_file_new_for_uri (gtk_recent_info_get_uri (recent_project));
193 if (g_file_query_exists (file, NULL))
195 recent_row = GTK_WIDGET (gtk_builder_get_object (builder, RECENT_ROW));
196 project_label = GTK_WIDGET (gtk_builder_get_object (builder, PROJECT_LABEL));
197 path_label = GTK_WIDGET (gtk_builder_get_object (builder, PATH_LABEL));
198 gtk_label_set_text (project_label, gtk_recent_info_get_display_name(recent_project));
199 gtk_label_set_text (path_label, g_file_get_path(file));
200 g_object_set_data_full (G_OBJECT (recent_row), URI_KEY, g_file_get_uri(file), g_free);
201 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (recent_row)), recent_row);
202 gtk_list_box_insert (recent_project_box, recent_row, -1);
204 g_object_unref (file);
207 g_object_unref (builder);
210 static void
211 refresh_recent_project_view (GtkListBox *box)
213 GSettings *settings;
214 GtkRecentManager *manager;
215 GtkRecentData *recent_project;
216 GList *items, *list;
217 gint i;
218 guint recent_limit;
220 manager = gtk_recent_manager_get_default ();
221 items = gtk_recent_manager_get_items (manager);
222 items = g_list_reverse (items);
223 list = items;
224 settings = g_settings_new (PREF_SCHEMA);
225 i = 0;
226 g_settings_get (settings, RECENT_LIMIT, "i", &recent_limit);
227 while (i < recent_limit && list != NULL)
229 if (strcmp (gtk_recent_info_get_mime_type (list->data), "application/x-anjuta") == 0)
231 recent_project = list->data;
232 add_recent_project_row (box, recent_project);
233 i++;
235 list = list->next;
237 g_list_free_full(items, (GDestroyNotify)gtk_recent_info_unref);
238 g_object_unref (settings);
241 static void
242 on_remove_project_clicked (GtkButton *button, gpointer user_data)
244 GtkRecentManager *manager;
245 GtkListBox *recent_list_box;
246 GtkListBoxRow *row;
247 GError *error;
249 manager = gtk_recent_manager_get_default ();
250 recent_list_box = GTK_LIST_BOX (user_data);
251 row = gtk_list_box_get_selected_row (recent_list_box);
252 error = NULL;
253 if (row != NULL)
255 if (gtk_recent_manager_remove_item (manager, g_object_get_data (row, URI_KEY), &error))
257 gtk_container_remove (GTK_CONTAINER (recent_list_box), row);
259 else
261 DEBUG_PRINT ("Could not remove recent item. %s", error->message);
262 g_error_free (error);
268 static void
269 add_action_separators (GtkListBoxRow *row, GtkListBoxRow *before, gpointer user_data)
271 GtkWidget *current;
273 if (before == NULL)
274 return;
276 current = gtk_list_box_row_get_header (row);
277 if (current == NULL)
279 current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
280 gtk_widget_show (current);
281 gtk_list_box_row_set_header (row, current);
285 static void
286 show_starter_page ()
288 return;
291 static GtkWidget*
292 create_starter_widget (StarterPlugin* plugin)
294 GError *error;
295 GtkWidget *stack;
296 GtkWidget *switcher;
297 GtkWidget *starter_box;
298 GtkWidget *switcher_box;
299 GtkWidget *actions_frame;
300 GtkWidget *actions_listbox;
301 GtkWidget *recent_projects_box;
302 GtkWidget *recent_listbox;
303 GtkBuilder *builder;
304 GtkWidget *button;
306 error = NULL;
307 builder = gtk_builder_new ();
309 if (!gtk_builder_add_from_resource (builder, "/org/gnome/anjuta/ui/starter.ui", &error))
311 DEBUG_PRINT ("Could not load starter.ui! %s", error->message);
312 g_error_free (error);
314 else
316 /* Manually assembling stack and switcher because they are not available in glade yet */
317 switcher = gtk_stack_switcher_new ();
318 stack = gtk_stack_new ();
319 gtk_stack_switcher_set_stack (switcher, stack);
320 gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_CROSSFADE);
321 gtk_stack_set_transition_duration (stack, TRANSITION_TIME);
323 starter_box = GTK_WIDGET (gtk_builder_get_object (builder, STARTER_BOX));
324 switcher_box = GTK_WIDGET (gtk_builder_get_object (builder, SWITCHER_BOX));
325 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (starter_box)), starter_box);
326 g_object_ref (starter_box);
327 gtk_box_pack_start (switcher_box, switcher, FALSE, FALSE, 0);
328 gtk_box_pack_start (starter_box, stack, FALSE, FALSE, 0);
329 gtk_widget_show_all (starter_box);
331 actions_listbox = GTK_WIDGET (gtk_builder_get_object (builder, ACTIONS_LISTBOX));
332 gtk_list_box_set_header_func (GTK_LIST_BOX (actions_listbox), add_action_separators, NULL, NULL);
333 actions_frame = GTK_WIDGET (gtk_builder_get_object (builder, ACTIONS_FRAME));
334 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (actions_frame)), actions_frame);
335 g_object_ref (actions_frame);
336 gtk_stack_add_titled (stack, actions_frame, ACTIONS_ID, "Actions");
338 recent_projects_box = GTK_WIDGET (gtk_builder_get_object (builder, RECENT_PROJECTS_BOX));
339 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (recent_projects_box)), recent_projects_box);
340 g_object_ref (recent_projects_box);
342 recent_listbox = GTK_WIDGET (gtk_builder_get_object (builder, RECENT_LISTBOX));
343 refresh_recent_project_view (GTK_LIST_BOX (recent_listbox));
345 gtk_stack_add_titled (stack, recent_projects_box, RECENT_PROJECTS_ID, "Recent Projects");
347 button = GTK_WIDGET (gtk_builder_get_object (builder, REMOVE_PROJECT_BUTTON));
348 g_signal_connect_object (G_OBJECT (button), "clicked",
349 G_CALLBACK (on_remove_project_clicked), recent_listbox, G_CONNECT_AFTER);
351 gtk_builder_connect_signals (builder, plugin);
353 g_object_unref (builder);
354 return starter_box;
357 /* Remove the starter plugin once a document was opened */
358 static void
359 on_value_added_current_project (AnjutaPlugin *plugin, const gchar *name,
360 const GValue *value, gpointer data)
362 GObject *project;
363 AnjutaShell *shell;
364 StarterPlugin *splugin;
366 project = g_value_get_object (value);
367 shell = ANJUTA_PLUGIN(plugin)->shell;
368 splugin = ANJUTA_PLUGIN_STARTER (plugin);
369 if (project)
371 if (splugin->priv->starter)
373 DEBUG_PRINT ("Hiding starter");
374 anjuta_shell_remove_widget (shell, splugin->priv->starter, NULL);
376 splugin->priv->starter = NULL;
381 /* Remove the starter plugin once a document was opened */
382 static void
383 on_value_added_current_editor (AnjutaPlugin *plugin, const gchar *name,
384 const GValue *value, gpointer data)
386 GObject *doc;
387 AnjutaShell *shell;
388 StarterPlugin *splugin;
390 doc = g_value_get_object (value);
391 shell = ANJUTA_PLUGIN(plugin)->shell;
392 splugin = ANJUTA_PLUGIN_STARTER (plugin);
393 if (doc)
395 if (splugin->priv->starter)
397 DEBUG_PRINT ("Hiding starter");
398 anjuta_shell_remove_widget (shell, splugin->priv->starter, NULL);
400 splugin->priv->starter = NULL;
404 static void
405 on_value_removed (AnjutaPlugin *plugin,
406 const gchar *name,
407 gpointer data)
409 AnjutaShell* shell = anjuta_plugin_get_shell (plugin);
410 StarterPlugin* splugin = ANJUTA_PLUGIN_STARTER (plugin);
411 IAnjutaDocumentManager* docman = anjuta_shell_get_interface (shell,
412 IAnjutaDocumentManager,
413 NULL);
414 IAnjutaProjectManager* pm = anjuta_shell_get_interface (shell,
415 IAnjutaProjectManager,
416 NULL);
418 if (!(docman && ianjuta_document_manager_get_doc_widgets (docman, NULL)) &&
419 !(pm && ianjuta_project_manager_get_current_project (pm, NULL)))
421 DEBUG_PRINT ("Showing starter");
422 splugin->priv->starter = create_starter_widget (splugin);
423 anjuta_shell_add_widget (shell, splugin->priv->starter,
424 "AnjutaStarter",
425 _("Start"),
426 GTK_STOCK_ABOUT,
427 ANJUTA_SHELL_PLACEMENT_CENTER,
428 NULL);
429 anjuta_shell_present_widget (shell, splugin->priv->starter, NULL);
430 g_object_unref (splugin->priv->starter);
434 static void
435 on_session_load (AnjutaShell *shell,
436 AnjutaSessionPhase phase,
437 AnjutaSession *session,
438 StarterPlugin *plugin)
440 if (phase == ANJUTA_SESSION_PHASE_END)
442 if (!plugin->priv->starter)
443 on_value_removed (ANJUTA_PLUGIN (plugin), NULL, plugin);
444 if (plugin->priv->starter)
446 anjuta_shell_maximize_widget (shell,
447 "AnjutaStarter",
448 NULL);
453 static gboolean
454 activate_plugin (AnjutaPlugin *plugin)
456 StarterPlugin *splugin = ANJUTA_PLUGIN_STARTER (plugin);
458 DEBUG_PRINT ("StarterPlugin: Activating document manager plugin...");
460 splugin->priv->editor_watch_id =
461 anjuta_plugin_add_watch (plugin,
462 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
463 on_value_added_current_editor,
464 on_value_removed,
465 NULL);
466 splugin->priv->project_watch_id =
467 anjuta_plugin_add_watch (plugin,
468 IANJUTA_PROJECT_MANAGER_CURRENT_PROJECT,
469 on_value_added_current_project,
470 on_value_removed,
471 NULL);
472 on_value_removed (plugin, NULL, splugin);
474 g_signal_connect (anjuta_plugin_get_shell (plugin),
475 "load-session",
476 G_CALLBACK (on_session_load),
477 plugin);
479 return TRUE;
482 static gboolean
483 deactivate_plugin (AnjutaPlugin *plugin)
485 StarterPlugin* splugin = ANJUTA_PLUGIN_STARTER (plugin);
486 DEBUG_PRINT ("StarterPlugin: Deactivating starter plugin...");
487 if (splugin->priv->starter)
488 anjuta_shell_remove_widget (anjuta_plugin_get_shell (plugin),
489 splugin->priv->starter, NULL);
491 anjuta_plugin_remove_watch (plugin, splugin->priv->editor_watch_id, FALSE);
492 anjuta_plugin_remove_watch (plugin, splugin->priv->project_watch_id, FALSE);
494 return TRUE;
497 static void
498 dispose (GObject *obj)
500 AnjutaPluginClass *klass;
501 gpointer parent_class;
503 klass = ANJUTA_PLUGIN_GET_CLASS(obj);
504 parent_class = g_type_class_peek_parent (klass);
505 G_OBJECT_CLASS (parent_class)->dispose (obj);
508 static void
509 finalize (GObject *obj)
511 AnjutaPluginClass *klass;
512 gpointer parent_class;
514 /* Finalization codes here */
515 klass = ANJUTA_PLUGIN_GET_CLASS(obj);
516 parent_class = g_type_class_peek_parent (klass);
517 G_OBJECT_CLASS (parent_class)->finalize (obj);
520 static void
521 starter_plugin_instance_init (GObject *obj)
523 StarterPlugin *splugin;
525 splugin = ANJUTA_PLUGIN_STARTER (obj);
526 splugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, ANJUTA_TYPE_PLUGIN_STARTER, StarterPluginPrivate);
529 static void
530 starter_plugin_class_init (GObjectClass *klass)
532 AnjutaPluginClass *plugin_class;
534 g_type_class_add_private (klass, sizeof (StarterPluginPrivate));
535 plugin_class = ANJUTA_PLUGIN_CLASS (klass);
536 plugin_class->activate = activate_plugin;
537 plugin_class->deactivate = deactivate_plugin;
538 klass->dispose = dispose;
539 klass->finalize = finalize;
542 ANJUTA_PLUGIN_BOILERPLATE (StarterPlugin, starter_plugin);
543 ANJUTA_SIMPLE_PLUGIN (StarterPlugin, starter_plugin);