Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/774d08e2a953d3379897922b950c6385e09ae6af
>---------------------------------------------------------------
commit 774d08e2a953d3379897922b950c6385e09ae6af
Author: Alex Alabuzhev <
alab...@gmail.com>
Date: Wed Jul 15 22:10:19 2026 +0100
Allow to select another codepage from bad codepage dialog when saving a file
>---------------------------------------------------------------
774d08e2a953d3379897922b950c6385e09ae6af
far/changelog | 5 ++++
far/fileedit.cpp | 75 ++++++++++++++++++++++++++++++++------------------------
far/fileedit.hpp | 2 +-
far/vbuild.m4 | 2 +-
4 files changed, 50 insertions(+), 34 deletions(-)
diff --git a/far/changelog b/far/changelog
index d4daf8c7c..f1fe284b3 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-07-15 22:08:49+01:00 - build 6717
+
+1. Allow to select another codepage from bad codepage dialog when saving a file.
+
--------------------------------------------------------------------------------
drkns 2026-07-14 21:21:14+01:00 - build 6716
diff --git a/far/fileedit.cpp b/far/fileedit.cpp
index 6cab0d592..ba871e378 100644
--- a/far/fileedit.cpp
+++ b/far/fileedit.cpp
@@ -184,11 +184,18 @@ bool dlgOpenEditor(string &strFileName, uintptr_t &codepage)
return false;
}
-static bool dlgBadEditorCodepage(uintptr_t& codepage, bytes_view const ErrorBytes)
+enum class badcp_action
+{
+ show,
+ proceed,
+ cancel
+};
+
+static badcp_action BadCodepageDialog(bool const IsLoad, uintptr_t& codepage, std::variant<wchar_t, bytes> const& Data)
{
DialogBuilder Builder(lng::MWarning);
- const auto [UsupportedData, UsupportedDataMessage] = codepages::UnsupportedDataMessage(bytes{ ErrorBytes });
+ const auto [UsupportedData, UsupportedDataMessage] = codepages::UnsupportedDataMessage(Data);
string const Messages[]
{
@@ -219,15 +226,30 @@ static bool dlgBadEditorCodepage(uintptr_t& codepage, bytes_view const ErrorByte
add_line(Messages[2]);
add_line(Messages[3]);
- Builder.AddOKCancel();
+ if (IsLoad)
+ Builder.AddOKCancel();
+ else
+ {
+ Builder.AddSeparator();
+ Builder.AddButtons({{ lng::MEditorSaveCPWarnShow, lng::MEditorSave, lng::MCancel }});
+ }
+
Builder.SetDialogMode(DMODE_WARNINGSTYLE);
Builder.SetId(BadEditorCodePageId);
- if (!Builder.ShowDialog())
- return false;
+ const auto Result = Builder.ShowDialogEx();
+ const auto CancelButtonId = IsLoad? 1 : 2;
- codepage = cp_val;
- return true;
+ if (Result < 0 || Result == CancelButtonId)
+ return badcp_action::cancel;
+
+ if (IsLoad || Result == 1)
+ {
+ codepage = cp_val;
+ return badcp_action::proceed;
+ }
+
+ return badcp_action::show;
}
enum enumSaveFileAs
@@ -1543,7 +1565,7 @@ bool FileEditor::LoadFile(const string_view Name, int& UserBreak, error_state_ex
{
BadConversion = true;
uintptr_t cp = m_codepage;
- if (!dlgBadEditorCodepage(cp, ErrorBytes)) // cancel
+ if (BadCodepageDialog(true, cp, bytes{ ErrorBytes }) == badcp_action::cancel)
{
EditFile.Close();
SetLastError(ERROR_OPEN_FAILED); //????
@@ -1713,15 +1735,8 @@ bool FileEditor::ReloadFile(uintptr_t codepage)
}
}
-// Eol and Codepage are used ONLY if bSaveAs = true!
-int FileEditor::SaveFile(const string_view Name, bool bSaveAs, error_state_ex& ErrorState, eol Eol, uintptr_t Codepage, bool AddSignature)
+int FileEditor::SaveFile(const string_view Name, bool bSaveAs, error_state_ex& ErrorState, eol Eol, uintptr_t& Codepage, bool AddSignature)
{
- if (!bSaveAs)
- {
- Eol = eol::none;
- Codepage=m_editor->GetCodePage();
- }
-
SCOPED_ACTION(taskbar::indeterminate);
SCOPED_ACTION(wakeful);
@@ -1826,11 +1841,16 @@ int FileEditor::SaveFile(const string_view Name, bool bSaveAs, error_state_ex& E
// 2025-05-31 MZK And the file is not ephemeral anymore
m_Flags.Clear(FFILEEDIT_DELETEONCLOSE | FFILEEDIT_DELETEONLYFILEONCLOSE | FFILEEDIT_EPHEMERAL);
- if (!IsUtfCodePage(Codepage))
+ for (;;)
{
+ if (IsUtfCodePage(Codepage))
+ break;
+
int LineNumber=-1;
encoding::diagnostics Diagnostics;
+ const auto CurrentCodepage = Codepage;
+
for(auto& Line: m_editor->Lines)
{
++LineNumber;
@@ -1844,24 +1864,12 @@ int FileEditor::SaveFile(const string_view Name, bool bSaveAs, error_state_ex& E
if (Diagnostics.ErrorPosition)
{
- const auto [UsupportedData, UsupportedDataMessage] = codepages::UnsupportedDataMessage(SaveStr[*Diagnostics.ErrorPosition]);
-
- //SetMessageHelp(L"EditorDataLostWarning")
- const auto Result = Message(MSG_WARNING,
- msg(lng::MWarning),
- {
- msg(lng::MUnsupportedCodePageSelectedCodepage),
- codepages::FormatName(Codepage),
- far::vformat(msg(lng::MUnsupportedCodePageDoesNotSupport), msg(UsupportedDataMessage)),
- UsupportedData,
- msg(lng::MEditorSaveNotRecommended)
- },
- { lng::MEditorSaveCPWarnShow, lng::MEditorSave, lng::MCancel });
+ const auto Result = BadCodepageDialog(false, Codepage, SaveStr[*Diagnostics.ErrorPosition]);
- if (Result == message_result::second_button)
+ if (Result == badcp_action::proceed)
break;
- if(Result == message_result::first_button)
+ if(Result == badcp_action::show)
{
m_editor->GoToLine(LineNumber);
if(!ValidStr)
@@ -1877,6 +1885,9 @@ int FileEditor::SaveFile(const string_view Name, bool bSaveAs, error_state_ex& E
return SAVEFILE_CANCEL;
}
}
+
+ if (CurrentCodepage == Codepage)
+ break;
}
const string NameForPlugin(Name);
diff --git a/far/fileedit.hpp b/far/fileedit.hpp
index 30051eb83..f8d7e3f7a 100644
--- a/far/fileedit.hpp
+++ b/far/fileedit.hpp
@@ -148,7 +148,7 @@ private:
bool LoadFile(string_view Name, int &UserBreak, error_state_ex& ErrorState);
bool ReloadFile(uintptr_t codepage);
//TextFormat, Codepage и AddSignature используются ТОЛЬКО, если bSaveAs = true!
- int SaveFile(string_view Name, bool bSaveAs, error_state_ex& ErrorState, eol Eol = eol::none, uintptr_t Codepage = CP_UTF16LE, bool AddSignature = false);
+ int SaveFile(string_view Name, bool bSaveAs, error_state_ex& ErrorState, eol Eol, uintptr_t& Codepage, bool AddSignature);
bool SaveAction(bool SaveAsIntention);
void SetTitle(const string* Title);
void SetFileName(string_view NewFileName);
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index a26334164..b7051fdf4 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6716
+6717