~ubuntu-branches/ubuntu/gutsy/gedit/gutsy-proposed

« back to all changes in this revision

Viewing changes to gedit/gedit-document-loader.c

  • Committer: Bazaar Package Importer
  • Author(s): Aron Sisak
  • Date: 2007-08-01 12:06:47 UTC
  • mfrom: (1.1.31 upstream)
  • Revision ID: james.westby@ubuntu.com-20070801120647-42ay4v2j0qj68gs8
Tags: 2.19.3-0ubuntu1
* New upstream release:
  - New Features and Fixes
    - Remove color settings and syntax highlighting editor from the
      preferences dialog and use a style scheme selector
    - Many improvements to the snippets plugin, notably support for importing
      and exporting snippets, support for regex snippets and support for
      activating snippets on drag'n'drop
    - Split DocumentLoader and DocumentSaver in abstract class and
      subclasses for easier maintainance
    - Add a gconf preference for smart-home-end
    - Fix external tool saving bug 
    - Adapt to latest GtkSourceView API changes
    - Misc Bugfixes
  - New and updated translations:
    - gu, ko, sv, si, zh_CN, fi, eu, et, es, it, hu, nl, ja, th, ta
* debian/patches/01_lpi.patch,
  - updated
* debian/patches/02_gtksourceview2.0.patch:
  - dropped as got fixed upstream
* debian/patches/90_autoconf.patch:
  - updated with autoconf
* debian/control.in
  - bumped gtksourceview, python-pygtksourceview versions (>= 2.19.3)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * gedit-document-loader.c
3
3
 * This file is part of gedit
4
4
 *
5
 
 * Copyright (C) 2005 - Paolo Maggi 
 
5
 * Copyright (C) 2005 - Paolo Maggi
 
6
 * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
6
7
 *
7
8
 * This program is free software; you can redistribute it and/or modify
8
9
 * it under the terms of the GNU General Public License as published by
21
22
 */
22
23
 
23
24
/*
24
 
 * Modified by the gedit Team, 2005. See the AUTHORS file for a 
25
 
 * list of people on the gedit Team.  
26
 
 * See the ChangeLog files for a list of changes. 
 
25
 * Modified by the gedit Team, 2005-2007. See the AUTHORS file for a
 
26
 * list of people on the gedit Team.
 
27
 * See the ChangeLog files for a list of changes.
27
28
 *
28
 
 * $Id: gedit-document-loader.c 5574 2007-03-13 17:40:04Z pborelli $
 
29
 * $Id: gedit-document-loader.c 5758 2007-07-29 22:28:28Z sfre $
29
30
 */
30
31
 
31
32
#ifdef HAVE_CONFIG_H
32
33
#include <config.h>
33
34
#endif
34
35
 
35
 
#include <sys/types.h>
36
 
#include <sys/stat.h>
37
 
#include <fcntl.h>
38
 
#include <sys/mman.h>
39
 
#include <signal.h>
40
 
#include <setjmp.h>
41
 
#include <string.h>
42
 
#include <errno.h>
43
 
 
44
36
#include <glib/gi18n.h>
45
 
#include <glib/gstdio.h>
46
 
#include <libgnomevfs/gnome-vfs.h>
47
37
 
48
38
#include "gedit-document-loader.h"
49
 
#include "gedit-convert.h"
50
39
#include "gedit-debug.h"
51
40
#include "gedit-metadata-manager.h"
52
41
#include "gedit-utils.h"
53
 
 
 
42
#include "gedit-convert.h"
54
43
#include "gedit-marshal.h"
55
44
 
56
 
#define READ_CHUNK_SIZE 8192
57
 
 
58
 
#define GEDIT_DOCUMENT_LOADER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
59
 
                                                  GEDIT_TYPE_DOCUMENT_LOADER,            \
60
 
                                                  GeditDocumentLoaderPrivate))
61
 
 
62
 
static void     async_close_cb (GnomeVFSAsyncHandle *handle,
63
 
                                GnomeVFSResult       result,
64
 
                                gpointer             data);
65
 
 
66
 
 
67
 
struct _GeditDocumentLoaderPrivate
68
 
{
69
 
        GeditDocument            *document;
70
 
 
71
 
        gboolean                  used;
72
 
        
73
 
        /* Info on the current file */
74
 
        gchar                    *uri;
75
 
        const GeditEncoding      *encoding;
76
 
 
77
 
        GnomeVFSURI              *vfs_uri;
78
 
 
79
 
        GnomeVFSFileInfo         *info;
80
 
        GnomeVFSFileSize          bytes_read;
81
 
 
82
 
        /* Handle for local files */
83
 
        gint                      fd;
84
 
        gchar                    *local_file_name;
85
 
        
86
 
        /* Handle for remote files */
87
 
        GnomeVFSAsyncHandle      *handle;
88
 
        GnomeVFSAsyncHandle      *info_handle;
89
 
 
90
 
        gchar                    *buffer;
91
 
 
92
 
        const GeditEncoding      *metadata_encoding;
93
 
        const GeditEncoding      *auto_detected_encoding;
94
 
 
95
 
        GError                   *error;
96
 
};
97
 
 
98
 
G_DEFINE_TYPE(GeditDocumentLoader, gedit_document_loader, G_TYPE_OBJECT)
 
45
/* Those are for the the gedit_document_loader_new() factory */
 
46
#include "gedit-mmap-document-loader.h"
 
47
#include "gedit-gnomevfs-document-loader.h"
 
48
 
 
49
G_DEFINE_ABSTRACT_TYPE(GeditDocumentLoader, gedit_document_loader, G_TYPE_OBJECT)
99
50
 
100
51
/* Signals */
101
52
 
112
63
{
113
64
        PROP_0,
114
65
        PROP_DOCUMENT,
 
66
        PROP_URI,
 
67
        PROP_ENCODING,
115
68
};
116
69
 
117
70
static void
120
73
                                    const GValue *value,
121
74
                                    GParamSpec   *pspec)
