~ubuntu-branches/ubuntu/karmic/evolution/karmic-proposed

« back to all changes in this revision

Viewing changes to composer/e-composer-autosave.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2009-10-19 11:28:09 UTC
  • mfrom: (1.1.69 upstream)
  • Revision ID: james.westby@ubuntu.com-20091019112809-dm58mhdd7mkedv4h
Tags: 2.28.1-0ubuntu1
* New upstream version:
  Bug Fixes:
  - #552552 - File/Empty Trash does not expunge maildir folder    
  - #592117 - Calendar printout love
  - #592313 - Default label names untranslated (lp: #442250)
  - #594373 - Calendar notifications are not cleared from system tray    
              (lp: #437755)
  - #595501 - Crash on a changed filter rule removal (lp: #452921)
  - #595923 - Fix user doc compilation warnings 
  - #595938 - User doc clean up 
  - #596130 - Use correct Name and GenericName in .desktop file    
  - #596157 - Use "Message-ID" instead of "Message-Id" 
  - #596160 - Compiler warnings about _MailComponentPrivate.quit_state    
  - #596712 - Recovered messages not autosaved until modification
  - #596800 - Hang on contacts merging 
  - #597108 - E_CONFIG_SECTION headers not properly escaped    
  - #597564 - Invalid g_object_unref call in redo_queries 
  Miscellaneous:
  Disable gdk_event_get_graphics_expose
  Various composer autosave fixes. 
* debian/patches/90_autoconf.patch:
  - new version update

Show diffs side-by-side

added added

removed removed

Lines of Context:
116
116
}
117
117
 
118
118
static void
 
119
composer_autosave_finish_cb (EMsgComposer *composer,
 
120
                             GAsyncResult *result)
 
121
{
 
122
        GError *error = NULL;
 
123
 
 
124
        e_composer_autosave_snapshot_finish (composer, result, &error);
 
125
 
 
126
        if (error != NULL) {
 
127
                e_error_run (
 
128
                        GTK_WINDOW (composer),
 
129
                        "mail-composer:no-autosave",
 
130
                        "", error->message, NULL);
 
131
                g_error_free (error);
 
132
        }
 
133
}
 
134
 
 
135
static void
119
136
composer_autosave_foreach (EMsgComposer *composer)
120
137
{
121
138
        /* Make sure the composer is still alive. */
122
139
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
123
140
 
124
141
        if (e_composer_autosave_get_enabled (composer))
125
 
                e_composer_autosave_snapshot_async (composer, NULL, NULL);
 
142
                e_composer_autosave_snapshot_async (
 
143
                        composer, (GAsyncReadyCallback)
 
144
                        composer_autosave_finish_cb, NULL);
126
145
}
127
146
 
128
147
static gint
250
269
}
251
270
 
