From ef163eac08bdce7c6a986e5f92265cbd79a284d3 Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:17:09 +0300 Subject: [PATCH 01/16] infolist: git info tuning --- far2l/bootstrap/scripts/farlang.templ.m4 | 11 +++++++++++ far2l/src/panels/infolist.cpp | 12 +++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 021f70ecc..52f534606 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -13304,6 +13304,17 @@ upd:"Free paging file" "Вільно файлу підкачки" "Вольна файла падпампоўкі" +InfoGitRootDir +"Git Root Directory" +"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" +upd:"Git Root Directory" + InfoDizAbsent "Файл описания папки отсутствует" "Folder description file is absent" diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index fe47787ee..0a2324aa6 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -625,9 +625,19 @@ void InfoList::ShowDirDescription(int YPos) std::vector lines; std::string cmd = "git -C \""; cmd+= EscapeCmdStr(Wide2MB(strDir.CPtr())); - cmd+= "\" status"; + cmd+= "\" status -s -b"; if (POpen(lines, cmd.c_str())) { + // text " git status " in separator + strGit = L" git status -s -b "; + TruncStrFromEnd(strGit, X2 - X1 - 3); + GotoXY(X1 + (X2 - X1 + 1 - (int)strGit.GetLength()) / 2, YPos); + PrintText(strGit); + // print git root dir + GotoXY(X1 + 2, ++YPos); + PrintText(Msg::InfoGitRootDir); + PrintInfo(strDir); + // print result of git status for (const auto &l : lines) { GotoXY(X1 + 2, ++YPos); PrintText(l.c_str()); From dbd58861a8d382f887c690fad18b64a14242e76b Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Fri, 1 Nov 2024 22:32:46 +0300 Subject: [PATCH 02/16] infolist: add hide/show blocks (backport from far3) + refactoring --- far2l/bootstrap/scripts/farlang.templ.m4 | 47 +- far2l/src/panels/infolist.cpp | 537 +++++++++++++---------- far2l/src/panels/infolist.hpp | 5 + 3 files changed, 345 insertions(+), 244 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 52f534606..1b0ce20d3 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -13118,15 +13118,15 @@ upd:"FS Flags" upd:"FS Flags" InfoPluginTitle -" Плагин на панели " -" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " -upd:" Plugin in panel " +"Плагин на панели" +"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" +upd:"Plugin in panel" InfoPluginStartDir "Плагин запущен в каталоге" @@ -13206,15 +13206,15 @@ upd:"Plugin ShortcutData" upd:"Plugin ShortcutData" InfoMemory -" Память " -" Memory " -" Paměť " -" Speicher " -" Memória " -" Pamięć " -" Memoria " -" Пам'ять " -" Памяць " +"Память" +"Memory" +"Paměť" +"Speicher" +"Memória" +"Pamięć" +"Memoria" +"Пам'ять" +"Памяць" InfoMemoryLoad "Загрузка памяти" @@ -13315,6 +13315,17 @@ upd:"Git Root Directory" upd:"Git Root Directory" upd:"Git Root Directory" +InfoDescription +"Описание" +"Description" +"Popis" +"Beschreibung" +"Megjegyzés" +"Opis" +"Descripción" +"Опис" +"Апісанне" + InfoDizAbsent "Файл описания папки отсутствует" "Folder description file is absent" diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index 0a2324aa6..673f6f3ee 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -69,11 +69,34 @@ static int LastDizWrapMode = -1; static int LastDizWrapType = -1; static int LastDizShowScrollbar = -1; +enum InfoListSectionStateIndex +{ + ILSS_DISKINFO, + ILSS_MEMORYINFO, + ILSS_GITINFO, + ILSS_DIRDESCRIPTION, + /*ILSS_PLDESCRIPTION, + ILSS_POWERSTATUS,*/ + + ILSS_SIZE +}; + +struct InfoList::InfoListSectionState +{ + bool Show; // раскрыть/свернуть? + int Y; // Где? (<0 - отсутствует) +}; + InfoList::InfoList() : - DizView(nullptr), PrevMacroMode(-1) + DizView(nullptr), PrevMacroMode(-1), SectionState(ILSS_SIZE) { Type = INFO_PANEL; + for (auto& i: SectionState) + { + i.Show = true; + i.Y = -1; + } if (LastDizWrapMode < 0) { LastDizWrapMode = Opt.ViOpt.ViewerIsWrap; LastDizWrapType = Opt.ViOpt.ViewerWrap; @@ -104,6 +127,30 @@ FARString &InfoList::GetTitle(FARString &strTitle, int SubLen, int TruncSize) return strTitle; } +void InfoList::DrawTitle(const wchar_t *Str, int Id, int &CurY) +{ + SetFarColor(COL_PANELBOX); + DrawSeparator(CurY); + SetFarColor(COL_PANELTEXT); + + if (Str != nullptr && *Str) { + FARString strTitle; + strTitle.Format(L" %ls ", Str); + TruncStr(strTitle, X2 - X1 - 3); + GotoXY(X1 + (X2 - X1 + 1 - (int)strTitle.GetLength()) / 2, CurY); + PrintText(strTitle); + } + GotoXY(X1 + 1, CurY); + PrintText(SectionState[Id].Show ? L"[-]" : L"[+]"); + SectionState[Id].Y=CurY; + CurY++; +} + +inline void InfoList::DrawTitle(FarLangMsg MsgID, int Id, int &CurY) +{ + DrawTitle(MsgID.CPtr(), Id, CurY); +} + void InfoList::DisplayObject() { FARString strTitle; @@ -143,15 +190,12 @@ void InfoList::DisplayObject() PrintInfo(CachedUserName()); } - /* #2 - disk info */ - - SetFarColor(COL_PANELBOX); - DrawSeparator(CurY); - SetFarColor(COL_PANELTEXT); + /* #2 - disk / plugin info */ AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); AnotherPanel->GetCurDir(strCurDir); + /* #2a.1 - disk info */ if (AnotherPanel->GetMode() != PLUGIN_PANEL) { if (strCurDir.IsEmpty()) @@ -164,264 +208,262 @@ void InfoList::DisplayObject() &strFileSystemName, &strFileSystemMountPoint); if (b_info) { // strTitle=FARString(L" ")+DiskType+L" "+Msg::InfoDisk+L" "+(strDriveRoot)+L" ("+strFileSystemName+L") "; - strTitle = FARString(L"") + L" (" + strFileSystemName + L") "; + strTitle = L"(" + strFileSystemName + L")"; strDiskNumber.Format(L"%08X-%08X", (DWORD)(VolumeNumber >> 32), (DWORD)(VolumeNumber & 0xffffffff)); } else // Error! strTitle = strCurDir; // strDriveRoot; - TruncStr(strTitle, X2 - X1 - 3); - GotoXY(X1 + (X2 - X1 + 1 - (int)strTitle.GetLength()) / 2, CurY++); - PrintText(strTitle); + DrawTitle(strTitle.CPtr(), ILSS_DISKINFO, CurY); + if (SectionState[ILSS_DISKINFO].Show) { + /* #2a.2 - disk info: size */ - /* #3 - disk info: size */ + uint64_t TotalSize, TotalFree, UserFree; - uint64_t TotalSize, TotalFree, UserFree; + if (apiGetDiskSize(strCurDir, &TotalSize, &TotalFree, &UserFree)) { + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskTotal); + InsertCommas(TotalSize, strOutStr); + PrintInfo(strOutStr); - if (apiGetDiskSize(strCurDir, &TotalSize, &TotalFree, &UserFree)) { - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskTotal); - InsertCommas(TotalSize, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskFree); + InsertCommas(UserFree, strOutStr); + PrintInfo(strOutStr); + } - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskFree); - InsertCommas(UserFree, strOutStr); - PrintInfo(strOutStr); - } + /* #2a.3 - disk info: label & SN */ - /* #4 - disk info: label & SN */ + if (!strVolumeName.IsEmpty()) { + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskLabel); + PrintInfo(strVolumeName); + } - if (!strVolumeName.IsEmpty()) { GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskLabel); - PrintInfo(strVolumeName); - } + PrintText(Msg::InfoDiskNumber); + PrintInfo(strDiskNumber); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskNumber); - PrintInfo(strDiskNumber); + // new fields + CurY++; // skip line - // new fields - CurY++; // skip line - - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskCurDir); - PrintInfo(strCurDir); - - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskRealDir); - PrintInfo(strRealDir); - - if (b_info) { GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskMountPoint); - PrintInfo(strFileSystemMountPoint); + PrintText(Msg::InfoDiskCurDir); + PrintInfo(strCurDir); GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskMaxFilenameLength); - strTitle.Format(L"%lu", (unsigned long) MaxNameLength); - PrintInfo(strTitle); + PrintText(Msg::InfoDiskRealDir); + PrintInfo(strRealDir); + + if (b_info) { + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskMountPoint); + PrintInfo(strFileSystemMountPoint); + + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskMaxFilenameLength); + strTitle.Format(L"%lu", (unsigned long) MaxNameLength); + PrintInfo(strTitle); - strOutStr.Clear(); + strOutStr.Clear(); #ifdef ST_RDONLY /* Mount read-only. */ - strOutStr += (FileSystemFlags & ST_RDONLY) ? "ro" : "rw"; + strOutStr += (FileSystemFlags & ST_RDONLY) ? "ro" : "rw"; #endif #ifdef ST_NOSUID /* Ignore suid and sgid bits. */ - if (FileSystemFlags & ST_NOSUID) - strOutStr += ",nosuid"; + if (FileSystemFlags & ST_NOSUID) + strOutStr += ",nosuid"; #endif #ifdef ST_NODEV /* Disallow access to device special files. */ - if (FileSystemFlags & ST_NODEV) - strOutStr += ",nodev"; + if (FileSystemFlags & ST_NODEV) + strOutStr += ",nodev"; #endif #ifdef ST_NOEXEC /* Disallow program execution. */ - if (FileSystemFlags & ST_NOEXEC) - strOutStr += ",noexec"; + if (FileSystemFlags & ST_NOEXEC) + strOutStr += ",noexec"; #endif #ifdef ST_SYNCHRONOUS /* Writes are synced at once. */ - if (FileSystemFlags & ST_SYNCHRONOUS) - strOutStr += ",sync"; + if (FileSystemFlags & ST_SYNCHRONOUS) + strOutStr += ",sync"; #endif #ifdef ST_MANDLOCK /* Allow mandatory locks on an FS. */ - if (FileSystemFlags & ST_MANDLOCK) - strOutStr += ",mandlock"; + if (FileSystemFlags & ST_MANDLOCK) + strOutStr += ",mandlock"; #endif #ifdef ST_WRITE /* Write on file/directory/symlink. */ - if (FileSystemFlags & ST_WRITE) - strOutStr += ",write"; + if (FileSystemFlags & ST_WRITE) + strOutStr += ",write"; #endif #ifdef ST_APPEND /* Append-only file. */ - if (FileSystemFlags & ST_APPEND) - strOutStr += ",append"; + if (FileSystemFlags & ST_APPEND) + strOutStr += ",append"; #endif #ifdef ST_IMMUTABLE /* Immutable file. */ - if (FileSystemFlags & ST_IMMUTABLE) - strOutStr += ",immutable"; + if (FileSystemFlags & ST_IMMUTABLE) + strOutStr += ",immutable"; #endif #ifdef ST_NOATIME /* Do not update access times. */ - if (FileSystemFlags & ST_NOATIME) - strOutStr += ",noatime"; + if (FileSystemFlags & ST_NOATIME) + strOutStr += ",noatime"; #endif #ifdef ST_NODIRATIME /* Do not update directory access times. */ - if (FileSystemFlags & ST_NODIRATIME) - strOutStr += ",nodiratime"; + if (FileSystemFlags & ST_NODIRATIME) + strOutStr += ",nodiratime"; #endif #ifdef ST_RELATIME /* Update atime relative to mtime/ctime. */ - if (FileSystemFlags & ST_RELATIME) - strOutStr += ",relatime"; + if (FileSystemFlags & ST_RELATIME) + strOutStr += ",relatime"; #endif #ifdef ST_NOSYMFOLLOW - if (FileSystemFlags & ST_NOSYMFOLLOW) - strOutStr += ",nosymfollow"; + if (FileSystemFlags & ST_NOSYMFOLLOW) + strOutStr += ",nosymfollow"; #endif - if (!strOutStr.IsEmpty()) { - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoDiskFlags); - PrintInfo(strOutStr); + if (!strOutStr.IsEmpty()) { + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoDiskFlags); + PrintInfo(strOutStr); + } } - } + } } - else { // plugin - strTitle = Msg::InfoPluginTitle; - GotoXY(X1 + (X2 - X1 + 1 - (int)strTitle.GetLength()) / 2, CurY++); - PrintText(strTitle); - - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginStartDir); - PrintInfo(strCurDir); - - HANDLE hPlugin = AnotherPanel->GetPluginHandle(); - if (hPlugin != INVALID_HANDLE_VALUE) { - PluginHandle *ph = (PluginHandle *)hPlugin; + /* 2b - plugin */ + else { + DrawTitle(Msg::InfoPluginTitle, ILSS_DISKINFO, CurY); + if (SectionState[ILSS_DISKINFO].Show) { GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginModuleName); - PrintInfo(PointToName(ph->pPlugin->GetModuleName())); - } + PrintText(Msg::InfoPluginStartDir); + PrintInfo(strCurDir); - OpenPluginInfo Info; - AnotherPanel->GetOpenPluginInfo(&Info); + HANDLE hPlugin = AnotherPanel->GetPluginHandle(); + if (hPlugin != INVALID_HANDLE_VALUE) { + PluginHandle *ph = (PluginHandle *)hPlugin; + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginModuleName); + PrintInfo(PointToName(ph->pPlugin->GetModuleName())); + } - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginHostFile); - PrintInfo(Info.HostFile); + OpenPluginInfo Info; + AnotherPanel->GetOpenPluginInfo(&Info); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginCurDir); - PrintInfo(Info.CurDir); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginHostFile); + PrintInfo(Info.HostFile); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginPanelTitle); - PrintInfo(Info.PanelTitle); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginCurDir); + PrintInfo(Info.CurDir); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginFormat); - PrintInfo(Info.Format); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginPanelTitle); + PrintInfo(Info.PanelTitle); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPluginShortcutData); - PrintInfo(Info.ShortcutData); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginFormat); + PrintInfo(Info.Format); + + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPluginShortcutData); + PrintInfo(Info.ShortcutData); + } } - /* #4 - memory info */ - - SetFarColor(COL_PANELBOX); - DrawSeparator(CurY); - SetFarColor(COL_PANELTEXT); - strTitle = Msg::InfoMemory; - TruncStr(strTitle, X2 - X1 - 3); - GotoXY(X1 + (X2 - X1 + 1 - (int)strTitle.GetLength()) / 2, CurY++); - PrintText(strTitle); + /* #3 - memory info */ + DrawTitle(Msg::InfoMemory, ILSS_MEMORYINFO, CurY); + if (SectionState[ILSS_MEMORYINFO].Show) { #ifdef __APPLE__ - unsigned long long totalram; - vm_size_t page_size; - unsigned long long freeram; - int ret_sc; + unsigned long long totalram; + vm_size_t page_size; + unsigned long long freeram; + int ret_sc; - // ret_sc = (sysctlbyname("hw.memsize", &totalram, &ulllen, NULL, 0) ? 1 : 0); - ret_sc = (KERN_SUCCESS != _host_page_size(mach_host_self(), &page_size) ? 1 : 0); + // ret_sc = (sysctlbyname("hw.memsize", &totalram, &ulllen, NULL, 0) ? 1 : 0); + ret_sc = (KERN_SUCCESS != _host_page_size(mach_host_self(), &page_size) ? 1 : 0); - mach_msg_type_number_t count = HOST_VM_INFO_COUNT; - vm_statistics_data_t vmstat; + mach_msg_type_number_t count = HOST_VM_INFO_COUNT; + vm_statistics_data_t vmstat; - ret_sc+= (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) - ? 1 - : 0); - totalram = - (vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count) * page_size; - freeram = vmstat.free_count * page_size; + ret_sc+= (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) + ? 1 + : 0); + totalram = + (vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count) * page_size; + freeram = vmstat.free_count * page_size; - // double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count; - // double wired = vmstat.wire_count; - // double active = vmstat.active_count; - // double inactive = vmstat.inactive_count; - // double free = vmstat.free_count; + // double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count; + // double wired = vmstat.wire_count; + // double active = vmstat.active_count; + // double inactive = vmstat.inactive_count; + // double free = vmstat.free_count; - if (!ret_sc) { - DWORD dwMemoryLoad = 100 - ToPercent64(freeram, totalram); + if (!ret_sc) { + DWORD dwMemoryLoad = 100 - ToPercent64(freeram, totalram); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryLoad); - strOutStr.Format(L"%d%%", dwMemoryLoad); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryLoad); + strOutStr.Format(L"%d%%", dwMemoryLoad); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryTotal); - InsertCommas(totalram, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryTotal); + InsertCommas(totalram, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryFree); - InsertCommas(freeram, strOutStr); - PrintInfo(strOutStr); - } + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryFree); + InsertCommas(freeram, strOutStr); + PrintInfo(strOutStr); + } #elif !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__HAIKU__) - struct sysinfo si = {}; - if (sysinfo(&si) == 0) { - DWORD dwMemoryLoad = 100 - ToPercent64(si.freeram + si.freeswap, si.totalram + si.totalswap); + struct sysinfo si = {}; + if (sysinfo(&si) == 0) { + DWORD dwMemoryLoad = 100 - ToPercent64(si.freeram + si.freeswap, si.totalram + si.totalswap); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryLoad); - strOutStr.Format(L"%d%%", dwMemoryLoad); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryLoad); + strOutStr.Format(L"%d%%", dwMemoryLoad); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryTotal); - InsertCommas(si.totalram, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryTotal); + InsertCommas(si.totalram, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoMemoryFree); - InsertCommas(si.freeram, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoMemoryFree); + InsertCommas(si.freeram, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoSharedMemory); - InsertCommas(si.sharedram, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoSharedMemory); + InsertCommas(si.sharedram, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoBufferMemory); - InsertCommas(si.bufferram, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoBufferMemory); + InsertCommas(si.bufferram, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPageFileTotal); - InsertCommas(si.totalswap, strOutStr); - PrintInfo(strOutStr); + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPageFileTotal); + InsertCommas(si.totalswap, strOutStr); + PrintInfo(strOutStr); - GotoXY(X1 + 2, CurY++); - PrintText(Msg::InfoPageFileFree); - InsertCommas(si.freeswap, strOutStr); - PrintInfo(strOutStr); - } + GotoXY(X1 + 2, CurY++); + PrintText(Msg::InfoPageFileFree); + InsertCommas(si.freeswap, strOutStr); + PrintInfo(strOutStr); + } #endif - /* #5 - description */ + } + /* #4 - git status */ + ShowGitStatus(CurY); + /* #5 - dir description */ ShowDirDescription(CurY); + + /* #6 - plugin description */ ShowPluginDescription(); } @@ -537,6 +579,19 @@ int InfoList::ProcessMouse(MOUSE_EVENT_RECORD *MouseEvent) { int RetCode; + if (MouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) + { + for (auto &elem : SectionState) + { + if (elem.Y<0 || MouseEvent->dwMousePosition.Y != elem.Y) + continue; + + elem.Show = !elem.Show; + Redraw(); + return TRUE; + } + } + if (Panel::PanelProcessMouse(MouseEvent, RetCode)) return (RetCode); @@ -608,15 +663,13 @@ void InfoList::PrintInfo(FarLangMsg MsgID) PrintInfo(MsgID.CPtr()); } -void InfoList::ShowDirDescription(int YPos) +void InfoList::ShowGitStatus(int &YPos) { Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); - DrawSeparator(YPos); if (AnotherPanel->GetMode() == FILE_PANEL) { FARString strDir; AnotherPanel->GetCurDir(strDir); - do { FARString strGit = strDir + L"/.git"; struct stat s; @@ -629,74 +682,106 @@ void InfoList::ShowDirDescription(int YPos) if (POpen(lines, cmd.c_str())) { // text " git status " in separator - strGit = L" git status -s -b "; - TruncStrFromEnd(strGit, X2 - X1 - 3); - GotoXY(X1 + (X2 - X1 + 1 - (int)strGit.GetLength()) / 2, YPos); - PrintText(strGit); - // print git root dir - GotoXY(X1 + 2, ++YPos); - PrintText(Msg::InfoGitRootDir); - PrintInfo(strDir); - // print result of git status - for (const auto &l : lines) { - GotoXY(X1 + 2, ++YPos); - PrintText(l.c_str()); + DrawTitle(L"git status -s -b", ILSS_GITINFO, YPos); + if (SectionState[ILSS_GITINFO].Show) { + // print git root dir + GotoXY(X1 + 2, YPos++); + PrintText(Msg::InfoGitRootDir); + PrintInfo(strDir); + // print result of git status + for (const auto &l : lines) { + GotoXY(X1 + 2, YPos++); + PrintText(l.c_str()); + } } - DrawSeparator(++YPos); } break; } } while (CutToSlash(strDir, true)); + } +} - AnotherPanel->GetCurDir(strDir); +void InfoList::ShowDirDescription(int YPos) +{ + Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); + if (AnotherPanel->GetMode() != FILE_PANEL) + return; - if (!strDir.IsEmpty()) - AddEndSlash(strDir); + if (!SectionState[ILSS_DIRDESCRIPTION].Show) { + DrawTitle(Msg::InfoDescription, ILSS_DIRDESCRIPTION, YPos); + return; + } - FARString strArgName; - const wchar_t *NamePtr = Opt.InfoPanel.strFolderInfoFiles; + DrawTitle(nullptr, ILSS_DIRDESCRIPTION, YPos); - while ((NamePtr = GetCommaWord(NamePtr, strArgName))) { - FARString strFullDizName; - strFullDizName = strDir; - strFullDizName+= strArgName; - FAR_FIND_DATA_EX FindData; + FARString strDir; + AnotherPanel->GetCurDir(strDir); - if (!apiGetFindDataEx(strFullDizName, FindData, FIND_FILE_FLAG_CASE_INSENSITIVE)) { - continue; - } + if (!strDir.IsEmpty()) + AddEndSlash(strDir); - CutToSlash(strFullDizName, false); - strFullDizName+= FindData.strFileName; + FARString strArgName; + const wchar_t *NamePtr = Opt.InfoPanel.strFolderInfoFiles; - if (OpenDizFile(strFullDizName, YPos)) - return; + while ((NamePtr = GetCommaWord(NamePtr, strArgName))) { + FARString strFullDizName; + strFullDizName = strDir; + strFullDizName+= strArgName; + FAR_FIND_DATA_EX FindData; + + if (!apiGetFindDataEx(strFullDizName, FindData, FIND_FILE_FLAG_CASE_INSENSITIVE)) { + continue; } + + CutToSlash(strFullDizName, false); + strFullDizName+= FindData.strFileName; + + if (OpenDizFile(strFullDizName, YPos - 1)) + return; } CloseFile(); + + strDir = L" "; + strDir += Msg::InfoDescription; + strDir += L" "; + TruncStr(strDir, X2 - X1 - 3); + GotoXY(X1 + (X2 - X1 - (int)strDir.GetLength()) / 2, YPos - 1); + SetFarColor(COL_PANELTEXT); + PrintText(strDir); + SetFarColor(COL_PANELTEXT); - GotoXY(X1 + 2, YPos + 1); + GotoXY(X1 + 2, YPos); PrintText(Msg::InfoDizAbsent); } void InfoList::ShowPluginDescription() { - Panel *AnotherPanel; - static wchar_t VertcalLine[2] = {BoxSymbols[BS_V2], 0}; - AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); + Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); if (AnotherPanel->GetMode() != PLUGIN_PANEL) return; - CloseFile(); OpenPluginInfo Info; AnotherPanel->GetOpenPluginInfo(&Info); + if (Info.InfoLinesNumber <= 0) + return; + + static wchar_t VertcalLine[2] = {BoxSymbols[BS_V2], 0}; + int Y; + + /*if (!SectionState[ILSS_PLDESCRIPTION].Show) { + Y = Y2 - 1; + DrawTitle(L"Plugin", ILSS_PLDESCRIPTION, Y); + return; + } + Y = Y2 - Info.InfoLinesNumber - 1; + DrawTitle(L"Plugin", ILSS_PLDESCRIPTION, Y);*/ for (int I = 0; I < Info.InfoLinesNumber; I++) { - int Y = Y2 - Info.InfoLinesNumber + I; + Y = Y2 - Info.InfoLinesNumber + I; - if (Y <= Y1) + if (Y <= Y1 + 1) continue; const InfoPanelLine *InfoLine = &Info.InfoLines[I]; diff --git a/far2l/src/panels/infolist.hpp b/far2l/src/panels/infolist.hpp index afa55f2c4..02621bb15 100644 --- a/far2l/src/panels/infolist.hpp +++ b/far2l/src/panels/infolist.hpp @@ -76,9 +76,12 @@ class InfoList : public Panel int OldWrapMode; int OldWrapType; FARString strDizFileName; + struct InfoListSectionState; + std::vector SectionState; private: virtual void DisplayObject(); + void ShowGitStatus(int &YPos); void ShowDirDescription(int YPos); void ShowPluginDescription(); @@ -86,6 +89,8 @@ class InfoList : public Panel void PrintText(FarLangMsg MsgID); void PrintInfo(const wchar_t *Str); void PrintInfo(FarLangMsg MsgID); + void DrawTitle(const wchar_t *Str, int Id, int &CurY); + void DrawTitle(FarLangMsg MsgID, int Id, int &CurY); int OpenDizFile(const wchar_t *DizFile, int YPos); void SetMacroMode(int Restore = FALSE); From 43cfbfb8f2d327757e94f29244b53ceaa286ec9a Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:16:14 +0300 Subject: [PATCH 03/16] minor --- far2l/src/panels/infolist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index 673f6f3ee..e82a619e3 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -781,7 +781,7 @@ void InfoList::ShowPluginDescription() for (int I = 0; I < Info.InfoLinesNumber; I++) { Y = Y2 - Info.InfoLinesNumber + I; - if (Y <= Y1 + 1) + if (Y <= Y1) continue; const InfoPanelLine *InfoLine = &Info.InfoLines[I]; From e80d11ef24e2c90b1629a3d57c18587b7b018faa Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Sat, 2 Nov 2024 10:40:10 +0300 Subject: [PATCH 04/16] infolist: last block (dir/plugin description) never hidden + code clean up --- far2l/bootstrap/scripts/farlang.templ.m4 | 22 +++++ far2l/src/panels/infolist.cpp | 109 +++++++++++------------ far2l/src/panels/infolist.hpp | 6 +- 3 files changed, 77 insertions(+), 60 deletions(-) diff --git a/far2l/bootstrap/scripts/farlang.templ.m4 b/far2l/bootstrap/scripts/farlang.templ.m4 index 1b0ce20d3..162c3d03e 100644 --- a/far2l/bootstrap/scripts/farlang.templ.m4 +++ b/far2l/bootstrap/scripts/farlang.templ.m4 @@ -13337,6 +13337,28 @@ InfoDizAbsent "Файл опису теки відсутній" "Файл апісання каталога адсутнічае" +InfoPluginDescription +"Описание от плагина" +"Plugin Description" +"Plugin Popis" +"Plugin Beschreibung" +"Plugin Megjegyzés" +"Plugin Opis" +"Plugin Descripción" +"Опис від модуля" +"Апісанне ад дадаткі" + +InfoPluginAbsent +"Расширенная информация от плагина отсутствует" +"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" +upd:"Plugin information is absent" + ErrorInvalidFunction l: "Некорректная функция" diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index e82a619e3..92426666d 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -74,8 +74,8 @@ enum InfoListSectionStateIndex ILSS_DISKINFO, ILSS_MEMORYINFO, ILSS_GITINFO, - ILSS_DIRDESCRIPTION, - /*ILSS_PLDESCRIPTION, + /*ILSS_DIRDESCRIPTION, + ILSS_PLDESCRIPTION, ILSS_POWERSTATUS,*/ ILSS_SIZE @@ -127,7 +127,7 @@ FARString &InfoList::GetTitle(FARString &strTitle, int SubLen, int TruncSize) return strTitle; } -void InfoList::DrawTitle(const wchar_t *Str, int Id, int &CurY) +void InfoList::DrawTitle(const wchar_t *Str, int Id, int CurY) { SetFarColor(COL_PANELBOX); DrawSeparator(CurY); @@ -140,13 +140,14 @@ void InfoList::DrawTitle(const wchar_t *Str, int Id, int &CurY) GotoXY(X1 + (X2 - X1 + 1 - (int)strTitle.GetLength()) / 2, CurY); PrintText(strTitle); } - GotoXY(X1 + 1, CurY); - PrintText(SectionState[Id].Show ? L"[-]" : L"[+]"); - SectionState[Id].Y=CurY; - CurY++; + if (Id >= 0 && Id < ILSS_SIZE ) { + GotoXY(X1 + 1, CurY); + PrintText(SectionState[Id].Show ? L"[-]" : L"[+]"); + SectionState[Id].Y = CurY; + } } -inline void InfoList::DrawTitle(FarLangMsg MsgID, int Id, int &CurY) +inline void InfoList::DrawTitle(FarLangMsg MsgID, int Id, int CurY) { DrawTitle(MsgID.CPtr(), Id, CurY); } @@ -214,7 +215,7 @@ void InfoList::DisplayObject() } else // Error! strTitle = strCurDir; // strDriveRoot; - DrawTitle(strTitle.CPtr(), ILSS_DISKINFO, CurY); + DrawTitle(strTitle.CPtr(), ILSS_DISKINFO, CurY++); if (SectionState[ILSS_DISKINFO].Show) { /* #2a.2 - disk info: size */ @@ -328,7 +329,7 @@ void InfoList::DisplayObject() } /* 2b - plugin */ else { - DrawTitle(Msg::InfoPluginTitle, ILSS_DISKINFO, CurY); + DrawTitle(Msg::InfoPluginTitle, ILSS_DISKINFO, CurY++); if (SectionState[ILSS_DISKINFO].Show) { GotoXY(X1 + 2, CurY++); PrintText(Msg::InfoPluginStartDir); @@ -368,7 +369,7 @@ void InfoList::DisplayObject() } /* #3 - memory info */ - DrawTitle(Msg::InfoMemory, ILSS_MEMORYINFO, CurY); + DrawTitle(Msg::InfoMemory, ILSS_MEMORYINFO, CurY++); if (SectionState[ILSS_MEMORYINFO].Show) { #ifdef __APPLE__ @@ -457,6 +458,7 @@ void InfoList::DisplayObject() } #endif } + /* #4 - git status */ ShowGitStatus(CurY); @@ -464,7 +466,7 @@ void InfoList::DisplayObject() ShowDirDescription(CurY); /* #6 - plugin description */ - ShowPluginDescription(); + ShowPluginDescription(CurY); } int64_t InfoList::VMProcess(MacroOpcode OpCode, void *vParam, int64_t iParam) @@ -667,38 +669,39 @@ void InfoList::ShowGitStatus(int &YPos) { Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); - if (AnotherPanel->GetMode() == FILE_PANEL) { - FARString strDir; - AnotherPanel->GetCurDir(strDir); - do { - FARString strGit = strDir + L"/.git"; - struct stat s; - if (stat(strGit.GetMB().c_str(), &s) == 0) { - fprintf(stderr, "GIT: %ls\n", strGit.CPtr()); - std::vector lines; - std::string cmd = "git -C \""; - cmd+= EscapeCmdStr(Wide2MB(strDir.CPtr())); - cmd+= "\" status -s -b"; - - if (POpen(lines, cmd.c_str())) { - // text " git status " in separator - DrawTitle(L"git status -s -b", ILSS_GITINFO, YPos); - if (SectionState[ILSS_GITINFO].Show) { - // print git root dir + if (AnotherPanel->GetMode() != FILE_PANEL) + return; + + FARString strDir; + AnotherPanel->GetCurDir(strDir); + do { + FARString strGit = strDir + L"/.git"; + struct stat s; + if (stat(strGit.GetMB().c_str(), &s) == 0) { + fprintf(stderr, "GIT: %ls\n", strGit.CPtr()); + std::vector lines; + std::string cmd = "git -C \""; + cmd+= EscapeCmdStr(Wide2MB(strDir.CPtr())); + cmd+= "\" status -s -b"; + + if (POpen(lines, cmd.c_str())) { + // text " git status " in separator + DrawTitle(L"git status -s -b", ILSS_GITINFO, YPos++); + if (SectionState[ILSS_GITINFO].Show) { + // print git root dir + GotoXY(X1 + 2, YPos++); + PrintText(Msg::InfoGitRootDir); + PrintInfo(strDir); + // print result of git status + for (const auto &l : lines) { GotoXY(X1 + 2, YPos++); - PrintText(Msg::InfoGitRootDir); - PrintInfo(strDir); - // print result of git status - for (const auto &l : lines) { - GotoXY(X1 + 2, YPos++); - PrintText(l.c_str()); - } + PrintText(l.c_str()); } } - break; } - } while (CutToSlash(strDir, true)); - } + break; + } + } while (CutToSlash(strDir, true)); } void InfoList::ShowDirDescription(int YPos) @@ -707,12 +710,7 @@ void InfoList::ShowDirDescription(int YPos) if (AnotherPanel->GetMode() != FILE_PANEL) return; - if (!SectionState[ILSS_DIRDESCRIPTION].Show) { - DrawTitle(Msg::InfoDescription, ILSS_DIRDESCRIPTION, YPos); - return; - } - - DrawTitle(nullptr, ILSS_DIRDESCRIPTION, YPos); + DrawTitle(nullptr, -1/*ILSS_DIRDESCRIPTION*/, YPos); FARString strDir; AnotherPanel->GetCurDir(strDir); @@ -736,7 +734,7 @@ void InfoList::ShowDirDescription(int YPos) CutToSlash(strFullDizName, false); strFullDizName+= FindData.strFileName; - if (OpenDizFile(strFullDizName, YPos - 1)) + if (OpenDizFile(strFullDizName, YPos)) return; } @@ -746,7 +744,7 @@ void InfoList::ShowDirDescription(int YPos) strDir += Msg::InfoDescription; strDir += L" "; TruncStr(strDir, X2 - X1 - 3); - GotoXY(X1 + (X2 - X1 - (int)strDir.GetLength()) / 2, YPos - 1); + GotoXY(X1 + (X2 - X1 - (int)strDir.GetLength()) / 2, YPos++); SetFarColor(COL_PANELTEXT); PrintText(strDir); @@ -755,7 +753,7 @@ void InfoList::ShowDirDescription(int YPos) PrintText(Msg::InfoDizAbsent); } -void InfoList::ShowPluginDescription() +void InfoList::ShowPluginDescription(int YPos) { Panel *AnotherPanel = CtrlObject->Cp()->GetAnotherPanel(this); @@ -765,19 +763,16 @@ void InfoList::ShowPluginDescription() OpenPluginInfo Info; AnotherPanel->GetOpenPluginInfo(&Info); - if (Info.InfoLinesNumber <= 0) + if (Info.InfoLinesNumber <= 0) { + DrawTitle(Msg::InfoPluginDescription, -1/*ILSS_DIRDESCRIPTION*/, YPos++); + GotoXY(X1 + 2, YPos); + PrintText(Msg::InfoPluginAbsent); return; + } static wchar_t VertcalLine[2] = {BoxSymbols[BS_V2], 0}; int Y; - /*if (!SectionState[ILSS_PLDESCRIPTION].Show) { - Y = Y2 - 1; - DrawTitle(L"Plugin", ILSS_PLDESCRIPTION, Y); - return; - } - Y = Y2 - Info.InfoLinesNumber - 1; - DrawTitle(L"Plugin", ILSS_PLDESCRIPTION, Y);*/ for (int I = 0; I < Info.InfoLinesNumber; I++) { Y = Y2 - Info.InfoLinesNumber + I; diff --git a/far2l/src/panels/infolist.hpp b/far2l/src/panels/infolist.hpp index 02621bb15..ead582617 100644 --- a/far2l/src/panels/infolist.hpp +++ b/far2l/src/panels/infolist.hpp @@ -83,14 +83,14 @@ class InfoList : public Panel virtual void DisplayObject(); void ShowGitStatus(int &YPos); void ShowDirDescription(int YPos); - void ShowPluginDescription(); + void ShowPluginDescription(int YPos); void PrintText(const wchar_t *Str); void PrintText(FarLangMsg MsgID); void PrintInfo(const wchar_t *Str); void PrintInfo(FarLangMsg MsgID); - void DrawTitle(const wchar_t *Str, int Id, int &CurY); - void DrawTitle(FarLangMsg MsgID, int Id, int &CurY); + void DrawTitle(const wchar_t *Str, int Id, int CurY); + void DrawTitle(FarLangMsg MsgID, int Id, int CurY); int OpenDizFile(const wchar_t *DizFile, int YPos); void SetMacroMode(int Restore = FALSE); From 1bf465e9bf998c24079f6b3aa63a61cab9cb568a Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Sat, 2 Nov 2024 13:13:36 +0300 Subject: [PATCH 05/16] farabout: show Plugin Strings in separate lines (usefull for lots of DiskMenuStrings, PluginMenuStrings & PluginConfigStrings after py:load in python plugin) --- far2l/src/cmdline.cpp | 49 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/far2l/src/cmdline.cpp b/far2l/src/cmdline.cpp index 7d0651af4..635149771 100644 --- a/far2l/src/cmdline.cpp +++ b/far2l/src/cmdline.cpp @@ -1044,54 +1044,55 @@ void FarAbout(PluginManager &Plugins) ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; int iFlags; + int j; PluginInfo pInfo{}; KeyFileReadHelper kfh(PluginsIni()); FARString fsCommandPrefix = L""; - FARString fsDiskMenuStrings = L""; - FARString fsPluginMenuStrings = L""; - FARString fsPluginConfigStrings = L""; + std::vector fsDiskMenuStrings; + std::vector fsPluginMenuStrings; + std::vector fsPluginConfigStrings; if (pPlugin->CheckWorkFlags(PIWF_CACHED)) { iFlags = kfh.GetUInt(pPlugin->GetSettingsName(), "Flags", 0); fsCommandPrefix = kfh.GetString(pPlugin->GetSettingsName(), "CommandPrefix", L""); - for (int j = 0; ; j++) { + for (j = 0; ; j++) { const auto &key_name = StrPrintf("DiskMenuString%d", j); /*if (!kfh.HasKey(key_name)) break;*/ fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); if( fs2.IsEmpty() ) break; - fsDiskMenuStrings.AppendFormat(L" %d=\"%ls\" ", j+1, fs2.CPtr()); + fsDiskMenuStrings.emplace_back(fs2); } - for (int j = 0; ; j++) { + for (j = 0; ; j++) { const auto &key_name = StrPrintf("PluginMenuString%d", j); /*if (!kfh.HasKey(key_name)) break;*/ fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); if( fs2.IsEmpty() ) break; - fsPluginMenuStrings.AppendFormat(L" %d=\"%ls\" ", j+1, fs2.CPtr()); + fsPluginMenuStrings.emplace_back(fs2); } - for (int j = 0; ; j++) { + for (j = 0; ; j++) { const auto &key_name = StrPrintf("PluginConfigString%d", j); /*if (!kfh.HasKey(key_name)) break;*/ fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); if( fs2.IsEmpty() ) break; - fsPluginConfigStrings.AppendFormat(L" %d=\"%ls\" ", j+1, fs2.CPtr()); + fsPluginConfigStrings.emplace_back(fs2); } } else { if (pPlugin->GetPluginInfo(&pInfo)) { iFlags = pInfo.Flags; fsCommandPrefix = pInfo.CommandPrefix; - for (int j = 0; j < pInfo.DiskMenuStringsNumber; j++) - fsDiskMenuStrings.AppendFormat(L" %d=\"%ls\"", j+1, pInfo.DiskMenuStrings[j]); - for (int j = 0; j < pInfo.PluginMenuStringsNumber; j++) - fsPluginMenuStrings.AppendFormat(L" %d=\"%ls\"", j+1, pInfo.PluginMenuStrings[j]); - for (int j = 0; j < pInfo.PluginConfigStringsNumber; j++) - fsPluginConfigStrings.AppendFormat(L" %d=\"%ls\"", j+1, pInfo.PluginConfigStrings[j]); + for (j = 0; j < pInfo.DiskMenuStringsNumber; j++) + fsDiskMenuStrings.emplace_back(pInfo.DiskMenuStrings[j]); + for (j = 0; j < pInfo.PluginMenuStringsNumber; j++) + fsPluginMenuStrings.emplace_back(pInfo.PluginMenuStrings[j]); + for (j = 0; j < pInfo.PluginConfigStringsNumber; j++) + fsPluginConfigStrings.emplace_back(pInfo.PluginConfigStrings[j]); } else iFlags = -1; @@ -1116,16 +1117,22 @@ void FarAbout(PluginManager &Plugins) mi.strName.Format(L"%ls %s EditorInput ", fs.CPtr(), pPlugin->HasProcessEditorInput() ? "[x]" : "[ ]"); ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - if ( !fsDiskMenuStrings.IsEmpty() ) { - mi.strName = fs + L" DiskMenuStrings:" + fsDiskMenuStrings; + j = 0; + for (auto& fs_vec : fsDiskMenuStrings) { + j++; + mi.strName.Format(L"%ls DiskMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; } - if ( !fsPluginMenuStrings.IsEmpty() ) { - mi.strName = fs + L" PluginMenuStrings:" + fsPluginMenuStrings; + j = 0; + for (auto& fs_vec : fsPluginMenuStrings) { + j++; + mi.strName.Format(L"%ls PluginMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; } - if ( !fsPluginConfigStrings.IsEmpty() ) { - mi.strName = fs + L"PluginConfigStrings:" + fsPluginConfigStrings; + j = 0; + for (auto& fs_vec : fsPluginConfigStrings) { + j++; + mi.strName.Format(L"%ls PluginConfigString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; } if ( !fsCommandPrefix.IsEmpty() ) { From 18228547163a79d5cac59a1e7622a8fbf4bd1ddd Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 3 Nov 2024 23:36:55 +0100 Subject: [PATCH 06/16] - fixed alt+letters workaround applying conditions - fixed keyup event doubling if window focus is lost - better logging --- WinPort/src/Backend/WX/wxMain.cpp | 31 +++++++++++++++++++++++-------- WinPort/src/ConsoleInput.cpp | 3 ++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index f37990fa7..4946ab0a0 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -131,6 +131,12 @@ extern "C" __attribute__ ((visibility("default"))) bool WinPortMainBackend(WinPo if (!wxInitialize()) return false; + fprintf(stderr, "FAR2L wxWidgets build version %d.%d.%d\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ); +#if wxCHECK_VERSION(2, 9, 2) + wxVersionInfo wxv = wxGetLibraryVersionInfo(); + fprintf(stderr, "FAR2L wxWidgets use version %d.%d.%d\n", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro() ); +#endif + wxSetAssertHandler(WinPortWxAssertHandler); DetectHostAbilities(); @@ -1224,7 +1230,11 @@ const char* GetWxVirtualKeyCodeName(int keycode) #undef WXK_ default: - return "ERR"; + + static char buffer[20] = {0}; + snprintf(buffer, sizeof(buffer), + ((keycode >= 20) && (keycode <= 0x7f)) ? "\"%c\"" : "%d", keycode); + return buffer; } } @@ -1291,11 +1301,11 @@ void WinPortPanel::OnKeyDown( wxKeyEvent& event ) ResetTimerIdling(); DWORD now = WINPORT(GetTickCount)(); const auto uni = event.GetUnicodeKey(); - fprintf(stderr, "\nOnKeyDown: %s %s raw=%x code=%x uni=%x (%lc) ts=%lu [now=%u]", + fprintf(stderr, "\nOnKeyDown: %s %s raw=%x code=%x uni=%x \"%lc\" ts=%lu [now=%u]", FormatWxKeyState(event.GetModifiers()), GetWxVirtualKeyCodeName(event.GetKeyCode()), event.GetRawKeyCode(), event.GetKeyCode(), - uni, (uni > 0x1f) ? uni : L' ', event.GetTimestamp(), now); + uni, (uni > 0x1f) ? uni : L'?', event.GetTimestamp(), now); _exclusive_hotkeys.OnKeyDown(event, _frame); @@ -1429,16 +1439,17 @@ void WinPortPanel::OnKeyUp( wxKeyEvent& event ) { ResetTimerIdling(); const auto uni = event.GetUnicodeKey(); - fprintf(stderr, "\nOnKeyUp: %s %s raw=%x code=%x uni=%x (%lc) ts=%lu", + fprintf(stderr, "\nOnKeyUp: %s %s raw=%x code=%x uni=%x \"%lc\" ts=%lu", FormatWxKeyState(event.GetModifiers()), GetWxVirtualKeyCodeName(event.GetKeyCode()), event.GetRawKeyCode(), event.GetKeyCode(), - uni, (uni > 0x1f) ? uni : L' ', event.GetTimestamp()); + uni, (uni > 0x1f) ? uni : L'?', event.GetTimestamp()); _exclusive_hotkeys.OnKeyUp(event); if (_enqueued_in_onchar) { _enqueued_in_onchar = false; + fprintf(stderr, " IN_ONCHAR\n"); return; } @@ -1531,11 +1542,11 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) if (_key_tracker.LastKeydown().GetTimestamp() != event.GetTimestamp()) { fprintf(stderr, "\n"); } - fprintf(stderr, "OnChar: %s %s raw=%x code=%x uni=%x (%lc) ts=%lu lke=%u", + fprintf(stderr, "\nOnChar: %s %s raw=%x code=%x uni=%x \"%lc\" ts=%lu lke=%u", FormatWxKeyState(event.GetModifiers()), GetWxVirtualKeyCodeName(event.GetKeyCode()), event.GetRawKeyCode(), event.GetKeyCode(), - uni, (uni > 0x1f) ? uni : L' ', event.GetTimestamp(), _last_keydown_enqueued); + uni, (uni > 0x1f) ? uni : L'?', event.GetTimestamp(), _last_keydown_enqueued); _exclusive_hotkeys.OnKeyUp(event); if (event.GetSkipped()) { @@ -1566,7 +1577,7 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.uChar.UnicodeChar = event.GetUnicodeKey(); #if !defined(__WXOSX__) && wxCHECK_VERSION(3, 2, 3) - if (event.AltDown()) { + if (event.AltDown() && isLayoutDependentKey(event)) { // workaround for wx issue #23421 @@ -1578,6 +1589,10 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.dwControlKeyState = ir_tmp.Event.KeyEvent.dwControlKeyState; ir.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; + + // avoid double up event in ResetInputState() + wxKeyEvent keyEventCopy = _key_tracker.LastKeydown(); + _key_tracker.OnKeyUp(keyEventCopy); } #endif diff --git a/WinPort/src/ConsoleInput.cpp b/WinPort/src/ConsoleInput.cpp index 2e7ff8dbd..6fab4ae69 100644 --- a/WinPort/src/ConsoleInput.cpp +++ b/WinPort/src/ConsoleInput.cpp @@ -301,10 +301,11 @@ void ConsoleInput::Enqueue(const INPUT_RECORD *data, DWORD size) if (size) { for (DWORD i = 0; i < size; ++i) { if (data[i].EventType == KEY_EVENT) { + const auto uni = data[i].Event.KeyEvent.uChar.UnicodeChar; fprintf(stderr, "ConsoleInput::Enqueue: %s %s \"%lc\" %s, %x %x %x %x\n", FormatKeyState(data[i].Event.KeyEvent.dwControlKeyState), VirtualKeyNames[data[i].Event.KeyEvent.wVirtualKeyCode], - data[i].Event.KeyEvent.uChar.UnicodeChar ? data[i].Event.KeyEvent.uChar.UnicodeChar : '#', + uni && (uni > 0x1f) ? uni : L'?', data[i].Event.KeyEvent.bKeyDown ? "DOWN" : "UP", data[i].Event.KeyEvent.dwControlKeyState, From 9bdaf2efbd576158aaf1126b4fdf3491ffd21517 Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:54:54 +0300 Subject: [PATCH 07/16] farabout: show WX version BUILD & USE - special for @unxed Transfer info from far2l_gui.so to main far2l via setenv may be not elegant, but inside code I couldn't implement it --- WinPort/src/Backend/WX/wxMain.cpp | 6 ++++++ far2l/src/cmdline.cpp | 1 + 2 files changed, 7 insertions(+) diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index 18ea2f548..6041c6429 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -132,9 +132,15 @@ extern "C" __attribute__ ((visibility("default"))) bool WinPortMainBackend(WinPo return false; fprintf(stderr, "FAR2L wxWidgets build version %d.%d.%d\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ); + char s_wx_build[15]; + snprintf(s_wx_build, ARRAYSIZE(s_wx_build), "%d.%d.%d", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ); + setenv("FAR2L_WX_BUILD", s_wx_build, 1); #if wxCHECK_VERSION(2, 9, 2) wxVersionInfo wxv = wxGetLibraryVersionInfo(); fprintf(stderr, "FAR2L wxWidgets use version %d.%d.%d\n", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro() ); + char s_wx_use[15]; + snprintf(s_wx_use, ARRAYSIZE(s_wx_use), "%d.%d.%d", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro() ); + setenv("FAR2L_WX_USE", s_wx_use, 1); #endif wxSetAssertHandler(WinPortWxAssertHandler); diff --git a/far2l/src/cmdline.cpp b/far2l/src/cmdline.cpp index 635149771..6ae9e0f8f 100644 --- a/far2l/src/cmdline.cpp +++ b/far2l/src/cmdline.cpp @@ -994,6 +994,7 @@ void FarAbout(PluginManager &Plugins) static const char * const env_vars[] = { "HOSTNAME", "USER", + "FAR2L_WX_BUILD", "FAR2L_WX_USE", "FARSETTINGS", "FAR2L_ARGS", "XDG_SESSION_TYPE", "TERM", "COLORTERM", From c71c0432106f9212b9bbe2b12a869141b1370c0b Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Mon, 4 Nov 2024 15:07:07 +0100 Subject: [PATCH 08/16] double keyup fix is also needed for plain chars without alt --- 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 4946ab0a0..829b51d53 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -1589,10 +1589,6 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.dwControlKeyState = ir_tmp.Event.KeyEvent.dwControlKeyState; ir.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; - - // avoid double up event in ResetInputState() - wxKeyEvent keyEventCopy = _key_tracker.LastKeydown(); - _key_tracker.OnKeyUp(keyEventCopy); } #endif @@ -1602,6 +1598,10 @@ void WinPortPanel::OnChar( wxKeyEvent& event ) ir.Event.KeyEvent.bKeyDown = FALSE; wxConsoleInputShim::Enqueue(&ir, 1); + // avoid double up event in ResetInputState() + wxKeyEvent keyEventCopy = _key_tracker.LastKeydown(); + _key_tracker.OnKeyUp(keyEventCopy); + _enqueued_in_onchar = true; } //event.Skip(); From 1777cb386677f17d1dacad34d474c59119b63d5f Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Mon, 4 Nov 2024 17:26:52 +0100 Subject: [PATCH 09/16] more detailed log --- WinPort/src/ConsoleInput.cpp | 208 +++++++++++++++++------------------ 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/WinPort/src/ConsoleInput.cpp b/WinPort/src/ConsoleInput.cpp index 6fab4ae69..545db2f73 100644 --- a/WinPort/src/ConsoleInput.cpp +++ b/WinPort/src/ConsoleInput.cpp @@ -2,33 +2,33 @@ #include "ConsoleInput.h" const char* VirtualKeyNames[] = { - "ERR", // 0x00 + "0x00", // 0x00 "VK_LBUTTON", // 0x01 "VK_RBUTTON", // 0x02 "VK_CANCEL", // 0x03 "VK_MBUTTON", // 0x04 "VK_XBUTTON1", // 0x05 "VK_XBUTTON2", // 0x06 - "ERR", // 0x07 + "0x07", // 0x07 "VK_BACK", // 0x08 "VK_TAB", // 0x09 - "ERR", // 0x0A - "ERR", // 0x0B + "0x0A", // 0x0A + "0x0B", // 0x0B "VK_CLEAR", // 0x0C "VK_RETURN", // 0x0D - "ERR", // 0x0E - "ERR", // 0x0F + "0x0E", // 0x0E + "0x0F", // 0x0F "VK_SHIFT", // 0x10 "VK_CONTROL", // 0x11 "VK_MENU", // 0x12 "VK_PAUSE", // 0x13 "VK_CAPITAL", // 0x14 "VK_HANGUEL", // 0x15 - "ERR", // 0x16 + "0x16", // 0x16 "VK_JUNJA", // 0x17 "VK_FINAL", // 0x18 "VK_HANJA", // 0x19 - "ERR", // 0x1A + "0x1A", // 0x1A "VK_ESCAPE", // 0x1B "VK_CONVERT", // 0x1C "VK_NONCONVERT", // 0x1D @@ -60,13 +60,13 @@ const char* VirtualKeyNames[] = { "VK_7", // 0x37 "VK_8", // 0x38 "VK_9", // 0x39 - "ERR", // 0x3A - "ERR", // 0x3B - "ERR", // 0x3C - "ERR", // 0x3D - "ERR", // 0x3E - "ERR", // 0x3F - "ERR", // 0x40 + "0x3A", // 0x3A + "0x3B", // 0x3B + "0x3C", // 0x3C + "0x3D", // 0x3D + "0x3E", // 0x3E + "0x3F", // 0x3F + "0x40", // 0x40 "VK_A", // 0x41 "VK_B", // 0x42 "VK_C", // 0x43 @@ -96,7 +96,7 @@ const char* VirtualKeyNames[] = { "VK_LWIN", // 0x5B "VK_RWIN", // 0x5C "VK_APPS", // 0x5D - "ERR", // 0x5E + "0x5E", // 0x5E "VK_SLEEP", // 0x5F "VK_NUMPAD0", // 0x60 "VK_NUMPAD1", // 0x61 @@ -138,56 +138,56 @@ const char* VirtualKeyNames[] = { "VK_F22", // 0x85 "VK_F23", // 0x86 "VK_F24", // 0x87 - "ERR", // 0x88 - "ERR", // 0x89 - "ERR", // 0x8A - "ERR", // 0x8B - "ERR", // 0x8C - "ERR", // 0x8D - "ERR", // 0x8E - "ERR", // 0x8F + "0x88", // 0x88 + "0x89", // 0x89 + "0x8A", // 0x8A + "0x8B", // 0x8B + "0x8C", // 0x8C + "0x8D", // 0x8D + "0x8E", // 0x8E + "0x8F", // 0x8F "VK_NUMLOCK", // 0x90 "VK_SCROLL", // 0x91 - "ERR", // 0x92 - "ERR", // 0x93 - "ERR", // 0x94 - "ERR", // 0x95 - "ERR", // 0x96 - "ERR", // 0x97 - "ERR", // 0x98 - "ERR", // 0x99 - "ERR", // 0x9A - "ERR", // 0x9B - "ERR", // 0x9C - "ERR", // 0x9D - "ERR", // 0x9E - "ERR", // 0x9F + "0x92", // 0x92 + "0x93", // 0x93 + "0x94", // 0x94 + "0x95", // 0x95 + "0x96", // 0x96 + "0x97", // 0x97 + "0x98", // 0x98 + "0x99", // 0x99 + "0x9A", // 0x9A + "0x9B", // 0x9B + "0x9C", // 0x9C + "0x9D", // 0x9D + "0x9E", // 0x9E + "0x9F", // 0x9F "VK_LSHIFT", // 0xA0 "VK_RSHIFT", // 0xA1 "VK_LCONTROL", // 0xA2 "VK_RCONTROL", // 0xA3 "VK_LMENU", // 0xA4 "VK_RMENU", // 0xA5 - "VK_BROWSER_BACK", // 0xA6 - "VK_BROWSER_FORWARD", // 0xA7 - "VK_BROWSER_REFRESH", // 0xA8 - "VK_BROWSER_STOP", // 0xA9 - "VK_BROWSER_SEARCH", // 0xAA - "VK_BROWSER_FAVORITES", // 0xAB - "VK_BROWSER_HOME", // 0xAC - "VK_VOLUME_MUTE", // 0xAD - "VK_VOLUME_DOWN", // 0xAE - "VK_VOLUME_UP", // 0xAF - "VK_MEDIA_NEXT_TRACK", // 0xB0 - "VK_MEDIA_PREV_TRACK", // 0xB1 - "VK_MEDIA_STOP", // 0xB2 - "VK_MEDIA_PLAY_PAUSE", // 0xB3 - "VK_LAUNCH_MAIL", // 0xB4 - "VK_LAUNCH_MEDIA_SELECT", // 0xB5 - "VK_LAUNCH_APP1", // 0xB6 - "VK_LAUNCH_APP2", // 0xB7 - "ERR", // 0xB8 - "ERR", // 0xB9 + "VK_BROWSER_BACK", // 0xA6 + "VK_BROWSER_FORWARD", // 0xA7 + "VK_BROWSER_REFRESH", // 0xA8 + "VK_BROWSER_STOP", // 0xA9 + "VK_BROWSER_SEARCH", // 0xAA + "VK_BROWSER_FAVORITES", // 0xAB + "VK_BROWSER_HOME", // 0xAC + "VK_VOLUME_MUTE", // 0xAD + "VK_VOLUME_DOWN", // 0xAE + "VK_VOLUME_UP", // 0xAF + "VK_MEDIA_NEXT_TRACK", // 0xB0 + "VK_MEDIA_PREV_TRACK", // 0xB1 + "VK_MEDIA_STOP", // 0xB2 + "VK_MEDIA_PLAY_PAUSE", // 0xB3 + "VK_LAUNCH_MAIL", // 0xB4 + "VK_LAUNCH_MEDIA_SELECT", // 0xB5 + "VK_LAUNCH_APP1", // 0xB6 + "VK_LAUNCH_APP2", // 0xB7 + "0xB8", // 0xB8 + "0xB9", // 0xB9 "VK_OEM_1", // 0xBA "VK_OEM_PLUS", // 0xBB "VK_OEM_COMMA", // 0xBC @@ -195,59 +195,59 @@ const char* VirtualKeyNames[] = { "VK_OEM_PERIOD", // 0xBE "VK_OEM_2", // 0xBF "VK_OEM_3", // 0xC0 - "ERR", // 0xC1 - "ERR", // 0xC2 - "ERR", // 0xC3 - "ERR", // 0xC4 - "ERR", // 0xC5 - "ERR", // 0xC6 - "ERR", // 0xC7 - "ERR", // 0xC8 - "ERR", // 0xC9 - "ERR", // 0xCA - "ERR", // 0xCB - "ERR", // 0xCC - "ERR", // 0xCD - "ERR", // 0xCE - "ERR", // 0xCF - "ERR", // 0xD0 - "ERR", // 0xD1 - "ERR", // 0xD2 - "ERR", // 0xD3 - "ERR", // 0xD4 - "ERR", // 0xD5 - "ERR", // 0xD6 - "ERR", // 0xD7 - "ERR", // 0xD8 - "ERR", // 0xD9 - "ERR", // 0xDA + "0xC1", // 0xC1 + "0xC2", // 0xC2 + "0xC3", // 0xC3 + "0xC4", // 0xC4 + "0xC5", // 0xC5 + "0xC6", // 0xC6 + "0xC7", // 0xC7 + "0xC8", // 0xC8 + "0xC9", // 0xC9 + "0xCA", // 0xCA + "0xCB", // 0xCB + "0xCC", // 0xCC + "0xCD", // 0xCD + "0xCE", // 0xCE + "0xCF", // 0xCF + "0xD0", // 0xD0 + "0xD1", // 0xD1 + "0xD2", // 0xD2 + "0xD3", // 0xD3 + "0xD4", // 0xD4 + "0xD5", // 0xD5 + "0xD6", // 0xD6 + "0xD7", // 0xD7 + "0xD8", // 0xD8 + "0xD9", // 0xD9 + "0xDA", // 0xDA "VK_OEM_4", // 0xDB "VK_OEM_5", // 0xDC "VK_OEM_6", // 0xDD "VK_OEM_7", // 0xDE "VK_OEM_8", // 0xDF - "ERR", // 0xE0 - "ERR", // 0xE1 + "0xE0", // 0xE0 + "0xE1", // 0xE1 "VK_OEM_102", // 0xE2 - "ERR", // 0xE3 - "ERR", // 0xE4 + "0xE3", // 0xE3 + "0xE4", // 0xE4 "VK_PROCESSKEY", // 0xE5 - "ERR", // 0xE6 + "0xE6", // 0xE6 "VK_PACKET", // 0xE7 - "ERR", // 0xE8 - "ERR", // 0xE9 - "ERR", // 0xEA - "ERR", // 0xEB - "ERR", // 0xEC - "ERR", // 0xED - "ERR", // 0xEE - "ERR", // 0xEF - "ERR", // 0xF0 - "ERR", // 0xF1 - "ERR", // 0xF2 - "ERR", // 0xF3 - "ERR", // 0xF4 - "ERR", // 0xF5 + "0xE8", // 0xE8 + "0xE9", // 0xE9 + "0xEA", // 0xEA + "0xEB", // 0xEB + "0xEC", // 0xEC + "0xED", // 0xED + "0xEE", // 0xEE + "0xEF", // 0xEF + "0xF0", // 0xF0 + "0xF1", // 0xF1 + "0xF2", // 0xF2 + "0xF3", // 0xF3 + "0xF4", // 0xF4 + "0xF5", // 0xF5 "VK_ATTN", // 0xF6 "VK_CRSEL", // 0xF7 "VK_EXSEL", // 0xF8 @@ -305,7 +305,7 @@ void ConsoleInput::Enqueue(const INPUT_RECORD *data, DWORD size) fprintf(stderr, "ConsoleInput::Enqueue: %s %s \"%lc\" %s, %x %x %x %x\n", FormatKeyState(data[i].Event.KeyEvent.dwControlKeyState), VirtualKeyNames[data[i].Event.KeyEvent.wVirtualKeyCode], - uni && (uni > 0x1f) ? uni : L'?', + (uni && (uni > 0x1f)) ? uni : L'?', data[i].Event.KeyEvent.bKeyDown ? "DOWN" : "UP", data[i].Event.KeyEvent.dwControlKeyState, From da8519d3a92751567d9fd5abfeef8966fb5b4f9b Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 6 Nov 2024 14:40:11 +0400 Subject: [PATCH 10/16] Fix redraw in filtered menu (see Mantis 0001794) --- far2l/src/vmenu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/far2l/src/vmenu.cpp b/far2l/src/vmenu.cpp index 37205f690..82fc87874 100644 --- a/far2l/src/vmenu.cpp +++ b/far2l/src/vmenu.cpp @@ -1584,6 +1584,7 @@ void VMenu::DrawEdges() { if (!CheckFlags(VMENU_DISABLEDRAWBACKGROUND) && !CheckFlags(VMENU_LISTBOX)) { if (BoxType == SHORT_DOUBLE_BOX || BoxType == SHORT_SINGLE_BOX) { + SetScreen(X1, Y1, X2, Y2, L' ', Colors[VMenuColorBody]); Box(X1, Y1, X2, Y2, Colors[VMenuColorBox], BoxType); if (!CheckFlags(VMENU_LISTBOX | VMENU_ALWAYSSCROLLBAR)) { From 2bc66593fa9cfc6bbb2d3d8090a62ad3962e2868 Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 6 Nov 2024 16:05:34 +0400 Subject: [PATCH 11/16] ps.sh: improve posix sh compatibility read -n is not supported in dash and is undefined in posix sh. --- far2l/bootstrap/ps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/far2l/bootstrap/ps.sh b/far2l/bootstrap/ps.sh index 84dc968f2..e7d4aedfc 100755 --- a/far2l/bootstrap/ps.sh +++ b/far2l/bootstrap/ps.sh @@ -22,8 +22,8 @@ else N=$(printf '\e[0m') echo "It is recommended to install <${B}htop${N}> utility." echo "Without <${B}htop${N}> installed far2l will use <${B}top${N}>." - echo "Press any key to continue..." - read -r -n 1 k <&1 + echo "Press Enter to continue..." + read k touch ~/.config/far2l/ps.warned fi top From a28ba540e8d123de66aff2d59af3b5c450afdd6d Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:36:14 +0300 Subject: [PATCH 12/16] infolist: optimize ShowPluginDescription(), remove non-used code --- far2l/src/panels/infolist.cpp | 34 +++++++++++++++------------------- far2l/src/panels/infolist.hpp | 1 + 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index 92426666d..2f02c2138 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -84,7 +84,7 @@ enum InfoListSectionStateIndex struct InfoList::InfoListSectionState { bool Show; // раскрыть/свернуть? - int Y; // Где? (<0 - отсутствует) + int Y; // Где? (<0 - отсутствует) }; InfoList::InfoList() @@ -152,6 +152,13 @@ inline void InfoList::DrawTitle(FarLangMsg MsgID, int Id, int CurY) DrawTitle(MsgID.CPtr(), Id, CurY); } +void InfoList::ClearTitles() +{ + for (int i=0; iSeparator) { FARString strTitle; @@ -795,9 +791,9 @@ void InfoList::ShowPluginDescription(int YPos) if (InfoLine->Text && *InfoLine->Text) strTitle.Append(L" ").Append(InfoLine->Text).Append(L" "); - DrawSeparator(Y); + DrawSeparator(YPos); TruncStr(strTitle, X2 - X1 - 3); - GotoXY(X1 + (X2 - X1 - (int)strTitle.GetLength()) / 2, Y); + GotoXY(X1 + (X2 - X1 - (int)strTitle.GetLength()) / 2, YPos); SetFarColor(COL_PANELTEXT); PrintText(strTitle); } else { diff --git a/far2l/src/panels/infolist.hpp b/far2l/src/panels/infolist.hpp index ead582617..51e102a77 100644 --- a/far2l/src/panels/infolist.hpp +++ b/far2l/src/panels/infolist.hpp @@ -91,6 +91,7 @@ class InfoList : public Panel void PrintInfo(FarLangMsg MsgID); void DrawTitle(const wchar_t *Str, int Id, int CurY); void DrawTitle(FarLangMsg MsgID, int Id, int CurY); + void ClearTitles(); int OpenDizFile(const wchar_t *DizFile, int YPos); void SetMacroMode(int Restore = FALSE); From 95294f729fdb3aef3e291f77988ee1ca9415a2cd Mon Sep 17 00:00:00 2001 From: akruphi <92621645+akruphi@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:45:25 +0300 Subject: [PATCH 13/16] infolist: show/hide titles only when mouse button pressed without motion --- far2l/src/panels/infolist.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/far2l/src/panels/infolist.cpp b/far2l/src/panels/infolist.cpp index 2f02c2138..75afbaa48 100644 --- a/far2l/src/panels/infolist.cpp +++ b/far2l/src/panels/infolist.cpp @@ -589,7 +589,8 @@ int InfoList::ProcessMouse(MOUSE_EVENT_RECORD *MouseEvent) { int RetCode; - if (MouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) + if ((MouseEvent->dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) + && (MouseEvent->dwEventFlags != MOUSE_MOVED)) { for (auto &elem : SectionState) { From e7ed022f9bbfa2efe0669a03ac56a95202f3f2e0 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 10 Nov 2024 13:22:38 +0300 Subject: [PATCH 14/16] refactor --- WinPort/WinPort.h | 5 +- WinPort/src/APIOther.cpp | 5 + WinPort/src/Backend/Backend.h | 6 +- WinPort/src/Backend/TTY/TTYBackend.cpp | 72 +++--- WinPort/src/Backend/TTY/TTYBackend.h | 4 +- WinPort/src/Backend/WX/wxMain.cpp | 57 ++++- WinPort/src/Backend/WX/wxMain.h | 3 + WinPort/src/Backend/WinPortMain.cpp | 9 - WinPort/src/ConsoleOutput.cpp | 5 + WinPort/src/ConsoleOutput.h | 1 + far2l/CMakeLists.txt | 1 + far2l/src/about.cpp | 305 +++++++++++++++++++++++++ far2l/src/cmdline.cpp | 286 +---------------------- far2l/src/console/constitle.cpp | 3 +- 14 files changed, 415 insertions(+), 347 deletions(-) create mode 100644 far2l/src/about.cpp diff --git a/WinPort/WinPort.h b/WinPort/WinPort.h index 5493f3650..16999a0ae 100644 --- a/WinPort/WinPort.h +++ b/WinPort/WinPort.h @@ -55,7 +55,10 @@ extern "C" { #ifndef FAR_PYTHON_GEN int WinPortMain(const char *full_exe_path, int argc, char **argv, int (*AppMain)(int argc, char **argv)); void WinPortHelp(); - const wchar_t *WinPortBackend(); + + // entity = -1 - current backend flavor + // entity = [0 .. until NULL result) - version information of different components + const char *WinPortBackendInfo(int entity); // true means far2l runs under smoke testing and code must // not skip events from input queue that sometimes used to make UX smoother diff --git a/WinPort/src/APIOther.cpp b/WinPort/src/APIOther.cpp index 4fdf3721b..d2a2a5431 100644 --- a/WinPort/src/APIOther.cpp +++ b/WinPort/src/APIOther.cpp @@ -3,6 +3,7 @@ #include "WinPort.h" #include "WinPortHandle.h" #include "PathHelpers.h" +#include "Backend.h" #include #include @@ -49,4 +50,8 @@ extern "C" { return TRUE; } + const char *WinPortBackendInfo(int entity) + { + return g_winport_con_out->BackendInfo(entity); + } } diff --git a/WinPort/src/Backend/Backend.h b/WinPort/src/Backend/Backend.h index 62c6e3bdc..c4f545628 100644 --- a/WinPort/src/Backend/Backend.h +++ b/WinPort/src/Backend/Backend.h @@ -8,7 +8,7 @@ /// Something changed in code below. /// "WinCompat.h" changed in a way affecting code below. /// Behavior of backend's code changed in incompatible way. -#define FAR2L_BACKEND_ABI_VERSION 0x0B +#define FAR2L_BACKEND_ABI_VERSION 0x0C #define NODETECT_NONE 0x0000 #define NODETECT_XI 0x0001 @@ -44,6 +44,7 @@ class IConsoleOutputBackend virtual bool OnConsoleSetBasePalette(void *pbuff) = 0; virtual void OnConsoleOverrideColor(DWORD Index, DWORD *ColorFG, DWORD *ColorBK) = 0; virtual void OnConsoleSetCursorBlinkTime(DWORD interval) = 0; + virtual const char *OnConsoleBackendInfo(int entity) = 0; }; class IClipboardBackend @@ -215,6 +216,8 @@ class IConsoleOutput virtual void RepaintsDeferStart() = 0; virtual void RepaintsDeferFinish() = 0; + virtual const char *BackendInfo(int entity) = 0; + inline std::wstring GetTitle() { std::wstring out(LockedGetTitle()); @@ -249,7 +252,6 @@ class IConsoleOutput extern IConsoleOutput *g_winport_con_out; extern IConsoleInput *g_winport_con_in; -extern const wchar_t *g_winport_backend; ////////////////////////////////////////////////////////////////////////////////// diff --git a/WinPort/src/Backend/TTY/TTYBackend.cpp b/WinPort/src/Backend/TTY/TTYBackend.cpp index 799a402b5..0f0e62b50 100644 --- a/WinPort/src/Backend/TTY/TTYBackend.cpp +++ b/WinPort/src/Backend/TTY/TTYBackend.cpp @@ -170,41 +170,10 @@ bool TTYBackend::Startup() return true; } -static wchar_t s_backend_identification[8] = L"TTY"; - -static void AppendBackendIdentificationChar(char ch) +void TTYBackend::BackendInfoChanged() { - const size_t l = wcslen(s_backend_identification); - if (l + 1 >= ARRAYSIZE(s_backend_identification)) { - abort(); - } - s_backend_identification[l + 1] = 0; - s_backend_identification[l] = (unsigned char)ch; -} - -void TTYBackend::UpdateBackendIdentification() -{ - s_backend_identification[3] = 0; - - if (_far2l_tty || _ttyx || _using_extension) { - AppendBackendIdentificationChar('|'); - } - - if (_far2l_tty) { - AppendBackendIdentificationChar('F'); - - } else if (_ttyx || _using_extension) { - if (_ttyx) { - AppendBackendIdentificationChar('X'); - } - if (_using_extension) { - AppendBackendIdentificationChar(_using_extension); - } else if (_ttyx && _ttyx->HasXi()) { - AppendBackendIdentificationChar('i'); - } - } - - g_winport_backend = s_backend_identification; + std::lock_guard lock(_backend_info); + _backend_info.flavor.clear(); } static bool UnderWayland() @@ -245,7 +214,7 @@ void TTYBackend::ReaderThread() ChooseSimpleClipboardBackend(); } } - UpdateBackendIdentification(); + BackendInfoChanged(); prev_far2l_tty = _far2l_tty; { @@ -1057,7 +1026,7 @@ void TTYBackend::OnUsingExtension(char extension) { if (_using_extension != extension) { _using_extension = extension; - UpdateBackendIdentification(); + BackendInfoChanged(); } } @@ -1239,6 +1208,37 @@ bool TTYBackend::OnConsoleBackgroundMode(bool TryEnterBackgroundMode) return true; } +const char *TTYBackend::OnConsoleBackendInfo(int entity) +{ + if (entity != -1) + return nullptr; + + std::lock_guard lock(_backend_info); + if (_backend_info.flavor.empty()) { + _backend_info.flavor.reserve(16); // avoid reallocation ever then + _backend_info.flavor = "TTY"; + + if (_far2l_tty || _ttyx || _using_extension) { + _backend_info.flavor+= '|'; + } + + if (_far2l_tty) { + _backend_info.flavor+= 'F'; + } else if (_ttyx || _using_extension) { + if (_ttyx) { + _backend_info.flavor+= 'X'; + } + if (_using_extension) { + _backend_info.flavor+= _using_extension; + } else if (_ttyx && _ttyx->HasXi()) { + _backend_info.flavor+= 'i'; + } + } + } + + return _backend_info.flavor.c_str(); +} + static void OnSigWinch(int) { diff --git a/WinPort/src/Backend/TTY/TTYBackend.h b/WinPort/src/Backend/TTY/TTYBackend.h index 66ea6d7b8..77478b576 100644 --- a/WinPort/src/Backend/TTY/TTYBackend.h +++ b/WinPort/src/Backend/TTY/TTYBackend.h @@ -56,7 +56,7 @@ class TTYBackend : IConsoleOutputBackend, ITTYInputSpecialSequenceHandler, IFar2 void ReaderThread(); void ReaderLoop(); void WriterThread(); - void UpdateBackendIdentification(); + void BackendInfoChanged(); std::condition_variable _async_cond; std::mutex _async_mutex; @@ -67,6 +67,7 @@ class TTYBackend : IConsoleOutputBackend, ITTYInputSpecialSequenceHandler, IFar2 std::atomic _largest_window_size_ready{false}; std::atomic _flush_input_queue{false}; + struct BI : std::mutex { std::string flavor; } _backend_info; struct Far2lInteractData { @@ -139,6 +140,7 @@ class TTYBackend : IConsoleOutputBackend, ITTYInputSpecialSequenceHandler, IFar2 virtual bool OnConsoleSetBasePalette(void *pbuff); virtual void OnConsoleOverrideColor(DWORD Index, DWORD *ColorFG, DWORD *ColorBK); virtual void OnConsoleSetCursorBlinkTime(DWORD interval); + const char *OnConsoleBackendInfo(int entity); // ITTYInputSpecialSequenceHandler virtual void OnUsingExtension(char extension); diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index c0ab3a65f..e1a9cfe23 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -1,4 +1,5 @@ #include "wxMain.h" +#include #define AREAS_REDUCTION @@ -131,18 +132,6 @@ extern "C" __attribute__ ((visibility("default"))) bool WinPortMainBackend(WinPo if (!wxInitialize()) return false; - fprintf(stderr, "FAR2L wxWidgets build version %d.%d.%d\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ); - char s_wx_build[15]; - snprintf(s_wx_build, ARRAYSIZE(s_wx_build), "%d.%d.%d", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ); - setenv("FAR2L_WX_BUILD", s_wx_build, 1); -#if wxCHECK_VERSION(2, 9, 2) - wxVersionInfo wxv = wxGetLibraryVersionInfo(); - fprintf(stderr, "FAR2L wxWidgets use version %d.%d.%d\n", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro() ); - char s_wx_use[15]; - snprintf(s_wx_use, ARRAYSIZE(s_wx_use), "%d.%d.%d", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro() ); - setenv("FAR2L_WX_USE", s_wx_use, 1); -#endif - wxSetAssertHandler(WinPortWxAssertHandler); DetectHostAbilities(); @@ -584,6 +573,32 @@ wxEND_EVENT_TABLE() WinPortPanel::WinPortPanel(WinPortFrame *frame, const wxPoint& pos, const wxSize& size) : _paint_context(this), _frame(frame), _refresh_rects_throttle(WINPORT(GetTickCount)()) { + _backend_info.emplace_back( + StrPrintf("Build/wxWidgets %d.%d.%d", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER)); + +#if wxCHECK_VERSION(2, 9, 2) + wxVersionInfo wxv = wxGetLibraryVersionInfo(); + _backend_info.emplace_back( + StrPrintf("wxWidgets %d.%d.%d", wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro())); + fprintf(stderr, "FAR2L wxWidgets build: %d.%d.%d actual: %d.%d.%d\n", + wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, wxv.GetMajor(), wxv.GetMinor(), wxv.GetMicro()); +#else + fprintf(stderr, "FAR2L wxWidgets build: %d.%d.%d\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER); +#endif + +#ifdef __WXGTK__ + typedef unsigned int (*gtk_get_x_version_t)(void); + gtk_get_x_version_t pfn_gtk_get_major_version = (gtk_get_x_version_t)dlsym(RTLD_DEFAULT, "gtk_get_major_version"); + if (pfn_gtk_get_major_version) { + gtk_get_x_version_t pfn_gtk_get_minor_version = (gtk_get_x_version_t)dlsym(RTLD_DEFAULT, "gtk_get_minor_version"); + gtk_get_x_version_t pfn_gtk_get_micro_version = (gtk_get_x_version_t)dlsym(RTLD_DEFAULT, "gtk_get_micro_version"); + _backend_info.emplace_back( + StrPrintf("GTK %d.%d.%d", pfn_gtk_get_major_version(), + pfn_gtk_get_minor_version ? pfn_gtk_get_minor_version() : -1, + pfn_gtk_get_micro_version ? pfn_gtk_get_micro_version() : -1)); + } +#endif + // far2l doesn't need special erase background SetBackgroundStyle(wxBG_STYLE_PAINT); Create(frame, wxID_ANY, pos, size, wxWANTS_CHARS | wxNO_BORDER); @@ -2021,6 +2036,24 @@ void WinPortPanel::OnConsoleSetCursorBlinkTime(DWORD interval) wxQueueEvent(this, event); } +const char *WinPortPanel::OnConsoleBackendInfo(int entity) +{ + if (entity == -1) { + return "GUI"; + } + + if (entity < 0) { + return nullptr; + } + + if (size_t(entity) >= _backend_info.size()) { + return nullptr; + } + + return _backend_info[size_t(entity)].c_str(); +} + + void WinPortPanel::CheckPutText2CLip() { if (!_text2clip.empty()) { diff --git a/WinPort/src/Backend/WX/wxMain.h b/WinPort/src/Backend/WX/wxMain.h index d40e96541..f038a83b9 100644 --- a/WinPort/src/Backend/WX/wxMain.h +++ b/WinPort/src/Backend/WX/wxMain.h @@ -90,6 +90,8 @@ class WinPortPanel: public wxPanel, protected IConsoleOutputBackend MOUSE_EVENT_RECORD _prev_mouse_event{}; DWORD _prev_mouse_event_ts{0}; + struct BI : std::vector {} _backend_info; + wxTimer* _periodic_timer{nullptr}; unsigned int _timer_idling_counter{0}; std::atomic _last_title_ticks{0}; @@ -166,6 +168,7 @@ class WinPortPanel: public wxPanel, protected IConsoleOutputBackend virtual bool OnConsoleSetBasePalette(void *pbuff); virtual void OnConsoleOverrideColor(DWORD Index, DWORD *ColorFG, DWORD *ColorBK); virtual void OnConsoleSetCursorBlinkTime(DWORD interval); + virtual const char *OnConsoleBackendInfo(int entity); public: WinPortPanel(WinPortFrame *frame, const wxPoint& pos, const wxSize& size); diff --git a/WinPort/src/Backend/WinPortMain.cpp b/WinPort/src/Backend/WinPortMain.cpp index a3e8e5bf0..3b1e53f5b 100644 --- a/WinPort/src/Backend/WinPortMain.cpp +++ b/WinPort/src/Backend/WinPortMain.cpp @@ -40,7 +40,6 @@ IConsoleOutput *g_winport_con_out = nullptr; IConsoleInput *g_winport_con_in = nullptr; -const wchar_t *g_winport_backend = L""; static BOOL g_winport_testing = FALSE; bool WinPortMainTTY(const char *full_exe_path, int std_in, int std_out, @@ -510,8 +509,6 @@ extern "C" int WinPortMain(const char *full_exe_path, int argc, char **argv, int typedef bool (*WinPortMainBackend_t)(WinPortMainBackendArg *a); WinPortMainBackend_t WinPortMainBackend_p = (WinPortMainBackend_t)dlsym(gui_so, "WinPortMainBackend"); if (WinPortMainBackend_p) { - g_winport_backend = L"GUI"; - tty_raw_mode.reset(); SudoAskpassImpl askass_impl; SudoAskpassServer askpass_srv(&askass_impl); @@ -536,7 +533,6 @@ extern "C" int WinPortMain(const char *full_exe_path, int argc, char **argv, int } if (arg_opts.tty) { - g_winport_backend = L"tty"; if (!tty_raw_mode) { tty_raw_mode.reset(new TTYRawMode(std_in, std_out)); } @@ -599,8 +595,3 @@ extern "C" int WinPortMain(const char *full_exe_path, int argc, char **argv, int return result; } - -extern "C" const wchar_t *WinPortBackend() -{ - return g_winport_backend; -} diff --git a/WinPort/src/ConsoleOutput.cpp b/WinPort/src/ConsoleOutput.cpp index 5aa318013..bbf2b8595 100644 --- a/WinPort/src/ConsoleOutput.cpp +++ b/WinPort/src/ConsoleOutput.cpp @@ -874,3 +874,8 @@ unsigned int ConsoleOutput::WaitForChange(unsigned int prev_change_id, unsigned } return _change_id; } + +const char *ConsoleOutput::BackendInfo(int entity) +{ + return _backend->OnConsoleBackendInfo(entity); +} diff --git a/WinPort/src/ConsoleOutput.h b/WinPort/src/ConsoleOutput.h index 6ddcf2fd1..85c87a5f4 100644 --- a/WinPort/src/ConsoleOutput.h +++ b/WinPort/src/ConsoleOutput.h @@ -131,4 +131,5 @@ class ConsoleOutput : public IConsoleOutput virtual void JoinConsoleOutput(IConsoleOutput *con_out); virtual unsigned int WaitForChange(unsigned int prev_change_id, unsigned int timeout_msec = -1); + virtual const char *BackendInfo(int entity); }; diff --git a/far2l/CMakeLists.txt b/far2l/CMakeLists.txt index 070b9e0be..b6d42271a 100644 --- a/far2l/CMakeLists.txt +++ b/far2l/CMakeLists.txt @@ -73,6 +73,7 @@ src/ViewerStrings.cpp src/ViewerPrinter.cpp src/fileholder.cpp src/GrepFile.cpp +src/about.cpp src/panels/panel.cpp src/panels/filelist.cpp diff --git a/far2l/src/about.cpp b/far2l/src/about.cpp new file mode 100644 index 000000000..a1b6f68b8 --- /dev/null +++ b/far2l/src/about.cpp @@ -0,0 +1,305 @@ +#include "headers.hpp" +#include +#include +#include "plugins.hpp" +#include "interf.hpp" +#include "clipboard.hpp" +#include "pathmix.hpp" +#include "vmenu.hpp" +#include "config.hpp" +#include "farversion.h" +#include "vtshell.h" + +void FarAbout(PluginManager &Plugins) +{ + static bool b_hide_empty = true; + int npl; + FARString fs, fs2, fs2copy; + MenuItemEx mi, mis; + mi.Flags = b_hide_empty ? LIF_HIDDEN : 0; + mis.Flags = LIF_SEPARATOR; + + VMenu ListAbout(b_hide_empty ? L"far:about *" : L"far:about", nullptr, 0, ScrY-4); + ListAbout.SetFlags(VMENU_SHOWAMPERSAND | VMENU_IGNORE_SINGLECLICK); + ListAbout.ClearFlags(VMENU_MOUSEREACTION); + //ListAbout.SetFlags(VMENU_WRAPMODE); + ListAbout.SetHelp(L"SpecCmd");//L"FarAbout"); + ListAbout.SetBottomTitle(L"ESC or F10 to close, Ctrl-C or Ctrl-Ins - copy all, Ctrl-H - (un)hide empty, Ctrl-Alt-F - filtering"); + + fs.Format(L" FAR2L Version: %s", FAR_BUILD); + ListAbout.AddItem(fs); fs2copy = fs; + fs = L" Compiler: "; +#if defined (__clang__) + fs.AppendFormat(L"Clang, version %d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); +#elif defined (__INTEL_COMPILER) + fs.AppendFormat(L"Intel C/C++, version %d (build date %d)", __INTEL_COMPILER, __INTEL_COMPILER_BUILD_DATE); +#elif defined (__GNUC__) + fs.AppendFormat(L"GCC, version %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +#else + fs.Append(L"Unknown"); +#endif + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + fs.Format(L" Platform: %s", FAR_PLATFORM); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + fs.Format(L" Backend: %s", WinPortBackendInfo(-1)); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + fs.Format(L" ConsoleColorPalette: %u", WINPORT(GetConsoleColorPalette)(NULL) ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + fs.Format(L" Admin: %ls", Opt.IsUserAdmin ? Msg::FarTitleAddonsAdmin : L"-"); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + //apiGetEnvironmentVariable("FARPID", fs2); + //fs = L" PID: " + fs2; + fs.Format(L" PID: %lu", (unsigned long)getpid()); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + //apiGetEnvironmentVariable("FARLANG", fs2); + fs = L" Main | Help languages: " + Opt.strLanguage + L" | " + Opt.strHelpLanguage; + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + fs.Format(L" OEM | ANSI codepages: %u | %u", WINPORT(GetOEMCP)(), WINPORT(GetACP)() ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + //apiGetEnvironmentVariable("FARHOME", fs2); + fs = L"Far directory (FARHOME): \"" + g_strFarPath.GetMB() + L"\""; + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + fs.Format(L" Config directory: \"%s\"", InMyConfig("",FALSE).c_str() ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + fs.Format(L" Cache directory: \"%s\"", InMyCache("",FALSE).c_str() ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + fs.Format(L" Temp directory: \"%s\"", InMyTemp("").c_str() ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + if (Opt.CmdLine.UseShell) + fs.Format(L" Command shell (User): \"%ls\"", Opt.CmdLine.strShell.CPtr() ); + else + fs.Format(L" Command shell (System): \"%s\"", GetSystemShell() ); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + ListAbout.AddItem(L""); fs2copy += "\n"; + struct utsname un; + fs = L" uname: "; + if (uname(&un)==0) { + fs.AppendFormat(L"%s %s %s %s", un.sysname, un.release, un.version, un.machine); + ListAbout.AddItem(fs); + } + else { + mi.strName = fs; + ListAbout.AddItem(&mi); + } + fs2copy += "\n" + fs; + + for (unsigned int i = 0; ; i++) { + const char *info = WinPortBackendInfo(i); + if (!info) { + break; + } + fs.Format(L"%23s: %s", "System component", info); + ListAbout.AddItem(fs); + fs2copy += "\n" + fs; + } + + static const char * const env_vars[] = { + "HOSTNAME", "USER", + "FARSETTINGS", "FAR2L_ARGS", + "XDG_SESSION_TYPE", + "TERM", "COLORTERM", + "GDK_BACKEND", "DESKTOP_SESSION", + "WSL_DISTRO_NAME", "WSL2_GUI_APPS_ENABLED", + "DISPLAY", "WAYLAND_DISPLAY" }; + for (unsigned int i = 0; i < ARRAYSIZE(env_vars); i++) { + fs.Format(L"%23s: ", env_vars[i]); + if (apiGetEnvironmentVariable(env_vars[i], fs2)) { + fs += fs2.CPtr(); + ListAbout.AddItem(fs); + } + else { + mi.strName = fs; + ListAbout.AddItem(&mi); + } + fs2copy += "\n" + fs; + } + + ListAbout.AddItem(L""); fs2copy += "\n"; + + npl = Plugins.GetPluginsCount(); + fs.Format(L" Number of plugins: %d", npl); + ListAbout.AddItem(fs); fs2copy += "\n" + fs; + + mi.Flags = 0; + + for(int i = 0; i < npl; i++) + { + fs.Format(L"Plugin#%02d ", i+1); + mis.strName = fs; + mi.PrefixLen = fs.GetLength()-1; + + Plugin *pPlugin = Plugins.GetPlugin(i); + if(pPlugin == nullptr) { + ListAbout.AddItem(&mis); fs2copy += "\n--- " + mis.strName + " ---"; + mi.strName = fs + L"!!! ERROR get plugin"; + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + continue; + } + mis.strName = fs + PointToName(pPlugin->GetModuleName()); + ListAbout.AddItem(&mis); fs2copy += "\n--- " + mis.strName + " ---"; + + mi.strName = fs + pPlugin->GetModuleName(); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + + mi.strName = fs + L"Settings Name: " + pPlugin->GetSettingsName(); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + + int iFlags; + int j; + PluginInfo pInfo{}; + KeyFileReadHelper kfh(PluginsIni()); + FARString fsCommandPrefix = L""; + std::vector fsDiskMenuStrings; + std::vector fsPluginMenuStrings; + std::vector fsPluginConfigStrings; + + if (pPlugin->CheckWorkFlags(PIWF_CACHED)) { + iFlags = kfh.GetUInt(pPlugin->GetSettingsName(), "Flags", 0); + fsCommandPrefix = kfh.GetString(pPlugin->GetSettingsName(), "CommandPrefix", L""); + for (j = 0; ; j++) { + const auto &key_name = StrPrintf("DiskMenuString%d", j); + /*if (!kfh.HasKey(key_name)) + break;*/ + fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); + if( fs2.IsEmpty() ) + break; + fsDiskMenuStrings.emplace_back(fs2); + } + for (j = 0; ; j++) { + const auto &key_name = StrPrintf("PluginMenuString%d", j); + /*if (!kfh.HasKey(key_name)) + break;*/ + fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); + if( fs2.IsEmpty() ) + break; + fsPluginMenuStrings.emplace_back(fs2); + } + for (j = 0; ; j++) { + const auto &key_name = StrPrintf("PluginConfigString%d", j); + /*if (!kfh.HasKey(key_name)) + break;*/ + fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); + if( fs2.IsEmpty() ) + break; + fsPluginConfigStrings.emplace_back(fs2); + } + } + else { + if (pPlugin->GetPluginInfo(&pInfo)) { + iFlags = pInfo.Flags; + fsCommandPrefix = pInfo.CommandPrefix; + for (j = 0; j < pInfo.DiskMenuStringsNumber; j++) + fsDiskMenuStrings.emplace_back(pInfo.DiskMenuStrings[j]); + for (j = 0; j < pInfo.PluginMenuStringsNumber; j++) + fsPluginMenuStrings.emplace_back(pInfo.PluginMenuStrings[j]); + for (j = 0; j < pInfo.PluginConfigStringsNumber; j++) + fsPluginConfigStrings.emplace_back(pInfo.PluginConfigStrings[j]); + } + else + iFlags = -1; + } + + mi.strName.Format(L"%ls %s Cached %s Loaded ", + fs.CPtr(), + pPlugin->CheckWorkFlags(PIWF_CACHED) ? "[x]" : "[ ]", + pPlugin->GetFuncFlags() & PICFF_LOADED ? "[x]" : "[ ]"); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + + if (iFlags >= 0) { + mi.strName.Format(L"%lsF11: %s Panel %s Dialog %s Viewer %s Editor ", + fs.CPtr(), + iFlags & PF_DISABLEPANELS ? "[ ]" : "[x]", + iFlags & PF_DIALOG ? "[x]" : "[ ]", + iFlags & PF_VIEWER ? "[x]" : "[ ]", + iFlags & PF_EDITOR ? "[x]" : "[ ]"); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + } + + mi.strName.Format(L"%ls %s EditorInput ", fs.CPtr(), pPlugin->HasProcessEditorInput() ? "[x]" : "[ ]"); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + + j = 0; + for (auto& fs_vec : fsDiskMenuStrings) { + j++; + mi.strName.Format(L"%ls DiskMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + } + j = 0; + for (auto& fs_vec : fsPluginMenuStrings) { + j++; + mi.strName.Format(L"%ls PluginMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + } + j = 0; + for (auto& fs_vec : fsPluginConfigStrings) { + j++; + mi.strName.Format(L"%ls PluginConfigString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + } + if ( !fsCommandPrefix.IsEmpty() ) { + mi.strName.Format(L"%ls CommandPrefix: \"%ls\"", fs.CPtr(), fsCommandPrefix.CPtr()); + ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; + } + + } + + ListAbout.SetPosition(-1, -1, 0, 0); + /*int iListExitCode = 0; + do { + ListAbout.Process(); + iListExitCode = ListAbout.GetExitCode(); + if (iListExitCode>=0) + ListAbout.ClearDone(); // no close after select item by ENTER or mouse click + } while(iListExitCode>=0);*/ + ListAbout.Show(); + do { + while (!ListAbout.Done()) { + FarKey Key = ListAbout.ReadInput(); + switch (Key) { + case KEY_CTRLC: + case KEY_CTRLINS: + case KEY_CTRLNUMPAD0: + CopyToClipboard(fs2copy.CPtr()); + break; + case KEY_CTRLH: { + struct MenuItemEx *mip; + if (b_hide_empty) { + b_hide_empty = false; + for (int i = 0; i < ListAbout.GetItemCount(); i++) { + mip = ListAbout.GetItemPtr(i); + mip->Flags &= ~LIF_HIDDEN; + } + ListAbout.SetTitle(L"far:about"); + } + else { + b_hide_empty = true; + for (int i = 0; i < ListAbout.GetItemCount(); i++) { + mip = ListAbout.GetItemPtr(i); + if (mip->strName.Ends(L": ")) + mip->Flags |= LIF_HIDDEN; + } + ListAbout.SetTitle(L"far:about *"); + } + } + ListAbout.Show(); + break; + default: + ListAbout.ProcessInput(); + continue; + } + } + if (ListAbout.GetExitCode() < 0) // exit from loop only by ESC or F10 or click outside vmenu + break; + ListAbout.ClearDone(); // no close after select item by ENTER or mouse click + } while(1); +} + diff --git a/far2l/src/cmdline.cpp b/far2l/src/cmdline.cpp index 6ae9e0f8f..e15757c41 100644 --- a/far2l/src/cmdline.cpp +++ b/far2l/src/cmdline.cpp @@ -72,7 +72,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "clipboard.hpp" #include "farversion.h" -#include CommandLine::CommandLine() : @@ -910,290 +909,6 @@ void CommandLine::RedrawWithoutComboBoxMark() DrawComboBoxMark(L' '); } -void FarAbout(PluginManager &Plugins) -{ - static bool b_hide_empty = true; - int npl; - FARString fs, fs2, fs2copy; - MenuItemEx mi, mis; - mi.Flags = b_hide_empty ? LIF_HIDDEN : 0; - mis.Flags = LIF_SEPARATOR; - - VMenu ListAbout(b_hide_empty ? L"far:about *" : L"far:about", nullptr, 0, ScrY-4); - ListAbout.SetFlags(VMENU_SHOWAMPERSAND | VMENU_IGNORE_SINGLECLICK); - ListAbout.ClearFlags(VMENU_MOUSEREACTION); - //ListAbout.SetFlags(VMENU_WRAPMODE); - ListAbout.SetHelp(L"SpecCmd");//L"FarAbout"); - ListAbout.SetBottomTitle(L"ESC or F10 to close, Ctrl-C or Ctrl-Ins - copy all, Ctrl-H - (un)hide empty, Ctrl-Alt-F - filtering"); - - fs.Format(L" FAR2L Version: %s", FAR_BUILD); - ListAbout.AddItem(fs); fs2copy = fs; - fs = L" Compiler: "; -#if defined (__clang__) - fs.AppendFormat(L"Clang, version %d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); -#elif defined (__INTEL_COMPILER) - fs.AppendFormat(L"Intel C/C++, version %d (build date %d)", __INTEL_COMPILER, __INTEL_COMPILER_BUILD_DATE); -#elif defined (__GNUC__) - fs.AppendFormat(L"GCC, version %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -#else - fs.Append(L"Unknown"); -#endif - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - fs.Format(L" Platform: %s", FAR_PLATFORM); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - fs.Format(L" Backend: %ls", WinPortBackend()); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - fs.Format(L" ConsoleColorPalette: %u", WINPORT(GetConsoleColorPalette)(NULL) ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - fs.Format(L" Admin: %ls", Opt.IsUserAdmin ? Msg::FarTitleAddonsAdmin : L"-"); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - //apiGetEnvironmentVariable("FARPID", fs2); - //fs = L" PID: " + fs2; - fs.Format(L" PID: %lu", (unsigned long)getpid()); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - //apiGetEnvironmentVariable("FARLANG", fs2); - fs = L" Main | Help languages: " + Opt.strLanguage + L" | " + Opt.strHelpLanguage; - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - fs.Format(L" OEM | ANSI codepages: %u | %u", WINPORT(GetOEMCP)(), WINPORT(GetACP)() ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - //apiGetEnvironmentVariable("FARHOME", fs2); - fs = L"Far directory (FARHOME): \"" + g_strFarPath.GetMB() + L"\""; - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - fs.Format(L" Config directory: \"%s\"", InMyConfig("",FALSE).c_str() ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - fs.Format(L" Cache directory: \"%s\"", InMyCache("",FALSE).c_str() ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - fs.Format(L" Temp directory: \"%s\"", InMyTemp("").c_str() ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - if (Opt.CmdLine.UseShell) - fs.Format(L" Command shell (User): \"%ls\"", Opt.CmdLine.strShell.CPtr() ); - else - fs.Format(L" Command shell (System): \"%s\"", GetSystemShell() ); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - ListAbout.AddItem(L""); fs2copy += "\n"; - struct utsname un; - fs = L" uname: "; - if (uname(&un)==0) { - fs.AppendFormat(L"%s %s %s %s", un.sysname, un.release, un.version, un.machine); - ListAbout.AddItem(fs); - } - else { - mi.strName = fs; - ListAbout.AddItem(&mi); - } - fs2copy += "\n" + fs; - - static const char * const env_vars[] = { - "HOSTNAME", "USER", - "FAR2L_WX_BUILD", "FAR2L_WX_USE", - "FARSETTINGS", "FAR2L_ARGS", - "XDG_SESSION_TYPE", - "TERM", "COLORTERM", - "GDK_BACKEND", "DESKTOP_SESSION", - "WSL_DISTRO_NAME", "WSL2_GUI_APPS_ENABLED", - "DISPLAY", "WAYLAND_DISPLAY" }; - for (unsigned int i = 0; i < ARRAYSIZE(env_vars); i++) { - fs.Format(L"%23s: ", env_vars[i]); - if (apiGetEnvironmentVariable(env_vars[i], fs2)) { - fs += fs2.CPtr(); - ListAbout.AddItem(fs); - } - else { - mi.strName = fs; - ListAbout.AddItem(&mi); - } - fs2copy += "\n" + fs; - } - - ListAbout.AddItem(L""); fs2copy += "\n"; - - npl = Plugins.GetPluginsCount(); - fs.Format(L" Number of plugins: %d", npl); - ListAbout.AddItem(fs); fs2copy += "\n" + fs; - - mi.Flags = 0; - - for(int i = 0; i < npl; i++) - { - fs.Format(L"Plugin#%02d ", i+1); - mis.strName = fs; - mi.PrefixLen = fs.GetLength()-1; - - Plugin *pPlugin = Plugins.GetPlugin(i); - if(pPlugin == nullptr) { - ListAbout.AddItem(&mis); fs2copy += "\n--- " + mis.strName + " ---"; - mi.strName = fs + L"!!! ERROR get plugin"; - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - continue; - } - mis.strName = fs + PointToName(pPlugin->GetModuleName()); - ListAbout.AddItem(&mis); fs2copy += "\n--- " + mis.strName + " ---"; - - mi.strName = fs + pPlugin->GetModuleName(); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - - mi.strName = fs + L"Settings Name: " + pPlugin->GetSettingsName(); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - - int iFlags; - int j; - PluginInfo pInfo{}; - KeyFileReadHelper kfh(PluginsIni()); - FARString fsCommandPrefix = L""; - std::vector fsDiskMenuStrings; - std::vector fsPluginMenuStrings; - std::vector fsPluginConfigStrings; - - if (pPlugin->CheckWorkFlags(PIWF_CACHED)) { - iFlags = kfh.GetUInt(pPlugin->GetSettingsName(), "Flags", 0); - fsCommandPrefix = kfh.GetString(pPlugin->GetSettingsName(), "CommandPrefix", L""); - for (j = 0; ; j++) { - const auto &key_name = StrPrintf("DiskMenuString%d", j); - /*if (!kfh.HasKey(key_name)) - break;*/ - fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); - if( fs2.IsEmpty() ) - break; - fsDiskMenuStrings.emplace_back(fs2); - } - for (j = 0; ; j++) { - const auto &key_name = StrPrintf("PluginMenuString%d", j); - /*if (!kfh.HasKey(key_name)) - break;*/ - fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); - if( fs2.IsEmpty() ) - break; - fsPluginMenuStrings.emplace_back(fs2); - } - for (j = 0; ; j++) { - const auto &key_name = StrPrintf("PluginConfigString%d", j); - /*if (!kfh.HasKey(key_name)) - break;*/ - fs2 = kfh.GetString(pPlugin->GetSettingsName(), key_name, ""); - if( fs2.IsEmpty() ) - break; - fsPluginConfigStrings.emplace_back(fs2); - } - } - else { - if (pPlugin->GetPluginInfo(&pInfo)) { - iFlags = pInfo.Flags; - fsCommandPrefix = pInfo.CommandPrefix; - for (j = 0; j < pInfo.DiskMenuStringsNumber; j++) - fsDiskMenuStrings.emplace_back(pInfo.DiskMenuStrings[j]); - for (j = 0; j < pInfo.PluginMenuStringsNumber; j++) - fsPluginMenuStrings.emplace_back(pInfo.PluginMenuStrings[j]); - for (j = 0; j < pInfo.PluginConfigStringsNumber; j++) - fsPluginConfigStrings.emplace_back(pInfo.PluginConfigStrings[j]); - } - else - iFlags = -1; - } - - mi.strName.Format(L"%ls %s Cached %s Loaded ", - fs.CPtr(), - pPlugin->CheckWorkFlags(PIWF_CACHED) ? "[x]" : "[ ]", - pPlugin->GetFuncFlags() & PICFF_LOADED ? "[x]" : "[ ]"); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - - if (iFlags >= 0) { - mi.strName.Format(L"%lsF11: %s Panel %s Dialog %s Viewer %s Editor ", - fs.CPtr(), - iFlags & PF_DISABLEPANELS ? "[ ]" : "[x]", - iFlags & PF_DIALOG ? "[x]" : "[ ]", - iFlags & PF_VIEWER ? "[x]" : "[ ]", - iFlags & PF_EDITOR ? "[x]" : "[ ]"); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - } - - mi.strName.Format(L"%ls %s EditorInput ", fs.CPtr(), pPlugin->HasProcessEditorInput() ? "[x]" : "[ ]"); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - - j = 0; - for (auto& fs_vec : fsDiskMenuStrings) { - j++; - mi.strName.Format(L"%ls DiskMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - } - j = 0; - for (auto& fs_vec : fsPluginMenuStrings) { - j++; - mi.strName.Format(L"%ls PluginMenuString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - } - j = 0; - for (auto& fs_vec : fsPluginConfigStrings) { - j++; - mi.strName.Format(L"%ls PluginConfigString: %2d=\"%ls\"", fs.CPtr(), j, fs_vec.CPtr()); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - } - if ( !fsCommandPrefix.IsEmpty() ) { - mi.strName.Format(L"%ls CommandPrefix: \"%ls\"", fs.CPtr(), fsCommandPrefix.CPtr()); - ListAbout.AddItem(&mi); fs2copy += "\n" + mi.strName; - } - - } - - ListAbout.SetPosition(-1, -1, 0, 0); - /*int iListExitCode = 0; - do { - ListAbout.Process(); - iListExitCode = ListAbout.GetExitCode(); - if (iListExitCode>=0) - ListAbout.ClearDone(); // no close after select item by ENTER or mouse click - } while(iListExitCode>=0);*/ - ListAbout.Show(); - do { - while (!ListAbout.Done()) { - FarKey Key = ListAbout.ReadInput(); - switch (Key) { - case KEY_CTRLC: - case KEY_CTRLINS: - case KEY_CTRLNUMPAD0: - CopyToClipboard(fs2copy.CPtr()); - break; - case KEY_CTRLH: { - struct MenuItemEx *mip; - if (b_hide_empty) { - b_hide_empty = false; - for (int i = 0; i < ListAbout.GetItemCount(); i++) { - mip = ListAbout.GetItemPtr(i); - mip->Flags &= ~LIF_HIDDEN; - } - ListAbout.SetTitle(L"far:about"); - } - else { - b_hide_empty = true; - for (int i = 0; i < ListAbout.GetItemCount(); i++) { - mip = ListAbout.GetItemPtr(i); - if (mip->strName.Ends(L": ")) - mip->Flags |= LIF_HIDDEN; - } - ListAbout.SetTitle(L"far:about *"); - } - } - ListAbout.Show(); - break; - default: - ListAbout.ProcessInput(); - continue; - } - } - if (ListAbout.GetExitCode() < 0) // exit from loop only by ESC or F10 or click outside vmenu - break; - ListAbout.ClearDone(); // no close after select item by ENTER or mouse click - } while(1); -} - bool CommandLine::ProcessFarCommands(const wchar_t *CmdLine) { bool b_far, b_edit = false, b_view = false; @@ -1219,6 +934,7 @@ bool CommandLine::ProcessFarCommands(const wchar_t *CmdLine) } if (b_far && str_command == L"far:about") { + void FarAbout(PluginManager &Plugins); FarAbout(CtrlObject->Plugins); return true; // prefix correct and was processed } diff --git a/far2l/src/console/constitle.cpp b/far2l/src/console/constitle.cpp index ea7a35f2e..ab73e0178 100644 --- a/far2l/src/console/constitle.cpp +++ b/far2l/src/console/constitle.cpp @@ -99,9 +99,10 @@ void ConsoleTitle::SetFarTitle(const wchar_t *Title, bool Force, bool Restoring) %Admin - Msg::FarTitleAddonsAdmin */ strFarTitle = Opt.strWindowTitle; + const auto &wsBackend = MB2Wide(WinPortBackendInfo(-1)); ReplaceStrings(strFarTitle, L"%Ver", strVer, -1); ReplaceStrings(strFarTitle, L"%Platform", strPlatform, -1); - ReplaceStrings(strFarTitle, L"%Backend", WinPortBackend(), -1); + ReplaceStrings(strFarTitle, L"%Backend", wsBackend.c_str(), -1); ReplaceStrings(strFarTitle, L"%Admin", Opt.IsUserAdmin ? Msg::FarTitleAddonsAdmin : L"", -1); FARString hn, un; From 9242bed54981cc87ccf1f886e2e97f13b3a1d2cd Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 10 Nov 2024 14:57:21 +0300 Subject: [PATCH 15/16] GUI backend: freeze console output while adhoc copy active --- WinPort/src/APIConsole.cpp | 66 +++++++++++++++++++++++++++---- WinPort/src/Backend/WX/wxMain.cpp | 7 +++- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/WinPort/src/APIConsole.cpp b/WinPort/src/APIConsole.cpp index 86f4ea40d..75ece1a49 100644 --- a/WinPort/src/APIConsole.cpp +++ b/WinPort/src/APIConsole.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include #include +#include #include "WinPort.h" #include "Backend.h" @@ -16,15 +18,34 @@ struct ForkedConsole IConsoleOutput *con_out{nullptr}; }; -static IConsoleOutput *ChooseConOut(HANDLE hConsole) +static std::atomic s_shadow_out{nullptr}; +static std::atomic s_out_usecnt{0}; + +class ChooseConOut { - if (!hConsole) { - return g_winport_con_out; + IConsoleOutput *_chosen{}; + +public: + ChooseConOut(HANDLE hConsole) + { + ++s_out_usecnt; + if (hConsole) { + ForkedConsole *fc = (ForkedConsole *)hConsole; + ASSERT(fc->magic == FORKED_CONSOLE_MAGIC); + _chosen = fc->con_out; + } else if (LIKELY(s_shadow_out == nullptr)) { + _chosen = g_winport_con_out; + } else { + _chosen = s_shadow_out; + } } - ForkedConsole *fc = (ForkedConsole *)hConsole; - ASSERT(fc->magic == FORKED_CONSOLE_MAGIC); - return fc->con_out; -} + ~ChooseConOut() + { + --s_out_usecnt; + } + inline operator IConsoleOutput *() { return _chosen; } + inline IConsoleOutput *operator->() { return _chosen; } +}; static IConsoleInput *ChooseConIn(HANDLE hConsole) { @@ -38,6 +59,35 @@ static IConsoleInput *ChooseConIn(HANDLE hConsole) extern "C" { + WINPORT_DECL(FreezeConsoleOutput,VOID,()) + { + if (s_shadow_out == nullptr) { + try { + // use NULL handle to make app treat its scroll callbacks as from main output + s_shadow_out = g_winport_con_out->ForkConsoleOutput(NULL); + } catch (...) { + s_shadow_out = nullptr; + fprintf(stderr, "%s: exception\n", __FUNCTION__); + } + } else { + fprintf(stderr, "%s: called while already frozen\n", __FUNCTION__); + } + } + + WINPORT_DECL(UnfreezeConsoleOutput,VOID,()) + { + static IConsoleOutput *shadow_out = s_shadow_out; + if (shadow_out) { + s_shadow_out = nullptr; + while (s_out_usecnt != 0) { + usleep(1); + } + g_winport_con_out->JoinConsoleOutput(shadow_out); + } else { + fprintf(stderr, "%s: called while not frozen\n", __FUNCTION__); + } + } + WINPORT_DECL(ForkConsole,HANDLE,()) { ForkedConsole *fc = NULL; @@ -123,7 +173,7 @@ extern "C" { WINPORT_DECL(GetConsoleScreenBufferInfo,BOOL,(HANDLE hConsoleOutput,CONSOLE_SCREEN_BUFFER_INFO *lpConsoleScreenBufferInfo)) { unsigned int width = 0, height = 0; - auto *con_out = ChooseConOut(hConsoleOutput); + ChooseConOut con_out(hConsoleOutput); con_out->GetSize(width, height); lpConsoleScreenBufferInfo->dwCursorPosition = con_out->GetCursor(); lpConsoleScreenBufferInfo->wAttributes = con_out->GetAttributes(); diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index e1a9cfe23..ec80ac7a3 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -44,6 +44,9 @@ static DWORD g_TIMER_IDLING_CYCLES = TIMER_IDLING_TIME / DEF_TIMER_PERIOD; bool WinPortClipboard_IsBusy(); +WINPORT_DECL_DEF(FreezeConsoleOutput,VOID,()) +WINPORT_DECL_DEF(UnfreezeConsoleOutput,VOID,()) + static void NormalizeArea(SMALL_RECT &area) { if (area.Left > area.Right) std::swap(area.Left, area.Right); @@ -1791,8 +1794,9 @@ void WinPortPanel::OnMouseQEdit( wxMouseEvent &event, COORD pos_char ) _mouse_qedit_start_ticks = WINPORT(GetTickCount)(); if (!_mouse_qedit_start_ticks) _mouse_qedit_start_ticks = 1; _mouse_qedit_moved = false; + WINPORT(FreezeConsoleOutput)(); DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); - + } else if (_mouse_qedit_start_ticks != 0) { if (event.Moving() || event.Dragging()) { DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); @@ -1836,6 +1840,7 @@ void WinPortPanel::OnMouseQEdit( wxMouseEvent &event, COORD pos_char ) _mouse_qedit_start_ticks = 0; DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); DamageAreaBetween(_mouse_qedit_start, pos_char); + WINPORT(UnfreezeConsoleOutput)(); } } } From d1fed9ab4e22705081d289a76c41bce3b1bfb832 Mon Sep 17 00:00:00 2001 From: elfmz Date: Sun, 10 Nov 2024 23:07:26 +0300 Subject: [PATCH 16/16] some fixes for recent change --- WinPort/src/APIConsole.cpp | 35 ++++++++++++++++++++----------- WinPort/src/Backend/Backend.h | 2 +- WinPort/src/Backend/WX/wxMain.cpp | 24 ++++++++++++++++++--- WinPort/src/Backend/WX/wxMain.h | 8 +++++++ WinPort/src/ConsoleOutput.cpp | 13 ++++++++---- WinPort/src/ConsoleOutput.h | 2 +- 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/WinPort/src/APIConsole.cpp b/WinPort/src/APIConsole.cpp index 75ece1a49..82d703c23 100644 --- a/WinPort/src/APIConsole.cpp +++ b/WinPort/src/APIConsole.cpp @@ -19,29 +19,36 @@ struct ForkedConsole }; static std::atomic s_shadow_out{nullptr}; -static std::atomic s_out_usecnt{0}; +static std::atomic s_shadow_usecnt{0}; class ChooseConOut { IConsoleOutput *_chosen{}; + bool _using_shadow{false}; public: ChooseConOut(HANDLE hConsole) { - ++s_out_usecnt; if (hConsole) { ForkedConsole *fc = (ForkedConsole *)hConsole; ASSERT(fc->magic == FORKED_CONSOLE_MAGIC); _chosen = fc->con_out; - } else if (LIKELY(s_shadow_out == nullptr)) { + return; + } + ++s_shadow_usecnt; + _chosen = s_shadow_out; + if (LIKELY(_chosen == nullptr)) { + --s_shadow_usecnt; // not gonna use shadow _chosen = g_winport_con_out; } else { - _chosen = s_shadow_out; + _using_shadow = true; } } ~ChooseConOut() { - --s_out_usecnt; + if (_using_shadow) { + --s_shadow_usecnt; + } } inline operator IConsoleOutput *() { return _chosen; } inline IConsoleOutput *operator->() { return _chosen; } @@ -64,9 +71,12 @@ extern "C" { if (s_shadow_out == nullptr) { try { // use NULL handle to make app treat its scroll callbacks as from main output - s_shadow_out = g_winport_con_out->ForkConsoleOutput(NULL); + IConsoleOutput *shadow_out = g_winport_con_out->ForkConsoleOutput(NULL); + shadow_out = s_shadow_out.exchange(shadow_out); + if (shadow_out) { + g_winport_con_out->JoinConsoleOutput(shadow_out); + } } catch (...) { - s_shadow_out = nullptr; fprintf(stderr, "%s: exception\n", __FUNCTION__); } } else { @@ -76,13 +86,13 @@ extern "C" { WINPORT_DECL(UnfreezeConsoleOutput,VOID,()) { - static IConsoleOutput *shadow_out = s_shadow_out; + IConsoleOutput *shadow_out = s_shadow_out.exchange(nullptr); if (shadow_out) { - s_shadow_out = nullptr; - while (s_out_usecnt != 0) { + while (s_shadow_usecnt != 0) { usleep(1); } g_winport_con_out->JoinConsoleOutput(shadow_out); + g_winport_con_out->RepaintsDeferFinish(true); } else { fprintf(stderr, "%s: called while not frozen\n", __FUNCTION__); } @@ -479,10 +489,11 @@ extern "C" { WINPORT_DECL(SetConsoleRepaintsDefer, VOID, (HANDLE hConsoleOutput, BOOL Deferring)) { + ChooseConOut con_out(hConsoleOutput); if (Deferring) { - ChooseConOut(hConsoleOutput)->RepaintsDeferStart(); + con_out->RepaintsDeferStart(); } else { - ChooseConOut(hConsoleOutput)->RepaintsDeferFinish(); + con_out->RepaintsDeferFinish(false); } } diff --git a/WinPort/src/Backend/Backend.h b/WinPort/src/Backend/Backend.h index c4f545628..252d66f0a 100644 --- a/WinPort/src/Backend/Backend.h +++ b/WinPort/src/Backend/Backend.h @@ -214,7 +214,7 @@ class IConsoleOutput virtual bool SetBasePalette(void *p) = 0; virtual void OverrideColor(DWORD Index, DWORD *ColorFG, DWORD *ColorBK) = 0; virtual void RepaintsDeferStart() = 0; - virtual void RepaintsDeferFinish() = 0; + virtual void RepaintsDeferFinish(bool force) = 0; virtual const char *BackendInfo(int entity) = 0; diff --git a/WinPort/src/Backend/WX/wxMain.cpp b/WinPort/src/Backend/WX/wxMain.cpp index ec80ac7a3..8e2c22877 100644 --- a/WinPort/src/Backend/WX/wxMain.cpp +++ b/WinPort/src/Backend/WX/wxMain.cpp @@ -23,6 +23,10 @@ // If time between adhoc text copy and mouse button release less then this value then text will not be copied. Used to protect against unwanted copy-paste-s #define QEDIT_COPY_MINIMAL_DELAY 150 +// This defines muh much time UI remain frozen after user released qedit, that +// allows user to quickly select another location before all shadowed output changes applied +#define QEDIT_UNFREEZE_DELAY 1000 + #if (wxCHECK_VERSION(3, 0, 5) || (wxCHECK_VERSION(3, 0, 4) && WX304PATCH)) && !(wxCHECK_VERSION(3, 1, 0) && !wxCHECK_VERSION(3, 1, 3)) // wx version is greater than 3.0.5 (3.0.4 on Ubuntu 20) and not in 3.1.0-3.1.2 #define WX_ALT_NONLATIN @@ -791,6 +795,12 @@ void WinPortPanel::OnTimerPeriodic(wxTimerEvent& event) return; } + if (_qedit_unfreeze_start_ticks != 0 + && WINPORT(GetTickCount)() - _qedit_unfreeze_start_ticks >= QEDIT_UNFREEZE_DELAY) { + WINPORT(UnfreezeConsoleOutput)(); + _qedit_unfreeze_start_ticks = 0; + } + CheckForResizePending(); CheckPutText2CLip(); if (_mouse_qedit_start_ticks != 0 && WINPORT(GetTickCount)() - _mouse_qedit_start_ticks > QEDIT_COPY_MINIMAL_DELAY) { @@ -799,7 +809,10 @@ void WinPortPanel::OnTimerPeriodic(wxTimerEvent& event) _paint_context.BlinkCursor(); ++_timer_idling_counter; // stop timer if counter reached limit and cursor is visible and no other timer-dependent things remained - if (_timer_idling_counter >= g_TIMER_IDLING_CYCLES && _paint_context.CursorBlinkState() && _text2clip.empty()) { + if (_timer_idling_counter >= g_TIMER_IDLING_CYCLES + && _paint_context.CursorBlinkState() + && _qedit_unfreeze_start_ticks == 0 + && _text2clip.empty()) { _periodic_timer->Stop(); } } @@ -1794,7 +1807,12 @@ void WinPortPanel::OnMouseQEdit( wxMouseEvent &event, COORD pos_char ) _mouse_qedit_start_ticks = WINPORT(GetTickCount)(); if (!_mouse_qedit_start_ticks) _mouse_qedit_start_ticks = 1; _mouse_qedit_moved = false; - WINPORT(FreezeConsoleOutput)(); + if (_qedit_unfreeze_start_ticks == 0) { + WINPORT(FreezeConsoleOutput)(); + } else { + _qedit_unfreeze_start_ticks = 0; + } + _qedit_out_state = QOS_FROZEN_BUSY; DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); } else if (_mouse_qedit_start_ticks != 0) { @@ -1840,7 +1858,7 @@ void WinPortPanel::OnMouseQEdit( wxMouseEvent &event, COORD pos_char ) _mouse_qedit_start_ticks = 0; DamageAreaBetween(_mouse_qedit_start, _mouse_qedit_last); DamageAreaBetween(_mouse_qedit_start, pos_char); - WINPORT(UnfreezeConsoleOutput)(); + _qedit_unfreeze_start_ticks = WINPORT(GetTickCount)(); } } } diff --git a/WinPort/src/Backend/WX/wxMain.h b/WinPort/src/Backend/WX/wxMain.h index f038a83b9..192eda385 100644 --- a/WinPort/src/Backend/WX/wxMain.h +++ b/WinPort/src/Backend/WX/wxMain.h @@ -108,6 +108,14 @@ class WinPortPanel: public wxPanel, protected IConsoleOutputBackend RP_DEFER, RP_INSTANT } _resize_pending{RP_NONE}; + enum + { + QOS_NOT_FROZEN, + QOS_FROZEN_BUSY, + QOS_UNFREEZE_PENDING, + QOS_UNFREEZE_PENDING2, + } _qedit_out_state{QOS_NOT_FROZEN}; + DWORD _qedit_unfreeze_start_ticks{0}; DWORD _mouse_state{0}, _mouse_qedit_start_ticks{0}, _mouse_qedit_moved{0}; COORD _mouse_qedit_start{}, _mouse_qedit_last{}; wchar_t _stolen_key{0}; diff --git a/WinPort/src/ConsoleOutput.cpp b/WinPort/src/ConsoleOutput.cpp index bbf2b8595..d0f9deeff 100644 --- a/WinPort/src/ConsoleOutput.cpp +++ b/WinPort/src/ConsoleOutput.cpp @@ -800,14 +800,19 @@ void ConsoleOutput::RepaintsDeferStart() ASSERT(_repaint_defer > 0); } -void ConsoleOutput::RepaintsDeferFinish() +void ConsoleOutput::RepaintsDeferFinish(bool force) { std::vector deferred_repaints; { std::lock_guard lock(_mutex); - ASSERT(_repaint_defer > 0); - --_repaint_defer; - deferred_repaints.swap(_deferred_repaints); + if (force) { + _repaint_defer = 0; + } else if (_repaint_defer > 0) { + --_repaint_defer; + } + if (_repaint_defer == 0) { + deferred_repaints.swap(_deferred_repaints); + } if (!deferred_repaints.empty()) { LockedChangeIdUpdate(); } diff --git a/WinPort/src/ConsoleOutput.h b/WinPort/src/ConsoleOutput.h index 85c87a5f4..335fe1e1e 100644 --- a/WinPort/src/ConsoleOutput.h +++ b/WinPort/src/ConsoleOutput.h @@ -125,7 +125,7 @@ class ConsoleOutput : public IConsoleOutput virtual bool SetBasePalette(void *p); virtual void OverrideColor(DWORD Index, DWORD *ColorFG, DWORD *ColorBK); virtual void RepaintsDeferStart(); - virtual void RepaintsDeferFinish(); + virtual void RepaintsDeferFinish(bool force); virtual IConsoleOutput *ForkConsoleOutput(HANDLE con_handle); virtual void JoinConsoleOutput(IConsoleOutput *con_out);