122
75
{
123
 
        GeditDocumentLoader *dl = GEDIT_DOCUMENT_LOADER (object);
 
76
        GeditDocumentLoader *loader = GEDIT_DOCUMENT_LOADER (object);
124
77
 
125
78
        switch (prop_id)
126
79
        {
127
80
                case PROP_DOCUMENT:
128
 
                        g_return_if_fail (dl->priv->document == NULL);
129
 
                        dl->priv->document = g_value_get_object (value);
 
81
                        g_return_if_fail (loader->document == NULL);
 
82
                        loader->document = g_value_get_object (value);
 
83
                        break;
 
84
                case PROP_URI:
 
85
                        g_return_if_fail (loader->uri == NULL);
 
86
                        loader->uri = g_value_dup_string (value);
 
87
                        break;
 
88
                case PROP_ENCODING:
 
89
                        g_return_if_fail (loader->encoding == NULL);
 
90
                        loader->encoding = g_value_get_boxed (value);
130
91
                        break;
131
92
                default:
132
93
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
140
101
                                    GValue     *value,
141
102
                                    GParamSpec *pspec)
142
103
{
143
 
        GeditDocumentLoader *dl = GEDIT_DOCUMENT_LOADER (object);
 
104
        GeditDocumentLoader *loader = GEDIT_DOCUMENT_LOADER (object);
144
105
 
145
106
        switch (prop_id)
146
107
        {
147
108
                case PROP_DOCUMENT:
148
 
                        g_value_set_object (value,
149
 
                                            dl->priv->document);
 
109
                        g_value_set_object (value, loader->document);
 
110
                        break;
 
111
                case PROP_URI:
 
112
                        g_value_set_string (value, loader->uri);
 
113
                        break;
 
114
                case PROP_ENCODING:
 
115
                        g_value_set_boxed (value, gedit_document_loader_get_encoding (loader));
150
116
                        break;
151
117
                default:
152
118
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
153
 
                        break;          
 
119
                        break;
154
120
        }
155
121
}
156
122
 
157
123
static void
158
124
gedit_document_loader_finalize (GObject *object)
159
125
{
160
 
        GeditDocumentLoaderPrivate *priv = GEDIT_DOCUMENT_LOADER (object)->priv;
161
 
 
162
 
        if (priv->handle != NULL)
163
 
        {               
164
 
                if (priv->info_handle != NULL)
165
 
                {
166
 
                        gnome_vfs_async_cancel (priv->info_handle);
167
 
                        gnome_vfs_async_close (priv->info_handle,
168
 
                                               async_close_cb, 
169
 
                                               NULL);
170
 
                }
171
 
 
172
 
                gnome_vfs_async_cancel (priv->handle);
173
 
                gnome_vfs_async_close (priv->handle,
174
 
                                       async_close_cb, 
175
 
                                       NULL);
176
 
        }
177
 
        
178
 
        g_free (priv->uri);
179
 
 
180
 
        if (priv->info)
181
 
                gnome_vfs_file_info_unref (priv->info);
182
 
 
183
 
 
184
 
        g_free (priv->local_file_name);
185
 
        g_free (priv->buffer);
186
 
 
187
 
        if (priv->vfs_uri)
188
 
                gnome_vfs_uri_unref (priv->vfs_uri);
189
 
 
190
 
        if (priv->error)
191
 
                g_error_free (priv->error);
 
126
        GeditDocumentLoader *loader = GEDIT_DOCUMENT_LOADER (object);
 
127
 
 
128
        g_free (loader->uri);
192
129
 
193
130
        G_OBJECT_CLASS (gedit_document_loader_parent_class)->finalize (object);
194
131
}
205
142
        g_object_class_install_property (object_class,
206
143
                                         PROP_DOCUMENT,
207
144
                                         g_param_spec_object ("document",
208
 
                                                         "Document",
209
 
                                                         "The GeditDocument this GeditDocumentLoader is associated with",
210
 
                                                         GEDIT_TYPE_DOCUMENT,
211
 
                                                         G_PARAM_READWRITE |
212
 
                                                         G_PARAM_CONSTRUCT_ONLY));
 
145
                                                              "Document",
 
146
                                                              "The GeditDocument this GeditDocumentLoader is associated with",
 
147
                                                              GEDIT_TYPE_DOCUMENT,
 
148
                                                              G_PARAM_READWRITE |
 
149
                                                              G_PARAM_CONSTRUCT_ONLY));
 
150
 
 
151
        g_object_class_install_property (object_class,
 
152
                                         PROP_URI,
 
153
                                         g_param_spec_string ("uri",
 
154
                                                              "URI",
 
155
                                                              "The URI this GeditDocumentLoader loads the document from",
 
156
                                                              "",
 
157
                                                              G_PARAM_READWRITE |
 
158
                                                              G_PARAM_CONSTRUCT_ONLY));
 
159
 
 
160
        g_object_class_install_property (object_class,
 
161
                                         PROP_ENCODING,
 
162
                                         g_param_spec_boxed ("encoding",
 
163
                                                             "Encoding",
 
164
                                                             "The encoding of the saved file",
 
165
                                                             GEDIT_TYPE_ENCODING,
 
166
                                                             G_PARAM_READWRITE |
 
167
                                                             G_PARAM_CONSTRUCT_ONLY));
213
168
 
214
169
        signals[LOADING] =
215
 
                g_signal_new ("loading",
 
170
                g_signal_new ("loading",
216
171
                              G_OBJECT_CLASS_TYPE (object_class),
217
172
                              G_SIGNAL_RUN_LAST,
218
173
                              G_STRUCT_OFFSET (GeditDocumentLoaderClass, loading),
222
177
                              2,
223
178
                              G_TYPE_BOOLEAN,
224
179
                              G_TYPE_POINTER);
225
 
 
226
 
        g_type_class_add_private (object_class, sizeof(GeditDocumentLoaderPrivate));
227
180
}
228
181
 
229
182
static void
230
183
gedit_document_loader_init (GeditDocumentLoader *loader)
231
184
{
232
 
        loader->priv = GEDIT_DOCUMENT_LOADER_GET_PRIVATE (loader);
233
 
 
234
 
        loader->priv->used = FALSE;
235
 
 
236
 
        loader->priv->fd = -1;
237
 
 
238
 
        loader->priv->error = NULL;
239
 
}
240
 
 
241
 
GeditDocumentLoader *
242
 
gedit_document_loader_new (GeditDocument *doc)
243
 
{
244
 
        GeditDocumentLoader *dl;
245
 
 
246
 
        g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
247
 
 
248
 
        dl = GEDIT_DOCUMENT_LOADER (g_object_new (GEDIT_TYPE_DOCUMENT_LOADER, 
249
 
                                                  "document", doc,
250
 
                                                  NULL));
251
 
 
252
 
        return dl;                                                
253
 
}
254
 
 
255
 
static const GeditEncoding *
256
 
get_metadata_encoding (const gchar *uri)
257
 
{
258
 
        const GeditEncoding *enc;
259
 
        gchar *charset;
260
 
 
261
 
        charset = gedit_metadata_manager_get (uri, "encoding");
262
 
 
263
 
        if (charset == NULL)
264
 
                return NULL;
265
 
 
266
 
        enc = gedit_encoding_get_from_charset (charset);
267
 
 
268
 
        g_free (charset);
269
 
 
270
 
        return enc;
 
185
        loader->used = FALSE;
271
186
}
272
187
 
273
188
static void
275
190
                         const gchar         *text,
276
191
                         gint                 len)
