2008-02-11 Johannes Schmid <jhs@gnome.org>
[anjuta-git-plugin.git] / plugins / document-manager / plugin.c
blobe6f3c3dee4e3d40a5430355f048ce1ab80b52788
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 <libgnomevfs/gnome-vfs-utils.h>
23 #include <libanjuta/anjuta-shell.h>
24 #include <libanjuta/anjuta-debug.h>
25 #include <libanjuta/anjuta-encodings.h>
27 #include <libegg/menu/egg-entry-action.h>
28 #include <libanjuta/interfaces/ianjuta-document-manager.h>
29 #include <libanjuta/interfaces/ianjuta-file.h>
30 #include <libanjuta/interfaces/ianjuta-editor.h>
31 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
32 #include <libanjuta/interfaces/ianjuta-editor-convert.h>
33 #include <libanjuta/interfaces/ianjuta-editor-view.h>
34 #include <libanjuta/interfaces/ianjuta-editor-line-mode.h>
35 #include <libanjuta/interfaces/ianjuta-editor-factory.h>
36 #include <libanjuta/interfaces/ianjuta-editor-folds.h>
37 #include <libanjuta/interfaces/ianjuta-editor-comment.h>
38 #include <libanjuta/interfaces/ianjuta-editor-zoom.h>
39 #include <libanjuta/interfaces/ianjuta-editor-goto.h>
40 #include <libanjuta/interfaces/ianjuta-editor-search.h>
41 #include <libanjuta/interfaces/ianjuta-file-savable.h>
42 #include <libanjuta/interfaces/ianjuta-editor-language.h>
43 #include <libanjuta/interfaces/ianjuta-language-support.h>
44 #include <libanjuta/interfaces/ianjuta-language.h>
45 #include <libanjuta/interfaces/ianjuta-preferences.h>
46 #include <libanjuta/interfaces/ianjuta-document.h>
48 #include "anjuta-docman.h"
49 #include "action-callbacks.h"
50 #include "plugin.h"
51 #include "search-box.h"
53 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-document-manager.ui"
54 #define PREFS_GLADE PACKAGE_DATA_DIR"/glade/anjuta-document-manager.glade"
55 #define ICON_FILE "anjuta-document-manager-plugin-48.png"
57 /* Pixmaps */
58 #define ANJUTA_PIXMAP_SWAP "anjuta-swap"
59 #define ANJUTA_PIXMAP_BOOKMARK_TOGGLE "anjuta-bookmark-toggle"
60 #define ANJUTA_PIXMAP_BOOKMARK_FIRST "anjuta-bookmark-first"
61 #define ANJUTA_PIXMAP_BOOKMARK_PREV "anjuta-bookmark-prev"
62 #define ANJUTA_PIXMAP_BOOKMARK_NEXT "anjuta-bookmark-next"
63 #define ANJUTA_PIXMAP_BOOKMARK_LAST "anjuta-bookmark-last"
64 #define ANJUTA_PIXMAP_BOOKMARK_CLEAR "anjuta-bookmark-clear"
66 #define ANJUTA_PIXMAP_FOLD_TOGGLE "anjuta-fold-toggle"
67 #define ANJUTA_PIXMAP_FOLD_CLOSE "anjuta-fold-close"
68 #define ANJUTA_PIXMAP_FOLD_OPEN "anjuta-fold-open"
70 #define ANJUTA_PIXMAP_BLOCK_SELECT "anjuta-block-select"
71 #define ANJUTA_PIXMAP_BLOCK_START "anjuta-block-start"
72 #define ANJUTA_PIXMAP_BLOCK_END "anjuta-block-end"
74 #define ANJUTA_PIXMAP_INDENT_INC "anjuta-indent-more"
75 #define ANJUTA_PIXMAP_INDENT_DCR "anjuta-indent-less"
77 #define ANJUTA_PIXMAP_GOTO_LINE "anjuta-go-line"
79 #define ANJUTA_PIXMAP_HISTORY_NEXT "anjuta-go-history-next"
80 #define ANJUTA_PIXMAP_HISTORY_PREV "anjuta-go-history-prev"
83 /* Stock icons */
84 #define ANJUTA_STOCK_SWAP "anjuta-swap"
85 #define ANJUTA_STOCK_FOLD_TOGGLE "anjuta-fold-toggle"
86 #define ANJUTA_STOCK_FOLD_OPEN "anjuta-fold-open"
87 #define ANJUTA_STOCK_FOLD_CLOSE "anjuta-fold-close"
88 #define ANJUTA_STOCK_BLOCK_SELECT "anjuta-block-select"
89 #define ANJUTA_STOCK_INDENT_INC "anjuta-indent-inc"
90 #define ANJUTA_STOCK_INDENT_DCR "anjuta-indect-dcr"
91 #define ANJUTA_STOCK_PREV_BRACE "anjuta-prev-brace"
92 #define ANJUTA_STOCK_NEXT_BRACE "anjuta-next-brace"
93 #define ANJUTA_STOCK_BLOCK_START "anjuta-block-start"
94 #define ANJUTA_STOCK_BLOCK_END "anjuta-block-end"
95 #define ANJUTA_STOCK_BOOKMARK_TOGGLE "anjuta-bookmark-toggle"
96 #define ANJUTA_STOCK_BOOKMARK_FIRST "anjuta-bookmark-first"
97 #define ANJUTA_STOCK_BOOKMARK_PREV "anjuta-bookmark-previous"
98 #define ANJUTA_STOCK_BOOKMARK_NEXT "anjuta-bookmark-next"
99 #define ANJUTA_STOCK_BOOKMARK_LAST "anjuta-bookmark-last"
100 #define ANJUTA_STOCK_BOOKMARK_CLEAR "anjuta-bookmark-clear"
101 #define ANJUTA_STOCK_GOTO_LINE "anjuta-goto-line"
102 #define ANJUTA_STOCK_HISTORY_NEXT "anjuta-history-next"
103 #define ANJUTA_STOCK_HISTORY_PREV "anjuta-history-prev"
104 #define ANJUTA_STOCK_MATCH_NEXT "anjuta-match-next"
105 #define ANJUTA_STOCK_MATCH_PREV "anjuta-match-prev"
108 static gpointer parent_class;
110 /* Shortcuts implementation */
111 enum {
112 m___ = 0,
113 mS__ = GDK_SHIFT_MASK,
114 m_C_ = GDK_CONTROL_MASK,
115 m__M = GDK_MOD1_MASK,
116 mSC_ = GDK_SHIFT_MASK | GDK_CONTROL_MASK,
119 enum {
120 ID_NEXTBUFFER = 1, /* Note: the value mustn't be 0 ! */
121 ID_PREVBUFFER,
122 ID_FIRSTBUFFER
125 typedef struct {
126 gint modifiers;
127 guint gdk_key;
128 gint id;
129 } ShortcutMapping;
131 static ShortcutMapping global_keymap[] = {
132 /* FIXME: HIG requires that Ctrl+Tab be used to transfer focus in multiline
133 text entries. So we can't use the following ctrl+tabbing. Is there other
134 sensible keys that can be used for them?
137 { m_C_, GDK_Tab, ID_NEXTBUFFER },
138 { mSC_, GDK_ISO_Left_Tab, ID_PREVBUFFER },
140 { m__M, GDK_1, ID_FIRSTBUFFER },
141 { m__M, GDK_2, ID_FIRSTBUFFER + 1},
142 { m__M, GDK_3, ID_FIRSTBUFFER + 2},
143 { m__M, GDK_4, ID_FIRSTBUFFER + 3},
144 { m__M, GDK_5, ID_FIRSTBUFFER + 4},
145 { m__M, GDK_6, ID_FIRSTBUFFER + 5},
146 { m__M, GDK_7, ID_FIRSTBUFFER + 6},
147 { m__M, GDK_8, ID_FIRSTBUFFER + 7},
148 { m__M, GDK_9, ID_FIRSTBUFFER + 8},
149 { m__M, GDK_0, ID_FIRSTBUFFER + 9},
150 { 0, 0, 0 }
153 static GtkActionEntry actions_file[] = {
154 { "ActionFileNew", GTK_STOCK_NEW, N_("_New"), "<control>n",
155 N_("New empty file"),
156 G_CALLBACK (on_new_file_activate)},
157 { "ActionFileSave", GTK_STOCK_SAVE, N_("_Save"), "<control>s",
158 N_("Save current file"), G_CALLBACK (on_save_activate)},
159 { "ActionFileSaveAs", GTK_STOCK_SAVE_AS, N_("Save _As..."), "<shift><control>s",
160 N_("Save the current file with a different name"),
161 G_CALLBACK (on_save_as_activate)},
162 { "ActionFileSaveAll", NULL, N_("Save A_ll"), NULL,
163 N_("Save all currently open files, except new files"),
164 G_CALLBACK (on_save_all_activate)},
165 { "ActionFileClose", GTK_STOCK_CLOSE, N_("_Close File"), "<control>w",
166 N_("Close current file"),
167 G_CALLBACK (on_close_file_activate)},
168 { "ActionFileCloseAll", GTK_STOCK_CLOSE, N_("Close All"), "<shift><control>w",
169 N_("Close all files"),
170 G_CALLBACK (on_close_all_file_activate)},
171 { "ActionFileReload", GTK_STOCK_REVERT_TO_SAVED, N_("Reload F_ile"), NULL,
172 N_("Reload current file"),
173 G_CALLBACK (on_reload_file_activate)},
174 { "ActionFileSwap", ANJUTA_STOCK_SWAP, N_("Swap .h/.c"), NULL,
175 N_("Swap c header and source files"),
176 G_CALLBACK (on_swap_activate)},
177 { "ActionMenuFileRecentFiles", NULL, N_("Recent _Files"), NULL, NULL, NULL}, /* menu title */
180 static GtkActionEntry actions_print[] = {
181 { "ActionPrintFile", GTK_STOCK_PRINT, N_("_Print..."), "<control>p",
182 N_("Print the current file"), G_CALLBACK (on_print_activate)},
183 { "ActionPrintPreview",
184 #ifdef GTK_STOCK_PRINT_PREVIEW
185 GTK_STOCK_PRINT_PREVIEW
186 #else
187 NULL
188 #endif
189 , N_("_Print Preview"), NULL,
190 N_("Preview the current file in print-format"),
191 G_CALLBACK (on_print_preview_activate)},
194 static GtkActionEntry actions_transform[] = {
195 { "ActionMenuEditTransform", NULL, N_("_Transform"), NULL, NULL, NULL}, /* menu title */
196 { "ActionEditMakeSelectionUppercase", NULL, N_("_Make Selection Uppercase"), NULL,
197 N_("Make the selected text uppercase"),
198 G_CALLBACK (on_editor_command_upper_case_activate)},
199 { "ActionEditMakeSelectionLowercase", NULL, N_("Make Selection Lowercase"), NULL,
200 N_("Make the selected text lowercase"),
201 G_CALLBACK (on_editor_command_lower_case_activate)},
202 { "ActionEditConvertCRLF", NULL, N_("Convert EOL to CRLF"), NULL,
203 N_("Convert End Of Line characters to DOS EOL (CRLF)"),
204 G_CALLBACK (on_editor_command_eol_crlf_activate)},
205 { "ActionEditConvertLF", NULL, N_("Convert EOL to LF"), NULL,
206 N_("Convert End Of Line characters to Unix EOL (LF)"),
207 G_CALLBACK (on_editor_command_eol_lf_activate)},
208 { "ActionEditConvertCR", NULL, N_("Convert EOL to CR"), NULL,
209 N_("Convert End Of Line characters to Mac OS EOL (CR)"),
210 G_CALLBACK (on_editor_command_eol_cr_activate)},
211 { "ActionEditConvertEOL", NULL, N_("Convert EOL to Majority EOL"), NULL,
212 N_("Convert End Of Line characters to majority of the EOL found in the file"),
213 G_CALLBACK (on_transform_eolchars1_activate)},
216 static GtkActionEntry actions_select[] = {
217 { "ActionMenuEditSelect", NULL, N_("_Select"), NULL, NULL, NULL}, /* menu title */
218 { "ActionEditSelectAll",
219 #ifdef GTK_STOCK_SELECT_ALL
220 GTK_STOCK_SELECT_ALL
221 #else
222 NULL
223 #endif
224 , N_("Select _All"), "<control>a",
225 N_("Select all text in the editor"),
226 G_CALLBACK (on_editor_command_select_all_activate)},
227 { "ActionEditSelectToBrace", NULL, N_("Select to _Brace"), NULL,
228 N_("Select the text in the matching braces"),
229 G_CALLBACK (on_editor_command_select_to_brace_activate)},
230 { "ActionEditSelectBlock", ANJUTA_STOCK_BLOCK_SELECT, N_("Select _Code Block"),
231 "<shift><control>b", N_("Select the current code block"),
232 G_CALLBACK (on_editor_command_select_block_activate)},
235 static GtkActionEntry actions_comment[] = {
236 { "ActionMenuEditComment", NULL, N_("Co_mment"), NULL, NULL, NULL},
237 /* Block comment: Uses line-comment (comment that affects only single line
238 such as '//' or '#') and comments a block of lines. */
239 { "ActionEditCommentBlock", NULL, N_("_Block Comment/Uncomment"), NULL,
240 N_("Block comment the selected text"),
241 G_CALLBACK (on_comment_block)},
242 /* Box comment: Uses stream-comment to comment a block of lines, usually with
243 some decorations, to give an appearance of box. */
244 { "ActionEditCommentBox", NULL, N_("Bo_x Comment/Uncomment"), NULL,
245 N_("Box comment the selected text"),
246 G_CALLBACK (on_comment_box)},
247 /* Stream comment: Uses 'stream comment' (comment that affects a stream of
248 characters -- has start and end comment code) and comments any code from
249 arbitrary start position to arbitrary end position (can be in middle of
250 lines). */
251 { "ActionEditCommentStream", NULL, N_("_Stream Comment/Uncomment"), NULL,
252 N_("Stream comment the selected text"),
253 G_CALLBACK (on_comment_stream)},
256 static GtkActionEntry actions_navigation[] = {
257 { "ActionMenuGoto", NULL, N_("_Goto"), NULL, NULL, NULL},/* menu title */
258 { "ActionEditGotoLine", ANJUTA_STOCK_GOTO_LINE, N_("_Line Number..."),
259 "<control><alt>g", N_("Go to a particular line in the editor"),
260 G_CALLBACK (on_goto_line_no1_activate)},
261 { "ActionEditGotoMatchingBrace", GTK_STOCK_JUMP_TO, N_("Matching _Brace"),
262 "<control><alt>m", N_("Go to the matching brace in the editor"),
263 G_CALLBACK (on_editor_command_match_brace_activate)},
264 { "ActionEditGotoBlockStart", ANJUTA_STOCK_BLOCK_START, N_("_Start of Block"),
265 "<control><alt>s", N_("Go to the start of the current block"),
266 G_CALLBACK (on_goto_block_start1_activate)},
267 { "ActionEditGotoBlockEnd", ANJUTA_STOCK_BLOCK_END, N_("_End of Block"),
268 "<control><alt>e", N_("Go to the end of the current block"),
269 G_CALLBACK (on_goto_block_end1_activate)},
270 { "ActionEditGotoHistoryPrev", ANJUTA_STOCK_HISTORY_PREV, N_("Previous _History"),
271 NULL, N_("Goto previous history"),
272 G_CALLBACK (on_prev_history)},
273 { "ActionEditGotoHistoryNext", ANJUTA_STOCK_HISTORY_NEXT, N_("Next Histor_y"),
274 NULL, N_("Goto next history"),
275 G_CALLBACK (on_next_history)}
278 static GtkActionEntry actions_search[] = {
279 { "ActionMenuEditSearch", NULL, N_("_Search"), NULL, NULL, NULL},
280 { "ActionEditSearchQuickSearch", GTK_STOCK_FIND, N_("_Quick Search"),
281 "<control>f", N_("Quick editor embedded search"),
282 G_CALLBACK (on_show_search)},
283 { "ActionEditSearchQuickSearchAgain", GTK_STOCK_FIND, N_("Quick _ReSearch"),
284 "<control><shift>f", N_("Repeat quick search"),
285 G_CALLBACK (on_repeat_quicksearch)}
288 static GtkActionEntry actions_edit[] = {
289 { "ActionMenuEdit", NULL, N_("_Edit"), NULL, NULL, NULL},/* menu title */
290 { "ActionMenuViewEditor", NULL, N_("_Editor"), NULL, NULL, NULL},
291 { "ActionViewEditorAddView",
292 #ifdef GTK_STOCK_EDIT
293 GTK_STOCK_EDIT
294 #else
295 NULL
296 #endif
297 , N_("_Add Editor View"), NULL,
298 N_("Add one more view of current document"),
299 G_CALLBACK (on_editor_add_view_activate)},
300 { "ActionViewEditorRemoveView", NULL, N_("_Remove Editor View"), NULL,
301 N_("Remove current view of the document"),
302 G_CALLBACK (on_editor_remove_view_activate)},
303 { "ActionEditUndo", GTK_STOCK_UNDO, N_("U_ndo"), "<control>z",
304 N_("Undo the last action"),
305 G_CALLBACK (on_editor_command_undo_activate)},
306 { "ActionEditRedo", GTK_STOCK_REDO, N_("_Redo"), "<control>r",
307 N_("Redo the last undone action"),
308 G_CALLBACK (on_editor_command_redo_activate)},
309 { "ActionEditCut", GTK_STOCK_CUT, N_("C_ut"), "<control>x",
310 N_("Cut the selected text from the editor to the clipboard"),
311 G_CALLBACK (on_editor_command_cut_activate)},
312 { "ActionEditCopy", GTK_STOCK_COPY, N_("_Copy"), "<control>c",
313 N_("Copy the selected text to the clipboard"),
314 G_CALLBACK (on_editor_command_copy_activate)},
315 { "ActionEditPaste", GTK_STOCK_PASTE, N_("_Paste"), "<control>v",
316 N_("Paste the content of clipboard at the current position"),
317 G_CALLBACK (on_editor_command_paste_activate)},
318 { "ActionEditClear",
319 #ifdef GTK_STOCK_DISCARD
320 GTK_STOCK_DISCARD
321 #else
322 GTK_STOCK_CLEAR
323 #endif
324 , N_("_Clear"), "Delete",
325 N_("Delete the selected text from the editor"),
326 G_CALLBACK (on_editor_command_clear_activate)},
329 static GtkToggleActionEntry actions_view[] = {
330 { "ActionViewEditorLinenumbers", NULL, N_("_Line Number Margin"), NULL,
331 N_("Show/Hide line numbers"),
332 G_CALLBACK (on_editor_linenos1_activate), FALSE},
333 { "ActionViewEditorMarkers", NULL, N_("_Marker Margin"), NULL,
334 N_("Show/Hide marker margin"),
335 G_CALLBACK (on_editor_markers1_activate), FALSE},
336 { "ActionViewEditorFolds", NULL, N_("_Code Fold Margin"), NULL,
337 N_("Show/Hide code fold margin"),
338 G_CALLBACK (on_editor_codefold1_activate), FALSE},
339 { "ActionViewEditorGuides", NULL, N_("_Indentation Guides"), NULL,
340 N_("Show/Hide indentation guides"),
341 G_CALLBACK (on_editor_indentguides1_activate), FALSE},
342 { "ActionViewEditorSpaces", NULL, N_("_White Space"), NULL,
343 N_("Show/Hide white spaces"),
344 G_CALLBACK (on_editor_whitespaces1_activate), FALSE},
345 { "ActionViewEditorEOL", NULL, N_("_Line End Characters"), NULL,
346 N_("Show/Hide line end characters"),
347 G_CALLBACK (on_editor_eolchars1_activate), FALSE},
348 { "ActionViewEditorWrapping", NULL, N_("Line _Wrapping"), NULL,
349 N_("Enable/disable line wrapping"),
350 G_CALLBACK (on_editor_linewrap1_activate), FALSE}
353 static GtkActionEntry actions_zoom[] = {
354 { "ActionViewEditorZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom In"), "<control>plus",
355 N_("Zoom in: Increase font size"),
356 G_CALLBACK (on_zoom_in_text_activate)},
357 { "ActionViewEditorZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom Out"), "<control>minus",
358 N_("Zoom out: Decrease font size"),
359 G_CALLBACK (on_zoom_out_text_activate)}
362 static GtkActionEntry actions_style[] = {
363 { "ActionMenuFormatStyle", NULL, N_("_Highlight Mode"), NULL, NULL, NULL}/* menu title */
366 static GtkActionEntry actions_format[] = {
367 { "ActionFormatFoldCloseAll", ANJUTA_STOCK_FOLD_CLOSE, N_("_Close All Folds"),
368 NULL, N_("Close all code folds in the editor"),
369 G_CALLBACK (on_editor_command_close_folds_all_activate)},
370 { "ActionFormatFoldOpenAll", ANJUTA_STOCK_FOLD_OPEN, N_("_Open All Folds"),
371 NULL, N_("Open all code folds in the editor"),
372 G_CALLBACK (on_editor_command_open_folds_all_activate)},
373 { "ActionFormatFoldToggle", ANJUTA_STOCK_FOLD_TOGGLE, N_("_Toggle Current Fold"),
374 NULL, N_("Toggle current code fold in the editor"),
375 G_CALLBACK (on_editor_command_toggle_fold_activate)},
378 static GtkActionEntry actions_bookmark[] = {
379 { "ActionMenuBookmark", NULL, N_("Bookmar_k"), NULL, NULL, NULL},
380 { "ActionBookmarkToggle", ANJUTA_STOCK_BOOKMARK_TOGGLE, N_("_Toggle Bookmark"),
381 "<control>k", N_("Toggle a bookmark at the current line position"),
382 G_CALLBACK (on_editor_command_bookmark_toggle_activate)},
383 { "ActionBookmarkFirst", ANJUTA_STOCK_BOOKMARK_FIRST, N_("_First Bookmark"),
384 NULL, N_("Jump to the first bookmark in the file"),
385 G_CALLBACK (on_editor_command_bookmark_first_activate)},
386 { "ActionBookmarkPrevious", ANJUTA_STOCK_BOOKMARK_PREV, N_("_Previous Bookmark"),
387 "<control>comma", N_("Jump to the previous bookmark in the file"),
388 G_CALLBACK (on_editor_command_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_editor_command_bookmark_next_activate)},
392 { "ActionBookmarkLast", ANJUTA_STOCK_BOOKMARK_LAST, N_("_Last Bookmark"),
393 NULL, N_("Jump to the last bookmark in the file"),
394 G_CALLBACK (on_editor_command_bookmark_last_activate)},
395 { "ActionBookmarkClear", ANJUTA_STOCK_BOOKMARK_CLEAR, N_("_Clear All Bookmarks"),
396 NULL, N_("Clear bookmarks"),
397 G_CALLBACK (on_editor_command_bookmark_clear_activate)},
400 struct ActionGroupInfo {
401 GtkActionEntry *group;
402 gint size;
403 gchar *name;
404 gchar *label;
407 struct ActionToggleGroupInfo {
408 GtkToggleActionEntry *group;
409 gint size;
410 gchar *name;
411 gchar *label;
414 static struct ActionGroupInfo action_groups[] = {
415 { actions_file, G_N_ELEMENTS (actions_file), "ActionGroupEditorFile", N_("Editor file operations")},
416 { actions_print, G_N_ELEMENTS (actions_print), "ActionGroupEditorPrint", N_("Editor print operations")},
417 { actions_transform, G_N_ELEMENTS (actions_transform), "ActionGroupEditorTransform", N_("Editor text transformation") },
418 { actions_select, G_N_ELEMENTS (actions_select), "ActionGroupEditorSelect", N_("Editor text selection") },
419 // { actions_insert, G_N_ELEMENTS (actions_insert), "ActionGroupEditorInsert", N_("Editor text insertions") },
420 { actions_comment, G_N_ELEMENTS (actions_comment), "ActionGroupEditorComment", N_("Editor code commenting") },
421 { actions_navigation, G_N_ELEMENTS (actions_navigation), "ActionGroupEditorNavigate", N_("Editor navigations") },
422 { actions_edit, G_N_ELEMENTS (actions_edit), "ActionGroupEditorEdit", N_("Editor edit operations") },
423 { actions_zoom, G_N_ELEMENTS (actions_zoom), "ActionGroupEditorZoom", N_("Editor zoom operations") },
424 { actions_style, G_N_ELEMENTS (actions_style), "ActionGroupEditorStyle", N_("Editor syntax highlighting styles") },
425 { actions_format, G_N_ELEMENTS (actions_format), "ActionGroupEditorFormat", N_("Editor text formating") },
426 { actions_bookmark, G_N_ELEMENTS (actions_bookmark), "ActionGroupEditorBookmark", N_("Editor bookmarks") },
427 { actions_search, G_N_ELEMENTS (actions_search), "ActionGroupEditorSearch", N_("Simple searching") }
430 static struct ActionToggleGroupInfo action_toggle_groups[] = {
431 { actions_view, G_N_ELEMENTS (actions_view), "ActionGroupEditorView", N_("Editor view settings") }
434 // void pref_set_style_combo(DocmanPlugin *plugin);
437 #define VIEW_LINENUMBERS_MARGIN "margin.linenumber.visible"
438 #define VIEW_MARKER_MARGIN "margin.marker.visible"
439 #define VIEW_FOLD_MARGIN "margin.fold.visible"
440 #define VIEW_INDENTATION_GUIDES "view.indentation.guides"
441 #define VIEW_WHITE_SPACES "view.whitespace"
442 #define VIEW_EOL "view.eol"
443 #define VIEW_LINE_WRAP "view.line.wrap"
445 static void
446 update_title (DocmanPlugin* doc_plugin)
448 IAnjutaDocument *doc;
449 AnjutaStatus *status;
450 gchar *filename;
451 gchar *title;
453 doc = anjuta_docman_get_current_document (ANJUTA_DOCMAN (doc_plugin->docman));
455 if (doc)
457 gchar *uri;
458 uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
459 if (uri)
461 filename = gnome_vfs_get_local_path_from_uri (uri);
462 g_free (uri);
464 else
465 filename = NULL;
467 else
468 filename = NULL;
469 if (filename && doc_plugin->project_name)
471 gchar *display_filename = NULL;
472 if (doc_plugin->project_path)
474 if (g_str_has_prefix (filename, doc_plugin->project_path))
476 /* the +1 is the '/' */
477 display_filename = filename + strlen (doc_plugin->project_path) + 1;
480 if (!display_filename)
481 display_filename = filename;
482 title = g_strconcat (doc_plugin->project_name, " - ", display_filename, NULL);
484 else if (filename)
486 title = g_strdup (filename);
488 else if (doc_plugin->project_name)
490 title = g_strdup (doc_plugin->project_name);
492 else
493 title = NULL;
495 status = anjuta_shell_get_status (ANJUTA_PLUGIN (doc_plugin)->shell, NULL);
496 /* NULL title is ok */
497 anjuta_status_set_title (status, title);
498 g_free (filename);
499 g_free (title);
502 static void
503 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
504 const GValue *value, gpointer user_data)
506 DocmanPlugin *doc_plugin;
507 const gchar *root_uri;
509 doc_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
511 DEBUG_PRINT ("Project added");
514 g_free (doc_plugin->project_name);
515 g_free (doc_plugin->project_path);
516 doc_plugin->project_name = NULL;
518 root_uri = g_value_get_string (value);
519 if (root_uri)
521 gchar* path =
522 gnome_vfs_get_local_path_from_uri (root_uri);
524 doc_plugin->project_name = g_path_get_basename(path);
525 doc_plugin->project_path = path;
527 if (doc_plugin->project_name)
529 update_title (doc_plugin);
534 static void
535 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
536 gpointer user_data)
538 DocmanPlugin *doc_plugin;
540 doc_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
542 DEBUG_PRINT ("Project removed");
544 g_free (doc_plugin->project_name);
545 doc_plugin->project_name = NULL;
547 update_title(doc_plugin);
550 static void
551 ui_states_init (AnjutaPlugin *plugin)
553 gint i;
554 DocmanPlugin *eplugin;
555 static const gchar *prefs[] = {
556 VIEW_LINENUMBERS_MARGIN,
557 VIEW_MARKER_MARGIN,
558 VIEW_FOLD_MARGIN,
559 VIEW_INDENTATION_GUIDES,
560 VIEW_WHITE_SPACES,
561 VIEW_EOL,
562 VIEW_LINE_WRAP
565 eplugin = ANJUTA_PLUGIN_DOCMAN (plugin);
566 for (i = 0; i < sizeof (actions_view)/sizeof(GtkToggleActionEntry); i++)
568 GtkAction *action;
569 gboolean state;
571 state = anjuta_preferences_get_int (eplugin->prefs, prefs[i]);
572 action = anjuta_ui_get_action (eplugin->ui, "ActionGroupEditorView",
573 actions_view[i].name);
574 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), state);
578 static void
579 ui_give_shorter_names (AnjutaPlugin *plugin)
581 AnjutaUI *ui;
582 GtkAction *action;
584 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
585 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
586 "ActionFileNew");
587 g_object_set (G_OBJECT (action), "short-label", _("New"),
588 "is-important", TRUE, NULL);
589 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
590 "ActionFileSave");
591 g_object_set (G_OBJECT (action), "short-label", _("Save"),
592 "is-important", TRUE, NULL);
593 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
594 "ActionFileReload");
595 g_object_set (G_OBJECT (action), "short-label", _("Reload"), NULL);
596 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
597 "ActionEditUndo");
598 g_object_set (G_OBJECT (action), "is-important", TRUE, NULL);
599 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
600 "ActionEditGotoLine");
601 g_object_set (G_OBJECT (action), "short-label", _("Goto"), NULL);
604 static void
605 update_document_ui_enable_all (AnjutaPlugin *plugin)
607 AnjutaUI *ui;
608 gint i, j;
609 GtkAction *action;
611 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
612 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
614 for (j = 0; j < action_groups[i].size; j++)
616 action = anjuta_ui_get_action (ui, action_groups[i].name,
617 action_groups[i].group[j].name);
618 if (action_groups[i].group[j].callback)
620 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
626 static void
627 update_document_ui_disable_all (AnjutaPlugin *plugin)
629 AnjutaUI *ui;
630 gint i, j;
631 GtkAction *action;
633 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
634 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
636 for (j = 0; j < action_groups[i].size; j++)
638 action = anjuta_ui_get_action (ui, action_groups[i].name,
639 action_groups[i].group[j].name);
640 if (action_groups[i].group[j].callback &&
641 strcmp (action_groups[i].group[j].name, "ActionFileNew") != 0)
643 /* Disable all but ActoinFileNew actions */
644 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
650 static void
651 update_document_ui_save_items (AnjutaPlugin *plugin, IAnjutaDocument *doc)
653 AnjutaUI *ui;
654 GtkAction *action;
656 ui = anjuta_shell_get_ui (plugin->shell, NULL);
658 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
659 "ActionEditUndo");
660 g_object_set (G_OBJECT (action), "sensitive",
661 ianjuta_document_can_undo (doc, NULL), NULL);
663 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
664 "ActionEditRedo");
665 g_object_set (G_OBJECT (action), "sensitive",
666 ianjuta_document_can_redo (doc, NULL), NULL);
668 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
669 "ActionFileSave");
670 g_object_set (G_OBJECT (action), "sensitive",
671 ianjuta_file_savable_is_dirty(IANJUTA_FILE_SAVABLE(doc), NULL),
672 NULL);
675 static void
676 update_document_ui_interface_items (AnjutaPlugin *plugin, IAnjutaDocument *doc)
678 AnjutaUI *ui;
679 GtkAction *action;
680 gboolean flag;
682 ui = anjuta_shell_get_ui (plugin->shell, NULL);
684 /* IAnjutaEditorLanguage */
685 flag = IANJUTA_IS_EDITOR_LANGUAGE (doc);
687 action = anjuta_ui_get_action (ui, "ActionGroupEditorStyle",
688 "ActionMenuFormatStyle");
689 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
691 if (flag)
693 IAnjutaLanguage *language;
694 language = anjuta_shell_get_interface (plugin->shell, IAnjutaLanguage, NULL);
695 if (language)
697 /* Check if it is a C or C++ file */
698 const gchar *lang_name =
699 ianjuta_language_get_name_from_editor (language, IANJUTA_EDITOR_LANGUAGE (doc), NULL);
700 flag = (lang_name && (g_str_equal (lang_name, "C") || g_str_equal (lang_name, "C++")));
704 action = anjuta_ui_get_action (ui, "ActionGroupEditorFile",
705 "ActionFileSwap");
706 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
708 /* IAnjutaDocument */
709 flag = IANJUTA_IS_DOCUMENT (doc);
711 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
712 "ActionEditCut");
713 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
715 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
716 "ActionEditCopy");
717 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
719 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
720 "ActionEditPaste");
721 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
723 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
724 "ActionEditClear");
725 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
727 /* IAnjutaEditorSelection */
728 flag = IANJUTA_IS_EDITOR_SELECTION (doc);
730 action = anjuta_ui_get_action (ui, "ActionGroupEditorSelect",
731 "ActionEditSelectAll");
732 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
734 action = anjuta_ui_get_action (ui, "ActionGroupEditorSelect",
735 "ActionEditSelectToBrace");
736 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
738 action = anjuta_ui_get_action (ui, "ActionGroupEditorSelect",
739 "ActionEditSelectBlock");
740 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
742 /* IAnjutaEditorConvert */
743 flag = IANJUTA_IS_EDITOR_CONVERT (doc);
744 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
745 "ActionEditMakeSelectionUppercase");
746 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
748 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
749 "ActionEditMakeSelectionLowercase");
750 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
752 /* IAnjutaEditorLineMode */
753 flag = IANJUTA_IS_EDITOR_LINE_MODE (doc);
755 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
756 "ActionEditConvertCRLF");
757 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
758 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
759 "ActionEditConvertLF");
760 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
761 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
762 "ActionEditConvertCR");
763 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
764 action = anjuta_ui_get_action (ui, "ActionGroupEditorTransform",
765 "ActionEditConvertEOL");
766 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
768 /* IAnjutaEditorView */
769 flag = IANJUTA_IS_EDITOR_VIEW (doc);
770 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
771 "ActionViewEditorAddView");
772 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
773 action = anjuta_ui_get_action (ui, "ActionGroupEditorEdit",
774 "ActionViewEditorRemoveView");
775 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
777 /* IAnjutaEditorFolds */
778 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
779 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
780 "ActionFormatFoldCloseAll");
781 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
783 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
784 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
785 "ActionFormatFoldOpenAll");
786 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
788 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
789 action = anjuta_ui_get_action (ui, "ActionGroupEditorFormat",
790 "ActionFormatFoldToggle");
791 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
793 flag = IANJUTA_IS_EDITOR_FOLDS (doc);
794 action = anjuta_ui_get_action (ui, "ActionGroupEditorView",
795 "ActionViewEditorFolds");
796 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
798 /* IAnjutaEditorComment */
799 flag = IANJUTA_IS_EDITOR_COMMENT (doc);
800 action = anjuta_ui_get_action (ui, "ActionGroupEditorComment",
801 "ActionMenuEditComment");
802 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
804 /* IAnjutaEditorZoom */
805 flag = IANJUTA_IS_EDITOR_ZOOM (doc);
806 action = anjuta_ui_get_action (ui, "ActionGroupEditorZoom",
807 "ActionViewEditorZoomIn");
808 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
809 action = anjuta_ui_get_action (ui, "ActionGroupEditorZoom",
810 "ActionViewEditorZoomOut");
811 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
813 /* IAnjutaEditorGoto */
814 flag = IANJUTA_IS_EDITOR_GOTO (doc);
815 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
816 "ActionEditGotoBlockStart");
817 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
818 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
819 "ActionEditGotoBlockEnd");
820 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
821 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
822 "ActionEditGotoMatchingBrace");
823 g_object_set (G_OBJECT (action), "visible", flag, "sensitive", flag, NULL);
825 /* IAnjutaEditorSearch */
826 flag = IANJUTA_IS_EDITOR_SEARCH (doc);
827 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
828 "ActionEditSearchQuickSearch");
829 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
830 action = anjuta_ui_get_action (ui, "ActionGroupEditorSearch",
831 "ActionEditSearchQuickSearchAgain");
832 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
833 action = anjuta_ui_get_action (ui, "ActionGroupEditorNavigate",
834 "ActionEditGotoLine");
835 g_object_set (G_OBJECT (action), "sensitive", flag, NULL);
839 static void
840 update_document_ui (AnjutaPlugin *plugin, IAnjutaDocument *doc)
842 if (doc == NULL)
844 update_document_ui_disable_all (plugin);
845 return;
847 update_document_ui_enable_all (plugin);
848 update_document_ui_save_items (plugin, doc);
849 update_document_ui_interface_items (plugin, doc);
852 static void
853 on_document_update_save_ui (IAnjutaDocument *doc, gboolean entered,
854 AnjutaPlugin *plugin)
856 update_document_ui_save_items (plugin, doc);
859 static void
860 register_stock_icons (AnjutaPlugin *plugin)
862 static gboolean registered = FALSE;
863 if (registered)
864 return;
865 registered = TRUE;
867 /* Register stock icons */
868 BEGIN_REGISTER_ICON (plugin);
869 REGISTER_ICON (ICON_FILE, "editor-plugin-icon");
870 REGISTER_ICON_FULL (ANJUTA_PIXMAP_SWAP, ANJUTA_STOCK_SWAP);
871 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_TOGGLE, ANJUTA_STOCK_FOLD_TOGGLE);
872 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_OPEN, ANJUTA_STOCK_FOLD_OPEN);
873 REGISTER_ICON_FULL (ANJUTA_PIXMAP_FOLD_CLOSE, ANJUTA_STOCK_FOLD_CLOSE);
874 REGISTER_ICON_FULL (ANJUTA_PIXMAP_INDENT_DCR, ANJUTA_STOCK_INDENT_DCR);
875 REGISTER_ICON_FULL (ANJUTA_PIXMAP_INDENT_INC, ANJUTA_STOCK_INDENT_INC);
876 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_SELECT, ANJUTA_STOCK_BLOCK_SELECT);
877 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_TOGGLE, ANJUTA_STOCK_BOOKMARK_TOGGLE);
878 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_FIRST, ANJUTA_STOCK_BOOKMARK_FIRST);
879 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_PREV, ANJUTA_STOCK_BOOKMARK_PREV);
880 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_NEXT, ANJUTA_STOCK_BOOKMARK_NEXT);
881 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_LAST, ANJUTA_STOCK_BOOKMARK_LAST);
882 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BOOKMARK_CLEAR, ANJUTA_STOCK_BOOKMARK_CLEAR);
883 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_START, ANJUTA_STOCK_BLOCK_START);
884 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BLOCK_END, ANJUTA_STOCK_BLOCK_END);
885 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_LINE, ANJUTA_STOCK_GOTO_LINE);
886 REGISTER_ICON_FULL (ANJUTA_PIXMAP_HISTORY_NEXT, ANJUTA_STOCK_HISTORY_NEXT);
887 REGISTER_ICON_FULL (ANJUTA_PIXMAP_HISTORY_PREV, ANJUTA_STOCK_HISTORY_PREV);
888 END_REGISTER_ICON;
891 #define TEXT_ZOOM_FACTOR "text.zoom.factor"
893 static void
894 update_status (DocmanPlugin *plugin, IAnjutaEditor *te)
896 AnjutaStatus *status;
898 if (te)
900 gchar *edit /*, *mode*/;
901 guint line, col, zoom;
903 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
904 if (status == NULL)
905 return;
907 /* TODO: Implement this in IAnjutaEditor some kind
908 gint editor_mode;
909 editor_mode = scintilla_send_message (SCINTILLA (te->widgets.editor),
910 SCI_GETEOLMODE, 0, 0);
911 switch (editor_mode) {
912 case SC_EOL_CRLF:
913 mode = g_strdup(_("DOS (CRLF)"));
914 break;
915 case SC_EOL_LF:
916 mode = g_strdup(_("Unix (LF)"));
917 break;
918 case SC_EOL_CR:
919 mode = g_strdup(_("Mac (CR)"));
920 break;
921 default:
922 mode = g_strdup(_("Unknown"));
923 break;
926 zoom = anjuta_preferences_get_int (plugin->prefs, TEXT_ZOOM_FACTOR);
927 line = ianjuta_editor_get_lineno (te, NULL);
928 col = ianjuta_editor_get_column (te, NULL);
930 if (ianjuta_editor_get_overwrite (te, NULL))
932 edit = g_strdup (_("OVR"));
934 else
936 edit = g_strdup (_("INS"));
938 anjuta_status_set_default (status, _("Zoom"), "%d", zoom);
939 anjuta_status_set_default (status, _("Line"), "%04d", line);
940 anjuta_status_set_default (status, _("Col"), "%03d", col);
941 anjuta_status_set_default (status, _("Mode"), edit);
942 // anjuta_status_set_default (status, _("EOL"), mode);
944 g_free (edit);
945 /* g_free (mode); */
947 else
949 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
950 if (status)
952 anjuta_status_set_default (status, _("Zoom"), NULL);
953 anjuta_status_set_default (status, _("Line"), NULL);
954 anjuta_status_set_default (status, _("Col"), NULL);
955 anjuta_status_set_default (status, _("Mode"), NULL);
956 /* anjuta_status_set_default (status, _("EOL"), NULL); */
961 static void
962 on_document_update_ui (IAnjutaDocument *doc, DocmanPlugin *plugin)
964 IAnjutaDocument *curdoc;
966 curdoc = anjuta_docman_get_current_document (ANJUTA_DOCMAN (plugin->docman));
967 if (IANJUTA_IS_EDITOR (curdoc) && curdoc == doc)
968 update_status (plugin, IANJUTA_EDITOR (curdoc));
971 /* Remove all instances of c from the string s. */
972 static void remove_char(gchar *s, gchar c)
974 gchar *t = s;
975 for (; *s ; ++s)
976 if (*s != c)
977 *t++ = *s;
978 *t = '\0';
981 /* Compare two strings, ignoring _ characters which indicate mnemonics.
982 * Returns -1, 0, or 1, just like strcmp(). */
983 static gint
984 menu_name_compare(const gchar *s, const char *t)
986 gchar *s1 = g_utf8_strdown(s, -1);
987 gchar *t1 = g_utf8_strdown(t, -1);
988 remove_char(s1, '_');
989 remove_char(t1, '_');
990 gint result = g_utf8_collate (s1, t1);
991 g_free(s1);
992 g_free(t1);
993 return result;
996 static gint
997 compare_language_name(const gchar *lang1, const gchar *lang2, IAnjutaEditorLanguage *manager)
999 const gchar *fullname1 = ianjuta_editor_language_get_language_name (manager, lang1, NULL);
1000 const gchar *fullname2 = ianjuta_editor_language_get_language_name (manager, lang2, NULL);
1001 return menu_name_compare(fullname1, fullname2);
1004 static GtkWidget*
1005 create_highlight_submenu (DocmanPlugin *plugin, IAnjutaEditor *editor)
1007 const GList *languages, *node;
1008 GList *sorted_languages;
1009 GtkWidget *submenu;
1010 GtkWidget *menuitem;
1012 submenu = gtk_menu_new ();
1014 if (!editor || !IANJUTA_IS_EDITOR_LANGUAGE (editor))
1015 return NULL;
1017 languages = ianjuta_editor_language_get_supported_languages (IANJUTA_EDITOR_LANGUAGE (editor), NULL);
1018 if (!languages)
1019 return NULL;
1021 /* Automatic highlight menu */
1022 menuitem = gtk_menu_item_new_with_mnemonic (_("Automatic"));
1023 g_signal_connect (G_OBJECT (menuitem), "activate",
1024 G_CALLBACK (on_force_hilite_activate),
1025 plugin);
1026 g_object_set_data(G_OBJECT(menuitem), "language_code", "auto-detect");
1027 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
1028 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), gtk_separator_menu_item_new());
1030 /* Sort languages so they appear alphabetically in the menu. */
1031 sorted_languages = g_list_copy((GList *) languages);
1032 sorted_languages = g_list_sort_with_data(sorted_languages, (GCompareDataFunc) compare_language_name,
1033 IANJUTA_EDITOR_LANGUAGE (editor));
1035 node = sorted_languages;
1036 while (node)
1038 const gchar *lang = node->data;
1039 const gchar *name = ianjuta_editor_language_get_language_name (IANJUTA_EDITOR_LANGUAGE (editor), lang, NULL);
1041 /* Should fix #493583 */
1042 if (name != NULL)
1044 menuitem = gtk_menu_item_new_with_mnemonic (name);
1045 g_object_set_data_full (G_OBJECT (menuitem), "language_code",
1046 g_strdup (lang),
1047 (GDestroyNotify)g_free);
1048 g_signal_connect (G_OBJECT (menuitem), "activate",
1049 G_CALLBACK (on_force_hilite_activate),
1050 plugin);
1051 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
1053 node = g_list_next (node);
1055 g_list_free(sorted_languages);
1057 gtk_widget_show_all (submenu);
1058 return submenu;
1061 static void
1062 on_document_added (AnjutaDocman *docman, IAnjutaDocument *doc,
1063 AnjutaPlugin *plugin)
1065 GtkWidget *highlight_submenu, *highlight_menu;
1066 DocmanPlugin *docman_plugin;
1068 docman_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1069 g_signal_connect (G_OBJECT (doc), "update_ui",
1070 G_CALLBACK (on_document_update_ui),
1071 docman_plugin);
1072 g_signal_connect (G_OBJECT (doc), "save_point",
1073 G_CALLBACK (on_document_update_save_ui),
1074 plugin);
1075 /* Present the vbox as this is the widget that was added to the shell */
1076 anjuta_shell_present_widget (plugin->shell,
1077 GTK_WIDGET (docman_plugin->vbox), NULL);
1079 if (IANJUTA_IS_EDITOR (doc))
1081 IAnjutaEditor *te;
1083 te = IANJUTA_EDITOR (doc);
1085 /* Create Highlight submenu */
1086 highlight_submenu =
1087 create_highlight_submenu (docman_plugin, te);
1088 if (highlight_submenu)
1090 highlight_menu =
1091 gtk_ui_manager_get_widget (GTK_UI_MANAGER (docman_plugin->ui),
1092 "/MenuMain/MenuView/MenuViewEditor/MenuFormatStyle");
1093 gtk_menu_item_set_submenu (GTK_MENU_ITEM (highlight_menu),
1094 highlight_submenu);
1099 static void
1100 on_support_plugin_deactivated (AnjutaPlugin* plugin, DocmanPlugin* docman_plugin)
1102 docman_plugin->support_plugins = g_list_remove (docman_plugin->support_plugins, plugin);
1105 static GList*
1106 load_new_support_plugins (DocmanPlugin* docman_plugin, GList* new_plugin_ids,
1107 AnjutaPluginManager* plugin_manager)
1109 GList* node;
1110 GList* needed_plugins = NULL;
1111 for (node = new_plugin_ids; node != NULL; node = g_list_next (node))
1113 gchar* plugin_id = node->data;
1114 GObject* new_plugin = anjuta_plugin_manager_get_plugin_by_id (plugin_manager,
1115 plugin_id);
1116 GList* item = g_list_find (docman_plugin->support_plugins, new_plugin);
1117 if (!item)
1119 DEBUG_PRINT ("Loading plugin: %s", plugin_id);
1120 g_signal_connect (new_plugin, "deactivated",
1121 G_CALLBACK (on_support_plugin_deactivated), docman_plugin);
1123 needed_plugins = g_list_append (needed_plugins, new_plugin);
1125 return needed_plugins;
1128 static void
1129 unload_unused_support_plugins (DocmanPlugin* docman_plugin,
1130 GList* needed_plugins)
1132 GList* plugins = g_list_copy (docman_plugin->support_plugins);
1133 GList* node;
1134 for (node = plugins; node != NULL; node = g_list_next (node))
1136 AnjutaPlugin* plugin = ANJUTA_PLUGIN (node->data);
1137 if (!g_list_find (needed_plugins, plugin))
1139 DEBUG_PRINT ("Unloading plugin");
1140 anjuta_plugin_deactivate (plugin);
1143 g_list_free (plugins);
1146 static void
1147 on_document_changed (AnjutaDocman *docman, IAnjutaDocument *doc,
1148 AnjutaPlugin *plugin)
1150 update_document_ui (plugin, doc);
1152 if (doc)
1154 GValue value = {0, };
1155 g_value_init (&value, G_TYPE_OBJECT);
1156 g_value_set_object (&value, doc);
1157 anjuta_shell_add_value (plugin->shell,
1158 "document_manager_current_editor",
1159 &value, NULL);
1160 g_value_unset(&value);
1162 else
1164 anjuta_shell_remove_value (plugin->shell, "document_manager_current_editor",
1165 NULL);
1168 if (doc && IANJUTA_IS_EDITOR (doc))
1170 DocmanPlugin *docman_plugin;
1172 docman_plugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1173 update_status (docman_plugin, IANJUTA_EDITOR (doc));
1175 if (IANJUTA_IS_EDITOR_LANGUAGE (doc))
1177 DEBUG_PRINT("Beginning language support");
1178 AnjutaPluginManager *plugin_manager;
1179 IAnjutaLanguage *lang_manager;
1180 GList *new_support_plugins, *support_plugin_descs, *needed_plugins, *node;
1181 const gchar *language;
1183 lang_manager = anjuta_shell_get_interface (plugin->shell,
1184 IAnjutaLanguage,
1185 NULL);
1186 if (!lang_manager)
1188 g_warning ("Could not load language manager!");
1189 goto out;
1191 language = ianjuta_language_get_name_from_editor (lang_manager,
1192 IANJUTA_EDITOR_LANGUAGE (doc),
1193 NULL);
1194 if (!language)
1196 DEBUG_PRINT ("Unloading all language support plugins");
1197 /* Unload all language support plugins */
1198 /* Copy the list because the "deactivate"-signal handler modifies
1199 * the original list */
1200 GList* plugins = g_list_copy (docman_plugin->support_plugins);
1201 g_list_foreach (plugins, (GFunc) anjuta_plugin_deactivate, NULL);
1202 g_list_free (plugins);
1203 goto out;
1206 /* Load current language editor support plugins */
1207 plugin_manager = anjuta_shell_get_plugin_manager (plugin->shell, NULL);
1208 support_plugin_descs = anjuta_plugin_manager_query (plugin_manager,
1209 "Anjuta Plugin",
1210 "Interfaces",
1211 "IAnjutaLanguageSupport",
1212 "Language Support",
1213 "Languages",
1214 language, NULL);
1215 new_support_plugins = NULL;
1216 for (node = support_plugin_descs; node != NULL; node = g_list_next (node))
1218 gchar *plugin_id;
1220 AnjutaPluginDescription *desc = node->data;
1222 anjuta_plugin_description_get_string (desc, "Anjuta Plugin", "Location",
1223 &plugin_id);
1225 new_support_plugins = g_list_append (new_support_plugins, plugin_id);
1227 g_list_free (support_plugin_descs);
1229 /* Load new plugins */
1230 needed_plugins =
1231 load_new_support_plugins (docman_plugin, new_support_plugins,
1232 plugin_manager);
1234 /* Unload unused plugins */
1235 unload_unused_support_plugins (docman_plugin, needed_plugins);
1237 /* Update list */
1238 g_list_free (docman_plugin->support_plugins);
1239 docman_plugin->support_plugins = needed_plugins;
1241 if (new_support_plugins)
1243 g_list_foreach (new_support_plugins, (GFunc) g_free, NULL);
1244 g_list_free (new_support_plugins);
1248 out:
1249 update_title (ANJUTA_PLUGIN_DOCMAN (plugin));
1252 static gboolean
1253 on_window_key_press_event (AnjutaShell *shell,
1254 GdkEventKey *event,
1255 DocmanPlugin *plugin)
1257 gint modifiers;
1258 gint i;
1260 g_return_val_if_fail (event != NULL, FALSE);
1262 modifiers = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK);
1264 for (i = 0; global_keymap[i].id; i++)
1265 if (event->keyval == global_keymap[i].gdk_key &&
1266 (event->state & global_keymap[i].modifiers) == global_keymap[i].modifiers)
1267 break;
1269 if (!global_keymap[i].id)
1270 return FALSE;
1272 switch (global_keymap[i].id) {
1273 case ID_NEXTBUFFER:
1274 case ID_PREVBUFFER:
1276 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1277 gint pages_nb;
1278 gint cur_page;
1280 if (!notebook->children)
1281 return FALSE;
1283 if (!plugin->g_tabbing)
1285 plugin->g_tabbing = TRUE;
1288 pages_nb = g_list_length (notebook->children);
1289 cur_page = gtk_notebook_get_current_page (notebook);
1291 if (global_keymap[i].id == ID_NEXTBUFFER)
1292 cur_page = (cur_page < pages_nb - 1) ? cur_page + 1 : 0;
1293 else
1294 cur_page = cur_page ? cur_page - 1 : pages_nb -1;
1296 gtk_notebook_set_page (notebook, cur_page);
1298 break;
1300 default:
1301 if (global_keymap[i].id >= ID_FIRSTBUFFER &&
1302 global_keymap[i].id <= (ID_FIRSTBUFFER + 9))
1304 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1305 gint page_req = global_keymap[i].id - ID_FIRSTBUFFER;
1307 if (!notebook->children)
1308 return FALSE;
1309 gtk_notebook_set_page(notebook, page_req);
1311 else
1312 return FALSE;
1315 /* Note: No reason for a shortcut to do more than one thing a time */
1316 g_signal_stop_emission_by_name (G_OBJECT (ANJUTA_PLUGIN(plugin)->shell),
1317 "key-press-event");
1319 return TRUE;
1322 #define EDITOR_TABS_RECENT_FIRST "editor.tabs.recent.first"
1323 #define EDITOR_TABS_POS "editor.tabs.pos"
1324 #define EDITOR_TABS_HIDE "editor.tabs.hide"
1325 #define EDITOR_TABS_ORDERING "editor.tabs.ordering"
1326 #define AUTOSAVE_TIMER "autosave.timer"
1327 #define SAVE_AUTOMATIC "save.automatic"
1329 static gboolean
1330 on_window_key_release_event (AnjutaShell *shell,
1331 GdkEventKey *event,
1332 DocmanPlugin *plugin)
1334 g_return_val_if_fail (event != NULL, FALSE);
1336 if (plugin->g_tabbing && ((event->keyval == GDK_Control_L) ||
1337 (event->keyval == GDK_Control_R)))
1339 GtkNotebook *notebook = GTK_NOTEBOOK (plugin->docman);
1340 GtkWidget *widget;
1341 gint cur_page;
1342 plugin->g_tabbing = FALSE;
1344 if (anjuta_preferences_get_int (plugin->prefs,
1345 EDITOR_TABS_RECENT_FIRST))
1348 TTimo: move the current notebook page to first position
1349 that maintains Ctrl-TABing on a list of most recently edited files
1351 cur_page = gtk_notebook_get_current_page (notebook);
1352 widget = gtk_notebook_get_nth_page (notebook, cur_page);
1353 gtk_notebook_reorder_child (notebook, widget, 0);
1356 return FALSE;
1359 static void
1360 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
1361 AnjutaSession *session, DocmanPlugin *plugin)
1363 GList *docwids, *node, *files;
1365 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
1366 return;
1368 files = anjuta_session_get_string_list (session, "File Loader", "Files"); /* probably NULL */
1369 if (files)
1370 files = g_list_reverse (files);
1371 /* buffers list is ordered last-opened to first-opened */
1372 docwids = anjuta_docman_get_all_doc_widgets (ANJUTA_DOCMAN (plugin->docman));
1373 if (docwids)
1375 for (node = docwids; node != NULL; node = g_list_next (node))
1377 /* only editor-documents are logged here. glade files etc handled elsewhere */
1378 if (IANJUTA_IS_EDITOR (node->data))
1380 IAnjutaEditor *te;
1381 gchar *te_uri;
1383 te = IANJUTA_EDITOR (node->data);
1384 te_uri = ianjuta_file_get_uri (IANJUTA_FILE (te), NULL);
1385 if (te_uri)
1387 gchar *uri;
1388 /* Save line locations also */
1389 uri = g_strdup_printf ("%s#%d", te_uri,
1390 ianjuta_editor_get_lineno (te, NULL));
1391 files = g_list_prepend (files, uri);
1392 g_free (te_uri);
1396 g_list_free (docwids);
1398 if (files)
1400 files = g_list_reverse (files);
1401 anjuta_session_set_string_list (session, "File Loader", "Files", files);
1402 g_list_foreach (files, (GFunc)g_free, NULL);
1403 g_list_free (files);
1407 static gboolean
1408 on_save_prompt_save_editor (AnjutaSavePrompt *save_prompt,
1409 gpointer item, gpointer user_data)
1411 DocmanPlugin *plugin;
1413 plugin = ANJUTA_PLUGIN_DOCMAN (user_data);
1414 return anjuta_docman_save_document (ANJUTA_DOCMAN (plugin->docman),
1415 IANJUTA_DOCUMENT (item),
1416 GTK_WIDGET (save_prompt));
1419 static void
1420 on_save_prompt (AnjutaShell *shell, AnjutaSavePrompt *save_prompt,
1421 DocmanPlugin *plugin)
1423 GList *buffers, *node;
1425 buffers = anjuta_docman_get_all_doc_widgets (ANJUTA_DOCMAN (plugin->docman));
1426 if (buffers)
1428 for (node = buffers; node; node = g_list_next (node))
1430 IAnjutaFileSavable *editor = IANJUTA_FILE_SAVABLE (node->data);
1431 if (ianjuta_file_savable_is_dirty (editor, NULL))
1433 const gchar *name;
1434 gchar *uri;
1436 name = ianjuta_document_get_filename (IANJUTA_DOCUMENT (editor), NULL);
1437 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
1438 anjuta_save_prompt_add_item (save_prompt, name, uri, editor,
1439 on_save_prompt_save_editor, plugin);
1440 g_free (uri);
1443 g_list_free (buffers);
1447 static void
1448 docman_plugin_set_tab_pos (DocmanPlugin *ep)
1450 if (anjuta_preferences_get_int_with_default (ep->prefs, EDITOR_TABS_HIDE,
1453 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ep->docman), FALSE);
1455 else
1457 gchar *tab_pos;
1458 GtkPositionType pos;
1460 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ep->docman), TRUE);
1461 tab_pos = anjuta_preferences_get (ep->prefs, EDITOR_TABS_POS);
1463 pos = GTK_POS_TOP;
1464 if (tab_pos)
1466 if (strcasecmp (tab_pos, "top") == 0)
1467 pos = GTK_POS_TOP;
1468 else if (strcasecmp (tab_pos, "left") == 0)
1469 pos = GTK_POS_LEFT;
1470 else if (strcasecmp (tab_pos, "right") == 0)
1471 pos = GTK_POS_RIGHT;
1472 else if (strcasecmp (tab_pos, "bottom") == 0)
1473 pos = GTK_POS_BOTTOM;
1474 g_free (tab_pos);
1476 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (ep->docman), pos);
1480 static void
1481 on_gconf_notify_prefs (GConfClient *gclient, guint cnxn_id,
1482 GConfEntry *entry, gpointer user_data)
1484 DocmanPlugin *ep = ANJUTA_PLUGIN_DOCMAN (user_data);
1485 docman_plugin_set_tab_pos (ep);
1488 static gboolean
1489 on_docman_auto_save (gpointer data)
1491 gboolean retval;
1492 const gchar *mesg;
1493 AnjutaPreferences* prefs;
1494 DocmanPlugin *plugin;
1495 AnjutaDocman *docman;
1496 AnjutaStatus* status;
1497 IAnjutaDocument *doc;
1498 GList *buffers, *node;
1500 plugin = ANJUTA_PLUGIN_DOCMAN (data);
1501 docman = ANJUTA_DOCMAN (plugin->docman);
1502 if (!docman)
1503 return FALSE;
1505 prefs = anjuta_shell_get_preferences (docman->shell, NULL);
1506 if (anjuta_preferences_get_int (prefs, SAVE_AUTOMATIC) == FALSE)
1508 plugin->autosave_on = FALSE;
1509 return FALSE;
1512 status = anjuta_shell_get_status (docman->shell, NULL);
1514 retval = TRUE;
1515 buffers = anjuta_docman_get_all_doc_widgets (docman);
1516 if (buffers)
1518 for (node = buffers; node != NULL; node = g_list_next (node))
1520 doc = IANJUTA_DOCUMENT (node->data);
1521 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
1523 gchar *uri;
1524 GError *err;
1525 uri = ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
1526 if (uri)
1528 g_free (uri);
1529 err = NULL;
1530 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), &err);
1532 if (!uri || err)
1534 gchar *fullmsg;
1535 mesg = ianjuta_document_get_filename (doc, NULL); /* this may fail, too */
1536 fullmsg = g_strdup_printf (_("Autosave failed for %s"), mesg);
1537 anjuta_status (status, fullmsg, 3);
1538 g_free (fullmsg);
1539 if (err)
1540 g_error_free (err);
1541 retval = FALSE;
1545 g_list_free (buffers);
1548 if (retval)
1550 anjuta_status (status, _("Autosave completed"), 3);
1552 return retval;
1555 static void
1556 on_gconf_notify_timer (GConfClient *gclient, guint cnxn_id,
1557 GConfEntry *entry, gpointer user_data)
1559 DocmanPlugin *plugin;
1560 AnjutaDocman *docman;
1561 AnjutaPreferences* prefs;
1562 gint auto_save_timer;
1563 gboolean auto_save;
1565 plugin = ANJUTA_PLUGIN_DOCMAN (user_data);
1566 docman = ANJUTA_DOCMAN (plugin->docman);
1568 prefs = anjuta_shell_get_preferences (docman->shell, NULL);
1570 auto_save_timer = anjuta_preferences_get_int(prefs, AUTOSAVE_TIMER);
1571 auto_save = anjuta_preferences_get_int(prefs, SAVE_AUTOMATIC);
1573 if (auto_save)
1575 if (plugin->autosave_on)
1577 if (auto_save_timer != plugin->autosave_it)
1579 g_source_remove (plugin->autosave_id);
1580 plugin->autosave_id =
1581 #if GLIB_CHECK_VERSION (2,14,0)
1582 g_timeout_add_seconds (auto_save_timer * 60,
1583 #else
1584 g_timeout_add (auto_save_timer * 60000,
1585 #endif
1586 on_docman_auto_save, plugin);
1589 else
1591 plugin->autosave_id =
1592 #if GLIB_CHECK_VERSION (2,14,0)
1593 g_timeout_add_seconds (auto_save_timer * 60,
1594 #else
1595 g_timeout_add (auto_save_timer * 60000,
1596 #endif
1597 on_docman_auto_save, plugin);
1599 plugin->autosave_it = auto_save_timer;
1600 plugin->autosave_on = TRUE;
1602 else if (plugin->autosave_on)
1604 g_source_remove (plugin->autosave_id);
1605 plugin->autosave_on = FALSE;
1609 #define REGISTER_NOTIFY(key, func) \
1610 notify_id = anjuta_preferences_notify_add (ep->prefs, \
1611 key, func, ep, NULL); \
1612 ep->gconf_notify_ids = g_list_prepend (ep->gconf_notify_ids, \
1613 GUINT_TO_POINTER (notify_id));
1614 static void
1615 prefs_init (DocmanPlugin *ep)
1617 guint notify_id;
1618 docman_plugin_set_tab_pos (ep);
1619 REGISTER_NOTIFY (EDITOR_TABS_HIDE, on_gconf_notify_prefs);
1620 REGISTER_NOTIFY (EDITOR_TABS_POS, on_gconf_notify_prefs);
1621 REGISTER_NOTIFY (AUTOSAVE_TIMER, on_gconf_notify_timer);
1622 REGISTER_NOTIFY (SAVE_AUTOMATIC, on_gconf_notify_timer);
1624 on_gconf_notify_timer(NULL,0,NULL, ep);
1627 static void
1628 prefs_finalize (DocmanPlugin *ep)
1630 GList *node;
1631 node = ep->gconf_notify_ids;
1632 while (node)
1634 anjuta_preferences_notify_remove (ep->prefs,
1635 GPOINTER_TO_UINT (node->data));
1636 node = g_list_next (node);
1638 g_list_free (ep->gconf_notify_ids);
1639 ep->gconf_notify_ids = NULL;
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 ("DocmanPlugin: Activating document manager plugin...");
1655 dplugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1656 dplugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
1657 dplugin->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
1659 ui = dplugin->ui;
1660 docman = anjuta_docman_new (dplugin, dplugin->prefs);
1661 dplugin->docman = docman;
1663 ANJUTA_DOCMAN(docman)->shell = plugin->shell;
1664 g_signal_connect (G_OBJECT (docman), "document-added",
1665 G_CALLBACK (on_document_added), plugin);
1666 g_signal_connect (G_OBJECT (docman), "document-changed",
1667 G_CALLBACK (on_document_changed), plugin);
1668 g_signal_connect (G_OBJECT (plugin->shell), "key-press-event",
1669 G_CALLBACK (on_window_key_press_event), plugin);
1670 g_signal_connect (G_OBJECT (plugin->shell), "key-release-event",
1671 G_CALLBACK (on_window_key_release_event), plugin);
1673 if (!initialized)
1675 register_stock_icons (plugin);
1677 dplugin->action_groups = NULL;
1678 /* Add all our editor actions */
1679 for (i = 0; i < G_N_ELEMENTS (action_groups); i++)
1681 group = anjuta_ui_add_action_group_entries (ui,
1682 action_groups[i].name,
1683 _(action_groups[i].label),
1684 action_groups[i].group,
1685 action_groups[i].size,
1686 GETTEXT_PACKAGE, TRUE,
1687 plugin);
1688 dplugin->action_groups =
1689 g_list_prepend (dplugin->action_groups, group);
1690 actions = gtk_action_group_list_actions (group);
1691 act = actions;
1692 while (act) {
1693 g_object_set_data (G_OBJECT (act->data), "Plugin", dplugin);
1694 act = g_list_next (act);
1697 for (i = 0; i < G_N_ELEMENTS (action_toggle_groups); i++)
1699 group = anjuta_ui_add_toggle_action_group_entries (ui,
1700 action_toggle_groups[i].name,
1701 _(action_toggle_groups[i].label),
1702 action_toggle_groups[i].group,
1703 action_toggle_groups[i].size,
1704 GETTEXT_PACKAGE, TRUE, plugin);
1705 dplugin->action_groups =
1706 g_list_prepend (dplugin->action_groups, group);
1707 actions = gtk_action_group_list_actions (group);
1708 act = actions;
1709 while (act) {
1710 g_object_set_data (G_OBJECT (act->data), "Plugin", dplugin);
1711 act = g_list_next (act);
1715 /* Add UI */
1716 dplugin->uiid = anjuta_ui_merge (ui, UI_FILE);
1717 dplugin->vbox = gtk_vbox_new (FALSE, 0);
1718 gtk_widget_show (dplugin->vbox);
1719 gtk_box_pack_start_defaults (GTK_BOX(dplugin->vbox), docman);
1720 anjuta_shell_add_widget_full (plugin->shell, dplugin->vbox,
1721 "AnjutaDocumentManager", _("Documents"),
1722 "editor-plugin-icon",
1723 ANJUTA_SHELL_PLACEMENT_CENTER,
1724 TRUE, NULL);
1726 ui_states_init(plugin);
1727 ui_give_shorter_names (plugin);
1728 update_document_ui (plugin, NULL);
1730 /* Create the default searchbox instance, but don't yet put it into
1731 dplugin->vbox, to prevent the box being displayed at session start */
1732 dplugin->search_box = search_box_new (ANJUTA_DOCMAN (docman));
1734 /* Setup popup menu */
1735 popup_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
1736 "/PopupDocumentManager");
1737 g_assert (popup_menu != NULL && GTK_IS_MENU (popup_menu));
1738 anjuta_docman_set_popup_menu (ANJUTA_DOCMAN (docman), popup_menu);
1739 if (!initialized)
1741 //search_and_replace_init (ANJUTA_DOCMAN (docman));
1743 /* Connect to save session */
1744 g_signal_connect (G_OBJECT (plugin->shell), "save-session",
1745 G_CALLBACK (on_session_save), plugin);
1746 /* Connect to save prompt */
1747 g_signal_connect (G_OBJECT (plugin->shell), "save-prompt",
1748 G_CALLBACK (on_save_prompt), plugin);
1750 dplugin->project_watch_id =
1751 anjuta_plugin_add_watch (plugin, "project_root_uri",
1752 value_added_project_root_uri,
1753 value_removed_project_root_uri, NULL);
1754 dplugin->project_name = NULL;
1756 prefs_init(ANJUTA_PLUGIN_DOCMAN (plugin));
1757 initialized = TRUE;
1759 return TRUE;
1762 static gboolean
1763 deactivate_plugin (AnjutaPlugin *plugin)
1765 // GtkIconFactory *icon_factory;
1766 DocmanPlugin *eplugin;
1767 AnjutaUI *ui;
1768 AnjutaStatus *status;
1769 GList *node;
1771 DEBUG_PRINT ("DocmanPlugin: Deactivating document manager plugin...");
1773 eplugin = ANJUTA_PLUGIN_DOCMAN (plugin);
1775 prefs_finalize (eplugin);
1776 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1777 G_CALLBACK (on_session_save), plugin);
1778 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1779 G_CALLBACK (on_save_prompt), plugin);
1781 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1782 status = anjuta_shell_get_status (plugin->shell, NULL);
1784 g_signal_handlers_disconnect_by_func (G_OBJECT (eplugin->docman),
1785 G_CALLBACK (on_document_changed),
1786 plugin);
1787 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1788 G_CALLBACK (on_window_key_press_event),
1789 plugin);
1790 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1791 G_CALLBACK (on_window_key_release_event),
1792 plugin);
1794 on_document_changed (ANJUTA_DOCMAN (eplugin->docman), NULL, plugin);
1796 /* Widget is removed from the container when destroyed */
1797 gtk_widget_destroy (eplugin->docman);
1798 gtk_widget_destroy (eplugin->search_box); /* the default searchbox instance may still be unparented */
1799 anjuta_ui_unmerge (ui, eplugin->uiid);
1800 node = eplugin->action_groups;
1801 while (node)
1803 GtkActionGroup *group = GTK_ACTION_GROUP (node->data);
1804 anjuta_ui_remove_action_group (ui, group);
1805 node = g_list_next (node);
1807 g_list_free (eplugin->action_groups);
1809 /* FIXME: */
1810 /* Unregister stock icons */
1811 /* Unregister preferences */
1813 eplugin->docman = NULL;
1814 eplugin->uiid = 0;
1815 eplugin->action_groups = NULL;
1817 return TRUE;
1820 static void
1821 dispose (GObject *obj)
1823 // DocmanPlugin *eplugin = ANJUTA_PLUGIN_DOCMAN (obj);
1824 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (obj));
1827 static void
1828 docman_plugin_instance_init (GObject *obj)
1830 DocmanPlugin *plugin = ANJUTA_PLUGIN_DOCMAN (obj);
1831 plugin->uiid = 0;
1832 plugin->g_tabbing = FALSE;
1833 plugin->gconf_notify_ids = NULL;
1834 plugin->support_plugins = NULL;
1837 static void
1838 docman_plugin_class_init (GObjectClass *klass)
1840 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1842 parent_class = g_type_class_peek_parent (klass);
1844 plugin_class->activate = activate_plugin;
1845 plugin_class->deactivate = deactivate_plugin;
1846 klass->dispose = dispose;
1849 /* Implement IAnjutaDocumentManager interfaces */
1850 static gchar*
1851 ianjuta_docman_get_uri (IAnjutaDocumentManager *plugin,
1852 const gchar *filename, GError **e)
1854 AnjutaDocman *docman;
1855 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1856 return anjuta_docman_get_uri (docman, filename);
1859 static IAnjutaDocument*
1860 ianjuta_docman_get_document_for_uri (IAnjutaDocumentManager *plugin,
1861 const gchar *file_uri, GError **e)
1863 AnjutaDocman *docman;
1864 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1865 return anjuta_docman_get_document_for_uri (docman, file_uri);
1868 static IAnjutaDocument*
1869 ianjuta_docman_get_current_document (IAnjutaDocumentManager *plugin, GError **e)
1871 AnjutaDocman *docman;
1872 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1873 return anjuta_docman_get_current_document (docman);
1876 static void
1877 ianjuta_docman_set_current_document (IAnjutaDocumentManager *plugin,
1878 IAnjutaDocument *doc, GError **e)
1880 AnjutaDocman *docman;
1881 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1882 anjuta_docman_set_current_document (docman, doc);
1885 static GList*
1886 ianjuta_docman_get_doc_widgets (IAnjutaDocumentManager *plugin, GError **e)
1888 AnjutaDocman *docman;
1889 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1890 return anjuta_docman_get_all_doc_widgets (docman);
1893 static IAnjutaEditor*
1894 ianjuta_docman_goto_uri_line (IAnjutaDocumentManager *plugin,
1895 const gchar *uri, gint linenum, GError **e)
1897 AnjutaDocman *docman;
1898 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1899 return anjuta_docman_goto_uri_line (docman, uri, linenum);
1902 static IAnjutaEditor*
1903 ianjuta_docman_goto_uri_line_mark (IAnjutaDocumentManager *plugin,
1904 const gchar *uri, gint linenum, gboolean mark, GError **e)
1906 AnjutaDocman *docman;
1907 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1908 return anjuta_docman_goto_uri_line_mark (docman, uri, linenum, mark);
1912 * anjuta_docman_add_buffer:
1913 * @plugin:
1914 * @filename:
1915 * @content file text, a 0-terminated utf-8 string
1916 * @r: store for pointer to error data struct
1918 * Return value: the new editor
1920 static IAnjutaEditor*
1921 ianjuta_docman_add_buffer (IAnjutaDocumentManager *plugin,
1922 const gchar *filename, const gchar *content,
1923 GError **e)
1925 AnjutaDocman *docman;
1926 IAnjutaEditor *te;
1927 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1928 te = anjuta_docman_add_editor (docman, NULL, filename);
1929 if (te)
1931 if (content != NULL && *content != '\0')
1932 ianjuta_editor_append (te, content, -1, NULL);
1934 return IANJUTA_EDITOR (te);
1936 return NULL;
1939 static void
1940 ianjuta_docman_add_document (IAnjutaDocumentManager *plugin,
1941 IAnjutaDocument* document,
1942 GError **e)
1944 AnjutaDocman *docman;
1945 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1947 anjuta_docman_add_document(docman, document, NULL);
1950 static gboolean
1951 ianjuta_docman_remove_document(IAnjutaDocumentManager *plugin,
1952 IAnjutaDocument *doc,
1953 gboolean save_before, GError **e)
1955 gboolean ret_val;
1956 AnjutaDocman *docman;
1958 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1960 if (save_before)
1962 ret_val = anjuta_docman_save_document(docman, doc,
1963 GTK_WIDGET (ANJUTA_PLUGIN (plugin)->shell));
1965 else
1966 ret_val = TRUE;
1968 if (ret_val)
1969 anjuta_docman_remove_document (docman, doc);
1971 return ret_val;
1974 static void
1975 ianjuta_document_manager_iface_init (IAnjutaDocumentManagerIface *iface)
1977 iface->add_buffer = ianjuta_docman_add_buffer;
1978 iface->add_document = ianjuta_docman_add_document;
1979 iface->find_document_with_uri = ianjuta_docman_get_document_for_uri;
1980 iface->get_current_document = ianjuta_docman_get_current_document;
1981 iface->get_doc_widgets = ianjuta_docman_get_doc_widgets;
1982 iface->get_uri = ianjuta_docman_get_uri;
1983 iface->goto_uri_line = ianjuta_docman_goto_uri_line;
1984 iface->goto_uri_line_mark = ianjuta_docman_goto_uri_line_mark;
1985 iface->remove_document = ianjuta_docman_remove_document;
1986 iface->set_current_document = ianjuta_docman_set_current_document;
1989 /* Implement IAnjutaFile interface */
1990 static void
1991 ifile_open (IAnjutaFile* plugin, const gchar* uri, GError** e)
1993 AnjutaDocman *docman;
1995 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
1996 anjuta_docman_goto_uri_line_mark (docman, uri, -1, FALSE);
1999 static gchar*
2000 ifile_get_uri (IAnjutaFile* plugin, GError** e)
2002 AnjutaDocman *docman;
2003 IAnjutaDocument *doc;
2005 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2006 doc = anjuta_docman_get_current_document (docman);
2007 if (doc != NULL)
2008 return ianjuta_file_get_uri (IANJUTA_FILE (doc), NULL);
2009 /* bad to call this func with NULL arg
2010 else if (ianjuta_document_get_filename (doc, NULL))
2011 return gnome_vfs_get_uri_from_local_path (ianjuta_document_get_filename(editor, NULL));
2013 else
2014 return NULL;
2017 static void
2018 ifile_iface_init (IAnjutaFileIface *iface)
2020 iface->open = ifile_open;
2021 iface->get_uri = ifile_get_uri;
2024 /* Implement IAnjutaFileSavable interface */
2025 static void
2026 isaveable_save (IAnjutaFileSavable* plugin, GError** e)
2028 /* Save all buffers whose path is known */
2029 AnjutaDocman *docman;
2030 GList *docwids, *node;
2032 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2033 docwids = anjuta_docman_get_all_doc_widgets (docman);
2034 if (docwids)
2036 for (node = docwids; node != NULL; node = g_list_next (node))
2038 IAnjutaDocument *doc;
2039 doc = IANJUTA_DOCUMENT (node->data);
2040 /* known-uri test occurs downstream */
2041 /* CHECKME test here and perform save-as when appropriate ? */
2042 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
2044 ianjuta_file_savable_save (IANJUTA_FILE_SAVABLE (doc), NULL);
2047 g_list_free (docwids);
2051 static void
2052 isavable_save_as (IAnjutaFileSavable* plugin, const gchar* uri, GError** e)
2054 DEBUG_PRINT("save_as: Not implemented in DocmanPlugin");
2057 static gboolean
2058 isavable_is_dirty (IAnjutaFileSavable* plugin, GError **e)
2060 /* Is any editor unsaved */
2061 AnjutaDocman *docman;
2062 IAnjutaDocument *doc;
2063 GList *buffers, *node;
2064 gboolean retval;
2066 retval = FALSE;
2067 docman = ANJUTA_DOCMAN ((ANJUTA_PLUGIN_DOCMAN (plugin)->docman));
2068 buffers = anjuta_docman_get_all_doc_widgets (docman);
2069 if (buffers)
2071 for (node = buffers; node; node = g_list_next (node))
2073 doc = IANJUTA_DOCUMENT (node->data);
2074 if (ianjuta_file_savable_is_dirty (IANJUTA_FILE_SAVABLE (doc), NULL))
2076 retval = TRUE;
2077 break;
2080 g_list_free (buffers);
2082 return retval;
2085 static void
2086 isavable_set_dirty(IAnjutaFileSavable* plugin, gboolean dirty, GError** e)
2088 DEBUG_PRINT("set_dirty: Not implemented in DocmanPlugin");
2091 static void
2092 isavable_iface_init (IAnjutaFileSavableIface *iface)
2094 iface->save = isaveable_save;
2095 iface->save_as = isavable_save_as;
2096 iface->set_dirty = isavable_set_dirty;
2097 iface->is_dirty = isavable_is_dirty;
2100 static void
2101 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2103 GladeXML* gxml;
2105 /* Add preferences */
2106 gxml = glade_xml_new (PREFS_GLADE, "preferences_dialog", NULL);
2108 anjuta_preferences_add_page (prefs,
2109 gxml, "Documents", _("Documents"), ICON_FILE);
2110 anjuta_encodings_init (prefs, gxml);
2112 g_object_unref (G_OBJECT (gxml));
2115 static void
2116 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2118 DocmanPlugin* plugin = ANJUTA_PLUGIN_DOCMAN (ipref);
2119 prefs_finalize(plugin);
2120 anjuta_preferences_remove_page(prefs, _("Documents"));
2123 static void
2124 ipreferences_iface_init(IAnjutaPreferencesIface* iface)
2126 iface->merge = ipreferences_merge;
2127 iface->unmerge = ipreferences_unmerge;
2130 ANJUTA_PLUGIN_BEGIN (DocmanPlugin, docman_plugin);
2131 ANJUTA_PLUGIN_ADD_INTERFACE(ianjuta_document_manager, IANJUTA_TYPE_DOCUMENT_MANAGER);
2132 ANJUTA_PLUGIN_ADD_INTERFACE(ifile, IANJUTA_TYPE_FILE);
2133 ANJUTA_PLUGIN_ADD_INTERFACE(isavable, IANJUTA_TYPE_FILE_SAVABLE);
2134 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences, IANJUTA_TYPE_PREFERENCES);
2135 ANJUTA_PLUGIN_END;
2137 ANJUTA_SIMPLE_PLUGIN (DocmanPlugin, docman_plugin);