252
271
typedef struct {
253
 
        GSimpleAsyncResult *result;
254
272
        EMsgComposer *composer;
 
273
        GSimpleAsyncResult *simple;
255
274
        AutosaveState *state;
256
275
 
257
276
        /* Transient data */
262
281
autosave_data_free (AutosaveData *data)
263
282
{
264
283
        g_object_unref (data->composer);
 
284
 
 
285
        if (data->input_stream != NULL)
 
286
                g_object_unref (data->input_stream);
 
287
 
265
288
        g_slice_free (AutosaveData, data);
266
289
}
267
290
 
268
291
static gboolean
269
 
autosave_snapshot_check_for_error (AutosaveData *data, GError *error)
 
292
autosave_snapshot_check_for_error (AutosaveData *data,
 
293
                                   GError *error)
270
294
{
 
295
        GSimpleAsyncResult *simple;
 
296
 
271
297
        if (error == NULL)
272
298
                return FALSE;
273
299
 
274
 
        g_simple_async_result_set_from_error (data->result, error);
275
 
        g_simple_async_result_set_op_res_gboolean (data->result, FALSE);
276
 
        g_simple_async_result_complete (data->result);
 
300
        /* Steal the result. */
 
301
        simple = data->simple;
 
302
        data->simple = NULL;
 
303
 
 
304
        g_simple_async_result_set_from_error (simple, error);
 
305
        g_simple_async_result_set_op_res_gboolean (simple, FALSE);
 
306
        g_simple_async_result_complete (simple);
277
307
        g_error_free (error);
278
308
 
279
309
        autosave_data_free (data);
282
312
}
283
313
 
284
314
static void
285
 
autosave_snapshot_splice_cb (GOutputStream *autosave_stream,
286
 
                             GSimpleAsyncResult *result,
 
315
autosave_snapshot_splice_cb (GOutputStream *output_stream,
 
316
                             GAsyncResult *result,
287
317
                             AutosaveData *data)
288
318
{
289
 
        gssize length;
 
319
        GSimpleAsyncResult *simple;
290
320
        GError *error = NULL;
291
321
 
292
 
        length = g_output_stream_splice_finish (
293
 
                autosave_stream, G_ASYNC_RESULT (result), &error);
294
 
        g_object_unref (data->input_stream);
 
322
        g_output_stream_splice_finish (output_stream, result, &error);
 
323
 
295
324
        if (autosave_snapshot_check_for_error (data, error))
296
325
                return;
297
326
 
300
329
         * which doesn't mean it's saved permanently */
301
330
        e_composer_autosave_set_saved (data->composer, TRUE);
302
331
 
303
 
        /* Tidy up */
 
332
        /* Steal the result. */
 
333
        simple = data->simple;
 
334
        data->simple = NULL;
 
335
 
 
336
        g_simple_async_result_set_op_res_gboolean (simple, TRUE);
 
337
        g_simple_async_result_complete (simple);
 
338
 
304
339
        autosave_data_free (data);
305
340
}
306
341
 
307
342
static void
308
 
autosave_snapshot_cb (GFile *autosave_file,
309
 
                      GSimpleAsyncResult *result,
 
343
autosave_snapshot_cb (GFile *file,
 
344
                      GAsyncResult *result,
310
345
                      AutosaveData *data)
311
346
{
312
347
        CamelMimeMessage *message;
316
351
        GByteArray *buffer;
317
352
        GError *error = NULL;
318
353
 
319
 
        output_stream = g_file_replace_finish (
320
 
                autosave_file, G_ASYNC_RESULT (result), &error);
 
354
        output_stream = g_file_replace_finish (file, result, &error);
 
355
 
321
356
        if (autosave_snapshot_check_for_error (data, error))
322
357
                return;
323
358
 
324
359
        /* Extract a MIME message from the composer. */
325
360
        message = e_msg_composer_get_message_draft (data->composer);
326
361
        if (message == NULL) {
327
 
                /* If we don't set an error, but return FALSE, the error message
328
 
                 * in this odd case (we don't have an error domain or code)
329
 
                 * will be set in the _finish() function. */
330
 
                g_simple_async_result_set_op_res_gboolean (result, FALSE);
 
362
                GSimpleAsyncResult *simple;
 
363
 
 
364
                /* Steal the result. */
 
365
                simple = data->simple;
 
366
                data->simple = NULL;
 
367
 
 
368
                /* FIXME Need to set a GError here. */
 
369
                g_simple_async_result_set_op_res_gboolean (simple, FALSE);
 
370
                g_simple_async_result_complete (simple);
331
371
                g_object_unref (output_stream);
332
372
                autosave_data_free (data);
333
373
                return;
335
375
 
336
376
        /* Decode the MIME part to an in-memory buffer.  We have to do
337
377
         * this because CamelStream is synchronous-only, and using threads
338
 
         * (as we do with foo()) is dangerous because CamelDataWrapper
339
 
         * is not reentrant. */
 
378
         * is dangerous because CamelDataWrapper is not reentrant. */
340
379
        buffer = g_byte_array_new ();
341
380
        camel_stream = camel_stream_mem_new ();
342
381
        camel_stream_mem_set_byte_array (
364
403
                G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
365
404
                G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)
366
405
                autosave_snapshot_splice_cb, data);
 
406
 
367
407
        g_object_unref (output_stream);
368
408
}
369
409
 
374
414
{
375
415
        AutosaveData *data;
376
416
        AutosaveState *state;
377
 
        GSimpleAsyncResult *result;
 
417
        GSimpleAsyncResult *simple;
378
418
 
379
419
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
380
420
 
381
 
        result = g_simple_async_result_new (
 
421
        simple = g_simple_async_result_new (
382
422
                G_OBJECT (composer), callback, user_data,
383
423
                e_composer_autosave_snapshot_async);
384
424
 
385
425
        /* If the contents are unchanged, exit early. */
386
426
        if (!gtkhtml_editor_get_changed (GTKHTML_EDITOR (composer))) {
387
 
                g_simple_async_result_set_op_res_gboolean (result, TRUE);
388
 
                g_simple_async_result_complete (result);
 
427
                g_simple_async_result_set_op_res_gboolean (simple, TRUE);
 
428
                g_simple_async_result_complete (simple);
389
429
                return;
390
430
        }
391
431
 
396
436
        errno = 0;
397
437
        if (!composer_autosave_state_open (state)) {
398
438
                g_simple_async_result_set_error (
399
 
                        result, G_FILE_ERROR,
 
439
                        simple, G_FILE_ERROR,
400
440
                        g_file_error_from_errno (errno),
401
441
                        "%s", g_strerror (errno));
402
 
                g_simple_async_result_set_op_res_gboolean (result, FALSE);
403
 
                g_simple_async_result_complete (result);
 
442
                g_simple_async_result_set_op_res_gboolean (simple, FALSE);
 
443
                g_simple_async_result_complete (simple);
404
444
                return;
405
445
        }
406
446
 
407
447
        /* Overwrite the file */
408
448
        data = g_slice_new (AutosaveData);
409
 
        data->composer = composer;
410
 
        data->result = result;
 
449
        data->composer = g_object_ref (composer);
 
450
        data->simple = simple;
411
451
        data->state = state;
412
452
 
413
453
        g_file_replace_async (
418
458
 
419
459
gboolean
420
460
e_composer_autosave_snapshot_finish (EMsgComposer *composer,
421
 
                                     GAsyncResult *async_result,
 
461
                                     GAsyncResult *result,
422
462
                                     GError **error)
423
463
{
424
 
        GSimpleAsyncResult *result;
 
464
        GSimpleAsyncResult *simple;
 
465
        gboolean success;
425
466
 
426
467
        g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
427
 
        g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (async_result), FALSE);
 
468
        g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
428
469
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
429
470
 
430
 
        result = G_SIMPLE_ASYNC_RESULT (async_result);
431
 
        g_warn_if_fail (g_simple_async_result_get_source_tag (result) ==
432
 
                        e_composer_autosave_snapshot_async);
433
 
 
434
 
        if (g_simple_async_result_propagate_error (result, error) ||
435
 
            !g_simple_async_result_get_op_res_gboolean (result)) {
436
 
                const gchar *errmsg;
437
 
                gchar *filename;
438
 
 
439
 
                /* Sort out the error message; use the GError message if
440
 
                 * possible. The only case where is isn't is where we couldn't
441
 
                 * get the message from the editor. */
442
 
                if (error && *error)
443
 
                        errmsg = (*error)->message;
444
 
                else
445
 
                        errmsg = _("Unable to retrieve message from editor");
446
 
 
447
 
                filename = e_composer_autosave_get_filename (composer);
448
 
                e_error_run (
449
 
                        GTK_WINDOW (composer), "mail-composer:no-autosave",
450
 
                        (filename != NULL) ? filename : "", errmsg, NULL);
451
 
                g_free (filename);
452
 
 
453
 
                return FALSE;
454
 
        }
455
 
 
456
 
        return TRUE;
 
471
        simple = G_SIMPLE_ASYNC_RESULT (result);
 
472
        success = g_simple_async_result_get_op_res_gboolean (simple);
 
473
        g_simple_async_result_propagate_error (simple, error);
 
474
        g_object_unref (simple);
 
475
 
 
476
        return success;
457
477
}
458
478
 
459
479
gchar *