Example #1
0
/* Synchronizes two lists of entries so that they contain only items that
 * present in both of the lists.  Assumes that both lists are sorted by id. */
static void
leave_only_dups(entries_t *curr, entries_t *other)
{
	int new_id = 0;
	int i = 0, j = 0;

	/* Skip leading unmatched files. */
	while(i < other->nentries && other->entries[i].id == -1)
	{
		++i;
	}

	/* Process sequences of files in two lists. */
	while(i < other->nentries)
	{
		const int id = other->entries[i].id;

		/* Skip sequence of unmatched files. */
		while(j < curr->nentries && curr->entries[j].id < id)
		{
			curr->entries[j++].id = -1;
		}

		if(j < curr->nentries && curr->entries[j].id == id)
		{
			/* Allocate next id when we find a matching pair of files in both
			 * lists. */
			++new_id;
			/* Update sequence of identical ids for other list. */
			do
			{
				other->entries[i++].id = new_id;
			}
			while(i < other->nentries && other->entries[i].id == id);

			/* Update sequence of identical ids for current list. */
			do
			{
				curr->entries[j++].id = new_id;
			}
			while(j < curr->nentries && curr->entries[j].id == id);
		}
	}

	/* Exclude unprocessed files in the tail. */
	while(j < curr->nentries)
	{
		curr->entries[j++].id = -1;
	}

	(void)zap_entries(other_view, other->entries, &other->nentries,
			&is_not_duplicate, NULL, 1, 0);
	(void)zap_entries(curr_view, curr->entries, &curr->nentries,
			&is_not_duplicate, NULL, 1, 0);
}
Example #2
0
void
name_filters_add_selection(view_t *view)
{
	dir_entry_t *entry;
	filter_t filter;
	int filtered;

	(void)filter_init(&filter, FILTER_DEF_CASE_SENSITIVITY);

	/* Traverse items and update/create filter values. */
	entry = NULL;
	while(iter_selection_or_current(view, &entry))
	{
		const char *name = entry->name;
		char name_with_slash[NAME_MAX + 1 + 1];

		if(fentry_is_dir(entry))
		{
			append_slash(entry->name, name_with_slash, sizeof(name_with_slash));
			name = name_with_slash;
		}

		(void)filter_append(&view->auto_filter, name);
		(void)filter_append(&filter, name);
	}

	/* Even current file might be unavailable for filtering.  In this case, just
	 * do nothing. */
	if(filter_is_empty(&filter))
	{
		filter_dispose(&filter);
		return;
	}

	if(view->custom.type == CV_DIFF)
	{
		(void)filter_in_compare(view, &filter, &is_newly_filtered);
		ui_view_schedule_redraw(view);
		filter_dispose(&filter);
		return;
	}

	/* Update entry lists to remove entries that must be filtered out now.  No
	 * view reload is needed. */
	filtered = zap_entries(view, view->dir_entry, &view->list_rows,
			&is_newly_filtered, &filter, 0, 1);
	if(flist_custom_active(view))
	{
		(void)zap_entries(view, view->local_filter.entries,
				&view->local_filter.entry_count, &is_newly_filtered, &filter, 1, 1);
	}
	else
	{
		view->filtered += filtered;
	}

	filter_dispose(&filter);

	fpos_ensure_valid_pos(view);
	ui_view_schedule_redraw(view);
}