Fix tdf#44291. Allow saving text without byte-order mark.

Change-Id: Ib16a4f37adcb2cfb3d2af9b6af21a4b32e4ae54c
Reviewed-on: https://gerrit.libreoffice.org/50388
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx
index 137cc4e..2e1e8b8 100644
--- a/sw/inc/shellio.hxx
+++ b/sw/inc/shellio.hxx
@@ -66,6 +66,7 @@
    rtl_TextEncoding eCharSet;
    LanguageType nLanguage;
    LineEnd eCRLF_Flag;
    bool bIncludeBOM;   // Whether to include a byte-order-mark in the output.

public:

@@ -81,12 +82,16 @@
    LineEnd GetParaFlags() const { return eCRLF_Flag; }
    void SetParaFlags( LineEnd eVal ) { eCRLF_Flag = eVal; }

    bool GetIncludeBOM() const { return bIncludeBOM; }
    void SetIncludeBOM( bool bVal ) { bIncludeBOM = bVal; }

    void Reset()
    {
        sFont.clear();
        eCRLF_Flag = GetSystemLineEnd();
        eCharSet = ::osl_getThreadTextEncoding();
        nLanguage = LANGUAGE_SYSTEM;
        bIncludeBOM = true;
    }
    // for the automatic conversion (mail/news/...)
    void ReadUserData( const OUString& );
diff --git a/sw/source/filter/ascii/wrtasc.cxx b/sw/source/filter/ascii/wrtasc.cxx
index b8964aaa..c5f6f3f 100644
--- a/sw/source/filter/ascii/wrtasc.cxx
+++ b/sw/source/filter/ascii/wrtasc.cxx
@@ -85,6 +85,8 @@

ErrCode SwASCWriter::WriteStream()
{
    bool bIncludeBOM = GetAsciiOptions().GetIncludeBOM();

    if( m_bASCII_ParaAsCR )           // If predefined
        m_sLineEnd = "\015";
    else if( m_bASCII_ParaAsBlank )
@@ -154,15 +156,25 @@
                        switch(GetAsciiOptions().GetCharSet())
                        {
                            case RTL_TEXTENCODING_UTF8:
                                Strm().WriteUChar( 0xEF ).WriteUChar( 0xBB ).WriteUChar( 0xBF );
                                if( bIncludeBOM )
                                {
                                    Strm().WriteUChar( 0xEF ).WriteUChar( 0xBB ).WriteUChar( 0xBF );
                                }

                                break;
                            case RTL_TEXTENCODING_UCS2:
#ifdef OSL_LITENDIAN
                                Strm().SetEndian(SvStreamEndian::LITTLE);
                                Strm().WriteUChar( 0xFF ).WriteUChar( 0xFE );
                                if( bIncludeBOM )
                                {
                                    Strm().WriteUChar( 0xFF ).WriteUChar( 0xFE );
                                }
#else
                                Strm().SetEndian(SvStreamEndian::BIG);
                                Strm().WriteUChar( 0xFE ).WriteUChar( 0xFF );
                                if( bIncludeBOM )
                                {
                                    Strm().WriteUChar( 0xFE ).WriteUChar( 0xFF );
                                }
#endif
                                break;

diff --git a/sw/source/filter/basflt/fltini.cxx b/sw/source/filter/basflt/fltini.cxx
index 16756e47..8ecd122 100644
--- a/sw/source/filter/basflt/fltini.cxx
+++ b/sw/source/filter/basflt/fltini.cxx
@@ -570,6 +570,7 @@
//      2. LineEnd - as CR/LR/CRLF
//      3. Fontname
//      4. Language
//      5. Whether to include byte-order-mark
// the delimiter character is ","

void SwAsciiOptions::ReadUserData( const OUString& rStr )
@@ -599,6 +600,9 @@
            case 3:         // Language
                nLanguage = LanguageTag::convertToLanguageTypeWithFallback( sToken );
                break;
            case 4:
                bIncludeBOM = !(sToken.equalsIgnoreAsciiCase("FALSE"));
                break;
            }
        }
        ++nCnt;
@@ -634,6 +638,17 @@
        rStr += LanguageTag::convertToBcp47(nLanguage);
    }
    rStr += ",";

    // 5. Whether to include byte-order-mark
    if( bIncludeBOM )
    {
        rStr += "true";
    }
    else
    {
        rStr += "false";
    }
    rStr += ",";
}

