1 /*
2 * xed-commands-edit.c
3 * This file is part of xed
4 *
5 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
6 * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
7 * Copyright (C) 2002-2005 Paolo Maggi
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 /*
26 * Modified by the xed Team, 1998-2005. See the AUTHORS file for a
27 * list of people on the xed Team.
28 * See the ChangeLog files for a list of changes.
29 *
30 * $Id$
31 */
32
33 #include <config.h>
34 #include <gtk/gtk.h>
35
36 #include "xed-commands.h"
37 #include "xed-window.h"
38 #include "xed-debug.h"
39 #include "xed-view.h"
40 #include "xed-preferences-dialog.h"
41
42 void
_xed_cmd_edit_undo(GtkAction * action,XedWindow * window)43 _xed_cmd_edit_undo (GtkAction *action,
44 XedWindow *window)
45 {
46 XedView *active_view;
47 GtkSourceBuffer *active_document;
48
49 xed_debug (DEBUG_COMMANDS);
50
51 active_view = xed_window_get_active_view (window);
52 g_return_if_fail (active_view);
53
54 active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
55
56 gtk_source_buffer_undo (active_document);
57
58 xed_view_scroll_to_cursor (active_view);
59
60 gtk_widget_grab_focus (GTK_WIDGET (active_view));
61 }
62
63 void
_xed_cmd_edit_redo(GtkAction * action,XedWindow * window)64 _xed_cmd_edit_redo (GtkAction *action,
65 XedWindow *window)
66 {
67 XedView *active_view;
68 GtkSourceBuffer *active_document;
69
70 xed_debug (DEBUG_COMMANDS);
71
72 active_view = xed_window_get_active_view (window);
73 g_return_if_fail (active_view);
74
75 active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
76
77 gtk_source_buffer_redo (active_document);
78
79 xed_view_scroll_to_cursor (active_view);
80
81 gtk_widget_grab_focus (GTK_WIDGET (active_view));
82 }
83
84 void
_xed_cmd_edit_cut(GtkAction * action,XedWindow * window)85 _xed_cmd_edit_cut (GtkAction *action,
86 XedWindow *window)
87 {
88 XedView *active_view;
89
90 xed_debug (DEBUG_COMMANDS);
91
92 active_view = xed_window_get_active_view (window);
93 g_return_if_fail (active_view);
94
95 xed_view_cut_clipboard (active_view);
96
97 gtk_widget_grab_focus (GTK_WIDGET (active_view));
98 }
99
100 void
_xed_cmd_edit_copy(GtkAction * action,XedWindow * window)101 _xed_cmd_edit_copy (GtkAction *action,
102 XedWindow *window)
103 {
104 XedView *active_view;
105
106 xed_debug (DEBUG_COMMANDS);
107
108 active_view = xed_window_get_active_view (window);
109 g_return_if_fail (active_view);
110
111 xed_view_copy_clipboard (active_view);
112
113 gtk_widget_grab_focus (GTK_WIDGET (active_view));
114 }
115
116 void
_xed_cmd_edit_paste(GtkAction * action,XedWindow * window)117 _xed_cmd_edit_paste (GtkAction *action,
118 XedWindow *window)
119 {
120 XedView *active_view;
121
122 xed_debug (DEBUG_COMMANDS);
123
124 active_view = xed_window_get_active_view (window);
125 g_return_if_fail (active_view);
126
127 xed_view_paste_clipboard (active_view);
128
129 gtk_widget_grab_focus (GTK_WIDGET (active_view));
130 }
131
132 void
_xed_cmd_edit_delete(GtkAction * action,XedWindow * window)133 _xed_cmd_edit_delete (GtkAction *action,
134 XedWindow *window)
135 {
136 XedView *active_view;
137
138 xed_debug (DEBUG_COMMANDS);
139
140 active_view = xed_window_get_active_view (window);
141 g_return_if_fail (active_view);
142
143 xed_view_delete_selection (active_view);
144
145 gtk_widget_grab_focus (GTK_WIDGET (active_view));
146 }
147
148 void
_xed_cmd_edit_select_all(GtkAction * action,XedWindow * window)149 _xed_cmd_edit_select_all (GtkAction *action,
150 XedWindow *window)
151 {
152 XedView *active_view;
153
154 xed_debug (DEBUG_COMMANDS);
155
156 active_view = xed_window_get_active_view (window);
157 g_return_if_fail (active_view);
158
159 xed_view_select_all (active_view);
160
161 gtk_widget_grab_focus (GTK_WIDGET (active_view));
162 }
163
164 void
_xed_cmd_edit_preferences(GtkAction * action,XedWindow * window)165 _xed_cmd_edit_preferences (GtkAction *action,
166 XedWindow *window)
167 {
168 xed_debug (DEBUG_COMMANDS);
169
170 xed_show_preferences_dialog (window);
171 }
172
173 void
_xed_cmd_edit_toggle_comment(GtkAction * action,XedWindow * window)174 _xed_cmd_edit_toggle_comment (GtkAction *action,
175 XedWindow *window)
176 {
177 XedView *active_view;
178 GtkSourceBuffer *active_document;
179 GtkSourceLanguage *language;
180 const gchar *comment_text;
181 gint start_line;
182 gint end_line;
183 gint i;
184 gboolean is_comment = FALSE;
185 GtkTextIter start_iter;
186 GtkTextIter end_iter;
187
188 xed_debug (DEBUG_COMMANDS);
189
190 active_view = xed_window_get_active_view (window);
191
192 if (active_view == NULL)
193 {
194 return;
195 }
196
197 active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
198 language = gtk_source_buffer_get_language (active_document);
199
200 if (language == NULL)
201 {
202 return;
203 }
204
205 comment_text = gtk_source_language_get_metadata (language, "line-comment-start");
206
207 if (comment_text == NULL)
208 {
209 return;
210 }
211
212 gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter);
213 start_line = gtk_text_iter_get_line (&start_iter);
214 end_line = gtk_text_iter_get_line (&end_iter);
215
216 gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (active_document)); // begin
217
218 // if some lines are already commented, consider the whole block commented and uncomment them
219 for (i = start_line; i <= end_line; i++)
220 {
221 GtkTextIter start_line_iter;
222 GtkTextIter end_line_iter;
223 const gchar *line_text;
224
225 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (active_document), &start_line_iter, i);
226 end_line_iter = start_line_iter;
227 gtk_text_iter_forward_to_line_end (&end_line_iter);
228
229 line_text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (active_document), &start_line_iter, &end_line_iter, TRUE);
230 if (g_str_has_prefix (line_text, comment_text))
231 {
232 is_comment = TRUE;
233 end_line_iter = start_line_iter;
234 gtk_text_iter_forward_chars (&end_line_iter, strlen(comment_text));
235 gtk_text_buffer_delete (GTK_TEXT_BUFFER (active_document), &start_line_iter, &end_line_iter);
236 }
237 }
238
239 // only comment if nothing was commented to begin with
240 if (!is_comment)
241 {
242 for (i = start_line; i <= end_line; i++)
243 {
244 GtkTextIter insert_iter;
245
246 gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (active_document), &insert_iter, i);
247 gtk_text_buffer_insert (GTK_TEXT_BUFFER (active_document), &insert_iter, comment_text, -1);
248 }
249 }
250
251 gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (active_document)); // end
252 }
253
254 void
_xed_cmd_edit_toggle_comment_block(GtkAction * action,XedWindow * window)255 _xed_cmd_edit_toggle_comment_block (GtkAction *action,
256 XedWindow *window)
257 {
258 XedView *active_view;
259 GtkSourceBuffer *active_document;
260 GtkSourceLanguage *language;
261 const gchar *start_text;
262 const gchar *end_text;
263 GtkTextIter start_iter;
264 GtkTextIter end_iter;
265 gchar *selected_text;
266 gchar *insert_text;
267
268 xed_debug (DEBUG_COMMANDS);
269
270 active_view = xed_window_get_active_view (window);
271
272 if (active_view == NULL)
273 {
274 return;
275 }
276
277 active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
278 language = gtk_source_buffer_get_language (active_document);
279
280 if (language == NULL)
281 {
282 return;
283 }
284
285 start_text = gtk_source_language_get_metadata (language, "block-comment-start");
286 end_text = gtk_source_language_get_metadata (language, "block-comment-end");
287
288 if (start_text == NULL || end_text == NULL)
289 {
290 return;
291 }
292
293 gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter);
294
295 selected_text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter, TRUE);
296
297 if (g_str_has_prefix (selected_text, start_text) && g_str_has_suffix (selected_text, end_text))
298 {
299 gint start = strlen (start_text);
300 gint end = strlen (end_text);
301 const gchar *tmp = selected_text + start;
302 insert_text = g_strndup (tmp , strlen(selected_text) - start - end);
303 }
304 else
305 {
306 insert_text = g_strconcat (start_text, selected_text, end_text, NULL);
307 }
308
309 gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (active_document)); // begin
310
311 // replace the selected text with the commented/uncommented version
312 gtk_text_buffer_delete (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter);
313 gtk_text_buffer_insert (GTK_TEXT_BUFFER (active_document), &end_iter, insert_text, -1);
314
315 // move selection back where it was
316 gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (active_document), &start_iter,
317 gtk_text_iter_get_offset (&end_iter) - strlen (insert_text));
318 gtk_text_buffer_select_range (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter);
319
320 gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (active_document)); // end
321
322 g_free (selected_text);
323 g_free (insert_text);
324 }
325