1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Johannes Schmid 2008 <jhs@gnome.org>
6 * anjuta-trunk is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta-trunk is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "sourceview-io.h"
21 #include "sourceview-private.h"
22 #include <libanjuta/interfaces/ianjuta-editor.h>
23 #include <libanjuta/anjuta-convert.h>
24 #include <libanjuta/anjuta-encodings.h>
26 #define READ_SIZE 4096
27 #define RATE_LIMIT 5000 /* Use a big rate limit to avoid duplicates */
43 #define IO_ERROR_QUARK g_quark_from_string ("SourceviewIO-Error")
45 static guint io_signals
[LAST_SIGNAL
] = { 0 };
47 G_DEFINE_TYPE (SourceviewIO
, sourceview_io
, G_TYPE_OBJECT
);
50 sourceview_io_init (SourceviewIO
*object
)
53 object
->filename
= NULL
;
54 object
->read_buffer
= NULL
;
55 object
->write_buffer
= NULL
;
56 object
->cancel
= g_cancellable_new();
57 object
->monitor
= NULL
;
58 object
->last_encoding
= NULL
;
59 object
->bytes_read
= 0;
63 sourceview_io_finalize (GObject
*object
)
65 SourceviewIO
* sio
= SOURCEVIEW_IO(object
);
67 g_object_unref (sio
->file
);
68 g_free(sio
->filename
);
69 g_free(sio
->read_buffer
);
70 g_free(sio
->write_buffer
);
71 g_object_unref (sio
->cancel
);
72 if (sio
->monitor_idle
> 0)
73 g_source_remove (sio
->monitor_idle
);
75 g_object_unref (sio
->monitor
);
77 G_OBJECT_CLASS (sourceview_io_parent_class
)->finalize (object
);
81 sourceview_io_class_init (SourceviewIOClass
*klass
)
83 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
85 object_class
->finalize
= sourceview_io_finalize
;
87 klass
->changed
= NULL
;
88 klass
->deleted
= NULL
;
89 klass
->save_finished
= NULL
;
90 klass
->open_finished
= NULL
;
91 klass
->open_failed
= NULL
;
92 klass
->save_failed
= NULL
;
94 io_signals
[SAVE_STATUS
] =
95 g_signal_new ("changed",
96 G_OBJECT_CLASS_TYPE (klass
),
98 G_STRUCT_OFFSET (SourceviewIOClass
, changed
),
100 g_cclosure_marshal_VOID__VOID
,
104 io_signals
[SAVE_FINISHED
] =
105 g_signal_new ("save-finished",
106 G_OBJECT_CLASS_TYPE (klass
),
108 G_STRUCT_OFFSET (SourceviewIOClass
, save_finished
),
110 g_cclosure_marshal_VOID__VOID
,
114 io_signals
[OPEN_FINISHED
] =
115 g_signal_new ("open-finished",
116 G_OBJECT_CLASS_TYPE (klass
),
118 G_STRUCT_OFFSET (SourceviewIOClass
, open_finished
),
120 g_cclosure_marshal_VOID__VOID
,
124 io_signals
[OPEN_FAILED
] =
125 g_signal_new ("open-failed",
126 G_OBJECT_CLASS_TYPE (klass
),
128 G_STRUCT_OFFSET (SourceviewIOClass
, open_failed
),
130 g_cclosure_marshal_VOID__POINTER
,
134 io_signals
[SAVE_FAILED
] =
135 g_signal_new ("save-failed",
136 G_OBJECT_CLASS_TYPE (klass
),
138 G_STRUCT_OFFSET (SourceviewIOClass
, save_failed
),
140 g_cclosure_marshal_VOID__POINTER
,
144 io_signals
[FILE_DELETED
] =
145 g_signal_new ("deleted",
146 G_OBJECT_CLASS_TYPE (klass
),
148 G_STRUCT_OFFSET (SourceviewIOClass
, deleted
),
150 g_cclosure_marshal_VOID__VOID
,
155 static void on_file_changed (GFileMonitor
* monitor
,
158 GFileMonitorEvent event_type
,
161 SourceviewIO
* sio
= SOURCEVIEW_IO(data
);
165 case G_FILE_MONITOR_EVENT_CREATED
:
166 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT
:
167 g_signal_emit_by_name (sio
, "changed");
169 case G_FILE_MONITOR_EVENT_DELETED
:
170 g_signal_emit_by_name (sio
, "deleted");
178 setup_monitor_idle(gpointer data
)
180 SourceviewIO
* sio
= SOURCEVIEW_IO(data
);
181 sio
->monitor_idle
= 0;
182 if (sio
->monitor
!= NULL
)
183 g_object_unref (sio
->monitor
);
184 sio
->monitor
= g_file_monitor_file (sio
->file
,
190 g_signal_connect (sio
->monitor
, "changed",
191 G_CALLBACK(on_file_changed
), sio
);
192 g_file_monitor_set_rate_limit (sio
->monitor
, RATE_LIMIT
);
198 setup_monitor(SourceviewIO
* sio
)
200 if (sio
->monitor_idle
> 0)
201 g_source_remove (sio
->monitor_idle
);
203 sio
->monitor_idle
= g_timeout_add_seconds (TIMEOUT
,
209 cancel_monitor (SourceviewIO
* sio
)
211 if (sio
->monitor
!= NULL
)
212 g_object_unref (sio
->monitor
);
217 set_display_name (SourceviewIO
* sio
)
219 GFileInfo
* file_info
= g_file_query_info (sio
->file
,
220 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
,
221 G_FILE_QUERY_INFO_NONE
,
226 g_free (sio
->filename
);
227 sio
->filename
= g_strdup(g_file_info_get_display_name (file_info
));
231 g_free (sio
->filename
);
232 sio
->filename
= NULL
;
234 g_object_unref (file_info
);
238 on_save_finished (GObject
* file
, GAsyncResult
* result
, gpointer data
)
240 SourceviewIO
* sio
= SOURCEVIEW_IO(data
);
241 AnjutaShell
* shell
= ANJUTA_PLUGIN (sio
->sv
->priv
->plugin
)->shell
;
243 g_file_replace_contents_finish (G_FILE (file
),
247 g_free (sio
->write_buffer
);
248 sio
->write_buffer
= NULL
;
251 g_signal_emit_by_name (sio
, "save-failed", err
);
256 set_display_name (sio
);
258 g_signal_emit_by_name (sio
, "save-finished");
260 g_object_unref (sio
);
261 anjuta_shell_saving_pop (shell
);
265 sourceview_io_save (SourceviewIO
* sio
)
269 GError
* error
= NULL
;
270 g_set_error (&error
, IO_ERROR_QUARK
, 0,
271 _("Could not save file because filename not yet specified"));
272 g_signal_emit_by_name (sio
, "save-failed", error
);
276 sourceview_io_save_as (sio
, sio
->file
);
280 sourceview_io_save_as (SourceviewIO
* sio
, GFile
* file
)
282 AnjutaShell
* shell
= ANJUTA_PLUGIN (sio
->sv
->priv
->plugin
)->shell
;
283 gboolean backup
= TRUE
;
286 g_return_if_fail (file
!= NULL
);
288 cancel_monitor (sio
);
290 backup
= g_settings_get_boolean (sio
->sv
->priv
->settings
,
293 if (sio
->last_encoding
== NULL
)
295 sio
->write_buffer
= ianjuta_editor_get_text_all (IANJUTA_EDITOR(sio
->sv
),
297 len
= strlen (sio
->write_buffer
);
302 gchar
* buffer_text
= ianjuta_editor_get_text_all (IANJUTA_EDITOR(sio
->sv
),
304 sio
->write_buffer
= anjuta_convert_from_utf8 (buffer_text
,
309 g_free (buffer_text
);
312 g_signal_emit_by_name (sio
, "save-failed", err
);
317 g_cancellable_reset (sio
->cancel
);
318 g_file_replace_contents_async (file
,
327 anjuta_shell_saving_push (shell
);
329 if (sio
->file
!= file
)
332 g_object_unref (sio
->file
);
339 static void insert_text_in_document(SourceviewIO
* sio
, const gchar
* text
, gsize len
)
341 GtkSourceBuffer
* document
= GTK_SOURCE_BUFFER (sio
->sv
->priv
->document
);
342 gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (sio
->sv
->priv
->document
));
344 /* Insert text in the buffer */
345 gtk_text_buffer_set_text (GTK_TEXT_BUFFER (document
),
349 gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (document
),
352 gtk_source_buffer_end_not_undoable_action (document
);
356 append_buffer (SourceviewIO
* sio
, gsize size
)
358 /* Text is utf-8 - good */
359 if (g_utf8_validate (sio
->read_buffer
, size
, NULL
))
361 insert_text_in_document (sio
, sio
->read_buffer
, size
);
365 /* Text is not utf-8 */
366 GError
*conv_error
= NULL
;
367 gchar
*converted_text
= NULL
;
368 gsize new_len
= size
;
369 const AnjutaEncoding
* enc
= NULL
;
371 converted_text
= anjuta_convert_to_utf8 (sio
->read_buffer
,
376 if (converted_text
== NULL
)
378 /* Last chance, let's try 8859-15 */
379 enc
= anjuta_encoding_get_from_charset( "ISO-8859-15");
381 converted_text
= anjuta_convert_to_utf8 (sio
->read_buffer
,
387 if (converted_text
== NULL
)
389 g_return_val_if_fail (conv_error
!= NULL
, FALSE
);
391 g_signal_emit_by_name (sio
, "open-failed", conv_error
);
392 g_error_free (conv_error
);
393 g_cancellable_cancel (sio
->cancel
);
396 sio
->last_encoding
= enc
;
397 insert_text_in_document (sio
, converted_text
, new_len
);
398 g_free (converted_text
);
404 on_read_finished (GObject
* input
, GAsyncResult
* result
, gpointer data
)
406 SourceviewIO
* sio
= SOURCEVIEW_IO(data
);
407 GInputStream
* input_stream
= G_INPUT_STREAM(input
);
408 gsize current_bytes
= 0;
411 current_bytes
= g_input_stream_read_finish (input_stream
, result
, &err
);
414 g_signal_emit_by_name (sio
, "open-failed", err
);
416 g_object_unref (input_stream
);
417 g_free (sio
->read_buffer
);
418 sio
->read_buffer
= NULL
;
423 sio
->bytes_read
+= current_bytes
;
424 if (current_bytes
!= 0)
426 sio
->read_buffer
= g_realloc (sio
->read_buffer
, sio
->bytes_read
+ READ_SIZE
);
427 g_input_stream_read_async (G_INPUT_STREAM (input_stream
),
428 sio
->read_buffer
+ sio
->bytes_read
,
438 if (append_buffer (sio
, sio
->bytes_read
))
439 g_signal_emit_by_name (sio
, "open-finished");
441 g_object_unref (input_stream
);
443 g_free (sio
->read_buffer
);
444 sio
->read_buffer
= NULL
;
449 sourceview_io_open (SourceviewIO
* sio
, GFile
* file
)
451 GFileInputStream
* input_stream
;
454 g_return_if_fail (file
!= NULL
);
457 g_object_unref (sio
->file
);
459 g_object_ref (sio
->file
);
460 set_display_name(sio
);
462 input_stream
= g_file_read (file
, NULL
, &err
);
465 g_signal_emit_by_name (sio
, "open-failed", err
);
469 sio
->read_buffer
= g_realloc (sio
->read_buffer
, READ_SIZE
);
470 g_input_stream_read_async (G_INPUT_STREAM (input_stream
),
480 sourceview_io_get_file (SourceviewIO
* sio
)
483 g_object_ref (sio
->file
);
488 sourceview_io_cancel (SourceviewIO
* sio
)
490 g_cancellable_cancel (sio
->cancel
);
494 sourceview_io_get_filename (SourceviewIO
* sio
)
496 static gint new_file_count
= 1;
497 if (sio
->filename
== NULL
) /* new file */
499 sio
->filename
= g_strdup_printf (_("New file %d"), new_file_count
++);
501 return sio
->filename
;
505 sourceview_io_set_filename (SourceviewIO
* sio
, const gchar
* filename
)
507 g_free (sio
->filename
);
508 sio
->filename
= g_strdup(filename
);
512 sourceview_io_get_mime_type (SourceviewIO
* sio
)
514 GFileInfo
* file_info
;
519 file_info
= g_file_query_info (sio
->file
,
520 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
,
521 G_FILE_QUERY_INFO_NONE
,
526 gchar
* mime_type
= g_strdup (g_file_info_get_content_type (file_info
));
527 g_object_unref (file_info
);
536 sourceview_io_get_read_only (SourceviewIO
* sio
)
538 GFileInfo
* file_info
;
544 file_info
= g_file_query_info (sio
->file
,
545 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
,
546 G_FILE_QUERY_INFO_NONE
,
552 retval
= !g_file_info_get_attribute_boolean (file_info
,
553 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
);
554 g_object_unref (file_info
);
559 sourceview_io_new (Sourceview
* sv
)
561 SourceviewIO
* sio
= SOURCEVIEW_IO(g_object_new (SOURCEVIEW_TYPE_IO
, NULL
));