From: John Ellis Date: Wed, 13 Apr 2005 22:29:53 +0000 (+0000) Subject: Wed Apr 13 18:16:14 2005 John Ellis X-Git-Tag: v1.0.0~1766 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=379a5aef4b251faa7ff2c68d30161824ea4c9b1c Wed Apr 13 18:16:14 2005 John Ellis * cache-loader.[ch]: New utility to load cache-able data. * cache.[ch]: Add embedded (exif) date caching. * pan-view.c: Use new cache loading mechanism. Add exif date support to timeline and calendar view. * src/Makefile.am: Add cache-loader.[c,h]. ##### Note: GQview CVS on sourceforge is not always up to date, please use ##### ##### an offical release when making enhancements and translation updates. ##### --- diff --git a/ChangeLog b/ChangeLog index 70ba8918..7cc7bc58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Wed Apr 13 18:16:14 2005 John Ellis + + * cache-loader.[ch]: New utility to load cache-able data. + * cache.[ch]: Add embedded (exif) date caching. + * pan-view.c: Use new cache loading mechanism. Add exif date support + to timeline and calendar view. + * src/Makefile.am: Add cache-loader.[c,h]. + Tue Apr 12 07:59:20 2005 John Ellis * pan-view.c: Use mostly neutral (gray) colors in the pan view to avoid diff --git a/TODO b/TODO index 772164b5..9db50ccb 100644 --- a/TODO +++ b/TODO @@ -5,31 +5,22 @@ Major: ---------------------------------------------- > pixbuf-renderer.c: - d> fix two pass render from corrupting it->qd pointer (need one pointer for each queue?). - d> fix image_change_from_image (to do this need a pixbuf_renderer_move_image). - d> fix broken zoom out drawing when using source tiles. - d> fix 2pass zoom when using source tiles and zoomed out (not always rendering second pass) - d> pixbuf_renderer_move should be clearing the tiles of the source image since they are no longer - valid and are then wasting memory (for example when full screen is active). + > tile dispose order is slightly incorrect, furthest ones from current position should be dropped first + > image.c: - d> need to keep a list of ImageWindows and provide function to sync options to each object. d> test and probably fix delay_flip. > UPDATE: works as before (pre pixbuf-renderer), but should be fixed to provide a single redraw by pre-rendering any scaled tiles that are visible before signaling 'render_complete'. > make this a g_object with signals for completed, changed, etc. - d> fix region computation rounding when updating scaled image in 'area ready' signal. > fix delay flip 'completed' signal (full screen busy cursor is not always turned off) - d> fix slow loading of images when zoomed out - bug could be poor clamping to visible in PixbufRenderer. + + > cache-load.c: + > should honor enable_thumbnails setting > work on pan view: > Pick a better keyboard shortcut than Control + J :) - d> Fix occasional redraw bugs when zoomed out. - d> Fix occasional odd requests for non-visible tiles when zoomed out (related to above?). - d> Fix slowness in image.c with huge grid size by changing use of pre-allocated tile array - to on-demand tile allocation (can this be implemented like source tiles?). - OR: use an array so that we do not need to walk a GList of pre-allocated tile containers w> Fix search scrolling to try to center image and info popup. > Fix info popup location to opposing horizontal side when near edge of grid. > Find something to do with middle mouse clicks. @@ -37,12 +28,16 @@ Major: > search should highlight all matching images (with toggle?) > should non-thumbnail images have a drop shadow? d> optimize pixbuf_draw_line (line endpoints should clip to draw region before draw loop) + > introduced bug (looks like clamp or rounding error) d> optimize pixbuf_draw_triangle + > introduced bug (round error?) > does new pixbuf_draw_triangle contain line edge rounding error? - d> move pixbuf_draw_* stuff into pixbuf_util.c + > check ref counting of image when redrawing after finish loading + > speed up sorting image.. stage when sorting/merging cache list + > time line view: - > allow use of file date or EXIF (embedded) date. + w> allow use of file date or EXIF (embedded) date. > allow horizontal _or_ vertical orientation. > calendar view: diff --git a/src/Makefile.am b/src/Makefile.am index 647d9cbd..e33c1f75 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,8 @@ gqview_SOURCES = \ bar_sort.h \ cache.c \ cache.h \ + cache-loader.c \ + cache-loader.h \ cache_maint.c \ cache_maint.h \ cellrenderericon.c \ diff --git a/src/cache-loader.c b/src/cache-loader.c new file mode 100644 index 00000000..05c4e464 --- /dev/null +++ b/src/cache-loader.c @@ -0,0 +1,246 @@ +/* + * GQview + * (C) 2005 John Ellis + * + * Author: John Ellis + * + * This software is released under the GNU General Public License (GNU GPL). + * Please read the included file COPYING for more information. + * This software comes with no warranty of any kind, use at your own risk! + */ + +#include "gqview.h" +#include "cache-loader.h" + +#include "exif.h" +#include "md5-util.h" +#include "ui_fileops.h" + + +static gboolean cache_loader_process(CacheLoader *cl); + + +static void cache_loader_done_cb(ImageLoader *il, gpointer data) +{ + CacheLoader *cl = data; + + cache_loader_process(cl); +} + +static void cache_loader_error_cb(ImageLoader *il, gpointer data) +{ + CacheLoader *cl = data; + + cl->error = TRUE; + cache_loader_done_cb(il, data); +} + +static gboolean cache_loader_process(CacheLoader *cl) +{ + if (cl->todo_mask & CACHE_LOADER_SIMILARITY && + !cl->cd->similarity) + { + GdkPixbuf *pixbuf; + + if (!cl->il && !cl->error) + { + cl->il = image_loader_new(cl->path); + image_loader_set_error_func(cl->il, cache_loader_error_cb, cl); + if (image_loader_start(cl->il, cache_loader_done_cb, cl)) + { + return FALSE; + } + + cl->error = TRUE; + } + + pixbuf = image_loader_get_pixbuf(cl->il); + if (pixbuf) + { + if (!cl->error) + { + ImageSimilarityData *sim; + + sim = image_sim_new_from_pixbuf(pixbuf); + cache_sim_data_set_similarity(cl->cd, sim); + image_sim_free(sim); + + cl->done_mask |= CACHE_LOADER_SIMILARITY; + } + + /* we have the dimensions via pixbuf */ + if (!cl->cd->dimensions) + { + cache_sim_data_set_dimensions(cl->cd, gdk_pixbuf_get_width(pixbuf), + gdk_pixbuf_get_height(pixbuf)); + if (cl->todo_mask & CACHE_LOADER_DIMENSIONS) + { + cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; + cl->done_mask |= CACHE_LOADER_DIMENSIONS; + } + } + } + + image_loader_free(cl->il); + cl->il = NULL; + + cl->todo_mask &= ~CACHE_LOADER_SIMILARITY; + } + else if (cl->todo_mask & CACHE_LOADER_DIMENSIONS && + !cl->cd->dimensions) + { + if (!cl->error && + image_load_dimensions(cl->path, &cl->cd->width, &cl->cd->height)) + { + cl->cd->dimensions = TRUE; + cl->done_mask |= CACHE_LOADER_DIMENSIONS; + } + else + { + cl->error = TRUE; + } + + cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; + } + else if (cl->todo_mask & CACHE_LOADER_MD5SUM && + !cl->cd->have_md5sum) + { + if (md5_get_digest_from_file_utf8(cl->path, cl->cd->md5sum)) + { + cl->cd->have_md5sum = TRUE; + cl->done_mask |= CACHE_LOADER_MD5SUM; + } + else + { + cl->error = TRUE; + } + + cl->todo_mask &= ~CACHE_LOADER_MD5SUM; + } + else if (cl->todo_mask & CACHE_LOADER_DATE && + !cl->cd->have_date) + { + time_t date = -1; + ExifData *exif; + + exif = exif_read(cl->path); + if (exif) + { + gchar *text; + + text = exif_get_data_as_text(exif, "fDateTime"); + if (text) + { + struct tm t = { 0 }; + + if (sscanf(text, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec) == 6) + { + t.tm_year -= 1900; + t.tm_mon -= 1; + date = mktime(&t); + } + g_free(text); + } + exif_free(exif); + } + + cl->cd->date = date; + cl->cd->have_date = TRUE; + + cl->done_mask |= CACHE_LOADER_DATE; + cl->todo_mask &= ~CACHE_LOADER_DATE; + } + else + { + /* done, save then call done function */ + if (enable_thumb_caching && + cl->done_mask != CACHE_LOADER_NONE) + { + gchar *base; + mode_t mode = 0755; + + base = cache_get_location(CACHE_TYPE_SIM, cl->path, FALSE, &mode); + if (cache_ensure_dir_exists(base, mode)) + { + g_free(cl->cd->path); + cl->cd->path = cache_get_location(CACHE_TYPE_SIM, cl->path, TRUE, NULL); + if (cache_sim_data_save(cl->cd)) + { + filetime_set(cl->cd->path, filetime(cl->path)); + } + } + g_free(base); + } + + cl->idle_id = -1; + + if (cl->done_func) + { + cl->done_func(cl, cl->error, cl->done_data); + } + + return FALSE; + } + + return TRUE; +} + +static gboolean cache_loader_idle_cb(gpointer data) +{ + CacheLoader *cl = data; + + return cache_loader_process(cl); +} + +CacheLoader *cache_loader_new(const gchar *path, CacheDataType load_mask, + CacheLoaderDoneFunc done_func, gpointer done_data) +{ + CacheLoader *cl; + gchar *found; + + if (!path || !isfile(path)) return NULL; + + cl = g_new0(CacheLoader, 1); + cl->path = g_strdup(path); + + cl->done_func = done_func; + cl->done_data = done_data; + + found = cache_find_location(CACHE_TYPE_SIM, path); + if (found && filetime(found) == filetime(path)) + { + cl->cd = cache_sim_data_load(found); + } + g_free(found); + + if (!cl->cd) cl->cd = cache_sim_data_new(); + + cl->todo_mask = load_mask; + cl->done_mask = CACHE_LOADER_NONE; + + cl->il = NULL; + cl->idle_id = g_idle_add(cache_loader_idle_cb, cl); + + cl->error = FALSE; + + return cl; +} + +void cache_loader_free(CacheLoader *cl) +{ + if (!cl) return; + + if (cl->idle_id != -1) + { + g_source_remove(cl->idle_id); + cl->idle_id = -1; + } + + image_loader_free(cl->il); + cache_sim_data_free(cl->cd); + + g_free(cl->path); + g_free(cl); +} + diff --git a/src/cache-loader.h b/src/cache-loader.h new file mode 100644 index 00000000..60959088 --- /dev/null +++ b/src/cache-loader.h @@ -0,0 +1,59 @@ +/* + * GQview + * (C) 2005 John Ellis + * + * Author: John Ellis + * + * This software is released under the GNU General Public License (GNU GPL). + * Please read the included file COPYING for more information. + * This software comes with no warranty of any kind, use at your own risk! + */ + + +#ifndef CACHE_LOADER_H +#define CACHE_LOADER_H + + +#include "cache.h" +#include "image-load.h" + + +typedef struct _CacheLoader CacheLoader; + +typedef void (* CacheLoaderDoneFunc)(CacheLoader *cl, gint error, gpointer data); + + +typedef enum { + CACHE_LOADER_NONE = 0, + CACHE_LOADER_DIMENSIONS = 1 << 0, + CACHE_LOADER_DATE = 1 << 1, + CACHE_LOADER_MD5SUM = 1 << 2, + CACHE_LOADER_SIMILARITY = 1 << 3 +} CacheDataType; + +struct _CacheLoader { + gchar *path; + CacheData *cd; + + CacheDataType todo_mask; + CacheDataType done_mask; + + CacheLoaderDoneFunc done_func; + gpointer done_data; + + gint error; + + ImageLoader *il; + gint idle_id; +}; + + +CacheLoader *cache_loader_new(const gchar *path, CacheDataType load_mask, + CacheLoaderDoneFunc done_func, gpointer done_data); + +void cache_loader_free(CacheLoader *cl); + + +#endif + + diff --git a/src/cache.c b/src/cache.c index ef983ab6..e2bb0940 100644 --- a/src/cache.c +++ b/src/cache.c @@ -27,6 +27,7 @@ * SIMcache * #coment * Dimensions=[ x ] + * Date=[] * Checksum=[] * MD5sum=[<32 character ascii text digest>] * SimilarityGrid[32 x 32]=<3072 bytes of data (1024 pixels in RGB format, 1 pixel is 24bits)> @@ -51,8 +52,7 @@ CacheData *cache_sim_data_new(void) CacheData *cd; cd = g_new0(CacheData, 1); - cd->dimensions = FALSE; - cd->similarity = FALSE; + cd->date = -1; return cd; } @@ -81,6 +81,15 @@ static gint cache_sim_write_dimensions(FILE *f, CacheData *cd) return TRUE; } +static gint cache_sim_write_date(FILE *f, CacheData *cd) +{ + if (!f || !cd || !cd->have_date) return FALSE; + + fprintf(f, "Date=[%ld]\n", cd->date); + + return TRUE; +} + static gint cache_sim_write_checksum(FILE *f, CacheData *cd) { if (!f || !cd || !cd->have_checksum) return FALSE; @@ -157,6 +166,7 @@ gint cache_sim_data_save(CacheData *cd) fprintf(f, "SIMcache\n#%s %s\n", PACKAGE, VERSION); cache_sim_write_dimensions(f, cd); + cache_sim_write_date(f, cd); cache_sim_write_checksum(f, cd); cache_sim_write_md5sum(f, cd); cache_sim_write_similarity(f, cd); @@ -234,6 +244,46 @@ static gint cache_sim_read_dimensions(FILE *f, char *buf, int s, CacheData *cd) return FALSE; } +static gint cache_sim_read_date(FILE *f, char *buf, int s, CacheData *cd) +{ + if (!f || !buf || !cd) return FALSE; + + if (s < 4 || strncmp("Date", buf, 4) != 0) return FALSE; + + if (fseek(f, - s, SEEK_CUR) == 0) + { + char b; + char buf[1024]; + gint p = 0; + + b = 'X'; + while (b != '[') + { + if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; + } + while (b != ']' && p < 1023) + { + if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; + buf[p] = b; + p++; + } + + while (b != '\n') + { + if (fread(&b, sizeof(b), 1, f) != 1) break; + } + + buf[p] = '\0'; + cd->date = strtol(buf, NULL, 10); + + cd->have_date = TRUE; + + return TRUE; + } + + return FALSE; +} + static gint cache_sim_read_checksum(FILE *f, char *buf, int s, CacheData *cd) { if (!f || !buf || !cd) return FALSE; @@ -414,6 +464,7 @@ CacheData *cache_sim_data_load(const gchar *path) { if (!cache_sim_read_comment(f, buf, s, cd) && !cache_sim_read_dimensions(f, buf, s, cd) && + !cache_sim_read_date(f, buf, s, cd) && !cache_sim_read_checksum(f, buf, s, cd) && !cache_sim_read_md5sum(f, buf, s, cd) && !cache_sim_read_similarity(f, buf, s, cd)) @@ -449,6 +500,14 @@ void cache_sim_data_set_dimensions(CacheData *cd, gint w, gint h) cd->dimensions = TRUE; } +void cache_sim_data_set_date(CacheData *cd, time_t date) +{ + if (!cd) return; + + cd->date = date; + cd->have_date = TRUE; +} + void cache_sim_data_set_checksum(CacheData *cd, long checksum) { if (!cd) return; diff --git a/src/cache.h b/src/cache.h index ce7afc0e..bc1c95fc 100644 --- a/src/cache.h +++ b/src/cache.h @@ -40,11 +40,13 @@ struct _CacheData gchar *path; gint width; gint height; + time_t date; long checksum; guchar md5sum[16]; ImageSimilarityData *sim; gint dimensions; + gint have_date; gint have_checksum; gint have_md5sum; gint similarity; @@ -60,6 +62,7 @@ gint cache_sim_data_save(CacheData *cd); CacheData *cache_sim_data_load(const gchar *path); void cache_sim_data_set_dimensions(CacheData *cd, gint w, gint h); +void cache_sim_data_set_date(CacheData *cd, time_t date); void cache_sim_data_set_checksum(CacheData *cd, long checksum); void cache_sim_data_set_md5sum(CacheData *cd, guchar digest[16]); void cache_sim_data_set_similarity(CacheData *cd, ImageSimilarityData *sd); diff --git a/src/pan-view.c b/src/pan-view.c index b1e2bebc..15e5a422 100644 --- a/src/pan-view.c +++ b/src/pan-view.c @@ -14,6 +14,7 @@ #include "pan-view.h" #include "cache.h" +#include "cache-loader.h" #include "dnd.h" #include "editors.h" #include "filelist.h" @@ -125,6 +126,8 @@ #define PAN_PREF_GROUP "pan_view_options" #define PAN_PREF_HIDE_WARNING "hide_performance_warning" +#define SORT_BY_EXIF_DATE 1 + typedef enum { LAYOUT_TIMELINE = 0, @@ -244,6 +247,7 @@ struct _PanWindow gint cache_count; gint cache_total; gint cache_tick; + CacheLoader *cache_cl; ImageLoader *il; ThumbLoader *tl; @@ -279,6 +283,8 @@ static GList *pan_window_layout_list(const gchar *path, SortType sort, gint asce static GList *pan_layout_intersect(PanWindow *pw, gint x, gint y, gint width, gint height); +static void pan_window_layout_update_idle(PanWindow *pw); + static GtkWidget *pan_popup_menu(PanWindow *pw); static void pan_fullscreen_toggle(PanWindow *pw, gint force_off); @@ -432,6 +438,9 @@ static void pan_cache_free(PanWindow *pw) pw->cache_count = 0; pw->cache_total = 0; pw->cache_tick = 0; + + cache_loader_free(pw->cache_cl); + pw->cache_cl = NULL; } static void pan_cache_fill(PanWindow *pw, const gchar *path) @@ -446,17 +455,40 @@ static void pan_cache_fill(PanWindow *pw, const gchar *path) pw->cache_total = g_list_length(pw->cache_todo); } +static void pan_cache_step_done_cb(CacheLoader *cl, gint error, gpointer data) +{ + PanWindow *pw = data; + + if (pw->cache_list) + { + PanCacheData *pc; + pc = pw->cache_list->data; + + if (!pc->cd) + { + pc->cd = cl->cd; + cl->cd = NULL; + } + } + + cache_loader_free(cl); + pw->cache_cl = NULL; + + pan_window_layout_update_idle(pw); +} + static gint pan_cache_step(PanWindow *pw) { FileData *fd; PanCacheData *pc; - CacheData *cd = NULL; + CacheDataType load_mask; - if (!pw->cache_todo) return FALSE; + if (!pw->cache_todo) return TRUE; fd = pw->cache_todo->data; pw->cache_todo = g_list_remove(pw->cache_todo, fd); +#if 0 if (enable_thumb_caching) { gchar *found; @@ -495,16 +527,68 @@ static gint pan_cache_step(PanWindow *pw) pw->cache_tick = 9; } - +#endif pc = g_new0(PanCacheData, 1); memcpy(pc, fd, sizeof(FileData)); g_free(fd); - pc->cd = cd; + pc->cd = NULL; pw->cache_list = g_list_prepend(pw->cache_list, pc); - return TRUE; + cache_loader_free(pw->cache_cl); + + load_mask = CACHE_LOADER_NONE; + if (pw->size > LAYOUT_SIZE_THUMB_LARGE) load_mask |= CACHE_LOADER_DIMENSIONS; + if (SORT_BY_EXIF_DATE) load_mask |= CACHE_LOADER_DATE; + pw->cache_cl = cache_loader_new(((FileData *)pc)->path, load_mask, + pan_cache_step_done_cb, pw); + return (pw->cache_cl == NULL); +} + +static void pan_cache_sync_date(PanWindow *pw, GList *list) +{ + GList *haystack; + GList *work; + + haystack = g_list_copy(pw->cache_list); + + work = list; + while (work) + { + FileData *fd; + GList *needle; + + fd = work->data; + work = work->next; + + needle = haystack; + while (needle) + { + PanCacheData *pc; + gchar *path; + + pc = needle->data; + path = ((FileData *)pc)->path; + if (path && strcmp(path, fd->path) == 0) + { + GList *tmp; + + if (pc->cd && pc->cd->have_date && pc->cd->date >= 0) + { + fd->date = pc->cd->date; + } + + tmp = needle; + needle = needle->next; + haystack = g_list_delete_link(haystack, tmp); + } + else + { + needle = needle->next; + } + } + } } /* @@ -1832,6 +1916,12 @@ static void pan_window_layout_compute_calendar(PanWindow *pw, const gchar *path, list = pan_window_layout_list(path, SORT_NONE, TRUE); list = filelist_sort(list, SORT_TIME, TRUE); + if (pw->cache_list && SORT_BY_EXIF_DATE) + { + pan_cache_sync_date(pw, list); + list = filelist_sort(list, SORT_TIME, TRUE); + } + day_max = 0; count = 0; tc = 0; @@ -2047,6 +2137,12 @@ static void pan_window_layout_compute_timeline(PanWindow *pw, const gchar *path, list = pan_window_layout_list(path, SORT_NONE, TRUE); list = filelist_sort(list, SORT_TIME, TRUE); + if (pw->cache_list && SORT_BY_EXIF_DATE) + { + pan_cache_sync_date(pw, list); + list = filelist_sort(list, SORT_TIME, TRUE); + } + *width = PAN_FOLDER_BOX_BORDER * 2; *height = PAN_FOLDER_BOX_BORDER * 2; @@ -2092,6 +2188,7 @@ static void pan_window_layout_compute_timeline(PanWindow *pw, const gchar *path, pi = pan_item_new_text(pw, x, y, buf, TEXT_ATTR_BOLD | TEXT_ATTR_HEADING, PAN_TEXT_COLOR, 255); + g_free(buf); y += pi->height; pi_month = pan_item_new_box(pw, file_data_new_simple(fd->path), @@ -3004,7 +3101,8 @@ static gint pan_window_layout_update_idle_cb(gpointer data) gint scroll_x; gint scroll_y; - if (pw->size > LAYOUT_SIZE_THUMB_LARGE) + if (pw->size > LAYOUT_SIZE_THUMB_LARGE || + (SORT_BY_EXIF_DATE && (pw->layout == LAYOUT_TIMELINE || pw->layout == LAYOUT_CALENDAR))) { if (!pw->cache_list && !pw->cache_todo) { @@ -3015,7 +3113,7 @@ static gint pan_window_layout_update_idle_cb(gpointer data) return TRUE; } } - if (pan_cache_step(pw)) + if (pw->cache_todo) { pw->cache_count++; pw->cache_tick++; @@ -3035,7 +3133,10 @@ static gint pan_window_layout_update_idle_cb(gpointer data) pw->cache_tick = 0; } - return TRUE; + if (pan_cache_step(pw)) return TRUE; + + pw->idle_id = -1; + return FALSE; } } @@ -3070,7 +3171,6 @@ static gint pan_window_layout_update_idle_cb(gpointer data) pan_window_message(pw, NULL); pw->idle_id = -1; - return FALSE; } @@ -3078,11 +3178,16 @@ static void pan_window_layout_update_idle(PanWindow *pw) { if (pw->idle_id == -1) { - pan_window_message(pw, _("Sorting images...")); pw->idle_id = g_idle_add(pan_window_layout_update_idle_cb, pw); } } +static void pan_window_layout_update(PanWindow *pw) +{ + pan_window_message(pw, _("Sorting images...")); + pan_window_layout_update_idle(pw); +} + /* *----------------------------------------------------------------------------- * pan window keyboard @@ -3998,7 +4103,7 @@ static void pan_window_layout_change_cb(GtkWidget *combo, gpointer data) PanWindow *pw = data; pw->layout = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - pan_window_layout_update_idle(pw); + pan_window_layout_update(pw); } static void pan_window_layout_size_cb(GtkWidget *combo, gpointer data) @@ -4006,7 +4111,7 @@ static void pan_window_layout_size_cb(GtkWidget *combo, gpointer data) PanWindow *pw = data; pw->size = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - pan_window_layout_update_idle(pw); + pan_window_layout_update(pw); } static void pan_window_entry_activate_cb(const gchar *new_text, gpointer data) @@ -4022,15 +4127,18 @@ static void pan_window_entry_activate_cb(const gchar *new_text, gpointer data) warning_dialog(_("Folder not found"), _("The entered path is not a folder"), GTK_STOCK_DIALOG_WARNING, pw->path_entry); - return; } + else + { + tab_completion_append_to_history(pw->path_entry, path); - tab_completion_append_to_history(pw->path_entry, path); + g_free(pw->path); + pw->path = g_strdup(path); - g_free(pw->path); - pw->path = g_strdup(path); + pan_window_layout_update(pw); + } - pan_window_layout_update_idle(pw); + g_free(path); } static void pan_window_entry_change_cb(GtkWidget *combo, gpointer data) @@ -4058,6 +4166,7 @@ static void pan_window_close(PanWindow *pw) gtk_widget_destroy(pw->window); pan_window_items_free(pw); + pan_cache_free(pw); g_free(pw->path); @@ -4263,7 +4372,7 @@ static void pan_window_new_real(const gchar *path) gtk_window_set_default_size(GTK_WINDOW(pw->window), PAN_WINDOW_DEFAULT_WIDTH, PAN_WINDOW_DEFAULT_HEIGHT); - pan_window_layout_update_idle(pw); + pan_window_layout_update(pw); gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget)); gtk_widget_show(pw->window); @@ -4554,7 +4663,7 @@ static void pan_window_get_dnd_data(GtkWidget *widget, GdkDragContext *context, g_free(pw->path); pw->path = g_strdup(path); - pan_window_layout_update_idle(pw); + pan_window_layout_update(pw); } path_list_free(list);