Skip to content

Commit

Permalink
Linux: Allow case-insensitive file filters and make that the default
Browse files Browse the repository at this point in the history
  • Loading branch information
btzy committed Feb 24, 2025
1 parent 29e3bcb commit 2590c53
Showing 1 changed file with 62 additions and 4 deletions.
66 changes: 62 additions & 4 deletions src/nfd_gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@

#include "nfd.h"

// Linux file extensions are case-sensitive, but perhaps in the vast majority of cases we actually
// want the filter list to be case-insensitive. Set NFD_LINUX_CASE_SENSITIVE_FILTER to 0 for
// case-insensitive filtering. If NFD_LINUX_CASE_SENSITIVE_FILTER is undefined, then it will be set
// to 0.
#if !defined(NFD_LINUX_CASE_SENSITIVE_FILTER)
#define NFD_LINUX_CASE_SENSITIVE_FILTER 0
#endif

namespace {

template <typename T>
Expand Down Expand Up @@ -122,6 +130,7 @@ void AddFiltersToDialog(GtkFileChooser* chooser,
*p_nameBuf++ = ' ';
}

#if NFD_LINUX_CASE_SENSITIVE_FILTER == 1
// +1 for the trailing '\0'
nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) *
(p_spec - p_extensionStart + 3));
Expand All @@ -130,10 +139,34 @@ void AddFiltersToDialog(GtkFileChooser* chooser,
*p_extnBufEnd++ = '.';
p_extnBufEnd = copy(p_extensionStart, p_spec, p_extnBufEnd);
*p_extnBufEnd++ = '\0';
assert((size_t)(p_extnBufEnd - extnBuf) ==
sizeof(nfdnchar_t) * (p_spec - p_extensionStart + 3));
gtk_file_filter_add_pattern(filter, extnBuf);
NFDi_Free(extnBuf);
#else
// Each character in the Latin alphabet is converted into 4 characters. E.g.
// 'a' is converted into "[Aa]". Other characters are preserved. Then we +1
// for the trailing '\0'.
nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(
sizeof(nfdnchar_t) * ((p_spec - p_extensionStart) * 4 + 3));
nfdnchar_t* p_extnBufEnd = extnBuf;
*p_extnBufEnd++ = '*';
*p_extnBufEnd++ = '.';
// this code will only make regular Latin characters case-insensitive; other
// characters remain case sensitive
for (const nfdnchar_t* it = p_extensionStart; it != p_spec; ++it) {
if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z')) {
*p_extnBufEnd++ = '[';
*p_extnBufEnd++ = *it;
// invert the case of the original character
*p_extnBufEnd++ = *it ^ static_cast<nfdnchar_t>(0x20);
*p_extnBufEnd++ = ']';
} else {
*p_extnBufEnd++ = *it;
}
}
*p_extnBufEnd++ = '\0';
gtk_file_filter_add_pattern(filter, extnBuf);
NFDi_Free(extnBuf);
#endif

if (*p_spec) {
// update the extension start point
Expand Down Expand Up @@ -222,6 +255,7 @@ Pair_GtkFileFilter_FileExtension* AddFiltersToDialogWithMap(GtkFileChooser* choo
*p_nameBuf++ = ' ';
}

#if NFD_LINUX_CASE_SENSITIVE_FILTER == 1
// +1 for the trailing '\0'
nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) *
(p_spec - p_extensionStart + 3));
Expand All @@ -230,10 +264,34 @@ Pair_GtkFileFilter_FileExtension* AddFiltersToDialogWithMap(GtkFileChooser* choo
*p_extnBufEnd++ = '.';
p_extnBufEnd = copy(p_extensionStart, p_spec, p_extnBufEnd);
*p_extnBufEnd++ = '\0';
assert((size_t)(p_extnBufEnd - extnBuf) ==
sizeof(nfdnchar_t) * (p_spec - p_extensionStart + 3));
gtk_file_filter_add_pattern(filter, extnBuf);
NFDi_Free(extnBuf);
#else
// Each character in the Latin alphabet is converted into 4 characters. E.g.
// 'a' is converted into "[Aa]". Other characters are preserved. Then we +1
// for the trailing '\0'.
nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(
sizeof(nfdnchar_t) * ((p_spec - p_extensionStart) * 4 + 3));
nfdnchar_t* p_extnBufEnd = extnBuf;
*p_extnBufEnd++ = '*';
*p_extnBufEnd++ = '.';
// this code will only make regular Latin characters case-insensitive; other
// characters remain case sensitive
for (const nfdnchar_t* it = p_extensionStart; it != p_spec; ++it) {
if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z')) {
*p_extnBufEnd++ = '[';
*p_extnBufEnd++ = *it;
// invert the case of the original character
*p_extnBufEnd++ = *it ^ static_cast<nfdnchar_t>(0x20);
*p_extnBufEnd++ = ']';
} else {
*p_extnBufEnd++ = *it;
}
}
*p_extnBufEnd++ = '\0';
gtk_file_filter_add_pattern(filter, extnBuf);
NFDi_Free(extnBuf);
#endif

// store current pointer in map (if it's
// the first one)
Expand Down

0 comments on commit 2590c53

Please sign in to comment.