static void cache_manager_standard_clean_start_cb(GenericDialog *gd, gpointer data) { CleanData *cd = data; GList *list; gchar *path; FileData *dir_fd; #if GTK_CHECK_VERSION(2,20,0) if (cd->list || !gtk_widget_get_sensitive(cd->button_start)) return; #else if (cd->list || !GTK_WIDGET_SENSITIVE(cd->button_start)) return; #endif gtk_widget_set_sensitive(cd->button_start, FALSE); gtk_widget_set_sensitive(cd->button_stop, TRUE); gtk_widget_set_sensitive(cd->button_close, FALSE); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("running...")); path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_NORMAL, NULL); dir_fd = file_data_new_simple(path); filelist_read(dir_fd, &list, NULL); cd->list = list; file_data_unref(dir_fd); g_free(path); path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_LARGE, NULL); dir_fd = file_data_new_simple(path); filelist_read(dir_fd, &list, NULL); cd->list = g_list_concat(cd->list, list); file_data_unref(dir_fd); g_free(path); path = g_build_filename(homedir(), THUMB_FOLDER_GLOBAL, THUMB_FOLDER_FAIL, NULL); dir_fd = file_data_new_simple(path); filelist_read(dir_fd, &list, NULL); cd->list = g_list_concat(cd->list, list); file_data_unref(dir_fd); g_free(path); cd->count_total = g_list_length(cd->list); cd->count_done = 0; /* start iterating */ if (cd->clear) { cd->idle_id = g_idle_add(cache_manager_standard_clean_clear_cb, cd); } else { cache_manager_standard_clean_valid_cb(NULL, TRUE, cd); } }
static void view_dir_list_do(ViewWindow *vw, GList *list, gboolean skip, gboolean recurse) { GList *work; view_window_set_list(vw, NULL); work = list; while (work) { FileData *fd = work->data; work = work->next; if (isdir(fd->path)) { if (!skip) { GList *list = NULL; if (recurse) { list = filelist_recursive(fd); } else { /*FIXME */ filelist_read(fd, &list, NULL); list = filelist_sort_path(list); list = filelist_filter(list, FALSE); } if (list) vw->list = g_list_concat(vw->list, list); } } else { /* FIXME: no filtering here */ vw->list = g_list_append(vw->list, file_data_ref(fd)); } } if (vw->list) { FileData *fd; vw->list_pointer = vw->list; fd = vw->list->data; image_change_fd(vw->imd, fd, image_zoom_get_default(vw->imd)); work = vw->list->next; if (options->image.enable_read_ahead && work) { fd = work->data; image_prebuffer_set(vw->imd, fd); } } else { image_change_fd(vw->imd, NULL, image_zoom_get_default(vw->imd)); } }
GList *pan_list_tree(const gchar *path, SortType sort, gint ascend, gint ignore_symlinks) { GList *flist = NULL; GList *dlist = NULL; GList *result; GList *folders; filelist_read(path, &flist, &dlist); if (sort != SORT_NONE) { flist = filelist_sort(flist, sort, ascend); dlist = filelist_sort(dlist, sort, ascend); } result = flist; folders = dlist; while (folders) { FileData *fd; fd = folders->data; folders = g_list_remove(folders, fd); if (!pan_is_ignored(fd->path, ignore_symlinks) && filelist_read(fd->path, &flist, &dlist)) { if (sort != SORT_NONE) { flist = filelist_sort(flist, sort, ascend); dlist = filelist_sort(dlist, sort, ascend); } result = g_list_concat(result, flist); folders = g_list_concat(dlist, folders); } file_data_free(fd); } return result; }
static void collect_manager_refresh(void) { GList *list; GList *work; FileData *dir_fd; dir_fd = file_data_new_simple(get_collections_dir()); filelist_read(dir_fd, &list, NULL); file_data_unref(dir_fd); work = collection_manager_entry_list; while (work && list) { CollectManagerEntry *entry; GList *list_step; entry = work->data; work = work->next; list_step = list; while (list_step && entry) { FileData *fd; fd = list_step->data; list_step = list_step->next; if (strcmp(fd->path, entry->path) == 0) { list = g_list_remove(list, fd); file_data_unref(fd); entry = NULL; } else { collect_manager_entry_free(entry); } } } work = list; while (work) { FileData *fd; fd = work->data; work = work->next; collect_manager_entry_new(fd->path); } filelist_free(list); }
static void cache_manager_render_folder(CleanData *cd, FileData *dir_fd) { GList *list_d = NULL; GList *list_f = NULL; if (cd->recurse) { filelist_read(dir_fd, &list_f, &list_d); } else { filelist_read(dir_fd, &list_f, NULL); } list_f = filelist_filter(list_f, FALSE); list_d = filelist_filter(list_d, TRUE); cd->list = g_list_concat(list_f, cd->list); cd->list_dir = g_list_concat(list_d, cd->list_dir); }
void add_seq_error_profile(char *seq, size_t seqlen, FileList *flist) { const read_t *r = filelist_read(flist); int fqoffset = flist->fqoffsets[flist->curr]; filelist_extend_errarr(flist, seqlen); size_t i, limit = MIN2(seqlen, r->seq.end); int rnd; for(i = 0; i < limit; i++) { if(toupper(seq[i]) == 'N' || toupper(r->seq.b[i]) == 'N') seq[i] = 'N'; else if((rnd = rand()) < qual_prob[r->qual.b[i] - fqoffset] * RAND_MAX) { seq[i] = mut(seq[i], rnd % 3); flist->errors[i]++; } } }
void view_window_new(FileData *fd) { GList *list; if (file_extension_match(fd->path, GQ_COLLECTION_EXT)) { ViewWindow *vw; CollectionData *cd; CollectInfo *info; cd = collection_new(fd->path); if (collection_load(cd, fd->path, COLLECTION_LOAD_NONE)) { info = collection_get_first(cd); } else { collection_unref(cd); cd = NULL; info = NULL; } vw = real_view_window_new(NULL, NULL, cd, info); if (vw && cd) { g_signal_connect(G_OBJECT(vw->window), "destroy", G_CALLBACK(view_window_collection_unref_cb), cd); } } else if (isdir(fd->path) && filelist_read(fd, &list, NULL)) { list = filelist_sort_path(list); list = filelist_filter(list, FALSE); real_view_window_new(NULL, list, NULL, NULL); filelist_free(list); } else { real_view_window_new(fd, NULL, NULL, NULL); } }
/* This checks relative caches in dir/.thumbnails and * removes them if they have no source counterpart. */ gint cache_maintain_dir(FileData *dir_fd, gint recursive, gint clear) { GList *list = NULL; gchar *cachedir; FileData *cachedir_fd; gboolean still_have_a_file = FALSE; GList *work; cachedir = g_build_filename(dir, GQ_CACHE_LOCAL_THUMB, NULL); cachedir_fd = file_data_new_simple(cachedir); g_free(cachedir); filelist_read(cachedir_fd, &list, NULL); work = list; while (work) { FileData *fd; gchar *source; fd = work->data; work = work->next; source = g_build_filename(dir->path, fd->name, NULL); if (clear || extension_truncate(source, GQ_CACHE_EXT_THUMB) || extension_truncate(source, GQ_CACHE_EXT_SIM)) { if (!clear && isfile(source)) { still_have_a_file = TRUE; } else { if (!unlink_file(fd->path)) { DEBUG_1("Failed to remove cache file %s", fd->path); still_have_a_file = TRUE; } } } else { still_have_a_file = TRUE; } g_free(source); } filelist_free(list); file_data_unref(cachedir_fd); if (recursive) { list = NULL; filelist_read(dir_fd, NULL, &list); work = list; while (work) { FileData *fd = work->data; work = work->next; still_have_a_file |= cache_maintain_dir(fd->path, recursive, clear); } filelist_free(list); } return still_have_a_file; }
/* This checks all files in ~/GQ_RC_DIR/thumbnails and * removes them if thay have no source counterpart. * (this assumes all cache files have an extension of 4 chars including '.') */ gint cache_maintain_home_dir(const gchar *dir, gint recursive, gint clear) { gchar *base; gint base_length; GList *dlist = NULL; FileData *dir_fd; GList *flist = NULL; gboolean still_have_a_file = FALSE; DEBUG_1("maintainance check: %s", dir); base_length = strlen(homedir()) + strlen("/") + strlen(GQ_CACHE_RC_THUMB); base = g_strconcat(homedir(), "/", GQ_CACHE_RC_THUMB, dir, NULL); dir_fd = file_data_new_simple(base); g_free(base); if (filelist_read(dir_fd, &flist, &dlist)) { GList *work; work = dlist; while (work) { FileData *fd = work->data; if (recursive && strlen(fd->path) > base_length && !cache_maintain_home_dir(fd->path + base_length, recursive, clear)) { DEBUG_1("Deleting thumb dir: %s", fd->path); if (!rmdir_utf8(fd->path)) { log_printf("Unable to delete dir: %s\n", fd->path); } } else { still_have_a_file = TRUE; } work = work->next; } work = flist; while (work) { FileData *fd = work->data; gchar *path = g_strdup(fd->path); gchar *dot; dot = extension_find_dot(path); if (dot) *dot = '\0'; if (clear || (strlen(path) > base_length && !isfile(path + base_length)) ) { if (dot) *dot = '.'; if (!unlink_file(path)) log_printf("failed to delete:%s\n", path); } else { still_have_a_file = TRUE; } g_free(path); work = work->next; } } filelist_free(dlist); filelist_free(flist); file_data_unref(dir_fd); return still_have_a_file; }
/* sorry for complexity (cm->done_list), but need it to remove empty dirs */ void cache_maintain_home(gboolean metadata, gboolean clear, GtkWidget *parent) { CMData *cm; GList *dlist; FileData *dir_fd; const gchar *msg; const gchar *cache_folder; GtkWidget *hbox; if (metadata) { cache_folder = get_metadata_cache_dir(); } else { cache_folder = get_thumbnails_cache_dir(); } dir_fd = file_data_new_simple(cache_folder); if (!filelist_read(dir_fd, NULL, &dlist)) { file_data_unref(dir_fd); return; } dlist = g_list_append(dlist, dir_fd); cm = g_new0(CMData, 1); cm->list = dlist; cm->done_list = NULL; cm->clear = clear; cm->metadata = metadata; if (metadata) { msg = _("Removing old metadata..."); } else if (clear) { msg = _("Clearing cached thumbnails..."); } else { msg = _("Removing old thumbnails..."); } cm->gd = generic_dialog_new(_("Maintenance"), "main_maintenance", parent, FALSE, NULL, cm); cm->gd->cancel_cb = cache_maintain_home_close_cb; cm->button_close = generic_dialog_add_button(cm->gd, GTK_STOCK_CLOSE, NULL, cache_maintain_home_close_cb, FALSE); gtk_widget_set_sensitive(cm->button_close, FALSE); cm->button_stop = generic_dialog_add_button(cm->gd, GTK_STOCK_STOP, NULL, cache_maintain_home_stop_cb, FALSE); generic_dialog_add_message(cm->gd, NULL, msg, NULL); gtk_window_set_default_size(GTK_WINDOW(cm->gd->dialog), PURGE_DIALOG_WIDTH, -1); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(cm->gd->vbox), hbox, FALSE, FALSE, 5); gtk_widget_show(hbox); cm->entry = gtk_entry_new(); GTK_WIDGET_UNSET_FLAGS(cm->entry, GTK_CAN_FOCUS); gtk_editable_set_editable(GTK_EDITABLE(cm->entry), FALSE); gtk_box_pack_start(GTK_BOX(hbox), cm->entry, TRUE, TRUE, 0); gtk_widget_show(cm->entry); cm->spinner = spinner_new(NULL, SPINNER_SPEED); gtk_box_pack_start(GTK_BOX(hbox), cm->spinner, FALSE, FALSE, 0); gtk_widget_show(cm->spinner); gtk_widget_show(cm->gd->dialog); cm->idle_id = g_idle_add(cache_maintain_home_cb, cm); }
static gboolean cache_maintain_home_cb(gpointer data) { CMData *cm = data; GList *dlist = NULL; GList *list = NULL; FileData *fd; gboolean just_done = FALSE; gboolean still_have_a_file = TRUE; gsize base_length; const gchar *cache_folder; if (cm->metadata) { cache_folder = get_metadata_cache_dir(); } else { cache_folder = get_thumbnails_cache_dir(); } base_length = strlen(cache_folder); if (!cm->list) { DEBUG_1("purge chk done."); cm->idle_id = 0; cache_maintain_home_stop(cm); return FALSE; } fd = cm->list->data; DEBUG_1("purge chk (%d) \"%s\"", (cm->clear && !cm->metadata), fd->path); if (g_list_find(cm->done_list, fd) == NULL) { cm->done_list = g_list_prepend(cm->done_list, fd); if (filelist_read(fd, &list, &dlist)) { GList *work; just_done = TRUE; still_have_a_file = FALSE; work = list; while (work) { FileData *fd_list = work->data; gchar *path_buf = g_strdup(fd_list->path); gchar *dot; dot = extension_find_dot(path_buf); if (dot) *dot = '\0'; if ((!cm->metadata && cm->clear) || (strlen(path_buf) > base_length && !isfile(path_buf + base_length)) ) { if (dot) *dot = '.'; if (!unlink_file(path_buf)) log_printf("failed to delete:%s\n", path_buf); } else { still_have_a_file = TRUE; } g_free(path_buf); work = work->next; } } } filelist_free(list); cm->list = g_list_concat(dlist, cm->list); if (cm->list && g_list_find(cm->done_list, cm->list->data) != NULL) { /* check if the dir is empty */ if (cm->list->data == fd && just_done) { if (!still_have_a_file && !dlist && cm->list->next && !rmdir_utf8(fd->path)) { log_printf("Unable to delete dir: %s\n", fd->path); } } else { /* must re-check for an empty dir */ if (isempty(fd->path) && cm->list->next && !rmdir_utf8(fd->path)) { log_printf("Unable to delete dir: %s\n", fd->path); } } fd = cm->list->data; cm->done_list = g_list_remove(cm->done_list, fd); cm->list = g_list_remove(cm->list, fd); file_data_unref(fd); } if (cm->list) { const gchar *buf; fd = cm->list->data; if (strlen(fd->path) > base_length) { buf = fd->path + base_length; } else { buf = "..."; } gtk_entry_set_text(GTK_ENTRY(cm->entry), buf); } return TRUE; }
static rc_t bogotune(void) { bool skip; result_t *best; int beg, end; uint cnt, scan; rc_t status = RC_OK; beg = time(NULL); ham_cutoff = 0.0; spam_cutoff = 0.1; /* Note: memory usage highest while reading messages */ /* usage decreases as distribute() converts to count format */ /* read all messages, merge training sets, look up scoring sets */ ns_cnt = filelist_read(REG_GOOD, ham_files); sp_cnt = filelist_read(REG_SPAM, spam_files); cnt = ns_cnt + sp_cnt; end = time(NULL); if (verbose >= TIME) { show_elapsed_time(beg, end, ns_cnt + sp_cnt, (double)cnt/(end-beg), "messages", "msg/sec"); } distribute(REG_GOOD, ns_msglists); distribute(REG_SPAM, sp_msglists); create_countlists(ns_msglists); create_countlists(sp_msglists); if (verbose >= TIME && time(NULL) - end > 2) { end = time(NULL); show_elapsed_time(beg, end, ns_cnt + sp_cnt, (double)cnt/(end-beg), "messages", "msg/sec"); } if (verbose > PARMS+1) { tunelist_print(ns_and_sp); tunelist_print(ns_msglists); tunelist_print(sp_msglists); } ns_cnt = count_messages(ns_msglists); sp_cnt = count_messages(sp_msglists); if (ds_flag == DS_DSK && !check_msg_counts()) exit(exit_zero ? EX_OK : EX_ERROR); fflush(stdout); check_percent = CHECK_PCT; /* for checking low scoring spam ** and high scoring non-spam */ ns_scores = xcalloc(ns_cnt, sizeof(double)); sp_scores = xcalloc(sp_cnt, sizeof(double)); robs = DEFAULT_ROBS; robx = DEFAULT_ROBX; min_dev = DEFAULT_MIN_DEV; if (check_for_high_ns_scores() | check_for_low_sp_scores()) scoring_error(); /* ** 5. Calculate x and cache size ** Calculate x with bogoutil's -r option (a new addition). ** Bound the calculated value within [0.4, 0.6] and set the range to be ** investigated to [x-0.1, x+0.1]. */ robx = get_robx(); if (ds_flag == DS_DSK) { db_cachesize = calc_db_cachesize(); printf("Recommended db cache size is %u MB\n", db_cachesize); } /* ** 6. Calculate fp target ** The fp target will be derived thus: score non-spams with s and md as ** shipped, and determine the count that will result from a spam cutoff ** of 0.95; if that is < 0.25%, try 0.9375 etc. */ min_dev = 0.02; /* set target and spam_cutoff */ if (coerced_target == 0) set_thresh(ns_cnt, ns_scores); else { /* if coerced target ... */ target = coerced_target; spam_cutoff = ns_scores[target-1]; } skip = ROUND(spam_cutoff,100000) < SCAN_CUTOFF; printf("False-positive target is %u (cutoff %8.6f)\n", target, spam_cutoff); #ifdef TEST if (test) { printf("m: %8.6f, s: %8.6f, x: %0.16f\n", min_dev, robs, robx); if (verbose < PARMS) print_ns_scores(target-2, target+2, 0); } #endif if (!esf_flag && (sp_esf < 1.0 || ns_esf < 1.0)) fprintf(stderr, "Warning: Using ESF values (sp=%8.6f, ns=%8.6f) from config file.\n", sp_esf, ns_esf); /* No longer needed */ wordhash_free(train); train = NULL; for (scan=0; scan <= 1 && !skip; scan ++) { uint r_count; uint rsi, rxi, mdi, spi, nsi; result_t *results, *r, *sorted; printf("Performing %s scan:\n", scan==0 ? "coarse" : "fine"); switch (scan) { case 0: /* COARSE */ /* ** 7. Coarsely scan s, md and x ** The coarse s scan will range from 1 to 0.01 in half decades, and the ** coarse md scan will range from 0.05 to 0.45 in steps of 0.05. The ** coarse x scan will use steps of 0.05. The trough must be surrounded on ** six sides by values below the 33% quantile (unless bounded on one or ** more sides). */ init_coarse(robx); break; case 1: /* FINE */ /* ** 8. Finely scan the peak region ** The fine s scan will range over the estimated s +/- half a decade in ** steps of a quarter decade, and the fine md scan will range over the ** estimated md +/- 0.075 in steps of 0.015. The fine x scan will range ** over the estimated x +/- 0.04 in steps of 0.02. Scans of s and md ** are bounded by the limits of the coarse scan. Again, the trough must ** be surrounded on six sides by values below the 33% quantile. If no ** such trough exists, a warning is given. */ init_fine(robs, min_dev, robx, spex, nsex); break; } r_count = rsval->cnt * mdval->cnt * rxval->cnt * spexp->cnt * nsexp->cnt; results = (result_t *) xcalloc(r_count, sizeof(result_t)); print_all_parms(r_count); if (verbose >= SUMMARY) { if (verbose >= SUMMARY+1) printf("%3s ", "cnt"); if (verbose >= SUMMARY+2) printf(" %s %s %s ", "s", "m", "x"); printf(" %4s %5s %4s %8s %8s %7s %3s %3s\n", "rs", "md", "rx", "spesf", "nsesf", "cutoff", "fp", "fn"); } cnt = 0; beg = time(NULL); for (rsi = 0; rsi < rsval->cnt; rsi++) { robs = rsval->data[rsi]; for (mdi = 0; mdi < mdval->cnt; mdi++) { min_dev = mdval->data[mdi]; for (rxi = 0; rxi < rxval->cnt; rxi++) { robx = rxval->data[rxi]; for (spi = 0; spi < spexp->cnt; spi++) { spex = spexp->data[spi]; sp_esf = ESF_SEL(sp_esf, pow(0.75, spex)); for (nsi = 0; nsi < nsexp->cnt; nsi++) { uint fp, fn; nsex = nsexp->data[nsi]; ns_esf = ESF_SEL(ns_esf, pow(0.75, nsex)); /* save parms */ r = &results[cnt++]; r->idx = cnt; r->rsi = rsi; r->rs = robs; r->rxi = rxi; r->rx = robx; r->mdi = mdi; r->md = min_dev; r->spi = spi; r->sp_exp = spex; r->nsi = nsi; r->ns_exp = nsex; if (verbose >= SUMMARY) { if (verbose >= SUMMARY+1) printf("%3u ", cnt); if (verbose >= SUMMARY+2) printf(" %u %u %u %u %u ", rsi, mdi, rxi, spi, nsi); printf("%6.4f %5.3f %5.3f %8.6f %8.6f", robs, min_dev, robx, sp_esf, ns_esf); fflush(stdout); } spam_cutoff = 0.01; score_ns(ns_scores); /* scores in descending order */ /* Determine spam_cutoff and false_pos */ for (fp = target; fp < ns_cnt; fp += 1) { spam_cutoff = ns_scores[fp-1]; if (spam_cutoff < 0.999999) break; if (coerced_target != 0) break; } if (ns_cnt < fp) fprintf(stderr, "Too few false positives to determine a valid cutoff\n"); score_sp(sp_scores); /* scores in ascending order */ fn = get_fn_count(sp_cnt, sp_scores); /* save results */ r->co = spam_cutoff; r->fp = fp; r->fn = fn; if (verbose < SUMMARY) progress(cnt, r_count); else { printf(" %8.6f %2u %3u\n", spam_cutoff, fp, fn); fflush(stdout); } #ifdef TEST if (test && spam_cutoff < 0.501) { printf("co: %0.16f\n", spam_cutoff); print_ns_scores(0, fp, 2); print_sp_scores(fn-10, fn, 10); } #endif if (fMakeCheck && cnt >= cMakeCheck) break; } if (fMakeCheck && cnt >= cMakeCheck) break; } if (fMakeCheck && cnt >= cMakeCheck) break; } if (fMakeCheck && cnt >= cMakeCheck) break; } fflush(stdout); if (fMakeCheck && cnt >= cMakeCheck) break; } if (verbose >= TIME) { end = time(NULL); show_elapsed_time(beg, end, cnt, (double)(end-beg)/cnt, "iterations", "secs"); } printf("\n"); /* Scan complete, now find minima */ sorted = results_sort(r_count, results); top_ten(sorted, r_count); best = count_outliers(r_count, sorted, results); robs = rsval->data[best->rsi]; robx = rxval->data[best->rxi]; min_dev = mdval->data[best->mdi]; spex = spexp->data[best->spi]; sp_esf = ESF_SEL(sp_esf, pow(0.75, spex)); nsex = nsexp->data[best->nsi]; ns_esf = ESF_SEL(ns_esf, pow(0.75, nsex)); printf( "Minimum found at s %6.4f, md %5.3f, x %5.3f, spesf %8.6f, nsesf %8.6f\n", robs, min_dev, robx, sp_esf, ns_esf); printf(" fp %u (%6.4f%%), fn %u (%6.4f%%)\n", best->fp, best->fp*100.0/ns_cnt, best->fn, best->fn*100.0/sp_cnt); printf("\n"); data_free(rsval); data_free(rxval); data_free(mdval); data_free(spexp); data_free(nsexp); xfree(results); xfree(sorted); } /* ** 9. Suggest possible spam and non-spam cutoff values ** With the final x, md and s values, score the spams and non-spams and ** sort the non-spam scores decreasing and the spam scores increasing; ** then, traverse the non-spam list until the 0.2% point; report cutoffs ** that give 0.05%, 0.1% and 0.2% fp. */ final_recommendations(skip); return status; }
gboolean vdtree_populate_path_by_iter(ViewDir *vd, GtkTreeIter *iter, gboolean force, FileData *target_fd) { GtkTreeModel *store; GList *list; GList *work; GList *old; time_t current_time; GtkTreeIter child; NodeData *nd; gboolean add_hidden = FALSE; gchar *link = NULL; store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &nd, -1); if (!nd) return FALSE; current_time = time(NULL); if (nd->expanded) { if (!nd->fd || !isdir(nd->fd->path)) { if (vd->click_fd == nd->fd) vd->click_fd = NULL; if (vd->drop_fd == nd->fd) vd->drop_fd = NULL; gtk_tree_store_remove(GTK_TREE_STORE(store), iter); vdtree_node_free(nd); return FALSE; } if (!force && current_time - nd->last_update < 2) { DEBUG_1("Too frequent update of %s", nd->fd->path); return TRUE; } file_data_check_changed_files(nd->fd); /* make sure we have recent info */ } /* when hidden files are not enabled, and the user enters a hidden path, * allow the tree to display that path by specifically inserting the hidden entries */ if (!options->file_filter.show_hidden_files && target_fd && strncmp(nd->fd->path, target_fd->path, strlen(nd->fd->path)) == 0) { gint n; n = strlen(nd->fd->path); if (target_fd->path[n] == G_DIR_SEPARATOR && target_fd->path[n+1] == '.') add_hidden = TRUE; } if (nd->expanded && (!force && !add_hidden) && nd->fd->version == nd->version) return TRUE; vdtree_busy_push(vd); filelist_read(nd->fd, NULL, &list); if (add_hidden) { gint n; gchar *name8; n = strlen(nd->fd->path) + 1; while (target_fd->path[n] != '\0' && target_fd->path[n] != G_DIR_SEPARATOR) n++; name8 = g_strndup(target_fd->path, n); if (isdir(name8)) { list = g_list_prepend(list, file_data_new_dir(name8)); } g_free(name8); } old = NULL; if (gtk_tree_model_iter_children(store, &child, iter)) { do { NodeData *cnd; gtk_tree_model_get(store, &child, DIR_COLUMN_POINTER, &cnd, -1); old = g_list_prepend(old, cnd); } while (gtk_tree_model_iter_next(store, &child)); } work = list; while (work) { FileData *fd; fd = work->data; work = work->next; if (strcmp(fd->name, ".") == 0 || strcmp(fd->name, "..") == 0) { file_data_unref(fd); } else { NodeData *cnd; cnd = vdtree_find_iter_by_fd(vd, iter, fd, &child); if (cnd) { if (cnd->expanded && cnd->version != fd->version) { vdtree_populate_path_by_iter(vd, &child, FALSE, target_fd); } gtk_tree_store_set(GTK_TREE_STORE(store), &child, DIR_COLUMN_NAME, fd->name, -1); if (islink(fd->path)) { link = realpath(fd->path, NULL); } else { link = NULL; } gtk_tree_store_set(GTK_TREE_STORE(store), &child, DIR_COLUMN_LINK, link, -1); cnd->version = fd->version; old = g_list_remove(old, cnd); file_data_unref(fd); } else { vdtree_add_by_data(vd, fd, iter); } } } work = old; while (work) { NodeData *cnd = work->data; work = work->next; if (vd->click_fd == cnd->fd) vd->click_fd = NULL; if (vd->drop_fd == cnd->fd) vd->drop_fd = NULL; if (vdtree_find_iter_by_data(vd, iter, cnd, &child)) { gtk_tree_store_remove(GTK_TREE_STORE(store), &child); vdtree_node_free(cnd); } } g_list_free(old); g_list_free(list); vdtree_busy_pop(vd); nd->expanded = TRUE; nd->last_update = current_time; g_free(link); return TRUE; }
static gboolean vdlist_populate(ViewDir *vd, gboolean clear) { GtkListStore *store; GList *work; GtkTreeIter iter; gboolean valid; gchar *filepath; GList *old_list; gboolean ret; FileData *fd; SortType sort_type = SORT_NAME; gboolean sort_ascend = TRUE; old_list = VDLIST(vd)->list; ret = filelist_read(vd->dir_fd, NULL, &VDLIST(vd)->list); VDLIST(vd)->list = filelist_sort(VDLIST(vd)->list, sort_type, sort_ascend); /* add . and .. */ if (options->file_filter.show_parent_directory && strcmp(vd->dir_fd->path, G_DIR_SEPARATOR_S) != 0) { filepath = g_build_filename(vd->dir_fd->path, "..", NULL); fd = file_data_new_dir(filepath); VDLIST(vd)->list = g_list_prepend(VDLIST(vd)->list, fd); g_free(filepath); } if (options->file_filter.show_dot_directory) { filepath = g_build_filename(vd->dir_fd->path, ".", NULL); fd = file_data_new_dir(filepath); VDLIST(vd)->list = g_list_prepend(VDLIST(vd)->list, fd); g_free(filepath); } store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view))); if (clear) gtk_list_store_clear(store); valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &iter, NULL); work = VDLIST(vd)->list; while (work) { gint match; GdkPixbuf *pixbuf; const gchar *date = ""; gboolean done = FALSE; fd = work->data; if (access_file(fd->path, R_OK | X_OK) && fd->name) { if (fd->name[0] == '.' && fd->name[1] == '\0') { pixbuf = vd->pf->open; } else if (fd->name[0] == '.' && fd->name[1] == '.' && fd->name[2] == '\0') { pixbuf = vd->pf->parent; } else { pixbuf = vd->pf->close; if (vd->layout && vd->layout->options.show_directory_date) date = text_from_time(fd->date); } } else { pixbuf = vd->pf->deny; } while (!done) { FileData *old_fd = NULL; if (valid) { gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, DIR_COLUMN_POINTER, &old_fd, -1); if (fd == old_fd) { match = 0; } else { match = filelist_sort_compare_filedata_full(fd, old_fd, sort_type, sort_ascend); if (match == 0) g_warning("multiple fd for the same path"); } } else { match = -1; } if (match < 0) { GtkTreeIter new; if (valid) { gtk_list_store_insert_before(store, &new, &iter); } else { gtk_list_store_append(store, &new); } gtk_list_store_set(store, &new, DIR_COLUMN_POINTER, fd, DIR_COLUMN_ICON, pixbuf, DIR_COLUMN_NAME, fd->name, DIR_COLUMN_DATE, date, -1); done = TRUE; } else if (match > 0)