277
192
{
 
193
        GeditDocument *doc = loader->document;
 
194
 
278
195
        g_return_if_fail (text != NULL);
279
196
 
280
 
        gtk_source_buffer_begin_not_undoable_action (
281
 
                                GTK_SOURCE_BUFFER (loader->priv->document));
 
197
        gtk_source_buffer_begin_not_undoable_action (GTK_SOURCE_BUFFER (doc));
282
198
 
283
 
        /* If the last char is a newline, don't add it to the buffer
284
 
        (otherwise GtkTextView shows it as an empty line). See bug #324942. */
 
199
        /* If the last char is a newline, don't add it to the buffer (otherwise
 
200
           GtkTextView shows it as an empty line). See bug #324942. */
285
201
        if ((len > 0) && (text[len-1] == '\n'))
286
202
                len--;
287
203
 
288
204
        /* Insert text in the buffer */
289
 
        gtk_text_buffer_set_text (GTK_TEXT_BUFFER (loader->priv->document), 
290
 
                                  text, 
291
 
                                  len);
292
 
 
293
 
        gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (loader->priv->document),
294
 
                                      FALSE);
295
 
 
296
 
        gtk_source_buffer_end_not_undoable_action (
297
 
                                GTK_SOURCE_BUFFER (loader->priv->document));
 
205
        gtk_text_buffer_set_text (GTK_TEXT_BUFFER (doc), text, len);
 
206
 
 
207
        gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), FALSE);
 
208
 
 
209
        gtk_source_buffer_end_not_undoable_action (GTK_SOURCE_BUFFER (doc));
298
210
}
299
211
 
300
 
static gboolean
301
 
update_document_contents (GeditDocumentLoader  *loader, 
302
 
                          const gchar          *file_contents,
303
 
                          gint                  file_size,
304
 
                          GError              **error)
 
212
/* This function is only meant to be called by child classes */
 
213
gboolean
 
214
gedit_document_loader_update_document_contents (GeditDocumentLoader  *loader,
 
215
                                                const gchar          *file_contents,
 
216
                                                gint                  file_size,
 
217
                                                GError              **error)
305
218
{
306
219
        gedit_debug (DEBUG_LOADER);
307
220
 
308
221
        g_return_val_if_fail (file_size > 0, FALSE);
309
222
        g_return_val_if_fail (file_contents != NULL, FALSE);
310
223
 
311
 
        if (loader->priv->encoding == gedit_encoding_get_utf8 ())
 
224
        /* short-circuit the case where the file is empty */
 
225
        if (file_size == 0)
 
226
        {
 
227
                if (loader->encoding == NULL)
 
228
                        loader->auto_detected_encoding = gedit_encoding_get_current ();
 
229
                insert_text_in_document (loader, "", 0);
 
230
                return TRUE;
 
231
        }
 
232
 
 
233
        if (loader->encoding == gedit_encoding_get_utf8 ())
312
234
        {
313
235
                if (g_utf8_validate (file_contents, file_size, NULL))
314
236
                {
315
237
                        insert_text_in_document (loader,
316
238
                                                 file_contents,
317
239
                                                 file_size);
318
 
                        
319
240
                        return TRUE;
320
241
                }
321
242
                else
322
243
                {
323
244
                        g_set_error (error,
324
 
                                     G_CONVERT_ERROR, 
 
245
                                     G_CONVERT_ERROR,
325
246
                                     G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
326
247
                                     "The file you are trying to open contains an invalid byte sequence.");
327
 
                                     
328
248
                        return FALSE;
329
249
                }
330
250
        }
334
254
                gchar *converted_text = NULL;
335
255
                gsize new_len = file_size;
336
256
 
337
 
                if (loader->priv->encoding == NULL)
 
257
                if (loader->encoding == NULL)
338
258
                {
339
259
                        /* Autodetecting the encoding: first try with the encoding
340
260
                        stored in the metadata, if any */
341
261
 
342
 
                        if (loader->priv->metadata_encoding != NULL)
 
262
                        if (loader->metadata_encoding != NULL)
343
263
                        {
344
264
                                converted_text = gedit_convert_to_utf8 (
345
265
                                                                file_contents,
346
266
                                                                file_size,
347
 
                                                                &loader->priv->metadata_encoding,
 
267
                                                                &loader->metadata_encoding,
348
268
                                                                &new_len,
349
269
                                                                NULL);
350
270
 
351
271
                                if (converted_text != NULL)
352
 
                                        loader->priv->auto_detected_encoding = loader->priv->metadata_encoding;
 
272
                                        loader->auto_detected_encoding = loader->metadata_encoding;
353
273
                        }
354
274
                }
355
275
 
356
 
                if (converted_text == NULL)                             
 
276
                if (converted_text == NULL)
357
277
                {
358
 
                        loader->priv->auto_detected_encoding = loader->priv->encoding;
 
278
                        loader->auto_detected_encoding = loader->encoding;
359
279
 
360
280
                        converted_text = gedit_convert_to_utf8 (
361
281
                                                        file_contents,
362
282
                                                        file_size,
363
 
                                                        &loader->priv->auto_detected_encoding,
 
283
                                                        &loader->auto_detected_encoding,
364
284
                                                        &new_len,
365
285
                                                        &conv_error);
366
286
                }
370
290
                        g_return_val_if_fail (conv_error != NULL, FALSE);
371
291
 
372
292
                        g_propagate_error (error, conv_error);
373
 
        
 
293
 
374
294
                        return FALSE;
375
295
                }
376
296
                else
388
308
        g_return_val_if_reached (FALSE);
389
309
}
390
310
 
391
 
/* The following function has been copied from gnome-vfs 
392
 
   (modules/file-method.c) file */
393
 
static void
394
 
get_access_info (GnomeVFSFileInfo *file_info,
395
 
                 const gchar *full_name)
396
 
{
397
 
        /* FIXME: should check errno after calling access because we don't
398
 
         * want to set valid_fields if something bad happened during one
399
 
         * of the access calls
400
 
         */
401
 
        if (g_access (full_name, W_OK) == 0) 
402
 
                file_info->permissions |= GNOME_VFS_PERM_ACCESS_WRITABLE;
403
 
                
404
 
        /*      
405
 
         * We don't need to know if a local file is readable or 
406
 
         * executable so I have commented the followig code to avoid 
407
 
         * multiple g_access calls - Paolo (Oct. 18, 2005) 
408
 
         */
409
 
 
410
 
        /*       
411
 
         *      if (g_access (full_name, R_OK) == 0) 
412
 
         *              file_info->permissions |= GNOME_VFS_PERM_ACCESS_READABLE;
413
 
         *
414
 
         * #ifdef G_OS_WIN32
415
 
         *      if (g_file_test (full_name, G_FILE_TEST_IS_EXECUTABLE))
416
 
         *              file_info->permissions |= GNOME_VFS_PERM_ACCESS_EXECUTABLE;
417
 
         * #else 
418
 
         *      if (g_access (full_name, X_OK) == 0)
419
 
         *              file_info->permissions |= GNOME_VFS_PERM_ACCESS_EXECUTABLE;
420
 
         * #endif 
421
 
         */
422
 
 
423
 
        file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ACCESS;
424
 
}
425
 
 
426
 
