Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/312d7595f040be5acb80d60f3a8dc62bdc432cd8
>---------------------------------------------------------------
commit 312d7595f040be5acb80d60f3a8dc62bdc432cd8
Author: Alex Alabuzhev <
alab...@gmail.com>
Date: Sun Dec 14 00:13:08 2025 +0000
Improve integer editing in far:config
Remove all the nonsense with separate dialogs for hex and binary,
make all the forms available in a single dialog.
>---------------------------------------------------------------
312d7595f040be5acb80d60f3a8dc62bdc432cd8
_build/vc/all.sln.DotSettings | 22 +-----
far/FarCze.hlf.m4 | 6 --
far/FarDlgBuilder.cpp | 46 +++++++----
far/FarDlgBuilder.hpp | 2 +-
far/FarEng.hlf.m4 | 6 --
far/FarGer.hlf.m4 | 6 --
far/FarHun.hlf.m4 | 6 --
far/FarPol.hlf.m4 | 6 --
far/FarRus.hlf.m4 | 6 --
far/FarSky.hlf.m4 | 6 --
far/FarUkr.hlf.m4 | 6 --
far/changelog | 7 ++
far/common/expected.hpp | 5 ++
far/config.cpp | 172 +++++++++++++++++++++++++++++++-----------
far/config.hpp | 21 +++---
far/farlang.templ.m4 | 120 +++++++++++++++++++++++++++++
far/vbuild.m4 | 2 +-
17 files changed, 311 insertions(+), 134 deletions(-)
diff --git a/_build/vc/all.sln.DotSettings b/_build/vc/all.sln.DotSettings
index 5ad9448dd..ba82d2867 100644
--- a/_build/vc/all.sln.DotSettings
+++ b/_build/vc/all.sln.DotSettings
@@ -96,24 +96,10 @@
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/SyncToVisualStudio/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=CppDefinitions/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=CppDefinitions/Options/=GenerateInlineDefinitions/@EntryIndexedValue">False</s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020fields/@EntryIndexedValue"><NamingElement Priority="10"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" Prefix="m_" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020public_0020fields/@EntryIndexedValue"><NamingElement Priority="11"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="PUBLIC"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Global_0020constants/@EntryIndexedValue"><NamingElement Priority="15"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Global_0020variables/@EntryIndexedValue"><NamingElement Priority="7"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Local_0020variables/@EntryIndexedValue"><NamingElement Priority="6"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="local variable" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Other_0020constants/@EntryIndexedValue"><NamingElement Priority="14"><Descriptor Static="True" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="local variable" /><type Name="struct field" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Parameters/@EntryIndexedValue"><NamingElement Priority="5"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="parameter" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Properties/@EntryIndexedValue"><NamingElement Priority="19"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="property" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Template_0020parameters/@EntryIndexedValue"><NamingElement Priority="4"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="template parameter" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=07D75BA034491D4A953ED6E5148F7D73/@EntryIndexedValue"><NamingElement Priority="7" Title="Global variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=0986077B083B554CB570196C4E178E7B/@EntryIndexedValue"><NamingElement Priority="6" Title="Local variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="local variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=10FB356B3B631748858CE96002923FED/@EntryIndexedValue"><NamingElement Priority="15" Title="Global constants"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=3CC43DE3F2C84F448EDBECAA8FCE0CDD/@EntryIndexedValue"><NamingElement Priority="10" Title="Class and struct fields"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="m_" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=3F52F651527C1D4C8F432A4BBEC2212F/@EntryIndexedValue"><NamingElement Priority="5" Title="Parameters"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="function parameter" /><type Name="lambda parameter" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=70D2E9E8D1ABBF41ADC9B673341F663B/@EntryIndexedValue"><NamingElement Priority="14" Title="Other constants"><Descriptor Static="True" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="local variable" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=933131A49FF3B540B4090016350AF382/@EntryIndexedValue"><NamingElement Priority="4" Title="Template parameters"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="type template parameter" /><type Name="non-type template parameter" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=C569A41554F17E429BE7B1195CB7702A/@EntryIndexedValue"><NamingElement Priority="11" Title="Class and struct public fields"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="PUBLIC"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
- <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=FDF2EE6BFEDAD44495192D8ED14B267D/@EntryIndexedValue"><NamingElement Priority="19" Title="Properties"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="property" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aa_bb" /></NamingElement></s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=0AFB7787612DF743B09AD9412E48D4CC/@EntryIndexedValue"><NamingElement Priority="7" Title="Local variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="local variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=1350D079A82E0740947E85445B5AF47C/@EntryIndexedValue"><NamingElement Priority="6" Title="Parameters"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="function parameter" /><type Name="lambda parameter" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=72514D5DF422D442B71A277F97B72887/@EntryIndexedValue"><NamingElement Priority="8" Title="Global variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=B82A063F0DDD98498A70D8D7EBB97F8D/@EntryIndexedValue"><NamingElement Priority="12" Title="Class and struct fields"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="m_" Suffix="" Style="AaBb" /></NamingElement></s:String>
<s:String x:Key="/Default/Environment/InlayHints/CppParameterNameHintsOptions2/ShowParameterNameHints/@EntryValue">Never</s:String>
<s:String x:Key="/Default/Environment/InlayHints/GeneralInlayHintsOptions/DefaultMode/@EntryValue">Never</s:String>
<s:Boolean x:Key="/Default/Environment/InlayHints/GeneralInlayHintsOptions/EnableInlayHints/@EntryValue">False</s:Boolean>
diff --git a/far/FarCze.hlf.m4 b/far/FarCze.hlf.m4
index de0aa0861..fbaf05a6d 100644
--- a/far/FarCze.hlf.m4
+++ b/far/FarCze.hlf.m4
@@ -5768,12 +5768,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/FarDlgBuilder.cpp b/far/FarDlgBuilder.cpp
index e8393160f..66a82701d 100644
--- a/far/FarDlgBuilder.cpp
+++ b/far/FarDlgBuilder.cpp
@@ -85,15 +85,22 @@ private:
class EditFieldIntBinding final: public DialogItemBinding
{
public:
- EditFieldIntBinding(IntOption* IntValue, int Width):
- m_IntValue(IntValue)
+ EditFieldIntBinding(IntOption* IntValue, int Width, bool const Unsigned):
+ m_IntValue(IntValue),
+ m_Unsigned(Unsigned)
{
- m_Mask[0] = L'#';
- const auto MaskWidth = std::min(static_cast<int>(std::size(m_Mask) - 1), Width);
+ m_Mask[0] = Unsigned? L'9' : L'#';
+ const auto MaskWidth = std::min(static_cast<int>(std::size(m_Mask) - 1), std::min(Width, 20));
std::fill(m_Mask + 1, m_Mask + MaskWidth, L'9');
m_Mask[MaskWidth] = {};
}
+ auto data() const
+ {
+ const auto Value = m_IntValue->Get();
+ return m_Unsigned? str(as_unsigned(Value)) : str(Value);
+ }
+
void SaveValue(DialogItemEx const& Item, int const RadioGroupIndex) override
{
{
@@ -125,6 +132,7 @@ public:
private:
IntOption* m_IntValue;
wchar_t m_Mask[32];
+ bool m_Unsigned;
};
class EditFieldHexBinding final: public DialogItemBinding
@@ -139,6 +147,11 @@ public:
*(std::end(m_Mask) - 1) = {};
}
+ auto data() const
+ {
+ return far::format(L"0x{:016X}"sv, as_unsigned(m_IntValue->Get()));
+ }
+
void SaveValue(DialogItemEx const& Item, int const RadioGroupIndex) override
{
unsigned long long Value;
@@ -171,6 +184,11 @@ public:
*(std::end(m_Mask) - 1) = {};
}
+ auto data() const
+ {
+ return far::format(L"{0:064b}", as_unsigned(m_IntValue->Get()));
+ }
+
void SaveValue(DialogItemEx const& Item, int const RadioGroupIndex) override
{
// Must be converted to unsigned type first regardless of underlying type
@@ -338,14 +356,14 @@ static intptr_t ItemWidth(const DialogItemEx& Item)
return 0;
}
+constexpr size_t SupportedSize = 128;
+
DialogBuilder::DialogBuilder(lng_string const Title, const string_view HelpTopic, Dialog::dialog_handler handler):
m_HelpTopic(HelpTopic),
m_handler(std::move(handler))
{
- constexpr size_t MinSize = 128;
-
- m_DialogItems.reserve(MinSize);
- m_Bindings.reserve(MinSize);
+ m_DialogItems.reserve(SupportedSize);
+ m_Bindings.reserve(SupportedSize);
AddBorder(Title.c_str());
}
@@ -425,14 +443,14 @@ DialogItemEx& DialogBuilder::AddButtonAfter(DialogItemEx const& RelativeTo, lng_
return Item;
}
-DialogItemEx& DialogBuilder::AddIntEditField(IntOption& Value, int Width)
+DialogItemEx& DialogBuilder::AddIntEditField(IntOption& Value, int Width, bool const Unsigned)
{
auto& Item = AddDialogItem(DI_FIXEDIT, L"");
- Item.strData = str(Value.Get());
SetNextY(Item);
Item.X2 = Item.X1 + Width - 1;
- auto Binding = std::make_unique<EditFieldIntBinding>(&Value, Width);
+ auto Binding = std::make_unique<EditFieldIntBinding>(&Value, Width, Unsigned);
+ Item.strData = Binding->data();
Item.Flags |= DIF_MASKEDIT;
Item.strMask = Binding->GetMask();
SetLastItemBinding(std::move(Binding));
@@ -442,11 +460,11 @@ DialogItemEx& DialogBuilder::AddIntEditField(IntOption& Value, int Width)
DialogItemEx& DialogBuilder::AddHexEditField(IntOption& Value, int Width)
{
auto& Item = AddDialogItem(DI_FIXEDIT, L"");
- Item.strData = far::format(L"{:016X}"sv, as_unsigned(Value.Get()));
SetNextY(Item);
Item.X2 = Item.X1 + Width - 1;
auto Binding = std::make_unique<EditFieldHexBinding>(&Value);
+ Item.strData = Binding->data();
Item.Flags |= DIF_MASKEDIT;
Item.strMask = Binding->GetMask();
SetLastItemBinding(std::move(Binding));
@@ -456,11 +474,11 @@ DialogItemEx& DialogBuilder::AddHexEditField(IntOption& Value, int Width)
DialogItemEx& DialogBuilder::AddBinaryEditField(IntOption& Value, int Width)
{
auto& Item = AddDialogItem(DI_FIXEDIT, L"");
- Item.strData = far::format(L"{0:064b}", as_unsigned(Value.Get()));
SetNextY(Item);
Item.X2 = Item.X1 + Width - 1;
auto Binding = std::make_unique<EditFieldBinaryBinding>(&Value);
+ Item.strData = Binding->data();
Item.Flags |= DIF_MASKEDIT;
Item.strMask = Binding->GetMask();
SetLastItemBinding(std::move(Binding));
@@ -814,6 +832,8 @@ bool DialogBuilder::ShowDialog()
DialogItemEx& DialogBuilder::AddDialogItem(FARDIALOGITEMTYPES Type, const wchar_t* Text)
{
+ assert(m_DialogItems.size() < SupportedSize);
+
auto& Item = m_DialogItems.emplace_back();
Item.Type = Type;
Item.strData = Text;
diff --git a/far/FarDlgBuilder.hpp b/far/FarDlgBuilder.hpp
index 38acb9890..c830d4283 100644
--- a/far/FarDlgBuilder.hpp
+++ b/far/FarDlgBuilder.hpp
@@ -142,7 +142,7 @@ public:
DialogItemEx& AddTextBefore(DialogItemEx& RelativeTo, lng_string Text);
DialogItemEx& AddTextAfter(DialogItemEx const& RelativeTo, lng_string Text, int skip = 1);
DialogItemEx& AddButtonAfter(DialogItemEx const& RelativeTo, lng_string Text);
- DialogItemEx& AddIntEditField(IntOption& Value, int Width);
+ DialogItemEx& AddIntEditField(IntOption& Value, int Width, bool Unsigned = false);
DialogItemEx& AddHexEditField(IntOption& Value, int Width);
DialogItemEx& AddBinaryEditField(IntOption& Value, int Width);
DialogItemEx& AddEditField(string& Value, int Width, string_view HistoryID = {}, FARDIALOGITEMFLAGS Flags = DIF_NONE);
diff --git a/far/FarEng.hlf.m4 b/far/FarEng.hlf.m4
index 33a58a467..675f02550 100644
--- a/far/FarEng.hlf.m4
+++ b/far/FarEng.hlf.m4
@@ -5735,12 +5735,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/FarGer.hlf.m4 b/far/FarGer.hlf.m4
index 10ba26372..ab3ca9fec 100644
--- a/far/FarGer.hlf.m4
+++ b/far/FarGer.hlf.m4
@@ -5826,12 +5826,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/FarHun.hlf.m4 b/far/FarHun.hlf.m4
index e11a18cc7..f2be86eac 100644
--- a/far/FarHun.hlf.m4
+++ b/far/FarHun.hlf.m4
@@ -5846,12 +5846,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/FarPol.hlf.m4 b/far/FarPol.hlf.m4
index b866add82..583225498 100644
--- a/far/FarPol.hlf.m4
+++ b/far/FarPol.hlf.m4
@@ -5746,12 +5746,6 @@ Jeżeli bieżąca wartość opcji jest inna niż domyślna, opcja jest oznaczona
#Enter# lub #F4#
Przełącza lub edytuje wartość.
- #Shift+F4#
- Edytuje wartość całkowitą jako wartość szesnastkową. Dla innych typów działa jak #F4#.
-
- #Alt+F4#
- Edytuje wartość całkowitą jak liczbę binarną. Dla innych typów działa jak #F4#.
-
#Del#
Przywraca domyślną wartość opcji.
diff --git a/far/FarRus.hlf.m4 b/far/FarRus.hlf.m4
index d04908cd3..3d7319c9c 100644
--- a/far/FarRus.hlf.m4
+++ b/far/FarRus.hlf.m4
@@ -5812,12 +5812,6 @@ $ #Редактор конфигурации#
#Enter# или #F4#
Переключить или редактировать значение.
- #Shift+F4#
- Редактировать целое значение как шестнадцатеричное число. Для прочих типов аналогично #F4#.
-
- #Alt+F4#
- Редактировать целое значение как двоичное число. Для прочих типов аналогично #F4#.
-
#Del#
Сбросить параметр в значение по умолчанию.
diff --git a/far/FarSky.hlf.m4 b/far/FarSky.hlf.m4
index 7b9d20b48..53793408a 100644
--- a/far/FarSky.hlf.m4
+++ b/far/FarSky.hlf.m4
@@ -5729,12 +5729,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/FarUkr.hlf.m4 b/far/FarUkr.hlf.m4
index db30097af..e895d300a 100644
--- a/far/FarUkr.hlf.m4
+++ b/far/FarUkr.hlf.m4
@@ -5817,12 +5817,6 @@ If current value of an option is other than the default, the option is marked wi
#Enter# or #F4#
Toggle or edit the value.
- #Shift+F4#
- Edit the integer value as a hexadecimal number. For other types works as #F4#.
-
- #Alt+F4#
- Edit the integer value as a binary number. For other types works as #F4#.
-
#Del#
Reset the option to its default value.
diff --git a/far/changelog b/far/changelog
index 8e66e5346..e074e674c 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,10 @@
+--------------------------------------------------------------------------------
+drkns 2025-12-14 00:12:57+00:00 - build 6615
+
+1. Improve integer editing in far:config.
+ Remove all the nonsense with separate dialogs for hex and binary,
+ make all the forms available in a single dialog.
+
--------------------------------------------------------------------------------
drkns 2025-12-08 08:26:49+00:00 - build 6614
diff --git a/far/common/expected.hpp b/far/common/expected.hpp
index be9c80860..282bdc360 100644
--- a/far/common/expected.hpp
+++ b/far/common/expected.hpp
@@ -106,6 +106,11 @@ public:
return &value();
}
+ T value_or(T&& DefaultValue)
+ {
+ return has_value()? **this : FWD(DefaultValue);
+ }
+
E const& error() const
{
if (!has_value())
diff --git a/far/config.cpp b/far/config.cpp
index dce7d5cd0..01b73cdb9 100644
--- a/far/config.cpp
+++ b/far/config.cpp
@@ -95,6 +95,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Common:
#include "common/algorithm.hpp"
#include "common/from_string.hpp"
+#include "common/scope_exit.hpp"
#include "common/uuid.hpp"
#include "common/view/enumerate.hpp"
#include "common/view/zip.hpp"
@@ -1442,12 +1443,17 @@ struct FARConfigItem
return Item;
}
- bool Edit(int Mode) const
+ bool Edit() const
{
- DialogBuilder Builder;
- Builder.AddText(concat(KeyName, L'.', ValName, L" ("sv, Value->GetType(), L"):"sv));
+ std::any Context;
+
+ DialogBuilder Builder(concat(KeyName, L'.', ValName, L" ("sv, Value->GetType(), L")"sv), {}, [&](Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2) -> intptr_t
+ {
+ return Value->EditProc(Dlg, Msg, Param1, Param2, Context);
+ });
+
int Result = 0;
- if (!Value->Edit(Builder, Mode))
+ if (!Value->Edit(Builder, Context))
{
Builder.AddSeparator();
Builder.AddButtons({{ lng::MOk, lng::MReset, lng::MCancel }});
@@ -1508,8 +1514,6 @@ static bool ParseIntValue(string_view const sValue, long long& iValue)
enum class edit_mode
{
normal,
- hex,
- bin,
reset
};
@@ -1530,6 +1534,12 @@ void detail::OptionImpl<base_type, derived>::StoreValue(GeneralConfig* Storage,
}
+intptr_t Option::EditProc(Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2, std::any& Context)
+{
+ return Dlg->DefProc(Msg, Param1, Param2);
+}
+
+
bool BoolOption::TryParse(const string_view value)
{
long long iValue;
@@ -1540,7 +1550,12 @@ bool BoolOption::TryParse(const string_view value)
return true;
}
-bool BoolOption::Edit(DialogBuilder&, int)
+string_view BoolOption::GetType() const
+{
+ return msg(lng::MConfigEditorBoolean);
+}
+
+bool BoolOption::Edit(DialogBuilder&, std::any&)
{
Set(!Get());
return true;
@@ -1563,7 +1578,12 @@ bool Bool3Option::TryParse(const string_view value)
return true;
}
-bool Bool3Option::Edit(DialogBuilder&, int)
+string_view Bool3Option::GetType() const
+{
+ return msg(lng::MConfigEditorTriState);
+}
+
+bool Bool3Option::Edit(DialogBuilder&, std::any&)
{
Set((Get() + 1) % 3);
return true;
@@ -1591,44 +1611,106 @@ bool IntOption::TryParse(const string_view value)
return true;
}
-bool IntOption::Edit(DialogBuilder& Builder, int const Param)
+struct int_edit_context
{
- switch (static_cast<edit_mode>(Param))
+ intptr_t
+ SignedItem,
+ UnsignedItem,
+ HexItem,
+ BinaryItem;
+
+ bool Updating{};
+};
+
+bool IntOption::Edit(DialogBuilder& Builder, std::any& Param)
+{
+ auto& Context = Param.emplace<int_edit_context>();
+
+ Builder.AddText(lng::MConfigEditorIntegerSigned);
+ Builder.AddIntEditField(*this, 21);
+ Context.SignedItem = Builder.GetLastID();
+
+ Builder.AddText(lng::MConfigEditorIntegerUnsigned);
+ Builder.AddIntEditField(*this, 21, true);
+ Context.UnsignedItem = Builder.GetLastID();
+
+ Builder.AddText(lng::MConfigEditorIntegerHexadecimal);
+ Builder.AddHexEditField(*this, 2 + 16);
+ Context.HexItem = Builder.GetLastID();
+
+ Builder.AddText(lng::MConfigEditorIntegerBinary);
+ Builder.AddBinaryEditField(*this, 64);
+ Context.BinaryItem = Builder.GetLastID();
+
+ string High, Low;
+ const auto BitCount = 64;
+
+ High.reserve(BitCount);
+ Low.reserve(BitCount);
+
+ for (const auto i: std::views::iota(0, BitCount))
{
- case edit_mode::normal:
- Builder.AddIntEditField(*this, 20);
- break;
+ const auto Num = BitCount - 1 - i;
+ High.push_back(static_cast<wchar_t>(L'0' + Num / 10));
+ Low.push_back(static_cast<wchar_t>(L'0' + Num % 10));
+ }
- case edit_mode::hex:
- Builder.AddHexEditField(*this, 16 + 2);
- break;
+ Builder.AddText(High).Flags |= DIF_DISABLE;
+ Builder.AddText(Low).Flags |= DIF_DISABLE;
- case edit_mode::bin:
+ Param = Context;
+
+ return false;
+}
+
+intptr_t IntOption::EditProc(Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2, std::any& Context)
+{
+ switch (Msg)
+ {
+ case DN_EDITCHANGE:
{
- Builder.AddBinaryEditField(*this, 64);
- string High, Low;
- const auto BitCount = 64;
+ auto& Ctx = std::any_cast<int_edit_context&>(Context);
+ const auto& Item = *static_cast<const FarDialogItem*>(Param2);
- High.reserve(BitCount);
- Low.reserve(BitCount);
+ if (Ctx.Updating)
+ return TRUE;
- for (const auto i: std::views::iota(0, BitCount))
+ Ctx.Updating = true;
+ SCOPE_EXIT{ Ctx.Updating = false; };
+
+ SCOPED_ACTION(Dialog::suppress_redraw)(Dlg);
+
+ const auto set = [&](intptr_t const Id, string const& Value)
{
- const auto Num = BitCount - 1 - i;
- High.push_back(static_cast<wchar_t>(L'0' + Num / 10));
- Low.push_back(static_cast<wchar_t>(L'0' + Num % 10));
- }
+ Dlg->SendMessage(DM_SETTEXTPTR, Id, UNSAFE_CSTR(Value));
+ };
+
+ const auto update = [&](unsigned long long Value)
+ {
+ if (Param1 != Ctx.SignedItem)
+ set(Ctx.SignedItem, str(as_signed(Value)));
+ if (Param1 != Ctx.UnsignedItem)
+ set(Ctx.UnsignedItem, str(as_unsigned(Value)));
+ if (Param1 != Ctx.HexItem)
+ set(Ctx.HexItem, far::format(L"0x{:016X}"sv, as_unsigned(Value)));
+ if (Param1 != Ctx.BinaryItem)
+ set(Ctx.BinaryItem, far::format(L"{0:064b}"sv, as_unsigned(Value)));
+ };
- Builder.AddText(High).Flags |= DIF_DISABLE;
- Builder.AddText(Low).Flags |= DIF_DISABLE;
+ if (Param1 == Ctx.SignedItem)
+ update(try_from_string<long long>(Item.Data).value_or(0));
+ else if (Param1 == Ctx.UnsignedItem)
+ update(try_from_string<unsigned long long>(Item.Data).value_or(0));
+ else if (Param1 == Ctx.HexItem)
+ update(try_from_string<unsigned long long>(Item.Data, {}, 16).value_or(0));
+ else if (Param1 == Ctx.BinaryItem)
+ update(try_from_string<unsigned long long>(Item.Data, {}, 2).value_or(0));
}
- break;
+ return TRUE;
default:
- std::unreachable();
+ return OptionImpl::EditProc(Dlg, Msg, Param1, Param2, Context);
}
-
- return false;
}
void IntOption::Export(FarSettingsItem& To) const
@@ -1643,8 +1725,18 @@ string IntOption::ExInfo() const
return far::format(L" = 0x{:X}"sv, as_unsigned(Get()));
}
+string_view IntOption::GetType() const
+{
+ return msg(lng::MConfigEditorInteger);
+}
+
-bool StringOption::Edit(DialogBuilder& Builder, int)
+string_view StringOption::GetType() const
+{
+ return msg(lng::MConfigEditorString);
+}
+
+bool StringOption::Edit(DialogBuilder& Builder, std::any&)
{
Builder.AddEditField(*this, 40);
return false;
@@ -2552,7 +2644,7 @@ intptr_t Options::AdvancedConfigDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Para
break;
default:
- if (!CurrentItem->Edit(static_cast<int>(EditMode)))
+ if (!CurrentItem->Edit())
return;
break;
}
@@ -2575,7 +2667,7 @@ intptr_t Options::AdvancedConfigDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Para
FarListTitles Titles{ sizeof(Titles) };
- const auto BottomTitle = KeysToLocalizedText(KEY_SHIFTF1, KEY_F4, KEY_SHIFTF4, KEY_ALTF4, KEY_DEL, KEY_CTRLH);
+ const auto BottomTitle = KeysToLocalizedText(KEY_SHIFTF1, KEY_F4, KEY_DEL, KEY_CTRLH);
Titles.Title = msg(lng::MConfigEditor).c_str();
Titles.Bottom = BottomTitle.c_str();
Dlg->SendMessage(DM_LISTSETTITLES, ac_item_listbox, &Titles);
@@ -2621,14 +2713,6 @@ intptr_t Options::AdvancedConfigDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Para
EditItem(edit_mode::normal);
break;
- case KEY_SHIFTF4:
- EditItem(edit_mode::hex);
- break;
-
- case KEY_ALTF4:
- EditItem(edit_mode::bin);
- break;
-
case KEY_DEL:
case KEY_NUMDEL:
EditItem(edit_mode::reset);
diff --git a/far/config.hpp b/far/config.hpp
index 4124a1ec6..a0b52f7ea 100644
--- a/far/config.hpp
+++ b/far/config.hpp
@@ -55,6 +55,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct FarSettingsItem;
class GeneralConfig;
class RegExp;
+class Dialog;
class DialogBuilder;
struct PanelViewSettings;
struct column;
@@ -175,7 +176,8 @@ public:
virtual bool IsDefault(const variant& Default) const = 0;
virtual void SetDefault(const variant& Default) = 0;
[[nodiscard]]
- virtual bool Edit(DialogBuilder& Builder, int Param) = 0;
+ virtual bool Edit(DialogBuilder& Builder, std::any& Param) = 0;
+ virtual intptr_t EditProc(Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2, std::any& Context);
virtual void Export(FarSettingsItem& To) const = 0;
[[nodiscard]]
@@ -332,9 +334,9 @@ public:
[[nodiscard]]
bool TryParse(string_view value) override;
[[nodiscard]]
- string_view GetType() const override { return L"boolean"sv; }
+ string_view GetType() const override;
[[nodiscard]]
- bool Edit(DialogBuilder& Builder, int Param) override;
+ bool Edit(DialogBuilder& Builder, std::any& Param) override;
void Export(FarSettingsItem& To) const override;
[[nodiscard]]
@@ -352,9 +354,9 @@ public:
[[nodiscard]]
bool TryParse(string_view value) override;
[[nodiscard]]
- string_view GetType() const override { return L"3-state"sv; }
+ string_view GetType() const override;
[[nodiscard]]
- bool Edit(DialogBuilder& Builder, int Param) override;
+ bool Edit(DialogBuilder& Builder, std::any& Param) override;
void Export(FarSettingsItem& To) const override;
[[nodiscard]]
@@ -374,9 +376,10 @@ public:
[[nodiscard]]
string ExInfo() const override;
[[nodiscard]]
- string_view GetType() const override { return L"integer"sv; }
+ string_view GetType() const override;
[[nodiscard]]
- bool Edit(DialogBuilder& Builder, int Param) override;
+ bool Edit(DialogBuilder& Builder, std::any& Param) override;
+ intptr_t EditProc(Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2, std::any& Context) override;
void Export(FarSettingsItem& To) const override;
IntOption& operator|=(long long Value){Set(Get()|Value); return *this;}
@@ -401,9 +404,9 @@ public:
[[nodiscard]]
bool TryParse(string_view value) override { Set(string(value)); return true; }
[[nodiscard]]
- string_view GetType() const override { return L"string"sv; }
+ string_view GetType() const override;
[[nodiscard]]
- bool Edit(DialogBuilder& Builder, int Param) override;
+ bool Edit(DialogBuilder& Builder, std::any& Param) override;
void Export(FarSettingsItem& To) const override;
StringOption& operator+=(const string& Value) {Set(Get()+Value); return *this;}
diff --git a/far/farlang.templ.m4 b/far/farlang.templ.m4
index 7f28d0bcd..f178340aa 100644
--- a/far/farlang.templ.m4
+++ b/far/farlang.templ.m4
@@ -4690,6 +4690,126 @@ upd:"Configuration editor"
upd:"Configuration editor"
upd:"Configuration editor"
+MConfigEditorBoolean
+upd:"boolean"
+"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+upd:"boolean"
+
+MConfigEditorTriState
+upd:"3-state"
+"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+upd:"3-state"
+
+MConfigEditorInteger
+upd:"integer"
+"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+upd:"integer"
+
+MConfigEditorString
+upd:"string"
+"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+upd:"string"
+
+MConfigEditorIntegerSigned
+upd:"Signed:"
+"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+upd:"Signed:"
+
+MConfigEditorIntegerUnsigned
+upd:"Unsigned:"
+"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+upd:"Unsigned:"
+
+MConfigEditorIntegerHexadecimal
+upd:"Hexadecimal:"
+"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+upd:"Hexadecimal:"
+
+MConfigEditorIntegerBinary
+upd:"Binary:"
+"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+upd:"Binary:"
+
MSaveSetupTitle
l:
"Конфигурация"
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index b41135939..4cd877762 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6614
+6615