mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-08-24 18:25:50 +00:00
No more overlapping desktop icons.
2008-08-24 Christian Neumair <cneumair@gnome.org> * libnautilus-private/nautilus-directory.c (nautilus_directory_schedule_position_set): * libnautilus-private/nautilus-file.c (get_time_from_time_string), (nautilus_file_get_time_metadata), (nautilus_file_set_time_metadata): * libnautilus-private/nautilus-file.h: * libnautilus-private/nautilus-icon-container.c (lay_down_icons_vertical_desktop), (nautilus_icon_container_class_init), (nautilus_icon_container_instance_init), (nautilus_icon_container_clear), (finish_adding_new_icons), (is_old_or_unknown_icon_data), (nautilus_icon_container_add), (nautilus_icon_container_begin_loading), (store_layout_timestamps_now), (nautilus_icon_container_end_loading), (nautilus_icon_container_get_store_layout_timestamps), (nautilus_icon_container_set_store_layout_timestamps): * libnautilus-private/nautilus-icon-container.h: * libnautilus-private/nautilus-icon-dnd.c (handle_local_move): * libnautilus-private/nautilus-icon-private.h: * libnautilus-private/nautilus-metadata.h: * src/file-manager/fm-desktop-icon-view.c (fm_desktop_icon_view_init): * src/file-manager/fm-directory-view.c (done_loading), (display_pending_files), (fm_directory_view_end_loading), (fm_directory_view_stop), (fm_directory_view_class_init): * src/file-manager/fm-directory-view.h: * src/file-manager/fm-icon-view.c (fm_icon_view_add_file), (fm_icon_view_begin_loading), (fm_icon_view_end_loading), (fm_icon_view_screen_changed), (get_stored_layout_timestamp), (store_layout_timestamp), (create_icon_container): No more overlapping desktop icons. Implement a layout timestamp concept where each file on the desktop and the desktop directory itself is timestamped when a full layout happened. Iff files were not part of the last layout (or added more recently, through DND), they are treated as being “semi-positioned“ (cf. 2005-11-07). This means that they may be freely shifted around, starting from their last position, until they don't overlap and fully laid out items. Should inter alia fix #330298. svn path=/trunk/; revision=14519
This commit is contained in:
parent
abc9377fa8
commit
40c79aec2d
44
ChangeLog
44
ChangeLog
|
@ -1,3 +1,47 @@
|
|||
2008-08-24 Christian Neumair <cneumair@gnome.org>
|
||||
|
||||
* libnautilus-private/nautilus-directory.c
|
||||
(nautilus_directory_schedule_position_set):
|
||||
* libnautilus-private/nautilus-file.c (get_time_from_time_string),
|
||||
(nautilus_file_get_time_metadata),
|
||||
(nautilus_file_set_time_metadata):
|
||||
* libnautilus-private/nautilus-file.h:
|
||||
* libnautilus-private/nautilus-icon-container.c
|
||||
(lay_down_icons_vertical_desktop),
|
||||
(nautilus_icon_container_class_init),
|
||||
(nautilus_icon_container_instance_init),
|
||||
(nautilus_icon_container_clear), (finish_adding_new_icons),
|
||||
(is_old_or_unknown_icon_data), (nautilus_icon_container_add),
|
||||
(nautilus_icon_container_begin_loading),
|
||||
(store_layout_timestamps_now),
|
||||
(nautilus_icon_container_end_loading),
|
||||
(nautilus_icon_container_get_store_layout_timestamps),
|
||||
(nautilus_icon_container_set_store_layout_timestamps):
|
||||
* libnautilus-private/nautilus-icon-container.h:
|
||||
* libnautilus-private/nautilus-icon-dnd.c (handle_local_move):
|
||||
* libnautilus-private/nautilus-icon-private.h:
|
||||
* libnautilus-private/nautilus-metadata.h:
|
||||
* src/file-manager/fm-desktop-icon-view.c
|
||||
(fm_desktop_icon_view_init):
|
||||
* src/file-manager/fm-directory-view.c (done_loading),
|
||||
(display_pending_files), (fm_directory_view_end_loading),
|
||||
(fm_directory_view_stop), (fm_directory_view_class_init):
|
||||
* src/file-manager/fm-directory-view.h:
|
||||
* src/file-manager/fm-icon-view.c (fm_icon_view_add_file),
|
||||
(fm_icon_view_begin_loading), (fm_icon_view_end_loading),
|
||||
(fm_icon_view_screen_changed), (get_stored_layout_timestamp),
|
||||
(store_layout_timestamp), (create_icon_container):
|
||||
No more overlapping desktop icons.
|
||||
|
||||
Implement a layout timestamp concept where each file on the desktop
|
||||
and the desktop directory itself is timestamped when a full layout
|
||||
happened. Iff files were not part of the last layout (or added more
|
||||
recently, through DND), they are treated as being “semi-positioned“
|
||||
(cf. 2005-11-07).
|
||||
This means that they may be freely shifted around, starting from their
|
||||
last position, until they don't overlap and fully laid out items.
|
||||
Should inter alia fix #330298.
|
||||
|
||||
2008-08-24 Christian Neumair <cneumair@gnome.org>
|
||||
|
||||
* libnautilus-private/nautilus-icon-container.c
|
||||
|
|
|
@ -1591,6 +1591,9 @@ nautilus_directory_schedule_position_set (GList *position_setting_list)
|
|||
const NautilusFileChangesQueuePosition *item;
|
||||
NautilusFile *file;
|
||||
char str[64];
|
||||
time_t now;
|
||||
|
||||
time (&now);
|
||||
|
||||
for (p = position_setting_list; p != NULL; p = p->next) {
|
||||
item = (NautilusFileChangesQueuePosition *) p->data;
|
||||
|
@ -1608,6 +1611,18 @@ nautilus_directory_schedule_position_set (GList *position_setting_list)
|
|||
NULL,
|
||||
str);
|
||||
|
||||
if (item->set) {
|
||||
nautilus_file_set_time_metadata
|
||||
(file,
|
||||
NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
|
||||
now);
|
||||
} else {
|
||||
nautilus_file_set_time_metadata
|
||||
(file,
|
||||
NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
|
||||
UNDEFINED_TIME);
|
||||
}
|
||||
|
||||
if (item->set) {
|
||||
g_snprintf (str, sizeof (str), "%d", item->screen);
|
||||
} else {
|
||||
|
|
|
@ -2976,6 +2976,62 @@ nautilus_file_get_integer_metadata (NautilusFile *file,
|
|||
default_metadata);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_time_from_time_string (const char *time_string,
|
||||
time_t *time)
|
||||
{
|
||||
long scanned_time;
|
||||
char c;
|
||||
|
||||
g_assert (time != NULL);
|
||||
|
||||
/* Only accept string if it has one integer with nothing
|
||||
* afterwards.
|
||||
*/
|
||||
if (time_string == NULL ||
|
||||
sscanf (time_string, "%ld%c", &scanned_time, &c) != 1) {
|
||||
return FALSE;
|
||||
}
|
||||
*time = (time_t) scanned_time;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
time_t
|
||||
nautilus_file_get_time_metadata (NautilusFile *file,
|
||||
const char *key)
|
||||
{
|
||||
time_t time;
|
||||
char *time_string;
|
||||
|
||||
time_string = nautilus_file_get_metadata (file, key, NULL);
|
||||
if (!get_time_from_time_string (time_string, &time)) {
|
||||
time = UNDEFINED_TIME;
|
||||
}
|
||||
g_free (time_string);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_file_set_time_metadata (NautilusFile *file,
|
||||
const char *key,
|
||||
time_t time)
|
||||
{
|
||||
char time_str[21];
|
||||
char *metadata;
|
||||
|
||||
if (time != UNDEFINED_TIME) {
|
||||
/* 2^64 turns out to be 20 characters */
|
||||
snprintf (time_str, 20, "%ld", time);
|
||||
time_str[20] = '\0';
|
||||
metadata = time_str;
|
||||
} else {
|
||||
metadata = NULL;
|
||||
}
|
||||
|
||||
nautilus_file_set_metadata (file, key, NULL, metadata);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nautilus_file_set_boolean_metadata (NautilusFile *file,
|
||||
|
|
|
@ -330,6 +330,14 @@ void nautilus_file_set_integer_metadata (Nautilu
|
|||
int default_metadata,
|
||||
int metadata);
|
||||
|
||||
#define UNDEFINED_TIME ((time_t) (-1))
|
||||
|
||||
time_t nautilus_file_get_time_metadata (NautilusFile *file,
|
||||
const char *key);
|
||||
void nautilus_file_set_time_metadata (NautilusFile *file,
|
||||
const char *key,
|
||||
time_t time);
|
||||
|
||||
|
||||
/* Attributes for file objects as user-displayable strings. */
|
||||
char * nautilus_file_get_string_attribute (NautilusFile *file,
|
||||
|
|
|
@ -152,6 +152,9 @@
|
|||
/* Copied from NautilusIconContainer */
|
||||
#define NAUTILUS_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT 5000
|
||||
|
||||
/* Copied from NautilusFile */
|
||||
#define UNDEFINED_TIME ((time_t) (-1))
|
||||
|
||||
enum {
|
||||
ACTION_ACTIVATE,
|
||||
ACTION_MENU,
|
||||
|
@ -216,6 +219,8 @@ static double get_mirror_x_position (NautilusIconContai
|
|||
NautilusIcon *icon,
|
||||
double x);
|
||||
|
||||
static void store_layout_timestamps_now (NautilusIconContainer *container);
|
||||
|
||||
static gpointer accessible_parent_class;
|
||||
|
||||
static GQuark accessible_private_data_quark = 0;
|
||||
|
@ -251,6 +256,8 @@ enum {
|
|||
GET_ICON_DROP_TARGET_URI,
|
||||
GET_STORED_ICON_POSITION,
|
||||
ICON_POSITION_CHANGED,
|
||||
GET_STORED_LAYOUT_TIMESTAMP,
|
||||
STORE_LAYOUT_TIMESTAMP,
|
||||
ICON_TEXT_CHANGED,
|
||||
ICON_STRETCH_STARTED,
|
||||
ICON_STRETCH_ENDED,
|
||||
|
@ -1925,7 +1932,6 @@ lay_down_icons_vertical_desktop (NautilusIconContainer *container, GList *icons)
|
|||
/* Start the icon in the first column */
|
||||
x = DESKTOP_PAD_HORIZONTAL + (SNAP_SIZE_X / 2) - ((icon_rect.x1 - icon_rect.x0) / 2);
|
||||
y = DESKTOP_PAD_VERTICAL + SNAP_SIZE_Y - (icon_rect.y1 - icon_rect.y0);
|
||||
g_message ("got rect y: %f", icon_rect.y1 - icon_rect.y0);
|
||||
|
||||
find_empty_location (container,
|
||||
grid,
|
||||
|
@ -5523,6 +5529,28 @@ nautilus_icon_container_class_init (NautilusIconContainerClass *class)
|
|||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER);
|
||||
signals[GET_STORED_LAYOUT_TIMESTAMP]
|
||||
= g_signal_new ("get_stored_layout_timestamp",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NautilusIconContainerClass,
|
||||
get_stored_layout_timestamp),
|
||||
NULL, NULL,
|
||||
eel_marshal_BOOLEAN__POINTER_POINTER,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER);
|
||||
signals[STORE_LAYOUT_TIMESTAMP]
|
||||
= g_signal_new ("store_layout_timestamp",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NautilusIconContainerClass,
|
||||
store_layout_timestamp),
|
||||
NULL, NULL,
|
||||
eel_marshal_BOOLEAN__POINTER_POINTER,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER);
|
||||
signals[LAYOUT_CHANGED]
|
||||
= g_signal_new ("layout_changed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
|
@ -5877,6 +5905,7 @@ nautilus_icon_container_instance_init (NautilusIconContainer *container)
|
|||
details = g_new0 (NautilusIconContainerDetails, 1);
|
||||
|
||||
details->icon_set = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
details->layout_timestamp = UNDEFINED_TIME;
|
||||
|
||||
details->zoom_level = NAUTILUS_ZOOM_LEVEL_STANDARD;
|
||||
|
||||
|
@ -6113,6 +6142,8 @@ nautilus_icon_container_clear (NautilusIconContainer *container)
|
|||
g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container));
|
||||
|
||||
details = container->details;
|
||||
details->layout_timestamp = UNDEFINED_TIME;
|
||||
details->store_layout_timestamps_when_finishing_new_icons = FALSE;
|
||||
|
||||
if (details->icons == NULL) {
|
||||
return;
|
||||
|
@ -6747,13 +6778,12 @@ finish_adding_new_icons (NautilusIconContainer *container)
|
|||
no_position_icons = semi_position_icons = NULL;
|
||||
for (p = new_icons; p != NULL; p = p->next) {
|
||||
icon = p->data;
|
||||
if (assign_icon_position (container, icon)) {
|
||||
if (!container->details->auto_layout && icon->has_lazy_position) {
|
||||
semi_position_icons = g_list_prepend (semi_position_icons, icon);
|
||||
}
|
||||
} else {
|
||||
no_position_icons = g_list_prepend (no_position_icons, icon);
|
||||
}
|
||||
if (icon->has_lazy_position) {
|
||||
assign_icon_position (container, icon);
|
||||
semi_position_icons = g_list_prepend (semi_position_icons, icon);
|
||||
} else if (!assign_icon_position (container, icon)) {
|
||||
no_position_icons = g_list_prepend (no_position_icons, icon);
|
||||
}
|
||||
|
||||
finish_adding_icon (container, icon);
|
||||
}
|
||||
|
@ -6780,6 +6810,7 @@ finish_adding_new_icons (NautilusIconContainer *container)
|
|||
|
||||
for (p = semi_position_icons; p != NULL; p = p->next) {
|
||||
NautilusIcon *icon;
|
||||
NautilusIconPosition position;
|
||||
int x, y;
|
||||
|
||||
icon = p->data;
|
||||
|
@ -6791,7 +6822,12 @@ finish_adding_new_icons (NautilusIconContainer *container)
|
|||
|
||||
icon_set_position (icon, x, y);
|
||||
|
||||
position.x = icon->x;
|
||||
position.y = icon->y;
|
||||
position.scale = icon->scale;
|
||||
placement_grid_mark_icon (grid, icon);
|
||||
g_signal_emit (container, signals[ICON_POSITION_CHANGED], 0,
|
||||
icon->data, &position);
|
||||
|
||||
/* ensure that next time we run this code, the formerly semi-positioned
|
||||
* icons are treated as being positioned. */
|
||||
|
@ -6808,28 +6844,50 @@ finish_adding_new_icons (NautilusIconContainer *container)
|
|||
g_assert (!container->details->auto_layout);
|
||||
|
||||
sort_icons (container, &no_position_icons);
|
||||
get_all_icon_bounds (container, NULL, NULL, NULL, &bottom, BOUNDS_USAGE_FOR_LAYOUT);
|
||||
lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM);
|
||||
if (nautilus_icon_container_get_is_desktop (container)) {
|
||||
lay_down_icons (container, no_position_icons, CONTAINER_PAD_TOP);
|
||||
} else {
|
||||
get_all_icon_bounds (container, NULL, NULL, NULL, &bottom, BOUNDS_USAGE_FOR_LAYOUT);
|
||||
lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM);
|
||||
}
|
||||
g_list_free (no_position_icons);
|
||||
}
|
||||
|
||||
if (container->details->store_layout_timestamps_when_finishing_new_icons) {
|
||||
store_layout_timestamps_now (container);
|
||||
container->details->store_layout_timestamps_when_finishing_new_icons = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_old_or_unknown_icon_data (NautilusIconContainer *container,
|
||||
NautilusIconData *data)
|
||||
{
|
||||
time_t timestamp;
|
||||
gboolean success;
|
||||
|
||||
if (container->details->layout_timestamp == UNDEFINED_TIME) {
|
||||
/* don't know */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_signal_emit (container,
|
||||
signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
|
||||
data, ×tamp, &success);
|
||||
return (!success || timestamp < container->details->layout_timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_icon_container_add:
|
||||
* @container: A NautilusIconContainer
|
||||
* @data: Icon data.
|
||||
* @has_lazy_position: Whether the saved icon position should only be used
|
||||
* if the previous icon position is free. If the position
|
||||
* is occupied, another position near the last one will
|
||||
* be used.
|
||||
*
|
||||
* Add icon to represent @data to container.
|
||||
* Returns FALSE if there was already such an icon.
|
||||
**/
|
||||
gboolean
|
||||
nautilus_icon_container_add (NautilusIconContainer *container,
|
||||
NautilusIconData *data,
|
||||
gboolean has_lazy_position)
|
||||
NautilusIconData *data)
|
||||
{
|
||||
NautilusIconContainerDetails *details;
|
||||
NautilusIcon *icon;
|
||||
|
@ -6849,7 +6907,12 @@ nautilus_icon_container_add (NautilusIconContainer *container,
|
|||
icon->data = data;
|
||||
icon->x = ICON_UNPOSITIONED_VALUE;
|
||||
icon->y = ICON_UNPOSITIONED_VALUE;
|
||||
icon->has_lazy_position = has_lazy_position;
|
||||
|
||||
/* Whether the saved icon position should only be used
|
||||
* if the previous icon position is free. If the position
|
||||
* is occupied, another position near the last one will
|
||||
*/
|
||||
icon->has_lazy_position = is_old_or_unknown_icon_data (container, data);
|
||||
icon->scale = 1.0;
|
||||
icon->item = NAUTILUS_ICON_CANVAS_ITEM
|
||||
(eel_canvas_item_new (EEL_CANVAS_GROUP (EEL_CANVAS (container)->root),
|
||||
|
@ -9151,5 +9214,68 @@ nautilus_icon_container_get_max_layout_lines (NautilusIconContainer *container)
|
|||
return limit;
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_icon_container_begin_loading (NautilusIconContainer *container)
|
||||
{
|
||||
gboolean dummy;
|
||||
|
||||
if (nautilus_icon_container_get_store_layout_timestamps (container)) {
|
||||
container->details->layout_timestamp = UNDEFINED_TIME;
|
||||
g_signal_emit (container,
|
||||
signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
|
||||
NULL, &container->details->layout_timestamp, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
store_layout_timestamps_now (NautilusIconContainer *container)
|
||||
{
|
||||
NautilusIcon *icon;
|
||||
GList *p;
|
||||
gboolean dummy;
|
||||
|
||||
container->details->layout_timestamp = time (NULL);
|
||||
g_signal_emit (container,
|
||||
signals[STORE_LAYOUT_TIMESTAMP], 0,
|
||||
NULL, &container->details->layout_timestamp, &dummy);
|
||||
|
||||
for (p = container->details->icons; p != NULL; p = p->next) {
|
||||
icon = p->data;
|
||||
|
||||
g_signal_emit (container,
|
||||
signals[STORE_LAYOUT_TIMESTAMP], 0,
|
||||
icon->data, &container->details->layout_timestamp, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nautilus_icon_container_end_loading (NautilusIconContainer *container,
|
||||
gboolean all_icons_added)
|
||||
{
|
||||
if (all_icons_added &&
|
||||
nautilus_icon_container_get_store_layout_timestamps (container)) {
|
||||
if (container->details->new_icons == NULL) {
|
||||
store_layout_timestamps_now (container);
|
||||
} else {
|
||||
container->details->store_layout_timestamps_when_finishing_new_icons = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_icon_container_get_store_layout_timestamps (NautilusIconContainer *container)
|
||||
{
|
||||
return container->details->store_layout_timestamps;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nautilus_icon_container_set_store_layout_timestamps (NautilusIconContainer *container,
|
||||
gboolean store_layout_timestamps)
|
||||
{
|
||||
container->details->store_layout_timestamps = store_layout_timestamps;
|
||||
}
|
||||
|
||||
|
||||
#endif /* ! NAUTILUS_OMIT_SELF_CHECK */
|
||||
|
|
|
@ -176,6 +176,24 @@ typedef struct {
|
|||
char * (* get_icon_drop_target_uri) (NautilusIconContainer *container,
|
||||
NautilusIconData *data);
|
||||
|
||||
/* If icon data is NULL, the layout timestamp of the container should be retrieved.
|
||||
* That is the time when the container displayed a fully loaded directory with
|
||||
* all icon positions assigned.
|
||||
*
|
||||
* If icon data is not NULL, the position timestamp of the icon should be retrieved.
|
||||
* That is the time when the file (i.e. icon data payload) was last displayed in a
|
||||
* fully loaded directory with all icon positions assigned.
|
||||
*/
|
||||
gboolean (* get_stored_layout_timestamp) (NautilusIconContainer *container,
|
||||
NautilusIconData *data,
|
||||
time_t *time);
|
||||
/* If icon data is NULL, the layout timestamp of the container should be stored.
|
||||
* If icon data is not NULL, the position timestamp of the container should be stored.
|
||||
*/
|
||||
gboolean (* store_layout_timestamp) (NautilusIconContainer *container,
|
||||
NautilusIconData *data,
|
||||
const time_t *time);
|
||||
|
||||
/* Notifications for the whole container. */
|
||||
void (* band_select_started) (NautilusIconContainer *container);
|
||||
void (* band_select_ended) (NautilusIconContainer *container);
|
||||
|
@ -214,8 +232,7 @@ GtkWidget * nautilus_icon_container_new (void);
|
|||
/* adding, removing, and managing icons */
|
||||
void nautilus_icon_container_clear (NautilusIconContainer *view);
|
||||
gboolean nautilus_icon_container_add (NautilusIconContainer *view,
|
||||
NautilusIconData *data,
|
||||
gboolean has_lazy_position);
|
||||
NautilusIconData *data);
|
||||
void nautilus_icon_container_layout_now (NautilusIconContainer *container);
|
||||
gboolean nautilus_icon_container_remove (NautilusIconContainer *view,
|
||||
NautilusIconData *data);
|
||||
|
@ -232,9 +249,11 @@ NautilusIconData *nautilus_icon_container_get_first_visible_icon (Nautilu
|
|||
void nautilus_icon_container_scroll_to_icon (NautilusIconContainer *container,
|
||||
NautilusIconData *data);
|
||||
|
||||
void nautilus_icon_container_begin_loading (NautilusIconContainer *container);
|
||||
void nautilus_icon_container_end_loading (NautilusIconContainer *container,
|
||||
gboolean all_icons_added);
|
||||
|
||||
/* control the layout */
|
||||
void nautilus_icon_container_set_is_reloading (NautilusIconContainer *container,
|
||||
gboolean is_reloading);
|
||||
gboolean nautilus_icon_container_is_auto_layout (NautilusIconContainer *container);
|
||||
void nautilus_icon_container_set_auto_layout (NautilusIconContainer *container,
|
||||
gboolean auto_layout);
|
||||
|
@ -313,6 +332,10 @@ void nautilus_icon_container_set_all_columns_same_width (NautilusIconContaine
|
|||
gboolean nautilus_icon_container_is_layout_rtl (NautilusIconContainer *container);
|
||||
gboolean nautilus_icon_container_is_layout_vertical (NautilusIconContainer *container);
|
||||
|
||||
gboolean nautilus_icon_container_get_store_layout_timestamps (NautilusIconContainer *container);
|
||||
void nautilus_icon_container_set_store_layout_timestamps (NautilusIconContainer *container,
|
||||
gboolean store_layout);
|
||||
|
||||
void nautilus_icon_container_widget_to_file_operation_position (NautilusIconContainer *container,
|
||||
GdkPoint *position);
|
||||
|
||||
|
|
|
@ -925,6 +925,7 @@ handle_local_move (NautilusIconContainer *container,
|
|||
NautilusFile *file;
|
||||
char screen_string[32];
|
||||
GdkScreen *screen;
|
||||
time_t now;
|
||||
|
||||
if (container->details->auto_layout) {
|
||||
if (!confirm_switch_to_manual_layout (container)) {
|
||||
|
@ -933,6 +934,7 @@ handle_local_move (NautilusIconContainer *container,
|
|||
nautilus_icon_container_freeze_icon_positions (container);
|
||||
}
|
||||
|
||||
time (&now);
|
||||
|
||||
/* Move and select the icons. */
|
||||
moved_icons = NULL;
|
||||
|
@ -955,10 +957,10 @@ handle_local_move (NautilusIconContainer *container,
|
|||
nautilus_file_set_metadata (file,
|
||||
NAUTILUS_METADATA_KEY_SCREEN,
|
||||
NULL, screen_string);
|
||||
nautilus_file_set_time_metadata (file,
|
||||
NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP, now);
|
||||
|
||||
nautilus_icon_container_add (container,
|
||||
NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
|
||||
FALSE);
|
||||
nautilus_icon_container_add (container, NAUTILUS_ICON_CONTAINER_ICON_DATA (file));
|
||||
|
||||
icon = nautilus_icon_container_get_icon_by_uri
|
||||
(container, item->uri);
|
||||
|
|
|
@ -273,7 +273,11 @@ struct NautilusIconContainerDetails {
|
|||
guint a11y_item_action_idle_handler;
|
||||
GQueue* a11y_item_action_queue;
|
||||
|
||||
eel_boolean_bit is_reloading : 1;
|
||||
eel_boolean_bit is_loading : 1;
|
||||
|
||||
eel_boolean_bit store_layout_timestamps : 1;
|
||||
eel_boolean_bit store_layout_timestamps_when_finishing_new_icons : 1;
|
||||
time_t layout_timestamp;
|
||||
|
||||
/* interactive search */
|
||||
gboolean disable_popdown;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY "icon_view_sort_by"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED "icon_view_sort_reversed"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED "icon_view_keep_aligned"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP "icon_view_layout_timestamp"
|
||||
|
||||
#define NAUTILUS_METADATA_KEY_LIST_VIEW_ZOOM_LEVEL "list_view_zoom_level"
|
||||
#define NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_COLUMN "list_view_sort_column"
|
||||
|
@ -69,6 +70,7 @@
|
|||
|
||||
#define NAUTILUS_METADATA_KEY_ANNOTATION "annotation"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_POSITION "icon_position"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP "icon_position_timestamp"
|
||||
#define NAUTILUS_METADATA_KEY_ICON_SCALE "icon_scale"
|
||||
#define NAUTILUS_METADATA_KEY_CUSTOM_ICON "custom_icon"
|
||||
#define NAUTILUS_METADATA_KEY_SCREEN "screen"
|
||||
|
|
|
@ -546,6 +546,7 @@ fm_desktop_icon_view_init (FMDesktopIconView *desktop_icon_view)
|
|||
|
||||
nautilus_icon_container_set_is_fixed_size (icon_container, TRUE);
|
||||
nautilus_icon_container_set_is_desktop (icon_container, TRUE);
|
||||
nautilus_icon_container_set_store_layout_timestamps (icon_container, TRUE);
|
||||
|
||||
/* Set allocation to be at 0, 0 */
|
||||
allocation = >K_WIDGET (icon_container)->allocation;
|
||||
|
|
|
@ -2343,7 +2343,8 @@ reveal_selection_idle_callback (gpointer data)
|
|||
}
|
||||
|
||||
static void
|
||||
done_loading (FMDirectoryView *view)
|
||||
done_loading (FMDirectoryView *view,
|
||||
gboolean all_files_seen)
|
||||
{
|
||||
GList *locations_selected, *selection;
|
||||
|
||||
|
@ -2393,7 +2394,7 @@ done_loading (FMDirectoryView *view)
|
|||
fm_directory_view_display_selection_info (view);
|
||||
}
|
||||
|
||||
fm_directory_view_end_loading (view);
|
||||
fm_directory_view_end_loading (view, all_files_seen);
|
||||
|
||||
view->details->loading = FALSE;
|
||||
}
|
||||
|
@ -2807,7 +2808,7 @@ display_pending_files (FMDirectoryView *view)
|
|||
if (view->details->model != NULL
|
||||
&& nautilus_directory_are_all_files_seen (view->details->model)
|
||||
&& g_hash_table_size (view->details->non_ready_files) == 0) {
|
||||
done_loading (view);
|
||||
done_loading (view, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3269,11 +3270,12 @@ fm_directory_view_begin_loading (FMDirectoryView *view)
|
|||
*
|
||||
**/
|
||||
void
|
||||
fm_directory_view_end_loading (FMDirectoryView *view)
|
||||
fm_directory_view_end_loading (FMDirectoryView *view,
|
||||
gboolean all_files_seen)
|
||||
{
|
||||
g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
|
||||
|
||||
g_signal_emit (view, signals[END_LOADING], 0);
|
||||
g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8791,7 +8793,7 @@ fm_directory_view_stop (FMDirectoryView *view)
|
|||
if (view->details->model != NULL) {
|
||||
nautilus_directory_file_monitor_remove (view->details->model, view);
|
||||
}
|
||||
done_loading (view);
|
||||
done_loading (view, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -9689,8 +9691,8 @@ fm_directory_view_class_init (FMDirectoryViewClass *klass)
|
|||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FMDirectoryViewClass, end_loading),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
g_cclosure_marshal_VOID__BOOLEAN,
|
||||
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
|
||||
signals[FILE_CHANGED] =
|
||||
g_signal_new ("file_changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
|
|
|
@ -108,8 +108,16 @@ struct FMDirectoryViewClass {
|
|||
* of a directory are added to the view. It can be replaced by a
|
||||
* subclass to do any necessary clean-up. The default implementation
|
||||
* does nothing.
|
||||
*
|
||||
* If all_files_seen is true, the handler may assume that
|
||||
* no load error ocurred, and all files of the underlying
|
||||
* directory were loaded.
|
||||
*
|
||||
* Otherwise, end_loading was emitted due to cancellation,
|
||||
* which usually means that not all files are available.
|
||||
*/
|
||||
void (* end_loading) (FMDirectoryView *view);
|
||||
void (* end_loading) (FMDirectoryView *view,
|
||||
gboolean all_files_seen);
|
||||
|
||||
/* The 'load_error' signal is emitted when the directory model
|
||||
* reports an error in the process of monitoring the directory's
|
||||
|
@ -382,7 +390,8 @@ gboolean fm_directory_view_get_active (FMDirect
|
|||
*/
|
||||
void fm_directory_view_clear (FMDirectoryView *view);
|
||||
void fm_directory_view_begin_loading (FMDirectoryView *view);
|
||||
void fm_directory_view_end_loading (FMDirectoryView *view);
|
||||
void fm_directory_view_end_loading (FMDirectoryView *view,
|
||||
gboolean all_files_seen);
|
||||
|
||||
gboolean fm_directory_view_get_loading (FMDirectoryView *view);
|
||||
|
||||
|
|
|
@ -269,6 +269,7 @@ get_stored_icon_position_callback (NautilusIconContainer *container,
|
|||
return position_good;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
set_sort_criterion (FMIconView *icon_view, const SortCriterion *sort)
|
||||
{
|
||||
|
@ -495,28 +496,6 @@ fm_icon_view_remove_file (FMDirectoryView *view, NautilusFile *file, NautilusDir
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_has_lazy_position (FMDirectoryView *view,
|
||||
NautilusFile *file)
|
||||
{
|
||||
gboolean lazy_position;
|
||||
|
||||
/* For volumes (i.e. cdrom icon) we use lazy positioning so that when
|
||||
* an old cdrom gets re-mounted in a place that now has another
|
||||
* icon we don't overlap that one. We don't do this in general though,
|
||||
* as it can cause icons moving around.
|
||||
*/
|
||||
lazy_position = nautilus_file_can_unmount (file);
|
||||
if (lazy_position && fm_directory_view_get_loading (view)) {
|
||||
/* if volumes are loaded during directory load, don't mark them
|
||||
* as lazy. This is wrong for files that were mounted during user
|
||||
* log-off, but it is right for files that were mounted during login. */
|
||||
lazy_position = FALSE;
|
||||
}
|
||||
|
||||
return lazy_position;
|
||||
}
|
||||
|
||||
static void
|
||||
fm_icon_view_add_file (FMDirectoryView *view, NautilusFile *file, NautilusDirectory *directory)
|
||||
{
|
||||
|
@ -539,8 +518,7 @@ fm_icon_view_add_file (FMDirectoryView *view, NautilusFile *file, NautilusDirect
|
|||
}
|
||||
|
||||
if (nautilus_icon_container_add (icon_container,
|
||||
NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
|
||||
file_has_lazy_position (view, file))) {
|
||||
NAUTILUS_ICON_CONTAINER_ICON_DATA (file))) {
|
||||
nautilus_file_ref (file);
|
||||
}
|
||||
}
|
||||
|
@ -1128,6 +1106,8 @@ fm_icon_view_begin_loading (FMDirectoryView *view)
|
|||
file = fm_directory_view_get_directory_as_file (view);
|
||||
icon_container = GTK_WIDGET (get_icon_container (icon_view));
|
||||
|
||||
nautilus_icon_container_begin_loading (NAUTILUS_ICON_CONTAINER (icon_container));
|
||||
|
||||
nautilus_icon_container_set_allow_moves (NAUTILUS_ICON_CONTAINER (icon_container),
|
||||
fm_directory_view_get_allow_moves (view));
|
||||
|
||||
|
@ -1206,11 +1186,16 @@ fm_icon_view_begin_loading (FMDirectoryView *view)
|
|||
}
|
||||
|
||||
static void
|
||||
fm_icon_view_end_loading (FMDirectoryView *view)
|
||||
fm_icon_view_end_loading (FMDirectoryView *view,
|
||||
gboolean all_files_seen)
|
||||
{
|
||||
FMIconView *icon_view;
|
||||
GtkWidget *icon_container;
|
||||
|
||||
icon_view = FM_ICON_VIEW (view);
|
||||
|
||||
icon_container = GTK_WIDGET (get_icon_container (icon_view));
|
||||
nautilus_icon_container_end_loading (NAUTILUS_ICON_CONTAINER (icon_container), all_files_seen);
|
||||
}
|
||||
|
||||
static NautilusZoomLevel
|
||||
|
@ -2180,8 +2165,7 @@ fm_icon_view_screen_changed (GtkWidget *widget,
|
|||
fm_icon_view_remove_file (view, file, directory);
|
||||
} else {
|
||||
if (nautilus_icon_container_add (icon_container,
|
||||
NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
|
||||
file_has_lazy_position (view, file))) {
|
||||
NAUTILUS_ICON_CONTAINER_ICON_DATA (file))) {
|
||||
nautilus_file_ref (file);
|
||||
}
|
||||
}
|
||||
|
@ -2573,6 +2557,62 @@ fm_icon_view_update_click_mode (FMIconView *icon_view)
|
|||
click_mode == NAUTILUS_CLICK_POLICY_SINGLE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_stored_layout_timestamp (NautilusIconContainer *container,
|
||||
NautilusIconData *icon_data,
|
||||
time_t *timestamp,
|
||||
FMIconView *view)
|
||||
{
|
||||
NautilusFile *file;
|
||||
NautilusDirectory *directory;
|
||||
|
||||
if (icon_data == NULL) {
|
||||
directory = fm_directory_view_get_model (FM_DIRECTORY_VIEW (view));
|
||||
if (directory == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = nautilus_directory_get_corresponding_file (directory);
|
||||
*timestamp = nautilus_file_get_time_metadata (file,
|
||||
NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP);
|
||||
nautilus_file_unref (file);
|
||||
} else {
|
||||
*timestamp = nautilus_file_get_time_metadata (NAUTILUS_FILE (icon_data),
|
||||
NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
store_layout_timestamp (NautilusIconContainer *container,
|
||||
NautilusIconData *icon_data,
|
||||
const time_t *timestamp,
|
||||
FMIconView *view)
|
||||
{
|
||||
NautilusFile *file;
|
||||
NautilusDirectory *directory;
|
||||
|
||||
if (icon_data == NULL) {
|
||||
directory = fm_directory_view_get_model (FM_DIRECTORY_VIEW (view));
|
||||
if (directory == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = nautilus_directory_get_corresponding_file (directory);
|
||||
nautilus_file_set_time_metadata (file,
|
||||
NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP,
|
||||
(time_t) *timestamp);
|
||||
nautilus_file_unref (file);
|
||||
} else {
|
||||
nautilus_file_set_time_metadata (NAUTILUS_FILE (icon_data),
|
||||
NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
|
||||
(time_t) *timestamp);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NautilusIconContainer *
|
||||
create_icon_container (FMIconView *icon_view)
|
||||
{
|
||||
|
@ -2626,6 +2666,11 @@ create_icon_container (FMIconView *icon_view)
|
|||
G_CALLBACK (fm_directory_view_update_menus), icon_view,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (icon_container, "get_stored_layout_timestamp",
|
||||
G_CALLBACK (get_stored_layout_timestamp), icon_view, 0);
|
||||
g_signal_connect_object (icon_container, "store_layout_timestamp",
|
||||
G_CALLBACK (store_layout_timestamp), icon_view, 0);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (icon_view),
|
||||
GTK_WIDGET (icon_container));
|
||||
|
||||
|
|
Loading…
Reference in a new issue