/* The following function has been copied from gnome-vfs 
427
 
   (gnome-vfs-module-shared.c) file */
428
 
static void
429
 
stat_to_file_info (GnomeVFSFileInfo *file_info,
430
 
                   const struct stat *statptr)
431
 
{
432
 
        if (S_ISDIR (statptr->st_mode))
433
 
                file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
434
 
        else if (S_ISCHR (statptr->st_mode))
435
 
                file_info->type = GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE;
436
 
        else if (S_ISBLK (statptr->st_mode))
437
 
                file_info->type = GNOME_VFS_FILE_TYPE_BLOCK_DEVICE;
438
 
        else if (S_ISFIFO (statptr->st_mode))
439
 
                file_info->type = GNOME_VFS_FILE_TYPE_FIFO;
440
 
        else if (S_ISSOCK (statptr->st_mode))
441
 
                file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
442
 
        else if (S_ISREG (statptr->st_mode))
443
 
                file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
444
 
        else if (S_ISLNK (statptr->st_mode))
445
 
                file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK;
446
 
        else
447
 
                file_info->type = GNOME_VFS_FILE_TYPE_UNKNOWN;
448
 
 
449
 
        file_info->permissions
450
 
                = statptr->st_mode & (GNOME_VFS_PERM_USER_ALL
451
 
                                      | GNOME_VFS_PERM_GROUP_ALL
452
 
                                      | GNOME_VFS_PERM_OTHER_ALL
453
 
                                      | GNOME_VFS_PERM_SUID
454
 
                                      | GNOME_VFS_PERM_SGID
455
 
                                      | GNOME_VFS_PERM_STICKY);
456
 
 
457
 
        file_info->device = statptr->st_dev;
458
 
        file_info->inode = statptr->st_ino;
459
 
 
460
 
        file_info->link_count = statptr->st_nlink;
461
 
 
462
 
        file_info->uid = statptr->st_uid;
463
 
        file_info->gid = statptr->st_gid;
464
 
 
465
 
        file_info->size = statptr->st_size;
466
 
        file_info->block_count = statptr->st_blocks;
467
 
        file_info->io_block_size = statptr->st_blksize;
468
 
        if (file_info->io_block_size > 0 &&
469
 
            file_info->io_block_size < 4096) {
470
 
                /* Never use smaller block than 4k,
471
 
                   should probably be pagesize.. */
472
 
                file_info->io_block_size = 4096;
473
 
        }
474
 
 
475
 
        file_info->atime = statptr->st_atime;
476
 
        file_info->ctime = statptr->st_ctime;
477
 
        file_info->mtime = statptr->st_mtime;
478
 
 
479
 
        file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE |
480
 
          GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | GNOME_VFS_FILE_INFO_FIELDS_FLAGS |
481
 
          GNOME_VFS_FILE_INFO_FIELDS_DEVICE | GNOME_VFS_FILE_INFO_FIELDS_INODE |
482
 
          GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | GNOME_VFS_FILE_INFO_FIELDS_SIZE |
483
 
          GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT | GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE |
484
 
          GNOME_VFS_FILE_INFO_FIELDS_ATIME | GNOME_VFS_FILE_INFO_FIELDS_MTIME |
485
 
          GNOME_VFS_FILE_INFO_FIELDS_CTIME;
486
 
}
487
 
 
488
 
static void
489
 
load_completed_or_failed (GeditDocumentLoader *loader)
490
 
{
491
 
        /* the object will be unrefed in the callback of the loading
492
 
         * signal, so we need to prevent finalization.
493
 
         */
494
 
        g_object_ref (loader);
495
 
        
496
 
        g_signal_emit (loader, 
497
 
                       signals[LOADING],
498
 
                       0,
499
 
                       TRUE, /* completed */
500
 
                       loader->priv->error);
501
 
 
502
 
        if (loader->priv->error == NULL)
503
 
                gedit_debug_message (DEBUG_LOADER, "load completed");
504
 
        else
505
 
                gedit_debug_message (DEBUG_LOADER, "load failed");
506
 
 
507
 
        g_object_unref (loader);                       
508
 
}
509
 
 
510
 
/* ----------- local files ----------- */
511
 
 
512
 
#define MAX_MIME_SNIFF_SIZE 4096
513
 
 
514
 
static sigjmp_buf mmap_env;
515
 
static struct sigaction old_sigbusact;
516
 
 
517
 
/* When we access the mmapped data we need to handle
518
 
 * SIGBUS signal, which is emitted if there was an
519
 
 * I/O error or if the file was truncated */
520
 
static void
521
 
mmap_sigbus_handler (int signo)
522
 
{
523
 
        siglongjmp (mmap_env, 0);
524
 
}
525
 
 
526
 
static gboolean
527
 
load_local_file_real (GeditDocumentLoader *loader)
528
 
