anjuta, document-manager, file-loader, glade, project-manager: Save relative URI
[anjuta.git] / plugins / document-manager / plugin.c
blob1aaaa52382b0bb2556c61827ad6ab8bfa6bfde57
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2000-2008 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>
22 #include <libanjuta/anjuta-shell.h>
23 #include <libanjuta/anjuta-debug.h>
24 #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.h>
29 #include <libanjuta/interfaces/ianjuta-editor.h>
30 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
31 #include <libanjuta/interfaces/ianjuta-editor-convert.h>
32 #include <libanjuta/interfaces/ianjuta-editor-view.h>
33 #include <libanjuta/interfaces/ianjuta-editor-line-mode.h>
34 #include <libanjuta/interfaces/ianjuta-editor-factory.h>
35 #include <libanjuta/interfaces/ianjuta-editor-folds.h>
36 #include <libanjuta/interfaces/ianjuta-editor-comment.h>
37 #include <libanjuta/interfaces/ianjuta-editor-zoom.h>
38 #include <libanjuta/interfaces/ianjuta-editor-goto.h>
39 #include <libanjuta/interfaces/ianjuta-editor-search.h>
40 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
41 #include <libanjuta/interfaces/ianjuta-file-savable.h>
42 #include <libanjuta/interfaces/ianjuta-editor-language.h>
43 #include <libanjuta/interfaces/ianjuta-language.h>
44 #include <libanjuta/interfaces/ianjuta-preferences.h>
45 #include <libanjuta/interfaces/ianjuta-document.h>
47 #include "anjuta-docman.h"
48 #include "action-callbacks.h"
49 #include "plugin.h"
50 #include "search-box.h"
51 #include "anjuta-bookmarks.h"
53 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-document-manager.xml"
54 #define PREFS_BUILDER PACKAGE_DATA_DIR"/glade/anjuta-document-manager.ui"
55 #define ICON_FILE "anjuta-document-manager-plugin-48.png"
57 #define PREF_SCHEMA "org.gnome.anjuta.document-manager"
59 #define ANJUTA_PIXMAP_BOOKMARK_TOGGLE "anjuta-bookmark-toggle"
60 #define ANJUTA_PIXMAP_BOOKMARK_PREV "anjuta-bookmark-prev"
61 #define ANJUTA_PIXMAP_BOOKMARK_NEXT "anjuta-bookmark-next"
62 #define ANJUTA_PIXMAP_BOOKMARK_CLEAR "anjuta-bookmark-clear"
64 #define ANJUTA_PIXMAP_FOLD_TOGGLE "anjuta-fold-toggle"
65 #define ANJUTA_PIXMAP_FOLD_CLOSE "anjuta-fold-close"
66 #define ANJUTA_PIXMAP_FOLD_OPEN "anjuta-fold-open"
68 #define ANJUTA_PIXMAP_BLOCK_SELECT "anjuta-block-select"
69 #define ANJUTA_PIXMAP_BLOCK_START "anjuta-block-start"
70 #define ANJUTA_PIXMAP_BLOCK_END "anjuta-block-end"
72 #define ANJUTA_PIXMAP_INDENT_INC "anjuta-indent-more"
73 #define ANJUTA_PIXMAP_INDENT_DCR "anjuta-indent-less"
75 #define ANJUTA_PIXMAP_GOTO_LINE "anjuta-go-line"
77 #define ANJUTA_PIXMAP_HISTORY_NEXT "anjuta-go-history-next"
78 #define ANJUTA_PIXMAP_HISTORY_PREV "anjuta-go-history-prev"
80 #define ANJUTA_PIXMAP_AUTOCOMPLETE "anjuta-complete-auto"
82 /* Stock icons */
83 #define ANJUTA_STOCK_FOLD_TOGGLE "anjuta-fold-toggle"
84 #define ANJUTA_STOCK_FOLD_OPEN "anjuta-fold-open"
85 #define ANJUTA_STOCK_FOLD_CLOSE "anjuta-fold-close"
86 #define ANJUTA_STOCK_BLOCK_SELECT "anjuta-block-select"
87 #define ANJUTA_STOCK_INDENT_INC "anjuta-indent-inc"
88 #define ANJUTA_STOCK_INDENT_DCR "anjuta-indect-dcr"
89 #define ANJUTA_STOCK_PREV_BRACE "anjuta-prev-brace"
90 #define ANJUTA_STOCK_NEXT_BRACE "anjuta-next-brace"
91 #define ANJUTA_STOCK_BLOCK_START "anjuta-block-start"
92 #define ANJUTA_STOCK_BLOCK_END "anjuta-block-end"
93 #define ANJUTA_STOCK_BOOKMARK_TOGGLE "anjuta-bookmark-toggle"
94 #define ANJUTA_STOCK_BOOKMARK_PREV "anjuta-bookmark-previous"
95 #define ANJUTA_STOCK_BOOKMARK_NEXT "anjuta-bookmark-next"
96 #define ANJUTA_STOCK_BOOKMARK_CLEAR "anjuta-bookmark-clear"
97 #define ANJUTA_STOCK_GOTO_LINE "anjuta-goto-line"
98 #define ANJUTA_STOCK_HISTORY_NEXT "anjuta-history-next"
99 #define ANJUTA_STOCK_HISTORY_PREV "anjuta-history-prev"
100 #define ANJUTA_STOCK_MATCH_NEXT "anjuta-match-next"
101 #define ANJUTA_STOCK_MATCH_PREV "anjuta-match-prev"
102 #define ANJUTA_STOCK_AUTOCOMPLETE "anjuta-autocomplete"
105 static gpointer parent_class;
107 /* Shortcuts implementation */
108 enum {
109 m___ = 0,
110 mS__ = GDK_SHIFT_MASK,
111 m_C_ = GDK_CONTROL_MASK,
112 m__M = GDK_MOD1_MASK,
113 mSC_ = GDK_SHIFT_MASK | GDK_CONTROL_MASK,
116 enum {
117 ID_NEXTBUFFER = 1, /* Note: the value mustn't be 0 ! */
118 ID_PREVBUFFER,
119 ID_FIRSTBUFFER
122 typedef struct {
123 gint modifiers;
124 guint gdk_key;
125 gint id;
126 } ShortcutMapping;
128 static ShortcutMapping global_keymap[] = {
129 /* FIXME: HIG requires that Ctrl+Tab be used to transfer focus in multiline
130 text entries. So we can't use the following ctrl+tabbing. Is there other
131 sensible keys that can be used for them?
134 { m_C_, GDK_Tab, ID_NEXTBUFFER },
135 { mSC_, GDK_ISO_Left_Tab, ID_PREVBUFFER },
137 { m__M, GDK_KEY_1, ID_FIRSTBUFFER },
138 { m__M, GDK_KEY_2, ID_FIRSTBUFFER + 1},
139 { m__M, GDK_KEY_3, ID_FIRSTBUFFER + 2},
140 { m__M, GDK_KEY_4, ID_FIRSTBUFFER + 3},
141 { m__M, GDK_KEY_5, ID_FIRSTBUFFER + 4},
142 { m__M, GDK_KEY_6, ID_FIRSTBUFFER + 5},
143 { m__M, GDK_KEY_7, ID_FIRSTBUFFER + 6},
144 { m__M, GDK_KEY_8, ID_FIRSTBUFFER + 7},
145 { m__M, GDK_KEY_9, ID_FIRSTBUFFER + 8},
146 { m__M, GDK_KEY_0, ID_FIRSTBUFFER + 9},
147 { 0, 0, 0 }
150 static GtkActionEntry actions_file[] = {
151 { "ActionFileSave", GTK_STOCK_SAVE, N_("_Save"), "<control>s",
152 N_("Save current file"), G_CALLBACK (on_save_activate)},
153 { "ActionFileSaveAs", GTK_STOCK_SAVE_AS, N_("Save _As…"), "<shift><control>s",
154 N_("Save the current file with a different name"),
155 G_CALLBACK (on_save_as_activate)},
156 { "ActionFileSaveAll", GTK_STOCK_SAVE, N_("Save A_ll"), "<shift><control>l",
157 N_("Save all currently open files, except new files"),
158 G_CALLBACK (on_save_all_activate)},
159 { "ActionFileClose", GTK_STOCK_CLOSE, N_("_Close File"), "<control>w",
160 N_("Close current file"),
161 G_CALLBACK (on_close_file_activate)},
162 { "ActionFileCloseAll", GTK_STOCK_CLOSE, N_("Close All"), "<shift><control>w",
163 N_("Close all files"),
164 G_CALLBACK (on_close_all_file_activate)},
165 { "ActionFileCloseOther", GTK_STOCK_CLOSE, N_("Close Others"), "<shift><control>o",
166 N_("Close other documents"),
167 G_CALLBACK (on_close_other_file_activate)},
168 { "ActionFileReload", GTK_STOCK_REVERT_TO_SAVED, N_("Reload F_ile"), NULL,
169 N_("Reload current file"),
170 G_CALLBACK (on_reload_file_activate)},
171 { "ActionMenuFileRecentFiles", NULL, N_("Recent _Files"), NULL, NULL, NULL}, /* menu title */
174 static GtkActionEntry actions_print[] = {
175 { "ActionPrintFile", GTK_STOCK_PRINT, N_("_Print…"), "<control>p",
176 N_("Print the current file"), G_CALLBACK (on_print_activate)},
177 { "ActionPrintPreview",
178 #ifdef GTK_STOCK_PRINT_PREVIEW
179 GTK_STOCK_PRINT_PREVIEW
180 #else
181 NULL
182 #endif
183 , N_("_Print Preview"), NULL,
184 N_("Preview the current file in print format"),
185 G_CALLBACK (on_print_preview_activate)},
188 static GtkActionEntry actions_transform[] = {
189 { "ActionMenuEditTransform", NULL, N_("_Transform"), NULL, NULL, NULL}, /* menu title */
190 { "ActionEditMakeSelectionUppercase", NULL, N_("_Make Selection Uppercase"), NULL,
191 N_("Make the selected text uppercase"),
192 G_CALLBACK (on_editor_command_upper_case_activate)},
193 { "ActionEditMakeSelectionLowercase", NULL, N_("Make Selection Lowercase"), NULL,
194 N_("Make the selected text lowercase"),
195 G_CALLBACK (on_editor_command_lower_case_activate)},
196 { "ActionEditConvertCRLF", NULL, N_("Convert EOL to CRLF"), NULL,
197 N_("Convert End Of Line characters to DOS EOL (CRLF)"),
198 G_CALLBACK (on_editor_command_eol_crlf_activate)},
199 { "ActionEditConvertLF", NULL, N_("Convert EOL to LF"), NULL,
200 N_("Convert End Of Line characters to Unix EOL (LF)"),
201 G_CALLBACK (on_editor_command_eol_lf_activate)},
202 { "ActionEditConvertCR", NULL, N_("Convert EOL to CR"), NULL,
203 N_("Convert End Of Line characters to Mac OS EOL (CR)"),
204 G_CALLBACK (on_editor_command_eol_cr_activate)},
205 { "ActionEditConvertEOL", NULL, N_("Convert EOL to Majority EOL"), NULL,
206 N_("Convert End Of Line characters to the most common EOL found in the file"),
207 G_CALLBACK (on_transform_eolchars1_activate)},
210 static GtkActionEntry actions_select[] = {
211 { "ActionMenuEditSelect", NULL, N_("_Select"), NULL, NULL, NULL}, /* menu title */
212 { "ActionEditSelectAll",
213 GTK_STOCK_SELECT_ALL, N_("Select _All"), "<control>a",
214 N_("Select all text in the editor"),
215 G_CALLBACK (on_editor_command_select_all_activate)},
216 { "ActionEditSelectBlock", ANJUTA_STOCK_BLOCK_SELECT, N_("Select _Code Block"),
217 "<shift><control>b", N_("Select the current code block"),
218 G_CALLBACK (on_editor_command_select_block_activate)}
221 static GtkActionEntry actions_comment[] = {
222 { "ActionMenuEditComment", NULL, N_("Co_mment"), NULL, NULL, NULL},
223 /* Block comment: Uses line-comment (comment that affects only single line
224 such as '//' or '#') and comments a block of lines. */
225 { "ActionEditCommentBlock", NULL, N_("_Block Comment/Uncomment"), NULL,
226 N_("Block comment the selected text"),
227 G_CALLBACK (on_comment_block)},
228 /* Box comment: Uses stream-comment to comment a block of lines, usually with
229 some decorations, to give an appearance of box. */
230 { "ActionEditCommentBox", NULL, N_("Bo_x Comment/Uncomment"), NULL,
231 N_("Box comment the selected text"),
232 G_CALLBACK (on_comment_box)},
233 /* Stream comment: Uses 'stream comment' (comment that affects a stream of
234 characters -- has start and end comment code) and comments any code from
235 arbitrary start position to arbitrary end position (can be in middle of
236 lines). */
237 { "ActionEditCommentStream", NULL, N_("_Stream Comment/Uncomment"), NULL,
238 N_("Stream comment the selected text"),
239 G_CALLBACK (on_comment_stream)},
242 static GtkActionEntry actions_navigation[] = {
243 { "ActionMenuGoto", NULL, N_("_Go to"), NULL, NULL, NULL},/* menu title */
244 { "ActionEditGotoLine", ANJUTA_STOCK_GOTO_LINE, N_("_Line Number…"),
245 "<control><alt>g", N_("Go to a particular line in the editor"),
246 G_CALLBACK (on_goto_line_no1_activate)},
247 { "ActionEditGotoMatchingBrace", GTK_STOCK_JUMP_TO, N_("Matching _Brace"),
248 "<control><alt>m", N_("Go to the matching brace in the editor"),
249 G_CALLBACK (on_editor_command_match_brace_activate)},
250 { "ActionEditGotoBlockStart", ANJUTA_STOCK_BLOCK_START, N_("_Start of Block"),
251 "<control><alt>s", N_("Go to the start of the current block"),
252 G_CALLBACK (on_goto_block_start1_activate)},
253 { "ActionEditGotoBlockEnd", ANJUTA_STOCK_BLOCK_END, N_("_End of Block"),
254 "<control><alt>e", N_("Go to the end of the current block"),
255 G_CALLBACK (on_goto_block_end1_activate)},
256 { "ActionEditGotoHistoryPrev", ANJUTA_STOCK_HISTORY_PREV, N_("Previous _History"),
257 "<alt>Left", N_("Go to previous history"),
258 G_CALLBACK (on_prev_history)},
259 { "ActionEditGotoHistoryNext", ANJUTA_STOCK_HISTORY_NEXT, N_("Next Histor_y"),
260 "<alt>Right", N_("Go to next history"),
261 G_CALLBACK (on_next_history)}
264 static GtkActionEntry actions_search[] = {
265 { "ActionMenuEditSearch", NULL, N_("_Search"), NULL, NULL, NULL},
266 { "ActionEditSearchQuickSearch", GTK_STOCK_FIND, N_("_Quick Search"),
267 "<control>f", N_("Quick editor embedded search"),
268 G_CALLBACK (on_show_search)},
269 { "ActionEditSearchQuickSearchAgain", GTK_STOCK_FIND, N_("Find _Next"),
270 "<control>g", N_("Search for next appearance of term."),
271 G_CALLBACK (on_repeat_quicksearch)},
272 { "ActionEditSearchReplace", GTK_STOCK_FIND, N_("Find and R_eplace…"),
273 "<control>h", N_("Search and replace"),
274 G_CALLBACK (on_search_and_replace)},
275 { "ActionEditSearchFindPrevious", GTK_STOCK_FIND, N_("Find _Previous"),
276 "<control><shift>g",
277 N_("Repeat the last Find command"),
278 G_CALLBACK (on_search_previous)},
279 { "ActionSearchboxPopupClearHighlight", GTK_STOCK_FIND, N_("Clear Highlight"),
280 NULL, N_("Clear all highlighted text"),
281 G_CALLBACK (on_search_popup_clear_highlight)}
284 static GtkToggleActionEntry actions_searchbox_popup[] = {
285 { "ActionSearchboxPopupCaseCheck", GTK_STOCK_FIND,
286 N_("Case Sensitive"), NULL,
287 N_("Match case in search results."),
288 G_CALLBACK (on_search_popup_case_sensitive_toggle)},
289 { "ActionSearchboxPopupHighlightAll", GTK_STOCK_FIND,
290 N_("Highlight All"), NULL,
291 N_("Highlight all occurrences"),
292 G_CALLBACK (on_search_popup_highlight_toggle)},
293 { "ActionSearchboxRegexSearch", GTK_STOCK_FIND,
294 N_("Regular Expression"), NULL,
295 N_("Search using regular expressions"),
296 G_CALLBACK (on_search_popup_regex_search)}
300 static GtkActionEntry actions_edit[] = {
301 { "ActionMenuEdit", NULL, N_("_Edit"), NULL, NULL, NULL},/* menu title */
302 { "ActionMenuViewEditor", NULL, N_("_Editor"), NULL, NULL, NULL},
303 { "ActionViewEditorAddView",
304 #ifdef GTK_STOCK_EDIT
305 GTK_STOCK_EDIT
306 #else
307 NULL
308 #endif
309 , N_("_Add Editor View"), NULL,
310 N_("Add one more view of current document"),
311 G_CALLBACK (on_editor_add_view_activate)},
312 { "ActionViewEditorRemoveView", NULL, N_("_Remove Editor View"), NULL,
313 N_("Remove current view of the document"),
314 G_CALLBACK (on_editor_remove_view_activate)},
315 { "ActionEditUndo", GTK_STOCK_UNDO, N_("U_ndo"), "<control>z",
316 N_("Undo the last action"),
317 G_CALLBACK (on_editor_command_undo_activate)},
318 { "ActionEditRedo", GTK_STOCK_REDO, N_("_Redo"), "<shift><control>z",
319 N_("Redo the last undone action"),
320 G_CALLBACK (on_editor_command_redo_activate)},
321 { "ActionEditCut", GTK_STOCK_CUT, N_("C_ut"), "<control>x",
322 N_("Cut the selected text from the editor to the clipboard"),
323 G_CALLBACK (on_editor_command_cut_activate)},
324 { "ActionEditCopy", GTK_STOCK_COPY, N_("_Copy"), "<control>c",
325 N_("Copy the selected text to the clipboard"),
326 G_CALLBACK (on_editor_command_copy_activate)},
327 { "ActionEditPaste", GTK_STOCK_PASTE, N_("_Paste"), "<control>v",
328 N_("Paste the content of clipboard at the current position"),
329 G_CALLBACK (on_editor_command_paste_activate)},
330 { "ActionEditClear",
331 #ifdef GTK_STOCK_DISCARD
332 GTK_STOCK_DISCARD
333 #else
334 GTK_STOCK_CLEAR
335 #endif
336 , N_("_Clear"), NULL,
337 N_("Delete the selected text from the editor"),
338 G_CALLBACK (on_editor_command_clear_activate)},
339 { "ActionEditAutocomplete", ANJUTA_STOCK_AUTOCOMPLETE,
340 N_("_Auto-Complete"), "<control>Return",
341 N_("Auto-complete the current word"), G_CALLBACK (on_autocomplete_activate)
346 static GtkActionEntry actions_zoom[] = {
347 { "ActionViewEditorZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom In"), "<control>KP_Add",
348 N_("Zoom in: Increase font size"),
349 G_CALLBACK (on_zoom_in_text_activate)},
350 { "ActionViewEditorZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom Out"), "<control>KP_Subtract",
351 N_("Zoom out: Decrease font size"),
352 G_CALLBACK (on_zoom_out_text_activate)}
355 static GtkActionEntry actions_style[] = {
356 { "ActionMenuFormatStyle", NULL, N_("_Highlight Mode"), NULL, NULL, NULL}/* menu title */
359 static GtkActionEntry actions_format[] = {
360 { "ActionFormatFoldCloseAll", ANJUTA_STOCK_FOLD_CLOSE, N_("_Close All Folds"),
361 NULL, N_("Close all code folds in the editor"),
362 G_CALLBACK (on_editor_command_close_folds_all_activate)},
363 { "ActionFormatFoldOpenAll", ANJUTA_STOCK_FOLD_OPEN, N_("_Open All Folds"),
364 NULL, N_("Open all code folds in the editor"),
365 G_CALLBACK (on_editor_command_open_folds_all_activate)},
366 { "ActionFormatFoldToggle", ANJUTA_STOCK_FOLD_TOGGLE, N_("_Toggle Current Fold"),
367 NULL, N_("Toggle current code fold in the editor"),
368 G_CALLBACK (on_editor_command_toggle_fold_activate)},
371 static GtkActionEntry actions_documents[] = {
372 {"ActionMenuDocuments", NULL, N_("_Documents"), NULL, NULL, NULL},
373 { "ActionDocumentsPrevious", GTK_STOCK_GO_BACK, N_("Previous Document"),
374 "<control>Page_Up", N_("Switch to previous document"),
375 G_CALLBACK (on_previous_document)},
376 { "ActionDocumentsNext", GTK_STOCK_GO_FORWARD, N_("Next Document"),
377 "<control>Page_Down", N_("Switch to next document"),
378 G_CALLBACK (on_next_document)},
381 static GtkActionEntry actions_bookmarks[] = {
382 { "ActionMenuBookmark", NULL, N_("Bookmar_k"), NULL, NULL, NULL},
383 { "ActionBookmarkToggle", GTK_STOCK_ADD, N_("_Toggle Bookmark"),
384 "<control>k", N_("Toggle bookmark at the current line position"),
385 G_CALLBACK (on_bookmark_toggle_activate)},
386 { "ActionBookmarkPrev", ANJUTA_STOCK_BOOKMARK_PREV, N_("_Previous Bookmark"),
387 "<control>comma", N_("Jump to the previous bookmark in the file"),
388 G_CALLBACK (on_bookmark_prev_activate)},
389 { "ActionBookmarkNext", ANJUTA_STOCK_BOOKMARK_NEXT, N_("_Next Bookmark"),
390 "<control>period", N_("Jump to the next bookmark in the file"),
391 G_CALLBACK (on_bookmark_next_activate)},
392 { "ActionBookmarksClear", ANJUTA_STOCK_BOOKMARK_CLEAR, N_("_Clear All Bookmarks"),
393 NULL, N_("Clear bookmarks"),
394 G_CALLBACK (on_bookmarks_clear_activate)},
397 struct ActionGroupInfo {
398 GtkActionEntry *group;
399 gint size;
400 gchar *name;
401 gchar *label;
404 struct ActionToggleGroupInfo {
405 GtkToggleActionEntry *group;
406 gint size;
407 gchar *name;
408 gchar *label;
411 static struct ActionGroupInfo action_groups[] = {
412 { actions_file, G_N_ELEMENTS (actions_file), "ActionGroupEditorFile", N_("Editor file operations")},
413 { actions_print, G_N_ELEMENTS (actions_print), "ActionGroupEditorPrint", N_("Editor print operations")},
414 { actions_transform, G_N_ELEMENTS (actions_transform), "ActionGroupEditorTransform", N_("Editor text transformation") },
415 { actions_select, G_N_ELEMENTS (actions_select), "ActionGroupEditorSelect", N_("Editor text selection") },
416 // { actions_insert, G_N_ELEMENTS (actions_insert), "ActionGroupEditorInsert", N_("Editor text insertions") },
417 { actions_comment, G_N_ELEMENTS (actions_comment), "ActionGroupEditorComment", N_("Editor code commenting") },
418 { actions_navigation, G_N_ELEMENTS (actions_navigation), "ActionGroupEditorNavigate", N_("Editor navigations") },
419 { actions_edit, G_N_ELEMENTS (actions_edit), "ActionGroupEditorEdit", N_("Editor edit operations") },
420 { actions_zoom, G_N_ELEMENTS (actions_zoom), "ActionGroupEditorZoom", N_("Editor zoom operations") },
421 { actions_style, G_N_ELEMENTS (actions_style), "ActionGroupEditorStyle", N_("Editor syntax highlighting styles") },
422 { actions_format, G_N_ELEMENTS (actions_format), "ActionGroupEditorFormat", N_("Editor text formating") },
423 { actions_search, G_N_ELEMENTS (actions_search), "ActionGroupEditorSearch", N_("Simple searching") },
424 { actions_documents, G_N_ELEMENTS (actions_documents), "ActionGroupDocuments", N_("Documents") },
425 { actions_bookmarks, G_N_ELEMENTS (actions_bookmarks), "ActionGroupBookmarks", N_("Bookmarks") }
428 static struct ActionToggleGroupInfo action_toggle_groups[] = {
429 { actions_searchbox_popup, G_N_ELEMENTS(actions_searchbox_popup),
430 "ActionGroupEditorSearchOptions", N_("Toggle search options") }
433 // void pref_set_style_combo(DocmanPlugin *plugin);
435 #define MAX_TITLE_LENGTH 80
437 static void
438 on_editor_lang_changed (IAnjutaEditor* editor, const gchar* language,
439 DocmanPlugin* plugin);
441 static gchar*
442 get_directory_display_name (DocmanPlugin* plugin,
443 GFile* file)
445 gchar* dir;
446 gchar* display_uri = g_file_get_parse_name (file);
447 gchar* display_dir;
448 dir = anjuta_util_uri_get_dirname (display_uri);
450 display_dir = anjuta_util_str_middle_truncate (dir,
451 MAX (20, MAX_TITLE_LENGTH));
452 g_free (display_uri);
453 g_free (dir);
454 return display_dir;
457 static void
458 update_title (DocmanPlugin* doc_plugin)
460 IAnjutaDocument *doc;
461 AnjutaStatus *status;
462 gchar *title;
464 doc = anjuta_docman_get_current_document (ANJUTA_DOCMAN (doc_plugin->docman));
466 if (doc)
468 gchar* real_filename;
469 gchar *dir;
470 const gchar *filename;
471 filename = ianjuta_document_get_filename (doc, NULL);
472 GFile* file;
473 file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
474 if (file)
476 dir = get_directory_display_name (doc_plugin, file);
477 g_object_unref (file);
479 else
481 dir = NULL;
483 if (ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE (doc), NULL))
485 gchar* dirty_name = g_strconcat ("*", filename, NULL);
486 real_filename = dirty_name;
488 else
489 real_filename = g_strdup (filename);
491 if (doc_plugin->project_name)
493 if (dir)
494 title = g_strdup_printf ("%s (%s) - %s", real_filename, dir,
495 doc_plugin->project_name);
496 else
497 title = g_strdup_printf ("%s - %s", real_filename,
498 doc_plugin->project_name);
500 else
502 if (dir)
503 title = g_strdup_printf ("%s (%s)", real_filename, dir);
504 else
505 title = g_strdup_printf ("%s", real_filename);
507 g_free (real_filename);
508 g_free (dir);
510 else
512 title = g_strdup (doc_plugin->project_name);
514 status = anjuta_shell_get_status (ANJUTA_PLUGIN (doc_plugin)->shell, NULL);
515 /* NULL title is ok */
516 anjuta_status_set_title (status, title);
517 g_free (title);
520 static void
521 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
522 const GValue *value, gpointer user_data)
524 DocmanPlugin *doc_plugin;
525 const gchar *root_uri;
527 doc_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
529 DEBUG_PRINT ("%s", "Project added");
532 g_free (doc_plugin->project_name);
533 g_free (doc_plugin->project_path);
534 doc_plugin->project_name = NULL;
536 root_uri = g_value_get_string (value);
537 if (root_uri)
539 GFile* file = g_file_new_for_uri (root_uri);
540 gchar* path = g_file_get_path (file);
542 doc_plugin->project_name = g_file_get_basename (file);
543 doc_plugin->project_path = path;
545 if (doc_plugin->project_name)
547 update_title (doc_plugin);
549 g_object_unref (file);
553 static void
554 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
555 gpointer user_data)
557 DocmanPlugin *doc_plugin;
559 doc_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
561 DEBUG_PRINT ("%s", "Project removed");
563 g_free (doc_plugin->project_name);
564 doc_plugin->project_name = NULL;
566 update_title(doc_plugin);
569 static void
570 ui_give_shorter_names (AnjutaPlugin *plugin)
572 AnjutaUI *ui;
573 GtkAction *action;
575 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
576 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
577 "ActionFileSave");
578 g_object_set (G_OBJECT (action), "short-label", _("Save"),
579 "is-important", TRUE, NULL);
580 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
581 "ActionFileReload");
582 g_object_set (G_OBJECT (action), "short-label", _("Reload"), NULL);
583 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
584 "ActionEditUndo");
585 g_object_set (G_OBJECT (action), "is-important", TRUE, NULL);
586 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
587 "ActionEditGotoLine");
588 g_object_set (G_OBJECT (action), "short-label", _("Go to"), NULL);
591 static void
592 update_document_ui_enable_all (AnjutaPlugin *plugin)
594 AnjutaUI *ui;
595 gint i, j;
596 GtkAction *action;
598 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
599 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
601 for (j = 0; j < action_groups[i].size; j++)
603 action = anjuta_ui_get_action (ui, action_groups[i].name,
604 action_groups[i].group[j].name);
605 if (action_groups[i].group[j].callback)
607 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
613 static void
614 update_document_ui_disable_all (AnjutaPlugin *plugin)
616 AnjutaUI *ui;
617 gint i, j;
618 GtkAction *action;
620 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
621 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
623 for (j = 0; j < action_groups[i].size; j++)
625 action = anjuta_ui_get_action (ui, action_groups[i].name,
626 action_groups[i].group[j].name);
627 if (action_groups[i].group[j].callback)
629 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
635 static void
636 update_document_ui_undo_items (AnjutaPlugin *plugin, IAnjutaDocument* doc)
638 AnjutaUI *ui;
639 GtkAction *action;
641 ui = anjuta_shell_get_ui (plugin->shell, NULL);
643 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
644 "ActionEditUndo");
645 g_object_set (G_OBJECT (action), "sensitive",
646 ianjuta_document_can_undo (doc, NULL), NULL);
648 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
649 "ActionEditRedo");
650 g_object_set (G_OBJECT (action), "sensitive",
651 ianjuta_document_can_redo (doc, NULL), NULL);
654 static void
655 update_document_ui_save_items (AnjutaPlugin *plugin, IAnjutaDocument *doc)
657 AnjutaUI *ui;
658 GtkAction *action;
660 ui = anjuta_shell_get_ui (plugin->shell, NULL);
662 if (anjuta_docman_get_current_document (ANJUTA_DOCMAN(ANJUTA_PLUGIN_DOCMAN(plugin)->docman)) ==
663 doc)
665 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
666 "ActionFileSave");
667 g_object_set (G_OBJECT (action), "sensitive",
668 ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE(doc), NULL),
669 NULL);
672 static void
673 update_document_ui_interface_items (AnjutaPlugin *plugin, IAnjutaDocument *doc)
675 AnjutaUI *ui;
676 GtkAction *action;
677 gboolean flag;
679 ui = anjuta_shell_get_ui (plugin->shell, NULL);
681 /* IAnjutaEditorLanguage */
682 flag = IANJUTA_IS_EDITOR_LANGUAGE (doc);
684 action = anjuta_ui_get_action (ui, "ActionGroupEditorStyle",
685 "ActionMenuFormatStyle");
686 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
688 /* IAnjutaDocument */
689 flag = IANJUTA_IS_DOCUMENT (doc);
691 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
692 "ActionEditCut");
693 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
695 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
696 "ActionEditCopy");
697 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
699 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
700 "ActionEditPaste");
701 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
703 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
704 "ActionEditClear");
705 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
707 /* IAnjutaEditorSelection */
708 flag = IANJUTA_IS_EDITOR_SELECTION (doc);
710 action = anjuta_ui_get_action (ui, "ActionGroupEditorSelect",
711 "ActionEditSelectAll");
712 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
714 action = anjuta_ui_get_action (ui, "ActionGroupEditorSelect",
715 "ActionEditSelectBlock");
716 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
718 /* IAnjutaEditorConvert */
719 flag = IANJUTA_IS_EDITOR_CONVERT (doc);
720 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
721 "ActionEditMakeSelectionUppercase");
722 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
724 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
725 "ActionEditMakeSelectionLowercase");
726 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
728 /* IAnjutaEditorLineMode */
729 flag = IANJUTA_IS_EDITOR_LINE_MODE (doc);
731 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
732 "ActionEditConvertCRLF");
733 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
734 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
735 "ActionEditConvertLF");
736 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
737 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
738 "ActionEditConvertCR");
739 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
740 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
741 "ActionEditConvertEOL");
742 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
744 /* IAnjutaEditorView */
745 flag = IANJUTA_IS_EDITOR_VIEW (doc);
746 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
747 "ActionViewEditorAddView");
748 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
749 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
750 "ActionViewEditorRemoveView");
751 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
753 /* IAnjutaEditorFolds */
754 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
755 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
756 "ActionFormatFoldCloseAll");
757 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
759 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
760 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
761 "ActionFormatFoldOpenAll");
762 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
764 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
765 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
766 "ActionFormatFoldToggle");
767 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
769 /* IAnjutaEditorComment */
770 flag = IANJUTA_IS_EDITOR_COMMENT (doc);
771 action = anjuta_ui_get_action (ui, "ActionGroupEditorComment",
772 "ActionMenuEditComment");
773 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
775 /* IAnjutaEditorZoom */
776 flag = IANJUTA_IS_EDITOR_ZOOM (doc);
777 action = anjuta_ui_get_action (ui, "ActionGroupEditorZoom",
778 "ActionViewEditorZoomIn");
779 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
780 action = anjuta_ui_get_action (ui, "ActionGroupEditorZoom",
781 "ActionViewEditorZoomOut");
782 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
784 /* IAnjutaEditorGoto */
785 flag = IANJUTA_IS_EDITOR_GOTO (doc);
786 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
787 "ActionEditGotoBlockStart");
788 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
789 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
790 "ActionEditGotoBlockEnd");
791 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
792 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
793 "ActionEditGotoMatchingBrace");
794 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
796 /* IAnjutaEditorSearch */
797 flag = IANJUTA_IS_EDITOR_SEARCH (doc);
798 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
799 "ActionEditSearchQuickSearch");
800 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
801 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
802 "ActionEditSearchQuickSearchAgain");
803 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
804 "ActionEditSearchFindPrevious");
805 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
806 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
807 "ActionEditSearchReplace");
808 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
809 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
810 "ActionSearchboxPopupClearHighlight");
811 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
812 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
813 "ActionEditGotoLine");
814 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
815 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearchOptions",
816 "ActionSearchboxPopupCaseCheck");
817 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
818 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearchOptions",
819 "ActionSearchboxPopupHighlightAll");
820 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
821 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearchOptions",
822 "ActionSearchboxRegexSearch");
823 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
825 /* IAnjutaEditorAssist */
826 flag = IANJUTA_IS_EDITOR_ASSIST (doc);
828 /* Enable autocompletion action */
829 action = anjuta_ui_get_action (ui,
830 "ActionGroupEditorEdit",
831 "ActionEditAutocomplete");
832 g_object_set (G_OBJECT (action), "visible", flag,
833 "sensitive", flag, NULL);
836 static void
837 update_document_ui (AnjutaPlugin *plugin, IAnjutaDocument *doc)
839 if (doc == NULL)
841 update_document_ui_disable_all (plugin);
842 return;
844 update_document_ui_enable_all (plugin);
845 update_document_ui_save_items (plugin, doc);
846 update_document_ui_interface_items (plugin, doc);
849 static void
850 on_document_update_save_ui (IAnjutaDocument *doc,
851 AnjutaPlugin *plugin)
853 update_document_ui_save_items (plugin, doc);
854 update_title(ANJUTA_PLUGIN_DOCMAN (plugin));
857 static void
858 register_stock_icons (AnjutaPlugin *plugin)
860 static gboolean registered = FALSE;
861 if (registered)
862 return;
863 registered = TRUE;
865 /* Register stock icons */
866 BEGIN_REGISTER_ICON (plugin);
867 REGISTER_ICON (ICON_FILE, "editor-plugin-icon");
868 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_TOGGLE, ANJUTA_STOCK_FOLD_TOGGLE);
869 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_OPEN, ANJUTA_STOCK_FOLD_OPEN);
870 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_CLOSE, ANJUTA_STOCK_FOLD_CLOSE);
871 REGISTER_ICON_FULL (ANJUTA_PIXMAP_INDENT_DCR, ANJUTA_STOCK_INDENT_DCR);
872 REGISTER_ICON_FULL (ANJUTA_PIXMAP_INDENT_INC, ANJUTA_STOCK_INDENT_INC);
873 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_SELECT, ANJUTA_STOCK_BLOCK_SELECT);
874 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_TOGGLE, ANJUTA_STOCK_BOOKMARK_TOGGLE);
875 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_PREV, ANJUTA_STOCK_BOOKMARK_PREV);
876 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_NEXT, ANJUTA_STOCK_BOOKMARK_NEXT);
877 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_CLEAR, ANJUTA_STOCK_BOOKMARK_CLEAR);
878 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_START, ANJUTA_STOCK_BLOCK_START);
879 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_END, ANJUTA_STOCK_BLOCK_END);
880 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_LINE, ANJUTA_STOCK_GOTO_LINE);
881 REGISTER_ICON_FULL (ANJUTA_PIXMAP_HISTORY_NEXT, ANJUTA_STOCK_HISTORY_NEXT);
882 REGISTER_ICON_FULL (ANJUTA_PIXMAP_HISTORY_PREV, ANJUTA_STOCK_HISTORY_PREV);
883 REGISTER_ICON_FULL (ANJUTA_PIXMAP_AUTOCOMPLETE, ANJUTA_STOCK_AUTOCOMPLETE);
884 END_REGISTER_ICON;
887 #define TEXT_ZOOM_FACTOR "text-zoom-factor"
889 static void
890 update_status (DocmanPlugin *plugin, IAnjutaEditor *te)
892 AnjutaStatus *status;
894 if (te)
896 gchar *edit /*, *mode*/;
897 guint line, col, zoom;
899 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
900 if (status == NULL)
901 return;
903 line = ianjuta_editor_get_lineno (te, NULL);
904 col = ianjuta_editor_get_column (te, NULL);
906 if (ianjuta_editor_get_overwrite (te, NULL))
908 edit = g_strdup (_("OVR"));
910 else
912 edit = g_strdup (_("INS"));
915 if (IANJUTA_IS_EDITOR_ZOOM(te))
917 zoom = g_settings_get_int (plugin->settings, TEXT_ZOOM_FACTOR);
918 anjuta_status_set_default (status, _("Zoom"), "%d", zoom);
920 else
921 anjuta_status_set_default (status, _("Zoom"), NULL);
923 anjuta_status_set_default (status, _("Line"), "%04d", line);
924 anjuta_status_set_default (status, _("Col"), "%03d", col);
925 anjuta_status_set_default (status, _("Mode"), edit);
926 // anjuta_status_set_default (status, _("EOL"), mode);
928 g_free (edit);
929 /* g_free (mode); */
931 else
933 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
934 if (status)
936 anjuta_status_set (status, "");
941 static void
942 on_document_update_ui (IAnjutaDocument *doc, DocmanPlugin *plugin)
944 IAnjutaDocument *curdoc;
946 curdoc = anjuta_docman_get_current_document (ANJUTA_DOCMAN (plugin->docman));
947 update_document_ui_undo_items (ANJUTA_PLUGIN(plugin), curdoc);
949 if (IANJUTA_IS_EDITOR (curdoc) && curdoc == doc)
951 update_status (plugin, IANJUTA_EDITOR (curdoc));
955 /* Remove all instances of c from the string s. */
956 static void remove_char(gchar *s, gchar c)
958 gchar *t = s;
959 for (; *s ; ++s)
960 if (*s != c)
961 *t++ = *s;
962 *t = '\0';
965 /* Compare two strings, ignoring _ characters which indicate mnemonics.
966 * Returns -1, 0, or 1, just like strcmp(). */
967 static gint
968 menu_name_compare(const gchar *s, const char *t)
970 gchar *s1 = g_utf8_strdown(s, -1);
971 gchar *t1 = g_utf8_strdown(t, -1);
972 remove_char(s1, '_');
973 remove_char(t1, '_');
974 gint result = g_utf8_collate (s1, t1);
975 g_free(s1);
976 g_free(t1);
977 return result;
980 static gint
981 compare_language_name(const gchar *lang1, const gchar *lang2, IAnjutaEditorLanguage *manager)
983 const gchar *fullname1 = ianjuta_editor_language_get_language_name (manager, lang1, NULL);
984 const gchar *fullname2 = ianjuta_editor_language_get_language_name (manager, lang2, NULL);
985 return menu_name_compare(fullname1, fullname2);
988 static GtkWidget*
989 create_highlight_submenu (DocmanPlugin *plugin, IAnjutaEditor *editor)
991 const GList *languages, *node;
992 GList *sorted_languages;
993 GtkWidget *submenu;
994 GtkWidget *auto_menuitem;
995 submenu = gtk_menu_new ();
997 if (!editor || !IANJUTA_IS_EDITOR_LANGUAGE (editor))
998 return NULL;
1000 languages = ianjuta_editor_language_get_supported_languages (IANJUTA_EDITOR_LANGUAGE (editor), NULL);
1001 if (!languages)
1002 return NULL;
1004 /* Automatic highlight menu */
1005 auto_menuitem = gtk_radio_menu_item_new_with_mnemonic (NULL, _("Automatic"));
1006 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(auto_menuitem), TRUE);
1007 g_signal_connect (G_OBJECT (auto_menuitem), "activate",
1008 G_CALLBACK (on_force_hilite_activate),
1009 plugin);
1010 g_object_set_data(G_OBJECT(auto_menuitem), "language_code", "auto-detect");
1011 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), auto_menuitem);
1012 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), gtk_separator_menu_item_new());
1014 /* Sort languages so they appear alphabetically in the menu. */
1015 sorted_languages = g_list_copy((GList *) languages);
1016 sorted_languages = g_list_sort_with_data(sorted_languages, (GCompareDataFunc) compare_language_name,
1017 IANJUTA_EDITOR_LANGUAGE (editor));
1019 node = sorted_languages;
1020 while (node)
1022 const gchar *lang = node->data;
1023 const gchar *name = ianjuta_editor_language_get_language_name (IANJUTA_EDITOR_LANGUAGE (editor), lang, NULL);
1025 /* Should fix #493583 */
1026 if (name != NULL)
1028 GtkWidget *menuitem;
1029 menuitem = gtk_radio_menu_item_new_with_mnemonic_from_widget (GTK_RADIO_MENU_ITEM(auto_menuitem), name);
1030 g_object_set_data_full (G_OBJECT (menuitem), "language_code",
1031 g_strdup (lang),
1032 (GDestroyNotify)g_free);
1033 g_signal_connect (G_OBJECT (menuitem), "activate",
1034 G_CALLBACK (on_force_hilite_activate),
1035 plugin);
1036 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
1037 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menuitem), FALSE);
1039 node = g_list_next (node);
1041 g_list_free(sorted_languages);
1043 gtk_widget_show_all (submenu);
1044 return submenu;
1047 static void
1048 on_support_plugin_deactivated (AnjutaPlugin* plugin, DocmanPlugin* docman_plugin)
1050 docman_plugin->support_plugins = g_list_remove (docman_plugin->support_plugins, plugin);
1053 static GList*
1054 load_new_support_plugins (DocmanPlugin* docman_plugin, GList* new_plugin_ids,
1055 AnjutaPluginManager* plugin_manager)
1057 GList* node;
1058 GList* needed_plugins = NULL;
1059 for (node = new_plugin_ids; node != NULL; node = g_list_next (node))
1061 gchar* plugin_id = node->data;
1062 GObject* new_plugin = anjuta_plugin_manager_get_plugin_by_id (plugin_manager,
1063 plugin_id);
1064 GList* item = g_list_find (docman_plugin->support_plugins, new_plugin);
1065 if (!item)
1067 DEBUG_PRINT ("Loading plugin: %s", plugin_id);
1068 g_signal_connect (new_plugin, "deactivated",
1069 G_CALLBACK (on_support_plugin_deactivated), docman_plugin);
1071 needed_plugins = g_list_append (needed_plugins, new_plugin);
1073 return needed_plugins;
1076 static void
1077 unload_unused_support_plugins (DocmanPlugin* docman_plugin,
1078 GList* needed_plugins)
1080 GList* plugins = g_list_copy (docman_plugin->support_plugins);
1081 GList* node;
1082 DEBUG_PRINT ("Unloading plugins");
1083 for (node = plugins; node != NULL; node = g_list_next (node))
1085 AnjutaPlugin* plugin = ANJUTA_PLUGIN (node->data);
1086 DEBUG_PRINT ("Checking plugin: %p", plugin);
1087 if (g_list_find (needed_plugins, plugin) == NULL)
1089 DEBUG_PRINT ("%s", "Unloading plugin");
1090 anjuta_plugin_deactivate (plugin);
1093 g_list_free (plugins);
1096 static void
1097 update_language_plugin (AnjutaDocman *docman, IAnjutaDocument *doc,
1098 AnjutaPlugin *plugin)
1100 DocmanPlugin* docman_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1102 DEBUG_PRINT("%s", "Beginning language support");
1103 if (doc && IANJUTA_IS_EDITOR_LANGUAGE (doc))
1105 AnjutaPluginManager *plugin_manager;
1106 IAnjutaLanguage *lang_manager;
1107 GList *new_support_plugins, *support_plugin_descs, *needed_plugins, *node;
1108 const gchar *language;
1110 lang_manager = anjuta_shell_get_interface (plugin->shell,
1111 IAnjutaLanguage,
1112 NULL);
1113 if (!lang_manager)
1115 g_warning ("Could not load language manager!");
1116 return;
1119 g_signal_handlers_block_by_func (doc, on_editor_lang_changed, plugin);
1120 language = ianjuta_language_get_name_from_editor (lang_manager,
1121 IANJUTA_EDITOR_LANGUAGE (doc),
1122 NULL);
1123 g_signal_handlers_unblock_by_func (doc, on_editor_lang_changed, plugin);
1125 if (!language)
1127 unload_unused_support_plugins (docman_plugin, NULL);
1128 return;
1131 /* Load current language editor support plugins */
1132 plugin_manager = anjuta_shell_get_plugin_manager (plugin->shell, NULL);
1133 support_plugin_descs = anjuta_plugin_manager_query (plugin_manager,
1134 "Anjuta Plugin",
1135 "Interfaces",
1136 "IAnjutaLanguageSupport",
1137 "Language Support",
1138 "Languages",
1139 language, NULL);
1140 new_support_plugins = NULL;
1141 for (node = support_plugin_descs; node != NULL; node = g_list_next (node))
1143 gchar *plugin_id;
1145 AnjutaPluginDescription *desc = node->data;
1147 anjuta_plugin_description_get_string (desc, "Anjuta Plugin", "Location",
1148 &plugin_id);
1150 new_support_plugins = g_list_append (new_support_plugins, plugin_id);
1152 g_list_free (support_plugin_descs);
1154 /* Load new plugins */
1155 needed_plugins =
1156 load_new_support_plugins (docman_plugin, new_support_plugins,
1157 plugin_manager);
1159 /* Unload unused plugins */
1160 unload_unused_support_plugins (docman_plugin, needed_plugins);
1162 /* Update list */
1163 g_list_free (docman_plugin->support_plugins);
1164 docman_plugin->support_plugins = needed_plugins;
1166 anjuta_util_glist_strings_free (new_support_plugins);
1168 else
1170 unload_unused_support_plugins (docman_plugin, NULL);
1174 static void
1175 on_document_changed (AnjutaDocman *docman, IAnjutaDocument *doc,
1176 AnjutaPlugin *plugin)
1178 DocmanPlugin *docman_plugin;
1179 update_document_ui (plugin, doc);
1181 docman_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1182 if (doc)
1184 GValue value = {0, };
1185 g_value_init (&value, G_TYPE_OBJECT);
1186 g_value_set_object (&value, doc);
1187 anjuta_shell_add_value (plugin->shell,
1188 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1189 &value, NULL);
1190 g_value_unset(&value);
1192 else
1194 anjuta_shell_remove_value (plugin->shell, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1195 NULL);
1199 if (doc && IANJUTA_IS_EDITOR (doc))
1201 update_status (docman_plugin, IANJUTA_EDITOR (doc));
1202 update_language_plugin (docman, doc, plugin);
1204 else
1206 update_status (docman_plugin, NULL);
1207 update_language_plugin (docman, NULL, plugin);
1209 update_title (ANJUTA_PLUGIN_DOCMAN (plugin));
1212 static void
1213 on_editor_lang_changed (IAnjutaEditor* editor,
1214 const gchar* language,
1215 DocmanPlugin* plugin)
1217 update_language_plugin (ANJUTA_DOCMAN (plugin->docman),
1218 IANJUTA_DOCUMENT (editor),
1219 ANJUTA_PLUGIN(plugin));
1222 static void
1223 on_document_added (AnjutaDocman *docman, IAnjutaDocument *doc,
1224 AnjutaPlugin *plugin)
1226 GtkWidget *highlight_submenu, *highlight_menu;
1227 DocmanPlugin *docman_plugin;
1229 docman_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1230 g_signal_connect (G_OBJECT (doc), "update_ui",
1231 G_CALLBACK (on_document_update_ui),
1232 docman_plugin);
1233 g_signal_connect (G_OBJECT (doc), "update-save-ui",
1234 G_CALLBACK (on_document_update_save_ui),
1235 plugin);
1237 /* Present the vbox as this is the widget that was added to the shell */
1238 anjuta_shell_present_widget (plugin->shell,
1239 GTK_WIDGET (docman_plugin->vbox), NULL);
1241 if (IANJUTA_IS_EDITOR (doc))
1243 IAnjutaEditor *te;
1245 te = IANJUTA_EDITOR (doc);
1247 /* Check for language changes */
1248 g_signal_connect (G_OBJECT (doc), "language-changed",
1249 G_CALLBACK (on_editor_lang_changed),
1250 docman_plugin);
1253 /* Create Highlight submenu */
1254 highlight_submenu =
1255 create_highlight_submenu (docman_plugin, te);
1256 if (highlight_submenu)
1258 highlight_menu =
1259 gtk_ui_manager_get_widget (GTK_UI_MANAGER (docman_plugin->ui),
1260 "/MenuMain/MenuView/MenuViewEditor/MenuFormatStyle");
1261 gtk_menu_item_set_submenu (GTK_MENU_ITEM (highlight_menu),
1262 highlight_submenu);
1267 static gboolean
1268 on_window_key_press_event (AnjutaShell *shell,
1269 GdkEventKey *event,
1270 DocmanPlugin *plugin)
1272 gint modifiers;
1273 gint i;
1275 g_return_val_if_fail (event != NULL, FALSE);
1277 modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK);
1279 for (i = 0; global_keymap[i].id; i++)
1280 if (event->keyval == global_keymap[i].gdk_key &&
1281 (event->state & global_keymap[i].modifiers) == global_keymap[i].modifiers)
1282 break;
1284 if (!global_keymap[i].id)
1285 return FALSE;
1287 switch (global_keymap[i].id) {
1288 case ID_NEXTBUFFER:
1289 case ID_PREVBUFFER:
1291 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1292 gint pages_nb;
1293 gint cur_page;
1295 if ((cur_page = gtk_notebook_get_current_page (notebook)) == -1);
1296 return FALSE;
1298 if (!plugin->g_tabbing)
1300 plugin->g_tabbing = TRUE;
1303 pages_nb = gtk_notebook_get_n_pages (notebook);
1305 if (global_keymap[i].id == ID_NEXTBUFFER)
1306 cur_page = (cur_page < pages_nb - 1) ? cur_page + 1 : 0;
1307 else
1308 cur_page = cur_page ? cur_page - 1 : pages_nb -1;
1310 gtk_notebook_set_current_page (notebook, cur_page);
1312 break;
1314 default:
1315 if (global_keymap[i].id >= ID_FIRSTBUFFER &&
1316 global_keymap[i].id <= (ID_FIRSTBUFFER + 9))
1318 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1319 gint page_req = global_keymap[i].id - ID_FIRSTBUFFER;
1321 if (gtk_notebook_get_n_pages (notebook) == 0);
1322 return FALSE;
1323 gtk_notebook_set_current_page(notebook, page_req);
1325 else
1326 return FALSE;
1329 /* Note: No reason for a shortcut to do more than one thing a time */
1330 g_signal_stop_emission_by_name (G_OBJECT (ANJUTA_PLUGIN(plugin)->shell),
1331 "key-press-event");
1333 return TRUE;
1336 #define EDITOR_TABS_RECENT_FIRST "docman-tabs-recent-first"
1337 #define EDITOR_TABS_POS "docman-tabs-pos"
1338 #define EDITOR_TABS_HIDE "docman-tabs-hide"
1339 #define EDITOR_TABS_ORDERING "docman-tabs-ordering"
1340 #define AUTOSAVE_TIMER "docman-autosave-timer"
1341 #define SAVE_AUTOMATIC "docman-automatic-save"
1343 static gboolean
1344 on_window_key_release_event (AnjutaShell *shell,
1345 GdkEventKey *event,
1346 DocmanPlugin *plugin)
1348 g_return_val_if_fail (event != NULL, FALSE);
1350 if (plugin->g_tabbing && ((event->keyval == GDK_KEY_Control_L) ||
1351 (event->keyval == GDK_KEY_Control_R)))
1353 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1354 GtkWidget *widget;
1355 gint cur_page;
1356 plugin->g_tabbing = FALSE;
1358 if (g_settings_get_boolean (plugin->settings,
1359 EDITOR_TABS_RECENT_FIRST))
1362 TTimo: move the current notebook page to first position
1363 that maintains Ctrl-TABing on a list of most recently edited files
1365 cur_page = gtk_notebook_get_current_page (notebook);
1366 widget = gtk_notebook_get_nth_page (notebook, cur_page);
1367 gtk_notebook_reorder_child (notebook, widget, 0);
1370 return FALSE;
1373 static void
1374 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
1375 AnjutaSession *session, DocmanPlugin *plugin)
1377 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
1378 return;
1380 anjuta_bookmarks_session_load (ANJUTA_BOOKMARKS (plugin->bookmarks),
1381 session);
1384 static void
1385 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
1386 AnjutaSession *session, DocmanPlugin *plugin)
1388 GList *docwids, *node, *files;
1390 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
1391 return;
1393 files = anjuta_session_get_string_list (session, "File Loader", "Files"); /* probably NULL */
1394 /* buffers list is ordered last-opened to first-opened */
1395 docwids = anjuta_docman_get_all_doc_widgets (ANJUTA_DOCMAN (plugin->docman));
1396 if (docwids)
1398 for (node = docwids; node != NULL; node = g_list_next (node))
1400 /* only editor-documents are logged here. glade files etc handled elsewhere */
1401 if (IANJUTA_IS_EDITOR (node->data))
1403 IAnjutaEditor *te;
1404 GFile* file;
1406 te = IANJUTA_EDITOR (node->data);
1407 file = ianjuta_file_get_file (IANJUTA_FILE (te), NULL);
1408 if (file)
1410 /* Save line locations also */
1411 gchar *line_number;
1413 line_number = g_strdup_printf ("%d", ianjuta_editor_get_lineno (te, NULL));
1414 files = g_list_prepend (files, anjuta_session_get_relative_uri_from_file (session, file, line_number));
1415 g_free (line_number);
1419 g_list_free (docwids);
1421 if (files)
1423 anjuta_session_set_string_list (session, "File Loader", "Files", files);
1424 g_list_foreach (files, (GFunc)g_free, NULL);
1425 g_list_free (files);
1428 anjuta_bookmarks_session_save (ANJUTA_BOOKMARKS (plugin->bookmarks),
1429 session);
1432 static gboolean
1433 on_save_prompt_save_editor (AnjutaSavePrompt *save_prompt,
1434 gpointer item, gpointer user_data)
1436 DocmanPlugin *plugin;
1438 plugin = ANJUTA_PLUGIN_DOCMAN (user_data);
1439 return anjuta_docman_save_document (ANJUTA_DOCMAN (plugin->docman),
1440 IANJUTA_DOCUMENT (item),
1441 GTK_WIDGET (save_prompt));
1444 static void
1445 on_save_prompt (AnjutaShell *shell, AnjutaSavePrompt *save_prompt,
1446 DocmanPlugin *plugin)
1448 GList *buffers, *node;
1450 buffers = anjuta_docman_get_all_doc_widgets (ANJUTA_DOCMAN (plugin->docman));
1451 if (buffers)
1453 for (node = buffers; node; node = g_list_next (node))
1455 IAnjutaFileSavable *editor = IANJUTA_FILE_SAVABLE (node->data);
1456 if (ianjuta_file_savable_is_dirty (editor, NULL))
1458 const gchar *name;
1459 gchar *uri = NULL;
1460 GFile* file;
1462 name = ianjuta_document_get_filename (IANJUTA_DOCUMENT (editor), NULL);
1463 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
1464 if (file)
1466 uri = g_file_get_uri (file);
1467 g_object_unref (file);
1469 anjuta_save_prompt_add_item (save_prompt, name, uri, editor,
1470 on_save_prompt_save_editor, plugin);
1471 g_free (uri);
1474 g_list_free (buffers);
1478 static void
1479 docman_plugin_set_tab_pos (DocmanPlugin *ep)
1481 if (g_settings_get_boolean (ep->settings, EDITOR_TABS_HIDE))
1483 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ep->docman), FALSE);
1485 else
1487 gchar *tab_pos;
1488 GtkPositionType pos;
1490 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ep->docman), TRUE);
1491 tab_pos = g_settings_get_string (ep->settings, EDITOR_TABS_POS);
1493 pos = GTK_POS_TOP;
1494 if (tab_pos)
1496 if (strcasecmp (tab_pos, "top") == 0)
1497 pos = GTK_POS_TOP;
1498 else if (strcasecmp (tab_pos, "left") == 0)
1499 pos = GTK_POS_LEFT;
1500 else if (strcasecmp (tab_pos, "right") == 0)
1501 pos = GTK_POS_RIGHT;
1502 else if (strcasecmp (tab_pos, "bottom") == 0)
1503 pos = GTK_POS_BOTTOM;
1504 g_free (tab_pos);
1506 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (ep->docman), pos);
1510 static void
1511 on_notify_prefs (AnjutaPreferences* prefs,
1512 const gchar* key, gpointer user_data)
1514 DocmanPlugin *ep = ANJUTA_PLUGIN_DOCMAN (user_data);
1515 docman_plugin_set_tab_pos (ep);
1518 static gboolean
1519 on_docman_auto_save (gpointer data)
1521 gboolean retval;
1522 DocmanPlugin *plugin;
1523 AnjutaDocman *docman;
1524 AnjutaStatus* status;
1525 IAnjutaDocument *doc;
1526 GList *buffers, *node;
1528 plugin = ANJUTA_PLUGIN_DOCMAN (data);
1529 docman = ANJUTA_DOCMAN (plugin->docman);
1530 if (!docman)
1531 return FALSE;
1533 if (g_settings_get_boolean (plugin->settings, SAVE_AUTOMATIC) == FALSE)
1535 plugin->autosave_on = FALSE;
1536 return FALSE;
1539 status = anjuta_shell_get_status (docman->shell, NULL);
1541 retval = TRUE;
1542 buffers = anjuta_docman_get_all_doc_widgets (docman);
1543 if (buffers)
1545 for (node = buffers; node != NULL; node = g_list_next (node))
1547 doc = IANJUTA_DOCUMENT (node->data);
1548 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL) &&
1549 !ianjuta_file_savable_is_conflict (IANJUTA_FILE_SAVABLE (doc), NULL))
1551 GFile* file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
1552 if (file)
1554 GError *err = NULL;
1555 g_object_unref (file);
1557 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), &err);
1558 if (err)
1560 gchar *fullmsg;
1561 const gchar *filename = ianjuta_document_get_filename (doc, NULL); /* this may fail, too */
1562 fullmsg = g_strdup_printf (_("Autosave failed for %s"), filename);
1563 anjuta_status (status, fullmsg, 3);
1564 g_free (fullmsg);
1565 g_error_free (err);
1566 retval = FALSE;
1571 g_list_free (buffers);
1574 if (retval)
1576 anjuta_status (status, _("Autosave completed"), 3);
1578 return retval;
1581 static void
1582 on_notify_timer (GSettings* settings,
1583 const gchar* key,
1584 gpointer user_data)
1586 DocmanPlugin *plugin;
1587 AnjutaDocman *docman;
1588 gint auto_save_timer;
1589 gboolean auto_save;
1591 plugin = ANJUTA_PLUGIN_DOCMAN (user_data);
1592 docman = ANJUTA_DOCMAN (plugin->docman);
1594 auto_save_timer = g_settings_get_int(settings, AUTOSAVE_TIMER);
1595 auto_save = g_settings_get_boolean(settings, SAVE_AUTOMATIC);
1597 if (auto_save)
1599 if (plugin->autosave_on)
1601 if (auto_save_timer != plugin->autosave_it)
1603 g_source_remove (plugin->autosave_id);
1604 plugin->autosave_id =
1605 g_timeout_add_seconds (auto_save_timer * 60,
1606 on_docman_auto_save, plugin);
1609 else
1611 plugin->autosave_id =
1612 g_timeout_add_seconds (auto_save_timer * 60,
1613 on_docman_auto_save, plugin);
1615 plugin->autosave_it = auto_save_timer;
1616 plugin->autosave_on = TRUE;
1618 else if (plugin->autosave_on)
1620 g_source_remove (plugin->autosave_id);
1621 plugin->autosave_on = FALSE;
1625 static void
1626 prefs_init (DocmanPlugin *ep)
1628 docman_plugin_set_tab_pos (ep);
1630 g_signal_connect (ep->settings, "changed::" EDITOR_TABS_HIDE,
1631 G_CALLBACK (on_notify_prefs), ep);
1632 g_signal_connect (ep->settings, "changed::" EDITOR_TABS_POS,
1633 G_CALLBACK (on_notify_prefs), ep);
1634 g_signal_connect (ep->settings, "changed::" AUTOSAVE_TIMER,
1635 G_CALLBACK (on_notify_timer), ep);
1636 g_signal_connect (ep->settings, "changed::" SAVE_AUTOMATIC,
1637 G_CALLBACK (on_notify_timer), ep);
1639 on_notify_timer(ep->settings, NULL, ep);
1642 static gboolean
1643 activate_plugin (AnjutaPlugin *plugin)
1645 GtkWidget *docman, *popup_menu;
1646 AnjutaUI *ui;
1647 DocmanPlugin *dplugin;
1648 GtkActionGroup *group;
1649 gint i;
1650 static gboolean initialized = FALSE;
1651 GList *actions, *act;
1653 DEBUG_PRINT ("%s", "DocmanPlugin: Activating document manager plugin…");
1655 dplugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1656 dplugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
1658 ui = dplugin->ui;
1659 docman = anjuta_docman_new (dplugin);
1660 dplugin->docman = docman;
1662 ANJUTA_DOCMAN(docman)->shell = plugin->shell;
1663 g_signal_connect (G_OBJECT (docman), "document-added",
1664 G_CALLBACK (on_document_added), plugin);
1665 g_signal_connect (G_OBJECT (docman), "document-changed",
1666 G_CALLBACK (on_document_changed), plugin);
1667 g_signal_connect (G_OBJECT (plugin->shell), "key-press-event",
1668 G_CALLBACK (on_window_key_press_event), plugin);
1669 g_signal_connect (G_OBJECT (plugin->shell), "key-release-event",
1670 G_CALLBACK (on_window_key_release_event), plugin);
1672 if (!initialized)
1674 register_stock_icons (plugin);
1676 dplugin->action_groups = NULL;
1677 /* Add all our editor actions */
1678 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
1680 group = anjuta_ui_add_action_group_entries (ui,
1681 action_groups[i].name,
1682 _(action_groups[i].label),
1683 action_groups[i].group,
1684 action_groups[i].size,
1685 GETTEXT_PACKAGE, TRUE,
1686 plugin);
1687 dplugin->action_groups =
1688 g_list_prepend (dplugin->action_groups, group);
1689 actions = gtk_action_group_list_actions (group);
1690 act = actions;
1691 while (act) {
1692 g_object_set_data (G_OBJECT (act->data), "Plugin", dplugin);
1693 act = g_list_next (act);
1696 for (i = 0; i < G_N_ELEMENTS (action_toggle_groups); i++)
1698 group = anjuta_ui_add_toggle_action_group_entries (ui,
1699 action_toggle_groups[i].name,
1700 _(action_toggle_groups[i].label),
1701 action_toggle_groups[i].group,
1702 action_toggle_groups[i].size,
1703 GETTEXT_PACKAGE, TRUE, plugin);
1704 dplugin->action_groups =
1705 g_list_prepend (dplugin->action_groups, group);
1706 actions = gtk_action_group_list_actions (group);
1707 act = actions;
1708 while (act) {
1709 g_object_set_data (G_OBJECT (act->data), "Plugin", dplugin);
1710 act = g_list_next (act);
1714 /* Add UI */
1715 dplugin->uiid = anjuta_ui_merge (ui, UI_FILE);
1716 dplugin->vbox = gtk_vbox_new (FALSE, 0);
1717 gtk_widget_show (dplugin->vbox);
1718 gtk_box_pack_start (GTK_BOX(dplugin->vbox), docman, TRUE, TRUE, 0);
1719 anjuta_shell_add_widget_full (plugin->shell, dplugin->vbox,
1720 "AnjutaDocumentManager", _("Documents"),
1721 "editor-plugin-icon",
1722 ANJUTA_SHELL_PLACEMENT_CENTER,
1723 TRUE, NULL);
1724 anjuta_shell_present_widget (plugin->shell, dplugin->vbox, NULL);
1726 ui_give_shorter_names (plugin);
1727 update_document_ui (plugin, NULL);
1729 /* Create the default searchbox instance, but don't yet put it into
1730 dplugin->vbox, to prevent the box being displayed at session start */
1731 dplugin->search_box = search_box_new (ANJUTA_DOCMAN (docman));
1733 /* Setup popup menu */
1734 popup_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
1735 "/PopupDocumentManager");
1736 g_assert (popup_menu != NULL && GTK_IS_MENU (popup_menu));
1737 anjuta_docman_set_popup_menu (ANJUTA_DOCMAN (docman), popup_menu);
1739 if (!initialized)
1742 /* Connect to save session */
1743 g_signal_connect (G_OBJECT (plugin->shell), "save-session",
1744 G_CALLBACK (on_session_save), plugin);
1745 /* Connect to load session */
1746 g_signal_connect (G_OBJECT (plugin->shell), "load-session",
1747 G_CALLBACK (on_session_load), plugin);
1749 /* Connect to save prompt */
1750 g_signal_connect (G_OBJECT (plugin->shell), "save-prompt",
1751 G_CALLBACK (on_save_prompt), plugin);
1753 /* Add bookmarks widget */
1754 dplugin->bookmarks = G_OBJECT(anjuta_bookmarks_new (dplugin));
1756 dplugin->project_watch_id =
1757 anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
1758 value_added_project_root_uri,
1759 value_removed_project_root_uri, NULL);
1760 dplugin->project_name = NULL;
1762 prefs_init(ANJUTA_PLUGIN_DOCMAN (plugin));
1763 initialized = TRUE;
1765 return TRUE;
1768 static gboolean
1769 deactivate_plugin (AnjutaPlugin *plugin)
1771 // GtkIconFactory *icon_factory;
1772 DocmanPlugin *eplugin;
1773 AnjutaUI *ui;
1774 AnjutaStatus *status;
1775 GList *node;
1777 DEBUG_PRINT ("%s", "DocmanPlugin: Deactivating document manager plugin…");
1779 eplugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1781 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1782 G_CALLBACK (on_session_save), plugin);
1783 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1784 G_CALLBACK (on_save_prompt), plugin);
1786 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1787 status = anjuta_shell_get_status (plugin->shell, NULL);
1789 g_signal_handlers_disconnect_by_func (G_OBJECT (eplugin->docman),
1790 G_CALLBACK (on_document_changed),
1791 plugin);
1792 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1793 G_CALLBACK (on_window_key_press_event),
1794 plugin);
1795 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1796 G_CALLBACK (on_window_key_release_event),
1797 plugin);
1799 on_document_changed (ANJUTA_DOCMAN (eplugin->docman), NULL, plugin);
1801 /* Widget is removed from the container when destroyed */
1802 gtk_widget_destroy (eplugin->docman);
1803 gtk_widget_destroy (eplugin->search_box); /* the default searchbox instance may still be unparented */
1804 g_object_unref (eplugin->bookmarks);
1805 anjuta_ui_unmerge (ui, eplugin->uiid);
1806 node = eplugin->action_groups;
1807 while (node)
1809 GtkActionGroup *group = GTK_ACTION_GROUP (node->data);
1810 anjuta_ui_remove_action_group (ui, group);
1811 node = g_list_next (node);
1813 g_list_free (eplugin->action_groups);
1815 /* FIXME: */
1816 /* Unregister stock icons */
1817 /* Unregister preferences */
1819 eplugin->docman = NULL;
1820 eplugin->uiid = 0;
1821 eplugin->action_groups = NULL;
1823 return TRUE;
1826 static void
1827 dispose (GObject *obj)
1829 DocmanPlugin *eplugin = ANJUTA_PLUGIN_DOCMAN (obj);
1831 g_object_unref (eplugin->settings);
1833 G_OBJECT_CLASS (parent_class)->dispose (obj);
1836 static void
1837 finalize (GObject *obj)
1839 /* Finalization codes here */
1840 G_OBJECT_CLASS (parent_class)->finalize (obj);
1843 static void
1844 docman_plugin_instance_init (GObject *obj)
1846 DocmanPlugin *plugin = ANJUTA_PLUGIN_DOCMAN (obj);
1847 plugin->uiid = 0;
1848 plugin->g_tabbing = FALSE;
1849 plugin->notify_ids = NULL;
1850 plugin->support_plugins = NULL;
1851 plugin->settings = g_settings_new (PREF_SCHEMA);
1854 static void
1855 docman_plugin_class_init (GObjectClass *klass)
1857 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1859 parent_class = g_type_class_peek_parent (klass);
1861 plugin_class->activate = activate_plugin;
1862 plugin_class->deactivate = deactivate_plugin;
1863 klass->dispose = dispose;
1864 klass->finalize = finalize;
1867 /* Implement IAnjutaDocumentManager interfaces */
1868 static GFile*
1869 ianjuta_docman_get_file (IAnjutaDocumentManager *plugin,
1870 const gchar *filename, GError **e)
1872 AnjutaDocman *docman;
1873 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1874 return anjuta_docman_get_file (docman, filename);
1877 static IAnjutaDocument*
1878 ianjuta_docman_get_document_for_file (IAnjutaDocumentManager *plugin,
1879 GFile* file, GError **e)
1881 AnjutaDocman *docman;
1882 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1883 return anjuta_docman_get_document_for_file (docman, file);
1886 static IAnjutaDocument*
1887 ianjuta_docman_get_current_document (IAnjutaDocumentManager *plugin, GError **e)
1889 AnjutaDocman *docman;
1890 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1891 return anjuta_docman_get_current_document (docman);
1894 static void
1895 ianjuta_docman_set_current_document (IAnjutaDocumentManager *plugin,
1896 IAnjutaDocument *doc, GError **e)
1898 AnjutaDocman *docman;
1899 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1900 anjuta_docman_set_current_document (docman, doc);
1903 static GList*
1904 ianjuta_docman_get_doc_widgets (IAnjutaDocumentManager *plugin, GError **e)
1906 AnjutaDocman *docman;
1907 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1908 return anjuta_docman_get_all_doc_widgets (docman);
1911 static IAnjutaEditor*
1912 ianjuta_docman_goto_file_line (IAnjutaDocumentManager *plugin,
1913 GFile* file, gint linenum, GError **e)
1915 AnjutaDocman *docman;
1916 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1917 return anjuta_docman_goto_file_line (docman, file, linenum);
1920 static IAnjutaEditor*
1921 ianjuta_docman_goto_file_line_mark (IAnjutaDocumentManager *plugin,
1922 GFile* file, gint linenum, gboolean mark, GError **e)
1924 AnjutaDocman *docman;
1925 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1926 return anjuta_docman_goto_file_line_mark (docman, file, linenum, mark);
1930 * anjuta_docman_add_buffer:
1931 * @plugin:
1932 * @filename:
1933 * @content file text, a 0-terminated utf-8 string
1934 * @r: store for pointer to error data struct
1936 * Return value: the new editor
1938 static IAnjutaEditor*
1939 ianjuta_docman_add_buffer (IAnjutaDocumentManager *plugin,
1940 const gchar* filename, const gchar *content,
1941 GError **e)
1943 AnjutaDocman *docman;
1944 IAnjutaEditor *te;
1945 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1946 te = anjuta_docman_add_editor (docman, NULL, filename);
1947 if (te)
1949 if (content != NULL && *content != '\0')
1950 ianjuta_editor_append (te, content, -1, NULL);
1952 return IANJUTA_EDITOR (te);
1954 return NULL;
1957 static void
1958 ianjuta_docman_add_document (IAnjutaDocumentManager *plugin,
1959 IAnjutaDocument* document,
1960 GError **e)
1962 AnjutaDocman *docman;
1963 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1965 anjuta_docman_add_document(docman, document, NULL);
1968 static gboolean
1969 ianjuta_docman_remove_document(IAnjutaDocumentManager *plugin,
1970 IAnjutaDocument *doc,
1971 gboolean save_before, GError **e)
1973 gboolean ret_val;
1974 AnjutaDocman *docman;
1976 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1978 if (save_before)
1980 ret_val = anjuta_docman_save_document(docman, doc,
1981 GTK_WIDGET (ANJUTA_PLUGIN (plugin)->shell));
1983 else
1984 ret_val = TRUE;
1986 if (ret_val)
1987 anjuta_docman_remove_document (docman, doc);
1989 return ret_val;
1992 static void
1993 ianjuta_docman_add_bookmark (IAnjutaDocumentManager* plugin,
1994 GFile* file,
1995 gint line,
1996 GError **e)
1998 AnjutaBookmarks* bookmarks = ANJUTA_BOOKMARKS (ANJUTA_PLUGIN_DOCMAN(plugin)->bookmarks);
1999 anjuta_bookmarks_add_file (bookmarks, file, line, NULL);
2002 static void
2003 ianjuta_document_manager_iface_init (IAnjutaDocumentManagerIface *iface)
2005 iface->add_buffer = ianjuta_docman_add_buffer;
2006 iface->add_document = ianjuta_docman_add_document;
2007 iface->find_document_with_file = ianjuta_docman_get_document_for_file;
2008 iface->get_current_document = ianjuta_docman_get_current_document;
2009 iface->get_doc_widgets = ianjuta_docman_get_doc_widgets;
2010 iface->get_file = ianjuta_docman_get_file;
2011 iface->goto_file_line = ianjuta_docman_goto_file_line;
2012 iface->goto_file_line_mark = ianjuta_docman_goto_file_line_mark;
2013 iface->remove_document = ianjuta_docman_remove_document;
2014 iface->set_current_document = ianjuta_docman_set_current_document;
2015 iface->add_bookmark = ianjuta_docman_add_bookmark;
2018 /* Implement IAnjutaFile interface */
2019 static void
2020 ifile_open (IAnjutaFile* plugin, GFile* file, GError** e)
2022 AnjutaDocman *docman;
2024 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2025 anjuta_docman_goto_file_line (docman, file, -1);
2028 static GFile*
2029 ifile_get_file (IAnjutaFile* plugin, GError** e)
2031 AnjutaDocman *docman;
2032 IAnjutaDocument *doc;
2034 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2035 doc = anjuta_docman_get_current_document (docman);
2036 if (doc != NULL)
2037 return ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
2038 else
2039 return NULL;
2042 static void
2043 ifile_iface_init (IAnjutaFileIface *iface)
2045 iface->open = ifile_open;
2046 iface->get_file = ifile_get_file;
2049 /* Implement IAnjutaFileSavable interface */
2050 static void
2051 isaveable_save (IAnjutaFileSavable* plugin, GError** e)
2053 /* Save all buffers whose path is known */
2054 AnjutaDocman *docman;
2055 GList *docwids, *node;
2057 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2058 docwids = anjuta_docman_get_all_doc_widgets (docman);
2059 if (docwids)
2061 for (node = docwids; node != NULL; node = g_list_next (node))
2063 IAnjutaDocument *doc;
2064 doc = IANJUTA_DOCUMENT (node->data);
2065 /* known-uri test occurs downstream */
2066 /* CHECKME test here and perform save-as when appropriate ? */
2067 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
2069 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
2072 g_list_free (docwids);
2076 static void
2077 isavable_save_as (IAnjutaFileSavable* plugin, GFile* file, GError** e)
2079 DEBUG_PRINT("%s", "save_as: Not implemented in DocmanPlugin");
2082 static gboolean
2083 isavable_is_dirty (IAnjutaFileSavable* plugin, GError **e)
2085 /* Is any editor unsaved */
2086 AnjutaDocman *docman;
2087 IAnjutaDocument *doc;
2088 GList *buffers, *node;
2089 gboolean retval;
2091 retval = FALSE;
2092 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2093 buffers = anjuta_docman_get_all_doc_widgets (docman);
2094 if (buffers)
2096 for (node = buffers; node; node = g_list_next (node))
2098 doc = IANJUTA_DOCUMENT (node->data);
2099 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
2101 retval = TRUE;
2102 break;
2105 g_list_free (buffers);
2107 return retval;
2110 static void
2111 isavable_set_dirty(IAnjutaFileSavable* plugin, gboolean dirty, GError** e)
2113 DEBUG_PRINT("%s", "set_dirty: Not implemented in DocmanPlugin");
2116 static void
2117 isavable_iface_init (IAnjutaFileSavableIface *iface)
2119 iface->save = isaveable_save;
2120 iface->save_as = isavable_save_as;
2121 iface->set_dirty = isavable_set_dirty;
2122 iface->is_dirty = isavable_is_dirty;
2125 static void
2126 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2128 GError* error = NULL;
2129 GtkBuilder* bxml = gtk_builder_new ();
2130 DocmanPlugin* doc_plugin = ANJUTA_PLUGIN_DOCMAN (ipref);
2132 /* Add preferences */
2133 if (!gtk_builder_add_from_file (bxml, PREFS_BUILDER, &error))
2135 g_warning ("Couldn't load builder file: %s", error->message);
2136 g_error_free (error);
2139 anjuta_preferences_add_from_builder (prefs, bxml,
2140 doc_plugin->settings,
2141 "Documents", _("Documents"), ICON_FILE);
2143 g_object_unref (G_OBJECT (bxml));
2146 static void
2147 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2149 /* DocmanPlugin* plugin = ANJUTA_PLUGIN_DOCMAN (ipref);*/
2150 anjuta_preferences_remove_page(prefs, _("Documents"));
2153 static void
2154 ipreferences_iface_init(IAnjutaPreferencesIface* iface)
2156 iface->merge = ipreferences_merge;
2157 iface->unmerge = ipreferences_unmerge;
2160 ANJUTA_PLUGIN_BEGIN (DocmanPlugin, docman_plugin);
2161 ANJUTA_PLUGIN_ADD_INTERFACE(ianjuta_document_manager, IANJUTA_TYPE_DOCUMENT_MANAGER);
2162 ANJUTA_PLUGIN_ADD_INTERFACE(ifile, IANJUTA_TYPE_FILE);
2163 ANJUTA_PLUGIN_ADD_INTERFACE(isavable, IANJUTA_TYPE_FILE_SAVABLE);
2164 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences, IANJUTA_TYPE_PREFERENCES);
2165 ANJUTA_PLUGIN_END;
2167 ANJUTA_SIMPLE_PLUGIN (DocmanPlugin, docman_plugin);