#ifdef DISABLE_DYNLOADING
diff --git a/sw/source/ui/dialog/ascfldlg.cxx b/sw/source/ui/dialog/ascfldlg.cxx
index 3b36d6f..1637fc7 100644
--- a/sw/source/ui/dialog/ascfldlg.cxx
+++ b/sw/source/ui/dialog/ascfldlg.cxx
@@ -71,6 +71,7 @@
    , m_xCRLF_RB(m_xBuilder->weld_radio_button("crlf"))
    , m_xCR_RB(m_xBuilder->weld_radio_button("cr"))
    , m_xLF_RB(m_xBuilder->weld_radio_button("lf"))
    , m_xIncludeBOM_CB(m_xBuilder->weld_check_button("includebom"))
{
    m_xFontLB->make_sorted();

@@ -222,6 +223,8 @@
                pPrt.disposeAndClear();
        }

        // hide the unused Controls for Export
        m_xIncludeBOM_CB->hide();
    }
    else
    {
@@ -230,6 +233,10 @@
        m_xFontLB->hide();
        m_xLanguageFT->hide();
        m_xLanguageLB->hide();


        SetIncludeBOM(aOpt.GetIncludeBOM());
        m_xIncludeBOM_CB->save_state();
    }

    // initialize character set
@@ -246,6 +253,8 @@
    m_xCRLF_RB->save_state();
    m_xLF_RB->save_state();
    m_xCR_RB->save_state();

    UpdateIncludeBOMSensitiveState();
}

SwAsciiFilterDlg::~SwAsciiFilterDlg()
@@ -269,6 +278,7 @@
    rOptions.SetCharSet( rtl_TextEncoding( nCCode ) );
    rOptions.SetLanguage( nLng );
    rOptions.SetParaFlags( GetCRLF() );
    rOptions.SetIncludeBOM( GetIncludeBOM() );

    // save the user settings
    OUString sData;
@@ -319,7 +329,34 @@
    return eEnd;
}

IMPL_LINK_NOARG( SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox&, void )
void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM )
{
    m_xIncludeBOM_CB->set_state(bIncludeBOM ? TRISTATE_TRUE : TRISTATE_FALSE);
}

bool SwAsciiFilterDlg::GetIncludeBOM() const
{
    return m_xIncludeBOM_CB->get_state() != TRISTATE_FALSE;
}

void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState()
{
    if (m_xIncludeBOM_CB->get_visible())
    {
        switch (m_xCharSetLB->GetSelectTextEncoding())
        {
            case RTL_TEXTENCODING_UTF8:
            case RTL_TEXTENCODING_UCS2:
                m_xIncludeBOM_CB->set_sensitive(true);
                break;
            default:
                m_xIncludeBOM_CB->set_sensitive(false);
                break;
        }
    }
}

IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox&, void)
{
    LineEnd eOldEnd = GetCRLF(), eEnd = LineEnd(-1);
    LanguageType nLng = m_xFontLB->get_visible()
@@ -391,6 +428,8 @@

    if (nOldLng != nLng && m_xFontLB->get_visible())
        m_xLanguageLB->set_active_id(nLng);

    UpdateIncludeBOMSensitiveState();
}

IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::ToggleButton&, rBtn, void)
diff --git a/sw/source/uibase/inc/ascfldlg.hxx b/sw/source/uibase/inc/ascfldlg.hxx
index 038d570..1a1fb11 100644
--- a/sw/source/uibase/inc/ascfldlg.hxx
+++ b/sw/source/uibase/inc/ascfldlg.hxx
@@ -43,11 +43,15 @@
    std::unique_ptr<weld::RadioButton> m_xCRLF_RB;
    std::unique_ptr<weld::RadioButton> m_xCR_RB;
    std::unique_ptr<weld::RadioButton> m_xLF_RB;
    std::unique_ptr<weld::CheckButton> m_xIncludeBOM_CB;

    DECL_LINK(CharSetSelHdl, weld::ComboBox&, void);
    DECL_LINK(LineEndHdl, weld::ToggleButton&, void);
    void SetCRLF( LineEnd eEnd );
    LineEnd GetCRLF() const;
    void SetIncludeBOM( bool bIncludeBOM );
    bool GetIncludeBOM() const;
    void UpdateIncludeBOMSensitiveState();

public:
    // CTOR:    for import - pStream is the inputstream
diff --git a/sw/uiconfig/swriter/ui/asciifilterdialog.ui b/sw/uiconfig/swriter/ui/asciifilterdialog.ui
index 2338fc8..52b3825 100644
--- a/sw/uiconfig/swriter/ui/asciifilterdialog.ui
+++ b/sw/uiconfig/swriter/ui/asciifilterdialog.ui
@@ -253,6 +253,22 @@
                        <property name="top_attach">2</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkCheckButton" id="includebom">
                        <property name="label" translatable="yes" context="asciifilterdialog|includebom">Include byte-order-mark</property>
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">False</property>
                        <property name="xalign">0</property>
                        <property name="draw_indicator">True</property>
                      </object>
                      <packing>
                        <property name="left_attach">0</property>
                        <property name="top_attach">4</property>
                        <property name="width">2</property>
                        <property name="height">1</property>
                      </packing>
                    </child>
                  </object>
                </child>
              </object>