From 31ede5f65404455aa60b7148db66c428c11052b2 Mon Sep 17 00:00:00 2001 From: anta999 Date: Sat, 21 Sep 2024 12:45:30 +0400 Subject: [PATCH 01/30] hold on --- far2l/bootstrap/scripts/farlang.templ.m4 | 18 +++---- far2l/src/filefilterparams.cpp | 17 +++---- far2l/src/hilight.cpp | 61 +++++++++++++++--------- far2l/src/vt/vtlog.h | 1 - 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 86afeb42d..00a9f578c 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -25343,15 +25343,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/src/filefilterparams.cpp b/far2l/src/filefilterparams.cpp index 2177754b7..685ecc1ea 100644 --- a/far2l/src/filefilterparams.cpp +++ b/far2l/src/filefilterparams.cpp @@ -923,7 +923,7 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) {DI_CHECKBOX, 7, 14, 0, 14, {}, DIF_3STATE, Msg::FileFilterAttrH }, {DI_CHECKBOX, 7, 15, 0, 15, {}, DIF_3STATE, Msg::FileFilterAttrS }, {DI_CHECKBOX, 7, 16, 0, 16, {}, DIF_3STATE, Msg::FileFilterAttrD }, - {DI_CHECKBOX, 7, 17, 0, 17, {}, DIF_3STATE, Msg::FileFilterAttrHardLinks }, + {DI_CHECKBOX, 26, 11, 0, 11, {}, DIF_3STATE, Msg::FileFilterAttrHardLinks }, {DI_CHECKBOX, 26, 12, 0, 12, {}, DIF_3STATE, Msg::FileFilterAttrC }, {DI_CHECKBOX, 26, 13, 0, 13, {}, DIF_3STATE, Msg::FileFilterAttrE }, @@ -970,15 +970,16 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) MakeDialogItemsEx(FilterDlgData, FilterDlg); if (ColorConfig) { - FilterDlg[ID_FF_TITLE].Y2+= 5; - for (int i = ID_FF_NAME; i <= ID_FF_SEPARATOR1; i++) - FilterDlg[i].Flags|= DIF_HIDDEN; + FilterDlg[ID_FF_TITLE].Y2 += 6; - for (int i = ID_FF_MATCHMASK; i <= ID_FF_LAST_ATTR; i++) { - FilterDlg[i].Y1-= 2; - FilterDlg[i].Y2-= 2; - } +// for (int i = ID_FF_NAME; i <= ID_FF_SEPARATOR1; i++) +// FilterDlg[i].Flags|= DIF_HIDDEN; + +// for (int i = ID_FF_MATCHMASK; i <= ID_FF_LAST_ATTR; i++) { +// FilterDlg[i].Y1-= 2; +// FilterDlg[i].Y2-= 2; +// } for (int i = ID_FF_SEPARATOR5; i <= ID_FF_MAKETRANSPARENT; i++) { FilterDlg[i].Y1+= 5; diff --git a/far2l/src/hilight.cpp b/far2l/src/hilight.cpp index bf7a2840f..a7c2a6da6 100644 --- a/far2l/src/hilight.cpp +++ b/far2l/src/hilight.cpp @@ -58,7 +58,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct HighlightStrings { - const char *Flags, *UseAttr, *IncludeAttributes, *ExcludeAttributes, *AttrSet, *AttrClear, *IgnoreMask, *UseMask, + const char *Name, *Flags, *UseAttr, *IncludeAttributes, *ExcludeAttributes, *AttrSet, *AttrClear, *IgnoreMask, *UseMask, *Mask, *NormalColor, *SelectedColor, *CursorColor, *SelectedCursorColor, *MarkCharNormalColor, *MarkCharSelectedColor, *MarkCharCursorColor, *MarkCharSelectedCursorColor, *MarkChar, *ContinueProcessing, *UseDate, *DateType, *DateAfter, *DateBefore, *DateRelative, *UseSize, *SizeAbove, *SizeBelow, *HighlightEdit, *HighlightList, *MarkStr, *NormalColorMask, @@ -66,7 +66,7 @@ struct HighlightStrings *MarkCharCursorColorMask, *MarkCharSelectedCursorColorMask, *MaskIgnoreCase; }; -static const HighlightStrings HLS = {"Flags", "UseAttr", "IncludeAttributes", "ExcludeAttributes", "AttrSet", "AttrClear", +static const HighlightStrings HLS = {"Name","Flags", "UseAttr", "IncludeAttributes", "ExcludeAttributes", "AttrSet", "AttrClear", "IgnoreMask", "UseMask", "Mask", "NormalColor", "SelectedColor", "CursorColor", "SelectedCursorColor", "MarkCharNormalColor", "MarkCharSelectedColor", "MarkCharCursorColor","MarkCharSelectedCursorColor", "MarkChar", "ContinueProcessing", "UseDate", "DateType", "DateAfter", "DateBefore", "DateRelative", "UseSize", "SizeAboveS", "SizeBelowS", "HighlightEdit", "HighlightList", @@ -131,6 +131,8 @@ static void SetDefaultHighlighting() // Mask NormalColor // IncludeAttributes // IgnoreMask CursorColor + +#if 0 {L"*", 1, FILE_ATTRIBUTE_REPARSE_POINT, 0x00, 0x90 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0x002190, 1, FFF_DISABLED}, {L"*", 1, FILE_ATTRIBUTE_HARDLINKS, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF00AB, 1, FFF_DISABLED}, {L"*", 1, FILE_ATTRIBUTE_BROKEN, 0x00, 0x10 | F_LIGHTRED, 0xFFFFFFFD0F, 0x30 | F_LIGHTRED, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, @@ -138,6 +140,25 @@ static void SetDefaultHighlighting() {L"*", 1, FILE_ATTRIBUTE_SYSTEM, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF263C, 1, FFF_DISABLED}, {L"*|..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {L"..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x00, 0xFFFFFFFD0F, 0x00, 0xFFFFFFFD0F, 0x000000, 0, 0}, +#else + {L"*", 1, FILE_ATTRIBUTE_BROKEN, 0x00, 0x10 | F_LIGHTRED, 0xFFFFFFFD0F, 0x30 | F_LIGHTRED, 0xFFFFFFFD0F, 0xFF0021 /*!*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF007E /*~*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_DIRECTORY, 0x90 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF0040 /*@*/, 0, 0}, + + {L"*", 1, FILE_ATTRIBUTE_DEVICE_CHAR, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF002D /*-*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_DEVICE_BLOCK, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF002B /*+*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_DEVICE_FIFO, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF007C /*|*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_DEVICE_SOCK, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF003D /*=*/, 0, 0}, + + {L"*", 1, FILE_ATTRIBUTE_HARDLINKS, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF00AB, 0, 0}, + + {L"*", 1, FILE_ATTRIBUTE_HIDDEN, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_SYSTEM, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF263C, 1, 0}, + {L"*|..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF002F /*/*/, 0, 0}, + {L"..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x00, 0xFFFFFFFD0F, 0x00, 0xFFFFFFFD0F, 0x00002F /*/*/, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_EXECUTABLE, 0, 0x10 | F_GREEN, 0xFFFFFFFD0F, 0x30 | F_GREEN, 0xFFFFFFFD0F, 0xFF002A /***/, 0, 0}, +#endif + {MasksSoundFiles,0, 0x00,0x00, (0xAAFF00ull << 16) | (0x10 | F_LIGHTGREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x005500ull << 16) | (0x30 | F_LIGHTGREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF266A, 0, FFF_DISABLED}, {MaskSharedObjects,0, 0x00,0x00, (0x00b800ull << 16) | (0x10 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x005500ull << 16) | (0x30 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, @@ -153,6 +174,7 @@ static void SetDefaultHighlighting() // это настройка для каталогов на тех панелях, которые должны раскрашиваться // без учета масок (например, список хостов в "far navigator") + {L"*", 1, FILE_ATTRIBUTE_EXECUTABLE | FILE_ATTRIBUTE_REPARSE_POINT, 0, 0x10 | F_GREEN, 0xFFFFFFFD0F, 0x30 | F_GREEN, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_DEVICE_CHAR, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0, 0, 0}, @@ -194,6 +216,8 @@ static void LoadFilter(FileFilterParams *HData, ConfigReader &cfg_reader, const { // Дефолтные значения выбраны так чтоб как можно правильней загрузить // настройки старых версий фара. + + if (bSortGroup) HData->SetMask(cfg_reader.GetInt(HLS.UseMask, 1) != 0, Mask); else @@ -302,6 +326,7 @@ static void LoadFilter(FileFilterParams *HData, ConfigReader &cfg_reader, const void HighlightFiles::InitHighlightFiles() { FARString strMask; + FARString strName; std::string strGroupName, strRegKey; const int GroupDelta[4] = {DEFAULT_SORT_GROUP, 0, DEFAULT_SORT_GROUP + 1, DEFAULT_SORT_GROUP}; const char *KeyNames[4] = {RegColorsHighlight, SortGroupsKeyName, SortGroupsKeyName, RegColorsHighlight}; @@ -338,6 +363,9 @@ void HighlightFiles::InitHighlightFiles() FileFilterParams *HData = HiData.addItem(); if (HData) { + cfg_reader->GetString(strName, HLS.Name, L""); + HData->SetTitle(strName); + LoadFilter(HData, *cfg_reader, strMask, GroupDelta[j] + (GroupDelta[j] == DEFAULT_SORT_GROUP ? 0 : i), (GroupDelta[j] == DEFAULT_SORT_GROUP ? false : true)); @@ -1035,10 +1063,13 @@ void HighlightFiles::SaveHiData() if (j == 1 || j == 2) { const wchar_t *Mask = nullptr; CurHiData->GetMask(&Mask); + cfg_writer.SelectSection(KeyNames[j]); cfg_writer.SetString(strGroupName, Mask); } cfg_writer.SelectSection(strRegKey); + cfg_writer.SetString(HLS.Name, CurHiData->GetTitle()); + SaveFilter(CurHiData, cfg_writer, (j == 1 || j == 2)); } @@ -1063,32 +1094,16 @@ void HighlightFiles::SaveHiData() static bool operator==(const HighlightDataColor &hl1, const HighlightDataColor &hl2) { -#if 0 - return !memcmp(&hl1, &hl2, sizeof(HighlightDataColor)); -#else - if (hl1.MarkLen != hl2.MarkLen) - return false; - if (hl1.Flags != hl2.Flags) + if (hl1.Flags != hl2.Flags || hl1.MarkLen != hl2.MarkLen) return false; - if (hl1.MarkLen) - if (memcmp(&hl1.Mark[0], &hl2.Mark[0], sizeof(wchar_t) * hl1.MarkLen)) - return false; - - for (size_t i = 0; i < ARRAYSIZE(hl1.Color); ++i) { - for (size_t j = 0; j < ARRAYSIZE(hl1.Color[i]); ++j) { - if (hl1.Color[i][j] != hl2.Color[i][j]) - return false; - if (hl1.Mask[i][j] != hl2.Mask[i][j]) - return false; - } - } + if (hl1.MarkLen && !memcmp(&hl1.Mark[0], &hl2.Mark[0], hl1.MarkLen)) + return false; - return true; -#endif +// return (!memcmp(hl1.Color, hl2.Color, sizeof(uint64_t) * 8) && !memcmp(hl1.Mask, hl2.Mask, sizeof(uint64_t) * 8)); + return (!memcmp(hl1.Color, hl2.Color, sizeof(uint64_t) * 16)); } - struct HighlightDataColorHash { size_t operator()(const HighlightDataColor &hl) const diff --git a/far2l/src/vt/vtlog.h b/far2l/src/vt/vtlog.h index 9835017a2..df3b8714a 100644 --- a/far2l/src/vt/vtlog.h +++ b/far2l/src/vt/vtlog.h @@ -14,5 +14,4 @@ namespace VTLog void Reset(HANDLE con_hnd); std::string GetAsFile(HANDLE con_hnd, bool colored, bool append_screen_lines = true); - } From f6ed2d0fae92d282bc62afa792f60bb265a6a16e Mon Sep 17 00:00:00 2001 From: anta999 Date: Sun, 20 Oct 2024 13:43:05 +0400 Subject: [PATCH 02/30] update highlight --- far2l/CMakeLists.txt | 3 +- far2l/bootstrap/scripts/farlang.templ.m4 | 302 ++++++++++++++++++-- far2l/far2sdk/farplug-wide.h | 14 +- far2l/src/cfg/ConfigOpt.cpp | 48 +--- far2l/src/cfg/ConfigRW.cpp | 1 + far2l/src/cfg/ConfigRW.hpp | 2 +- far2l/src/cfg/MaskGroups.cpp | 239 ++++++++++++++++ far2l/src/cfg/MaskGroups.hpp | 4 + far2l/src/cfg/config.cpp | 1 + far2l/src/cfg/config.hpp | 5 + far2l/src/cfg/language.cpp | 57 +++- far2l/src/cfg/language.hpp | 2 + far2l/src/console/palette.cpp | 63 ++++ far2l/src/console/palette.hpp | 2 + far2l/src/filefilterparams.cpp | 234 ++++++++++----- far2l/src/filefilterparams.hpp | 3 + far2l/src/filemask/BaseFileMask.hpp | 50 ---- far2l/src/filemask/CFileMask.cpp | 63 +--- far2l/src/filemask/CFileMask.hpp | 31 +- far2l/src/filemask/FileMasksProcessor.cpp | 254 +++++++++++++--- far2l/src/filemask/FileMasksProcessor.hpp | 88 ++++-- far2l/src/filemask/FileMasksWithExclude.cpp | 139 --------- far2l/src/filemask/FileMasksWithExclude.hpp | 59 ---- far2l/src/filepanels.cpp | 84 ++++-- far2l/src/filepanels.hpp | 2 +- far2l/src/filetype.cpp | 4 +- far2l/src/findfile.cpp | 2 +- far2l/src/hilight.cpp | 59 ++-- far2l/src/hilight.hpp | 6 +- far2l/src/hist/history.cpp | 12 +- far2l/src/lang.hpp | 2 + far2l/src/main.cpp | 5 + far2l/src/mix/StrCells.cpp | 6 +- far2l/src/mix/mix.cpp | 2 +- far2l/src/mix/panelmix.cpp | 88 +++++- far2l/src/mix/panelmix.hpp | 5 + far2l/src/mix/processname.cpp | 33 +++ far2l/src/mix/strmix.cpp | 2 + far2l/src/mix/strmix.hpp | 1 + far2l/src/mix/udlist.hpp | 2 + far2l/src/options.cpp | 11 + far2l/src/panels/filelist.cpp | 47 +++ far2l/src/panels/filelist.hpp | 10 +- far2l/src/panels/flmodes.cpp | 50 ++++ far2l/src/panels/flshow.cpp | 56 +++- far2l/src/panels/flupdate.cpp | 33 ++- far2l/src/pick_color.cpp | 23 +- far2l/src/setcolor.cpp | 4 +- 48 files changed, 1588 insertions(+), 625 deletions(-) create mode 100644 far2l/src/cfg/MaskGroups.cpp create mode 100644 far2l/src/cfg/MaskGroups.hpp delete mode 100644 far2l/src/filemask/BaseFileMask.hpp delete mode 100644 far2l/src/filemask/FileMasksWithExclude.cpp delete mode 100644 far2l/src/filemask/FileMasksWithExclude.hpp diff --git a/far2l/CMakeLists.txt b/far2l/CMakeLists.txt index d68a27750..ddb64141b 100644 --- a/far2l/CMakeLists.txt +++ b/far2l/CMakeLists.txt @@ -100,7 +100,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 @@ -119,6 +119,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/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index e4ec59c36..67ee814ba 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -1521,6 +1521,61 @@ 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" +"Групи масок файлів" +"Суполкі масак файлаў" + +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" +"Ви бажаєте видалити" +"Вы жадаеце выдаліць" + +MaskGroupRestore +"Вы хотите восстановить наборы масок по умолчанию?" +"Do you wish to restore default mask sets?" +"Přejete si obnovit výchozí sestavy masek?" +"Wollen Sie voreingestellte Maskensets zurückstellen?" +upd:"Do you wish to restore default mask sets?" +"Chcesz przywrócić domyślne ustawienia masek?" +"Quiere restablecer por defecto máscaras?" +"Ви бажаєте відновити набори масок за замовчуванням?" +"Вы жадаеце узнавіць прадвызначаны набор масак?" + HistoryTitle l: "История команд" @@ -9145,51 +9200,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" @@ -12709,6 +12895,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) " @@ -14180,6 +14388,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" @@ -14412,6 +14642,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" @@ -16847,6 +17088,17 @@ SetBW "Чорно-біл&ий режим" "Чорна-бел&ы рэжым" +Palette +"П&алитра" +"P&alette" +"P&aleta" +"P&alette" +"P&aletta" +"P&aleta" +"P&aleta" +"П&алітра" +"&алiтра" + SetColorPanelNormal l: "Обычный текст" @@ -18596,15 +18848,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 "Вы хотите удалить пункт меню" diff --git a/far2l/far2sdk/farplug-wide.h b/far2l/far2sdk/farplug-wide.h index b59cd3ba8..f6bd7a959 100644 --- a/far2l/far2sdk/farplug-wide.h +++ b/far2l/far2sdk/farplug-wide.h @@ -1901,12 +1901,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/cfg/ConfigOpt.cpp b/far2l/src/cfg/ConfigOpt.cpp index c59c7bc12..539675f89 100644 --- a/far2l/src/cfg/ConfigOpt.cpp +++ b/far2l/src/cfg/ConfigOpt.cpp @@ -122,10 +122,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 +379,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 +389,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 +436,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 +599,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 +688,7 @@ void ConfigOptLoad() Opt.HelpTabSize = 8; // пока жестко пропишем... // SanitizePalette(); - MergePalette(); +// MergePalette(); Opt.ViOpt.ViewerIsWrap&= 1; Opt.ViOpt.ViewerWrap&= 1; 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..3d6a82099 --- /dev/null +++ b/far2l/src/cfg/MaskGroups.cpp @@ -0,0 +1,239 @@ +/* +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" + +/* +MMaskGroupRestore +MMaskGroupFindMask +MMaskGroupTotal +======================================== + +MaskGroupRestore +"Вы хотите восстановить наборы масок по умолчанию?" +"Do you wish to restore default mask sets?" +*/ + +static const wchar_t *Help = L"MaskGroupsSettings"; + +struct FileMaskStrings +{ + const char *TypeFmt, *Type0, *MaskName, *MaskValue; +}; + +static const FileMaskStrings FMS= +{ + "MaskGroups/Type%d", + "MaskGroups/Type", + "Name", + "Value", +}; + +static int FillMasksMenu(VMenu *TypesMenu, int MenuPos) +{ + ConfigReader cfg_reader; + int DizWidth = 10; + MenuItemEx TypesMenuItem; + TypesMenu->DeleteItems(); + int NumLine = 0; + + for (;; NumLine++) + { + cfg_reader.SelectSectionFmt(FMS.TypeFmt, NumLine); + FARString strMask; + if (!cfg_reader.GetString(strMask, FMS.MaskValue)) + break; + + FARString strMenuText; + + if (DizWidth) + { + FARString strName = cfg_reader.GetString(FMS.MaskName); + if (static_cast(strName.GetLength()) > DizWidth) + { + strName.Truncate(DizWidth - (Opt.NoGraphics ? 3 : 1)); + strName += (Opt.NoGraphics ? L"..." : L"…"); + } + strMenuText.Format(L"%-*.*ls %lc ", DizWidth, DizWidth, strName.CPtr(), BoxSymbols[BS_V1]); + } + + strMenuText += strMask; + TypesMenuItem.Clear(); + TypesMenuItem.strName = strMenuText; + TypesMenuItem.SetSelect(NumLine == MenuPos); + TypesMenu->AddItem(&TypesMenuItem); + } + + TypesMenuItem.strName.Clear(); + TypesMenuItem.SetSelect(NumLine == MenuPos); + TypesMenu->AddItem(&TypesMenuItem); + return NumLine; +} + +static bool EditMaskRecord (int EditPos, bool NewRec) +{ + bool Result = false; + FARString strName, strMasks; + + if (!NewRec) + { + ConfigReader cfg_reader; + cfg_reader.SelectSectionFmt(FMS.TypeFmt, EditPos); + strMasks = cfg_reader.GetString(FMS.MaskValue); + strName = cfg_reader.GetString(FMS.MaskName); + } + + DialogBuilder Builder(Msg::MaskGroupTitle, Help); +// Builder.SetId(EditMaskGroupId); + Builder.AddText(Msg::MaskGroupName); + Builder.AddEditField(&strName, 60); + Builder.AddText(Msg::MaskGroupMasks); + Builder.AddEditField(&strMasks, 60); + Builder.AddOKCancel(); + + if (Builder.ShowDialog() && !strName.IsEmpty() && !strMasks.IsEmpty()) + { + ConfigWriter cfg_writer; + cfg_writer.SelectSectionFmt(FMS.TypeFmt, EditPos); + + if (NewRec) + { + cfg_writer.ReserveIndexedSection(FMS.Type0, (unsigned int)EditPos); + } + + cfg_writer.SetString(FMS.MaskValue, strMasks); + cfg_writer.SetString(FMS.MaskName, strName); + Result = true; + } + + return Result; +} + +static bool DeleteMaskRecord(int DeletePos) +{ + bool Result = false; + FARString strItemName; + + { + ConfigReader cfg_reader; + cfg_reader.SelectSectionFmt(FMS.TypeFmt, DeletePos); + strItemName = cfg_reader.GetString(FMS.MaskName); + } + + if (!Message(MSG_WARNING, 2, Msg::MaskGroupTitle, Msg::MaskGroupAskDelete, strItemName, Msg::Delete, Msg::Cancel)) + { + ConfigWriter cfg_writer; + cfg_writer.SelectSectionFmt(FMS.TypeFmt, DeletePos); + cfg_writer.RemoveSection(); + cfg_writer.DefragIndexedSections(FMS.Type0); + Result = true; + } + + return Result; +} + +void MaskGroupsSettings() +{ + int NumLine = 0; + int MenuPos = 0; + VMenu MasksMenu(Msg::MaskGroupTitle, nullptr, 0, ScrY-4); + MasksMenu.SetHelp(Help); + MasksMenu.SetFlags(VMENU_WRAPMODE); + MasksMenu.SetPosition(-1, -1, 0, 0); +// MasksMenu.SetId(MaskGroupsMenuId); + //MasksMenu.SetBottomTitle(L"Ins Del F4 F7 Ctrl+R"); + MasksMenu.SetBottomTitle(L"Ins Del F4"); + while (1) + { + bool OuterLoop = true; + bool MenuModified = false; + + while (!MasksMenu.Done()) + { + if (OuterLoop || MenuModified) + { + if (MenuModified) + { + CtrlObject->HiFiles->UpdateHighlighting(true); + } + MasksMenu.Hide(); + NumLine = FillMasksMenu(&MasksMenu, MenuPos); + MasksMenu.SetPosition(-1, -1, -1, -1); + MasksMenu.Show(); + MenuModified = false; + OuterLoop = false; + } + + FarKey Key = MasksMenu.ReadInput(); + MenuPos = MasksMenu.GetSelectPos(); + + switch (Key) + { + case KEY_NUMDEL: + case KEY_DEL: + MenuModified = (MenuPos < NumLine) && DeleteMaskRecord(MenuPos); + break; + + case KEY_NUMPAD0: + case KEY_INS: + MenuModified = EditMaskRecord(MenuPos, true); + break; + + case KEY_NUMENTER: + case KEY_ENTER: + case KEY_F4: + MenuModified = (MenuPos < NumLine) && EditMaskRecord(MenuPos, false); + break; + + default: + MasksMenu.ProcessInput(); + break; + } + } + + int ExitCode = MasksMenu.Modal::GetExitCode(); + + if (ExitCode != -1) + { + MenuPos = ExitCode; + MasksMenu.ClearDone(); + MasksMenu.WriteInput(KEY_F4); + continue; + } + + break; + } +} + +bool GetMaskGroup(const FARString &MaskName, FARString &MaskValue) +{ + ConfigReader cfg_reader; + FARString strMaskName; + + for (int Num = 0; + cfg_reader.SelectSectionFmt(FMS.TypeFmt, Num), + cfg_reader.GetString(strMaskName, FMS.MaskName); + Num++) + { + if (!StrCmpI(strMaskName, MaskName)) + return cfg_reader.GetString(MaskValue, FMS.MaskValue); + } + return false; +} diff --git a/far2l/src/cfg/MaskGroups.hpp b/far2l/src/cfg/MaskGroups.hpp new file mode 100644 index 000000000..e55ca78d7 --- /dev/null +++ b/far2l/src/cfg/MaskGroups.hpp @@ -0,0 +1,4 @@ +#pragma once + +void MaskGroupsSettings(); +bool GetMaskGroup(const FARString &MaskName, FARString &MaskValue); diff --git a/far2l/src/cfg/config.cpp b/far2l/src/cfg/config.cpp index b374af375..c99bbb173 100644 --- a/far2l/src/cfg/config.cpp +++ b/far2l/src/cfg/config.cpp @@ -929,6 +929,7 @@ void LanguageSettings() CtrlObject->Cp()->RedrawKeyBar(); CtrlObject->Cp()->SetScreenPosition(); ApplySudoConfiguration(); + UpdateDefaultColumnTypeWidths(); } delete LangMenu; //???? BUGBUG } diff --git a/far2l/src/cfg/config.hpp b/far2l/src/cfg/config.hpp index a03eeb953..59df68981 100644 --- a/far2l/src/cfg/config.hpp +++ b/far2l/src/cfg/config.hpp @@ -401,7 +401,10 @@ struct Options int ShowFilenameMarks; int FilenameMarksAlign; + DWORD FilenameMarksInStatusBar; DWORD MinFilenameIndentation, MaxFilenameIndentation; + DWORD DirNameStyle; + DWORD ShowSymlinkSize; int Highlight; int CursorBlinkTime; @@ -415,6 +418,7 @@ struct Options int RightSelectedFirst; int LeftSelectedFirst; int SelectFolders; + int AttrStrStyle; int PanelCaseSensitiveCompareSelect; int ReverseSort; int SortFolderExt; @@ -480,6 +484,7 @@ struct Options int LeftHeightDecrement; int RightHeightDecrement; int WidthDecrement; + int PanelsDisposition; int ShowColumnTitles; int ShowPanelStatus; diff --git a/far2l/src/cfg/language.cpp b/far2l/src/cfg/language.cpp index f980349d1..9edd26f5a 100644 --- a/far2l/src/cfg/language.cpp +++ b/far2l/src/cfg/language.cpp @@ -292,9 +292,17 @@ int GetOptionsParam(FILE *SrcFile, const wchar_t *KeyName, FARString &strValue, /////////////////////////////////////// + +typedef struct lang_data_item_s { + + void *ptr; + size_t datasize; + +} lang_data_item_t; + class LanguageData { - std::vector _data; + std::vector _data; bool _shrinked = false; LanguageData(const LanguageData &) = delete; @@ -305,28 +313,29 @@ class LanguageData ~LanguageData() { for (const auto &p : _data) { - free(p); + free(p.ptr); } } - int Add(const void *ptr, size_t len) + int Add(const void *ptr, size_t len, size_t chars) { _shrinked = false; _data.emplace_back(); - _data.back() = malloc(len); - if (!_data.back()) { + _data.back().ptr = malloc(len); + if (!_data.back().ptr) { _data.pop_back(); return -1; } - memcpy(_data.back(), ptr, len); + memcpy(_data.back().ptr, ptr, len); + _data.back().datasize = (chars >= 2) ? chars - 2 : 0; return _data.size() - 1; } template inline int AddChars(const CharT *chars, size_t cnt) { - return Add(chars, cnt * sizeof(CharT)); + return Add(chars, cnt * sizeof(CharT), cnt); } template @@ -341,7 +350,16 @@ class LanguageData _shrinked = true; _data.shrink_to_fit(); } - return (ID < _data.size()) ? _data[ID] : nullptr; + return (ID < _data.size()) ? _data[ID].ptr : nullptr; + } + + const size_t GetDataSize(size_t ID) + { + if (!_shrinked) { + _shrinked = true; + _data.shrink_to_fit(); + } + return (ID < _data.size()) ? _data[ID].datasize : (size_t)0; } inline int Count() const { return _data.size(); } @@ -548,6 +566,15 @@ const void *Language::GetMsg(FarLangMsgID id) const return nullptr; } +const size_t Language::GetMsgLen(FarLangMsgID id) const +{ + if (_data && (_loaded || this == &Lang)) { + return _data->GetDataSize(id); + } + + return 0; +} + const wchar_t *Language::GetMsgWide(FarLangMsgID id) const { if (!_wide) { @@ -558,6 +585,15 @@ const wchar_t *Language::GetMsgWide(FarLangMsgID id) const return (const wchar_t *)GetMsg(id); } +const size_t Language::GetMsgWLen(FarLangMsgID id) const +{ +// if (!_wide) { +// fprintf(stderr, "Language::GetMsgWLen(%d): but language is MULTIBYTE\n", id); +// return 0; +// } + return GetMsgLen(id); +} + const char *Language::GetMsgMB(FarLangMsgID id) const { if (_wide) { @@ -601,3 +637,8 @@ const wchar_t *FarLangMsg::GetMsg(FarLangMsgID id) { return ::Lang.GetMsgWide(id); } + +const size_t FarLangMsg::GetMsgLen(FarLangMsgID id) +{ + return ::Lang.GetMsgWLen(id); +} diff --git a/far2l/src/cfg/language.hpp b/far2l/src/cfg/language.hpp index bd2534ad0..597929cb1 100644 --- a/far2l/src/cfg/language.hpp +++ b/far2l/src/cfg/language.hpp @@ -57,6 +57,7 @@ class Language void Close(); const wchar_t *GetMsgWide(FarLangMsgID id) const; + const size_t GetMsgWLen(FarLangMsgID id) const; const char *GetMsgMB(FarLangMsgID id) const; inline bool IsLanguageLoaded() const { return _loaded; } @@ -73,6 +74,7 @@ class Language bool _wide = true; const void *GetMsg(FarLangMsgID id) const; + const size_t GetMsgLen(FarLangMsgID id) const; }; extern Language Lang; diff --git a/far2l/src/console/palette.cpp b/far2l/src/console/palette.cpp index 6ce76361b..52d35bac3 100644 --- a/far2l/src/console/palette.cpp +++ b/far2l/src/console/palette.cpp @@ -214,6 +214,14 @@ uint8_t DefaultPalette8bit[SIZE_ARRAY_PALETTE] = { F_YELLOW | B_LIGHTGRAY, // COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON, }; +//uint64_t DefaultPaletteRGB[SIZE_ARRAY_PALETTE] = { +//uint64_t DefaultPaletteRGB[1] = { + +// RGB(90, 90, 90) + +//}; + + uint8_t BlackPalette8bit[SIZE_ARRAY_PALETTE] = { F_BLACK | B_LIGHTGRAY, // COL_MENUTEXT, F_LIGHTGRAY | B_BLACK, // COL_MENUSELECTEDTEXT, @@ -392,9 +400,63 @@ uint8_t BlackPalette8bit[SIZE_ARRAY_PALETTE] = { F_WHITE | B_BLACK, // COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON, }; + uint8_t Palette8bit[SIZE_ARRAY_PALETTE]; uint64_t Palette[SIZE_ARRAY_PALETTE]; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//// FIXME +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ZeroFarPalette( void ) +{ + memset( Palette8bit, 0, SIZE_ARRAY_PALETTE ); + memset( Palette, 0, sizeof(uint64_t) * SIZE_ARRAY_PALETTE ); +} + +static uint32_t def16rgbpal0[32] = { // test + 0x000000,0xA02800,0x00A000,0xA0A000,0x0000A0,0xA000A0,0x00A0A0,0xC0C0C0, + 0x808080,0xFF5500,0x00FF00,0xFFFF00,0x0000FF,0xFF00FF,0x00FFFF,0xFFFFFF, + 0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0xC0C0C0, + 0x808080,0xFF0000,0x00FF00,0xFFFF00,0x0000FF,0xFF00FF,0x00FFFF,0xFFFFFF +}; + +static uint32_t def16rgbpal1[32] = { // test + 0X000000,0XAA0000,0X00AA00,0XAAAA00,0X0000AA,0XAA00AA,0X0055AA,0XAAAAAA, + 0X555555,0XFF5555,0X55FF55,0XFFFF55,0X5555FF,0XFF55FF,0X55FFFF,0XFFFFFF, + 0X000000,0XAA0000,0X00AA00,0XAAAA00,0X0000AA,0XAA00AA,0X0055AA,0XAAAAAA, + 0X555555,0XFF5555,0X55FF55,0XFFFF55,0X5555FF,0XFF55FF,0X55FFFF,0XFFFFFF +}; + +void InitFarPalette( void ) // test +{ + if ( *((uint64_t *)&Palette8bit[0]) != 0 ) { + for(size_t i = 0; i < SIZE_ARRAY_PALETTE; i++) { + Palette[i] &= 0xFFFFFFFFFFFFFF00; + Palette[i] |= Palette8bit[i]; + } + return; + } + + uint32_t basepalette[32]; + WINPORT(GetConsoleBasePalette)(NULL, basepalette); + + if ( !Palette[0] && !Palette[1] && !Palette[2] && !Palette[3] ) { + + for(size_t i = 0; i < SIZE_ARRAY_PALETTE; i++) { + uint8_t color = DefaultPalette8bit[i]; + Palette[i] = ((uint64_t)basepalette[16 + (color & 0xF)] << 16); + Palette[i] += ((uint64_t)basepalette[color >> 4] << 40); +// Palette[i] = ((uint64_t)def16rgbpal1[16 + (color & 0xF)] << 16); +// Palette[i] += ((uint64_t)def16rgbpal1[color >> 4] << 40); + + Palette[i] += FOREGROUND_TRUECOLOR + BACKGROUND_TRUECOLOR; + Palette[i] += color; + } + } + +} + /* 1.65 - 0x52 1.70 b1 (272) - 0x54 @@ -408,6 +470,7 @@ uint64_t Palette[SIZE_ARRAY_PALETTE]; 1.75 rc1 (2555) - 0x8B 2.0 (848) - 0x8B */ + void ConvertCurrentPalette() { // DWORD Size=GetRegKeySize("Colors","CurrentPalette"); diff --git a/far2l/src/console/palette.hpp b/far2l/src/console/palette.hpp index 1388b4d9d..4128a0c36 100644 --- a/far2l/src/console/palette.hpp +++ b/far2l/src/console/palette.hpp @@ -48,4 +48,6 @@ inline uint64_t FarColorToReal(unsigned int FarColor) return (FarColor < SIZE_ARRAY_PALETTE) ? Palette[FarColor] : 4 * 16 + 15; } +void ZeroFarPalette( void ); +void InitFarPalette( void ); void ConvertCurrentPalette(); diff --git a/far2l/src/filefilterparams.cpp b/far2l/src/filefilterparams.cpp index 685ecc1ea..944a3a825 100644 --- a/far2l/src/filefilterparams.cpp +++ b/far2l/src/filefilterparams.cpp @@ -35,13 +35,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "colors.hpp" #include "CFileMask.hpp" -#include "FileMasksWithExclude.hpp" +//#include "FileMasksWithExclude.hpp" #include "lang.hpp" #include "keys.hpp" #include "ctrlobj.hpp" #include "dialog.hpp" #include "filelist.hpp" #include "filefilterparams.hpp" +#include "udlist.hpp" #include "palette.hpp" #include "message.hpp" #include "interf.hpp" @@ -206,6 +207,11 @@ const wchar_t *FileFilterParams::GetTitle() const return m_strTitle; } +const size_t FileFilterParams::GetTitleLen() const +{ + return m_strTitle.GetLength(); +} + bool FileFilterParams::GetMask(const wchar_t **Mask) const { if (Mask) @@ -369,57 +375,98 @@ bool FileFilterParams::FileInFilterImpl(const FARString &strFileName, DWORD dwFi return true; } -// Централизованная функция для создания строк меню различных фильтров. -void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, int Hotkey, bool bPanelType, - const wchar_t *FMask, const wchar_t *Title) +void FillPreviewStr(wchar_t *dstStr, size_t dstsize, const wchar_t *srcStr, const size_t srcsize) +{ + size_t ng = 0, mcl = 0; + + if (!dstStr || !dstsize) + return; + + if (srcStr && srcsize) { + ng = dstsize; + mcl = StrSizeOfCells(srcStr, srcsize, ng, false); + memcpy(dstStr, srcStr, mcl * sizeof(wchar_t)); + dstStr += mcl; + } + + while(ng < dstsize) { + *dstStr++ = 32; + ng++; + } + + *dstStr = 0; +} + +void FillAttrStr(wchar_t *AttrStr, size_t truncatelen, uint32_t IncludeAttr, uint32_t ExcludeAttr) { - const wchar_t AttrC[] = L"RAHSD truncatelen - 1) { + AttrStr[truncatelen - 1] = L'…'; + AttrStr[truncatelen] = 0; + } +} + +// Централизованная функция для создания строк меню различных фильтров. +void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, int Hotkey, bool bPanelType, + const wchar_t *FMask, const wchar_t *Title) +{ + wchar_t MarkStrPrw[8]; + wchar_t NameStrPrw[32]; + + const wchar_t Format1A[] = L"%ls %lc %-16.16ls %-2.2ls %lc %ls"; + const wchar_t Format1c[] = L"&%lc. %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; + const wchar_t Format1d[] = L" %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; + const wchar_t Format2[] = L"%ls %lc %ls %lc %-16.16ls %-3.3ls %lc %ls"; const wchar_t DownArrow = 0x2193; const wchar_t *Name, *Mask; + + size_t NameLen; DWORD IncludeAttr, ExcludeAttr; bool UseMask, UseSize, UseDate, RelativeDate; - HighlightDataColor hl; - #define MARK_STRING_PREVIEW_LENGTH 5 - wchar_t MarkStrPrw[MARK_STRING_PREVIEW_LENGTH + 4] = {0}; if (bPanelType) { Name = Title; + NameLen = wcslen(Title); UseMask = true; Mask = FMask; IncludeAttr = 0; ExcludeAttr = FILE_ATTRIBUTE_DIRECTORY; RelativeDate = UseDate = UseSize = false; } else { - FF->GetColors(&hl); - size_t ng = 0, mcl = 0; - - if (hl.MarkLen) { - ng = MARK_STRING_PREVIEW_LENGTH; - mcl = StrSizeOfCells(hl.Mark, hl.MarkLen, ng, false); - memcpy(MarkStrPrw, hl.Mark, mcl * sizeof(wchar_t)); - ng = StrCellsCount( MarkStrPrw, mcl ); - } - for (int i = ng; i < MARK_STRING_PREVIEW_LENGTH; i++, mcl++) { - MarkStrPrw[mcl] = 32; - } - MarkStrPrw[mcl] = 0; - Name = FF->GetTitle(); + NameLen = FF->GetTitleLen(); + FillPreviewStr(MarkStrPrw, 5, hl.Mark, hl.MarkLen); + UseMask = FF->GetMask(&Mask); if (!FF->GetAttr(&IncludeAttr, &ExcludeAttr)) @@ -429,19 +476,8 @@ void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, i UseDate = FF->GetDate(nullptr, nullptr, nullptr, &RelativeDate); } - wchar_t Attr[ARRAYSIZE(AttrC) * 2] = {0}; - - for (size_t i = 0; i < ARRAYSIZE(AttrF); i++) { - wchar_t *Ptr = Attr + i * 2; - *Ptr = AttrC[i]; - - if ((IncludeAttr & AttrF[i]) == AttrF[i]) - *(Ptr + 1) = L'+'; - else if ((ExcludeAttr & AttrF[i]) == AttrF[i]) - *(Ptr + 1) = L'-'; - else - *Ptr = *(Ptr + 1) = L'.'; - } + wchar_t Attr[32]; + FillAttrStr(Attr, 16, IncludeAttr, ExcludeAttr); wchar_t SizeDate[4] = L"..."; @@ -460,13 +496,15 @@ void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, i if (FF->GetContinueProcessing()) SizeDate[2] = DownArrow; - strDest.Format(Format2, MarkStrPrw, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], + FillPreviewStr(NameStrPrw, 18, Name, NameLen); + strDest.Format(Format2, MarkStrPrw, BoxSymbols[BS_V1], NameStrPrw, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L""); } else { SizeDate[2] = 0; if (!Hotkey && !bPanelType) { - strDest.Format(wcschr(Name, L'&') ? Format1b : Format1a, Name, BoxSymbols[BS_V1], Attr, SizeDate, + FillPreviewStr(NameStrPrw, wcschr(Name, L'&') ? 22 : 21, Name, NameLen); + strDest.Format(Format1A, NameStrPrw, BoxSymbols[BS_V1], Attr, SizeDate, BoxSymbols[BS_V1], UseMask ? Mask : L""); } else if (Hotkey) { strDest.Format(Format1c, @@ -483,6 +521,7 @@ void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, i struct filterpar_highlight_state_s { HighlightDataColor hl; + wchar_t wsIndent[16]; CHAR_INFO vbuff[64]; }; @@ -556,6 +595,9 @@ enum enumFileFilterConfig ID_HER_MARK_TITLE, ID_HER_MARKEDIT, ID_HER_MARKINHERIT, + ID_HER_MARKADDINHERIT, + ID_HER_CUSTOMINDENT, + ID_HER_INDENTEDIT, ID_HER_NORMALFILE, ID_HER_NORMALMARKING, @@ -640,7 +682,6 @@ LONG_PTR WINAPI FileFilterConfigDlgProc(HANDLE hDlg, int Msg, int Param1, LONG_P size_t freespace = irect.Right - irect.Left - filenameexamplelen - 2; size_t ng = freespace; size_t mcl = StrSizeOfCells(hl->Mark, hl->MarkLen, ng, false); - ng = StrCellsCount( hl->Mark, mcl ); size_t prews = std::min(Opt.MinFilenameIndentation, Opt.MaxFilenameIndentation); if (ng < prews) @@ -815,6 +856,35 @@ LONG_PTR WINAPI FileFilterConfigDlgProc(HANDLE hDlg, int Msg, int Param1, LONG_P SendDlgMessage(hDlg, DM_REDRAW, 0, 0); return TRUE; } + if (Param1 == ID_HER_INDENTEDIT) { + + int nLength = (int)SendDlgMessage(hDlg, DM_GETTEXTLENGTH, ID_HER_INDENTEDIT, 0); + if (nLength > 2 || nLength < 0) { + SendDlgMessage(hDlg, DM_SETTEXTPTRSILENT, ID_HER_INDENTEDIT, (LONG_PTR)&fphlstate->wsIndent[0]); + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + return TRUE; + } + wchar_t wsTemp[16]; + SendDlgMessage(hDlg, DM_GETTEXTPTR, ID_HER_INDENTEDIT, (LONG_PTR)&wsTemp[0]); + for (size_t i = 0; i < (size_t)nLength; i++) { + if (wsTemp[i] < L'0' || wsTemp[i] > L'9') { + SendDlgMessage(hDlg, DM_SETTEXTPTRSILENT, ID_HER_INDENTEDIT, (LONG_PTR)&fphlstate->wsIndent[0]); + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + return TRUE; + } + } + size_t v = wcstoul(wsTemp, nullptr, 10); + if (v > HIGHLIGHT_MAX_MARK_LENGTH) { + SendDlgMessage(hDlg, DM_SETTEXTPTRSILENT, ID_HER_INDENTEDIT, (LONG_PTR)&fphlstate->wsIndent[0]); + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + return TRUE; + } + fphlstate->hl.Indent = v; + SendDlgMessage(hDlg, DM_GETTEXTPTR, ID_HER_INDENTEDIT, (LONG_PTR)&fphlstate->wsIndent[0]); + + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + return TRUE; + } break; case DN_CLOSE: @@ -923,8 +993,8 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) {DI_CHECKBOX, 7, 14, 0, 14, {}, DIF_3STATE, Msg::FileFilterAttrH }, {DI_CHECKBOX, 7, 15, 0, 15, {}, DIF_3STATE, Msg::FileFilterAttrS }, {DI_CHECKBOX, 7, 16, 0, 16, {}, DIF_3STATE, Msg::FileFilterAttrD }, - {DI_CHECKBOX, 26, 11, 0, 11, {}, DIF_3STATE, Msg::FileFilterAttrHardLinks }, + {DI_CHECKBOX, 26, 11, 0, 11, {}, DIF_3STATE, Msg::FileFilterAttrHardLinks }, {DI_CHECKBOX, 26, 12, 0, 12, {}, DIF_3STATE, Msg::FileFilterAttrC }, {DI_CHECKBOX, 26, 13, 0, 13, {}, DIF_3STATE, Msg::FileFilterAttrE }, {DI_CHECKBOX, 26, 14, 0, 14, {}, DIF_3STATE, Msg::FileFilterAttrNI }, @@ -942,25 +1012,26 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) {DI_CHECKBOX, 64, 14, 0, 14, {}, DIF_3STATE, Msg::FileFilterAttrDevFIFO }, {DI_CHECKBOX, 64, 15, 0, 15, {}, DIF_3STATE, Msg::FileFilterAttrDevSock }, - {DI_TEXT, -1, 16, 0, 16, {}, DIF_SEPARATOR, Msg::HighlightColors }, - {DI_TEXT, 16, 17, 0, 17, {}, 0, Msg::HighlightMarking }, - {DI_EDIT, 5, 17, 14, 17, {}, 0, L"" }, - {DI_CHECKBOX, 0, 17, 0, 17, {}, 0, Msg::HighlightMarkStrInherit }, - - {DI_BUTTON, 5, 18, 0, 18, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName1 }, - {DI_BUTTON, 0, 18, 0, 18, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking1 }, - {DI_BUTTON, 5, 19, 0, 19, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName2 }, - {DI_BUTTON, 0, 19, 0, 19, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking2 }, - {DI_BUTTON, 5, 20, 0, 20, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName3 }, - {DI_BUTTON, 0, 20, 0, 20, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking3 }, - {DI_BUTTON, 5, 21, 0, 21, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName4 }, - {DI_BUTTON, 0, 21, 0, 21, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking4 }, - - {DI_USERCONTROL, 54, 18, 79, 21, {}, DIF_NOFOCUS, L"" }, - {DI_CHECKBOX, 5, 22, 0, 22, {}, 0, Msg::HighlightContinueProcessing }, - + {DI_TEXT, -1, 17, 0, 17, {}, DIF_SEPARATOR, Msg::HighlightColors }, + {DI_TEXT, 16, 18, 0, 18, {}, 0, Msg::HighlightMarking }, + {DI_EDIT, 5, 18, 14, 18, {}, 0, L"" }, + {DI_CHECKBOX, 0, 18, 0, 18, {}, 0, Msg::HighlightMarkStrInherit }, + {DI_CHECKBOX, 0, 18, 0, 18, {}, 0, Msg::HighlightMarkAddInherit }, + {DI_CHECKBOX, 0, 18, 0, 18, {}, DIF_HIDDEN, Msg::HighlightCustomIdent }, + {DI_EDIT, 0, 18, 4, 18, {}, DIF_HIDDEN, L"" }, + + {DI_BUTTON, 5, 19, 0, 19, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName1 }, + {DI_BUTTON, 0, 19, 0, 19, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking1 }, + {DI_BUTTON, 5, 20, 0, 20, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName2 }, + {DI_BUTTON, 0, 20, 0, 20, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking2 }, + {DI_BUTTON, 5, 21, 0, 21, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName3 }, + {DI_BUTTON, 0, 21, 0, 21, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking3 }, + {DI_BUTTON, 5, 22, 0, 22, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightFileName4 }, + {DI_BUTTON, 0, 22, 0, 22, {}, DIF_BTNNOCLOSE | DIF_NOBRACKETS, Msg::HighlightMarking4 }, + {DI_USERCONTROL, 54, 19, 79, 22, {}, DIF_NOFOCUS, L"" }, + + {DI_CHECKBOX, 5, 23, 0, 23, {}, 0, Msg::HighlightContinueProcessing }, {DI_TEXT, 0, 18, 0, 18, {}, DIF_SEPARATOR, L"" }, - {DI_BUTTON, 0, 19, 0, 19, {}, DIF_DEFAULT | DIF_CENTERGROUP, Msg::Ok }, {DI_BUTTON, 0, 19, 0, 19, {}, DIF_CENTERGROUP | DIF_BTNNOCLOSE, Msg::FileFilterReset }, {DI_BUTTON, 0, 19, 0, 19, {}, DIF_CENTERGROUP, Msg::FileFilterCancel }, @@ -973,18 +1044,11 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) FilterDlg[ID_FF_TITLE].Y2 += 6; -// for (int i = ID_FF_NAME; i <= ID_FF_SEPARATOR1; i++) -// FilterDlg[i].Flags|= DIF_HIDDEN; - -// for (int i = ID_FF_MATCHMASK; i <= ID_FF_LAST_ATTR; i++) { -// FilterDlg[i].Y1-= 2; -// FilterDlg[i].Y2-= 2; -// } - for (int i = ID_FF_SEPARATOR5; i <= ID_FF_MAKETRANSPARENT; i++) { - FilterDlg[i].Y1+= 5; - FilterDlg[i].Y2+= 5; + FilterDlg[i].Y1 += 6; + FilterDlg[i].Y2 += 6; } + } else { for (int i = ID_HER_SEPARATOR1; i <= ID_HER_CONTINUEPROCESSING; i++) FilterDlg[i].Flags|= DIF_HIDDEN; @@ -1006,6 +1070,17 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) FilterDlg[ID_HER_MARKINHERIT].X1 = FilterDlg[ID_HER_MARK_TITLE].X1 + (int)FilterDlg[ID_HER_MARK_TITLE].strData.GetLength() - (FilterDlg[ID_HER_MARK_TITLE].strData.Contains(L'&') ? 1 : 0) + 1; + FilterDlg[ID_HER_MARKADDINHERIT].X1 = FilterDlg[ID_HER_MARKINHERIT].X1 + + (int)FilterDlg[ID_HER_MARKINHERIT].strData.GetLength() + - (FilterDlg[ID_HER_MARKINHERIT].strData.Contains(L'&') ? 1 : 0) + 5; + FilterDlg[ID_HER_CUSTOMINDENT].X1 = FilterDlg[ID_HER_MARKADDINHERIT].X1 + + (int)FilterDlg[ID_HER_MARKADDINHERIT].strData.GetLength() + - (FilterDlg[ID_HER_MARKADDINHERIT].strData.Contains(L'&') ? 1 : 0) + 5; + FilterDlg[ID_HER_INDENTEDIT].X1 = FilterDlg[ID_HER_CUSTOMINDENT].X1 + + (int)FilterDlg[ID_HER_CUSTOMINDENT].strData.GetLength() + - (FilterDlg[ID_HER_CUSTOMINDENT].strData.Contains(L'&') ? 1 : 0) + 5; + FilterDlg[ID_HER_INDENTEDIT].X2 = FilterDlg[ID_HER_INDENTEDIT].X1 + 4; + for (int i = ID_HER_NORMALMARKING; i <= ID_HER_SELECTEDCURSORMARKING; i+= 2) FilterDlg[i].X1 = FilterDlg[ID_HER_NORMALFILE].X1 @@ -1017,8 +1092,13 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) FF->GetColors(&fphlstate.hl); FilterDlg[ID_HER_COLOREXAMPLE].VBuf = fphlstate.vbuff; + swprintf(fphlstate.wsIndent, 10, L"%u", fphlstate.hl.Indent); + FilterDlg[ID_HER_INDENTEDIT].strData = fphlstate.wsIndent; + FilterDlg[ID_HER_MARKEDIT].strData = fphlstate.hl.Mark; FilterDlg[ID_HER_MARKINHERIT].Selected = ((fphlstate.hl.Flags & HL_FLAGS_MARK_INHERIT) ? 1 : 0); + FilterDlg[ID_HER_MARKADDINHERIT].Selected = ((fphlstate.hl.Flags & HL_FLAGS_MARK_ADD) ? 1 : 0); + FilterDlg[ID_HER_CUSTOMINDENT].Selected = ((fphlstate.hl.Flags & HL_FLAGS_INDENT) ? 1 : 0); FilterDlg[ID_HER_CONTINUEPROCESSING].Selected = (FF->GetContinueProcessing() ? 1 : 0); FilterDlg[ID_FF_NAMEEDIT].strData = FF->GetTitle(); @@ -1202,8 +1282,10 @@ bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig) if (FilterDlg[ID_FF_MATCHMASK].Selected && !FileMask.Set(FilterDlg[ID_FF_MASKEDIT].strData, 0)) continue; -// fphlstate.hl.Flags = 0; - fphlstate.hl.Flags = FilterDlg[ID_HER_MARKINHERIT].Selected; // HL_FLAGS_MARK_INHERIT + fphlstate.hl.Flags = (HL_FLAGS_MARK_INHERIT * FilterDlg[ID_HER_MARKINHERIT].Selected); + fphlstate.hl.Flags |= (HL_FLAGS_MARK_ADD * FilterDlg[ID_HER_MARKADDINHERIT].Selected); + fphlstate.hl.Flags |= (HL_FLAGS_INDENT * FilterDlg[ID_HER_CUSTOMINDENT].Selected); + fphlstate.hl.Indent = wcstoul(FilterDlg[ID_HER_INDENTEDIT].strData, nullptr, 10); FF->SetColors(&fphlstate.hl); FF->SetContinueProcessing(FilterDlg[ID_HER_CONTINUEPROCESSING].Selected != 0); diff --git a/far2l/src/filefilterparams.hpp b/far2l/src/filefilterparams.hpp index f38715171..757aa4cde 100644 --- a/far2l/src/filefilterparams.hpp +++ b/far2l/src/filefilterparams.hpp @@ -153,6 +153,7 @@ class FileFilterParams void ClearAllFlags() { memset(FFlags, 0, sizeof(FFlags)); } const wchar_t *GetTitle() const; + const size_t GetTitleLen() const; bool GetMask(const wchar_t **Mask) const; bool GetMaskIgnoreCase() const; bool GetDate(DWORD *DateType, FILETIME *DateAfter, FILETIME *DateBefore, bool *bRelative) const; @@ -171,6 +172,8 @@ class FileFilterParams bool FileInFilter(const FileListItem &fli, uint64_t CurrentTime) const; bool FileInFilter(const FAR_FIND_DATA_EX &fde, uint64_t CurrentTime) const; bool FileInFilter(const FAR_FIND_DATA &fd, uint64_t CurrentTime) const; + + void RefreshMask() { if(FMask.Used) FMask.FilterMask.Set(FMask.strMask, FMF_SILENT); } }; bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig = false); diff --git a/far2l/src/filemask/BaseFileMask.hpp b/far2l/src/filemask/BaseFileMask.hpp deleted file mode 100644 index ec9889f6d..000000000 --- a/far2l/src/filemask/BaseFileMask.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -/* -BaseFileMask.hpp - -Абстрактный класс, заведен для удобства работы с масками. -*/ -/* -Copyright (c) 1996 Eugene Roshal -Copyright (c) 2000 Far Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "noncopyable.hpp" - -#include - -class BaseFileMask : private NonCopyable -{ -public: - BaseFileMask() {} - virtual ~BaseFileMask() {} - -public: - virtual bool Set(const wchar_t *Masks, DWORD Flags) = 0; - virtual bool Compare(const wchar_t *Name, bool ignorecase = true) const = 0; - virtual bool IsEmpty() const { return true; } -}; diff --git a/far2l/src/filemask/CFileMask.cpp b/far2l/src/filemask/CFileMask.cpp index 330ea9a5e..f306fdddd 100644 --- a/far2l/src/filemask/CFileMask.cpp +++ b/far2l/src/filemask/CFileMask.cpp @@ -34,75 +34,42 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "headers.hpp" #include "CFileMask.hpp" -#include "FileMasksProcessor.hpp" -#include "FileMasksWithExclude.hpp" #include "lang.hpp" #include "message.hpp" #include "pathmix.hpp" - -CFileMask::CFileMask() - : - FileMask(nullptr) -{} - -void CFileMask::Free() -{ - if (FileMask) - delete FileMask; - - FileMask = nullptr; -} +#include "strmix.hpp" /* Инициализирует список масок. Принимает список, разделенных запятой или точкой с запятой. Разрешается указывать маски исключения, отделив их от основных - символом '|' Возвращает FALSE при неудаче (например, одна из длина одной из + символом '|' Возвращает FALSE при неудаче (например, длина одной из масок равна 0). */ - bool CFileMask::Set(const wchar_t *Masks, DWORD Flags) { - Free(); - bool Result = false; int Silent = Flags & FMF_SILENT; - DWORD flags = 0; - if (Flags & FMF_ADDASTERISK) - flags|= FMPF_ADDASTERISK; + FARString strMask(Masks); + RemoveTrailingSpaces(strMask); + FileMask.Reset(); - if (Masks && *Masks) { - if (FileMasksWithExclude::IsExcludeMask(Masks)) { - if (!(Flags & FMF_FORBIDEXCLUDE)) - FileMask = new FileMasksWithExclude; - } else { - FileMask = new FileMasksProcessor; - } + bool Result = !strMask.IsEmpty() && FileMask.Set(strMask, Flags & FMF_ADDASTERISK); - if (FileMask) - Result = FileMask->Set(Masks, flags); + if (!Result) + { + FileMask.Reset(); - if (!Result) - Free(); + if (!Silent) + Message(MSG_WARNING,1,Msg::Warning,Msg::IncorrectMask, Msg::Ok); } - if (!Silent && !Result) - Message(MSG_WARNING, 1, Msg::Warning, Msg::IncorrectMask, Msg::Ok); - return Result; } -// Возвращает TRUE, если список масок пустой -bool CFileMask::IsEmpty() const -{ - return FileMask ? FileMask->IsEmpty() : true; -} - -/* - сравнить имя файла со списком масок - Возвращает TRUE в случае успеха. - Путь в имени файла игнорируется. +/* сравнить имя файла со списком масок + Возвращает TRUE в случае успеха. */ -bool CFileMask::Compare(const wchar_t *FileName, bool ignorecase) const +bool CFileMask::Compare(const wchar_t *FileName, bool CaseSens, bool SkipPath) const { - return FileMask ? FileMask->Compare(PointToName(FileName), ignorecase) : false; + return FileMask.Compare(SkipPath ? PointToName(FileName):FileName, CaseSens); } diff --git a/far2l/src/filemask/CFileMask.hpp b/far2l/src/filemask/CFileMask.hpp index 67acbeb06..0dcc0293f 100644 --- a/far2l/src/filemask/CFileMask.hpp +++ b/far2l/src/filemask/CFileMask.hpp @@ -33,28 +33,19 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "BaseFileMask.hpp" +#include "FileMasksProcessor.hpp" #include "noncopyable.hpp" -enum FM_FLAGS -{ - FMF_SILENT = 0x00000001, - FMF_FORBIDEXCLUDE = 0x00000002, - FMF_ADDASTERISK = 0x00000004 -}; - class CFileMask : private NonCopyable { -private: - BaseFileMask *FileMask; - -public: - CFileMask(); - ~CFileMask() { Free(); } - -public: - bool Set(const wchar_t *Masks, DWORD Flags); - bool Compare(const wchar_t *Name, bool ignorecase = true) const; - bool IsEmpty() const; - void Free(); + private: + FileMasksProcessor FileMask; + + public: + CFileMask() {} + ~CFileMask() {} + + public: + bool Set(const wchar_t *Masks, DWORD Flags); + bool Compare(const wchar_t *Name, bool CaseSens, bool SkipPath=true) const; }; diff --git a/far2l/src/filemask/FileMasksProcessor.cpp b/far2l/src/filemask/FileMasksProcessor.cpp index 3dafd698b..24e6289b2 100644 --- a/far2l/src/filemask/FileMasksProcessor.cpp +++ b/far2l/src/filemask/FileMasksProcessor.cpp @@ -36,19 +36,108 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FileMasksProcessor.hpp" #include "processname.hpp" -#include "StackHeapArray.hpp" +#include "udlist.hpp" +#include "MaskGroups.hpp" -FileMasksProcessor::FileMasksProcessor() - : - BaseFileMask(), re(nullptr), n(0) -{} +// Protect against cases like a= or a=, b=, etc. +// It also restricts valid nesting depth but the limit is high enough to cover all practical cases. +// This method was chosen due to its simplicity. +#define MAXCALLDEPTH 64 -void FileMasksProcessor::Free() +static wchar_t *FindExcludeChar(wchar_t *masks) { - Masks.Free(); + for (bool regexp=false; *masks; masks++) + { + if (!regexp) + { + if (*masks == EXCLUDEMASKSEPARATOR) + return masks; + if (*masks == L'/') + regexp = true; + } + else + { + if (*masks == L'\\') + { + if (*(++masks) == 0) // skip the next char + break; + } + else if (*masks == L'/') + regexp = false; + } + } + return nullptr; +} + +bool SingleFileMask::Set(const wchar_t *Masks, DWORD Flags) +{ + Mask = Masks; + return !Mask.IsEmpty(); +} + +bool SingleFileMask::Compare(const wchar_t *Name, bool CaseSens) const +{ + return CmpName(Mask.CPtr(), Name, false, CaseSens); +} +void SingleFileMask::Reset() +{ + Mask.Clear(); +} + +RegexMask::RegexMask() : re(nullptr) +{ +} + +void RegexMask::Reset() +{ re.reset(); - n = 0; +} + +bool RegexMask::Set(const wchar_t *masks, DWORD Flags) +{ + Reset(); + + if (*masks == L'/') + { + re.reset(new(std::nothrow) RegExp); + if (re && re->Compile(masks, OP_PERLSTYLE|OP_OPTIMIZE)) + { + return true; + } + Reset(); + } + + return false; +} + +bool RegexMask::Compare(const wchar_t *FileName, bool CaseSens) const +{ + if (re) + { + RegExpMatch MatchData[1]; + int BrCount = ARRAYSIZE(MatchData); + return re->Search(ReStringView(FileName), MatchData, BrCount); + } + + return false; +} + +FileMasksProcessor::FileMasksProcessor() : CallDepth(0) +{ +} + +FileMasksProcessor::FileMasksProcessor(int aCallDepth) : CallDepth(aCallDepth) +{ +} + +void FileMasksProcessor::Reset() +{ + for (auto I: IncludeMasks) { I->Reset(); delete I; } + for (auto I: ExcludeMasks) { I->Reset(); delete I; } + + IncludeMasks.clear(); + ExcludeMasks.clear(); } /* @@ -56,58 +145,137 @@ void FileMasksProcessor::Free() Возвращает FALSE при неудаче (например, одна из длина одной из масок равна 0) */ - bool FileMasksProcessor::Set(const wchar_t *masks, DWORD Flags) { - Free(); - // разделителем масок является не только запятая, но и точка с запятой! - DWORD flags = ULF_PACKASTERISKS | ULF_PROCESSBRACKETS | ULF_SORT | ULF_UNIQUE; + Reset(); - if (Flags & FMPF_ADDASTERISK) - flags|= ULF_ADDASTERISK; + if (CallDepth >= MAXCALLDEPTH) return false; - if (masks && *masks == L'/') { - re.reset(new (std::nothrow) RegExp); - if (re && re->Compile(masks, OP_PERLSTYLE | OP_OPTIMIZE)) { - n = re->GetBracketsCount(); - return true; + if (!*masks) return false; + + bool rc = false; + wchar_t *MasksStr = wcsdup(masks); + + if (MasksStr) { + rc = true; + + wchar_t *pInclude = MasksStr; + while (iswspace(*pInclude)) + pInclude++; + + wchar_t *pExclude = FindExcludeChar(pInclude); + + if (pExclude) { + *pExclude++ = 0; + while (iswspace(*pExclude)) + pExclude++; + + if (*pInclude == 0 && *pExclude == 0) + rc = false; + else if (*pExclude == 0) // treat empty exclude mask as no exclude mask + pExclude = nullptr; + else { + wchar_t *ptr = FindExcludeChar(pExclude); + if (ptr) *ptr = 0; // ignore all starting from the 2-nd exclude char + } } - re.reset(); - return false; - } - Masks.SetParameters(L',', L';', flags); - return Masks.Set(masks); -} + if (rc) + rc = SetPart(*pInclude ? pInclude : L"*", Flags & FMF_ADDASTERISK, IncludeMasks); -bool FileMasksProcessor::IsEmpty() const -{ - if (re) { - return !n; + if (rc && pExclude) + rc = SetPart(pExclude, 0, ExcludeMasks); + + free(MasksStr); } - return Masks.IsEmpty(); + if (!rc) + Reset(); + + return rc; } /* - сравнить имя файла со списком масок - Возвращает TRUE в случае успеха. - Путь к файлу в FileName НЕ игнорируется + Компилирует список масок. + Принимает список масок, разделенных запятой или точкой с запятой. + Возвращает FALSE при неудаче (например, длина одной из масок равна 0). */ -bool FileMasksProcessor::Compare(const wchar_t *FileName, bool ignorecase) const +bool FileMasksProcessor::SetPart(const wchar_t *masks, DWORD Flags, std::vector &Target) { - if (re) { - StackHeapArray m(n); - int i = n; - return re->Search(ReStringView(FileName), m.Get(), i); + DWORD flags = ULF_PACKASTERISKS | ULF_PROCESSBRACKETS | ULF_PROCESSREGEXP; + + if (Flags & FMF_ADDASTERISK) + flags |= ULF_ADDASTERISK; + + UserDefinedList UdList(L';', L',', flags); + +// UserDefinedList(DWORD Flags=0, wchar_t separator1=L';', wchar_t separator2=L','); +// UserDefinedList(WORD separator1, WORD separator2, DWORD Flags); + + if (UdList.Set(masks)) + { + FARString strMask; + const wchar_t *onemask; + + for (int I=0; (onemask=UdList.Get(I)); I++) + { + BaseFileMask *baseMask = nullptr; + + if (*onemask == L'<') + { + auto pStart = onemask; + auto pEnd = wcschr(++pStart, L'>'); + if (pEnd && pEnd!=pStart && pEnd[1]==0) + { + FARString strKey(pStart, pEnd-pStart); + if (GetMaskGroup(strKey, strMask)) + { + baseMask = new(std::nothrow) FileMasksProcessor(CallDepth + 1); + onemask = strMask.CPtr(); + } + } + } + + if (!baseMask) + { + if (*onemask == L'/') + baseMask = new(std::nothrow) RegexMask; + else + baseMask = new(std::nothrow) SingleFileMask(); + } + + if (baseMask && baseMask->Set(onemask,0)) + { + Target.push_back(baseMask); + } + else + { + Reset(); + delete baseMask; + return false; + } + } + return true; } - const wchar_t *MaskPtr; // указатель на текущую маску в списке - for (size_t MI = 0; nullptr != (MaskPtr = Masks.Get(MI)); ++MI) { - // SkipPath=FALSE, т.к. в CFileMask вызывается PointToName - if (CmpName(MaskPtr, FileName, false, ignorecase)) + return false; +} + +/* сравнить имя файла со списком масок + Возвращает TRUE в случае успеха. + Путь к файлу в FileName НЕ игнорируется */ +bool FileMasksProcessor::Compare(const wchar_t *FileName, bool CaseSens) const +{ + for (auto I: IncludeMasks) + { + if (I->Compare(FileName, CaseSens)) + { + for (auto J: ExcludeMasks) + { + if (J->Compare(FileName, CaseSens)) return false; + } return true; + } } - return false; } diff --git a/far2l/src/filemask/FileMasksProcessor.hpp b/far2l/src/filemask/FileMasksProcessor.hpp index 6318f4513..5f32961a9 100644 --- a/far2l/src/filemask/FileMasksProcessor.hpp +++ b/far2l/src/filemask/FileMasksProcessor.hpp @@ -34,31 +34,79 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "BaseFileMask.hpp" -#include "udlist.hpp" +#include +#include "noncopyable.hpp" #include "RegExp.hpp" +#include "FARString.hpp" -enum FMP_FLAGS +#define EXCLUDEMASKSEPARATOR (L'|') + +enum FM_FLAGS +{ + FMF_SILENT = 0x00000001, + FMF_ADDASTERISK = 0x00000002, // Добавлять '*', если маска не содержит ни одного из символов: '*', '?', '.' +}; + +class BaseFileMask : private NonCopyable +{ + public: + BaseFileMask() {} + virtual ~BaseFileMask() {} + + public: + virtual bool Set(const wchar_t *Masks, DWORD Flags) = 0; + virtual bool Compare(const wchar_t *Name, bool CaseSens) const = 0; + virtual void Reset() = 0; +}; + +class SingleFileMask : public BaseFileMask { - FMPF_ADDASTERISK = 0x00000001 // Добавлять '*', если маска не содержит - // ни одного из следующих - // символов: '*', '?', '.' + public: + SingleFileMask() : BaseFileMask() {} + ~SingleFileMask() override {} + + public: + bool Set(const wchar_t *Masks, DWORD Flags) override; + bool Compare(const wchar_t *Name, bool CaseSens) const override; + void Reset() override; + + private: + FARString Mask; +}; + +class RegexMask : public BaseFileMask +{ + public: + RegexMask(); + ~RegexMask() override {} + + public: + bool Set(const wchar_t *Masks, DWORD Flags) override; + bool Compare(const wchar_t *Name, bool CaseSens) const override; + void Reset() override; + + private: + std::unique_ptr re; }; class FileMasksProcessor : public BaseFileMask { -public: - FileMasksProcessor(); - virtual ~FileMasksProcessor() { Free(); } - -public: - virtual bool Set(const wchar_t *Masks, DWORD Flags); - virtual bool Compare(const wchar_t *Name, bool ignorecase = true) const; - virtual bool IsEmpty() const; - void Free(); - -private: - UserDefinedList Masks; // список масок файлов - std::unique_ptr re; - int n = 0; + public: + FileMasksProcessor(); + ~FileMasksProcessor() override { Reset(); } + + public: + bool Set(const wchar_t *Masks, DWORD Flags) override; + bool Compare(const wchar_t *Name, bool CaseSens) const override; + void Reset() override; + + private: + std::vector IncludeMasks; + std::vector ExcludeMasks; + const int CallDepth; + + private: + FileMasksProcessor(int aCallDepth); + bool SetPart(const wchar_t *Masks, DWORD Flags, std::vector& Target); }; + diff --git a/far2l/src/filemask/FileMasksWithExclude.cpp b/far2l/src/filemask/FileMasksWithExclude.cpp deleted file mode 100644 index 3ac98b09c..000000000 --- a/far2l/src/filemask/FileMasksWithExclude.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* -FileMasksWithExclude.cpp - -Класс для работы со сложными масками файлов (учитывается наличие масок -исключения). -*/ -/* -Copyright (c) 1996 Eugene Roshal -Copyright (c) 2000 Far Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "headers.hpp" - -#include "FileMasksWithExclude.hpp" - -const wchar_t EXCLUDEMASKSEPARATOR = L'|'; - -FileMasksWithExclude::FileMasksWithExclude() - : - BaseFileMask() -{} - -void FileMasksWithExclude::Free() -{ - Include.Free(); - Exclude.Free(); -} - -bool FileMasksWithExclude::IsExcludeMask(const wchar_t *masks) -{ - return FindExcludeChar(masks) != nullptr; -} - -const wchar_t *FileMasksWithExclude::FindExcludeChar(const wchar_t *masks) -{ - if (masks) { - for (bool regexp = false; *masks; masks++) { - if (!regexp) { - if (*masks == EXCLUDEMASKSEPARATOR) - return masks; - if (*masks == L'/') - regexp = true; - } else { - if (*masks == L'\\') { - if (*(++masks) == 0) // skip the next char - break; - } else if (*masks == L'/') - regexp = false; - } - } - } - - return nullptr; -} - -/* - Инициализирует список масок. Принимает список, разделенных запятой. - Возвращает FALSE при неудаче (например, одна из - длина одной из масок равна 0) -*/ - -bool FileMasksWithExclude::Set(const wchar_t *masks, DWORD Flags) -{ - Free(); - - if (nullptr == masks || !*masks) - return FALSE; - - size_t len = StrLength(masks) + 1; - bool rc = false; - wchar_t *MasksStr = (wchar_t *)malloc(len * sizeof(wchar_t)); - - if (MasksStr) { - rc = true; - wcscpy(MasksStr, masks); - wchar_t *pExclude = (wchar_t *)FindExcludeChar(MasksStr); - - if (pExclude) { - *pExclude = 0; - ++pExclude; - - if (*pExclude != L'/' && wcschr(pExclude, EXCLUDEMASKSEPARATOR)) - rc = FALSE; - } - - if (rc) { - rc = Include.Set(*MasksStr ? MasksStr : L"*", (Flags & FMPF_ADDASTERISK) ? FMPF_ADDASTERISK : 0); - - if (rc) - rc = Exclude.Set(pExclude, 0); - } - } - - if (!rc) - Free(); - - if (MasksStr) - free(MasksStr); - - return rc; -} - -/* - сравнить имя файла со списком масок - Возвращает TRUE в случае успеха. - Путь к файлу в FileName НЕ игнорируется -*/ -bool FileMasksWithExclude::Compare(const wchar_t *FileName, bool ignorecase) const -{ - return (Include.Compare(FileName, ignorecase) && !Exclude.Compare(FileName, ignorecase)); -} - -bool FileMasksWithExclude::IsEmpty() const -{ - return (Include.IsEmpty() && Exclude.IsEmpty()); -} diff --git a/far2l/src/filemask/FileMasksWithExclude.hpp b/far2l/src/filemask/FileMasksWithExclude.hpp deleted file mode 100644 index 083e6f452..000000000 --- a/far2l/src/filemask/FileMasksWithExclude.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -/* -FileMasksWithExclude.hpp - -Класс для работы со сложными масками файлов (учитывается наличие масок -исключения). -*/ -/* -Copyright (c) 1996 Eugene Roshal -Copyright (c) 2000 Far Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "FileMasksProcessor.hpp" - -extern const wchar_t EXCLUDEMASKSEPARATOR; - -class FileMasksWithExclude : public BaseFileMask -{ -private: - void Free(); - static const wchar_t *FindExcludeChar(const wchar_t *masks); - -public: - FileMasksWithExclude(); - virtual ~FileMasksWithExclude() {} - -public: - virtual bool Set(const wchar_t *Masks, DWORD Flags); - virtual bool Compare(const wchar_t *Name, bool ignorecase = true) const; - virtual bool IsEmpty() const; - static bool IsExcludeMask(const wchar_t *masks); - -private: - FileMasksProcessor Include, Exclude; -}; diff --git a/far2l/src/filepanels.cpp b/far2l/src/filepanels.cpp index 86151a923..ffa86abb3 100644 --- a/far2l/src/filepanels.cpp +++ b/far2l/src/filepanels.cpp @@ -92,7 +92,7 @@ static void PrepareOptFolder(FARString &strSrc, int IsLocalPath_FarPath) void FilePanels::Init() { SetPanelPositions(FileList::IsModeFullScreen(Opt.LeftPanel.ViewMode), - FileList::IsModeFullScreen(Opt.RightPanel.ViewMode)); + FileList::IsModeFullScreen(Opt.RightPanel.ViewMode), Opt.PanelsDisposition); LeftPanel->SetViewMode(Opt.LeftPanel.ViewMode); RightPanel->SetViewMode(Opt.RightPanel.ViewMode); LeftPanel->SetSortMode(std::min(std::max(Opt.LeftPanel.SortMode, 0), (int)MAX_PANEL_SORT_MODE)); @@ -227,7 +227,8 @@ void FilePanels::UpdateCmdLineVisibility(bool repos) const bool left_overlap = LeftPanel->IsVisible() && left_y2 + Opt.ShowKeyBar >= ScrY; const bool right_overlap = RightPanel->IsVisible() && right_y2 + Opt.ShowKeyBar >= ScrY; - const bool new_cl_visible = !left_overlap || !right_overlap; +// const bool new_cl_visible = !left_overlap || !right_overlap; + const bool new_cl_visible = !left_overlap && !right_overlap; int new_cl_x1 = 0, new_cl_x2 = ScrX - 1, new_cl_y = ScrY - (Opt.ShowKeyBar); if (new_cl_visible) { @@ -259,32 +260,63 @@ void FilePanels::UpdateCmdLineVisibility(bool repos) } } -void FilePanels::SetPanelPositions(int LeftFullScreen, int RightFullScreen) +void FilePanels::SetPanelPositions(int LeftFullScreen, int RightFullScreen, int Disposition) { - if (Opt.WidthDecrement < -(ScrX / 2 - 10)) - Opt.WidthDecrement = -(ScrX / 2 - 10); + if (Disposition == 0) { /// vertical panels - if (Opt.WidthDecrement > (ScrX / 2 - 10)) - Opt.WidthDecrement = (ScrX / 2 - 10); + Opt.LeftHeightDecrement = Max(-1, Min(Opt.LeftHeightDecrement, ScrY - 7)); + Opt.RightHeightDecrement = Max(-1, Min(Opt.RightHeightDecrement, ScrY - 7)); - Opt.LeftHeightDecrement = Max(-1, Min(Opt.LeftHeightDecrement, ScrY - 7)); - Opt.RightHeightDecrement = Max(-1, Min(Opt.RightHeightDecrement, ScrY - 7)); + if (Opt.WidthDecrement < -(ScrX / 2 - 10)) + Opt.WidthDecrement = -(ScrX / 2 - 10); - const int LeftY2 = ScrY - 1 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement; - const int RightY2 = ScrY - 1 - (Opt.ShowKeyBar) - Opt.RightHeightDecrement; + if (Opt.WidthDecrement > (ScrX / 2 - 10)) + Opt.WidthDecrement = (ScrX / 2 - 10); - if (LeftFullScreen) { - LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2); - LeftPanel->ViewSettings.FullScreen = 1; - } else { - LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX / 2 - Opt.WidthDecrement, LeftY2); + const int LeftY2 = ScrY - 1 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement; + const int RightY2 = ScrY - 1 - (Opt.ShowKeyBar) - Opt.RightHeightDecrement; + + if (LeftFullScreen) { + LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2); + LeftPanel->ViewSettings.FullScreen = 1; + } else { + LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX / 2 - Opt.WidthDecrement, LeftY2); + } + + if (RightFullScreen) { + RightPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); + RightPanel->ViewSettings.FullScreen = 1; + } else { + RightPanel->SetPosition(ScrX / 2 + 1 - Opt.WidthDecrement, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); + } } + else if (Disposition == 1) { /// horizontal panels - if (RightFullScreen) { - RightPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); - RightPanel->ViewSettings.FullScreen = 1; - } else { - RightPanel->SetPosition(ScrX / 2 + 1 - Opt.WidthDecrement, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); + Opt.LeftHeightDecrement = Max(-1, Min(Opt.LeftHeightDecrement, ScrY - 13)); + Opt.RightHeightDecrement = Max(-1, Min(Opt.RightHeightDecrement, ScrY - 13)); + + if (Opt.WidthDecrement < -((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) + Opt.WidthDecrement = -((ScrY - Opt.LeftHeightDecrement) / 2 - 6); + + if (Opt.WidthDecrement > ((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) + Opt.WidthDecrement = ((ScrY - Opt.LeftHeightDecrement) / 2 - 6); + + const int LeftY2 = (ScrY - Opt.ShowMenuBar) / 2 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement / 2; + const int RightY2 = ScrY - (Opt.ShowKeyBar) - 1 - Opt.RightHeightDecrement; + + if (LeftFullScreen) { + LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2); + LeftPanel->ViewSettings.FullScreen = 1; + } else { + LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2 - Opt.WidthDecrement ); + } + + if (RightFullScreen) { + RightPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); + RightPanel->ViewSettings.FullScreen = 1; + } else { + RightPanel->SetPosition(0, LeftY2 + 1 - Opt.WidthDecrement, ScrX, RightY2); + } } UpdateCmdLineVisibility(true); @@ -295,7 +327,7 @@ void FilePanels::SetScreenPosition() _OT(SysLog(L"[%p] FilePanels::SetScreenPosition() {%d, %d - %d, %d}", this, X1, Y1, X2, Y2)); TopMenuBar.SetPosition(0, 0, ScrX, 0); MainKeyBar.SetPosition(0, ScrY, ScrX, ScrY); - SetPanelPositions(LeftPanel->IsFullScreen(), RightPanel->IsFullScreen()); + SetPanelPositions(LeftPanel->IsFullScreen(), RightPanel->IsFullScreen(), Opt.PanelsDisposition); SetPosition(0, 0, ScrX, ScrY); } @@ -583,6 +615,14 @@ int FilePanels::ProcessKey(FarKey Key) break; } +// case (KEY_CTRL + KEY_COMMA) | KEY_ALT: { + case (KEY_CTRL + KEY_COMMA): { + Opt.PanelsDisposition ^= 1; + SetScreenPosition(); + FrameManager->RefreshFrame(); + break; + } + /* $ 08.04.2002 IS При смене диска установим принудительно текущий каталог на активной diff --git a/far2l/src/filepanels.hpp b/far2l/src/filepanels.hpp index 908dbe54e..66b19bf94 100644 --- a/far2l/src/filepanels.hpp +++ b/far2l/src/filepanels.hpp @@ -69,7 +69,7 @@ class FilePanels : public Frame Panel *GetAnotherPanel(Panel *Current); Panel *ChangePanelToFilled(Panel *Current, int NewType); Panel *ChangePanel(Panel *Current, int NewType, int CreateNew, int Force); - void SetPanelPositions(int LeftFullScreen, int RightFullScreen); + void SetPanelPositions(int LeftFullScreen, int RightFullScreen, int Disposition); // void SetPanelPositions(); void SetupKeyBar(); diff --git a/far2l/src/filetype.cpp b/far2l/src/filetype.cpp index d86ebcaa8..e012521c3 100644 --- a/far2l/src/filetype.cpp +++ b/far2l/src/filetype.cpp @@ -86,7 +86,7 @@ static int GetDescriptionWidth(ConfigReader &cfg_reader, const wchar_t *Name = n if (!Name) { CurWidth = HiStrCellsCount(strDescription); } else { - if (!FMask.Compare(Name)) + if (!FMask.Compare(Name, false)) continue; FARString strExpandedDesc = strDescription; @@ -142,7 +142,7 @@ bool ProcessLocalFileTypes(const wchar_t *Name, int Mode, bool CanAddHistory, FA break; if (FMask.Set(strMask, FMF_SILENT)) { - if (FMask.Compare(Name)) { + if (FMask.Compare(Name, false)) { LPCSTR Type = nullptr; switch (Mode) { diff --git a/far2l/src/findfile.cpp b/far2l/src/findfile.cpp index 6f49ad23a..060d27110 100644 --- a/far2l/src/findfile.cpp +++ b/far2l/src/findfile.cpp @@ -2892,7 +2892,7 @@ FindFiles::FindFiles() FindFiles::~FindFiles() { - FileMaskForFindFile.Free(); +// FileMaskForFindFile.Free(); itd.ClearAllLists(); ScrBuf.ResetShadow(); diff --git a/far2l/src/hilight.cpp b/far2l/src/hilight.cpp index 9bac17e86..1a7c92952 100644 --- a/far2l/src/hilight.cpp +++ b/far2l/src/hilight.cpp @@ -58,7 +58,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct HighlightStrings { - const char *Name, *Flags, *UseAttr, *IncludeAttributes, *ExcludeAttributes, *AttrSet, *AttrClear, *IgnoreMask, *UseMask, + const char *Name, *Flags, *CFlags, *Indent, *UseAttr, *IncludeAttributes, *ExcludeAttributes, *AttrSet, *AttrClear, *IgnoreMask, *UseMask, *Mask, *NormalColor, *SelectedColor, *CursorColor, *SelectedCursorColor, *MarkCharNormalColor, *MarkCharSelectedColor, *MarkCharCursorColor, *MarkCharSelectedCursorColor, *MarkChar, *ContinueProcessing, *UseDate, *DateType, *DateAfter, *DateBefore, *DateRelative, *UseSize, *SizeAbove, *SizeBelow, *HighlightEdit, *HighlightList, *MarkStr, *NormalColorMask, @@ -66,7 +66,7 @@ struct HighlightStrings *MarkCharCursorColorMask, *MarkCharSelectedCursorColorMask, *MaskIgnoreCase; }; -static const HighlightStrings HLS = {"Name","Flags", "UseAttr", "IncludeAttributes", "ExcludeAttributes", "AttrSet", "AttrClear", +static const HighlightStrings HLS = {"Name","Flags", "CFlags", "Indent", "UseAttr", "IncludeAttributes", "ExcludeAttributes", "AttrSet", "AttrClear", "IgnoreMask", "UseMask", "Mask", "NormalColor", "SelectedColor", "CursorColor", "SelectedCursorColor", "MarkCharNormalColor", "MarkCharSelectedColor", "MarkCharCursorColor","MarkCharSelectedCursorColor", "MarkChar", "ContinueProcessing", "UseDate", "DateType", "DateAfter", "DateBefore", "DateRelative", "UseSize", "SizeAboveS", "SizeBelowS", "HighlightEdit", "HighlightList", @@ -244,12 +244,17 @@ static void LoadFilter(FileFilterParams *HData, ConfigReader &cfg_reader, const hl.Mask[HIGHLIGHTCOLORTYPE_MARKSTR][HIGHLIGHTCOLOR_UNDERCURSOR] = cfg_reader.GetULL(HLS.MarkCharCursorColorMask, 0); hl.Mask[HIGHLIGHTCOLORTYPE_MARKSTR][HIGHLIGHTCOLOR_SELECTEDUNDERCURSOR] = cfg_reader.GetULL(HLS.MarkCharSelectedCursorColorMask, 0); + hl.Flags = cfg_reader.GetUInt(HLS.CFlags, 0); + hl.Indent = cfg_reader.GetUInt(HLS.Indent, 0); + if (hl.Indent > HIGHLIGHT_MAX_MARK_LENGTH) + hl.Indent = HIGHLIGHT_MAX_MARK_LENGTH; + { // Load Mark str FARString strMark = cfg_reader.GetString(HLS.MarkStr, L""); DWORD dwMarkLen = strMark.GetLength(); DWORD dwMarkChar = cfg_reader.GetUInt(HLS.MarkChar, 0); - hl.Flags = (dwMarkChar & 0xFF0000) >> 23; + hl.Flags |= (dwMarkChar & 0xFF0000) >> 23; dwMarkChar &= 0x0000FFFF; if (dwMarkLen) { @@ -257,7 +262,6 @@ static void LoadFilter(FileFilterParams *HData, ConfigReader &cfg_reader, const dwMarkLen = HIGHLIGHT_MAX_MARK_LENGTH; memcpy(&hl.Mark[0], strMark.GetBuffer(), sizeof(wchar_t) * dwMarkLen); - strMark.ReleaseBuffer(); } else if (dwMarkChar) { hl.Mark[0] = dwMarkChar; @@ -268,8 +272,7 @@ static void LoadFilter(FileFilterParams *HData, ConfigReader &cfg_reader, const hl.MarkLen = dwMarkLen; } - -#if 1 +#if 0 // FIXME: Temporary code for compatibility with old settings where there are no transparency masks for colors for (int j = 0; j < 2; j++) { @@ -377,7 +380,8 @@ static const HighlightDataColor DefaultStartingColors = { {0x0, 0x0, 0x0, 0x0}, // Mask[0][4] // Transparency Masks 0 = fully transparent {0x0, 0x0, 0x0, 0x0}}, // Mask[1][4] 0, // size_t MarkLen; - 1, // flags; + HL_FLAGS_MARK_INHERIT | HL_FLAGS_MARK_ADD, // flags; + 0, // indent { 0 }, // wchar_t Mark }; @@ -389,6 +393,7 @@ const HighlightDataColor ZeroColors = {0x0, 0x0, 0x0, 0x0}}, // Mask[1][4] 0, // size_t MarkLen; 0, // flags; + 0, // indent { 0 }, // wchar_t Mark }; @@ -456,7 +461,7 @@ static void ApplyColors(HighlightDataColor *hlDst, HighlightDataColor *hlSrc) hlDst->MarkLen = hlSrc->MarkLen; memcpy(hlDst->Mark, hlSrc->Mark, sizeof(wchar_t) * hlSrc->MarkLen); } - else { // Если есть наследование, добавим метку к старой + else if (hlSrc->Flags & HL_FLAGS_MARK_ADD) { // Если есть наследование, добавим метку к старой uint32_t freespace = (HIGHLIGHT_MAX_MARK_LENGTH - hlDst->MarkLen); if (freespace) { // Если есть хоть какое то место, добавим что влезет uint32_t copylen = (freespace < hlSrc->MarkLen) ? freespace : hlSrc->MarkLen; @@ -1003,18 +1008,9 @@ static void SaveFilter(FileFilterParams *CurHiData, ConfigWriter &cfg_writer, bo cfg_writer.SetULL(HLS.MarkCharSelectedCursorColorMask, hl.Mask[HIGHLIGHTCOLORTYPE_MARKSTR][HIGHLIGHTCOLOR_SELECTEDUNDERCURSOR]); - { // Save Mark str - FARString strMark = L""; -// DWORD dwMarkChar = (hl.MarkLen == 1) ? hl.Mark[0] : 0; - DWORD dwMarkChar = 0; - dwMarkChar |= (0xFF0000 * (hl.Flags & HL_FLAGS_MARK_INHERIT)); - - cfg_writer.SetUInt(HLS.MarkChar, dwMarkChar); - -// if (hl.MarkLen > 1) - strMark = hl.Mark; - cfg_writer.SetString(HLS.MarkStr, strMark); - } + cfg_writer.SetUInt(HLS.Indent, hl.Indent); + cfg_writer.SetUInt(HLS.CFlags, hl.Flags); + cfg_writer.SetString(HLS.MarkStr, hl.Mark); cfg_writer.SetInt(HLS.ContinueProcessing, (CurHiData->GetContinueProcessing() ? 1 : 0)); } @@ -1069,12 +1065,31 @@ void HighlightFiles::SaveHiData() } } +void HighlightFiles::UpdateHighlighting(bool RefreshMasks) +{ + ScrBuf.Lock(); // отменяем всякую прорисовку + + ProcessGroups(); + + if (RefreshMasks) { + for (size_t i = 0; i < HiData.getCount(); i++) { + HiData.getItem(i)->RefreshMask(); + } + } + + CtrlObject->Cp()->LeftPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->LeftPanel->Redraw(); + CtrlObject->Cp()->RightPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->RightPanel->Redraw(); + + ScrBuf.Unlock(); // разрешаем прорисовку +} //////// static bool operator==(const HighlightDataColor &hl1, const HighlightDataColor &hl2) { - if (hl1.Flags != hl2.Flags || hl1.MarkLen != hl2.MarkLen) + if (hl1.Flags != hl2.Flags || hl1.MarkLen != hl2.MarkLen || hl1.Indent != hl2.Indent) return false; if (hl1.MarkLen && wmemcmp(&hl1.Mark[0], &hl2.Mark[0], hl1.MarkLen) != 0) @@ -1093,7 +1108,7 @@ struct HighlightDataColorHash { size_t operator()(const HighlightDataColor &hl) const { - size_t out = hl.Flags ^ (hl.MarkLen * 0xFFFF); + size_t out = (hl.Flags + hl.Indent) ^ (hl.MarkLen * 0xFFFF); for (size_t i = 0; i < ARRAYSIZE(hl.Color); ++i) { for (size_t j = 0; j < ARRAYSIZE(hl.Color[i]); ++j) { diff --git a/far2l/src/hilight.hpp b/far2l/src/hilight.hpp index 47781b824..64ff5339e 100644 --- a/far2l/src/hilight.hpp +++ b/far2l/src/hilight.hpp @@ -56,6 +56,8 @@ enum enumHighlightDataColor enum HIGHLIGHT_FLAGS { HL_FLAGS_MARK_INHERIT = 1, + HL_FLAGS_MARK_ADD = 2, // to inheritable + HL_FLAGS_INDENT = 4, }; struct HighlightDataColor @@ -63,8 +65,9 @@ struct HighlightDataColor uint64_t Color[2][4]; // [0=file, 1=mark][0=normal,1=selected,2=undercursor,3=selectedundercursor]; // nonzero upper 3 bytes meaning foreground RGB, nonzero lower 3 bytes meaning background RGB uint64_t Mask[2][4]; // transparency mask, 0 = fully transparent - uint32_t Flags; uint32_t MarkLen; + uint32_t Flags; + uint32_t Indent; wchar_t Mark[HIGHLIGHT_MAX_MARK_LENGTH + 1]; // + null terminator }; @@ -92,6 +95,7 @@ class HighlightFiles void GetHiColor(FileListItem **FileItem, size_t FileCount, bool UseAttrHighlighting, size_t *MarkLM); int GetGroup(const FileListItem *fli); void HiEdit(int MenuPos); + void UpdateHighlighting(bool RefreshMasks = false); void SaveHiData(); }; diff --git a/far2l/src/hist/history.cpp b/far2l/src/hist/history.cpp index f5c4b820d..1e965606b 100644 --- a/far2l/src/hist/history.cpp +++ b/far2l/src/hist/history.cpp @@ -80,12 +80,14 @@ static bool IsAllowedForHistory(const wchar_t *Str) return false; FileMasksProcessor fmp; - fmp.Set(Opt.AutoComplete.Exceptions.CPtr(), FMPF_ADDASTERISK); - if (!fmp.IsEmpty() && fmp.Compare(Str)) { - return false; - } + return !(fmp.Set(Opt.AutoComplete.Exceptions.CPtr(), FMF_ADDASTERISK) && fmp.Compare(Str,true)); - return true; +// fmp.Set(Opt.AutoComplete.Exceptions.CPtr(), FMF_ADDASTERISK); +// if (!fmp.IsEmpty() && fmp.Compare(Str, true)) { +// return false; +// } + +// return true; } /* diff --git a/far2l/src/lang.hpp b/far2l/src/lang.hpp index 4bf9d87cd..123e3976e 100644 --- a/far2l/src/lang.hpp +++ b/far2l/src/lang.hpp @@ -50,6 +50,7 @@ struct FarLangMsg inline FarLangMsgID ID() const { return _id; } inline const wchar_t *CPtr() const { return GetMsg(_id); } + inline const size_t Len() const { return GetMsgLen(_id); } inline operator const wchar_t *() const { return GetMsg(_id); } inline FarLangMsg operator+(int delta) const { return FarLangMsg{_id + delta}; } @@ -63,6 +64,7 @@ struct FarLangMsg private: static const wchar_t *GetMsg(FarLangMsgID id); // impl in cfg/language.cpp + static const size_t GetMsgLen(FarLangMsgID id); }; namespace Msg diff --git a/far2l/src/main.cpp b/far2l/src/main.cpp index 765cd18e8..a3c6e914c 100644 --- a/far2l/src/main.cpp +++ b/far2l/src/main.cpp @@ -75,6 +75,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ConfigRW.hpp" #include "ConfigOptSaveLoad.hpp" #include "help.hpp" +#include "mix/panelmix.hpp" #ifdef DIRECT_RT int DirectRT = 0; @@ -586,7 +587,10 @@ int FarAppMain(int argc, char **argv) Opt.LoadPlug.PluginsPersonal = FALSE; } + ZeroFarPalette(); ConfigOptLoad(); + InitFarPalette(); + InitConsole(); WINPORT(SetConsoleCursorBlinkTime)(NULL, Opt.CursorBlinkTime); @@ -612,6 +616,7 @@ int FarAppMain(int argc, char **argv) setenv("FARLANG", Opt.strLanguage.GetMB().c_str(), 1); initMacroVarTable(1); + UpdateDefaultColumnTypeWidths(); CheckForImportLegacyShortcuts(); // (!!!) temporary STUB because now Editor can not input filename "", see: fileedit.cpp -> FileEditor::Init() diff --git a/far2l/src/mix/StrCells.cpp b/far2l/src/mix/StrCells.cpp index aadf6295e..9d67b6218 100644 --- a/far2l/src/mix/StrCells.cpp +++ b/far2l/src/mix/StrCells.cpp @@ -41,10 +41,12 @@ size_t StrSizeOfCells(const wchar_t *pwz, size_t n, size_t &ng, bool round_up) } if (i < n) { if (IsCharFullWidth(pwz[i])) { - ++g; - if (!round_up && g == ng) { +// ++g; +// if (!round_up && g == ng) { + if (!round_up && (g + 1) == ng) { break; } + ++g; } ++i; } diff --git a/far2l/src/mix/mix.cpp b/far2l/src/mix/mix.cpp index d0e54804d..336aa9a8b 100644 --- a/far2l/src/mix/mix.cpp +++ b/far2l/src/mix/mix.cpp @@ -98,7 +98,7 @@ FarRecursiveSearch(const wchar_t *InitDir, const wchar_t *Mask, FRSUSERFUNC Func ScTree.SetFindPath(InitDir, L"*"); while (ScTree.GetNextName(&FindData, strFullName)) { - if (FMask.Compare(FindData.strFileName)) { + if (FMask.Compare(FindData.strFileName, false)) { FAR_FIND_DATA fdata; apiFindDataExToData(&FindData, &fdata); diff --git a/far2l/src/mix/panelmix.cpp b/far2l/src/mix/panelmix.cpp index 125767084..fe71f4c0f 100644 --- a/far2l/src/mix/panelmix.cpp +++ b/far2l/src/mix/panelmix.cpp @@ -47,13 +47,54 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "lang.hpp" #include "datetime.hpp" -int ColumnTypeWidth[] = {0, 6, 6, 8, 5, 14, 14, 14, 14, 10, 0, 0, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#if 0 +enum PANEL_COLUMN_TYPE +{ + NAME_COLUMN = 0, + SIZE_COLUMN, + PHYSICAL_COLUMN, + DATE_COLUMN, + TIME_COLUMN, + WDATE_COLUMN, + CDATE_COLUMN, + ADATE_COLUMN, + CHDATE_COLUMN, + ATTR_COLUMN, + DIZ_COLUMN, + OWNER_COLUMN, + GROUP_COLUMN, + NUMLINK_COLUMN, + RESERVED_COLUMN1, + RESERVED_COLUMN2, + CUSTOM_COLUMN0, + CUSTOM_COLUMN_LAST = CUSTOM_COLUMN0 + 19, +}; +#endif + +int ColumnTypeWidth[32] = {0, 9, 9, 8, 5, 14, 14, 14, 14, 10, 0, 0, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; static const wchar_t *ColumnSymbol[] = {L"N", L"S", L"P", L"D", L"T", L"DM", L"DC", L"DA", L"DE", L"A", L"Z", L"O", L"U", L"LN", L"F", L"G", L"C0", L"C1", L"C2", L"C3", L"C4", L"C5", L"C6", L"C7", L"C8", L"C9", L"C10", L"C11", L"C12", L"C13", L"C14", L"C15", L"C16", L"C17", L"C18", L"C19"}; +static const FarLangMsg DirUpNames[4] = {Msg::DirUp, Msg::DirUp2, Msg::DirUp3, Msg::DirUp4}; +static const FarLangMsg DirNames[4] = {Msg::DirName, Msg::DirName2, Msg::DirName3, Msg::DirName4}; +static const FarLangMsg SymLinkNames[4] = {Msg::SymLinkName, Msg::SymLinkName2, Msg::SymLinkName3, Msg::SymLinkName4}; +static const FarLangMsg JunctionNames[4] = {Msg::JunctionName, Msg::JunctionName2, Msg::JunctionName3, Msg::JunctionName4}; + +static const wchar_t surdircharleft[4] = { 60, 16, 61, 32 }; +static const wchar_t surdircharright[4] = { 62, 17, 61, 32 }; + +void UpdateDefaultColumnTypeWidths( void ) +{ + size_t nameindex = Opt.DirNameStyle & 3; + + ColumnTypeWidth[SIZE_COLUMN] = ColumnTypeWidth[PHYSICAL_COLUMN] = \ + std::max( std::max(DirUpNames[nameindex].Len(), DirNames[nameindex].Len()) + \ + ((Opt.DirNameStyle & DIRNAME_STYLE_SURR_CH) >> 3), (size_t)6ul ); +} + void ShellUpdatePanels(Panel *SrcPanel, BOOL NeedSetUpADir) { if (!SrcPanel) @@ -257,6 +298,9 @@ void TextToViewSettings(const wchar_t *ColumnTitles, const wchar_t *ColumnWidths case L'T': ColumnType|= COLUMN_THOUSAND; break; + case L'A': + ColumnType|= COLUMN_AUTO; + break; } Ptr++; @@ -373,6 +417,9 @@ void ViewSettingsToText(unsigned int *ViewColumnTypes, int *ViewColumnWidths, in if (ViewColumnTypes[I] & COLUMN_THOUSAND) strColumnTitles+= L'T'; + + if (ViewColumnTypes[I] & COLUMN_AUTO) + strColumnTitles+= L'A'; break; case WDATE_COLUMN: @@ -528,6 +575,7 @@ const FARString FormatStr_Size(int64_t FileSize, int64_t PhysicalSize, const FAR DWORD FileAttributes, uint8_t ShowFolderSize, int ColumnType, DWORD Flags, int Width) { FormatString strResult; + static const wchar_t *wstrwhitespace = L" "; bool Physical = (ColumnType == PHYSICAL_COLUMN); @@ -536,20 +584,42 @@ const FARString FormatStr_Size(int64_t FileSize, int64_t PhysicalSize, const FAR strResult << L"~"; } - if (!Physical && (FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) - && !ShowFolderSize) { - const wchar_t *PtrName = Msg::ListFolder; + if (!Physical && (FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | (FILE_ATTRIBUTE_REPARSE_POINT * (!Opt.ShowSymlinkSize)))) && !ShowFolderSize) { + + size_t nameindex = Opt.DirNameStyle & 3; + FarLangMsg lname = DirNames[nameindex]; if (TestParentFolderName(strName)) { - PtrName = Msg::ListUp; + lname = DirUpNames[nameindex]; } else if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - PtrName = Msg::ListSymLink; + lname = SymLinkNames[nameindex]; } + const wchar_t *PtrName = lname; + size_t namelen = lname.Len(); + strResult << fmt::Size(Width); - if (StrLength(PtrName) <= Width - 2) { + + if ((intptr_t)namelen <= Width - 2) { + FARString strOutStr; + + if (Opt.DirNameStyle & DIRNAME_STYLE_SURR_CH) { + size_t surindex = (Opt.DirNameStyle >> 2) & 3; + strOutStr.Append(&surdircharleft[surindex], 1); + strOutStr.Append(PtrName, namelen); + strOutStr.Append(&surdircharright[surindex], 1); + } + else { + strOutStr.Append(PtrName, namelen); + } + + if (Opt.DirNameStyle & DIRNAME_STYLE_CENTERED) { + size_t addfc = (((size_t)Width - (namelen + ((Opt.DirNameStyle & DIRNAME_STYLE_SURR_CH) >> 3)) + 1 ) >> 1) & 63; + if (addfc) + strOutStr.Append(wstrwhitespace, addfc); + } // precombine into tmp string to avoid miseffect of fmt::Size etc (#1137) - strResult << FARString(L"<").Append(PtrName).Append(L'>'); + strResult << strOutStr; } else { strResult << PtrName; } diff --git a/far2l/src/mix/panelmix.hpp b/far2l/src/mix/panelmix.hpp index 2a277bb6e..9063e6153 100644 --- a/far2l/src/mix/panelmix.hpp +++ b/far2l/src/mix/panelmix.hpp @@ -48,3 +48,8 @@ void TextToViewSettings(const wchar_t *ColumnTitles, const wchar_t *ColumnWidths unsigned int *ViewColumnTypes, int *ViewColumnWidths, int *ViewColumnWidthsTypes, int &ColumnCount); void ViewSettingsToText(unsigned int *ViewColumnTypes, int *ViewColumnWidths, int *ViewColumnWidthsTypes, int ColumnCount, FARString &strColumnTitles, FARString &strColumnWidths); + +#define DIRNAME_STYLE_SURR_CH 0x10 +#define DIRNAME_STYLE_CENTERED 0x20 + +void UpdateDefaultColumnTypeWidths( void ); diff --git a/far2l/src/mix/processname.cpp b/far2l/src/mix/processname.cpp index ae8959a22..3e800bfd5 100644 --- a/far2l/src/mix/processname.cpp +++ b/far2l/src/mix/processname.cpp @@ -38,6 +38,38 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pathmix.hpp" #include "CFileMask.hpp" +int WINAPI ProcessName(const wchar_t *param1, wchar_t *param2, DWORD size, DWORD flags) +{ + bool skippath = (flags & PN_SKIPPATH); + bool silent = !(flags & PN_SHOWERRORMESSAGE); + bool casesens = (flags & PN_CASESENSITIVE); + DWORD mode = flags & 0xFF0000; + + if (mode == PN_CMPNAME) + return CmpName(param1, param2, skippath, casesens) ? TRUE : FALSE; + + else if (mode == PN_CMPNAMELIST || mode == PN_CHECKMASK) + { + CFileMask Masks; + if (!Masks.Set(param1, silent ? FMF_SILENT : 0)) + return FALSE; + if (mode == PN_CHECKMASK) + return TRUE; + return Masks.Compare(param2, casesens, skippath) ? TRUE : FALSE; + } + + else if (mode == PN_GENERATENAME) + { + FARString strResult = param2; + int nResult = ConvertWildcards(param1, strResult, flags & 0xFFFF); + far_wcsncpy(param2, strResult, size); + return nResult; + } + + return FALSE; +} + +#if 0 // обработать имя файла: сравнить с маской, масками, сгенерировать по маске int WINAPI ProcessName(const wchar_t *param1, wchar_t *param2, DWORD size, DWORD flags) { @@ -62,6 +94,7 @@ int WINAPI ProcessName(const wchar_t *param1, wchar_t *param2, DWORD size, DWORD return FALSE; } +#endif /* $ 09.10.2000 IS diff --git a/far2l/src/mix/strmix.cpp b/far2l/src/mix/strmix.cpp index 2a31c9291..ff8df3230 100644 --- a/far2l/src/mix/strmix.cpp +++ b/far2l/src/mix/strmix.cpp @@ -665,6 +665,7 @@ FARString &WINAPI FileSizeToStr(FARString &strDestStr, uint64_t Size, int Width, strStr.Format(L"%llu", Sz); if ((!UseMinSizeIndex && strStr.GetLength() <= static_cast(Width)) || Width < 5) { + if (ShowBytesIndex) { Width-= (Economic ? 1 : 2); @@ -677,6 +678,7 @@ FARString &WINAPI FileSizeToStr(FARString &strDestStr, uint64_t Size, int Width, strDestStr.Format(L"%*.*ls %1.1ls", Width, Width, strStr.CPtr(), UnitStr[0][IndexDiv]); } else strDestStr.Format(L"%*.*ls", Width, Width, strStr.CPtr()); + } else { Width-= (Economic ? 1 : 2); IndexB = 0; diff --git a/far2l/src/mix/strmix.hpp b/far2l/src/mix/strmix.hpp index f5f2b13d8..b779b8055 100644 --- a/far2l/src/mix/strmix.hpp +++ b/far2l/src/mix/strmix.hpp @@ -51,6 +51,7 @@ enum COLUMN_MINSIZEINDEX = 0x00200000, COLUMN_SHOWBYTESINDEX = 0x00100000, COLUMN_FULLOWNER = 0x00080000, + COLUMN_AUTO = 0x00040000, // MINSIZEINDEX может быть только 0, 1, 2 или 3 (K,M,G,T) COLUMN_MINSIZEINDEX_MASK = 0x00000003, diff --git a/far2l/src/mix/udlist.hpp b/far2l/src/mix/udlist.hpp index 1244567f8..eba45d3bb 100644 --- a/far2l/src/mix/udlist.hpp +++ b/far2l/src/mix/udlist.hpp @@ -49,6 +49,8 @@ enum UDL_FLAGS ULF_NOTTRIM = 0x00000040, // не удалять пробелы ULF_NOTUNQUOTES = 0x00000080, // не раскавычивать ULF_ACCOUNTEMPTYLINE = 0x00000100, // учитывать пустые "строки" + ULF_CASESENSITIVE =0x00000200, // регистрозависимый + ULF_PROCESSREGEXP =0x00000400, // учитывать регулярные выражения, например /a+,b+;c+/i }; class UserDefinedListItem diff --git a/far2l/src/options.cpp b/far2l/src/options.cpp index a6859312c..c08a66034 100644 --- a/far2l/src/options.cpp +++ b/far2l/src/options.cpp @@ -59,6 +59,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "strmix.hpp" #include "interf.hpp" #include "codepage.hpp" +#include "MaskGroups.hpp" enum enumMenus { @@ -128,6 +129,7 @@ enum enumCommandsMenu MENU_COMMANDS_FOLDERHISTORY, MENU_COMMANDS_SEPARATOR1, MENU_COMMANDS_SWAPPANELS, + MENU_COMMANDS_HORZPANELS, MENU_COMMANDS_TOGGLEPANELS, MENU_COMMANDS_COMPAREFOLDERS, MENU_COMMANDS_SEPARATOR2, @@ -155,6 +157,7 @@ enum enumOptionsMenu MENU_OPTIONS_VMENUSETTINGS, MENU_OPTIONS_CMDLINESETTINGS, MENU_OPTIONS_AUTOCOMPLETESETTINGS, + MENU_OPTIONS_MASKGROUPS, // MENU_OPTIONS_INFOPANELSETTINGS, MENU_OPTIONS_SEPARATOR1, MENU_OPTIONS_CONFIRMATIONS, @@ -254,6 +257,7 @@ void ShellOptions(int LastCommand, MOUSE_EVENT_RECORD *MouseEvent) {Msg::MenuFoldersHistory, 0, KEY_ALTF12}, {L"", LIF_SEPARATOR, 0 }, {Msg::MenuSwapPanels, 0, KEY_CTRLU }, + { Opt.PanelsDisposition ? Msg::MenuVerticalPanels : Msg::MenuHorizontalPanels, 0,(KEY_CTRL + KEY_COMMA) }, {Msg::MenuTogglePanels, 0, KEY_CTRLO }, {Msg::MenuCompareFolders, 0, 0 }, {L"", LIF_SEPARATOR, 0 }, @@ -278,6 +282,7 @@ void ShellOptions(int LastCommand, MOUSE_EVENT_RECORD *MouseEvent) {Msg::MenuVMenuSettings, 0, 0 }, {Msg::MenuCmdlineSettings, 0, 0 }, {Msg::MenuAutoCompleteSettings, 0, 0 }, + {Msg::MenuMaskGroups, 0, 0 }, {L"", LIF_SEPARATOR, 0 }, {Msg::MenuConfirmation, 0, 0 }, {Msg::MenuFilePanelModes, 0, 0 }, @@ -503,6 +508,9 @@ void ShellOptions(int LastCommand, MOUSE_EVENT_RECORD *MouseEvent) case MENU_COMMANDS_SWAPPANELS: // Swap panels FrameManager->ProcessKey(KEY_CTRLU); break; + case MENU_COMMANDS_HORZPANELS: // Hrz/Vert panels disposition + FrameManager->ProcessKey(KEY_CTRL + KEY_COMMA); + break; case MENU_COMMANDS_TOGGLEPANELS: // Panels On/Off FrameManager->ProcessKey(KEY_CTRLO); break; @@ -576,6 +584,9 @@ void ShellOptions(int LastCommand, MOUSE_EVENT_RECORD *MouseEvent) // case MENU_OPTIONS_INFOPANELSETTINGS: // InfoPanel Settings // InfoPanelSettings(); // break; + case MENU_OPTIONS_MASKGROUPS: + MaskGroupsSettings(); + break; case MENU_OPTIONS_CONFIRMATIONS: // Confirmations SetConfirmations(); break; diff --git a/far2l/src/panels/filelist.cpp b/far2l/src/panels/filelist.cpp index e271b7866..149c592e6 100644 --- a/far2l/src/panels/filelist.cpp +++ b/far2l/src/panels/filelist.cpp @@ -123,6 +123,10 @@ FileList::FileList() SelFileSize(0), TotalFileSize(0), FreeDiskSize(0), + TotalFilePhysSize(0), + LargestFilSize(0), + LargestFilSizeL(0), + LargestFilPhysSize(0), MarkLM(0), LastUpdateTime(0), Height(0), @@ -165,6 +169,9 @@ FileList::FileList() DirectoriesFirst = 1; Columns = PreparePanelView(&ViewSettings); PluginCommand = -1; + + extern int ColumnTypeWidth[32]; + memcpy(AutoColumnWidth, ColumnTypeWidth, sizeof(int) * 32); } FileList::~FileList() @@ -1240,6 +1247,37 @@ int FileList::ProcessKey(FarKey Key) AnotherPanel->Redraw(); return TRUE; } + + case KEY_CTRLD | KEY_ALT: { + ++Opt.DirNameStyle &= 63; + UpdateDefaultColumnTypeWidths( ); + UpdateAutoColumnWidth(); + Redraw(); + Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); + AnotherPanel->Update(UPDATE_KEEP_SELECTION); + AnotherPanel->Redraw(); + return TRUE; + } + + case KEY_CTRLL | KEY_ALT: { + Opt.ShowSymlinkSize ^= 1; + UpdateAutoColumnWidth(); + Redraw(); + Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); + AnotherPanel->Update(UPDATE_KEEP_SELECTION); + AnotherPanel->Redraw(); + return TRUE; + } + + case KEY_CTRLN | KEY_ALT: { + Opt.FilenameMarksInStatusBar ^= 1; + Redraw(); + Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); + AnotherPanel->Update(UPDATE_KEEP_SELECTION); + AnotherPanel->Redraw(); + return TRUE; + } + case KEY_CTRLR: { Update(UPDATE_KEEP_SELECTION | UPDATE_CAN_BE_ANNOYING); Redraw(); @@ -2954,6 +2992,8 @@ void FileList::SetViewMode(int ViewMode) if (AnotherPanel->GetType() == TREE_PANEL) AnotherPanel->Redraw(); } + + UpdateAutoColumnWidth(); } void FileList::SetSortMode(int SortMode) @@ -4257,6 +4297,9 @@ void FileList::CountDirSize(DWORD PluginFlags) Item->FileSize = FileSize; Item->PhysicalSize = PhysicalSize; Item->ShowFolderSize = 1; + LargestFilSize = std::max(FileSize, LargestFilSize); + LargestFilSizeL = std::max(FileSize, LargestFilSizeL); + LargestFilPhysSize = std::max(PhysicalSize, LargestFilPhysSize); } else break; } @@ -4278,9 +4321,13 @@ void FileList::CountDirSize(DWORD PluginFlags) ListData[CurFile]->FileSize = FileSize; ListData[CurFile]->PhysicalSize = PhysicalSize; ListData[CurFile]->ShowFolderSize = 1; + LargestFilSize = std::max(FileSize, LargestFilSize); + LargestFilSizeL = std::max(FileSize, LargestFilSizeL); + LargestFilPhysSize = std::max(PhysicalSize, LargestFilPhysSize); } } + UpdateAutoColumnWidth( ); SortFileList(TRUE); ShowFileList(TRUE); CtrlObject->Cp()->Redraw(); diff --git a/far2l/src/panels/filelist.hpp b/far2l/src/panels/filelist.hpp index c4c0e9cc1..5a787c6e4 100644 --- a/far2l/src/panels/filelist.hpp +++ b/far2l/src/panels/filelist.hpp @@ -194,12 +194,17 @@ class FileList : public Panel uint64_t SelFileSize; uint64_t TotalFileSize; uint64_t FreeDiskSize; + uint64_t TotalFilePhysSize; + uint64_t LargestFilSize; + uint64_t LargestFilSizeL; + uint64_t LargestFilPhysSize; size_t MarkLM; clock_t LastUpdateTime; int Height, Columns; std::deque _symlinks_backlog; int ColumnsInGlobal; + int AutoColumnWidth[32]; int LeftPos; int ShiftSelection; @@ -270,7 +275,7 @@ class FileList : public Panel HANDLE OpenPluginForFile(const wchar_t *FileName, DWORD FileAttr, OPENFILEPLUGINTYPE Type); int PreparePanelView(PanelViewSettings *PanelView); int PrepareColumnWidths(unsigned int *ColumnTypes, int *ColumnWidths, int *ColumnWidthsTypes, - int &ColumnCount, int FullScreen); + int &ColumnCount, int FullScreen, bool bStatus); void PrepareViewSettings(int ViewMode, OpenPluginInfo *PlugInfo); void PluginDelete(); @@ -323,6 +328,7 @@ class FileList : public Panel virtual void CloseChangeNotification(); virtual void SortFileList(int KeepPosition); virtual void SetViewMode(int ViewMode); + virtual void SetSortMode(int SortMode); void SetSortMode0(int SortMode); virtual void ChangeSortOrder(int NewOrder); @@ -337,6 +343,8 @@ class FileList : public Panel virtual int GetPrevCaseSensitiveSort(); virtual int GetPrevDirectoriesFirst(); + void UpdateAutoColumnWidth(); + HANDLE OpenFilePlugin(const wchar_t *FileName, int PushPrev, OPENFILEPLUGINTYPE Type); virtual int GetFileName(FARString &strName, int Pos, DWORD &FileAttr); virtual int GetCurrentPos(); diff --git a/far2l/src/panels/flmodes.cpp b/far2l/src/panels/flmodes.cpp index c6f4fdbe1..32900c07f 100644 --- a/far2l/src/panels/flmodes.cpp +++ b/far2l/src/panels/flmodes.cpp @@ -45,6 +45,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define PANELMODES_INI "panel_modes.ini" +#if 0 PanelViewSettings ViewSettingsArray[] = { /* 00 */ {{COLUMN_MARK | NAME_COLUMN, SIZE_COLUMN | COLUMN_COMMAS, DATE_COLUMN}, {0, 10, 0}, 3, {COLUMN_RIGHTALIGN | NAME_COLUMN}, {0}, 1, 0, 1, 0, 0, 0, 0, @@ -83,6 +84,55 @@ PanelViewSettings ViewSettingsArray[] = { {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, {0, 6, 6, 6, 0, 5}, 6, 0, 1, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}}; +#endif + +PanelViewSettings ViewSettingsArray[] = { + /* 00 */ {{COLUMN_MARK | NAME_COLUMN, SIZE_COLUMN | COLUMN_COMMAS | COLUMN_AUTO, DATE_COLUMN}, {0, 0, 0}, 3, + {COLUMN_RIGHTALIGN | NAME_COLUMN}, {0}, 1, 0, 1, 0, 0, 0, 0, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, {COUNT_WIDTH}}, + + /* 01 */ {{NAME_COLUMN, NAME_COLUMN, NAME_COLUMN}, {0, 0, 0}, 3, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 6, 6, 0, 0, 5}, 6, 0, 1, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}, + + /* 02 */ {{NAME_COLUMN, NAME_COLUMN}, {0, 0}, 2, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 6, 6, 9, 0, 5}, 6, 0, 0, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}, + + /* 03 */ {{NAME_COLUMN, SIZE_COLUMN | COLUMN_AUTO, DATE_COLUMN, TIME_COLUMN}, {0, 0, 0, 5}, 4, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN}, {0, 6, 6}, 3, 0, 1, 0, 0, 0, 0, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, {COUNT_WIDTH}}, + + /* 04 */ {{NAME_COLUMN, SIZE_COLUMN | COLUMN_COMMAS | COLUMN_AUTO}, {0, 0}, 2, + {COLUMN_RIGHTALIGN | NAME_COLUMN, SIZE_COLUMN, OWNER_COLUMN, GROUP_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 9, 6, 6, 0, 5}, 6, 0, 0, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}, + + /* 05 */ {{NAME_COLUMN, SIZE_COLUMN, PHYSICAL_COLUMN, WDATE_COLUMN, CDATE_COLUMN, ADATE_COLUMN, OWNER_COLUMN, GROUP_COLUMN, ATTR_COLUMN}, + {0, 0, 0, 14, 14, 14, 6, 6, 0}, 9, {COLUMN_RIGHTALIGN | NAME_COLUMN}, {0}, 1, 1, 1, 0, 0, 0, + 0, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH}}, + + /* 06 */ {{NAME_COLUMN, DIZ_COLUMN}, {40, 0}, 2, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 6, 6, 9, 0, 5}, 6, 0, 1, 0, 0, 0, 0, {PERCENT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}, + + /* 07 */ {{NAME_COLUMN, SIZE_COLUMN | COLUMN_AUTO, DIZ_COLUMN}, {0, 0, 54}, 3, {COLUMN_RIGHTALIGN | NAME_COLUMN}, {0}, 1, 1, + 1, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, {COUNT_WIDTH}}, + + /* 08 */ {{NAME_COLUMN, SIZE_COLUMN, OWNER_COLUMN, GROUP_COLUMN}, {0, 0, 6, 15}, 4, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 6, 6, 9, 0, 5}, 6, 0, 1, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}, + + /* 09 */ {{NAME_COLUMN, SIZE_COLUMN | COLUMN_AUTO, NUMLINK_COLUMN}, {0, 0, 4}, 3, + {COLUMN_RIGHTALIGN | NAME_COLUMN, OWNER_COLUMN, GROUP_COLUMN, SIZE_COLUMN, DATE_COLUMN, TIME_COLUMN}, + {0, 6, 6, 9, 0, 5}, 6, 0, 1, 0, 0, 0, 0, {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}, + {COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH, COUNT_WIDTH}}}; size_t SizeViewSettingsArray = ARRAYSIZE(ViewSettingsArray); diff --git a/far2l/src/panels/flshow.cpp b/far2l/src/panels/flshow.cpp index 732777ab3..a2554e140 100644 --- a/far2l/src/panels/flshow.cpp +++ b/far2l/src/panels/flshow.cpp @@ -693,16 +693,37 @@ void FileList::PrepareViewSettings(int ViewMode, OpenPluginInfo *PlugInfo) Height+= 2; } +void FileList::UpdateAutoColumnWidth( void ) +{ + for (int c = 0; c < ViewSettings.ColumnCount; c++) { + + int ColumnType = std::min( ViewSettings.ColumnType[c] & 0xff, 31u ); + bool bPhysical = (ColumnType == PHYSICAL_COLUMN); + + if (ColumnType == SIZE_COLUMN || bPhysical) { + + FARString strOutStr; + size_t len = FileSizeToStr(strOutStr, bPhysical ? LargestFilPhysSize : Opt.ShowSymlinkSize ? LargestFilSizeL : LargestFilSize, -1, ViewSettings.ColumnType[c]).GetLength(); + + AutoColumnWidth[ColumnType] = std::max( len + 1, (size_t)ColumnTypeWidth[ColumnType] ); + } + else { + AutoColumnWidth[ColumnType] = ColumnTypeWidth[ColumnType]; + } + } +} + int FileList::PreparePanelView(PanelViewSettings *PanelView) { PrepareColumnWidths(PanelView->StatusColumnType, PanelView->StatusColumnWidth, - PanelView->StatusColumnWidthType, PanelView->StatusColumnCount, PanelView->FullScreen); + PanelView->StatusColumnWidthType, PanelView->StatusColumnCount, PanelView->FullScreen, true); + return (PrepareColumnWidths(PanelView->ColumnType, PanelView->ColumnWidth, PanelView->ColumnWidthType, - PanelView->ColumnCount, PanelView->FullScreen)); + PanelView->ColumnCount, PanelView->FullScreen, false)); } int FileList::PrepareColumnWidths(unsigned int *ColumnTypes, int *ColumnWidths, int *ColumnWidthsTypes, - int &ColumnCount, int FullScreen) + int &ColumnCount, int FullScreen, bool bStatusBar) { int TotalWidth, TotalPercentWidth, TotalPercentCount, ZeroLengthCount, EmptyColumns, I; ZeroLengthCount = EmptyColumns = 0; @@ -710,16 +731,18 @@ int FileList::PrepareColumnWidths(unsigned int *ColumnTypes, int *ColumnWidths, TotalPercentCount = TotalPercentWidth = 0; for (I = 0; I < ColumnCount; I++) { + if (ColumnWidths[I] < 0) { EmptyColumns++; continue; } - int ColumnType = ColumnTypes[I] & 0xff; +// int ColumnType = ColumnTypes[I] & 0xff; + int ColumnType = std::min( ColumnTypes[I] & 0xff, 31u ); if (!ColumnWidths[I]) { ColumnWidthsTypes[I] = COUNT_WIDTH; // manage all zero-width columns in same way - ColumnWidths[I] = ColumnTypeWidth[ColumnType]; + ColumnWidths[I] = (ColumnTypes[I] & COLUMN_AUTO) ? AutoColumnWidth[ColumnType] : ColumnTypeWidth[ColumnType]; if (ColumnType == WDATE_COLUMN || ColumnType == CDATE_COLUMN || ColumnType == ADATE_COLUMN || ColumnType == CHDATE_COLUMN) { @@ -730,6 +753,12 @@ int FileList::PrepareColumnWidths(unsigned int *ColumnTypes, int *ColumnWidths, ColumnWidths[I]++; } } + else { + if (ColumnType == SIZE_COLUMN || ColumnType == PHYSICAL_COLUMN) { + if (ColumnWidths[I] < ColumnTypeWidth[SIZE_COLUMN]) + ColumnWidths[I] = ColumnTypeWidth[SIZE_COLUMN]; + } + } if (!ColumnWidths[I]) ZeroLengthCount++; @@ -851,10 +880,13 @@ static int MakeCurLeftPos(int ColumnWidth, const wchar_t *Str, int LeftPos, int LeftPos = Cells - ColumnWidth; size_t ng = LeftPos; - int out = StrSizeOfCells(Str, wcslen(Str), ng, false); + int out = StrSizeOfCells(Str, wcslen(Str), ng, true); + +// if (MaxLeftPos < (int)ng) +// MaxLeftPos = (int)ng; - if (MaxLeftPos < (int)ng) - MaxLeftPos = (int)ng; + if (MaxLeftPos < LeftPos) + MaxLeftPos = LeftPos; return out; } @@ -950,7 +982,7 @@ void FileList::ShowList(int ShowStatus, int StartColumn, OpenPluginInfo &Info) { /// Draw mark str size_t prews = std::min(Opt.MinFilenameIndentation, Opt.MaxFilenameIndentation); - if (Opt.ShowFilenameMarks && Opt.Highlight + if (Opt.ShowFilenameMarks && Opt.Highlight && (!ShowStatus || Opt.FilenameMarksInStatusBar) && (PanelMode != PLUGIN_PANEL || ( !(Info.Flags & OPIF_HL_MARKERS_NOSHOW) && (Info.Flags & OPIF_USEHIGHLIGHTING) )) ) { @@ -966,7 +998,7 @@ void FileList::ShowList(int ShowStatus, int StartColumn, OpenPluginInfo &Info) size_t ng = Width, outlen; outlen = StrSizeOfCells(hl->Mark, hl->MarkLen, ng, false); - ng = StrCellsCount( hl->Mark, outlen ); +// ng = StrCellsCount( hl->Mark, outlen ); Width -= ng; if (ng < prews) @@ -1011,7 +1043,7 @@ void FileList::ShowList(int ShowStatus, int StartColumn, OpenPluginInfo &Info) if (!ShowStatus && LeftPos) { if (LeftPos > 0 && !RightAlign) { CurLeftPos = MakeCurLeftPos(Width, NamePtr, LeftPos, MaxLeftPos); - NamePtr+= CurLeftPos; + NamePtr += CurLeftPos; } else if (RightAlign) { int Cells = (int)StrZCellsCount(NamePtr); if (Cells > Width) { @@ -1022,7 +1054,7 @@ void FileList::ShowList(int ShowStatus, int StartColumn, OpenPluginInfo &Info) RightBracket = TRUE; size_t ng = Cells + CurRightPos - Width; - NamePtr+= StrSizeOfCells(NamePtr, wcslen(NamePtr), ng, false); + NamePtr += StrSizeOfCells(NamePtr, wcslen(NamePtr), ng, false); RightAlign = FALSE; if (MinLeftPos > CurRightPos) diff --git a/far2l/src/panels/flupdate.cpp b/far2l/src/panels/flupdate.cpp index fe239e653..7894a1c64 100644 --- a/far2l/src/panels/flupdate.cpp +++ b/far2l/src/panels/flupdate.cpp @@ -166,7 +166,7 @@ void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessa SelFileCount = 0; SelFileSize = 0; TotalFileCount = 0; - TotalFileSize = 0; + TotalFileSize = TotalFilePhysSize = LargestFilSize = LargestFilSizeL = LargestFilPhysSize = 0; CacheSelIndex = -1; CacheSelClearIndex = -1; MarkLM = 0; @@ -255,9 +255,17 @@ void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessa NewPtr->NumberOfLinks = fdata.nHardLinks; if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0 || Opt.ScanJunction) { TotalFileSize += NewPtr->FileSize; } + + if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + LargestFilSize = std::max(NewPtr->FileSize, LargestFilSize); + + LargestFilSizeL = std::max(NewPtr->FileSize, LargestFilSizeL); + TotalFilePhysSize += NewPtr->PhysicalSize; + LargestFilPhysSize = std::max(NewPtr->PhysicalSize, LargestFilPhysSize); } NewPtr->SortGroup = DEFAULT_SORT_GROUP; @@ -374,7 +382,15 @@ void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessa FAR_FIND_DATA &fdata = PanelData[i].FindData; PluginToFileListItem(&PanelData[i], CurPtr); - TotalFileSize+= fdata.nFileSize; + TotalFileSize += fdata.nFileSize; + TotalFilePhysSize += fdata.nPhysicalSize; + + if ( !(fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ) + LargestFilSize = std::max(fdata.nFileSize, LargestFilSize); + + LargestFilSizeL = std::max(fdata.nFileSize, LargestFilSizeL); + LargestFilPhysSize = std::max(fdata.nPhysicalSize, LargestFilPhysSize); + CurPtr->PrevSelected = CurPtr->Selected = false; CurPtr->ShowFolderSize = 0; CurPtr->SortGroup = CtrlObject->HiFiles->GetGroup(CurPtr); @@ -412,6 +428,8 @@ void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessa if (!GoToFile(strCurName) && !strNextCurName.IsEmpty()) GoToFile(strNextCurName); + UpdateAutoColumnWidth(); + /* $ 13.02.2002 DJ SetTitle() - только если мы текущий фрейм! @@ -571,7 +589,7 @@ void FileList::UpdatePlugin(int KeepSelection, int IgnoreVisible) SelFileCount = 0; SelFileSize = 0; TotalFileCount = 0; - TotalFileSize = 0; + TotalFileSize = TotalFilePhysSize = LargestFilSize = LargestFilSizeL = LargestFilPhysSize = 0; CacheSelIndex = -1; CacheSelClearIndex = -1; MarkLM = 0; @@ -644,7 +662,13 @@ void FileList::UpdatePlugin(int KeepSelection, int IgnoreVisible) TotalFileCount++; } - TotalFileSize+= CurListData->FileSize; + if ( !(CurListData->FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) ) + LargestFilSize = std::max(CurListData->FileSize, LargestFilSize); + + LargestFilSizeL = std::max(CurListData->FileSize, LargestFilSizeL); + TotalFileSize += CurListData->FileSize; + TotalFilePhysSize += CurListData->PhysicalSize; + LargestFilPhysSize = std::max(CurListData->PhysicalSize, LargestFilPhysSize); } if (!ListData.IsEmpty() && ((Info.Flags & OPIF_USEHIGHLIGHTING) || (Info.Flags & OPIF_USEATTRHIGHLIGHTING))) CtrlObject->HiFiles->GetHiColor(&ListData[0], ListData.Count(), @@ -697,6 +721,7 @@ void FileList::UpdatePlugin(int KeepSelection, int IgnoreVisible) if (!GoToFile(strCurName) && !strNextCurName.IsEmpty()) GoToFile(strNextCurName); + UpdateAutoColumnWidth(); SetTitle(); } diff --git a/far2l/src/pick_color.cpp b/far2l/src/pick_color.cpp index 7d8f23eab..4facd8add 100644 --- a/far2l/src/pick_color.cpp +++ b/far2l/src/pick_color.cpp @@ -802,16 +802,21 @@ static bool GetColorDialogInner(uint64_t *color, uint64_t *mask, bool bRGB, bool colorState.update_color( ); + static const FarLangMsg msgTextStyles[] = { + Msg::PickColorStyleOverline, + Msg::PickColorStyleStrikeout, + Msg::PickColorStyleUnderline, + Msg::PickColorStyleInverse, + Msg::PickColorStyleBlinking, + Msg::PickColorStyleBold, + Msg::PickColorStyleItalic }; + size_t extrasize = 10; - { - size_t ml; - if ((ml = wcslen(Msg::PickColorStyleOverline)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleStrikeout)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleUnderline)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleInverse)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleBlinking)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleBold)) > extrasize) extrasize = ml; - if ((ml = wcslen(Msg::PickColorStyleItalic)) > extrasize) extrasize = ml; + + for (size_t i = 0; i < ARRAYSIZE(msgTextStyles); i++) { + size_t len = msgTextStyles[i].Len(); + if (extrasize < len) + extrasize = len; } DialogDataEx ColorDlgData[] = { diff --git a/far2l/src/setcolor.cpp b/far2l/src/setcolor.cpp index dea78d45b..168de56b2 100644 --- a/far2l/src/setcolor.cpp +++ b/far2l/src/setcolor.cpp @@ -126,7 +126,9 @@ void SetColors() {L"", LIF_SEPARATOR, 0}, {(const wchar_t *)Msg::SetDefaultColors, 0, 0}, {(const wchar_t *)Msg::SetDefaultColorsRGB, 0, 0}, - {(const wchar_t *)Msg::SetBW, 0, 0} + {(const wchar_t *)Msg::SetBW, 0, 0}, + {L"", LIF_SEPARATOR, 0}, + {(const wchar_t *)Msg::Palette, 0, 0} }; MenuDataEx PanelItems[] = { {(const wchar_t *)Msg::SetColorPanelNormal, LIF_SELECTED, 0}, From 6ddde2ece516368e84de83b4703548c3ba777085 Mon Sep 17 00:00:00 2001 From: anta999 Date: Sun, 20 Oct 2024 15:06:57 +0400 Subject: [PATCH 03/30] fix mark inherit --- far2l/src/hilight.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/far2l/src/hilight.cpp b/far2l/src/hilight.cpp index 1a7c92952..a37490eea 100644 --- a/far2l/src/hilight.cpp +++ b/far2l/src/hilight.cpp @@ -457,7 +457,7 @@ static void ApplyColors(HighlightDataColor *hlDst, HighlightDataColor *hlSrc) // Унаследуем пометку из Src в Dst если она есть if (hlSrc->MarkLen) { // Если нет наследования в Src, то просто заменим метку на новую в Dst - if (!(hlSrc->Flags & HL_FLAGS_MARK_INHERIT)) { + if ( !(hlSrc->Flags & HL_FLAGS_MARK_INHERIT) || !hlDst->MarkLen ) { hlDst->MarkLen = hlSrc->MarkLen; memcpy(hlDst->Mark, hlSrc->Mark, sizeof(wchar_t) * hlSrc->MarkLen); } From 7cb120f60d5304287e48925805c2af2ac6caa7d7 Mon Sep 17 00:00:00 2001 From: anta999 Date: Sun, 20 Oct 2024 19:53:27 +0400 Subject: [PATCH 04/30] ctrl+m select attr string style --- far2l/bootstrap/scripts/farlang.templ.m4 | 36 ++++----- far2l/src/filefilter.cpp | 71 +++++++++++++----- far2l/src/filefilter.hpp | 1 + far2l/src/filefilterparams.cpp | 94 ++++++++++++++++++------ far2l/src/filefilterparams.hpp | 2 +- far2l/src/hilight.cpp | 8 +- 6 files changed, 152 insertions(+), 60 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 67ee814ba..f9cbf85ca 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -12051,15 +12051,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 "Файлы панели" @@ -12785,15 +12785,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 "Верхняя группа сортировки" diff --git a/far2l/src/filefilter.cpp b/far2l/src/filefilter.cpp index bb2ebf5be..ac9255bf7 100644 --- a/far2l/src/filefilter.cpp +++ b/far2l/src/filefilter.cpp @@ -48,6 +48,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pathmix.hpp" #include "strmix.hpp" #include "interf.hpp" +#include "scrbuf.hpp" + static int _cdecl ExtSort(const void *el1, const void *el2); @@ -76,27 +78,19 @@ Panel *FileFilter::GetHostPanel() return m_HostPanel; } -bool FileFilter::FilterEdit() +void FileFilter::FillMenu(VMenu &FilterList) { - if (bMenuOpen) - return false; - - bMenuOpen = true; MenuItemEx ListItem; - int ExitCode; - bool bNeedUpdate = false; - VMenu FilterList(Msg::FilterTitle, nullptr, 0, ScrY - 6); - FilterList.SetHelp(L"FiltersMenu"); - FilterList.SetPosition(-1, -1, 0, 0); - FilterList.SetBottomTitle(Msg::FilterBottom); - FilterList.SetFlags(/*VMENU_SHOWAMPERSAND|*/ VMENU_WRAPMODE); + uint32_t attrstyle = Opt.AttrStrStyle; + + FilterList.DeleteItems(); for (size_t i = 0; i < FilterData.getCount(); i++) { ListItem.Clear(); - MenuString(ListItem.strName, FilterData.getItem(i)); + MenuString(ListItem.strName, FilterData.getItem(i), attrstyle); if (!i) - ListItem.Flags|= LIF_SELECTED; + ListItem.Flags |= LIF_SELECTED; auto Check = GetCheck(FilterData.getItem(i)); @@ -139,7 +133,7 @@ bool FileFilter::FilterEdit() FilterList.AddItem(&ListItem); ListItem.Clear(); FoldersFilter.SetTitle(Msg::FolderFileType); - MenuString(ListItem.strName, &FoldersFilter, false, L'0'); + MenuString(ListItem.strName, &FoldersFilter, attrstyle, false, L'0'); auto Check = GetCheck(&FoldersFilter); if (Check) @@ -172,14 +166,34 @@ bool FileFilter::FilterEdit() for (int i = 0, h = L'1'; i < ExtCount; i++, (h == L'9' ? h = L'A' : (h == L'Z' || h ? h++ : h = 0))) { wchar_t *CurExtPtr = ExtPtr + i * MAX_PATH; - MenuString(ListItem.strName, nullptr, false, h, true, CurExtPtr, Msg::PanelFileType); + MenuString(ListItem.strName, nullptr, attrstyle, false, h, true, CurExtPtr, Msg::PanelFileType); ListItem.SetCheck(CurExtPtr[StrLength(CurExtPtr) + 1]); FilterList.SetUserData(CurExtPtr, 0, FilterList.AddItem(&ListItem)); } free(ExtPtr); } +} + +bool FileFilter::FilterEdit() +{ + if (bMenuOpen) + return false; + + bMenuOpen = true; + MenuItemEx ListItem; + int ExitCode; + bool bNeedUpdate = false; + Panel *LeftPanel = CtrlObject->Cp()->LeftPanel; + Panel *RightPanel = CtrlObject->Cp()->RightPanel; + VMenu FilterList(Msg::FilterTitle, nullptr, 0, ScrY - 6); + FilterList.SetHelp(L"FiltersMenu"); + FilterList.SetPosition(-1, -1, 0, 0); + FilterList.SetBottomTitle(Msg::FilterBottom); + FilterList.SetFlags(/*VMENU_SHOWAMPERSAND|*/ VMENU_WRAPMODE); + + FillMenu(FilterList); FilterList.Show(); while (!FilterList.Done()) { @@ -195,6 +209,27 @@ bool FileFilter::FilterEdit() Key = L'X'; switch (Key) { + case KEY_CTRLM: { + Opt.AttrStrStyle ^= 1; + + int SelPos = FilterList.GetSelectPos(); + if (SelPos < 0 || SelPos == (int)FilterData.getCount()) + SelPos = 0; + + ScrBuf.Lock(); + FilterList.Hide(); + LeftPanel->Update(UPDATE_KEEP_SELECTION); + LeftPanel->Redraw(); + RightPanel->Update(UPDATE_KEEP_SELECTION); + RightPanel->Redraw(); + FillMenu(FilterList); + FilterList.SetPosition(-1, -1, 0, 0); + FilterList.SetSelectPos(SelPos, 1); + FilterList.Show(); + ScrBuf.Unlock(); + break; + } + case L'+': case L'-': case L'I': @@ -241,7 +276,7 @@ bool FileFilter::FilterEdit() if (SelPos < (int)FilterData.getCount()) { if (FileFilterConfig(FilterData.getItem(SelPos))) { ListItem.Clear(); - MenuString(ListItem.strName, FilterData.getItem(SelPos)); + MenuString(ListItem.strName, FilterData.getItem(SelPos), Opt.AttrStrStyle); auto Check = GetCheck(FilterData.getItem(SelPos)); if (Check) @@ -302,7 +337,7 @@ bool FileFilter::FilterEdit() if (FileFilterConfig(NewFilter)) { ListItem.Clear(); - MenuString(ListItem.strName, NewFilter); + MenuString(ListItem.strName, NewFilter, Opt.AttrStrStyle); FilterList.AddItem(&ListItem, static_cast(SelPos)); FilterList.SetSelectPos(static_cast(SelPos), 1); FilterList.SetPosition(-1, -1, 0, 0); diff --git a/far2l/src/filefilter.hpp b/far2l/src/filefilter.hpp index 299730aad..237aa1614 100644 --- a/far2l/src/filefilter.hpp +++ b/far2l/src/filefilter.hpp @@ -67,6 +67,7 @@ class FileFilter FileFilter(Panel *HostPanel, FAR_FILE_FILTER_TYPE FilterType); ~FileFilter(); + void FillMenu(VMenu &FilterList); bool FilterEdit(); void UpdateCurrentTime(); bool FileInFilter(const FileListItem &fli, enumFileInFilterType *foundType = nullptr); diff --git a/far2l/src/filefilterparams.cpp b/far2l/src/filefilterparams.cpp index 944a3a825..ca10c8bbc 100644 --- a/far2l/src/filefilterparams.cpp +++ b/far2l/src/filefilterparams.cpp @@ -397,7 +397,23 @@ void FillPreviewStr(wchar_t *dstStr, size_t dstsize, const wchar_t *srcStr, cons *dstStr = 0; } -void FillAttrStr(wchar_t *AttrStr, size_t truncatelen, uint32_t IncludeAttr, uint32_t ExcludeAttr) +#if 0 + wchar_t Attr[ARRAYSIZE(AttrC) * 2] = {0}; + + for (size_t i = 0; i < ARRAYSIZE(AttrF); i++) { + wchar_t *Ptr = Attr + i * 2; + *Ptr = AttrC[i]; + + if ((IncludeAttr & AttrF[i]) == AttrF[i]) + *(Ptr + 1) = L'+'; + else if ((ExcludeAttr & AttrF[i]) == AttrF[i]) + *(Ptr + 1) = L'-'; + else + *Ptr = *(Ptr + 1) = L'.'; + } +#endif + +void FillAttrStr(wchar_t *AttrStr, size_t truncatelen, uint32_t IncludeAttr, uint32_t ExcludeAttr, uint32_t style) { static const wchar_t AttrC[] = L"RAHSD truncatelen - 1) { + AttrStr[truncatelen - 1] = L'…'; + AttrStr[truncatelen] = 0; + return; + } + } - if (ExcludeAttr) { - *Ptr++ = L'-'; + else { for (size_t i = 0; i < ARRAYSIZE(AttrF); i++) { - if ((ExcludeAttr & AttrF[i])) - *Ptr++ = AttrC[i]; + wchar_t *Ptr = AttrStr + i * 2; + *Ptr = AttrC[i]; + + if ((IncludeAttr & AttrF[i]) == AttrF[i]) + *(Ptr + 1) = L'+'; + else if ((ExcludeAttr & AttrF[i]) == AttrF[i]) + *(Ptr + 1) = L'-'; + else + *Ptr = *(Ptr + 1) = L'.'; } + Ptr += ARRAYSIZE(AttrF) * 2; } - *Ptr = 0; - if ((size_t)(Ptr - AttrStr) > truncatelen - 1) { - AttrStr[truncatelen - 1] = L'…'; - AttrStr[truncatelen] = 0; + while(Ptr < (AttrStr + truncatelen)) { + *Ptr++ = 32; } + + AttrStr[truncatelen] = 0; } // Централизованная функция для создания строк меню различных фильтров. -void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, int Hotkey, bool bPanelType, +void MenuString(FARString &strDest, FileFilterParams *FF, uint32_t attrstyle, bool bHighlightType, int Hotkey, bool bPanelType, const wchar_t *FMask, const wchar_t *Title) { wchar_t MarkStrPrw[8]; wchar_t NameStrPrw[32]; - const wchar_t Format1A[] = L"%ls %lc %-16.16ls %-2.2ls %lc %ls"; - const wchar_t Format1c[] = L"&%lc. %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; - const wchar_t Format1d[] = L" %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; - const wchar_t Format2[] = L"%ls %lc %ls %lc %-16.16ls %-3.3ls %lc %ls"; +// const wchar_t Format1A[] = L"%ls %lc %-16.16ls %-2.2ls %lc %ls"; + const wchar_t Format1A[] = L"%ls %lc %ls %-2.2ls %lc %ls"; + + const wchar_t Format1c[] = L"&%lc. %-18.18ls %lc %ls %-2.2ls %lc %ls"; + const wchar_t Format1d[] = L" %-18.18ls %lc %ls %-2.2ls %lc %ls"; + +// const wchar_t Format1c[] = L"&%lc. %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; +// const wchar_t Format1d[] = L" %-18.18ls %lc %-16.16ls %-2.2ls %lc %ls"; + + const wchar_t Format2[] = L"%ls %lc %ls %lc %ls %-3.3ls %lc %ls"; const wchar_t DownArrow = 0x2193; const wchar_t *Name, *Mask; @@ -476,8 +523,11 @@ void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType, i UseDate = FF->GetDate(nullptr, nullptr, nullptr, &RelativeDate); } - wchar_t Attr[32]; - FillAttrStr(Attr, 16, IncludeAttr, ExcludeAttr); + wchar_t Attr[64]; + switch(attrstyle) { + case 0: FillAttrStr(Attr, 38, IncludeAttr, ExcludeAttr, attrstyle); break; + case 1: FillAttrStr(Attr, 16, IncludeAttr, ExcludeAttr, attrstyle); break; + } wchar_t SizeDate[4] = L"..."; diff --git a/far2l/src/filefilterparams.hpp b/far2l/src/filefilterparams.hpp index 757aa4cde..919b1e34f 100644 --- a/far2l/src/filefilterparams.hpp +++ b/far2l/src/filefilterparams.hpp @@ -179,5 +179,5 @@ class FileFilterParams bool FileFilterConfig(FileFilterParams *FF, bool ColorConfig = false); // Централизованная функция для создания строк меню различных фильтров. -void MenuString(FARString &strDest, FileFilterParams *FF, bool bHighlightType = false, int Hotkey = 0, +void MenuString(FARString &strDest, FileFilterParams *FF, uint32_t maskstyle, bool bHighlightType = false, int Hotkey = 0, bool bPanelType = false, const wchar_t *FMask = nullptr, const wchar_t *Title = nullptr); diff --git a/far2l/src/hilight.cpp b/far2l/src/hilight.cpp index a37490eea..82f01c3d6 100644 --- a/far2l/src/hilight.cpp +++ b/far2l/src/hilight.cpp @@ -630,12 +630,13 @@ void HighlightFiles::FillMenu(VMenu *HiMenu, int MenuPos) }; HiMenu->DeleteItems(); HiMenuItem.Clear(); + uint32_t attrstyle = Opt.AttrStrStyle; for (int j = 0; j < 4; j++) { for (int i = Count[j][0]; i < Count[j][1]; i++) { FileFilterParams *ffp = HiData.getItem(i); - MenuString(HiMenuItem.strName, ffp, true); + MenuString(HiMenuItem.strName, ffp, attrstyle, true); if (ffp->GetFlags(FFFT_CUSTOM) & FFF_DISABLED) { HiMenuItem.Flags |= LIF_GRAYED; @@ -730,6 +731,11 @@ void HighlightFiles::HiEdit(int MenuPos) $ 07.07.2000 IS Если нажали ctrl+r, то восстановить значения по умолчанию. */ + case KEY_CTRLM: { + Opt.AttrStrStyle ^= 1; + NeedUpdate = true; + } + break; case KEY_SUBTRACT: case KEY_ADD: From 8d0df36dad1dcc66ef069688bf5982570a3eb3ed Mon Sep 17 00:00:00 2001 From: anta999 Date: Wed, 23 Oct 2024 12:53:35 +0400 Subject: [PATCH 05/30] all fixed + dircfg dialog Added dir name cfg dialog Fixed draw artefacts --- far2l/bootstrap/scripts/farlang.templ.m4 | 66 +++++++++ far2l/src/DialogBuilder.cpp | 20 +++ far2l/src/DialogBuilder.hpp | 4 + far2l/src/cfg/config.cpp | 175 +++++++++++++++++++++++ far2l/src/cfg/config.hpp | 1 + far2l/src/cmdline.cpp | 5 +- far2l/src/cmdline.hpp | 2 +- far2l/src/console/interf.cpp | 17 ++- far2l/src/filefilterparams.cpp | 36 ++--- far2l/src/filepanels.cpp | 51 ++++++- far2l/src/mix/panelmix.cpp | 13 +- far2l/src/mix/panelmix.hpp | 7 + far2l/src/panels/filelist.cpp | 16 ++- 13 files changed, 369 insertions(+), 44 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index f9cbf85ca..4c964b02a 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -2321,6 +2321,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" 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/config.cpp b/far2l/src/cfg/config.cpp index c99bbb173..b0bc881fd 100644 --- a/far2l/src/cfg/config.cpp +++ b/far2l/src/cfg/config.cpp @@ -269,6 +269,181 @@ void PanelSettings() } } +enum enumDirCfgDialog +{ + ID_DIRCFG_TITLE = 0, + + ID_DIRCFG_STYLE_TEXT, + ID_DIRCFG_STYLE_COMBO, + ID_DIRCFG_SEPARATOR, + ID_DIRCFG_BUTTON_APPLY, + + ID_DIRCFG_CHECKBOX_CENTER, + ID_DIRCFG_CHECKBOX_SURR, + ID_DIRCFG_SURR_COMBO, + + ID_DIRCFG_SEPARATOR2, + ID_DIRCFG_BUTTON_OK, + ID_DIRCFG_BUTTON_RESTORE, + ID_DIRCFG_BUTTON_CANCEL +}; + +typedef struct dircfg_data_s { + + int DirNameStyle; + int SurrIndex; + bool bCentered; + bool bSurr; + +} dircfg_data_t; + +static LONG_PTR WINAPI DirCfgDlgProc(HANDLE hDlg, int Msg, int Param1, LONG_PTR Param2) +{ + // DialogBuilder *Builder = (DialogBuilder *)((Dialog *)hDlg)->GetDialogData(); + dircfg_data_t *dircfg_data = (dircfg_data_t *)SendDlgMessage(hDlg, DM_GETDLGDATA, 0, 0); + wchar_t tmp[48 * 4]; + + auto update_surrcombo = [&]() { + + FarListItem listitems[4]; + FarList farlist = { 4, listitems }; +// FarListPos flpos = {dircfg_data->SurrIndex, 0}; + + for (size_t i = 0; i < 4; i++) { + swprintf(tmp + i * 16, 16, L"%C%S%C", surdircharleft[i], DirNames[dircfg_data->DirNameStyle].CPtr(), surdircharright[i]); +// listitems[i] = {0, tmp + i * 16, {(DWORD)i,0,0} }; + listitems[i].Flags = (i == (size_t)dircfg_data->SurrIndex) ? LIF_SELECTED : 0; + listitems[i].Text = tmp + i * 16; + listitems[i].Reserved[0] = (DWORD)i; + } + + SendDlgMessage(hDlg, DM_LISTSET, ID_DIRCFG_SURR_COMBO, (LONG_PTR)&farlist); +// SendDlgMessage(hDlg, DM_LISTSETCURPOS, dircfg_data->DirNameStyleComboID, (LONG_PTR)&flpos); + }; + + switch (Msg) { + + case DN_INITDIALOG: { + + FarListItem listitems[4]; + FarList farlist = { 4, listitems }; +// FarListPos flpos = {dircfg_data->DirNameStyle, 0}; + + for (size_t i = 0; i < 4; i++) { + swprintf(tmp + i * 48, 48, L"%-10.10S | %-10.10S | %-10.10S", DirNames[i].CPtr(), DirUpNames[i].CPtr(), SymLinkNames[i].CPtr()); +// listitems[i] = {0, tmp + i * 48, {(DWORD)i,(DWORD)i,(DWORD)i} }; + listitems[i].Flags = (i == (size_t)dircfg_data->DirNameStyle) ? LIF_SELECTED : 0; + listitems[i].Text = tmp + i * 48; + listitems[i].Reserved[0] = (DWORD)i; + } + + SendDlgMessage(hDlg, DM_LISTSET, ID_DIRCFG_STYLE_COMBO, (LONG_PTR)&farlist); +// SendDlgMessage(hDlg, DM_LISTSETCURPOS, dircfg_data->DirNameStyleComboID, (LONG_PTR)&flpos); + update_surrcombo( ); + } + break; + + case DN_LISTCHANGE: { + if (Param1 == ID_DIRCFG_STYLE_COMBO) { + + dircfg_data->DirNameStyle = SendDlgMessage(hDlg, DM_LISTGETCURPOS, ID_DIRCFG_STYLE_COMBO, (LONG_PTR)0); + update_surrcombo( ); + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + } + else if (Param1 == ID_DIRCFG_SURR_COMBO) { + dircfg_data->SurrIndex = SendDlgMessage(hDlg, DM_LISTGETCURPOS, ID_DIRCFG_SURR_COMBO, (LONG_PTR)0); + } + } + + case DN_BTNCLICK: { + if (Param1 == ID_DIRCFG_CHECKBOX_CENTER) { + dircfg_data->bCentered = (bool)(SendDlgMessage(hDlg, DM_GETCHECK, ID_DIRCFG_CHECKBOX_CENTER, 0)); + } + else if (Param1 == ID_DIRCFG_CHECKBOX_SURR) { + dircfg_data->bSurr = (bool)(SendDlgMessage(hDlg, DM_GETCHECK, ID_DIRCFG_CHECKBOX_SURR, 0)); + } + else if (Param1 == ID_DIRCFG_BUTTON_APPLY) { + + Opt.DirNameStyle = dircfg_data->DirNameStyle; + Opt.DirNameStyle |= (dircfg_data->SurrIndex << 2); + Opt.DirNameStyle |= DIRNAME_STYLE_CENTERED * dircfg_data->bCentered; + Opt.DirNameStyle |= DIRNAME_STYLE_SURR_CH * dircfg_data->bSurr; + + SendDlgMessage(hDlg, DM_SHOWDIALOG, 0, 0); + UpdateDefaultColumnTypeWidths( ); + CtrlObject->Cp()->LeftPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->RightPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->Redraw(); + + SendDlgMessage(hDlg, DM_SHOWDIALOG, 1, 0); + SendDlgMessage(hDlg, DM_REDRAW, 0, 0); + } + } + + } // switch + + return DefDlgProc(hDlg, Msg, Param1, Param2); +} + +void DirectoryNameSettings() +{ + dircfg_data_t dircfg_data; + DialogDataEx DirCfgDlgData[] = { + + {DI_DOUBLEBOX, 3, 1, 46, 11, {}, 0, Msg::DirSettingsTitle}, + {DI_TEXT, 5, 2, 35, 2, {}, 0, Msg::DirSettingsShowAs}, + {DI_COMBOBOX, 5, 3, 5+40, 3, {}, DIF_DROPDOWNLIST | DIF_LISTNOAMPERSAND | DIF_LISTWRAPMODE, L""}, + {DI_TEXT, 0, 4, 0, 4, {}, DIF_SEPARATOR, L""}, + + {DI_BUTTON, 30, 5, 36, 5, {}, DIF_CENTERGROUP | DIF_BTNNOCLOSE, Msg::DirSettingsApply}, + + {DI_CHECKBOX, 5, 6, 20, 6, {}, DIF_AUTOMATION, Msg::DirSettingsCenter}, + {DI_CHECKBOX, 5, 7, 20, 7, {}, DIF_AUTOMATION, Msg::DirSettingsSurround}, + + {DI_COMBOBOX, 10, 8, 26, 8, {}, DIF_DROPDOWNLIST | DIF_LISTNOAMPERSAND | DIF_LISTWRAPMODE, L""}, + + {DI_TEXT, 0, 9, 0, 9, {}, DIF_SEPARATOR, L""}, + {DI_BUTTON, 0, 10, 0, 10, {}, DIF_DEFAULT | DIF_CENTERGROUP, Msg::Ok}, + {DI_BUTTON, 0, 10, 0, 10, {}, DIF_CENTERGROUP, Msg::Cancel}, + }; + + MakeDialogItemsEx(DirCfgDlgData, DirCfgDlg); + + dircfg_data.DirNameStyle = Opt.DirNameStyle & 3; + dircfg_data.SurrIndex = (Opt.DirNameStyle >> 2) & 3; + dircfg_data.bCentered = (Opt.DirNameStyle & DIRNAME_STYLE_CENTERED); + dircfg_data.bSurr = (Opt.DirNameStyle & DIRNAME_STYLE_SURR_CH); + + DirCfgDlg[ID_DIRCFG_CHECKBOX_CENTER].Selected = dircfg_data.bCentered; + DirCfgDlg[ID_DIRCFG_CHECKBOX_SURR].Selected = dircfg_data.bSurr; + + if (!dircfg_data.bSurr) + DirCfgDlg[ID_DIRCFG_SURR_COMBO].Flags |= DIF_DISABLE; + + Dialog Dlg(DirCfgDlg, ARRAYSIZE(DirCfgDlg), DirCfgDlgProc, (LONG_PTR)&dircfg_data); + + int dialogsizex = 50; + int dialogsizey = 13; + Dlg.SetPosition(-1, -1, dialogsizex, dialogsizey); + Dlg.SetAutomation(ID_DIRCFG_CHECKBOX_SURR, ID_DIRCFG_SURR_COMBO, DIF_DISABLE, DIF_NONE, DIF_NONE, DIF_DISABLE); + + Dlg.Process(); + int ExitCode = Dlg.GetExitCode(); + + if (ExitCode == ID_DIRCFG_BUTTON_OK) { + Opt.DirNameStyle = dircfg_data.DirNameStyle; + Opt.DirNameStyle |= (dircfg_data.SurrIndex << 2); + Opt.DirNameStyle |= DIRNAME_STYLE_CENTERED * dircfg_data.bCentered; + Opt.DirNameStyle |= DIRNAME_STYLE_SURR_CH * dircfg_data.bSurr; + + UpdateDefaultColumnTypeWidths( ); + CtrlObject->Cp()->LeftPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->RightPanel->Update(UPDATE_KEEP_SELECTION); + CtrlObject->Cp()->Redraw(); + } +} + + void InputSettings() { const DWORD supported_tweaks = ApplyConsoleTweaks(); diff --git a/far2l/src/cfg/config.hpp b/far2l/src/cfg/config.hpp index 59df68981..482a0f473 100644 --- a/far2l/src/cfg/config.hpp +++ b/far2l/src/cfg/config.hpp @@ -663,3 +663,4 @@ void SetFolderInfoFiles(); void InfoPanelSettings(); void AutoCompleteSettings(); void LanguageSettings(); +void DirectoryNameSettings(); diff --git a/far2l/src/cmdline.cpp b/far2l/src/cmdline.cpp index 8292f7ad1..ec8813479 100644 --- a/far2l/src/cmdline.cpp +++ b/far2l/src/cmdline.cpp @@ -869,9 +869,10 @@ void CommandLine::SaveBackground() } else fprintf(stderr, "CommandLine::SaveBackground: no BackgroundScreen\n"); } -void CommandLine::ShowBackground() + +void CommandLine::ShowBackground(bool showanyway) { - if (!IsVisible()) + if (!IsVisible() && !showanyway) return; if (BackgroundScreen) { diff --git a/far2l/src/cmdline.hpp b/far2l/src/cmdline.hpp index 2cda5dafc..1fd124b01 100644 --- a/far2l/src/cmdline.hpp +++ b/far2l/src/cmdline.hpp @@ -130,7 +130,7 @@ class CommandLine : public ScreenObject void SaveBackground(int X1, int Y1, int X2, int Y2); void SaveBackground(); - void ShowBackground(); + void ShowBackground(bool showanyway = false); void CorrectRealScreenCoord(); void LockUpdatePanel(int Mode) { Flags.Change(FCMDOBJ_LOCKUPDATEPANEL, Mode); }; diff --git a/far2l/src/console/interf.cpp b/far2l/src/console/interf.cpp index 07fe16b95..11523d017 100644 --- a/far2l/src/console/interf.cpp +++ b/far2l/src/console/interf.cpp @@ -510,7 +510,22 @@ void Text(const WCHAR Ch, uint64_t Color, size_t Length) if ( !Length ) return; - ScrBuf.FillRect(CurX, CurY, CurX + Length, CurY, Ch, Color); + int X1 = CurX; + int Y1 = CurY; + int X2 = CurX + Length; + int Y2 = CurY; + + if (X1 < 0) + X1 = 0; + if (Y1 < 0) + Y1 = 0; + + if (X2 > ScrX) + X2 = ScrX; + if (Y2 > ScrY) + Y2 = ScrY; + + ScrBuf.FillRect(X1, Y1, X2, Y2, Ch, Color); CurX += Length; } diff --git a/far2l/src/filefilterparams.cpp b/far2l/src/filefilterparams.cpp index ca10c8bbc..a0195da00 100644 --- a/far2l/src/filefilterparams.cpp +++ b/far2l/src/filefilterparams.cpp @@ -413,7 +413,7 @@ void FillPreviewStr(wchar_t *dstStr, size_t dstsize, const wchar_t *srcStr, cons } #endif -void FillAttrStr(wchar_t *AttrStr, size_t truncatelen, uint32_t IncludeAttr, uint32_t ExcludeAttr, uint32_t style) +void FillAttrStr(wchar_t *AttrStr, uint32_t IncludeAttr, uint32_t ExcludeAttr, uint32_t style) { static const wchar_t AttrC[] = L"RAHSD truncatelen - 1) { - AttrStr[truncatelen - 1] = L'…'; - AttrStr[truncatelen] = 0; - return; + while(Ptr < (AttrStr + 23)) { + *Ptr++ = 32; } - + *Ptr = 0; } else { for (size_t i = 0; i < ARRAYSIZE(AttrF); i++) { @@ -466,13 +463,8 @@ void FillAttrStr(wchar_t *AttrStr, size_t truncatelen, uint32_t IncludeAttr, uin *Ptr = *(Ptr + 1) = L'.'; } Ptr += ARRAYSIZE(AttrF) * 2; + *Ptr = 0; } - - while(Ptr < (AttrStr + truncatelen)) { - *Ptr++ = 32; - } - - AttrStr[truncatelen] = 0; } // Централизованная функция для создания строк меню различных фильтров. @@ -525,8 +517,8 @@ void MenuString(FARString &strDest, FileFilterParams *FF, uint32_t attrstyle, bo wchar_t Attr[64]; switch(attrstyle) { - case 0: FillAttrStr(Attr, 38, IncludeAttr, ExcludeAttr, attrstyle); break; - case 1: FillAttrStr(Attr, 16, IncludeAttr, ExcludeAttr, attrstyle); break; + case 0: FillAttrStr(Attr, IncludeAttr, ExcludeAttr, attrstyle); break; + case 1: FillAttrStr(Attr, IncludeAttr, ExcludeAttr, attrstyle); break; } wchar_t SizeDate[4] = L"..."; @@ -718,14 +710,16 @@ LONG_PTR WINAPI FileFilterConfigDlgProc(HANDLE hDlg, int Msg, int Param1, LONG_P static const DWORD FarColor[] = {COL_PANELTEXT, COL_PANELSELECTEDTEXT, COL_PANELCURSOR, COL_PANELSELECTEDCURSOR}; wchar_t VerticalLine0[] = {BoxSymbols[BS_V2], 0}; wchar_t VerticalLine1[] = {BoxSymbols[BS_V1], 0}; + SMALL_RECT drect; + SMALL_RECT irect; - union { SMALL_RECT drect; uint64_t i64drect; }; - union { SMALL_RECT irect; uint64_t i64irect; }; SendDlgMessage(hDlg, DM_GETDLGRECT, 0, (intptr_t)&drect); - drect.Right = drect.Left; - drect.Bottom = drect.Top; SendDlgMessage(hDlg, DM_GETITEMPOSITION, ID_HER_COLOREXAMPLE, (intptr_t)&irect); - i64irect += i64drect; + + irect.Top += drect.Top; + irect.Bottom += drect.Top; + irect.Right += drect.Left; + irect.Left += drect.Left; HighlightDataColor *hl = &fphlstate->hl; size_t filenameexamplelen = wcslen(Msg::HighlightExample1); diff --git a/far2l/src/filepanels.cpp b/far2l/src/filepanels.cpp index 0a7765d72..03639014b 100644 --- a/far2l/src/filepanels.cpp +++ b/far2l/src/filepanels.cpp @@ -219,7 +219,7 @@ void FilePanels::UpdateCmdLineVisibility(bool repos) int left_x1, left_x2, left_y1, left_y2; int right_x1, right_x2, right_y1, right_y2; int cl_x1, cl_x2, cl_y; - bool cl_visible = CtrlObject->CmdLine->IsVisible(); + bool cl_visible = CtrlObject->CmdLine->IsVisible(), new_cl_visible; LeftPanel->GetPosition(left_x1, left_y1, left_x2, left_y2); RightPanel->GetPosition(right_x1, right_y1, right_x2, right_y2); @@ -227,8 +227,11 @@ void FilePanels::UpdateCmdLineVisibility(bool repos) const bool left_overlap = LeftPanel->IsVisible() && left_y2 + Opt.ShowKeyBar >= ScrY; const bool right_overlap = RightPanel->IsVisible() && right_y2 + Opt.ShowKeyBar >= ScrY; -// const bool new_cl_visible = !left_overlap || !right_overlap; - const bool new_cl_visible = !left_overlap && !right_overlap; + + if (!Opt.PanelsDisposition) + new_cl_visible = !left_overlap || !right_overlap; + else + new_cl_visible = !left_overlap && !right_overlap; int new_cl_x1 = 0, new_cl_x2 = ScrX - 1, new_cl_y = ScrY - (Opt.ShowKeyBar); if (new_cl_visible) { @@ -245,6 +248,7 @@ void FilePanels::UpdateCmdLineVisibility(bool repos) if (cl_repos || repos) { CtrlObject->CmdLine->SetPosition(new_cl_x1, new_cl_y, new_cl_x2, new_cl_y); } + if (cl_visible != new_cl_visible || cl_repos || repos) { if (new_cl_visible) { CtrlObject->CmdLine->Redraw(); @@ -292,18 +296,44 @@ void FilePanels::SetPanelPositions(int LeftFullScreen, int RightFullScreen, int } else if (Disposition == 1) { /// horizontal panels + LeftPanel->ViewSettings.FullScreen = 0; + RightPanel->ViewSettings.FullScreen = 0; + Opt.LeftHeightDecrement = Max(-1, Min(Opt.LeftHeightDecrement, ScrY - 13)); Opt.RightHeightDecrement = Max(-1, Min(Opt.RightHeightDecrement, ScrY - 13)); +#if 0 + const bool bRightPanelVisible = RightPanel->IsVisible(); + const bool bLeftPanelVisible = LeftPanel->IsVisible(); + + if (bRightPanelVisible) { + if (Opt.WidthDecrement < -((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) + Opt.WidthDecrement = -((ScrY - Opt.LeftHeightDecrement) / 2 - 6); + } + else { + if (Opt.WidthDecrement < -((ScrY - Opt.LeftHeightDecrement) / 2)) + Opt.WidthDecrement = -((ScrY - Opt.LeftHeightDecrement) / 2); + } + if (bLeftPanelVisible) { + if (Opt.WidthDecrement > ((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) + Opt.WidthDecrement = ((ScrY - Opt.LeftHeightDecrement) / 2 - 6); + } + else { + if (Opt.WidthDecrement > ((ScrY - Opt.LeftHeightDecrement) / 2)) + Opt.WidthDecrement = ((ScrY - Opt.LeftHeightDecrement) / 2); + } +#else if (Opt.WidthDecrement < -((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) Opt.WidthDecrement = -((ScrY - Opt.LeftHeightDecrement) / 2 - 6); if (Opt.WidthDecrement > ((ScrY - Opt.LeftHeightDecrement) / 2 - 6)) Opt.WidthDecrement = ((ScrY - Opt.LeftHeightDecrement) / 2 - 6); +#endif const int LeftY2 = (ScrY - Opt.ShowMenuBar) / 2 - (Opt.ShowKeyBar) - Opt.LeftHeightDecrement / 2; - const int RightY2 = ScrY - (Opt.ShowKeyBar) - 1 - Opt.RightHeightDecrement; + int RightY2 = ScrY - (Opt.ShowKeyBar) - 1 - Opt.RightHeightDecrement; +#if 0 if (LeftFullScreen) { LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2); LeftPanel->ViewSettings.FullScreen = 1; @@ -315,8 +345,17 @@ void FilePanels::SetPanelPositions(int LeftFullScreen, int RightFullScreen, int RightPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, RightY2); RightPanel->ViewSettings.FullScreen = 1; } else { + if (RightY2 - 5 < LeftY2 + 1 - Opt.WidthDecrement) + RightY2 = LeftY2 + 1 - Opt.WidthDecrement + 5; RightPanel->SetPosition(0, LeftY2 + 1 - Opt.WidthDecrement, ScrX, RightY2); } +#else + LeftPanel->SetPosition(0, Opt.ShowMenuBar ? 1 : 0, ScrX, LeftY2 - Opt.WidthDecrement ); + + if (RightY2 - 5 < LeftY2 + 1 - Opt.WidthDecrement) + RightY2 = LeftY2 + 1 - Opt.WidthDecrement + 5; + RightPanel->SetPosition(0, LeftY2 + 1 - Opt.WidthDecrement, ScrX, RightY2); +#endif } UpdateCmdLineVisibility(true); @@ -687,6 +726,7 @@ int FilePanels::ProcessKey(FarKey Key) break; } +// case KEY_CTRLALTUP: case KEY_CTRLSHIFTUP: case KEY_CTRLSHIFTNUMPAD8: { int &HeightDecrement = @@ -699,6 +739,7 @@ int FilePanels::ProcessKey(FarKey Key) break; } +// case KEY_CTRLALTDOWN: case KEY_CTRLSHIFTDOWN: case KEY_CTRLSHIFTNUMPAD2: { int &HeightDecrement = @@ -1004,7 +1045,7 @@ void FilePanels::DisplayObject() // if ( !Focus ) // return; _OT(SysLog(L"[%p] FilePanels::Redraw() {%d, %d - %d, %d}", this, X1, Y1, X2, Y2)); - CtrlObject->CmdLine->ShowBackground(); + CtrlObject->CmdLine->ShowBackground( (bool)(Opt.PanelsDisposition) ); if (Opt.ShowMenuBar) CtrlObject->TopMenuBar->Show(); diff --git a/far2l/src/mix/panelmix.cpp b/far2l/src/mix/panelmix.cpp index fe71f4c0f..b2af7123e 100644 --- a/far2l/src/mix/panelmix.cpp +++ b/far2l/src/mix/panelmix.cpp @@ -78,13 +78,12 @@ static const wchar_t *ColumnSymbol[] = {L"N", L"S", L"P", L"D", L"T", L"DM", L"D L"O", L"U", L"LN", L"F", L"G", L"C0", L"C1", L"C2", L"C3", L"C4", L"C5", L"C6", L"C7", L"C8", L"C9", L"C10", L"C11", L"C12", L"C13", L"C14", L"C15", L"C16", L"C17", L"C18", L"C19"}; -static const FarLangMsg DirUpNames[4] = {Msg::DirUp, Msg::DirUp2, Msg::DirUp3, Msg::DirUp4}; -static const FarLangMsg DirNames[4] = {Msg::DirName, Msg::DirName2, Msg::DirName3, Msg::DirName4}; -static const FarLangMsg SymLinkNames[4] = {Msg::SymLinkName, Msg::SymLinkName2, Msg::SymLinkName3, Msg::SymLinkName4}; -static const FarLangMsg JunctionNames[4] = {Msg::JunctionName, Msg::JunctionName2, Msg::JunctionName3, Msg::JunctionName4}; - -static const wchar_t surdircharleft[4] = { 60, 16, 61, 32 }; -static const wchar_t surdircharright[4] = { 62, 17, 61, 32 }; +FarLangMsg DirUpNames[4] = {Msg::DirUp, Msg::DirUp2, Msg::DirUp3, Msg::DirUp4}; +FarLangMsg DirNames[4] = {Msg::DirName, Msg::DirName2, Msg::DirName3, Msg::DirName4}; +FarLangMsg SymLinkNames[4] = {Msg::SymLinkName, Msg::SymLinkName2, Msg::SymLinkName3, Msg::SymLinkName4}; +FarLangMsg JunctionNames[4] = {Msg::JunctionName, Msg::JunctionName2, Msg::JunctionName3, Msg::JunctionName4}; +wchar_t surdircharleft[4] = { 60, 16, 61, 32 }; +wchar_t surdircharright[4] = { 62, 17, 61, 32 }; void UpdateDefaultColumnTypeWidths( void ) { diff --git a/far2l/src/mix/panelmix.hpp b/far2l/src/mix/panelmix.hpp index 9063e6153..fd533e8eb 100644 --- a/far2l/src/mix/panelmix.hpp +++ b/far2l/src/mix/panelmix.hpp @@ -49,6 +49,13 @@ void TextToViewSettings(const wchar_t *ColumnTitles, const wchar_t *ColumnWidths void ViewSettingsToText(unsigned int *ViewColumnTypes, int *ViewColumnWidths, int *ViewColumnWidthsTypes, int ColumnCount, FARString &strColumnTitles, FARString &strColumnWidths); +extern FarLangMsg DirUpNames[4]; +extern FarLangMsg DirNames[4]; +extern FarLangMsg SymLinkNames[4]; +extern FarLangMsg JunctionNames[4]; +extern wchar_t surdircharleft[4]; +extern wchar_t surdircharright[4]; + #define DIRNAME_STYLE_SURR_CH 0x10 #define DIRNAME_STYLE_CENTERED 0x20 diff --git a/far2l/src/panels/filelist.cpp b/far2l/src/panels/filelist.cpp index 149c592e6..4c4dbbf6b 100644 --- a/far2l/src/panels/filelist.cpp +++ b/far2l/src/panels/filelist.cpp @@ -1249,13 +1249,15 @@ int FileList::ProcessKey(FarKey Key) } case KEY_CTRLD | KEY_ALT: { - ++Opt.DirNameStyle &= 63; - UpdateDefaultColumnTypeWidths( ); - UpdateAutoColumnWidth(); - Redraw(); - Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); - AnotherPanel->Update(UPDATE_KEEP_SELECTION); - AnotherPanel->Redraw(); + DirectoryNameSettings( ); + +// ++Opt.DirNameStyle &= 63; +// UpdateDefaultColumnTypeWidths( ); +// UpdateAutoColumnWidth(); +// Redraw(); +// Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); +// AnotherPanel->Update(UPDATE_KEEP_SELECTION); +// AnotherPanel->Redraw(); return TRUE; } From 81eb26a17df23d40e04b25d235c56348fe192a4d Mon Sep 17 00:00:00 2001 From: anta999 Date: Thu, 24 Oct 2024 02:30:44 +0400 Subject: [PATCH 06/30] fixed #2461 Garbage in the terminal + DirCfg Dialog Update fixed #2461 Garbage in the terminal after running menu command with hidden command line Updated DirName Config Dialog --- far2l/src/cfg/config.cpp | 25 ++++++++++++------------- far2l/src/execute.cpp | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/far2l/src/cfg/config.cpp b/far2l/src/cfg/config.cpp index b0bc881fd..d88d7eba6 100644 --- a/far2l/src/cfg/config.cpp +++ b/far2l/src/cfg/config.cpp @@ -276,7 +276,6 @@ enum enumDirCfgDialog ID_DIRCFG_STYLE_TEXT, ID_DIRCFG_STYLE_COMBO, ID_DIRCFG_SEPARATOR, - ID_DIRCFG_BUTTON_APPLY, ID_DIRCFG_CHECKBOX_CENTER, ID_DIRCFG_CHECKBOX_SURR, @@ -285,7 +284,8 @@ enum enumDirCfgDialog ID_DIRCFG_SEPARATOR2, ID_DIRCFG_BUTTON_OK, ID_DIRCFG_BUTTON_RESTORE, - ID_DIRCFG_BUTTON_CANCEL + ID_DIRCFG_BUTTON_CANCEL, + ID_DIRCFG_BUTTON_APPLY, }; typedef struct dircfg_data_s { @@ -390,21 +390,20 @@ void DirectoryNameSettings() dircfg_data_t dircfg_data; DialogDataEx DirCfgDlgData[] = { - {DI_DOUBLEBOX, 3, 1, 46, 11, {}, 0, Msg::DirSettingsTitle}, + {DI_DOUBLEBOX, 3, 1, 47, 10, {}, 0, Msg::DirSettingsTitle}, {DI_TEXT, 5, 2, 35, 2, {}, 0, Msg::DirSettingsShowAs}, {DI_COMBOBOX, 5, 3, 5+40, 3, {}, DIF_DROPDOWNLIST | DIF_LISTNOAMPERSAND | DIF_LISTWRAPMODE, L""}, {DI_TEXT, 0, 4, 0, 4, {}, DIF_SEPARATOR, L""}, - {DI_BUTTON, 30, 5, 36, 5, {}, DIF_CENTERGROUP | DIF_BTNNOCLOSE, Msg::DirSettingsApply}, - - {DI_CHECKBOX, 5, 6, 20, 6, {}, DIF_AUTOMATION, Msg::DirSettingsCenter}, - {DI_CHECKBOX, 5, 7, 20, 7, {}, DIF_AUTOMATION, Msg::DirSettingsSurround}, + {DI_CHECKBOX, 5, 5, 20, 5, {}, DIF_AUTOMATION, Msg::DirSettingsCenter}, + {DI_CHECKBOX, 5, 6, 20, 6, {}, DIF_AUTOMATION, Msg::DirSettingsSurround}, + {DI_COMBOBOX, 9, 7, 26, 7, {}, DIF_DROPDOWNLIST | DIF_LISTNOAMPERSAND | DIF_LISTWRAPMODE, L""}, - {DI_COMBOBOX, 10, 8, 26, 8, {}, DIF_DROPDOWNLIST | DIF_LISTNOAMPERSAND | DIF_LISTWRAPMODE, L""}, + {DI_TEXT, 0, 8, 0, 8, {}, DIF_SEPARATOR, L""}, + {DI_BUTTON, 0, 9, 0, 9, {}, DIF_DEFAULT | DIF_CENTERGROUP, Msg::Ok}, + {DI_BUTTON, 0, 9, 0, 9, {}, DIF_CENTERGROUP, Msg::Cancel}, + {DI_BUTTON, 0, 9, 0, 9, {}, DIF_CENTERGROUP | DIF_BTNNOCLOSE, Msg::DirSettingsApply}, - {DI_TEXT, 0, 9, 0, 9, {}, DIF_SEPARATOR, L""}, - {DI_BUTTON, 0, 10, 0, 10, {}, DIF_DEFAULT | DIF_CENTERGROUP, Msg::Ok}, - {DI_BUTTON, 0, 10, 0, 10, {}, DIF_CENTERGROUP, Msg::Cancel}, }; MakeDialogItemsEx(DirCfgDlgData, DirCfgDlg); @@ -422,8 +421,8 @@ void DirectoryNameSettings() Dialog Dlg(DirCfgDlg, ARRAYSIZE(DirCfgDlg), DirCfgDlgProc, (LONG_PTR)&dircfg_data); - int dialogsizex = 50; - int dialogsizey = 13; + int dialogsizex = 51; + int dialogsizey = 12; Dlg.SetPosition(-1, -1, dialogsizex, dialogsizey); Dlg.SetAutomation(ID_DIRCFG_CHECKBOX_SURR, ID_DIRCFG_SURR_COMBO, DIF_DISABLE, DIF_NONE, DIF_NONE, DIF_DISABLE); diff --git a/far2l/src/execute.cpp b/far2l/src/execute.cpp index c51b46812..8f521540c 100644 --- a/far2l/src/execute.cpp +++ b/far2l/src/execute.cpp @@ -253,7 +253,7 @@ class FarExecuteScope { ProcessShowClock++; if (CtrlObject && CtrlObject->CmdLine) { - CtrlObject->CmdLine->ShowBackground(); + CtrlObject->CmdLine->ShowBackground(true); CtrlObject->CmdLine->RedrawWithoutComboBoxMark(); } // CtrlObject->CmdLine->SetString(L"", TRUE); From 82aa9c8ab560c5806c16e38d4a4cad79adf87075 Mon Sep 17 00:00:00 2001 From: anta999 Date: Fri, 25 Oct 2024 17:59:48 +0400 Subject: [PATCH 07/30] MaskGroup updated --- far2l/bootstrap/scripts/farlang.templ.m4 | 61 ++++++-- far2l/src/cfg/ConfigOpt.cpp | 3 + far2l/src/cfg/MaskGroups.cpp | 170 ++++++++++++++++++++--- far2l/src/cfg/MaskGroups.hpp | 1 + far2l/src/cfg/config.cpp | 1 - far2l/src/console/palette.cpp | 4 +- far2l/src/filefilter.cpp | 21 +++ far2l/src/filefilter.hpp | 1 + far2l/src/panels/filelist.cpp | 2 +- far2l/src/vmenu.hpp | 3 +- 10 files changed, 236 insertions(+), 31 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 4c964b02a..07b73336e 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -1532,6 +1532,17 @@ upd:"Groups of file masks" "Групи масок файлів" "Суполкі масак файлаў" +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:" @@ -1565,16 +1576,50 @@ MaskGroupAskDelete "Ви бажаєте видалити" "Вы жадаеце выдаліць" +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 wish to restore default mask sets?" -"Přejete si obnovit výchozí sestavy masek?" -"Wollen Sie voreingestellte Maskensets zurückstellen?" -upd:"Do you wish to restore default mask sets?" -"Chcesz przywrócić domyślne ustawienia masek?" -"Quiere restablecer por defecto máscaras?" -"Ви бажаєте відновити набори масок за замовчуванням?" -"Вы жадаеце узнавіць прадвызначаны набор масак?" +"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: diff --git a/far2l/src/cfg/ConfigOpt.cpp b/far2l/src/cfg/ConfigOpt.cpp index 539675f89..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(); @@ -740,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/MaskGroups.cpp b/far2l/src/cfg/MaskGroups.cpp index 3d6a82099..a2569fd8d 100644 --- a/far2l/src/cfg/MaskGroups.cpp +++ b/far2l/src/cfg/MaskGroups.cpp @@ -20,32 +20,71 @@ Groups of file masks #include "vmenu.hpp" #include "MaskGroups.hpp" -/* -MMaskGroupRestore -MMaskGroupFindMask -MMaskGroupTotal -======================================== - -MaskGroupRestore -"Вы хотите восстановить наборы масок по умолчанию?" -"Do you wish to restore default mask sets?" -*/ - static const wchar_t *Help = L"MaskGroupsSettings"; struct FileMaskStrings { - const char *TypeFmt, *Type0, *MaskName, *MaskValue; + 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",_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/man/far2l.1 b/man/far2l.1 index a2faccc3c..a9e1e215b 100644 --- a/man/far2l.1 +++ b/man/far2l.1 @@ -1,6 +1,6 @@ .\" -*- mode: troff; coding: UTF-8 -*- .\"TOPICS "Topics:" -.TH FAR2L 1 "October 2024" "FAR2L Version 2.6.4" "Linux fork of FAR Manager v2" +.TH FAR2L 1 "November 2024" "FAR2L Version 2.6.4" "Linux fork of FAR Manager v2" .\"SKIP_SECTION" .SH "NAME" far2l \- Two-panel file manager, with built\-in terminal and other usefulness\'es. diff --git a/man/ru/far2l.1 b/man/ru/far2l.1 index c454899f5..50c2b8009 100644 --- a/man/ru/far2l.1 +++ b/man/ru/far2l.1 @@ -1,6 +1,6 @@ .\" -*- mode: troff; coding: UTF-8 -*- .\"TOPICS "Topics:" -.TH FAR2L 1 "October 2024" "FAR2L Version 2.6.4" "Linux fork of FAR Manager v2" +.TH FAR2L 1 "November 2024" "FAR2L Version 2.6.4" "Linux fork of FAR Manager v2" .\"SKIP_SECTION" .SH "НАИМЕНОВАНИЕ" far2l \- Двухпанельный файловый менеджер, работающий в текстовом режиме, со встроенным терминалом и другими полезными функциями. From 0c90dff3dd6484d55002d54992fa9d0d3d42131a Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Sat, 16 Nov 2024 09:12:35 +0300 Subject: [PATCH 13/30] rough mention of last year's changes in far2l/far2sdk/farplug-wide.h --- HACKING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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. From 429c4385530ea00dcba80fc3c4c2a443e62e1183 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 16 Nov 2024 22:58:01 +0400 Subject: [PATCH 14/30] fix tmppanel: change %s to %ls --- tmppanel/configs/plug/TmpBel.lng | 2 +- tmppanel/configs/plug/TmpEng.lng | 2 +- tmppanel/configs/plug/TmpRus.lng | 2 +- tmppanel/src/TmpClass.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tmppanel/configs/plug/TmpBel.lng b/tmppanel/configs/plug/TmpBel.lng index 557427e9a..1af674811 100644 --- a/tmppanel/configs/plug/TmpBel.lng +++ b/tmppanel/configs/plug/TmpBel.lng @@ -6,7 +6,7 @@ "Папярэджанне" "Часовая панэль" -" %sЧасовая панэль [%d] " +" %lsЧасовая панэль [%d] " "часовая" diff --git a/tmppanel/configs/plug/TmpEng.lng b/tmppanel/configs/plug/TmpEng.lng index 50dbde1b0..62a0a95ad 100644 --- a/tmppanel/configs/plug/TmpEng.lng +++ b/tmppanel/configs/plug/TmpEng.lng @@ -6,7 +6,7 @@ "Warning" "Temporary panel" -" %sTemporary panel [%d] " +" %lsTemporary panel [%d] " "temporary" diff --git a/tmppanel/configs/plug/TmpRus.lng b/tmppanel/configs/plug/TmpRus.lng index da21bc7e0..a09ce77de 100644 --- a/tmppanel/configs/plug/TmpRus.lng +++ b/tmppanel/configs/plug/TmpRus.lng @@ -6,7 +6,7 @@ "Предупреждение" "Временная панель" -" %sВременная панель [%d] " +" %lsВременная панель [%d] " "временная" diff --git a/tmppanel/src/TmpClass.cpp b/tmppanel/src/TmpClass.cpp index 5ab379928..66492ba5c 100644 --- a/tmppanel/src/TmpClass.cpp +++ b/tmppanel/src/TmpClass.cpp @@ -58,7 +58,7 @@ void TmpPanel::GetOpenPluginInfo(struct OpenPluginInfo *Info) if (StartupOptCommonPanel) FSF.snprintf(Title, ARRAYSIZE(Title) - 1, GetMsg(MTempPanelTitleNum), PANEL_MODE, PanelIndex); else - FSF.snprintf(Title, ARRAYSIZE(Title) - 1, _T(" %s%s "), PANEL_MODE, GetMsg(MTempPanel)); + FSF.snprintf(Title, ARRAYSIZE(Title) - 1, _T(" %ls%ls "), PANEL_MODE, GetMsg(MTempPanel)); #undef PANEL_MODE Info->PanelTitle = Title; @@ -728,7 +728,7 @@ void TmpPanel::ProcessPanelSwitchMenu() else if (i < 36) FSF.snprintf(_OUT, sizeof(_OUT) - 1, fmt1, _T('A') - 10 + i, txt, CommonPanels[i].ItemsNumber); else - FSF.snprintf(_OUT, sizeof(_OUT) - 1, _T(" %s %d"), txt, CommonPanels[i].ItemsNumber); + FSF.snprintf(_OUT, sizeof(_OUT) - 1, _T(" %ls %d"), txt, CommonPanels[i].ItemsNumber); #undef _OUT } fmi[PanelIndex].Selected = TRUE; From 4369fb07405b2e81e0a4d92e6dcf1f44aea86bd1 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 00:38:13 +0300 Subject: [PATCH 15/30] fix build under macos elcapitan --- colorer/CMakeLists.txt | 5 ++- .../src/Colorer-library/src/CMakeLists.txt | 2 +- .../src/Colorer-library/src/colorer/Common.h | 6 +++ .../src/colorer/base/BaseNames.h | 3 +- .../src/colorer/base/XmlTagDefs.h | 2 - .../src/colorer/common/Logger.h | 8 ++++ .../src/colorer/xml/libxml2/LibXmlReader.cpp | 2 +- colorer/src/pcolorer2/CerrLogger.cpp | 41 +++++++++++++++++++ colorer/src/pcolorer2/CerrLogger.h | 39 ++---------------- multiarc/src/formats/7z/C/Aes.c | 2 +- multiarc/src/formats/7z/C/AesOpt.c | 4 +- multiarc/src/formats/rar/unrar/rijndael.cpp | 2 + multiarc/src/formats/rar/unrar/system.cpp | 4 +- 13 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 colorer/src/pcolorer2/CerrLogger.cpp 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/multiarc/src/formats/7z/C/Aes.c b/multiarc/src/formats/7z/C/Aes.c index abc5d24b4..6d06f9429 100644 --- a/multiarc/src/formats/7z/C/Aes.c +++ b/multiarc/src/formats/7z/C/Aes.c @@ -69,7 +69,7 @@ static Byte InvS[256]; #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) #define USE_HW_AES - #if defined(__clang__) && (__clang_major__ >= 8) \ + #if defined(__clang__) && (__clang_major__ >= 9) \ || defined(__GNUC__) && (__GNUC__ >= 8) #define USE_HW_VAES #endif diff --git a/multiarc/src/formats/7z/C/AesOpt.c b/multiarc/src/formats/7z/C/AesOpt.c index 58769ea05..5a9486bee 100644 --- a/multiarc/src/formats/7z/C/AesOpt.c +++ b/multiarc/src/formats/7z/C/AesOpt.c @@ -21,7 +21,7 @@ #if !defined(__AES__) #define ATTRIB_AES __attribute__((__target__("aes"))) #endif - #if defined(__clang__) && (__clang_major__ >= 8) \ + #if defined(__clang__) && (__clang_major__ >= 9) \ || defined(__GNUC__) && (__GNUC__ >= 8) #define USE_INTEL_VAES #if !defined(__AES__) || !defined(__VAES__) || !defined(__AVX__) || !defined(__AVX2__) @@ -351,7 +351,6 @@ AES_FUNC_START2 (AesCtr_Code_HW) } - #ifdef USE_INTEL_VAES /* @@ -665,6 +664,7 @@ VAES_COMPAT_STUB (AesCtr_Code_HW) 13.0.1 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_AES) 16 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 */ + #if defined(__clang__) && __clang_major__ < 16 #if !defined(__ARM_FEATURE_AES) && \ !defined(__ARM_FEATURE_CRYPTO) diff --git a/multiarc/src/formats/rar/unrar/rijndael.cpp b/multiarc/src/formats/rar/unrar/rijndael.cpp index 8707b5784..688719c79 100644 --- a/multiarc/src/formats/rar/unrar/rijndael.cpp +++ b/multiarc/src/formats/rar/unrar/rijndael.cpp @@ -112,7 +112,9 @@ void Rijndael::Init(bool Encrypt,const byte *key,uint keyLen,const byte * initVe else AES_NI=false; #elif defined(__GNUC__) +# if !defined(__clang__) || (__clang_major__ >= 9) // ElCapinal's XCode: "error: invalid cpu feature string for builtin" AES_NI=__builtin_cpu_supports("aes"); +# endif #endif #elif defined(USE_NEON_AES) diff --git a/multiarc/src/formats/rar/unrar/system.cpp b/multiarc/src/formats/rar/unrar/system.cpp index cf9d1836e..746d335d4 100644 --- a/multiarc/src/formats/rar/unrar/system.cpp +++ b/multiarc/src/formats/rar/unrar/system.cpp @@ -213,12 +213,12 @@ SSE_VERSION GetSSEVersion() if ((CPUInfo[3] & 0x2000000)!=0) return SSE_SSE; } -#elif defined(__GNUC__) +#elif defined(__GNUC__) && (!defined(__clang__) || (__clang_major__ >= 9)) if (__builtin_cpu_supports("avx2")) return SSE_AVX2; if (__builtin_cpu_supports("sse4.1")) return SSE_SSE41; - if (__builtin_cpu_supports("ssse3")) + if (__builtin_cpu_supports("sse3")) return SSE_SSSE3; if (__builtin_cpu_supports("sse2")) return SSE_SSE2; From 34abc8a8793bf0e15597b13f6ab66a8f4d17eecf Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Sun, 17 Nov 2024 10:13:57 +0300 Subject: [PATCH 16/30] Help minor in HighlightList --- far2l/bootstrap/scripts/FarEng.hlf.m4 | 4 +++- far2l/bootstrap/scripts/FarHun.hlf.m4 | 4 +++- far2l/bootstrap/scripts/FarRus.hlf.m4 | 4 +++- far2l/bootstrap/scripts/FarUkr.hlf.m4 | 3 ++- 4 files changed, 11 insertions(+), 4 deletions(-) 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 From 2c766bd5742b92e531c7f8d0988ba57a83eb7055 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 11:00:44 +0300 Subject: [PATCH 17/30] fix kitty dup keys (fix #2503) --- far2l/src/vt/vtshell_translation_kitty.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/far2l/src/vt/vtshell_translation_kitty.cpp b/far2l/src/vt/vtshell_translation_kitty.cpp index 142184255..fbf522019 100644 --- a/far2l/src/vt/vtshell_translation_kitty.cpp +++ b/far2l/src/vt/vtshell_translation_kitty.cpp @@ -7,6 +7,14 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) const bool ctrl = (KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) != 0; const bool alt = (KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) != 0; const bool shift = (KeyEvent.dwControlKeyState & (SHIFT_PRESSED)) != 0; + + std::string out; + if (!(flags & 8) && KeyEvent.uChar.UnicodeChar && !alt && !ctrl) { // "Report all keys as escape codes" disabled + // just send text + Wide2MB(&KeyEvent.uChar.UnicodeChar, 1, out); + return out; + } + // References: // https://sw.kovidgoyal.net/kitty/keyboard-protocol/ // https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes @@ -145,7 +153,7 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) if (!keycode) return std::string(); - std::string out = "\x1B["; // Старт последовательности + out = "\x1B["; // Старт последовательности // Добавляем значение keycode out+= std::to_string(keycode); @@ -193,10 +201,5 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) // Добавляем значение suffix out+= suffix; - if (!(flags & 8) && KeyEvent.uChar.UnicodeChar && !alt && !ctrl) { // "Report all keys as escape codes" disabled - // just send text - Wide2MB(&KeyEvent.uChar.UnicodeChar, 1, out, true); - } - return out; } From 039536bbfc99039d8d6398d91e70cdb8ee23b7bc Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 11:12:24 +0300 Subject: [PATCH 18/30] VT/Kitty: dont send modifiers as needed --- far2l/src/vt/vtshell_translation_kitty.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/far2l/src/vt/vtshell_translation_kitty.cpp b/far2l/src/vt/vtshell_translation_kitty.cpp index fbf522019..1636167ee 100644 --- a/far2l/src/vt/vtshell_translation_kitty.cpp +++ b/far2l/src/vt/vtshell_translation_kitty.cpp @@ -95,6 +95,10 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) case VK_MENU: { + if (!(flags & 8)) { // "Report all keys as escape codes" disabled - do not sent modifiers themselfs + return std::string(); + } + if (KeyEvent.dwControlKeyState & ENHANCED_KEY) { // right keycode = 57449; suffix = 'u'; @@ -108,6 +112,10 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) case VK_CONTROL: { + if (!(flags & 8)) { // "Report all keys as escape codes" disabled - do not sent modifiers themselfs + return std::string(); + } + if ((KeyEvent.dwControlKeyState & ENHANCED_KEY)) { // right keycode = 57448; suffix = 'u'; @@ -121,6 +129,10 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) case VK_SHIFT: { + if (!(flags & 8)) { // "Report all keys as escape codes" disabled - do not sent modifiers themselfs + return std::string(); + } + if (KeyEvent.wVirtualScanCode == RIGHT_SHIFT_VSC) { // right keycode = 57447; suffix = 'u'; @@ -137,13 +149,6 @@ std::string VT_TranslateKeyToKitty(const KEY_EVENT_RECORD &KeyEvent, int flags) // avoid sending base char if it is equal to keycode if (base == keycode) { base = 0; } - if (!(flags & 8)) { // "Report all keys as escape codes" disabled - // do not sent modifiers themselfs - if (!keycode && (modifiers > 1)) { - return std::string(); - } - } - // Записываем ESC-последовательность // CSI unicode-key-code:shifted-key:base-layout-key ; modifiers:event-type ; text-as-codepoints u From a9650f0d7c3554b9ed37f0c0d3a55f808306d628 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 13:14:02 +0300 Subject: [PATCH 19/30] asm -> __asm__ __volatile__ (touch #2494) --- multiarc/src/formats/7z/C/SwapBytes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/multiarc/src/formats/7z/C/SwapBytes.c b/multiarc/src/formats/7z/C/SwapBytes.c index 9290592b7..f5cbc0de0 100644 --- a/multiarc/src/formats/7z/C/SwapBytes.c +++ b/multiarc/src/formats/7z/C/SwapBytes.c @@ -506,8 +506,8 @@ void Z7_FASTCALL && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ || (defined(__clang__) && (__clang_major__ >= 4))) - #define SWAP2_64_VAR(v) asm ("rev16 %x0,%x0" : "+r" (v)); - #define SWAP4_64_VAR(v) asm ("rev32 %x0,%x0" : "+r" (v)); + #define SWAP2_64_VAR(v) __asm__ __volatile__ ("rev16 %x0,%x0" : "+r" (v)); + #define SWAP4_64_VAR(v) __asm__ __volatile__ ("rev32 %x0,%x0" : "+r" (v)); #else // is not ARM64-GNU @@ -593,9 +593,9 @@ SwapBytes4_64(CSwapUInt32 *items, const CSwapUInt32 *lim) || (defined(__clang__) && (__clang_major__ >= 4))) #ifdef MY_CPU_64BIT - #define SWAP2_32_VAR(v) asm ("rev16 %w0,%w0" : "+r" (v)); + #define SWAP2_32_VAR(v) __asm__ __volatile__ ("rev16 %w0,%w0" : "+r" (v)); #else - #define SWAP2_32_VAR(v) asm ("rev16 %0,%0" : "+r" (v)); // for clang/gcc + #define SWAP2_32_VAR(v) __asm__ __volatile__ ("rev16 %0,%0" : "+r" (v)); // for clang/gcc // asm ("rev16 %r0,%r0" : "+r" (a)); // for gcc #endif From a15cedcebd015143c12f57c68d24eb40f82847db Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 14:19:46 +0300 Subject: [PATCH 20/30] TTY: workaround for cases when terminal reports 0:0 size e.g. serial console --- WinPort/src/Backend/TTY/TTYBackend.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WinPort/src/Backend/TTY/TTYBackend.cpp b/WinPort/src/Backend/TTY/TTYBackend.cpp index 0f0e62b50..d902f981b 100644 --- a/WinPort/src/Backend/TTY/TTYBackend.cpp +++ b/WinPort/src/Backend/TTY/TTYBackend.cpp @@ -139,6 +139,13 @@ void TTYBackend::GetWinSize(struct winsize &w) w.ws_col = g_far2l_term_width; } } + if (w.ws_row == 0 && w.ws_col == 0) { + // when running over serial console 0:0 is returned always and far2l unusable + // TBD: may be set fixed size resolution for such case through env variable or command line arguments? + fprintf(stderr, "%s: ignoring 0:0 terminal size\n", __FUNCTION__); + w.ws_row = g_far2l_term_height; + w.ws_col = g_far2l_term_width; + } } void TTYBackend::DetachNotifyPipe() From 9e4ba2a2a4e26162eef801e6281f575406a29e3d Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 14:28:19 +0300 Subject: [PATCH 21/30] version script to update buildroot package --- packaging/version_bump_patch.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packaging/version_bump_patch.sh b/packaging/version_bump_patch.sh index a0f119c08..46767cd52 100755 --- a/packaging/version_bump_patch.sh +++ b/packaging/version_bump_patch.sh @@ -3,8 +3,14 @@ NEW_VERSION=$1 if [ "$NEW_VERSION" = "" ]; then NEW_VERSION=$(perl -F'\.' -lane 'print $F[0].".".$F[1].".".($F[2]+1)' ./version) fi + echo NEW_VERSION=$NEW_VERSION +NEW_TAG=v_$NEW_VERSION + echo $NEW_VERSION > ./version -git add ./version + +sed -i "s|FAR2L_VERSION = .*|FAR2L_VERSION = $NEW_TAG|" buildroot/far2l/far2l.mk + +git add ./version ./buildroot/far2l/far2l.mk git commit -m "Bump version to $NEW_VERSION" -git tag v_$NEW_VERSION +git tag $NEW_TAG From 86a84c00929d00feb92fdebaa1555d1ef459d9c2 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 17 Nov 2024 16:17:12 +0300 Subject: [PATCH 22/30] TTY: use LINES and COLUMNS envs if TIOCGWINSZ didnt produce sane result --- WinPort/src/Backend/TTY/TTYBackend.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/WinPort/src/Backend/TTY/TTYBackend.cpp b/WinPort/src/Backend/TTY/TTYBackend.cpp index d902f981b..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,16 +147,16 @@ 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 (w.ws_row == 0 && w.ws_col == 0) { + 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 - // TBD: may be set fixed size resolution for such case through env variable or command line arguments? - fprintf(stderr, "%s: ignoring 0:0 terminal size\n", __FUNCTION__); - w.ws_row = g_far2l_term_height; - w.ws_col = g_far2l_term_width; + // 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); } } From 2f38afe0cb957792f33b50d5c1e7e1582667b1be Mon Sep 17 00:00:00 2001 From: elfmz Date: Mon, 18 Nov 2024 00:09:57 +0300 Subject: [PATCH 23/30] mac: fix for doubled key events (fix #2505) --- WinPort/src/Backend/WX/wxMain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index e775bc214..b12bf3b69 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -1563,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(); } @@ -1633,11 +1632,12 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.bKeyDown = FALSE; wxConsoleInputShim::Enqueue(&ir, 1); +#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(); } From 9d4d3fecd36e2b5c96f5697ad0326d2bc2609b6e Mon Sep 17 00:00:00 2001 From: elfmz Date: Mon, 18 Nov 2024 09:07:36 +0300 Subject: [PATCH 24/30] more keybd fixes --- .../Backend/TTY/TTYInputSequenceParserExts.cpp | 15 ++++++++++++++- WinPort/src/Backend/WX/wxMain.cpp | 5 +++-- 2 files changed, 17 insertions(+), 3 deletions(-) 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 b12bf3b69..d8bc2c593 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -1621,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 @@ -1632,11 +1632,12 @@ 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(); From 9eef95bc87af0f8fe0e6c1b859d5fec59406e3e4 Mon Sep 17 00:00:00 2001 From: elfmz Date: Mon, 18 Nov 2024 09:57:59 +0300 Subject: [PATCH 25/30] Bump version to 2.6.4 --- packaging/buildroot/far2l/far2l.mk | 2 +- packaging/version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/buildroot/far2l/far2l.mk b/packaging/buildroot/far2l/far2l.mk index 09f62ba38..000c6fe6a 100644 --- a/packaging/buildroot/far2l/far2l.mk +++ b/packaging/buildroot/far2l/far2l.mk @@ -4,7 +4,7 @@ # ################################################################################ -FAR2L_VERSION = master +FAR2L_VERSION = v_2.6.4 FAR2L_SITE = $(call github,elfmz,far2l,$(FAR2L_VERSION)) FAR2L_LICENSE = GPL-2 FAR2L_LICENSE_FILES = LICENSE.txt diff --git a/packaging/version b/packaging/version index ec1cf33c3..2714f5313 100644 --- a/packaging/version +++ b/packaging/version @@ -1 +1 @@ -2.6.3 +2.6.4 From db76634c30d60f63dbc550bb97edfd532d5b69ce Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:23:52 +0300 Subject: [PATCH 26/30] Fix order of default Highlight for processing combined cases - now executable mark `*` show also for hidden files - text-files group with non-extension mask by name (`read.me`,`readme*`) processing after all Thanks @spnethw for problem statement. --- far2l/src/hilight.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/far2l/src/hilight.cpp b/far2l/src/hilight.cpp index b519c3ba0..909d606af 100644 --- a/far2l/src/hilight.cpp +++ b/far2l/src/hilight.cpp @@ -131,38 +131,43 @@ static void SetDefaultHighlighting() // Mask NormalColor // IncludeAttributes // IgnoreMask CursorColor + // === broken '!' {L"*", 1, FILE_ATTRIBUTE_BROKEN, 0x00, 0x10 | F_LIGHTRED, 0xFFFFFFFD0F, 0x30 | F_LIGHTRED, 0xFFFFFFFD0F, 0xFF0021 /*!*/, 0, 0}, + // === symlinks (to directory '~', to file '@') {L"*", 1, FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF007E /*~*/, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_DIRECTORY, 0x90 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF0040 /*@*/, 0, 0}, - + // === devices (char '-', block '+', FIFO '|', socket '=') {L"*", 1, FILE_ATTRIBUTE_DEVICE_CHAR, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF002D /*-*/, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_DEVICE_BLOCK, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF002B /*+*/, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_DEVICE_FIFO, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF007C /*|*/, 0, 0}, {L"*", 1, FILE_ATTRIBUTE_DEVICE_SOCK, 0x00, 0x10 | F_LIGHTBLUE, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF003D /*=*/, 0, 0}, - - {L"*", 1, FILE_ATTRIBUTE_HARDLINKS, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF00AB, 0, 0}, - - {L"*", 1, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, - {L"*", 1, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF002F /*/*/, 0, 0}, - {L"*", 1, FILE_ATTRIBUTE_SYSTEM, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF263C, 1, 0}, + // === regular directories & files // это настройка для каталогов на тех панелях, которые должны раскрашиваться // без учета масок (например, список хостов в "far navigator") {L"*", 1, FILE_ATTRIBUTE_EXECUTABLE | FILE_ATTRIBUTE_REPARSE_POINT, 0, 0x10 | F_GREEN, 0xFFFFFFFD0F, 0x30 | F_GREEN, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, + // executable files '*' + {L"*", 1, FILE_ATTRIBUTE_EXECUTABLE, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_GREEN, 0xFFFFFFFD0F, 0x30 | F_GREEN, 0xFFFFFFFD0F, 0xFF002A /***/, 1, 0}, + // hidden files (without mark) & directories '/' + {L"*", 1, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, + {L"*", 1, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF002F /*/*/, 0, 0}, + // directories '/' {L"*|..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x10 | F_WHITE, 0xFFFFFFFD0F, 0x30 | F_WHITE, 0xFFFFFFFD0F, 0xFF002F /*/*/, 0, 0}, {L"..", 0, FILE_ATTRIBUTE_DIRECTORY, 0x00, 0x00, 0xFFFFFFFD0F, 0x00, 0xFFFFFFFD0F, 0x00002F /*/*/, 0, 0}, - {L"*", 1, FILE_ATTRIBUTE_EXECUTABLE, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_GREEN, 0xFFFFFFFD0F, 0x30 | F_GREEN, 0xFFFFFFFD0F, 0xFF002A /***/, 1, 0}, - + // system '☼' & with more 1 hardlink '«' + {L"*", 1, FILE_ATTRIBUTE_SYSTEM, 0x00, 0x10 | F_CYAN, 0xFFFFFFFD0F, 0x30 | F_DARKGRAY, 0xFFFFFFFD0F, 0xFF263C, 1, 0}, + {L"*", 1, FILE_ATTRIBUTE_HARDLINKS, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTCYAN, 0xFFFFFFFD0F, 0x30 | F_BLUE, 0xFFFFFFFD0F, 0xFF00AB, 0, 0}, + // sound '♪' (disabled by default) {MasksSoundFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0xAAFF00ull << 16) | (0x10 | F_LIGHTGREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x005500ull << 16) | (0x30 | F_LIGHTGREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF266A, 0, FFF_DISABLED}, + // all other without any mark, only different colors {MaskSharedObjects,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0x00b800ull << 16) | (0x10 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x005500ull << 16) | (0x30 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MaskSourceFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0xffbcacull << 16) | (0x10 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x8F0C00ull << 16) | (0x30 | F_GREEN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MaskVideoFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0x30b8ffull << 16) | (0x10 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x006767ull << 16) | (0x30 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MaskImageFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0x00ffaeull << 16) | (0x10 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x00432eull << 16) | (0x30 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MaskModelFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0x00ffaeull << 16) | (0x10 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x00432eull << 16) | (0x30 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, - {MaskTextFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0xccccccull << 16) | (0x10 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x767676ull << 16) | (0x30 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, - {MasksScripts, 0, 0x00, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTGREEN, 0xFFFFFFFD0F, 0x30 | F_LIGHTGREEN, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MasksArchives, 0, 0x00, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_LIGHTMAGENTA, 0xFFFFFFFD0F, 0x30 | F_LIGHTMAGENTA, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, {MasksTemporary, 0, 0x00, FILE_ATTRIBUTE_DIRECTORY, 0x10 | F_BROWN, 0xFFFFFFFD0F, 0x30 | F_BROWN, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, + {MaskTextFiles,0, 0x00, FILE_ATTRIBUTE_DIRECTORY, (0xccccccull << 16) | (0x10 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, (0x767676ull << 16) | (0x30 | F_BROWN) | FOREGROUND_TRUECOLOR, 0xFFFFFFFD0F, 0xFF0000, 0, 0}, }; From f756ac540ff8ce18bd5d77e546059e9cbbf97ed1 Mon Sep 17 00:00:00 2001 From: exkrexpexfex <75270873+exkrexpexfex@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:48:54 +0300 Subject: [PATCH 27/30] Crash on overflow when searching in a large file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit around line number 21475226 which gives integer overflow when multiplied by 100 ``` Process 23391 stopped * thread #8, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x000000010031a21c far2l`FARString::Content::Create(nCapacity=184467440737095499) at FARString.cpp:125:19 122 Content *out = (Content *)malloc(sizeof(Content) + sizeof(wchar_t) * nCapacity); 123 //Так как ни где выше в коде мы не готовы на случай что памяти не хватит 124 //то уж лучше и здесь не проверять, а сразу падать -> 125 out->m_nRefCount = 1; 126 out->m_nCapacity = (unsigned int)std::min(nCapacity, (size_t)std::numeric_limits::max()); 127 out->m_nLength = 0; 128 out->m_Data[0] = 0; Target 0: (far2l) stopped. (lldb) bt * thread #8, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x000000010031a21c far2l`FARString::Content::Create(nCapacity=184467440737095499) at FARString.cpp:125:19 frame #1: 0x000000010031af2c far2l`FARString::Replace(this=0x00000001701cacf8, Pos=0, Len=0, Ch=L'█', Count=184467440737095499) at FARString.cpp:293:22 frame #2: 0x00000001000a84f4 far2l`FARString::Append(this=0x00000001701cacf8, Ch=L'█', Count=184467440737095499) at FARString.hpp:173:59 frame #3: 0x0000000100119414 far2l`Editor::EditorShowMsg(Title=L"Search", Msg=L"Searching for", Name=L"\"user= \"", Percent=-47) at editor.cpp:6259:15 frame #4: 0x0000000100115e94 far2l`Editor::Search(this=0x000000012b20c530, Next=0) at editor.cpp:3430:5 frame #5: 0x0000000100110964 far2l`Editor::ProcessKey(this=0x000000012b20c530, Key=2097270) at editor.cpp:1874:9 ``` --- far2l/src/editor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/far2l/src/editor.cpp b/far2l/src/editor.cpp index ce51c36ef..8acb32da4 100644 --- a/far2l/src/editor.cpp +++ b/far2l/src/editor.cpp @@ -50,6 +50,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "syslog.hpp" #include "interf.hpp" #include "message.hpp" +#include "mix.hpp" #include "clipboard.hpp" #include "xlat.hpp" #include "datetime.hpp" @@ -3427,7 +3428,7 @@ BOOL Editor::Search(int Next) SetCursorType(FALSE, -1); int Total = ReverseSearch ? StartLine : NumLastLine - StartLine; int Current = abs(NewNumLine - StartLine); - EditorShowMsg(Msg::EditSearchTitle, Msg::EditSearchingFor, strMsgStr, Current * 100 / Total); + EditorShowMsg(Msg::EditSearchTitle, Msg::EditSearchingFor, strMsgStr, ToPercent64(Current, Total)); if (CheckForEscSilent()) { if (ConfirmAbortOp()) { @@ -6246,7 +6247,7 @@ void Editor::EditorShowMsg(const wchar_t *Title, const wchar_t *Msg, const wchar { FARString strProgress; - if (Percent != -1) { + if (Percent > -1) { FormatString strPercent; strPercent << Percent; From 78d088f68305fcfdb7690b522bc5c0c1d12654f2 Mon Sep 17 00:00:00 2001 From: spvkgn Date: Tue, 19 Nov 2024 19:07:39 +0500 Subject: [PATCH 28/30] inside: add PE format --- inside/configs/plug/config.ini | 3 +++ inside/src/inside.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/inside/configs/plug/config.ini b/inside/configs/plug/config.ini index f1f350cda..dbf7eef24 100644 --- a/inside/configs/plug/config.ini +++ b/inside/configs/plug/config.ini @@ -6,6 +6,9 @@ ProgramHeaders.txt=readelf -W -l $F Symbols.txt=nm $F SymbolsDynamic.txt=nm --dynamic $F +[PE] +Info.txt=readpe -A $F + [Disasm_20] PPC.s=powerpc-linux-gnu-objdump -d -w -z $F PPC_VLE.s=powerpc-eabivle-objdump -d -w -z $F diff --git a/inside/src/inside.cpp b/inside/src/inside.cpp index 38266f214..83c68dcf1 100644 --- a/inside/src/inside.cpp +++ b/inside/src/inside.cpp @@ -99,6 +99,10 @@ static const char *DetectPlainKind(const char *Name, const unsigned char *Data, } else if (DataSize >= 8 && Data[0] == 'f' && Data[1] == 'L' && Data[2] == 'a' && Data[3] == 'C' && ext && strcasecmp(ext, ".flac") == 0) { return "FLAC"; + } else if (DataSize >= 4 && Data[0] == 0x4d && Data[1] == 0x5a + && ext && (strcasecmp(ext, ".exe") == 0 || strcasecmp(ext, ".dll") == 0 || strcasecmp(ext, ".sys") == 0 + || strcasecmp(ext, ".drv") == 0 || strcasecmp(ext, ".ocx") == 0 || strcasecmp(ext, ".efi") == 0)) { + return "PE"; } return nullptr; From b761a5d8ab561a5e237091e324db7c1030d0144a Mon Sep 17 00:00:00 2001 From: spvkgn Date: Tue, 19 Nov 2024 19:08:17 +0500 Subject: [PATCH 29/30] inside: add png, ogg, m4a --- inside/configs/plug/config.ini | 11 +++++++++++ inside/src/inside.cpp | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/inside/configs/plug/config.ini b/inside/configs/plug/config.ini index dbf7eef24..40ec7a780 100644 --- a/inside/configs/plug/config.ini +++ b/inside/configs/plug/config.ini @@ -56,6 +56,9 @@ Info.txt=exiftool $F ASCIIArt.txt=jp2a $F ASCIIArt.ans=jp2a --colors $F +[PNG] +Info.txt=exiftool $F + [MP3] Info.txt=exiftool $F @@ -67,3 +70,11 @@ Info.txt=exiftool $F [WV] Info.txt=exiftool $F + +[OGG] +Info.txt=exiftool $F +mediainfo.txt=mediainfo $F + +[M4A] +Info.txt=exiftool $F +mediainfo.txt=mediainfo $F diff --git a/inside/src/inside.cpp b/inside/src/inside.cpp index 83c68dcf1..800f47299 100644 --- a/inside/src/inside.cpp +++ b/inside/src/inside.cpp @@ -79,13 +79,17 @@ static const char *DetectPlainKind(const char *Name, const unsigned char *Data, && ext && (strcasecmp(ext, ".jpg") == 0 || strcasecmp(ext, ".jpeg") == 0)) { return "JPG"; + } else if (DataSize >= 8 && Data[0] == 0x89 && Data[1] == 0x50 && Data[2] == 0x4e && Data[3] == 0x47 + && ext && strcasecmp(ext, ".png") == 0) { + return "PNG"; + } else if (DataSize >= 8 && Data[0] == 'A' && Data[1] == 'T' && Data[2] == '&' && Data[3] == 'T' && Data[4] == 'F' && Data[5] == 'O' && Data[6] == 'R' && Data[7] == 'M' && ext && strcasecmp(ext, ".djvu") == 0) { // Ensure - return "DJVU"; - } else if (DataSize >= 8 && ext && strcasecmp(ext, ".mp3") == 0) { + } else if (DataSize >= 8 && Data[0] == 0x49 && Data[1] == 0x44 && Data[2] == 0x33 + && ext && strcasecmp(ext, ".mp3") == 0) { return "MP3"; } else if (DataSize >= 8 && Data[0] == 'M' && Data[1] == 'A' && Data[2] == 'C' @@ -99,6 +103,15 @@ static const char *DetectPlainKind(const char *Name, const unsigned char *Data, } else if (DataSize >= 8 && Data[0] == 'f' && Data[1] == 'L' && Data[2] == 'a' && Data[3] == 'C' && ext && strcasecmp(ext, ".flac") == 0) { return "FLAC"; + + } else if (DataSize >= 8 && Data[0] == 'O' && Data[1] == 'g' && Data[2] == 'g' && Data[3] == 'S' + && ext && (strcasecmp(ext, ".ogg") == 0 || strcasecmp(ext, ".oga") == 0 || strcasecmp(ext, ".opus") == 0)) { + return "OGG"; + + } else if (DataSize >= 12 && memcmp(Data + 4, "ftypM4A ", 8) == 0 + && ext && strcasecmp(ext, ".m4a") == 0) { + return "M4A"; + } else if (DataSize >= 4 && Data[0] == 0x4d && Data[1] == 0x5a && ext && (strcasecmp(ext, ".exe") == 0 || strcasecmp(ext, ".dll") == 0 || strcasecmp(ext, ".sys") == 0 || strcasecmp(ext, ".drv") == 0 || strcasecmp(ext, ".ocx") == 0 || strcasecmp(ext, ".efi") == 0)) { From e4bc52719f910ba45cb2c9e0591ff36443b1029e Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 20 Nov 2024 12:09:40 +0400 Subject: [PATCH 30/30] tmppanel: fix PANIC-PANIC crash in menu from file list --- tmppanel/src/TmpPanel.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tmppanel/src/TmpPanel.cpp b/tmppanel/src/TmpPanel.cpp index 72dad44ad..36bd0df16 100644 --- a/tmppanel/src/TmpPanel.cpp +++ b/tmppanel/src/TmpPanel.cpp @@ -360,14 +360,17 @@ void ReadFileLines(int fd, DWORD FileSizeLow, TCHAR **argv, TCHAR *args, UINT *n for (int i = 0; i < argc; ++i) { TCHAR *param, *p = TMP; ExpandEnvStrs(argv[i], TMP); - param = ParseParam(p); - FSF.TruncStr(param ? param : p, 67); - - fmi[i].Text = wcsdup(param ? param : p); + param = ParseParam(p); + if (!param) { + param = p; + } - fmi[i].Separator = !lstrcmp(param, _T("-")); + FSF.TruncStr(param, 67); + fmi[i].Text = wcsdup(param); + fmi[i].Separator = !lstrcmp(param, L"-"); fmi[i].Selected = FALSE; fmi[i].Checked = FALSE; + } // fmi[0].Selected=TRUE; @@ -389,9 +392,10 @@ void ReadFileLines(int fd, DWORD FileSizeLow, TCHAR **argv, TCHAR *args, UINT *n free(fmi); if ((unsigned)ExitCode < (unsigned)argc) { - ExpandEnvStrs(argv[ExitCode], TMP); - TCHAR *p = TMP; + TCHAR *p = argv[ExitCode]; ParseParam(p); + ExpandEnvStrs(p, TMP); + p = TMP; FAR_FIND_DATA FindData; int bShellExecute = BreakCode != -1; @@ -445,7 +449,7 @@ void ReadFileLines(int fd, DWORD FileSizeLow, TCHAR **argv, TCHAR *args, UINT *n return hPlugin; } else { ShowMenuFromList(pName); - return INVALID_HANDLE_VALUE; + return ((HANDLE)-2); } #undef pName }