{
529
 
        struct stat statbuf;
530
 
        GnomeVFSResult result;
531
 
        gint ret;
532
 
 
533
 
        g_return_val_if_fail (loader->priv->fd != -1, FALSE);
534
 
 
535
 
        if (fstat (loader->priv->fd, &statbuf) != 0) 
536
 
        {
537
 
                result = gnome_vfs_result_from_errno ();
538
 
 
539
 
                g_set_error (&loader->priv->error,
540
 
                             GEDIT_DOCUMENT_ERROR,
541
 
                             result,
542
 
                             gnome_vfs_result_to_string (result));
543
 
 
544
 
                goto done;
545
 
        }
546
 
 
547
 
        /* not a regular file */
548
 
        if (!S_ISREG (statbuf.st_mode))
549
 
        {
550
 
                if (S_ISDIR (statbuf.st_mode))
551
 
                {
552
 
                        g_set_error (&loader->priv->error,
553
 
                                     GEDIT_DOCUMENT_ERROR,
554
 
                                     GNOME_VFS_ERROR_IS_DIRECTORY,
555
 
                                     gnome_vfs_result_to_string (GNOME_VFS_ERROR_IS_DIRECTORY));
556
 
                }
557
 
                else
558
 
                {
559
 
                        g_set_error (&loader->priv->error,
560
 
                                     GEDIT_DOCUMENT_ERROR,
561
 
                                     GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE,
562
 
                                     "Not a regular file");
563
 
                }
564
 
 
565
 
                goto done;
566
 
        }
567
 
 
568
 
        loader->priv->info = gnome_vfs_file_info_new ();
569
 
        stat_to_file_info (loader->priv->info, &statbuf);
570
 
        GNOME_VFS_FILE_INFO_SET_LOCAL (loader->priv->info, TRUE);
571
 
        get_access_info (loader->priv->info, loader->priv->local_file_name);
572
 
        
573
 
        if (loader->priv->info->size == 0)
574
 
        {
575
 
                if (loader->priv->encoding == NULL)
576
 
                        loader->priv->auto_detected_encoding = gedit_encoding_get_current ();
577
 
 
578
 
                /* clear the contents in case we are reverting */
579
 
                insert_text_in_document (loader, "", 0);
580
 
 
581
 
                /* guessing the mime from the filename is up to the caller */
582
 
        }
583
 
        else
584
 
        {
585
 
                gchar *mapped_file;
586
 
                const gchar *mime_type;
587
 
                struct sigaction sigbusact;
588
 
 
589
 
                /* CHECK: should we lock the file */            
590
 
                mapped_file = mmap (0, /* start */
591
 
                                    loader->priv->info->size, 
592
 
                                    PROT_READ,
593
 
                                    MAP_PRIVATE, /* flags */
594
 
                                    loader->priv->fd,
595
 
                                    0 /* offset */);
596
 
 
597
 
                if (mapped_file == MAP_FAILED)
598
 
                {
599
 
                        gedit_debug_message (DEBUG_LOADER, "mmap failed");
600
 
 
601
 
                        result = gnome_vfs_result_from_errno ();
602
 
 
603
 
                        g_set_error (&loader->priv->error,
604
 
                                     GEDIT_DOCUMENT_ERROR,
605
 
                                     result,
606
 
                                     gnome_vfs_result_to_string (result));
607
 
 
608
 
                        goto done;
609
 
                }
610
 
 
611
 
                /* prepare to handle the SIGBUS signal which
612
 
                 * may be fired when accessing the mmapped
613
 
                 * data in case of I/O error.
614
 
                 * See bug #354046.
615
 
                 */
616
 
                sigbusact.sa_handler = mmap_sigbus_handler;
617
 
                sigemptyset (&sigbusact.sa_mask);
618
 
                sigbusact.sa_flags = SA_RESETHAND;
619
 
                sigaction (SIGBUS, &sigbusact, &old_sigbusact );
620
 
 
621
 
                if (sigsetjmp (mmap_env, 1) != 0)
622
 
                {
623
 
                        gedit_debug_message (DEBUG_LOADER, "SIGBUS during mmap");
624
 
 
625
 
                        g_set_error (&loader->priv->error,
626
 
                                     GEDIT_DOCUMENT_ERROR,
627
 
                                     GNOME_VFS_ERROR_IO,
628
 
                                     gnome_vfs_result_to_string (GNOME_VFS_ERROR_IO));
629
 
 
630
 
                        ret = munmap (mapped_file, loader->priv->info->size);
631
 
                        if (ret != 0)
632
 
                                g_warning ("File '%s' has not been correctly unmapped: %s",
633
 
                                           loader->priv->uri,
634
 
                                           strerror (errno));
635
 
 
636
 
                        goto done;
637
 
                }
638
 
 
639
 
                loader->priv->bytes_read = loader->priv->info->size;
640
 
 
641
 
                if (!update_document_contents (loader,
642
 
                                               mapped_file,
643
 
                                               loader->priv->info->size,
644
 
                                               &loader->priv->error))
645
 
                {
646
 
                        ret = munmap (mapped_file, loader->priv->info->size);
647
 
                        if (ret != 0)
648
 
                                g_warning ("File '%s' has not been correctly unmapped: %s",
649
 
                                           loader->priv->uri,
650
 
                                           strerror (errno));
651
 
 
652
 
                        goto done;
653
 
                }
654
 
 
655
 
                /* restore the default sigbus handler */
656
 
                sigaction (SIGBUS, &old_sigbusact, 0);
657
 
 
658
 
                mime_type = gnome_vfs_get_mime_type_for_name_and_data (loader->priv->local_file_name,
659
 
                                mapped_file,
660
 
                                MIN (loader->priv->bytes_read, MAX_MIME_SNIFF_SIZE));
661
 
 
662
 
                if ((mime_type != NULL) &&
663
 
                     strcmp (mime_type, GNOME_VFS_MIME_TYPE_UNKNOWN) != 0)
664
 
                {
665
 
                        loader->priv->info->mime_type = g_strdup (mime_type);
666
 
                        loader->priv->info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
667
 
                }
668
 
 
669
 
                ret = munmap (mapped_file, loader->priv->info->size);
670
 
 
671
 
                if (ret != 0)
672
 
                        g_warning ("File '%s' has not been correctly unmapped: %s",
673
 
                                   loader->priv->uri,
674
 
                                   strerror (errno));
675
 
        }
676
 
 
677
 
 done:
678
 
        ret = close (loader->priv->fd);
679
 
 
680
 
        if (ret != 0)
681
 
                g_warning ("File '%s' has not been correctly closed: %s",
682
 
                           loader->priv->uri,
683
 
                           strerror (errno));
684
 
 
685
 
        loader->priv->fd = -1;
686
 
 
687
 
        load_completed_or_failed (loader);
688
 
        
689
 
        return FALSE;
690
 
}
691
 
 
692
 
static gboolean
693
 
open_local_failed (GeditDocumentLoader *loader)
694
 
{
695
 
        load_completed_or_failed (loader);
696
 
 
697
 
        /* stop the timeout */
698
 
        return FALSE;
699
 
}
700
 
 
701
 
static void
702
 
load_local_file (GeditDocumentLoader *loader,
703
 
                 const gchar         *fname)
704
 
{
705
 
        gedit_debug (DEBUG_LOADER);
706
 
 
707
 
        g_signal_emit (loader,
708
 
                       signals[LOADING],
709
 
                       0,
710
 
                       FALSE,
711
 
                       NULL);
712
 
 
713
 
        loader->priv->fd = open (fname, O_RDONLY);
714
 
        if (loader->priv->fd == -1)
715
 
        {
716
 
                GnomeVFSResult result = gnome_vfs_result_from_errno ();
717
 
 
718
 
                g_set_error (&loader->priv->error,
719
 
                             GEDIT_DOCUMENT_ERROR,
720
 
                             result,
721
 
                             gnome_vfs_result_to_string (result));
722
 
 
723
 
                g_timeout_add_full (G_PRIORITY_HIGH,
724
 
                                    0,
725
 
                                    (GSourceFunc) open_local_failed,
726
 
                                    loader,
727
 
                                    NULL);
728
 
                                    
729
 
                return;                     
730
 
        }
731
 
 
732
 
        g_free (loader->priv->local_file_name);
733
 
        loader->priv->local_file_name = g_strdup (fname);
734
 
 
735
 
        g_timeout_add_full (G_PRIORITY_HIGH,
736
 
                            0,
737
 
                            (GSourceFunc) load_local_file_real,
738
 
                            loader,
739
 
                            NULL);
740
 
}
741
 
 
742
 
