1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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
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>
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
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
{
61 gint project_watch_id
;
65 on_recent_project_activated (GtkListBox
*box
, GtkListBoxRow
*row
, gpointer user_data
)
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
);
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
),
82 GList
*plugin_handles
= NULL
;
85 plugin_handles
= anjuta_plugin_manager_query (plugin_manager
,
90 if (plugin_handles
!= NULL
)
93 anjuta_plugin_manager_get_plugin_by_handle (plugin_manager
, (AnjutaPluginHandle
*)plugin_handles
->data
);
95 ianjuta_wizard_activate (IANJUTA_WIZARD (wizard
), NULL
);
97 g_list_free (plugin_handles
);
101 on_local_doc_activated (GtkListBoxRow
*row
, gpointer user_data
)
103 gtk_show_uri (NULL
, "help:anjuta-manual", GDK_CURRENT_TIME
, NULL
);
107 on_local_faq_activated (GtkListBoxRow
*row
, gpointer user_data
)
109 gtk_show_uri (NULL
, "help:anjuta-faqs", GDK_CURRENT_TIME
, NULL
);
113 on_online_doc_activated (GtkListBoxRow
*row
, gpointer user_data
)
115 gtk_show_uri (NULL
, "https://developer.gnome.org/references", GDK_CURRENT_TIME
, NULL
);
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
);
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
),
131 GList
*plugin_handles
= NULL
;
133 plugin_handles
= anjuta_plugin_manager_query (plugin_manager
,
139 if (plugin_handles
!= NULL
)
142 anjuta_plugin_manager_get_plugin_by_handle (plugin_manager
, (AnjutaPluginHandle
*)plugin_handles
->data
);
144 ianjuta_wizard_activate (IANJUTA_WIZARD (wizard
), NULL
);
146 g_list_free (plugin_handles
);
150 on_row_activated (GtkListBox
*box
, GtkListBoxRow
*row
, gpointer user_data
)
156 name
= gtk_widget_get_name (row
);
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
);
175 add_recent_project_row (GtkListBox
*recent_project_box
, GtkRecentData
*recent_project
)
179 GtkWidget
*recent_row
;
180 GtkLabel
*project_label
, *path_label
;
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
);
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
);
211 refresh_recent_project_view (GtkListBox
*box
)
214 GtkRecentManager
*manager
;
215 GtkRecentData
*recent_project
;
220 manager
= gtk_recent_manager_get_default ();
221 items
= gtk_recent_manager_get_items (manager
);
222 items
= g_list_reverse (items
);
224 settings
= g_settings_new (PREF_SCHEMA
);
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
);
237 g_list_free_full(items
, (GDestroyNotify
)gtk_recent_info_unref
);
238 g_object_unref (settings
);
242 on_remove_project_clicked (GtkButton
*button
, gpointer user_data
)
244 GtkRecentManager
*manager
;
245 GtkListBox
*recent_list_box
;
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
);
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
);
261 DEBUG_PRINT ("Could not remove recent item. %s", error
->message
);
262 g_error_free (error
);
269 add_action_separators (GtkListBoxRow
*row
, GtkListBoxRow
*before
, gpointer user_data
)
276 current
= gtk_list_box_row_get_header (row
);
279 current
= gtk_separator_new (GTK_ORIENTATION_HORIZONTAL
);
280 gtk_widget_show (current
);
281 gtk_list_box_row_set_header (row
, current
);
292 create_starter_widget (StarterPlugin
* plugin
)
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
;
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
);
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
);
357 /* Remove the starter plugin once a document was opened */
359 on_value_added_current_project (AnjutaPlugin
*plugin
, const gchar
*name
,
360 const GValue
*value
, gpointer data
)
364 StarterPlugin
*splugin
;
366 project
= g_value_get_object (value
);
367 shell
= ANJUTA_PLUGIN(plugin
)->shell
;
368 splugin
= ANJUTA_PLUGIN_STARTER (plugin
);
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 */
383 on_value_added_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
384 const GValue
*value
, gpointer data
)
388 StarterPlugin
*splugin
;
390 doc
= g_value_get_object (value
);
391 shell
= ANJUTA_PLUGIN(plugin
)->shell
;
392 splugin
= ANJUTA_PLUGIN_STARTER (plugin
);
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
;
405 on_value_removed (AnjutaPlugin
*plugin
,
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
,
414 IAnjutaProjectManager
* pm
= anjuta_shell_get_interface (shell
,
415 IAnjutaProjectManager
,
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
,
427 ANJUTA_SHELL_PLACEMENT_CENTER
,
429 anjuta_shell_present_widget (shell
, splugin
->priv
->starter
, NULL
);
430 g_object_unref (splugin
->priv
->starter
);
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
,
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
,
466 splugin
->priv
->project_watch_id
=
467 anjuta_plugin_add_watch (plugin
,
468 IANJUTA_PROJECT_MANAGER_CURRENT_PROJECT
,
469 on_value_added_current_project
,
472 on_value_removed (plugin
, NULL
, splugin
);
474 g_signal_connect (anjuta_plugin_get_shell (plugin
),
476 G_CALLBACK (on_session_load
),
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
);
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
);
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
);
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
);
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
);