diff --git a/thunar/thunar-io-jobs.c b/thunar/thunar-io-jobs.c index 5a238f1b151f0919f725a2d848b5647da529af64..f95246648ad2033c464631121ddbb2f5a12a4c1c 100644 --- a/thunar/thunar-io-jobs.c +++ b/thunar/thunar-io-jobs.c @@ -1891,3 +1891,150 @@ thunar_io_jobs_load_content_types (GList *files) g_signal_connect_swapped (job, "finished", G_CALLBACK (thunar_g_list_free_full), copy); return job; } + + + +static gboolean +_thunar_job_load_statusbar_text (ThunarJob *job, + GArray *param_values, + GError **error) +{ + ThunarStandardView *standard_view; + ThunarFile *thunar_folder; + GList *thunar_files; + gboolean show_file_size_binary_format; + ThunarDateStyle date_style; + const gchar *date_custom_style; + gchar *text_for_files; + gchar *temp_string; + GList *text_list = NULL; + guint status_bar_active_info; + guint64 size; + + if (exo_job_set_error_if_cancelled (EXO_JOB (job), error)) + return FALSE; + + standard_view = g_value_get_object (&g_array_index (param_values, GValue, 0)); + thunar_folder = g_value_get_object (&g_array_index (param_values, GValue, 1)); + thunar_files = g_value_get_boxed (&g_array_index (param_values, GValue, 2)); + show_file_size_binary_format = g_value_get_boolean (&g_array_index (param_values, GValue, 3)); + date_style = g_value_get_enum (&g_array_index (param_values, GValue, 4)); + date_custom_style = g_value_get_string (&g_array_index (param_values, GValue, 5)); + status_bar_active_info = g_value_get_uint (&g_array_index (param_values, GValue, 6)); + + text_for_files = thunar_util_get_statusbar_text_for_files (thunar_files, + show_file_size_binary_format, + date_style, + date_custom_style, + status_bar_active_info); + + /* the text is about a selection of files or about a folder */ + if (thunar_folder == 0) + { + temp_string = g_strdup_printf (_ ("Selection: %s"), text_for_files); + text_list = g_list_append (text_list, temp_string); + g_free (text_for_files); + } + else + { + text_list = g_list_append (text_list, text_for_files); + + /* check if we can determine the amount of free space for the volume */ + if (thunar_g_file_get_free_space (thunar_file_get_file (thunar_folder), &size, NULL)) + { + /* humanize the free space */ + gchar *size_string = g_format_size_full (size, show_file_size_binary_format ? G_FORMAT_SIZE_IEC_UNITS : G_FORMAT_SIZE_DEFAULT); + temp_string = g_strdup_printf (_ ("Free space: %s"), size_string); + text_list = g_list_append (text_list, temp_string); + g_free (size_string); + } + } + + temp_string = thunar_util_strjoin_list (text_list, " | "); + g_list_free_full (text_list, g_free); + + thunar_standard_view_set_statusbar_text (standard_view, temp_string); + g_free (temp_string); + + return TRUE; +} + + + +ThunarJob * +thunar_io_jobs_load_statusbar_text_for_folder (ThunarStandardView *standard_view, + ThunarFolder *folder) +{ + ThunarPreferences *preferences; + gboolean show_file_size_binary_format; + ThunarDateStyle date_style; + const gchar *date_custom_style; + guint status_bar_active_info; + GList *files; + GList *copy; + ThunarFile *file; + + preferences = thunar_preferences_get (); + g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, + "misc_date-custom-style", &date_custom_style, + "misc-file-size-binary", &show_file_size_binary_format, + "misc-status-bar-active-info", &status_bar_active_info, NULL); + + files = thunar_folder_get_files (folder); + file = thunar_folder_get_corresponding_file (folder); + + if (file == NULL) + return NULL; + + /* This will increase the ref count on each ThunarFile */ + copy = thunar_g_list_copy_deep (files); + + ThunarJob *job = thunar_simple_job_new (_thunar_job_load_statusbar_text, 7, + THUNAR_TYPE_STANDARD_VIEW, g_object_ref (standard_view), + THUNAR_TYPE_FILE, g_object_ref (file), + THUNAR_TYPE_G_FILE_LIST, files, + G_TYPE_BOOLEAN, show_file_size_binary_format, + THUNAR_TYPE_DATE_STYLE, date_style, + G_TYPE_STRING, date_custom_style, + G_TYPE_UINT, status_bar_active_info); + + g_signal_connect_swapped (job, "finished", G_CALLBACK (thunar_g_list_free_full), copy); + g_signal_connect_swapped (job, "finished", G_CALLBACK (g_object_unref), file); + g_signal_connect_swapped (job, "finished", G_CALLBACK (g_object_unref), standard_view); + return job; +} + + + +ThunarJob * +thunar_io_jobs_load_statusbar_text_for_selection (ThunarStandardView *standard_view, GList *selected_files) +{ + ThunarPreferences *preferences; + gboolean show_file_size_binary_format; + ThunarDateStyle date_style; + const gchar *date_custom_style; + guint status_bar_active_info; + GList *copy; + + preferences = thunar_preferences_get (); + g_object_get (G_OBJECT (preferences),"misc-date-style", &date_style, + "misc_date-custom-style", &date_custom_style, + "misc-file-size-binary", &show_file_size_binary_format, + "misc-status-bar-active-info", &status_bar_active_info, NULL); + + /* This will increase the ref count on each ThunarFile */ + copy = thunar_g_list_copy_deep (selected_files); + + ThunarJob *job = thunar_simple_job_new (_thunar_job_load_statusbar_text, 7, + THUNAR_TYPE_STANDARD_VIEW, g_object_ref (standard_view), + THUNAR_TYPE_FILE, NULL, + THUNAR_TYPE_G_FILE_LIST, selected_files, + G_TYPE_BOOLEAN, show_file_size_binary_format, + THUNAR_TYPE_DATE_STYLE, date_style, + G_TYPE_STRING, date_custom_style, + G_TYPE_UINT, status_bar_active_info); + + g_signal_connect_swapped (job, "finished", G_CALLBACK (thunar_g_list_free_full), copy); + g_signal_connect_swapped (job, "finished", G_CALLBACK (g_object_unref), standard_view); + return job; +} \ No newline at end of file diff --git a/thunar/thunar-io-jobs.h b/thunar/thunar-io-jobs.h index 39884f0c32ca6083aa8f334051681216e66661f3..c6d9d9da50055e9d2c3ada8f606b5938f4c64d5a 100644 --- a/thunar/thunar-io-jobs.h +++ b/thunar/thunar-io-jobs.h @@ -24,6 +24,7 @@ #include "thunar/thunar-job.h" #include "thunar/thunar-enum-types.h" #include "thunar/thunar-standard-view-model.h" +#include "thunar/thunar-standard-view.h" #include "thunar/thunar-job.h" G_BEGIN_DECLS @@ -63,8 +64,11 @@ ThunarJob *thunar_io_jobs_clear_metadata_for_files (GList *files, ThunarJob *thunar_io_jobs_set_metadata_for_files (GList *files, ThunarGType type, ...); -ThunarJob *thunar_io_jobs_load_content_types(GList *files) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - +ThunarJob *thunar_io_jobs_load_content_types (GList *files) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +ThunarJob *thunar_io_jobs_load_statusbar_text_for_folder (ThunarStandardView *standard_view, + ThunarFolder *folder); +ThunarJob *thunar_io_jobs_load_statusbar_text_for_selection (ThunarStandardView *standard_view, + GList *selected_files); G_END_DECLS #endif /* !__THUNAR_IO_JOBS_H__ */ diff --git a/thunar/thunar-standard-view-model.c b/thunar/thunar-standard-view-model.c index 51492dd190bf7d4f65bb1c44e6d68cfc6b2d1541..6f95747edbc19b8fb66481f669c410808dc46ada 100644 --- a/thunar/thunar-standard-view-model.c +++ b/thunar/thunar-standard-view-model.c @@ -427,205 +427,6 @@ thunar_standard_view_model_add_search_files (ThunarStandardViewModel *model, -/** - * thunar_standard_view_model_get_statusbar_text: - * @store : a #ThunarListModel instance. - * @selected_items : the list of selected items (as GtkTreePath's). - * - * Generates the statusbar text for @store with the given - * @selected_items. - * - * This function is used by the #ThunarStandardView (and thereby - * implicitly by #ThunarIconView and #ThunarDetailsView) to - * calculate the text to display in the statusbar for a given - * file selection. - * - * The caller is reponsible to free the returned text using - * g_free() when it's no longer needed. - * - * Return value: the statusbar text for @store with the given - * @selected_items. - **/ -gchar * -thunar_standard_view_model_get_statusbar_text (ThunarStandardViewModel *model, - GList *selected_items) -{ - const gchar *content_type; - const gchar *original_path; - GtkTreeIter iter; - ThunarFile *file, *_file; - guint64 size; - GList *lp; - GList *text_list = NULL; - gchar *temp_string = NULL; - gchar *text = ""; - gint height; - gint width; - ThunarFolder *folder; - ThunarPreferences *preferences; - gboolean show_image_size; - gboolean show_file_size_binary_format; - GList *relevant_files = NULL; - guint active; - gboolean show_size, show_size_in_bytes, show_filetype, show_display_name, show_last_modified; - ThunarDateStyle date_style; - gchar *date_custom_style; - gchar *date_string; - - _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW_MODEL (model), NULL); - - preferences = thunar_preferences_get (); - g_object_get (G_OBJECT (preferences), "misc-status-bar-active-info", &active, NULL); - g_object_get (G_OBJECT (model), "date-style", &date_style, "date-custom-style", &date_custom_style, NULL); - show_size = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE); - show_size_in_bytes = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE_IN_BYTES); - show_filetype = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_FILETYPE); - show_display_name = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_DISPLAY_NAME); - show_last_modified = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_LAST_MODIFIED); - show_file_size_binary_format = thunar_standard_view_model_get_file_size_binary (model); - - if (selected_items == NULL) /* nothing selected */ - { - /* try to determine a file for the current folder */ - folder = thunar_standard_view_model_get_folder (model); - relevant_files = thunar_folder_get_files (folder); - file = (folder != NULL) ? thunar_folder_get_corresponding_file (folder) : NULL; - temp_string = thunar_util_get_statusbar_text_for_files (relevant_files, show_file_size_binary_format, date_style, date_custom_style); - text_list = g_list_append (text_list, temp_string); - - /* check if we can determine the amount of free space for the volume */ - if (G_LIKELY (file != NULL && thunar_g_file_get_free_space (thunar_file_get_file (file), &size, NULL))) - { - /* humanize the free space */ - gchar *size_string = g_format_size_full (size, show_file_size_binary_format ? G_FORMAT_SIZE_IEC_UNITS : G_FORMAT_SIZE_DEFAULT); - temp_string = g_strdup_printf (_ ("Free space: %s"), size_string); - text_list = g_list_append (text_list, temp_string); - g_free (size_string); - } - - g_list_free (relevant_files); - } - else if (selected_items->next == NULL) /* only one item selected */ - { - /* resolve the iter for the single path */ - gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, selected_items->data); - - /* get the file for the given iter */ - file = thunar_standard_view_model_get_file (model, &iter); - - if (file == NULL) - return g_strdup (""); - - /* determine the content type of the file */ - content_type = thunar_file_get_content_type (file); - - if (show_display_name == TRUE) - { - if (g_strcmp0 (thunar_file_get_display_name (file), thunar_file_get_basename (file)) != 0) - temp_string = g_strdup_printf (_ ("\"%s\" (%s)"), thunar_file_get_display_name (file), thunar_file_get_basename (file)); - else - temp_string = g_strdup_printf (_ ("\"%s\""), thunar_file_get_display_name (file)); - text_list = g_list_append (text_list, temp_string); - } - - if (thunar_file_is_regular (file) || G_UNLIKELY (thunar_file_is_symlink (file))) - { - if (show_size == TRUE) - { - if (show_size_in_bytes == TRUE) - temp_string = thunar_file_get_size_string_long (file, show_file_size_binary_format); - else - temp_string = thunar_file_get_size_string_formatted (file, show_file_size_binary_format); - text_list = g_list_append (text_list, temp_string); - } - } - - if (show_filetype == TRUE) - { - if (G_UNLIKELY (content_type != NULL && g_str_equal (content_type, "inode/symlink"))) - temp_string = g_strdup (_ ("broken link")); - else if (G_UNLIKELY (thunar_file_is_symlink (file))) - temp_string = g_strdup_printf (_ ("link to %s"), thunar_file_get_symlink_target (file)); - else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_SHORTCUT)) - temp_string = g_strdup (_ ("shortcut")); - else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_MOUNTABLE)) - temp_string = g_strdup (_ ("mountable")); - else - { - gchar *description = g_content_type_get_description (content_type); - temp_string = g_strdup_printf (_ ("%s"), description); - g_free (description); - } - text_list = g_list_append (text_list, temp_string); - } - - /* append the original path (if any) */ - original_path = thunar_file_get_original_path (file); - if (G_UNLIKELY (original_path != NULL)) - { - /* append the original path to the statusbar text */ - gchar *original_path_string = g_filename_display_name (original_path); - temp_string = g_strdup_printf ("%s %s", _ ("Original Path:"), original_path_string); - text_list = g_list_append (text_list, temp_string); - g_free (original_path_string); - } - else if (thunar_file_is_local (file) - && thunar_file_is_regular (file) - && g_str_has_prefix (content_type, "image/")) /* bug #2913 */ - { - /* check if the size should be visible in the statusbar, disabled by - * default to avoid high i/o */ - g_object_get (preferences, "misc-image-size-in-statusbar", &show_image_size, NULL); - if (show_image_size) - { - /* check if we can determine the dimension of this file (only for image files) */ - gchar *file_path = g_file_get_path (thunar_file_get_file (file)); - if (file_path != NULL && gdk_pixbuf_get_file_info (file_path, &width, &height) != NULL) - { - /* append the image dimensions to the statusbar text */ - temp_string = g_strdup_printf ("%s %dx%d", _ ("Image Size:"), width, height); - text_list = g_list_append (text_list, temp_string); - } - g_free (file_path); - } - } - - if (show_last_modified) - { - date_string = thunar_file_get_date_string (file, THUNAR_FILE_DATE_MODIFIED, date_style, date_custom_style); - temp_string = g_strdup_printf (_ ("Last Modified: %s"), date_string); - text_list = g_list_append (text_list, temp_string); - g_free (date_string); - } - - g_object_unref (file); - } - else /* more than one item selected */ - { - gchar *selected_string; - /* build GList of files from selection */ - for (lp = selected_items; lp != NULL; lp = lp->next) - { - gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, lp->data); - _file = thunar_standard_view_model_get_file (model, &iter); - if (_file != NULL) - relevant_files = g_list_append (relevant_files, _file); - } - selected_string = thunar_util_get_statusbar_text_for_files (relevant_files, show_file_size_binary_format, date_style, date_custom_style); - temp_string = g_strdup_printf (_ ("Selection: %s"), selected_string); - text_list = g_list_append (text_list, temp_string); - g_list_free_full (relevant_files, g_object_unref); - g_free (selected_string); - } - - text = thunar_util_strjoin_list (text_list, " | "); - g_list_free_full (text_list, g_free); - g_object_unref (preferences); - return text; -} - - - static gboolean _thunar_standard_view_model_match_pattern_foreach (GtkTreeModel *model, GtkTreePath *path, diff --git a/thunar/thunar-standard-view-model.h b/thunar/thunar-standard-view-model.h index e6cd592f387174a855de4a36fc3bd38861f3df10..517c97cdaca920d9ea1092c4bd36ad5e330f7d07 100644 --- a/thunar/thunar-standard-view-model.h +++ b/thunar/thunar-standard-view-model.h @@ -141,9 +141,6 @@ GList *thunar_standard_view_model_get_paths_for_pattern (ThunarStanda const gchar *pattern, gboolean case_sensitive, gboolean match_diacritics); - -gchar *thunar_standard_view_model_get_statusbar_text (ThunarStandardViewModel *model, - GList *selected_items); ThunarJob *thunar_standard_view_model_get_job (ThunarStandardViewModel *model); void thunar_standard_view_model_set_job (ThunarStandardViewModel *model, ThunarJob *job); diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index 3b8873b105e9f00bf61dc22d615e2850b5b2c16d..4d6865e0f1b20ef0238ac682e2526df74c1c425e 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -45,6 +45,7 @@ #include "thunar/thunar-gtk-extensions.h" #include "thunar/thunar-history.h" #include "thunar/thunar-icon-renderer.h" +#include "thunar/thunar-io-jobs.h" #include "thunar/thunar-text-renderer.h" #include "thunar/thunar-marshal.h" #include "thunar/thunar-pango-extensions.h" @@ -141,7 +142,7 @@ static gboolean thunar_standard_view_get_loading (Thu static void thunar_standard_view_set_loading (ThunarStandardView *standard_view, gboolean loading); static gboolean thunar_standard_view_get_searching (ThunarView *view); -static const gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); +static gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); static gboolean thunar_standard_view_get_show_hidden (ThunarView *view); static void thunar_standard_view_set_show_hidden (ThunarView *view, gboolean show_hidden); @@ -301,9 +302,11 @@ struct _ThunarStandardViewPrivate /* scroll_to_file support */ GHashTable *scroll_to_files; - /* statusbar */ + /* statusbar text is mutex protected, since filled by a dedicated ThunarJob */ gchar *statusbar_text; + GMutex statusbar_text_mutex; guint statusbar_text_idle_id; + ThunarJob *statusbar_job; /* right-click drag/popup support */ GList *drag_g_file_list; @@ -727,9 +730,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) /* override ThunarView's properties */ g_iface = g_type_default_interface_peek (THUNAR_TYPE_VIEW); - standard_view_props[PROP_STATUSBAR_TEXT] = - g_param_spec_override ("statusbar-text", - g_object_interface_find_property (g_iface, "statusbar-text")); standard_view_props[PROP_SHOW_HIDDEN] = g_param_spec_override ("show-hidden", @@ -746,6 +746,19 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) GTK_TYPE_ACCEL_GROUP, G_PARAM_WRITABLE); + /** + * ThunarStandardView:statusbar-text: + * + * The text to be displayed in the status bar. + **/ + standard_view_props[PROP_STATUSBAR_TEXT] = + g_param_spec_string ("statusbar-text", + "statusbar-text", + "statusbar-text", + NULL, + EXO_PARAM_READABLE); + + /* install all properties */ g_object_class_install_properties (gobject_class, N_PROPERTIES, standard_view_props); @@ -794,7 +807,6 @@ static void thunar_standard_view_view_init (ThunarViewIface *iface) { iface->get_loading = thunar_standard_view_get_loading; - iface->get_statusbar_text = thunar_standard_view_get_statusbar_text; iface->get_show_hidden = thunar_standard_view_get_show_hidden; iface->set_show_hidden = thunar_standard_view_set_show_hidden; iface->get_zoom_level = thunar_standard_view_get_zoom_level; @@ -874,6 +886,8 @@ thunar_standard_view_init (ThunarStandardView *standard_view) standard_view->priv->type = 0; standard_view->priv->css_provider = NULL; + + g_mutex_init (&standard_view->priv->statusbar_text_mutex); } static void thunar_standard_view_store_sort_column (ThunarStandardView *standard_view) @@ -1068,6 +1082,16 @@ thunar_standard_view_finalize (GObject *object) g_source_remove (standard_view->priv->statusbar_text_idle_id); g_free (standard_view->priv->statusbar_text); + if (standard_view->priv->statusbar_job != NULL) + { + g_signal_handlers_disconnect_by_data (standard_view->priv->statusbar_job, standard_view); + exo_job_cancel (EXO_JOB (standard_view->priv->statusbar_job)); + g_object_unref (standard_view->priv->statusbar_job); + standard_view->priv->statusbar_job = NULL; + } + + g_mutex_clear (&standard_view->priv->statusbar_text_mutex); + /* release the scroll_to_files hash table */ g_hash_table_destroy (standard_view->priv->scroll_to_files); @@ -1132,7 +1156,7 @@ thunar_standard_view_get_property (GObject *object, break; case PROP_STATUSBAR_TEXT: - g_value_set_static_string (value, thunar_view_get_statusbar_text (THUNAR_VIEW (object))); + g_value_set_string (value, thunar_standard_view_get_statusbar_text (THUNAR_VIEW (object))); break; case PROP_ZOOM_LEVEL: @@ -1698,8 +1722,18 @@ thunar_standard_view_set_loading (ThunarStandardView *standard_view, * scrolling after loading circumvents the scroll caused by gtk_tree_view_set_cell */ if (THUNAR_IS_DETAILS_VIEW (standard_view)) { + gchar *statusbar_text; + + statusbar_text = g_strdup (_("Loading folder contents...")); + thunar_standard_view_set_statusbar_text (standard_view, statusbar_text); + g_free (statusbar_text); + g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_STATUSBAR_TEXT]); + if (G_UNLIKELY (!loading)) { + /* update the statusbar text after loading is finished */ + thunar_standard_view_update_statusbar_text (standard_view); + if (standard_view->priv->scroll_to_file != NULL) { /* remember and reset the scroll_to_file reference */ @@ -1740,37 +1774,57 @@ thunar_standard_view_set_loading (ThunarStandardView *standard_view, /* notify listeners */ g_object_freeze_notify (G_OBJECT (standard_view)); g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_LOADING]); - thunar_standard_view_update_statusbar_text (standard_view); g_object_thaw_notify (G_OBJECT (standard_view)); } -static const gchar* -thunar_standard_view_get_statusbar_text (ThunarView *view) +static void +thunar_standard_view_load_statusbar_text_finished (ThunarJob *job, + ThunarStandardView *standard_view) { - ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); - GList *items; + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), NULL); + /* tell everybody that the statusbar text may have changed */ + g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_STATUSBAR_TEXT]); - /* generate the statusbar text on-demand */ - if (standard_view->priv->statusbar_text == NULL) + if (standard_view->priv->statusbar_job != NULL) { - /* query the selected items (actually a list of GtkTreePath's) */ - items = THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items (standard_view); + g_object_unref (standard_view->priv->statusbar_job); + standard_view->priv->statusbar_job = NULL; + } +} - /* we display a loading text if no items are - * selected and the view is loading - */ - if (items == NULL && standard_view->loading) - return _("Loading folder contents..."); - standard_view->priv->statusbar_text = thunar_standard_view_model_get_statusbar_text (standard_view->model, items); - g_list_free_full (items, (GDestroyNotify) gtk_tree_path_free); - } +void +thunar_standard_view_set_statusbar_text (ThunarStandardView *standard_view, + const gchar *text) +{ + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + g_mutex_lock (&standard_view->priv->statusbar_text_mutex); + g_free (standard_view->priv->statusbar_text); + standard_view->priv->statusbar_text = g_strdup (text); + g_mutex_unlock (&standard_view->priv->statusbar_text_mutex); +} + + +static gchar* +thunar_standard_view_get_statusbar_text (ThunarView *view) +{ + ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + gchar *text; + + _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), NULL); - return standard_view->priv->statusbar_text; + g_mutex_lock (&standard_view->priv->statusbar_text_mutex); + if (standard_view->priv->statusbar_text == 0) + text = g_strdup (" "); + else + text = g_strdup (standard_view->priv->statusbar_text); + g_mutex_unlock (&standard_view->priv->statusbar_text_mutex); + + return text; } @@ -2232,21 +2286,93 @@ thunar_standard_view_get_drop_file (ThunarStandardView *standard_view, +static void +thunar_standard_view_update_statusbar_text_error (ThunarJob *job, + ThunarStandardView *standard_view) +{ + g_warning ("Error while updating statusbar"); +} + + + static gboolean thunar_standard_view_update_statusbar_text_idle (gpointer data) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (data); + GList *selected_items_tree_path_list; + GtkTreeIter iter; + ThunarFile *file; _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE); - /* clear the current status text (will be recalculated on-demand) */ - g_free (standard_view->priv->statusbar_text); - standard_view->priv->statusbar_text = NULL; - standard_view->priv->statusbar_text_idle_id = 0; - /* tell everybody that the statusbar text may have changed (This will trigger a "get" and as such an update of the string) */ - g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_STATUSBAR_TEXT]); + /* cancel pending statusbar job, if any */ + if (standard_view->priv->statusbar_job != NULL) + { + g_signal_handlers_disconnect_by_data (standard_view->priv->statusbar_job, standard_view); + exo_job_cancel (EXO_JOB (standard_view->priv->statusbar_job)); + g_object_unref (standard_view->priv->statusbar_job); + standard_view->priv->statusbar_job = NULL; + } + + /* query the selected items */ + selected_items_tree_path_list = THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items (standard_view); + + if (selected_items_tree_path_list == NULL) /* nothing selected */ + { + standard_view->priv->statusbar_job = thunar_io_jobs_load_statusbar_text_for_folder (standard_view, thunar_standard_view_model_get_folder (standard_view->model)); + + g_signal_connect (standard_view->priv->statusbar_job, "error", G_CALLBACK (thunar_standard_view_update_statusbar_text_error), standard_view); + g_signal_connect (standard_view->priv->statusbar_job, "finished", G_CALLBACK (thunar_standard_view_load_statusbar_text_finished), standard_view); + + exo_job_launch (EXO_JOB (standard_view->priv->statusbar_job)); + } + else if (selected_items_tree_path_list->next == NULL) /* only one item selected */ + { + gchar *statusbar_text; + + /* resolve the iter for the single path */ + gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, selected_items_tree_path_list->data); + + /* get the file for the given iter */ + file = thunar_standard_view_model_get_file (standard_view->model, &iter); + + if (file == NULL) + return FALSE; + + /* For s single file we load the text without using a separate job */ + statusbar_text = thunar_util_get_statusbar_text_for_single_file (file); + if (statusbar_text != NULL) + thunar_standard_view_set_statusbar_text (standard_view, statusbar_text); + g_free (statusbar_text); + + g_object_unref (file); + g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_STATUSBAR_TEXT]); + } + else /* more than one item selected */ + { + GList *selected_files = NULL; + GList *lp; + + /* build GList of files from selection */ + for (lp = selected_items_tree_path_list; lp != NULL; lp = lp->next) + { + gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, lp->data); + file = thunar_standard_view_model_get_file (standard_view->model, &iter); + if (file != NULL) + selected_files = g_list_append (selected_files, file); + } + + standard_view->priv->statusbar_job = thunar_io_jobs_load_statusbar_text_for_selection (standard_view, selected_files); + g_signal_connect (standard_view->priv->statusbar_job, "error", G_CALLBACK (thunar_standard_view_update_statusbar_text_error), standard_view); + g_signal_connect (standard_view->priv->statusbar_job, "finished", G_CALLBACK (thunar_standard_view_load_statusbar_text_finished), standard_view); + g_list_free_full (selected_files, g_object_unref); + + exo_job_launch (EXO_JOB (standard_view->priv->statusbar_job)); + } + + g_list_free_full (selected_items_tree_path_list, (GDestroyNotify) gtk_tree_path_free); return FALSE; } @@ -2263,7 +2389,7 @@ thunar_standard_view_update_statusbar_text (ThunarStandardView *standard_view) /* restart a new one, this way we avoid multiple update when * the user is pressing a key to scroll */ standard_view->priv->statusbar_text_idle_id = - g_timeout_add_full (G_PRIORITY_LOW, 500, thunar_standard_view_update_statusbar_text_idle, + g_timeout_add_full (G_PRIORITY_LOW, 50, thunar_standard_view_update_statusbar_text_idle, standard_view, NULL); } diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h index e3e814ff9b5e79497707e3d0751804bcda9383da..d7dffc6f5f0885c6222c2b31b4b32b38c01327d7 100644 --- a/thunar/thunar-standard-view.h +++ b/thunar/thunar-standard-view.h @@ -210,6 +210,8 @@ GType thunar_standard_view_get_saved_view_type (ThunarStandardVi XfceGtkActionEntry *thunar_standard_view_get_action_entries (void); void thunar_standard_view_queue_redraw (ThunarStandardView *standard_view); +void thunar_standard_view_set_statusbar_text (ThunarStandardView *standard_view, + const gchar* text); G_END_DECLS; diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c index a7c48cfcf39fb454dabc871219c482d93209620d..4d4f4823125b451f5a5259bc9a0c67d78424d350 100644 --- a/thunar/thunar-util.c +++ b/thunar/thunar-util.c @@ -1208,7 +1208,8 @@ gchar* thunar_util_get_statusbar_text_for_files (GList *files, gboolean show_file_size_binary_format, ThunarDateStyle date_style, - const gchar *date_custom_style) + const gchar *date_custom_style, + guint status_bar_actve_info) { guint64 size_summary = 0; gint folder_count = 0; @@ -1219,19 +1220,14 @@ thunar_util_get_statusbar_text_for_files (GList *files, gchar *temp_string = NULL; gchar *folder_text = NULL; gchar *non_folder_text = NULL; - ThunarPreferences *preferences; - guint active; guint64 last_modified_date = 0; guint64 temp_last_modified_date; GFileInfo *last_modified_file = NULL; gboolean show_size, show_size_in_bytes, show_last_modified; - preferences = thunar_preferences_get (); - g_object_get (G_OBJECT (preferences), "misc-status-bar-active-info", &active, NULL); - show_size = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE); - show_size_in_bytes = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE_IN_BYTES); - show_last_modified = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_LAST_MODIFIED); - g_object_unref (preferences); + show_size = thunar_status_bar_info_check_active (status_bar_actve_info, THUNAR_STATUS_BAR_INFO_SIZE); + show_size_in_bytes = thunar_status_bar_info_check_active (status_bar_actve_info, THUNAR_STATUS_BAR_INFO_SIZE_IN_BYTES); + show_last_modified = thunar_status_bar_info_check_active (status_bar_actve_info, THUNAR_STATUS_BAR_INFO_LAST_MODIFIED); /* analyze files */ for (lp = files; lp != NULL; lp = lp->next) @@ -1315,6 +1311,127 @@ thunar_util_get_statusbar_text_for_files (GList *files, temp_string = thunar_util_strjoin_list (text_list, " | "); g_list_free_full (text_list, g_free); - g_object_unref (last_modified_file); + if (last_modified_file != NULL) + g_object_unref (last_modified_file); return temp_string; +} + + + +gchar* +thunar_util_get_statusbar_text_for_single_file (ThunarFile *file) +{ + const gchar *content_type; + const gchar *original_path; + GList *text_list = NULL; + gchar *temp_string = NULL; + gchar *text = ""; + gint height; + gint width; + ThunarPreferences *preferences; + gboolean show_image_size; + gboolean show_file_size_binary_format; + guint active; + gboolean show_size, show_size_in_bytes, show_filetype, show_display_name, show_last_modified; + ThunarDateStyle date_style; + gchar *date_custom_style; + gchar *date_string; + + preferences = thunar_preferences_get (); + g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, + "misc_date-custom-style", &date_custom_style, + "misc-status-bar-active-info", &active, + "misc-file-size-binary", &show_file_size_binary_format, NULL); + show_size = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE); + show_size_in_bytes = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_SIZE_IN_BYTES); + show_filetype = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_FILETYPE); + show_display_name = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_DISPLAY_NAME); + show_last_modified = thunar_status_bar_info_check_active (active, THUNAR_STATUS_BAR_INFO_LAST_MODIFIED); + + /* determine the content type of the file */ + content_type = thunar_file_get_content_type (file); + + if (show_display_name == TRUE) + { + if (g_strcmp0 (thunar_file_get_display_name (file), thunar_file_get_basename (file)) != 0) + temp_string = g_strdup_printf (_ ("\"%s\" (%s)"), thunar_file_get_display_name (file), thunar_file_get_basename (file)); + else + temp_string = g_strdup_printf (_ ("\"%s\""), thunar_file_get_display_name (file)); + text_list = g_list_append (text_list, temp_string); + } + + if (thunar_file_is_regular (file) || G_UNLIKELY (thunar_file_is_symlink (file))) + { + if (show_size == TRUE) + { + if (show_size_in_bytes == TRUE) + temp_string = thunar_file_get_size_string_long (file, show_file_size_binary_format); + else + temp_string = thunar_file_get_size_string_formatted (file, show_file_size_binary_format); + text_list = g_list_append (text_list, temp_string); + } + } + + if (show_filetype == TRUE) + { + if (G_UNLIKELY (content_type != NULL && g_str_equal (content_type, "inode/symlink"))) + temp_string = g_strdup (_ ("broken link")); + else if (G_UNLIKELY (thunar_file_is_symlink (file))) + temp_string = g_strdup_printf (_ ("link to %s"), thunar_file_get_symlink_target (file)); + else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_SHORTCUT)) + temp_string = g_strdup (_ ("shortcut")); + else if (G_UNLIKELY (thunar_file_get_kind (file) == G_FILE_TYPE_MOUNTABLE)) + temp_string = g_strdup (_ ("mountable")); + else + { + gchar *description = g_content_type_get_description (content_type); + temp_string = g_strdup_printf (_ ("%s"), description); + g_free (description); + } + text_list = g_list_append (text_list, temp_string); + } + + /* append the original path (if any) */ + original_path = thunar_file_get_original_path (file); + if (G_UNLIKELY (original_path != NULL)) + { + /* append the original path to the statusbar text */ + gchar *original_path_string = g_filename_display_name (original_path); + temp_string = g_strdup_printf ("%s %s", _ ("Original Path:"), original_path_string); + text_list = g_list_append (text_list, temp_string); + g_free (original_path_string); + } + else if (thunar_file_is_local (file) + && thunar_file_is_regular (file) + && g_str_has_prefix (content_type, "image/")) /* bug #2913 */ + { + /* check if the size should be visible in the statusbar, disabled by + * default to avoid high i/o */ + g_object_get (preferences, "misc-image-size-in-statusbar", &show_image_size, NULL); + if (show_image_size) + { + /* check if we can determine the dimension of this file (only for image files) */ + gchar *file_path = g_file_get_path (thunar_file_get_file (file)); + if (file_path != NULL && gdk_pixbuf_get_file_info (file_path, &width, &height) != NULL) + { + /* append the image dimensions to the statusbar text */ + temp_string = g_strdup_printf ("%s %dx%d", _ ("Image Size:"), width, height); + text_list = g_list_append (text_list, temp_string); + } + g_free (file_path); + } + } + + if (show_last_modified) + { + date_string = thunar_file_get_date_string (file, THUNAR_FILE_DATE_MODIFIED, date_style, date_custom_style); + temp_string = g_strdup_printf (_ ("Last Modified: %s"), date_string); + text_list = g_list_append (text_list, temp_string); + g_free (date_string); + } + + text = thunar_util_strjoin_list (text_list, " | "); + g_list_free_full (text_list, g_free); + g_object_unref (preferences); + return text; } \ No newline at end of file diff --git a/thunar/thunar-util.h b/thunar/thunar-util.h index 391064b4d73ebe2b95400ad62ac0f86020045b21..28031354510def872b01f44ddaa1a36d1129a089 100644 --- a/thunar/thunar-util.h +++ b/thunar/thunar-util.h @@ -94,7 +94,9 @@ gboolean thunar_util_save_geometry_timer (gpointer user_data); gchar* thunar_util_get_statusbar_text_for_files (GList *files, gboolean show_file_size_binary_format, ThunarDateStyle date_style, - const gchar *date_custom_style); + const gchar *date_custom_style, + guint status_bar_actve_info); +gchar* thunar_util_get_statusbar_text_for_single_file (ThunarFile *file); G_END_DECLS; diff --git a/thunar/thunar-view.c b/thunar/thunar-view.c index 143f8b3a54d6bef493b1c30221a364308327b34a..c4540231f429abee1c53c71a91a88b5d2325bd4f 100644 --- a/thunar/thunar-view.c +++ b/thunar/thunar-view.c @@ -81,21 +81,6 @@ thunar_view_class_init (gpointer klass) FALSE, EXO_PARAM_READABLE)); - /** - * ThunarView:statusbar-text: - * - * The text to be displayed in the status bar, which is associated - * with this #ThunarView instance. Implementations should invoke - * #g_object_notify() on this property, whenever they have a new - * text to be display in the status bar (e.g. the selection changed - * or similar). - **/ - g_object_interface_install_property (klass, - g_param_spec_string ("statusbar-text", - "statusbar-text", - "statusbar-text", - NULL, - EXO_PARAM_READABLE)); /** * ThunarView:show-hidden: @@ -145,25 +130,6 @@ thunar_view_get_loading (ThunarView *view) -/** - * thunar_view_get_statusbar_text: - * @view : a #ThunarView instance. - * - * Queries the text that should be displayed in the status bar - * associated with @view. - * - * Return value: the text to be displayed in the status bar - * asssociated with @view. - **/ -const gchar* -thunar_view_get_statusbar_text (ThunarView *view) -{ - _thunar_return_val_if_fail (THUNAR_IS_VIEW (view), NULL); - return (*THUNAR_VIEW_GET_IFACE (view)->get_statusbar_text) (view); -} - - - /** * thunar_view_get_show_hidden: * @view : a #ThunarView instance. diff --git a/thunar/thunar-view.h b/thunar/thunar-view.h index 4dc641a953b0aca8ab7af828d66af78d2fa3f68f..13fca0a9ba10cec6d412715fa954230b13550ad2 100644 --- a/thunar/thunar-view.h +++ b/thunar/thunar-view.h @@ -40,8 +40,6 @@ struct _ThunarViewIface /* virtual methods */ gboolean (*get_loading) (ThunarView *view); - const gchar *(*get_statusbar_text) (ThunarView *view); - gboolean (*get_show_hidden) (ThunarView *view); void (*set_show_hidden) (ThunarView *view, gboolean show_hidden); @@ -72,7 +70,6 @@ struct _ThunarViewIface GType thunar_view_get_type (void) G_GNUC_CONST; gboolean thunar_view_get_loading (ThunarView *view); -const gchar *thunar_view_get_statusbar_text (ThunarView *view); gboolean thunar_view_get_show_hidden (ThunarView *view); void thunar_view_set_show_hidden (ThunarView *view, diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 6a9b64bcb0874f2beef81636511e156ba17b8116..60b29525d0c30818446026734a596d162a4144da 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -1059,7 +1059,7 @@ thunar_window_init (ThunarWindow *window) thunar_statusbar_setup_event (THUNAR_STATUSBAR (window->statusbar), event_box); if (G_LIKELY (window->view != NULL)) - thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); + thunar_window_binding_create (window, THUNAR_STANDARD_VIEW (window->view), "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); /* ensure that all the view types are registered */ g_type_ensure (THUNAR_TYPE_ICON_VIEW); @@ -2192,7 +2192,7 @@ thunar_window_switch_current_view (ThunarWindow *window, /* connect to the statusbar (if any) */ if (G_LIKELY (window->statusbar != NULL)) { - thunar_window_binding_create (window, new_view, "statusbar-text", + thunar_window_binding_create (window, THUNAR_STANDARD_VIEW (new_view), "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); }