/* ----------- remote files ----------- */
743
 
 
744
 
static void
745
 
async_close_cb (GnomeVFSAsyncHandle *handle,
746
 
                GnomeVFSResult       result,
747
 
                gpointer             data)
748
 
{
749
 
        /* nothing to do... no point in reporting an error */
750
 
}
751
 
 
752
 
static void
753
 
remote_load_completed_or_failed (GeditDocumentLoader *loader)
754
 
{
755
 
        /* free the buffer and close the handle */
756
 
        gnome_vfs_async_close (loader->priv->handle,
757
 
                               async_close_cb,
758
 
                               NULL);
759
 
                               
760
 
        loader->priv->handle = NULL;
761
 
 
762
 
        g_free (loader->priv->buffer);
763
 
        loader->priv->buffer = NULL;
764
 
 
765
 
        load_completed_or_failed (loader);
766
 
}
767
 
 
768
 
/* prototype, because they call each other... isn't C lovely */
769
 
static void     read_file_chunk         (GeditDocumentLoader *loader);
770
 
 
771
 
static void
772
 
async_read_cb (GnomeVFSAsyncHandle *handle,
773
 
               GnomeVFSResult       result,
774
 
               gpointer             buffer,
775
 
               GnomeVFSFileSize     bytes_requested,
776
 
               GnomeVFSFileSize     bytes_read,
777
 
               gpointer             data)
778
 
{
779
 
        GeditDocumentLoader *loader = GEDIT_DOCUMENT_LOADER (data);
780
 
 
781
 
        gedit_debug (DEBUG_LOADER);
782
 
 
783
 
        /* reality checks. */
784
 
        g_return_if_fail (bytes_requested == READ_CHUNK_SIZE);
785
 
        g_return_if_fail (loader->priv->handle == handle);
786
 
        g_return_if_fail (loader->priv->buffer + loader->priv->bytes_read == buffer);
787
 
        g_return_if_fail (bytes_read <= bytes_requested);
788
 
 
789
 
        /* error occurred */
790
 
        if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF)
791
 
        {
792
 
                g_set_error (&loader->priv->error,
793
 
                             GEDIT_DOCUMENT_ERROR,
794
 
                             result,
795
 
                             gnome_vfs_result_to_string (result));
796
 
 
797
 
                remote_load_completed_or_failed (loader);
798
 
 
799
 
                return;
800
 
        }
801
 
 
802
 
        /* Check for the extremely unlikely case where the file size overflows. */
803
 
        if (loader->priv->bytes_read + bytes_read < loader->priv->bytes_read)
804
 
        {
805
 
                g_set_error (&loader->priv->error,
806
 
                             GEDIT_DOCUMENT_ERROR,
807
 
                             GNOME_VFS_ERROR_TOO_BIG,
808
 
                             gnome_vfs_result_to_string (GNOME_VFS_ERROR_TOO_BIG));
809
 
 
810
 
                remote_load_completed_or_failed (loader);
811
 
 
812
 
                return;
813
 
        }
814
 
 
815
 
        /* Bump the size. */
816
 
        loader->priv->bytes_read += bytes_read;
817
 
 
818
 
        /* end of the file, we are done! */
819
 
        if (bytes_read == 0 || result != GNOME_VFS_OK)
820
 
        {
821
 
                if (loader->priv->bytes_read == 0)
822
 
                {
823
 
                        if (loader->priv->encoding == NULL)
824
 
                                loader->priv->auto_detected_encoding = gedit_encoding_get_current ();
825
 
                }
826
 
                else
827
 
                {
828
 
                        update_document_contents (loader,
829
 
                                                  loader->priv->buffer,
830
 
                                                  loader->priv->bytes_read,
831
 
                                                  &loader->priv->error);
832
 
                }
833
 
 
834
 
                remote_load_completed_or_failed (loader);
835
 
 
836
 
                return;
837
 
        }
838
 
 
839
 
        /* otherwise emit progress and read some more */
840
 
 
841
 
        /* note that this signal blocks the read... check if it isn't
842
 
         * a performance problem
843
 
         */
844
 
        g_signal_emit (loader,
845
 
                       signals[LOADING],
846
 
                       0,
847
 
                       FALSE,
848
 
                       NULL);
849
 
 
850
 
        read_file_chunk (loader);
851
 
}
852
 
 
853
 
static void
854
 
read_file_chunk (GeditDocumentLoader *loader)
855
 
{
856
 
        loader->priv->buffer = g_realloc (loader->priv->buffer,
857
 
                                          loader->priv->bytes_read + READ_CHUNK_SIZE);
858
 
 
859
 
        gnome_vfs_async_read (loader->priv->handle,
860
 
                              loader->priv->buffer + loader->priv->bytes_read,
861
 
                              READ_CHUNK_SIZE,
862
 
                              async_read_cb,
863
 
                              loader);
864
 
}
865
 
 
866
 
static void
867
 
remote_get_info_cb (GnomeVFSAsyncHandle *handle,
868
 
                    GList               *results,
869
 
                    gpointer             data)
870
 
{
871
 
        GeditDocumentLoader *loader = GEDIT_DOCUMENT_LOADER (data);
872
 
        GnomeVFSGetFileInfoResult *info_result;
873
 
 
874
 
        gedit_debug (DEBUG_LOADER);
875
 
 
876
 
        /* assert that the list has one and only one item */
877
 
        g_return_if_fail (results != NULL && results->next == NULL);
878
 
 
879
 
        loader->priv->info_handle = NULL;
880
 
        
881
 
        info_result = (GnomeVFSGetFileInfoResult *) results->data;
882
 
        g_return_if_fail (info_result != NULL);
883
 
 
884
 
        if (info_result->result != GNOME_VFS_OK)
885
 
        {
886
 
                g_set_error (&loader->priv->error,
887
 
                             GEDIT_DOCUMENT_ERROR,
888
 
                             info_result->result,
889
 
                             gnome_vfs_result_to_string (info_result->result));
890
 
 
891
 
                remote_load_completed_or_failed (loader);
892
 
 
893
 
                return;
894
 
        }
895
 
 
896
 
        /* CHECK: ref is necessary, right? or the info will go away... */
897
 
        loader->priv->info = info_result->file_info;
898
 
        gnome_vfs_file_info_ref (loader->priv->info);
899
 
 
900
 
        /* if it's not a regular file, error out... */
901
 
        if (info_result->file_info->type != GNOME_VFS_FILE_TYPE_REGULAR)
902
 
        {
903
 
                g_set_error (&loader->priv->error,
904
 
                             GEDIT_DOCUMENT_ERROR,
905
 
                             GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE,
906
 
                             "Not a regular file");
907
 
 
908
 
                remote_load_completed_or_failed (loader);
909
 
 
910
 
                return;
911
 
        }
912
 
 
913
 
        /* start reading */
914
 
        read_file_chunk (loader);
915
 
}
916
 
 
917
 
