diff --git a/CMakeLists.txt b/CMakeLists.txt index 26e891a17..9673ad5d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,8 +145,8 @@ endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -Wno-unused-function -D_FILE_OFFSET_BITS=64") # -fsanitize=address set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c99 -fPIC -Wno-unused-function -D_FILE_OFFSET_BITS=64") # -fsanitize=address -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O2") +set(CMAKE_CXX_FLAGS_RELEASE "-O2") +set(CMAKE_C_FLAGS_RELEASE "-O2") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(APP_DIR ${CMAKE_BINARY_DIR}/install) diff --git a/HACKING.md b/HACKING.md index 6e8a1613f..2e4987755 100644 --- a/HACKING.md +++ b/HACKING.md @@ -83,10 +83,10 @@ far2l uses this to resolve symlink destination when user selects plugin's item t ### Added following dialog messages: * `DM_SETREADONLY` - changes readonly-ness of selected dialog edit control item -* `DM_GETCOLOR` - retrieves current color attributes of selected dialog item -* `DM_SETCOLOR` - changes current color attributes of selected dialog item -* `DM_SETTRUECOLOR` - sets 24-bit RGB colors to selected dialog item, can be used within DN_CTLCOLORDLGITEM handler to provide extra coloring. -* `DM_GETTRUECOLOR` - retrieves 24-bit RGB colors of selected dialog item, if they were set before by DM_SETTRUECOLOR. +* `DM_GETDEFAULTCOLOR` +* `DM_GETCOLOR = DM_SETTRUECOLOR` - sets 24-bit RGB colors to selected dialog item (see DN_CTLCOLORDLGITEM). +* `DM_SETCOLOR = DM_GETTRUECOLOR` - retrieves 24-bit RGB colors of selected dialog item. +* `DM_SETTEXTPTRSILENT` * `ECTL_ADDTRUECOLOR` - applies coloring to editor like ECTL_ADDCOLOR does but allows to specify 24 RGB color using EditorTrueColor structure. * `ECTL_GETTRUECOLOR` - retrieves coloring of editor like ECTL_GETCOLOR does but gets 24 RGB color using EditorTrueColor structure. diff --git a/README.md b/README.md index 0c17fc6ab..5bec59e92 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,15 @@ FreeBSD/MacOS (Cirrus CI): [![Cirrus](https://api.cirrus-ci.com/github/elfmz/far * 7z ANSI-C Decoder * utf-cpp by ww898 +_Note_: Far2l uses keyboard shortcurts in the tradition of the Far Manager for Windows, +but some of them (**Alt**-**F1**, **Alt**-**F2**, **Alt**-**F7**, **Ctrl**-arrows, etc.) +usually exclusively used in desktop environment GNOME, KDE, Xfce, macOS etc. and in terminal emulators. +To work with these keys in far2l you need to _release keyboard shortcuts globally_ +in the environment settings (see [#2326](https://github.com/elfmz/far2l/issues/2326)) +or use far2l lifehacks: +_Sticky controls via **Ctrl**-**Space** or **Alt**-**Space**_ or _Exclusively handle hotkeys option in the Input settings_ +(see details in buil-in far2l help). + ### UI Backends FAR2L has base UI Backends (see details in build-in help section **UI backends**): @@ -42,11 +51,11 @@ FreeBSD/MacOS (Cirrus CI): [![Cirrus](https://api.cirrus-ci.com/github/elfmz/far | **Works:** | in **console**
and in any
**terminal** | in **terminal
window**
under graphic
X11 session
| in **terminal
window**
under graphic
X11 session
| in **Desktop
environment**
(X11
or Wayland
or macOS)
via wxWidgets
| | **Binaries:** | far2l | far2l
far2l_ttyx.broker | far2l
far2l_ttyx.broker | far2l
far2l_gui.so | | **[Dependencies](#required-dependencies):** | minimal | + libx11 | + libx11, libxi | + wxWidgets, GTK | -| **Keyboard:** | _Typical terminals_:
**only essential
key combinations**

_KiTTY_ (putty fork),
_kitty_ (*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| _Typical terminals_:
**only essential
key combinations**

_KiTTY_ (putty fork),
_kitty_ (*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| _Typical terminals_:
**most of key
combinations under x11**;
**only essential key
combinations
under Wayland**

_KiTTY_ (putty fork),
_kitty_ (*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| **All key
combinations** | -| **Clipboard
access:** | _Typical terminals_:
via command line
tools like xclip

_kitty_ (*nix one),
_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| _Typical terminals_,
_kitty_ (*nix one):
via **x11 interaction**

_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| _Typical terminals_,
_kitty_ (*nix one):
via **x11 interaction**

_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| via
**wxWidgets API**

via command line
tools under WSL
| -| **Typical
use case:** | **Servers**,
embedded
(*wrt, etc) | Run far2l in
favorite terminal
but with
**better UX**
| Run far2l in
favorite terminal
but with
**best UX**
| **Desktop** | -| [Debian](https://packages.debian.org/search?keywords=far2l) packages: | _none_
(use `far2l` due to
[auto downgrade](#downgrade))
| `far2l` | `far2l` | `far2l-wx`
(since _2.6.4_) | -| [Ubuntu](https://packages.ubuntu.com/search?keywords=far2l) packages: | _none_
(use `far2l` due to
[auto downgrade](#downgrade))
| `far2l` | `far2l` | _none_ | +| **Keyboard:** | _Typical terminals_:
**only essential
key combinations**

_KiTTY_ (putty fork),
_kitty_ (\*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| _Typical terminals_:
**only essential
key combinations**

_KiTTY_ (putty fork),
_kitty_ (\*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| _Typical terminals_:
**most of key
combinations under x11**;
**only essential key
combinations
under Wayland**

_KiTTY_ (putty fork),
_kitty_ (\*nix one),
_iTerm2_,
_Windows Terminal_,
far2l’s VT: **full support**
| **All key
combinations** | +| **Clipboard
access:** | _Typical terminals_:
via command line
tools like xclip

_kitty_ (\*nix one),
_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| _Typical terminals_,
_kitty_ (\*nix one):
via **x11 interaction**

_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| _Typical terminals_,
_kitty_ (\*nix one):
via **x11 interaction**

_iTerm2_:
via **OSC52**

_Windows Terminal_:
via **OSC52**
or via **command line
tools under WSL**

_KiTTY_ (putty fork),
far2l’s VT:
via **far2l extensions**
| via
**wxWidgets API**

via command line
tools under WSL
| +| **Typical
use case:** | **Servers**,
embedded
(\*wrt, etc) | Run far2l in
favorite terminal
but with
**better UX**
| Run far2l in
favorite terminal
but with
**best UX**
| **Desktop** | +| [Debian](#debian) packages: | _none_
(use `far2l` due to
[auto downgrade](#downgrade))
| `far2l` | `far2l` | `far2l-wx`
(since _2.6.4_) | +| [Ubuntu](#debian) packages: | _none_
(use `far2l` due to
[auto downgrade](#downgrade))
| `far2l` | `far2l` | _none_ | | Community [PPA](#community_bins): | `far2l` | `far2l-ttyx` | `far2l-ttyx` | `far2l-gui` | _Note_: When running far2l automatically downgrade @@ -61,7 +70,7 @@ for plain **TTY**: `far2l --tty --nodetect=x` _Note about use OSC 52 in TTY/TTY|X_: to interact with the system clipboard you must **not forget to enable OSC 52** -in both the **FAR2L settings** (`Options`->`Interface settings`->`Use OSC52 to set clipboard data`, +in both the **FAR2L settings** (`Options`⇒`Interface settings`⇒`Use OSC52 to set clipboard data`, which shown in the dialog only if far2l run in TTY/TTY|X mode and all other options for clipboard access are unavailable; you can run `far2l --tty --nodetect` to force not use others clipboard options), and in **terminal settings** option OSC 52 must be allowed (by default, OSC 52 is disabled in some terminals for security reasons; @@ -69,6 +78,7 @@ OSC 52 in many terminals is implemented only for the copy mode, and paste from t ## Installing, Running + #### Debian/Ubuntu binaries from the official repositories * **TTY X/Xi** backends only (Debian / Ubuntu 23.10+) @@ -88,6 +98,23 @@ https://packages.debian.org/search?keywords=far2l or https://packages.ubuntu.com _Note_: binaries in official repositories may be very outdated, actual binaries or portable see in [Community packages & binaries](#community_bins). +
Backport official packages for old Debian/Ubuntu system + +A simple sid back port should be as easy as (build your own binary deb from the official source deb package, +required install [dependencies](#required-dependencies)): + +```sh +# you will find the latest dsc link at http://packages.debian.org/sid/far2l +dget http://deb.debian.org/debian/pool/main/f/far2l/2.6.3~beta+ds-1.dsc +dpkg-source -x *.dsc +cd far2l-*/ +debuild +# cd .. and install your self built far2l*.deb +``` + +
+ + #### OSX/MacOS binaries You can install prebuilt package for x86_64 platform via Homebrew Cask, by command: @@ -122,7 +149,7 @@ See also [Community packages & binaries](#community_bins) * `libnfs-dev` (_optional_ - needed for **NetRocks/NFS**) * `libneon27-dev` (or later, _optional_ - needed for **NetRocks/WebDAV**) * `libarchive-dev` (_optional_ - needed for better archives support in **multiarc**) -* `libunrar-dev` (_optional_ - needed for RAR archives support in **multiarc**, see `UNRAR` command line option) +* `libunrar-dev` (_optional_ - needed for RAR archives support in **multiarc**, see `-DUNRAR` command line option) * `libpcre2-dev` (_optional_ - needed for advanced custom archive formats support in **multiarc**) * `python3-dev` (_optional_ - needed for **python plugins** support, see `-DPYTHON` command line option) * `python3-cffi` (_optional_ - needed for **python plugins** support, see `-DPYTHON` command line option) @@ -131,22 +158,12 @@ See also [Community packages & binaries](#community_bins) * `g++` * `git` (needed for downloading source code) -#### Or simply on Debian/Ubuntu: +or simply on **Debian/Ubuntu**: ``` sh apt-get install libwxgtk3.0-gtk3-dev libx11-dev libxi-dev libpcre2-dev libxml2-dev libuchardet-dev libssh-dev libssl-dev libsmbclient-dev libnfs-dev libneon27-dev libarchive-dev cmake pkg-config g++ git ``` -A simple sid back port should be as easy as (build your own binary deb from the official source deb package): -```sh -# you will find the latest dsc link at http://packages.debian.org/sid/far2l -dget http://deb.debian.org/debian/pool/main/f/far2l/far2l_2.5.0~beta+git20230223+ds-2.dsc -dpkg-source -x *.dsc -cd far2l-*/ -debuild -# cd .. and install your self built far2l*.deb -``` - -In older distributions: use libwxgtk3.0-dev instead of libwxgtk3.0-gtk3-dev +In older distributions: use `libwxgtk3.0-dev` instead of `libwxgtk3.0-gtk3-dev`. #### Clone and Build * Clone current master @@ -313,7 +330,7 @@ You can import the project into your favourite IDE like QtCreator, CodeLite, or ## Terminals and SSH clients Supporting extended far2l keyboard shortcuts and clipboard access - * **kovidgoyal's kitty** (Linux, macOS, *BSD): https://github.com/kovidgoyal/kitty & https://sw.kovidgoyal.net/kitty (TTY|k backend: keys by kovidgoyal's kitty keyboard protocol; turn on OSC 52 in far2l and kitty for clipboard support) + * **kovidgoyal's kitty** (Linux, macOS, \*BSD): https://github.com/kovidgoyal/kitty & https://sw.kovidgoyal.net/kitty (TTY|k backend: keys by kovidgoyal's kitty keyboard protocol; turn on OSC 52 in far2l and kitty for clipboard support) * **Wez's Terminal Emulator** (Linux, FreeBSD, Windows): https://github.com/wez/wezterm & https://wezfurlong.org/wezterm (TTY|k backend: keys in Linux, FreeBSD by kovidgoyal's kitty keyboard protocol; TTY|w backend: keys in Windows by win32-input-mode, enabled by default; turn on OSC 52 for clipboard support) [kitty keyboard protocol not supported in macOS & Windows] * **iTerm2** (macOS): https://gitlab.com/gnachman/iterm2 & https://iterm2.com (TTY|a backend: keys by iTerm2 "raw keyboard" protocol; turn on OSC 52 for clipboard support) * **Windows Terminal** (TTY|w backend: keys by win32-input-mode; turn on OSC 52 for clipboard support; has mouse bug: https://github.com/microsoft/terminal/issues/15083 ) @@ -332,7 +349,8 @@ one of the best way to initiate the connection **inside local far2l-GUI** * A collection of macros for far2l: https://github.com/corporateshark/far2l-macros * Turbo Vision, TUI framework supporting far2l terminal extensions: https://github.com/magiblot/tvision * turbo, text editor supporting far2l terminal extensions: https://github.com/magiblot/turbo - * Tool to import color schemes from windows FAR manager 2 .reg format: https://github.com/unxed/far2ltricks/blob/main/misc/far2l_import.pl + * far2ltricks: https://github.com/unxed/far2ltricks + * tool to import color schemes from windows FAR manager 2 .reg format: https://github.com/unxed/far2ltricks/blob/main/misc/far2l_import.pl * **Community wiki & tips** (in Russian; unofficial): https://github.com/akruphi/far2l/wiki diff --git a/WinPort/src/APITime.cpp b/WinPort/src/APITime.cpp index 5fa02c35e..e114ab8d1 100644 --- a/WinPort/src/APITime.cpp +++ b/WinPort/src/APITime.cpp @@ -377,11 +377,11 @@ WINPORT_DECL(DosDateTimeToFileTime, BOOL, ( WORD fatdate, WORD fattime, LPFILETI static unsigned s_time_failmask = 0; -WINPORT_DECL(GetTickCount, DWORD, ()) +static DWORD64 GetTickCountInner() { (void)s_time_failmask; #ifdef _WIN32 - return ::GetTickCount(); + return ::GetTickCount64(); #elif defined(__APPLE__) static mach_timebase_info_data_t g_timebase_info; if (g_timebase_info.denom == 0) @@ -397,9 +397,9 @@ WINPORT_DECL(GetTickCount, DWORD, ()) # else if (LIKELY(clock_gettime(CLOCK_REALTIME_COARSE, &spec) == 0)) { # endif - DWORD rv = spec.tv_sec; + DWORD64 rv = spec.tv_sec; rv*= 1000; - rv+= (DWORD)(spec.tv_nsec / 1000000); + rv+= (DWORD64)(spec.tv_nsec / 1000000); return rv; } fprintf(stderr, "%s: clock_gettime error %u\n", __FUNCTION__, errno); @@ -409,19 +409,25 @@ WINPORT_DECL(GetTickCount, DWORD, ()) if (LIKELY((s_time_failmask & 2) == 0)) { struct timeval tv{}; if (LIKELY(gettimeofday(&tv, NULL) == 0)) { - DWORD rv = tv.tv_sec; + DWORD64 rv = tv.tv_sec; rv*= 1000; - rv+= (DWORD)(tv.tv_usec / 1000); + rv+= (DWORD64)(tv.tv_usec / 1000); return rv; } fprintf(stderr, "%s: gettimeofday error %u\n", __FUNCTION__, errno); s_time_failmask|= 2; } - return DWORD(time(NULL) * 1000); + return DWORD64(time(NULL) * 1000); #endif } +WINPORT_DECL(GetTickCount, DWORD, ()) +{ + DWORD out = (DWORD)GetTickCountInner(); + return LIKELY(out != 0) ? out : 1; +} + WINPORT_DECL(Sleep, VOID, (DWORD dwMilliseconds)) { #ifdef _WIN32 @@ -436,10 +442,11 @@ WINPORT_DECL(Sleep, VOID, (DWORD dwMilliseconds)) #endif } -static clock_t g_process_start_stamp = WINPORT(GetTickCount)(); +static DWORD64 g_process_start_stamp = GetTickCountInner(); + SHAREDSYMBOL clock_t GetProcessUptimeMSec() { - clock_t now = WINPORT(GetTickCount)(); - return (now - g_process_start_stamp); + clock_t out = (clock_t)(GetTickCountInner() - g_process_start_stamp); + return LIKELY(out != 0) ? out : 1; } diff --git a/WinPort/src/Backend/TTY/TTYBackend.cpp b/WinPort/src/Backend/TTY/TTYBackend.cpp index 0f0e62b50..4474d3bab 100644 --- a/WinPort/src/Backend/TTY/TTYBackend.cpp +++ b/WinPort/src/Backend/TTY/TTYBackend.cpp @@ -128,6 +128,18 @@ TTYBackend::~TTYBackend() DetachNotifyPipe(); } +static unsigned short GetWinSizeEnv(const char *env, unsigned short def) +{ + const char *psz = getenv(env); + if (psz && *psz) { // use it if it contains sane integer value + int v = atoi(psz); + if (v > 10 && v < 4096) { + return (unsigned short)v; + } + } + return def; +} + void TTYBackend::GetWinSize(struct winsize &w) { int r = ioctl(_stdout, TIOCGWINSZ, &w); @@ -135,10 +147,17 @@ void TTYBackend::GetWinSize(struct winsize &w) r = ioctl(_stdin, TIOCGWINSZ, &w); if (UNLIKELY(r != 0)) { perror("TIOCGWINSZ"); - w.ws_row = g_far2l_term_height; - w.ws_col = g_far2l_term_width; } } + if (UNLIKELY(r != 0) || (w.ws_row == 0 && w.ws_col == 0)) { + // when running over serial console 0:0 is returned always and far2l unusable + // try to use $LINES and $COLUMNS if they contain sane values, + // otherwise fallback to hardcoded 80:25 + w.ws_row = GetWinSizeEnv("LINES", g_far2l_term_height); + w.ws_col = GetWinSizeEnv("COLUMNS", g_far2l_term_width); + fprintf(stderr, "%s: fallback size %u:%u\n", + __FUNCTION__, (unsigned int)w.ws_row, (unsigned int)w.ws_col); + } } void TTYBackend::DetachNotifyPipe() diff --git a/WinPort/src/Backend/TTY/TTYInputSequenceParserExts.cpp b/WinPort/src/Backend/TTY/TTYInputSequenceParserExts.cpp index 4938d50c3..329211f27 100644 --- a/WinPort/src/Backend/TTY/TTYInputSequenceParserExts.cpp +++ b/WinPort/src/Backend/TTY/TTYInputSequenceParserExts.cpp @@ -378,13 +378,26 @@ size_t TTYInputSequenceParser::TryParseAsKittyEscapeSequence(const char *s, size if ((modif_state & KITTY_MOD_CAPSLOCK) && !(modif_state & KITTY_MOD_SHIFT)) { // it's weird, but kitty can not give us uppercase utf8 in caps lock mode // ("text-as-codepoints" mode should solve it, but it is not working for cyrillic chars for unknown reason) - ir.Event.KeyEvent.uChar.UnicodeChar = towupper(ir.Event.KeyEvent.uChar.UnicodeChar); + // ir.Event.KeyEvent.uChar.UnicodeChar = towupper(ir.Event.KeyEvent.uChar.UnicodeChar); + WINPORT(CharUpperBuff)(&ir.Event.KeyEvent.uChar.UnicodeChar, 1); } ir.Event.KeyEvent.bKeyDown = (event_type != KITTY_EVT_KEYUP) ? 1 : 0; ir.Event.KeyEvent.wRepeatCount = 0; + if ((ir.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED) || + (ir.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED)) { + switch (ir.Event.KeyEvent.wVirtualKeyCode) { + case VK_ESCAPE: case VK_DELETE: case VK_BACK: case VK_TAB: case VK_RETURN: case VK_SPACE: + break; + default: + if (ir.Event.KeyEvent.uChar.UnicodeChar > 0) { + WINPORT(CharUpperBuff)(&ir.Event.KeyEvent.uChar.UnicodeChar, 1); + } + } + } + _ir_pending.emplace_back(ir); if (!_using_extension) { diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index 8e2c22877..d8bc2c593 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -23,7 +23,7 @@ // If time between adhoc text copy and mouse button release less then this value then text will not be copied. Used to protect against unwanted copy-paste-s #define QEDIT_COPY_MINIMAL_DELAY 150 -// This defines muh much time UI remain frozen after user released qedit, that +// This defines how much time UI remain frozen after user released qedit, that // allows user to quickly select another location before all shadowed output changes applied #define QEDIT_UNFREEZE_DELAY 1000 @@ -870,11 +870,11 @@ void WinPortPanel::OnConsoleOutputUpdated(const SMALL_RECT *areas, size_t count) if (_refresh_rects.empty()) { action = A_QUEUE; #ifndef __APPLE__ - } else if (_refresh_rects_throttle != (DWORD)-1 && + } else if (_refresh_rects_throttle != 0 && WINPORT(GetTickCount)() - _refresh_rects_throttle > 500 && !wxIsMainThread()) { action = A_THROTTLE; - _refresh_rects_throttle = (DWORD)-1; + _refresh_rects_throttle = 0; #else //TODO: fix stuck #endif @@ -958,8 +958,6 @@ void WinPortPanel::OnConsoleOutputUpdated(const SMALL_RECT *areas, size_t count) CallInMain(fn); std::lock_guard lock(_refresh_rects); _refresh_rects_throttle = WINPORT(GetTickCount)(); - if (_refresh_rects_throttle == (DWORD)-1) - _refresh_rects_throttle = 0; } break; case A_NOTHING: break; @@ -1565,9 +1563,8 @@ void WinPortPanel::OnKeyUp( wxKeyEvent& event ) (!_key_tracker.Alt() || _key_tracker.Shift() || _key_tracker.LeftControl() || _key_tracker.RightControl() || !isNumpadNumericKey(event.GetKeyCode()) || g_wayland) && // workaround for #2294, 2464 #endif - - _key_tracker.CheckForSuddenModifiersUp()) { - _exclusive_hotkeys.Reset(); + _key_tracker.CheckForSuddenModifiersUp()) { + _exclusive_hotkeys.Reset(); } //event.Skip(); } @@ -1624,8 +1621,8 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.wVirtualKeyCode = ir_tmp.Event.KeyEvent.wVirtualKeyCode; ir.Event.KeyEvent.wVirtualScanCode = ir_tmp.Event.KeyEvent.wVirtualScanCode; ir.Event.KeyEvent.dwControlKeyState = ir_tmp.Event.KeyEvent.dwControlKeyState; - ir.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; + WINPORT(CharUpperBuff)(&ir.Event.KeyEvent.uChar.UnicodeChar, 1); } #endif @@ -1635,11 +1632,13 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.bKeyDown = FALSE; wxConsoleInputShim::Enqueue(&ir, 1); + _enqueued_in_onchar = true; + +#if !defined(__WXOSX__) // avoid double up event in ResetInputState() wxKeyEvent keyEventCopy = _key_tracker.LastKeydown(); _key_tracker.OnKeyUp(keyEventCopy); - - _enqueued_in_onchar = true; +#endif } //event.Skip(); } @@ -1812,7 +1811,6 @@ void WinPortPanel::OnMouseQEdit( wxMouseEvent &event, COORD pos_char ) } else { _qedit_unfreeze_start_ticks = 0; } - _qedit_out_state = QOS_FROZEN_BUSY; DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); } else if (_mouse_qedit_start_ticks != 0) { diff --git a/WinPort/src/Backend/WX/wxMain.h b/WinPort/src/Backend/WX/wxMain.h index 192eda385..d76155fed 100644 --- a/WinPort/src/Backend/WX/wxMain.h +++ b/WinPort/src/Backend/WX/wxMain.h @@ -108,13 +108,6 @@ class WinPortPanel: public wxPanel, protected IConsoleOutputBackend RP_DEFER, RP_INSTANT } _resize_pending{RP_NONE}; - enum - { - QOS_NOT_FROZEN, - QOS_FROZEN_BUSY, - QOS_UNFREEZE_PENDING, - QOS_UNFREEZE_PENDING2, - } _qedit_out_state{QOS_NOT_FROZEN}; DWORD _qedit_unfreeze_start_ticks{0}; DWORD _mouse_state{0}, _mouse_qedit_start_ticks{0}, _mouse_qedit_moved{0}; COORD _mouse_qedit_start{}, _mouse_qedit_last{}; diff --git a/colorer/CMakeLists.txt b/colorer/CMakeLists.txt index a5a225bad..aee3adc62 100644 --- a/colorer/CMakeLists.txt +++ b/colorer/CMakeLists.txt @@ -21,6 +21,7 @@ set(SOURCES src/pcolorer2/FarHrcSettings.cpp src/pcolorer2/pcolorer.cpp src/pcolorer2/tools.cpp + src/pcolorer2/CerrLogger.cpp src/pcolorer2/CerrLogger.h ) @@ -73,5 +74,5 @@ add_subdirectory("${LIBCOLORER_TREE}" "${CMAKE_BINARY_DIR}/Colorer-library/src") set_target_properties(colorer PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES - CXX_EXTENSIONS NO -) \ No newline at end of file + CXX_EXTENSIONS YES +) diff --git a/colorer/src/Colorer-library/src/CMakeLists.txt b/colorer/src/Colorer-library/src/CMakeLists.txt index 414a5de6b..f6db68165 100644 --- a/colorer/src/Colorer-library/src/CMakeLists.txt +++ b/colorer/src/Colorer-library/src/CMakeLists.txt @@ -229,7 +229,7 @@ target_include_directories(colorer_lib PUBLIC set_target_properties(colorer_lib PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES - CXX_EXTENSIONS NO + CXX_EXTENSIONS YES ) target_link_libraries(colorer_lib diff --git a/colorer/src/Colorer-library/src/colorer/Common.h b/colorer/src/Colorer-library/src/colorer/Common.h index 92bd6834c..51592e403 100644 --- a/colorer/src/Colorer-library/src/colorer/Common.h +++ b/colorer/src/Colorer-library/src/colorer/Common.h @@ -9,6 +9,12 @@ #include "colorer/strings/legacy/strings.h" #endif +#if __cplusplus >= 201703L +# define UNICODE_LITERAL(name, value) inline const auto name = UnicodeString(value); +#else +# define UNICODE_LITERAL(name, value) static const auto name = UnicodeString(value); +#endif + /* Logging */ diff --git a/colorer/src/Colorer-library/src/colorer/base/BaseNames.h b/colorer/src/Colorer-library/src/colorer/base/BaseNames.h index c993afd8c..0c38964cf 100644 --- a/colorer/src/Colorer-library/src/colorer/base/BaseNames.h +++ b/colorer/src/Colorer-library/src/colorer/base/BaseNames.h @@ -5,6 +5,7 @@ const char16_t HrdNameDefault[] = u"default\0"; const char16_t HrdClassRgb[] = u"rgb\0"; const char16_t HrdClassText[] = u"text\0"; -inline const auto jar = UnicodeString(u"jar:"); +UNICODE_LITERAL(jar, u"jar:") +//inline const auto jar = UnicodeString(u"jar:"); #endif // COLORER_BASENAMES_H diff --git a/colorer/src/Colorer-library/src/colorer/base/XmlTagDefs.h b/colorer/src/Colorer-library/src/colorer/base/XmlTagDefs.h index 76be2a2bc..3a4f0251d 100644 --- a/colorer/src/Colorer-library/src/colorer/base/XmlTagDefs.h +++ b/colorer/src/Colorer-library/src/colorer/base/XmlTagDefs.h @@ -1,8 +1,6 @@ #ifndef COLORER_XMLTAGDEFS_H #define COLORER_XMLTAGDEFS_H -#define UNICODE_LITERAL(name, value) inline const auto name = UnicodeString(value); - /* catalog.xml diff --git a/colorer/src/Colorer-library/src/colorer/common/Logger.h b/colorer/src/Colorer-library/src/colorer/common/Logger.h index ae444ef1a..7b0051d58 100644 --- a/colorer/src/Colorer-library/src/colorer/common/Logger.h +++ b/colorer/src/Colorer-library/src/colorer/common/Logger.h @@ -3,6 +3,14 @@ #include +#if __cplusplus < 201703L +# include +namespace std +{ + typedef experimental::string_view string_view; +} +#endif + namespace details { class Argument diff --git a/colorer/src/Colorer-library/src/colorer/xml/libxml2/LibXmlReader.cpp b/colorer/src/Colorer-library/src/colorer/xml/libxml2/LibXmlReader.cpp index ca54463e6..d2cb6a0d5 100644 --- a/colorer/src/Colorer-library/src/colorer/xml/libxml2/LibXmlReader.cpp +++ b/colorer/src/Colorer-library/src/colorer/xml/libxml2/LibXmlReader.cpp @@ -107,7 +107,7 @@ void LibXmlReader::getAttributes(const xmlNode* node, std::unordered_mapproperties; attr != nullptr; attr = attr->next) { const auto content = xmlNodeGetContent(attr->children); - data.emplace(std::pair(reinterpret_cast(attr->name), reinterpret_cast(content))); + data.emplace(std::make_pair(reinterpret_cast(attr->name), reinterpret_cast(content))); xmlFree(content); } } diff --git a/colorer/src/pcolorer2/CerrLogger.cpp b/colorer/src/pcolorer2/CerrLogger.cpp new file mode 100644 index 000000000..073aff4cb --- /dev/null +++ b/colorer/src/pcolorer2/CerrLogger.cpp @@ -0,0 +1,41 @@ +#include "pcolorer.h" +#include "FarEditorSet.h" +#include "CerrLogger.h" + +const char *CerrLogger::LogLevelStr[] {"off", "error", "warning", "info", "debug", "trace"}; + +CerrLogger::CerrLogger() +{ + const char* verbose_env = getenv("COLORER_VERBOSE"); + if (verbose_env) { + current_level = getLogLevel(verbose_env); + } +} + +void CerrLogger::log(Logger::LogLevel level, const char* /*filename_in*/, int /*line_in*/, + const char* /*funcname_in*/, const char* message) +{ + if (level > current_level) { + return; + } + std::time_t const t = std::time(nullptr); + char mbstr[30]; + std::strftime(mbstr, sizeof(mbstr), "%FT%T", std::localtime(&t)); + std::cerr << "[" << mbstr << "] [FarColorer] [" << LogLevelStr[level] << "] "; + std::cerr << message << '\n'; +} + +Logger::LogLevel CerrLogger::getLogLevel(const std::string& log_level) +{ + int i = 0; + for (auto it : LogLevelStr) { + if (log_level == it) { + return static_cast(i); + } + i++; + } + if (log_level == "warn") { + current_level = Logger::LOG_WARN; + } + return Logger::LOG_OFF; +} diff --git a/colorer/src/pcolorer2/CerrLogger.h b/colorer/src/pcolorer2/CerrLogger.h index bb8783f3f..c25a828e8 100644 --- a/colorer/src/pcolorer2/CerrLogger.h +++ b/colorer/src/pcolorer2/CerrLogger.h @@ -8,46 +8,15 @@ class CerrLogger : public Logger { public: - static constexpr std::string_view LogLevelStr[] {"off", "error", "warning", - "info", "debug", "trace"}; + static const char *LogLevelStr[]; - CerrLogger() - { - const char* verbose_env = getenv("COLORER_VERBOSE"); - if (verbose_env) { - current_level = getLogLevel(verbose_env); - } - } + CerrLogger(); ~CerrLogger() override = default; void log(Logger::LogLevel level, const char* /*filename_in*/, int /*line_in*/, - const char* /*funcname_in*/, const char* message) override - { - if (level > current_level) { - return; - } - std::time_t const t = std::time(nullptr); - char mbstr[30]; - std::strftime(mbstr, sizeof(mbstr), "%FT%T", std::localtime(&t)); - std::cerr << "[" << mbstr << "] [FarColorer] [" << LogLevelStr[level] << "] "; - std::cerr << message << '\n'; - } - - Logger::LogLevel getLogLevel(const std::string& log_level) - { - int i = 0; - for (auto it : LogLevelStr) { - if (log_level == it) { - return static_cast(i); - } - i++; - } - if (log_level == "warn") { - current_level = Logger::LOG_WARN; - } - return Logger::LOG_OFF; - } + const char* /*funcname_in*/, const char* message) override; + Logger::LogLevel getLogLevel(const std::string& log_level); void flush() override {}; diff --git a/far2l/CMakeLists.txt b/far2l/CMakeLists.txt index b6d42271a..088bd887b 100644 --- a/far2l/CMakeLists.txt +++ b/far2l/CMakeLists.txt @@ -101,7 +101,7 @@ src/console/scrsaver.cpp src/filemask/CFileMask.cpp src/filemask/FileMasksProcessor.cpp -src/filemask/FileMasksWithExclude.cpp +#src/filemask/FileMasksWithExclude.cpp src/locale/codepage.cpp src/locale/DetectCodepage.cpp @@ -120,6 +120,7 @@ src/cfg/ConfigRW.cpp src/cfg/ConfigLegacy.cpp src/cfg/HotkeyLetterDialog.cpp src/cfg/language.cpp +src/cfg/MaskGroups.cpp src/hist/history.cpp src/hist/poscache.cpp diff --git a/far2l/bootstrap/scripts/FarEng.hlf.m4 b/far2l/bootstrap/scripts/FarEng.hlf.m4 index 4d67639bd..8d75fc702 100644 --- a/far2l/bootstrap/scripts/FarEng.hlf.m4 +++ b/far2l/bootstrap/scripts/FarEng.hlf.m4 @@ -3413,7 +3413,9 @@ combinations are available: #Ctrl-Down# - Move a group down. The highlighting groups are checked from top to bottom. If it is detected -that a file belongs to a group, no further groups are checked. +that a file belongs to a group, no further groups are checked, +unless #[x] Continue processing# is set in the group +(see last indicator #↓# in group list). Display of markers is controlled globally via a checkbox in the ~Panel settings~@PanelSettings@ dialog diff --git a/far2l/bootstrap/scripts/FarHun.hlf.m4 b/far2l/bootstrap/scripts/FarHun.hlf.m4 index 325a285dd..2b4d85e17 100644 --- a/far2l/bootstrap/scripts/FarHun.hlf.m4 +++ b/far2l/bootstrap/scripts/FarHun.hlf.m4 @@ -2967,7 +2967,9 @@ csoportokat #Ctrl-Le# - A csoportot lefelé mozgatja A FAR a csoportkiemeléseket felülről lefelé haladva vizsgálja. Ha érzékeli, -hogy a fájl valamelyik csoport tagja, további hovatartozását nem vizsgálja. +hogy a fájl valamelyik csoport tagja, további hovatartozását nem vizsgálja, +unless #[x] Folyamatos feldolgozás# is set in the group +(see last indicator #↓# in group list). Display of markers is controlled globally via a checkbox in the ~Panel settings~@PanelSettings@ dialog diff --git a/far2l/bootstrap/scripts/FarRus.hlf.m4 b/far2l/bootstrap/scripts/FarRus.hlf.m4 index 6fc113230..42d8aa541 100644 --- a/far2l/bootstrap/scripts/FarRus.hlf.m4 +++ b/far2l/bootstrap/scripts/FarRus.hlf.m4 @@ -3472,7 +3472,9 @@ $ #Раскраска файлов и группы сортировки: кла Группы раскраски анализируются от начала к концу. Если обнаружено, что файл принадлежит к какой-либо группе, то принадлежность к остальным группам не -проверяется. +проверяется, кроме случая включенного параметра +#[x] Продолжать обработку# в настройках группы +(см. последний индикатор #↓# в списке групп). Отображение маркеров управляется глобально галочкой в диалоге ~Настройки панели~@PanelSettings@ diff --git a/far2l/bootstrap/scripts/FarUkr.hlf.m4 b/far2l/bootstrap/scripts/FarUkr.hlf.m4 index 0d05cce1d..cc4f66b62 100644 --- a/far2l/bootstrap/scripts/FarUkr.hlf.m4 +++ b/far2l/bootstrap/scripts/FarUkr.hlf.m4 @@ -3315,7 +3315,8 @@ $ #Розмальовка файлів та групи сортування: к Групи розмальовки аналізуються від початку до кінця. Якщо виявлено, що файл належить до будь-якої групи, то приналежність до інших груп не -перевіряється. +перевіряється, unless #[x] Продовжувати обробку# is set in the group +(see last indicator #↓# in group list). Display of markers is controlled globally via a checkbox in the ~Panel settings~@PanelSettings@ dialog diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 162c3d03e..4fb14b555 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -1521,6 +1521,106 @@ le://End of functional keys "" "" +MaskGroupTitle +"Группы масок файлов" +"Groups of file masks" +"Skupiny masek souborů" +"Gruppe der Datenmasken" +upd:"Groups of file masks" +"Grupy masek plików" +"Grupos de máscara de archivos" +"Групи масок файлів" +"Суполкі масак файлаў" + +MaskGroupBottomTitle +"Ins Del F4 F7 Ctrl+Вверх/Вниз Ctrl+R" +"Ins Del F4 F7 Ctrl+Up/Down Ctrl+R" +"Ins Del F4 F7 Ctrl+Nahoru/Dolů Ctrl+R" +"Ins Del F4 F7 Ctrl+Hoch/Runter Ctrl+R" +"Ins Del F4 F7 Ctrl+Felfelé/Lefelé Ctrl+R" +"Ins Del F4 F7 Ctrl+Wgórę/Wdół Ctrl+R" +"Ins Del F4 F7 Ctrl+Arriba/Abajo Ctrl+R" +"Ins Del F4 F7 Ctrl+Вгору/Вниз Ctrl+R" +"Ins Del F4 F7 Ctrl+Уверх/Уніз Ctrl+R"" + +MaskGroupName +"&Имя:" +"&Name:" +"Jmé&no:" +"&Name:" +"&Neve:" +"&Nazwa:" +"&Nombre:" +"&Ім'я:" +"&Імя:" + +MaskGroupMasks +"Одна или несколько &масок файлов:" +"A file &mask or several file masks:" +"&Maska nebo masky souborů:" +"Datei&maske (mehrere getrennt mit Komma):" +"F&ájlmaszk(ok, vesszővel elválasztva):" +"&Maska pliku lub kilka masek oddzielonych przecinkami:" +"&Máscara de archivo o múltiples máscaras de archivos:" +"Одна або декілька &масок файлів:" +"Адна ці некалькі &масак файлаў" + +MaskGroupAskDelete +"Вы хотите удалить" +"Do you wish to delete" +"Přejete si smazat" +"Wollen Sie folgendes Objekt löschen" +"Törölni akar" +"Czy chcesz usunąć" +"Quiere borrar" +"Ви бажаєте видалити" +"Вы жадаеце выдаліць" + +MaskGroupTargetFilter +"&Имя цели для масок:" +"Target &name for masks:" +"&Cílové jméno pro masky:" +"&Zielname für Masken:" +"&Cél neve a maszkokhoz: +"&Nazwa docelowa dla masek:" +"&Nombre de destino para máscaras:" +"&Ім'я цілі для масок:" +"&Імя мэты для масак:" + +MaskGroupTotal +"Всего: %d" +"Total: %d" +"Celkem: %d" +"Insgesamt: %d" +"Összesen: %d" +"Razem: %d" +"Total: %d" +"Всього: %d" +"Усяго: %d" + +MaskGroupWarning +"Будут потеряны все Ваши настройки" +"You will lose all changes" +"Všechny změny budou ztraceny" +"Sie verlieren jegliche Änderungen" +"Minden változtatás elvész" +"Wszystkie zmiany zostaną utracone" +"Usted perderá todos los cambios" +"Втрачені всі Ваші налаштування" +"Будуць згублены усе Налады" + +MaskGroupRestore +"Вы хотите восстановить наборы масок по умолчанию?" +"Do you want to restore the default mask sets?" +"Chcete obnovit výchozí sady masek?" +"Möchten Sie die Standardmaskensätze wiederherstellen?" +"Szeretné visszaállítani az alapértelmezett maszkhalmazokat?" +"Czy chcesz przywrócić domyślne zestawy masek?" +"¿Quieres restaurar los conjuntos de máscaras predeterminados?" +"Ви хочете відновити набори масок за замовчуванням?" +"Вы хочаце адновіць наборы масак па змаўчанні?" + + HistoryTitle l: "История команд" @@ -2266,6 +2366,72 @@ upd:"Input settings" "Налаштування введення" "Налады увода" +DirSettingsTitle +"Настройки отображения каталога" +"Directory showas settings" +"Nastavení zobrazení adresáře" +"Einstellungen zur Anzeige des Verzeichnisses" +"Könyvtár megjelenítési beállításai" +"Ustawienia wyświetlania katalogu" +"Configuración de visualización del directorio" +"Налаштування відображення каталогу" +"Налады адлюстравання каталога" + +DirSettingsCenter +"Выравнивать по центру" +"Center align" +"Zarovnat do středu" +"Zentrieren" +"Középre igazítani" +"Wyśrodkować" +"Alinear al centro" +"Вирівняти по центру" +"Выраўнаваць па цэнтры" + +DirSettingsSurround +"Символы вокруг" +"Symbols around" +"Symboly kolem" +"Symbole um" +"Szimbólumok körül" +"Symbole wokół" +"Símbolos alrededor" +"Символи навколо" +"Сімвалы вакол" + +DirSettingsShowAs +"Показывать директорию как:" +"Show directory as:" +"Zobrazit adresář jako:" +"Verzeichnis anzeigen als:" +"Könyvtár megjelenítéseként:" +"Pokaż katalog jako:" +"Mostrar directorio como:" +"Показувати каталог як:" +"Паказваць каталог як:" + +DirSettingsEmpty +"-" +"-" +"-" +"-" +"-" +"-" +"-" +"-" +"-" + +DirSettingsApply +"Применить" +"Apply" +"Použít" +"Anwenden" +"Alkalmaz" +"Zastosować" +"Aplicar" +"Застосувати" +"Ужыць" + ConfigClock "&Часы в панелях" "&Clock in panels" @@ -9145,51 +9311,182 @@ ColumnMumLinks "КлС" "КлСпасылак" -ListUp -l: +DirUp "Вверх" -" Up " +"Up" "Nahoru" -" Hoch " -" Fel " +"Nach oben" +"Felfelé" "W górę" -"UP-DIR" +"Arriba" "Вгору" "Уверх" -ListFolder +DirName "Папка" "Folder" -"Adresář" +"Složka" "Ordner" -" Mappa " +"Mappa" "Folder" -" DIR " -"Тека" -"Каталог" +"Carpeta" +"Папка" +"Папка" -ListSymLink +DirUp2 +"КАТАЛОГ" +"UP--DIR" +"KATALOG" +"KATALOG" +"KATALÓG" +"KATALOG" +"CATÁLOG" +"КАТАЛОГ" +"КАТАЛОГ" + +DirName2 +"КАТАЛОГ" +"SUB-DIR" +"KATALOG" +"KATALOG" +"KATALÓG" +"KATALOG" +"CATÁLOG" +"КАТАЛОГ" +"КАТАЛОГ" + +DirUp3 +"ДИР-ВВЕРХ" +"DIR-UP" +"DIR-NAHORU" +"VERZ-OBEN" +"KÖNYV-FENT" +"KAT-W GÓRĘ" +"DIR-ARRIBA" +"ДИР-ВГОРУ" +"ДЫР-ЎВЕРХ" + +DirName3 +"ДИРЕКТОРИЯ" +"DIRECTORY" +"ADRESÁŘ" +"VERZEICHNIS" +"KÖNYVTÁR" +"KATALOG" +"DIRECTORIO" +"ДИРЕКТОРІЯ" +"ДЫРЭКТЫРЫЯ" + +DirUp4 +"ДИР-ВВЕРХ" +"DIR-UP" +"DIR-NAHORU" +"VERZ-OBEN" +"KÖNYV-FENT" +"KAT-W GÓRĘ" +"DIR-ARRIBA" +"ДИР-ВГОРУ" +"ДЫР-ЎВЕРХ" + +DirName4 +"ПОД-ДИРЕК" +"SUB-DIR" +"POD-ADRESÁ" +"UNTERVERZ" +"ALMAPPÁLYA" +"PODKATALOG" +"SUBDIRECTO" +"ПІД-ДИРЕК" +"ПАД-ДЫРЭК" + +SymLinkName "Ссылка" "Symlink" "Link" "Symlink" "SzimLnk" "LinkSym" -" Enlac" +"Enlac" "Посилання" "Спасылак" -ListJunction +SymLinkName2 +"Ссылка" +"Symlink" +"Syodkaz" +"Symlink" +"Hivatko" +"Symlink" +"Enlace" +"Посилан" +"Справка" + +SymLinkName3 +"ССЫЛКА" +"SYMLINK" +"SYODKAZ" +"SYMLINK" +"HIVATKO" +"SYMLINK" +"ENLACE" +"ПОСИЛАН" +"СПРАВКА" + +SymLinkName4 +"ССЫЛКА" +"SYMLINK" +"SYODKAZ" +"SYMLINK" +"HIVATKO" +"SYMLINK" +"ENLACE" +"ПОСИЛАН" +"СПРАВКА" + +JunctionName "Связь" "Junction" "Křížení" "Knoten" "Csomópt" "Dowiązania" -" Junc " +"Junc" "Зв'язок" "Злучэнне" +JunctionName2 +"СВЯЗЬ" +"JUNCDIR" +"KŘÍŽENÍ" +"KNOTEN" +"CSOMÓPT" +"DOWIĄZANIA" +"JUNC" +"ЗВ'ЯЗОК" +"ЗЛУЧЭННЕ" + +JunctionName3 +"СВЯЗЬ" +"JUNCDIR" +"KŘÍŽENÍ" +"KNOTEN" +"CSOMÓPT" +"DOWIĄZANIA" +"JUNC" +"ЗВ'ЯЗОК" +"ЗЛУЧЭННЕ" + +JunctionName4 +"СВЯЗЬ" +"JUNCDIR" +"KŘÍŽENÍ" +"KNOTEN" +"CSOMÓPT" +"DOWIĄZANIA" +"JUNC" +"ЗВ'ЯЗОК" +"ЗЛУЧЭННЕ" + ListBytes "Б" "B" @@ -11865,15 +12162,15 @@ l: "Меню фільтраў" FilterBottom -"+ - Пробел I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" -"+ - Space I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" -"+ - Mezera I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" -"+ - Leer I X BS UmschBS Einf Entf F4 F5 StrgUp StrgDn" -"+ - Szóköz I X BS Shift+BS Ins Del F4 F5 Ctrl+Fel Ctrl+Le" -"+ - Spacja I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" -"Seleccione: '+' '-' Space. Editor: Ins Del F4" -"+ - Пробіл I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" -"+ - Space I X BS Shift+BS Ins Del F4 F5 Ctrl+Up Ctrl+Dn" +"+ - Пробел I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" +"+ - Space I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" +"+ - Mezera I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" +"+ - Leer I X BS UmschBS Einf Entf F4 F5 StrgUp/Dn Ctrl+M" +"+ - Szóköz I X BS Shift+BS Ins Del F4 F5 Ctrl+Fel/Le Ctrl+M" +"+ - Spacja I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" +"Seleccione: '+' '-' Space. Editor: Ins Del F4 Ctrl+M" +"+ - Пробіл I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" +"+ - Space I X BS Shift+BS Ins Del F4 F5 Ctrl+Up/Dn Ctrl+M" PanelFileType "Файлы панели" @@ -12599,15 +12896,15 @@ l: "Афарбоўка файлаў" HighlightBottom -"+ - Пробел Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" -"+ - Space Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" -"+ - Mezera Ins Del F4 F5 Ctrl+Nahoru Ctrl+Dolů" -"+ - Leer Einf Entf F4 F5 Strg+Up,Strg+Down Strg+R" -"+ - Szóköz Ins Del F4 F5 Ctrl+Fel Ctrl+Le Ctrl+R" -"+ - Spacja Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" -"+ - Space Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" -"+ - Пробіл Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" -"+ - Space Ins Del F4 F5 Ctrl+Up Ctrl+Down Ctrl+R" +"+ - Пробел Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" +"+ - Space Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" +"+ - Mezera Ins Del F4 F5 Ctrl+Nahoru/Dolů Ctrl+M" +"+ - Leer Einf Entf F4 F5 Strg+Up/Down Strg+R Strg+M" +"+ - Szóköz Ins Del F4 F5 Ctrl+Fel/Le Ctrl+R Ctrl+M" +"+ - Spacja Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" +"+ - Space Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" +"+ - Пробіл Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" +"+ - Space Ins Del F4 F5 Ctrl+Up/Down Ctrl+R Ctrl+M" HighlightUpperSortGroup "Верхняя группа сортировки" @@ -12709,6 +13006,28 @@ HighlightMarkStrInherit "Спадкувати" "Падзярэваць" +HighlightMarkAddInherit +"Добавить" +"Add" +"Přidat" +"Hinzufügen" +"Hozzáad" +"Dodaj" +"Añadir" +"Додати" +"Дадаць" + +HighlightCustomIdent +"Отступ" +"Indent" +"Odsazení" +"Einzug" +"Behúzás" +"Wcięcie" +"Sangría" +"Відступ" +"Адступ" + HighlightColors " Цвета файлов (\"чёрный на чёрном\" - цвет по умолчанию) " " File name colors (\"black on black\" - default color) " @@ -14367,6 +14686,28 @@ MenuSwapPanels "Зм&інити панелі Ctrl+U" "З&мяніць панэлі Ctrl+U" +MenuHorizontalPanels +"Гори&зонтальные панели Ctrl+," +"Hori&zontal panels Ctrl+," +"Hori&zontální panely Ctrl+," +"Hori&zontale Paneele Strg+," +"Hori&zontális panel Ctrl+," +"Po&ziome panele Ctrl+," +"Paneles hori&zontales Ctrl+," +"Гори&зонтальні панелі Ctrl+," +"Гори&зантальныя панэлі Ctrl+," + +MenuVerticalPanels +"Вер&тикальные панели Ctrl+," +"Ver&tical panels Ctrl+," +"Ver&tikální panely Ctrl+," +"Ver&tikale Paneele Strg+," +"Ver&tikális panelek Ctrl+," +"Pionow&e panele Ctrl+," +"Paneles ver&ticales Ctrl+," +"Вер&тикальні панелі Ctrl+," +"Вер&тыкальныя панэлі Ctrl+," + MenuTogglePanels "Панели &Вкл/Выкл Ctrl+O" "&Panels On/Off Ctrl+O" @@ -14599,6 +14940,17 @@ upd:"AutoComplete && History settings" "На&лаштування автозавершення та історії" "На&лады аўтазаканчэння і гістарычных" +MenuMaskGroups +"Группы масок файлов" +"Groups of file mas&ks" +"Skupiny masek souborů" +"Gruppe der Datenmasken" +upd:"Groups of file masks" +"Grupy masek p&lików" +"Grupos de máscara de archivos" +"Групи масок файлів" +"Суполкі масак файлаў" + MenuInfoPanelSettings "Нас&тройки информационной панели" "Inf&oPanel settings" @@ -17034,6 +17386,17 @@ SetBW "Чорно-біл&ий режим" "Чорна-бел&ы рэжым" +Palette +"П&алитра" +"P&alette" +"P&aleta" +"P&alette" +"P&aletta" +"P&aleta" +"P&aleta" +"П&алітра" +"&алiтра" + SetColorPanelNormal l: "Обычный текст" @@ -18783,15 +19146,15 @@ LocalMenuTitle "Мясцовае меню" MainMenuBottomTitle -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Entf Einf F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" -"Del Ins F4 Ctrl+F4 Ctrl+Up Ctrl+Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" +"Del Ins F4 Ctrl+F4 Ctrl+Up/Down Ctrl+Alt+F" AskDeleteMenuItem "Вы хотите удалить пункт меню" @@ -25530,15 +25893,15 @@ FileHilightTitle "Афарбоўка файлаў" FileFilterName -"Имя &фильтра:" -"Filter &name:" -"Jmé&no filtru:" -"Filter&name:" -"Szűrő &neve:" -"Nazwa &filtra:" -"&Nombre filtro:" -"Ім'я &фільтра:" -"Імя &фільтра:" +"&Имя:" +"&Name:" +"Jmé&no:" +"&Name:" +"&Neve:" +"&Nazwa:" +"&Nombre:" +"&Ім'я:" +"&Імя:" FileFilterMatchMask "&Маска:" diff --git a/far2l/far2sdk/farplug-wide.h b/far2l/far2sdk/farplug-wide.h index 48751176b..8db905e5f 100644 --- a/far2l/far2sdk/farplug-wide.h +++ b/far2l/far2sdk/farplug-wide.h @@ -1902,12 +1902,18 @@ typedef int (WINAPI *FARSTDLOCALSTRNCMP)(const wchar_t *s1,const wchar_t *s2,int enum PROCESSNAME_FLAGS { - PN_CMPNAME = 0x00000000UL, - PN_CMPNAMELIST = 0x00010000UL, - PN_GENERATENAME = 0x00020000UL, - PN_SKIPPATH = 0x01000000UL, + PN_CMPNAME = 0x00000000UL, + PN_CMPNAMELIST = 0x00010000UL, + PN_GENERATENAME = 0x00020000UL, + PN_CHECKMASK = 0x00030000UL, + PN_SKIPPATH = 0x01000000UL, + PN_SHOWERRORMESSAGE = 0x02000000UL, + PN_RESERVED1 = 0x04000000UL, + PN_CASESENSITIVE = 0x08000000UL, + PN_NONE = 0 }; + typedef int (WINAPI *FARSTDPROCESSNAME)(const wchar_t *param1, wchar_t *param2, DWORD size, DWORD flags); typedef void (WINAPI *FARSTDUNQUOTE)(wchar_t *Str); diff --git a/far2l/src/DialogBuilder.cpp b/far2l/src/DialogBuilder.cpp index eb0265226..03f1ef748 100644 --- a/far2l/src/DialogBuilder.cpp +++ b/far2l/src/DialogBuilder.cpp @@ -84,6 +84,7 @@ DialogBuilder::DialogBuilder(FarLangMsg TitleMessageId, const wchar_t *HelpTopic : HelpTopic(HelpTopic) { + UserDlgProc = nullptr; AddBorder(GetLangString(TitleMessageId)); } @@ -210,11 +211,22 @@ void DialogBuilder::LinkFlagsByID(DialogItemEx *Parent, int TargetID, FarDialogI LONG_PTR WINAPI DialogBuilder::DlgProc(HANDLE hDlg, int Msg, int Param1, LONG_PTR Param2) { +#if 0 + DialogBuilder *Builder = (DialogBuilder *)((Dialog *)hDlg)->GetDialogData(); + + if (Builder->UserDlgProc) { + const LONG_PTR rv = Builder->UserDlgProc(hDlg, Msg, Param1, Param2); + if (rv != -1) + return rv; + } +#endif + if (Msg == DN_INITDIALOG) { DialogBuilder *Builder = (DialogBuilder *)((Dialog *)hDlg)->GetDialogData(); for (const auto &CB : Builder->CodePageBoxes) { FillCodePagesList(hDlg, CB.Index, CB.Value, CB.allowAuto, CB.allowAll); } + } else if (Msg == DN_EDITCHANGE) { DialogBuilder *Builder = (DialogBuilder *)((Dialog *)hDlg)->GetDialogData(); for (auto &CB : Builder->CodePageBoxes) @@ -228,6 +240,14 @@ LONG_PTR WINAPI DialogBuilder::DlgProc(HANDLE hDlg, int Msg, int Param1, LONG_PT return DefDlgProc(hDlg, Msg, Param1, Param2); } +bool DialogBuilder::SetUserDlgProc(FARWINDOWPROC UserDlgProc, LONG_PTR UserParam2) +{ + this->UserDlgProc = UserDlgProc; + this->UserData = UserParam2; + + return true; +} + int DialogBuilder::DoShowDialog() { Dialog Dlg(DialogItems, DialogItemsCount, DlgProc, (LONG_PTR)this); diff --git a/far2l/src/DialogBuilder.hpp b/far2l/src/DialogBuilder.hpp index 01277007b..dbb6d4381 100644 --- a/far2l/src/DialogBuilder.hpp +++ b/far2l/src/DialogBuilder.hpp @@ -64,6 +64,7 @@ class DialogBuilder : public DialogBuilderBase bool allowAll; }; std::list CodePageBoxes; // must be list to keep pointers valid + FARWINDOWPROC UserDlgProc; const wchar_t *HelpTopic; @@ -86,6 +87,9 @@ class DialogBuilder : public DialogBuilderBase DialogItemEx * AddEditField(FARString *Value, int Width, const wchar_t *HistoryID = nullptr, int Flags = 0); + LONG_PTR UserData; + bool SetUserDlgProc(FARWINDOWPROC UserProc, LONG_PTR UserParam2); + // Добавляет поле типа DI_FIXEDIT для редактирования указанного числового значения. virtual DialogItemEx *AddIntEditField(int *Value, int Width, int Flags = 0); diff --git a/far2l/src/cfg/ConfigOpt.cpp b/far2l/src/cfg/ConfigOpt.cpp index c59c7bc12..64717cada 100644 --- a/far2l/src/cfg/ConfigOpt.cpp +++ b/far2l/src/cfg/ConfigOpt.cpp @@ -69,6 +69,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ConfigOptSaveLoad.hpp" #include "pick_color256.hpp" #include "pick_colorRGB.hpp" +#include "MaskGroups.hpp" + void SanitizeHistoryCounts(); void SanitizeIndentationCounts(); @@ -122,10 +124,10 @@ static constexpr const char *NSecVMenu = "VMenu"; static FARString strKeyNameConsoleDetachKey; const ConfigOpt g_cfg_opts[] { - {true, NSecColors, "CurrentPalette", SIZE_ARRAY_PALETTE, (BYTE *)Palette8bit, (BYTE *)DefaultPalette8bit}, - {true, NSecColors, "CurrentPaletteRGB", SIZE_ARRAY_PALETTE * 8, (BYTE *)Palette, nullptr}, - {true, NSecColors, "TempColors256", TEMP_COLORS256_SIZE, g_tempcolors256, g_tempcolors256}, - {true, NSecColors, "TempColorsRGB", TEMP_COLORSRGB_SIZE, (BYTE *)g_tempcolorsRGB, (BYTE *)g_tempcolorsRGB}, + {false, NSecColors, "CurrentPalette", SIZE_ARRAY_PALETTE, (BYTE *)Palette8bit, nullptr}, + {true, NSecColors, "CurrentPaletteRGB", SIZE_ARRAY_PALETTE * sizeof(uint64_t), (BYTE *)Palette, nullptr}, + {true, NSecColors, "TempColors256", TEMP_COLORS256_SIZE, g_tempcolors256, nullptr}, + {true, NSecColors, "TempColorsRGB", TEMP_COLORSRGB_SIZE, (BYTE *)g_tempcolorsRGB, nullptr}, {true, NSecScreen, "Clock", &Opt.Clock, 1}, {true, NSecScreen, "ViewerEditorClock", &Opt.ViewerEditorClock, 0}, @@ -379,6 +381,7 @@ const ConfigOpt g_cfg_opts[] { {true, NSecPanel, "Highlight", &Opt.Highlight, 1}, {true, NSecPanel, "SortFolderExt", &Opt.SortFolderExt, 0}, {true, NSecPanel, "SelectFolders", &Opt.SelectFolders, 0}, + {true, NSecPanel, "AttrStrStyle", &Opt.AttrStrStyle, 1}, {true, NSecPanel, "CaseSensitiveCompareSelect", &Opt.PanelCaseSensitiveCompareSelect, 1}, {true, NSecPanel, "ReverseSort", &Opt.ReverseSort, 1}, {false, NSecPanel, "RightClickRule", &Opt.PanelRightClickRule, 2}, @@ -388,8 +391,11 @@ const ConfigOpt g_cfg_opts[] { {true, NSecPanel, "AutoUpdateLimit", &Opt.AutoUpdateLimit, 0}, {true, NSecPanel, "ShowFilenameMarks", &Opt.ShowFilenameMarks, 1}, {true, NSecPanel, "FilenameMarksAlign", &Opt.FilenameMarksAlign, 1}, + {true, NSecPanel, "FilenameMarksInStatusBar", &Opt.FilenameMarksAlign, 1}, {true, NSecPanel, "MinFilenameIndentation", &Opt.MinFilenameIndentation, 0}, {true, NSecPanel, "MaxFilenameIndentation", &Opt.MaxFilenameIndentation, HIGHLIGHT_MAX_MARK_LENGTH}, + {true, NSecPanel, "DirNameStyle", &Opt.DirNameStyle, (1 + (0 << 2)) + DIRNAME_STYLE_SURR_CH + DIRNAME_STYLE_CENTERED }, + {true, NSecPanel, "ShowSymlinkSize", &Opt.ShowSymlinkSize, 0}, {true, NSecPanelLeft, "Type", &Opt.LeftPanel.Type, 0}, {true, NSecPanelLeft, "Visible", &Opt.LeftPanel.Visible, 1}, @@ -432,6 +438,7 @@ const ConfigOpt g_cfg_opts[] { {true, NSecLayout, "RightHeightDecrement", &Opt.RightHeightDecrement, 0}, {true, NSecLayout, "WidthDecrement", &Opt.WidthDecrement, 0}, {true, NSecLayout, "FullscreenHelp", &Opt.FullScreenHelp, 0}, + {true, NSecLayout, "PanelsDisposition", &Opt.PanelsDisposition, 0}, {true, NSecDescriptions, "ListNames", &Opt.Diz.strListNames, L"Descript.ion,Files.bbs"}, {true, NSecDescriptions, "UpdateMode", &Opt.Diz.UpdateMode, DIZ_UPDATE_IF_DISPLAYED}, @@ -594,39 +601,6 @@ static void SanitizePalette() #endif } -static void MergePalette() -{ - for(size_t i = 0; i < SIZE_ARRAY_PALETTE; i++) { - - Palette[i] &= 0xFFFFFFFFFFFFFF00; - Palette[i] |= Palette8bit[i]; - } - -// uint32_t basepalette[32]; -// WINPORT(GetConsoleBasePalette)(NULL, basepalette); - -/* - for(size_t i = 0; i < SIZE_ARRAY_PALETTE; i++) { - uint8_t color = Palette8bit[i]; - - Palette[i] &= 0xFFFFFFFFFFFFFF00; - - if (!(Palette[i] & FOREGROUND_TRUECOLOR)) { - Palette[i] &= 0xFFFFFF000000FFFF; - Palette[i] += ((uint64_t)basepalette[16 + (color & 0xF)] << 16); - Palette[i] += FOREGROUND_TRUECOLOR; - } - if (!(Palette[i] & BACKGROUND_TRUECOLOR)) { - Palette[i] &= 0x000000FFFFFFFFFF; - Palette[i] += ((uint64_t)basepalette[color >> 4] << 40); - Palette[i] += BACKGROUND_TRUECOLOR; - } - - Palette[i] += color; - } -*/ -} - void ConfigOptFromCmdLine() { for (auto Str: Opt.CmdLineStrings) @@ -716,7 +690,7 @@ void ConfigOptLoad() Opt.HelpTabSize = 8; // пока жестко пропишем... // SanitizePalette(); - MergePalette(); +// MergePalette(); Opt.ViOpt.ViewerIsWrap&= 1; Opt.ViOpt.ViewerWrap&= 1; @@ -768,6 +742,7 @@ void ConfigOptLoad() Opt.FindOpt.OutColumnWidthType, Opt.FindOpt.OutColumnCount); } + CheckMaskGroups(); FileFilter::InitFilter(cfg_reader); // avoid negative decrement for now as hiding command line by Ctrl+Down is a new feature and may confuse diff --git a/far2l/src/cfg/ConfigRW.cpp b/far2l/src/cfg/ConfigRW.cpp index 2d2158683..4b14d99f1 100644 --- a/far2l/src/cfg/ConfigRW.cpp +++ b/far2l/src/cfg/ConfigRW.cpp @@ -30,6 +30,7 @@ static const SectionProps s_section_props [] = { {"Panel", "settings/panel.ini", false}, {"CodePages", "settings/codepages.ini", false}, {"XLat", "settings/xlat.ini", false}, + {"MaskGroups", "settings/maskgroups.ini"}, {"Colors", "settings/colors.ini", false}, {"SortGroups", "settings/colors.ini", false}, {"UserMenu", "settings/user_menu.ini", false}, diff --git a/far2l/src/cfg/ConfigRW.hpp b/far2l/src/cfg/ConfigRW.hpp index 470e2dbc6..4cb9479c7 100644 --- a/far2l/src/cfg/ConfigRW.hpp +++ b/far2l/src/cfg/ConfigRW.hpp @@ -44,7 +44,7 @@ class ConfigReader : public ConfigSection inline bool HasSection() const { return _has_section; }; bool HasKey(const std::string &name) const; FARString GetString(const std::string &name, const wchar_t *def = L"") const; - bool GetString(FARString &out, const std::string &name, const wchar_t *def) const; + bool GetString(FARString &out, const std::string &name, const wchar_t *def = L"") const; bool GetString(std::string &out, const std::string &name, const char *def) const; int GetInt(const std::string &name, int def = 0) const; unsigned int GetUInt(const std::string &name, unsigned int def = 0) const; diff --git a/far2l/src/cfg/MaskGroups.cpp b/far2l/src/cfg/MaskGroups.cpp new file mode 100644 index 000000000..cde530516 --- /dev/null +++ b/far2l/src/cfg/MaskGroups.cpp @@ -0,0 +1,377 @@ +/* +MaskGroups.cpp + +Groups of file masks +*/ + +#include "headers.hpp" + +#include "config.hpp" +#include "ConfigRW.hpp" +#include "ctrlobj.hpp" +#include "DialogBuilder.hpp" +#include "dialog.hpp" +#include "DlgGuid.hpp" +#include "hilight.hpp" +#include "interf.hpp" +#include "keys.hpp" +#include "lang.hpp" +#include "message.hpp" +#include "vmenu.hpp" +#include "MaskGroups.hpp" + +static const wchar_t *Help = L"MaskGroupsSettings"; + +struct FileMaskStrings +{ + const char *Root, *TypeFmt, *Type0, *MaskName, *MaskValue; +}; + +static const FileMaskStrings FMS= +{ + "MaskGroups", + "MaskGroups/Type%d", + "MaskGroups/Type", + "Name", + "Value", +}; + +static void ApplyDefaultMaskGroups() +{ + static const std::pair Sets[] + { + { L"arc", L"*.rar,*.zip,*.[zj],*.[bxg7]z,*.[bg]zip,*.tar,*.t[agbx]z,*.ar[cj],*.r[0-9][0-9],*.a[0-9][0-9],*.bz2,*.cab,*.msi,*.jar,*.lha,*.lzh," + L"*.ha,*.ac[bei],*.pa[ck],*.rk,*.cpio,*.rpm,*.zoo,*.hqx,*.sit,*.ice,*.uc2,*.ain,*.imp,*.777,*.ufa,*.boa,*.bs[2a],*.sea,*.hpk,*.ddi," + L"*.x2,*.rkv,*.[lw]sz,*.h[ay]p,*.lim,*.sqz,*.chz" }, + { L"temp", L"*.cache,*.temp,*.tmp,*.bak,*.old,*.backup,*.back,temp,temp.*,temporary*" }, + { L"tmp", L"" }, + { L"exec", L"*.sh,*.pl,*.cmd,*.exe,*.bat,*.com,*.elf,*.run,*.AppImage,*.apk,*.rb" }, + { L"sound", L"*.aif,*.cda,*.mid,*.midi,*.mp3,*.mpa,*.ogg,*.wma,*.flac,*.wav,*.ape,*.wv,*.voc,*.669,*.digi,*.amf,*.ams,*.dbm,*.dmf,*.dsm,*.gdm," + L"*.imf,*.it,*.itg,*.itp,*.j2b,*.mdl,*.med,*.mo3,*.mod,*.mt2,*.mtm,*.okt,*.plm,*.psm,*.ptm,*.s3m,*.sfx,*.stm,*.stp,*.uax,*.ult,*.xm"}, + { L"snd", L"" }, + { L"pic", L"*.avif,*.jpg,*.jpeg,*.jpeg2000,*.ico,*.gif,*.png,*.webp,*.tga,*.bmp,*.pcx,*.tiff,*.tif,*.psd,*.eps,*.indd,*.svg,*.ai,*.cpt,*.kra," + L"*.pdn,*.psp,*.xcf,*.sai,*.cgm,*.mpo,*.pns,*.jps" }, + { L"video", L"*.mkv,*.webm,*.mpg,*.mp2,*.mpeg,*.mpe,*.mpv,*.mp4,*.m4p,*.m4v,*.avi,*.wmv,*.mov,*.qt,*.flv,*.swf,*.avchd,*.3gp,*.vob" }, + { L"media", L",