982
* e_util_free_nullable_object_slist:
983
* @objects: (element-type GObject): a #GSList of nullable #GObject<!-- -->s
985
* Calls g_object_unref() on each member of @objects if non-%NULL and then frees
986
* also @objects itself.
991
e_util_free_nullable_object_slist (GSList *objects)
994
for (l = objects; l; l = l->next) {
996
g_object_unref (l->data);
998
g_slist_free (objects);
1001
/* Helper for e_file_recursive_delete() */
1003
file_recursive_delete_thread (GSimpleAsyncResult *simple,
1005
GCancellable *cancellable)
1007
GError *error = NULL;
1009
e_file_recursive_delete_sync (G_FILE (object), cancellable, &error);
1012
g_simple_async_result_take_error (simple, error);
1016
* e_file_recursive_delete_sync:
1017
* @file: a #GFile to delete
1018
* @cancellable: optional #GCancellable object, or %NULL
1019
* @error: return location for a #GError, or %NULL
1021
* Deletes @file. If @file is a directory, its contents are deleted
1022
* recursively before @file itself is deleted. The recursive delete
1023
* operation will stop on the first error.
1025
* If @cancellable is not %NULL, then the operation can be cancelled
1026
* by triggering the cancellable object from another thread. If the
1027
* operation was cancelled, the error #G_IO_ERROR_CANCELLED will be
1030
* Returns: %TRUE if the file was deleted, %FALSE otherwise
1035
e_file_recursive_delete_sync (GFile *file,
1036
GCancellable *cancellable,
1039
GFileEnumerator *file_enumerator;
1040
GFileInfo *file_info;
1041
GFileType file_type;
1042
gboolean success = TRUE;
1043
GError *local_error = NULL;
1045
g_return_val_if_fail (G_IS_FILE (file), FALSE);
1047
file_type = g_file_query_file_type (
1048
file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable);
1050
/* If this is not a directory, delete like normal. */
1051
if (file_type != G_FILE_TYPE_DIRECTORY)
1052
return g_file_delete (file, cancellable, error);
1054
/* Note, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS is critical here
1055
* so we only delete files inside the directory being deleted. */
1056
file_enumerator = g_file_enumerate_children (
1057
file, G_FILE_ATTRIBUTE_STANDARD_NAME,
1058
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1059
cancellable, error);
1061
if (file_enumerator == NULL)
1064
file_info = g_file_enumerator_next_file (
1065
file_enumerator, cancellable, &local_error);
1067
while (file_info != NULL) {
1071
name = g_file_info_get_name (file_info);
1073
/* Here's the recursive part. */
1074
child = g_file_get_child (file, name);
1075
success = e_file_recursive_delete_sync (
1076
child, cancellable, error);
1077
g_object_unref (child);
1079
g_object_unref (file_info);
1084
file_info = g_file_enumerator_next_file (
1085
file_enumerator, cancellable, &local_error);
1088
if (local_error != NULL) {
1089
g_propagate_error (error, local_error);
1093
g_object_unref (file_enumerator);
1098
/* The directory should be empty now. */
1099
return g_file_delete (file, cancellable, error);
1103
* e_file_recursive_delete:
1104
* @file: a #GFile to delete
1105
* @io_priority: the I/O priority of the request
1106
* @cancellable: optional #GCancellable object, or %NULL
1107
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
1108
* @user_data: data to pass to the callback function
1110
* Asynchronously deletes @file. If @file is a directory, its contents
1111
* are deleted recursively before @file itself is deleted. The recursive
1112
* delete operation will stop on the first error.
1114
* If @cancellable is not %NULL, then the operation can be cancelled
1115
* by triggering the cancellable object before the operation finishes.
1117
* When the operation is finished, @callback will be called. You can then
1118
* call e_file_recursive_delete_finish() to get the result of the operation.
1123
e_file_recursive_delete (GFile *file,
1125
GCancellable *cancellable,
1126
GAsyncReadyCallback callback,
1129
GSimpleAsyncResult *simple;
1131
g_return_if_fail (G_IS_FILE (file));
1133
simple = g_simple_async_result_new (
1134
G_OBJECT (file), callback, user_data,
1135
e_file_recursive_delete);
1137
g_simple_async_result_set_check_cancellable (simple, cancellable);
1139
g_simple_async_result_run_in_thread (
1140
simple, file_recursive_delete_thread,
1141
io_priority, cancellable);
1143
g_object_unref (simple);
1147
* e_file_recursive_delete_finish:
1148
* @file: a #GFile to delete
1149
* @result: a #GAsyncResult
1150
* @error: return location for a #GError, or %NULL
1152
* Finishes the operation started with e_file_recursive_delete().
1154
* If the operation was cancelled, the error #G_IO_ERROR_CANCELLED will be
1157
* Returns: %TRUE if the file was deleted, %FALSE otherwise
1162
e_file_recursive_delete_finish (GFile *file,
1163
GAsyncResult *result,
1166
GSimpleAsyncResult *simple;
1168
g_return_val_if_fail (
1169
g_simple_async_result_is_valid (
1170
result, G_OBJECT (file), e_file_recursive_delete), FALSE);
1172
simple = G_SIMPLE_ASYNC_RESULT (result);
1174
/* Assume success unless a GError is set. */
1175
return !g_simple_async_result_propagate_error (simple, error);
950
1179
* e_binding_transform_enum_value_to_nick:
951
1180
* @binding: a #GBinding
952
1181
* @source_value: a #GValue whose type is derived from #G_TYPE_ENUM
1024
1253
return success;
1259
* #EAsyncClosure provides a simple way to run an asynchronous function
1260
* synchronously without blocking a running #GMainLoop or using threads.
1262
* 1) Create an #EAsyncClosure with e_async_closure_new().
1264
* 2) Call the asynchronous function passing e_async_closure_callback() as
1265
* the #GAsyncReadyCallback argument and the #EAsyncClosure as the data
1268
* 3) Call e_async_closure_wait() and collect the #GAsyncResult.
1270
* 4) Call the corresponding asynchronous "finish" function, passing the
1271
* #GAsyncResult returned by e_async_closure_wait().
1273
* 5) If needed, repeat steps 2-4 for additional asynchronous functions
1274
* using the same #EAsyncClosure.
1276
* 6) Finally, free the #EAsyncClosure with e_async_closure_free().
1280
struct _EAsyncClosure {
1282
GMainContext *context;
1283
GAsyncResult *result;
1287
* e_async_closure_new:
1289
* Creates a new #EAsyncClosure for use with asynchronous functions.
1291
* Returns: a new #EAsyncClosure
1296
e_async_closure_new (void)
1298
EAsyncClosure *closure;
1300
closure = g_slice_new0 (EAsyncClosure);
1301
closure->context = g_main_context_new ();
1302
closure->loop = g_main_loop_new (closure->context, FALSE);
1304
g_main_context_push_thread_default (closure->context);
1310
* e_async_closure_wait:
1311
* @closure: an #EAsyncClosure
1313
* Call this function immediately after starting an asynchronous operation.
1314
* The function waits for the asynchronous operation to complete and returns
1315
* its #GAsyncResult to be passed to the operation's "finish" function.
1317
* This function can be called repeatedly on the same #EAsyncClosure to
1318
* easily string together multiple asynchronous operations.
1320
* Returns: (transfer none): a #GAsyncResult which is owned by the closure
1325
e_async_closure_wait (EAsyncClosure *closure)
1327
g_return_val_if_fail (closure != NULL, NULL);
1329
g_main_loop_run (closure->loop);
1331
return closure->result;
1335
* e_async_closure_free:
1336
* @closure: an #EAsyncClosure
1338
* Frees the @closure and the resources it holds.
1343
e_async_closure_free (EAsyncClosure *closure)
1345
g_return_if_fail (closure != NULL);
1347
g_main_context_pop_thread_default (closure->context);
1349
g_main_loop_unref (closure->loop);
1350
g_main_context_unref (closure->context);
1352
if (closure->result != NULL)
1353
g_object_unref (closure->result);
1355
g_slice_free (EAsyncClosure, closure);
1359
* e_async_closure_callback:
1360
* @object: a #GObject
1361
* @result: a #GAsyncResult
1362
* @closure: an #EAsyncClosure
1364
* Pass this function as the #GAsyncReadyCallback argument of an asynchronous
1365
* function, and the #EAsyncClosure as the data argument.
1367
* This causes e_async_closure_wait() to terminate and return @result.
1372
e_async_closure_callback (GObject *object,
1373
GAsyncResult *result,
1376
EAsyncClosure *real_closure;
1378
g_return_if_fail (G_IS_OBJECT (object));
1379
g_return_if_fail (G_IS_ASYNC_RESULT (result));
1380
g_return_if_fail (closure != NULL);
1382
real_closure = closure;
1384
/* Replace any previous result. */
1385
if (real_closure->result != NULL)
1386
g_object_unref (real_closure->result);
1387
real_closure->result = g_object_ref (result);
1389
g_main_loop_quit (real_closure->loop);
1027
1392
#ifdef G_OS_WIN32
1029
1394
#include <windows.h>