static void
918
 
async_open_callback (GnomeVFSAsyncHandle *handle,
919
 
                     GnomeVFSResult       result,
920
 
                     GeditDocumentLoader *loader)
921
 
{
922
 
        GList *uri_list = NULL;
923
 
 
924
 
        gedit_debug (DEBUG_LOADER);
925
 
 
926
 
        g_return_if_fail (loader->priv->handle == handle);
927
 
 
928
 
        if (result != GNOME_VFS_OK)
929
 
        {
930
 
                g_set_error (&loader->priv->error,
931
 
                             GEDIT_DOCUMENT_ERROR,
932
 
                             result,
933
 
                             gnome_vfs_result_to_string (result));
934
 
 
935
 
                /* in this case we don't need to close the handle */
936
 
                load_completed_or_failed (loader);
937
 
 
938
 
                return;
939
 
        }
940
 
 
941
 
        /* get the file info after open to avoid races... this really
942
 
         * should be async_get_file_info_from_handle (fstat equivalent)
943
 
         * but gnome-vfs lacks that.
944
 
         */
945
 
 
946
 
        uri_list = g_list_prepend (uri_list, loader->priv->vfs_uri);
947
 
 
948
 
        gnome_vfs_async_get_file_info (&loader->priv->info_handle,
949
 
                                       uri_list,
950
 
                                       GNOME_VFS_FILE_INFO_DEFAULT |
951
 
                                       GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
952
 
                                       GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE |
953
 
                                       GNOME_VFS_FILE_INFO_FOLLOW_LINKS,
954
 
                                       GNOME_VFS_PRIORITY_MAX,
955
 
                                       remote_get_info_cb,
956
 
                                       loader);
957
 
 
958
 
        g_list_free (uri_list);
959
 
}
960
 
 
961
 
static void
962
 
load_remote_file (GeditDocumentLoader *loader)
963
 
{
964
 
        gedit_debug (DEBUG_LOADER);
965
 
 
966
 
        g_return_if_fail (loader->priv->handle == NULL);
967
 
 
968
 
        /* loading start */
969
 
        g_signal_emit (loader,
970
 
                       signals[LOADING],
971
 
                       0,
972
 
                       FALSE,
973
 
                       NULL);
974
 
 
975
 
        gnome_vfs_async_open_uri (&loader->priv->handle,
976
 
                                  loader->priv->vfs_uri,
977
 
                                  GNOME_VFS_OPEN_READ,
978
 
                                  GNOME_VFS_PRIORITY_MAX,
979
 
                                  (GnomeVFSAsyncOpenCallback) async_open_callback,
980
 
                                  loader);
981
 
}
982
 
 
983
 
/* ---------- public api ---------- */
984
 
 
985
 
static gboolean
986
 
vfs_uri_new_failed (GeditDocumentLoader *loader)
987
 
{
988
 
        load_completed_or_failed (loader);
989
 
 
990
 
        /* stop the timeout */
991
 
        return FALSE;
 
311
void
 
312
gedit_document_loader_loading (GeditDocumentLoader *loader,
 
313
                               gboolean             completed,
 
314
                               GError              *error)
 
315
{
 
316
        /* the object will be unrefed in the callback of the loading signal
 
317
         * (when completed == TRUE), so we need to prevent finalization.
 
318
         */
 
319
        if (completed)
 
320
        {
 
321
                g_object_ref (loader);
 
322
        }
 
323
 
 
324
        g_signal_emit (loader, signals[LOADING], 0, completed, error);
 
325
 
 
326
        if (completed)
 
327
        {
 
328
                if (error == NULL)
 
329
                        gedit_debug_message (DEBUG_LOADER, "load completed");
 
330
                else
 
331
                        gedit_debug_message (DEBUG_LOADER, "load failed");
 
332
 
 
333
                g_object_unref (loader);
 
334
        }
 
335
}
 
336
 
 
337
static const GeditEncoding *
 
338
get_metadata_encoding (const gchar *uri)
 
339
{
 
340
        const GeditEncoding *enc;
 
341
        gchar *charset;
 
342
 
 
343
        charset = gedit_metadata_manager_get (uri, "encoding");
 
344
 
 
345
        if (charset == NULL)
 
346
                return NULL;
 
347
 
 
348
        enc = gedit_encoding_get_from_charset (charset);
 
349
 
 
350
        g_free (charset);
 
351
 
 
352
        return enc;
 
353
}
 
354
 
 
355
GeditDocumentLoader *
 
356
gedit_document_loader_new (GeditDocument       *doc,
 
357
                           const gchar         *uri,
 
358
                           const GeditEncoding *encoding)
 
359
{
 
360
        GeditDocumentLoader *loader;
 
361
        GType loader_type;
 
362
 
 
363
        g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
 
364
 
 
365
        if (gedit_utils_uri_has_file_scheme (uri))
 
366
                loader_type = GEDIT_TYPE_MMAP_DOCUMENT_LOADER;
 
367
        else
 
368
                loader_type = GEDIT_TYPE_GNOMEVFS_DOCUMENT_LOADER;
 
369
 
 
370
        loader = GEDIT_DOCUMENT_LOADER (g_object_new (loader_type,
 
371
                                                      "document", doc,
 
372
                                                      "uri", uri,
 
373
                                                      "encoding", encoding,
 
374
                                                      NULL));
 
375
 
 
376
        return loader;
992
377
}
993
378
 
994
379
/* If enconding == NULL, the encoding will be autodetected */
995
380
void
996
 
gedit_document_loader_load (GeditDocumentLoader *loader,
997
 
                            const gchar         *uri,
998
 
                            const GeditEncoding *encoding)
 
381
gedit_document_loader_load (GeditDocumentLoader *loader)
999
382
{
1000
 
        gchar *local_path;
1001
 
 
1002
383
        gedit_debug (DEBUG_LOADER);
1003
384
 
1004
385
        g_return_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader));
1005
 
        g_return_if_fail (uri != NULL);
1006
386
 
1007
387
        /* the loader can be used just once, then it must be thrown away */
1008
 
        g_return_if_fail (loader->priv->used == FALSE);
1009
 
        loader->priv->used = TRUE;
1010
 
 
1011
 
        /* vfs_uri may be NULL for some valid but unsupported uris */
