Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTK file-open case-insensitive filters #157

Closed
inflex opened this issue Feb 22, 2025 · 7 comments · Fixed by #158
Closed

GTK file-open case-insensitive filters #157

inflex opened this issue Feb 22, 2025 · 7 comments · Fixed by #158

Comments

@inflex
Copy link

inflex commented Feb 22, 2025

Good day, many thanks for NFD-extended, it has been a great replacement for my project, thank you so much.

One thing I had to tackle was implementing GTK/linux case-insensitive filters, and I honestly don't know if I missed something obvious, in which case I duly apologise, but I ended up butchering your good work to drop in a piece of my old code from my prior file-picking.

I did see that gtkmm has implemented in case insensitive suffix matching with;

void Gtk::FileFilter::add_suffix

( https://gnome.pages.gitlab.gnome.org/gtkmm/classGtk_1_1FileFilter.html )

but I'm not sure how that aligns with the API/lib utilised here.

For the interim, and I apologise for the code to follow, I've created this Frankenstein's monster of a blob ( nfd_gtk.cpp );

I did also clobber the building of the filter name as I was passing many extensions ( 22 ).

(EDIT: Converted to use std::string so as to provide memory safety)

void AddFiltersToDialog(GtkFileChooser* chooser,
		const nfdnfilteritem_t* filterList,
		nfdfiltersize_t filterCount) {
	if (filterCount) {
		assert(filterList);

		// we have filters to add ... format and add them
		for (nfdfiltersize_t index = 0; index != filterCount; ++index) {
			GtkFileFilter* filter = gtk_file_filter_new();
			const nfdnchar_t *p_spec = filterList[index].spec;

			while (p_spec && *p_spec) {

				// Using std::string for easy memory-safe usage ( requires <string> )
				std::string cis_filter = std::string("*."); 

				// For each character in the individual file extension, expand out to [aA] if isalpha()
				while (*p_spec != '\0' && *p_spec != ',') {
					char tmp[5];
					if (isalpha(*p_spec)) {
						snprintf(tmp, sizeof(tmp), "[%c%c]", tolower(*p_spec), toupper(*p_spec));
					} else {
						snprintf(tmp, sizeof(tmp), "%c", *p_spec);
					}
					cis_filter += std::string(tmp);
					p_spec++;
				}

				// Add the case-insensitive variant to the filter
				gtk_file_filter_add_pattern(filter, cis_filter.c_str());

				// Jump to the next pspec char if there's one so that the while loop starts with a new glob filter
				if (*p_spec == ',') p_spec++;

			} // for each char in the filter spec

			// add to the filter set
			gtk_file_filter_set_name(filter, filterList[index].name);

			// add filter to chooser
			gtk_file_chooser_add_filter(chooser, filter);
		} // for each filter 
	} // if there's filters

	/* always append a wildcard option to the end*/

	GtkFileFilter* filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "All files");
	gtk_file_filter_add_pattern(filter, "*");
	gtk_file_chooser_add_filter(chooser, filter);
}
@btzy
Copy link
Owner

btzy commented Feb 23, 2025

Hi, thanks for reporting this issue.

I agree that even on Linux, which uses a case-sensitive file system by default, many users will actually want file extensions to be matched case-insensitively.

Gtk.FileFilter.add_suffix seems to be a GTK4 function, which is unavailable to NFDe because we are using GTK3. There was an attempt some time ago (#38) to implement a GTK4 backend, but it was abandoned because it amounted to a pretty large rewrite of the GTK3 backend, there were a few issues I couldn't resolve satisfactorily, and furthermore it was more complicated than GTK3 due to new abstractions introduced in GTK4.

The original issue that led to the addition of Gtk.FileFilter.add_suffix in GTK4 seems to be https://gitlab.gnome.org/GNOME/gtk/-/issues/3705, and on that issue, they've provided two ways to implement case-insensitive filtering on GTK3 (one of which is precisely what you've done).

I think what you're doing seems to be the best workaround for GTK3. I'll add this to NFDe (likely under a feature flag that will be enabled by default, so that people who want the old behaviour can still get it).

@inflex
Copy link
Author

inflex commented Feb 23, 2025

Thank you for taking the time to look at the issue, and further thanks for explaning the .add_suffix details ( GTK4 v 3 ).

I hadn't taken the time sorry to see if there was a feature flag option to pass through but I appreciate that you'll reimplement the concept in your own preferred way.

Would it be worth having something akin to a FILTER_NAME_TERSE option to choose between having the suffixes not appended to the filtername?

I'll leave it all in your good hands; NFD-extended has already made things quite a lot nicer for my software.

@btzy
Copy link
Owner

btzy commented Feb 23, 2025

Would it be worth having something akin to a FILTER_NAME_TERSE option to choose between having the suffixes not appended to the filtername?

This is implementable on Linux but not Windows. Windows appends the extensions automatically to the dropdown menu, and there seems to be no way to get rid of it. Is it appropriate to leave out the suffix though? It seems that most Linux applications will add the suffixes to the dropdown menu items, perhaps for clarity.

@inflex
Copy link
Author

inflex commented Feb 23, 2025

Interestingly under W10, the suffixes do not show, perhaps Windows implements a length test?

Certainly implement it as you see fit, I can always work-around should I feel the want to do so.

Image attached of the W10 build with ~22 suffixes added under the filter of "Boardviews".

Image

@btzy
Copy link
Owner

btzy commented Feb 23, 2025

I did not realise that Windows does not show suffixes under some conditions. This warrants more investigation, and given this is how Windows behaves, it seems reasonable to have a knob under Linux to choose whether to append suffixes or not.

@btzy
Copy link
Owner

btzy commented Feb 23, 2025

I figured it out - the file extension is hidden when you have the "Hide extensions for known file types" option enabled in Windows Explorer. I think Windows usually comes with this option enabled by default.

@inflex
Copy link
Author

inflex commented Feb 23, 2025

I see that turning on file-extensions in the View menu of File Explorer does expose them in the pulldown filter list; at least Windows has the good sense here to crop the list and show the full expansion with a hover-over

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants