void thunar_progress_dialog_add_job (ThunarProgressDialog *dialog, ThunarJob *job, const gchar *icon_name, const gchar *title) { GtkWidget *viewport; GtkWidget *view; _thunar_return_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog)); _thunar_return_if_fail (THUNAR_IS_JOB (job)); _thunar_return_if_fail (g_utf8_validate (title, -1, NULL)); view = thunar_progress_view_new_with_job (job); thunar_progress_view_set_icon_name (THUNAR_PROGRESS_VIEW (view), icon_name); thunar_progress_view_set_title (THUNAR_PROGRESS_VIEW (view), title); gtk_box_pack_start (GTK_BOX (dialog->content_box), view, FALSE, TRUE, 0); gtk_widget_show (view); /* use the first job's icon-name for the dialog */ if (dialog->views == NULL) gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name); /* add the view to the list of known views */ dialog->views = g_list_prepend (dialog->views, view); /* check if we need to wrap the views in a scroll window (starting * at SCROLLVIEW_THRESHOLD parallel operations */ if (g_list_length (dialog->views) == SCROLLVIEW_THRESHOLD) { /* create a scrolled window and add it to the dialog */ dialog->scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dialog->scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (dialog->vbox), dialog->scrollwin); gtk_widget_show (dialog->scrollwin); /* create a viewport for the content box */ viewport = gtk_viewport_new (gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (dialog->scrollwin)), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (dialog->scrollwin))); gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE); gtk_container_add (GTK_CONTAINER (dialog->scrollwin), viewport); gtk_widget_show (viewport); /* move the content box into the viewport */ gtk_widget_reparent (dialog->content_box, viewport); } g_signal_connect_swapped (view, "need-attention", G_CALLBACK (thunar_progress_dialog_view_needs_attention), dialog); g_signal_connect_swapped (view, "finished", G_CALLBACK (thunar_progress_dialog_job_finished), dialog); if (dialog->status_icon != NULL) thunar_progress_dialog_update_status_icon (dialog); }
GList * thunar_io_scan_directory (ThunarJob *job, GFile *file, GFileQueryInfoFlags flags, gboolean recursively, gboolean unlinking, GError **error) { GFileEnumerator *enumerator; GFileInfo *info; GFileType type; GError *err = NULL; GFile *child_file; GList *child_files = NULL; GList *files = NULL; _thunar_return_val_if_fail (THUNAR_IS_JOB (job), NULL); _thunar_return_val_if_fail (G_IS_FILE (file), NULL); _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL); /* abort if the job was cancelled */ if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) return NULL; /* don't recurse when we are scanning prior to unlinking and the current * file/dir is in the trash. In GVfs, only the top-level directories in * the trash can be modified and deleted directly. See * http://bugzilla.xfce.org/show_bug.cgi?id=7147 * for more information */ if (unlinking && thunar_g_file_is_trashed (file) && !thunar_g_file_is_root (file)) { return NULL; } /* query the file type */ type = g_file_query_file_type (file, flags, exo_job_get_cancellable (EXO_JOB (job))); /* abort if the job was cancelled */ if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) return NULL; /* ignore non-directory nodes */ if (type != G_FILE_TYPE_DIRECTORY) return NULL; /* try to read from the direectory */ enumerator = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME, flags, exo_job_get_cancellable (EXO_JOB (job)), &err); /* abort if there was an error or the job was cancelled */ if (err != NULL) { g_propagate_error (error, err); return NULL; } /* query info of the first child */ info = g_file_enumerator_next_file (enumerator, exo_job_get_cancellable (EXO_JOB (job)), &err); /* iterate over children one by one as long as there's no error */ while (info != NULL && err == NULL && !exo_job_is_cancelled (EXO_JOB (job))) { /* create GFile for the child and prepend it to the file list */ child_file = g_file_get_child (file, g_file_info_get_name (info)); files = thunar_g_file_list_prepend (files, child_file); /* if the child is a directory and we need to recurse ... just do so */ if (recursively && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { child_files = thunar_io_scan_directory (job, child_file, flags, recursively, unlinking, &err); /* prepend children to the file list to make sure they're * processed first (required for unlinking) */ files = g_list_concat (child_files, files); } g_object_unref (child_file); g_object_unref (info); info = g_file_enumerator_next_file (enumerator, exo_job_get_cancellable (EXO_JOB (job)), &err); } /* release the enumerator */ g_object_unref (enumerator); if (G_UNLIKELY (err != NULL)) { g_propagate_error (error, err); thunar_g_file_list_free (files); return NULL; } else if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err)) { g_propagate_error (error, err); thunar_g_file_list_free (files); return NULL; } return files; }