1012
 
        loader->priv->vfs_uri = gnome_vfs_uri_new (uri);
1013
 
        if (loader->priv->vfs_uri == NULL)
1014
 
        {
1015
 
                g_set_error (&loader->priv->error,
1016
 
                             GEDIT_DOCUMENT_ERROR,
1017
 
                             GNOME_VFS_ERROR_NOT_SUPPORTED,
1018
 
                             gnome_vfs_result_to_string (GNOME_VFS_ERROR_NOT_SUPPORTED));
1019
 
 
1020
 
                g_timeout_add_full (G_PRIORITY_HIGH,
1021
 
                                    0,
1022
 
                                    (GSourceFunc) vfs_uri_new_failed,
1023
 
                                    loader,
1024
 
                                    NULL);
1025
 
 
1026
 
                return;
1027
 
        }
1028
 
 
1029
 
        loader->priv->encoding = encoding;
1030
 
 
1031
 
        if (encoding == NULL)
1032
 
        {
1033
 
                loader->priv->metadata_encoding = get_metadata_encoding (uri);
1034
 
        }
1035
 
 
1036
 
        loader->priv->uri = g_strdup (uri);
1037
 
 
1038
 
        local_path = gnome_vfs_get_local_path_from_uri (uri);
1039
 
        if (local_path != NULL)
1040
 
        {
1041
 
                load_local_file (loader, local_path);
1042
 
                g_free (local_path);
1043
 
        }
1044
 
        else
1045
 
        {
1046
 
                load_remote_file (loader);
1047
 
        }
 
388
        g_return_if_fail (loader->used == FALSE);
 
389
        loader->used = TRUE;
 
390
 
 
391
        if (loader->encoding == NULL)
 
392
                loader->metadata_encoding = get_metadata_encoding (loader->uri);
 
393
 
 
394
        GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->load (loader);
 
395
}
 
396
 
 
397
gboolean 
 
398
gedit_document_loader_cancel (GeditDocumentLoader *loader)
 
399
{
 
400
        gedit_debug (DEBUG_LOADER);
 
401
 
 
402
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), FALSE);
 
403
 
 
404
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->cancel (loader);
1048
405
}
1049
406
 
1050
407
/* Returns STDIN_URI if loading from stdin */
1053
410
{
1054
411
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), NULL);
1055
412
 
1056
 
        return loader->priv->uri;
 
413
        return loader->uri;
1057
414
}
1058
415
 
1059
416
/* it may return NULL, it's up to gedit-document handle it */
1062
419
{
1063
420
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), NULL);
1064
421
 
1065
 
        if (loader->priv->info &&
1066
 
            (loader->priv->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE))
1067
 
                return loader->priv->info->mime_type;
1068
 
        else
1069
 
                return NULL;
 
422
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_mime_type (loader);
1070
423
}
1071
424
 
1072
425
time_t
1074
427
{
1075
428
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), 0);
1076
429
 
1077
 
        if (loader->priv->info &&
1078
 
            (loader->priv->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME))
1079
 
                return loader->priv->info->mtime;
1080
 
        else
1081
 
                return 0;
 
430
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_mtime (loader);
1082
431
}
1083
432
 
1084
433
/* Returns 0 if file size is unknown */
1087
436
{
1088
437
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), 0);
1089
438
 
1090
 
        if (loader->priv->info == NULL)
1091
 
                return 0;
1092
 
 
1093
 
        return loader->priv->info->size;
1094
 
}                                                                        
 
439
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_file_size (loader);
 
440
}
1095
441
 
1096
442
GnomeVFSFileSize
1097
443
gedit_document_loader_get_bytes_read (GeditDocumentLoader *loader)
1098
444
{
1099
445
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), 0);
1100
446
 
1101
 
        return loader->priv->bytes_read;
1102
 
}
1103
 
 
1104
 
gboolean 
1105
 
gedit_document_loader_cancel (GeditDocumentLoader *loader)
1106
 
{
1107
 
        gedit_debug (DEBUG_LOADER);
1108
 
 
1109
 
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), FALSE);
1110
 
 
1111
 
        if (loader->priv->handle == NULL)
1112
 
                return FALSE;
1113
 
 
1114
 
        if (loader->priv->info_handle != NULL)
1115
 
        {
1116
 
                gnome_vfs_async_cancel (loader->priv->info_handle);
1117
 
                gnome_vfs_async_close (loader->priv->info_handle,
1118
 
                                       async_close_cb, 
1119
 
                                       NULL);
1120
 
        }
1121
 
 
1122
 
        gnome_vfs_async_cancel (loader->priv->handle);
1123
 
 
1124
 
        g_set_error (&loader->priv->error,
1125
 
                     GEDIT_DOCUMENT_ERROR,
1126
 
                     GNOME_VFS_ERROR_CANCELLED,
1127
 
                     gnome_vfs_result_to_string (GNOME_VFS_ERROR_CANCELLED));
1128
 
 
1129
 
        remote_load_completed_or_failed (loader);
1130
 
 
1131
 
        return TRUE;
 
447
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_bytes_read (loader);
1132
448
}
1133
449
 
1134
450
/* In the case the loader does not know if the file is readonly, for example 
1139
455
{
1140
456
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), FALSE);
1141
457
 
1142
 
        if (!gedit_utils_uri_has_writable_scheme (loader->priv->uri))
 
458
        /* if configuration says the scheme is not writable, do not query the
 
459
           actual loader object, and return TRUE */
 
460
        if (!gedit_utils_uri_has_writable_scheme (loader->uri))
1143
461
                return TRUE;
1144
462
 
1145
 
        if (loader->priv->info &&
1146
 
            (loader->priv->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_ACCESS))
1147
 
                return (loader->priv->info->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE) ? FALSE : TRUE;
1148
 
        else
1149
 
                return FALSE;
 
463
        return GEDIT_DOCUMENT_LOADER_GET_CLASS (loader)->get_readonly (loader);
1150
464
}
1151
465
 
1152
466
const GeditEncoding *
1154
468
{
1155
469
        g_return_val_if_fail (GEDIT_IS_DOCUMENT_LOADER (loader), NULL);
1156
470
 
1157
 
        if (loader->priv->encoding != NULL)
1158
 
                return loader->priv->encoding;
1159
 
                
1160
 
        g_return_val_if_fail (loader->priv->auto_detected_encoding != NULL, 
 
471
        if (loader->encoding != NULL)
 
472
                return loader->encoding;
 
473
 
 
474
        g_return_val_if_fail (loader->auto_detected_encoding != NULL, 
1161
475
                              gedit_encoding_get_current ());
1162
 
                          
1163
 
        return loader->priv->auto_detected_encoding;
 
476
 
 
477
        return loader->auto_detected_encoding;
1164
478
}