weld SvxCharTwoLinesPage

Change-Id: I54a8963cd8b12f5fd51bf6b3bb791a4a15fbd13d
Reviewed-on: https://gerrit.libreoffice.org/55762
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
index 144b13e..37b8dae 100644
--- a/cui/source/inc/chardlg.hxx
+++ b/cui/source/inc/chardlg.hxx
@@ -327,32 +327,31 @@ public:

// class SvxCharTwoLinesPage ---------------------------------------------

class SvxCharTwoLinesPage : public SvxCharBasePage
class SvxCharTwoLinesPage : public CharBasePage
{
    friend class VclPtr<SvxCharTwoLinesPage>;
private:
    static const sal_uInt16 pTwoLinesRanges[];
    VclPtr<CheckBox>           m_pTwoLinesBtn;
    VclPtr<VclContainer>       m_pEnclosingFrame;
    VclPtr<ListBox>            m_pStartBracketLB;
    VclPtr<ListBox>            m_pEndBracketLB;

    sal_uInt16              m_nStartBracketPosition;
    sal_uInt16              m_nEndBracketPosition;

    SvxCharTwoLinesPage(vcl::Window* pParent, const SfxItemSet& rSet);
    std::unique_ptr<weld::CheckButton>  m_xTwoLinesBtn;
    std::unique_ptr<weld::Widget> m_xEnclosingFrame;
    std::unique_ptr<weld::TreeView> m_xStartBracketLB;
    std::unique_ptr<weld::TreeView> m_xEndBracketLB;

    SvxCharTwoLinesPage(TabPageParent pParent, const SfxItemSet& rSet);

    void                UpdatePreview_Impl();
    void                Initialize();
    void                SelectCharacter( ListBox* pBox );
    void                SetBracket( sal_Unicode cBracket, bool bStart );
    void                SelectCharacter(weld::TreeView* pBox);
    void                SetBracket(sal_Unicode cBracket, bool bStart);

    DECL_LINK(TwoLinesHdl_Impl, Button*, void);
    DECL_LINK(CharacterMapHdl_Impl, ListBox&, void );
    DECL_LINK(TwoLinesHdl_Impl, weld::ToggleButton&, void);
    DECL_LINK(CharacterMapHdl_Impl, weld::TreeView&, void);

public:
    virtual ~SvxCharTwoLinesPage() override;
    virtual void dispose() override;

    using SfxTabPage::ActivatePage;
    using SfxTabPage::DeactivatePage;
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index 0ee3241..4227b50 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -3127,45 +3127,33 @@ void SvxCharPositionPage::PageCreated(const SfxAllItemSet& aSet)
}
// class SvxCharTwoLinesPage ------------------------------------------------

SvxCharTwoLinesPage::SvxCharTwoLinesPage(vcl::Window* pParent, const SfxItemSet& rInSet)
    : SvxCharBasePage(pParent, "TwoLinesPage", "cui/ui/twolinespage.ui", rInSet)
SvxCharTwoLinesPage::SvxCharTwoLinesPage(TabPageParent pParent, const SfxItemSet& rInSet)
    : CharBasePage(pParent, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet)
    , m_nStartBracketPosition( 0 )
    , m_nEndBracketPosition( 0 )
    , m_xTwoLinesBtn(m_xBuilder->weld_check_button("twolines"))
    , m_xEnclosingFrame(m_xBuilder->weld_widget("enclosing"))
    , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
    , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
{
    get(m_pTwoLinesBtn, "twolines");
    get(m_pEnclosingFrame, "enclosing");
    get(m_pStartBracketLB, "startbracket");
    get(m_pEndBracketLB, "endbracket");

    get(m_pPreviewWin, "preview");

    m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
    Initialize();
}

SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
{
    disposeOnce();
}

void SvxCharTwoLinesPage::dispose()
{
    m_pTwoLinesBtn.clear();
    m_pEnclosingFrame.clear();
    m_pStartBracketLB.clear();
    m_pEndBracketLB.clear();
    SvxCharBasePage::dispose();
}

void SvxCharTwoLinesPage::Initialize()
{
    m_pTwoLinesBtn->Check( false );
    TwoLinesHdl_Impl( nullptr );
    m_xTwoLinesBtn->set_active(false);
    TwoLinesHdl_Impl(*m_xTwoLinesBtn);

    m_pTwoLinesBtn->SetClickHdl( LINK( this, SvxCharTwoLinesPage, TwoLinesHdl_Impl ) );
    m_xTwoLinesBtn->connect_toggled(LINK(this, SvxCharTwoLinesPage, TwoLinesHdl_Impl));

    Link<ListBox&,void> aLink = LINK( this, SvxCharTwoLinesPage, CharacterMapHdl_Impl );
    m_pStartBracketLB->SetSelectHdl( aLink );
    m_pEndBracketLB->SetSelectHdl( aLink );
    Link<weld::TreeView&,void> aLink = LINK(this, SvxCharTwoLinesPage, CharacterMapHdl_Impl);
    m_xStartBracketLB->connect_changed(aLink);
    m_xEndBracketLB->connect_changed(aLink);

    SvxFont& rFont = GetPreviewFont();
    SvxFont& rCJKFont = GetPreviewCJKFont();
@@ -3175,10 +3163,9 @@ void SvxCharTwoLinesPage::Initialize()
    rCTLFont.SetFontSize( Size( 0, 220 ) );
}


void SvxCharTwoLinesPage::SelectCharacter( ListBox* pBox )
void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView* pBox)
{
    bool bStart = pBox == m_pStartBracketLB;
    bool bStart = pBox == m_xStartBracketLB.get();
    SvxCharacterMap aDlg(GetFrameWeld(), nullptr, false);
    aDlg.DisableFontSelection();

@@ -3189,28 +3176,28 @@ void SvxCharTwoLinesPage::SelectCharacter( ListBox* pBox )
    }
    else
    {
        pBox->SelectEntryPos( bStart ? m_nStartBracketPosition : m_nEndBracketPosition );
        pBox->select(bStart ? m_nStartBracketPosition : m_nEndBracketPosition);
    }
}


void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
{
    sal_Int32 nEntryPos = 0;
    ListBox* pBox = bStart ? m_pStartBracketLB.get() : m_pEndBracketLB.get();
    if ( 0 == cBracket )
        pBox->SelectEntryPos(0);
    int nEntryPos = 0;
    weld::TreeView* pBox = bStart ? m_xStartBracketLB.get() : m_xEndBracketLB.get();
    if (cBracket == 0)
        pBox->select(0);
    else
    {
        bool bFound = false;
        for ( sal_Int32 i = 1; i < pBox->GetEntryCount(); ++i )
        for (int i = 1; i < pBox->n_children(); ++i)
        {
            if ( reinterpret_cast<sal_uLong>(pBox->GetEntryData(i)) != CHRDLG_ENCLOSE_SPECIAL_CHAR )
            if (pBox->get_id(i).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR)
            {
                const sal_Unicode cChar = pBox->GetEntry(i)[0];
                if ( cChar == cBracket )
                const sal_Unicode cChar = pBox->get_text(i)[0];
                if (cChar == cBracket)
                {
                    pBox->SelectEntryPos(i);
                    pBox->select(i);
                    nEntryPos = i;
                    bFound = true;
                    break;
@@ -3218,37 +3205,35 @@ void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
            }
        }

        if ( !bFound )
        if (!bFound)
        {
            nEntryPos = pBox->InsertEntry( OUString(cBracket) );
            pBox->SelectEntryPos( nEntryPos );
            pBox->append_text(OUString(cBracket));
            nEntryPos = pBox->n_children() - 1;
            pBox->select(nEntryPos);
        }
    }
    if( bStart )
    if (bStart)
        m_nStartBracketPosition = nEntryPos;
    else
        m_nEndBracketPosition = nEntryPos;
}


IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, Button*, void)
IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, weld::ToggleButton&, void)
{
    bool bChecked = m_pTwoLinesBtn->IsChecked();
    m_pEnclosingFrame->Enable( bChecked );

    bool bChecked = m_xTwoLinesBtn->get_active();
    m_xEnclosingFrame->set_sensitive(bChecked);
    UpdatePreview_Impl();
}


IMPL_LINK( SvxCharTwoLinesPage, CharacterMapHdl_Impl, ListBox&, rBox, void )
IMPL_LINK(SvxCharTwoLinesPage, CharacterMapHdl_Impl, weld::TreeView&, rBox, void)
{
    sal_Int32 nPos = rBox.GetSelectedEntryPos();
    if ( CHRDLG_ENCLOSE_SPECIAL_CHAR == reinterpret_cast<sal_uLong>(rBox.GetEntryData( nPos )) )
    int nPos = rBox.get_selected_index();
    if (rBox.get_id(nPos).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR)
        SelectCharacter( &rBox );
    else
    {
        bool bStart = &rBox == m_pStartBracketLB;
        if( bStart )
        bool bStart = &rBox == m_xStartBracketLB.get();
        if (bStart)
            m_nStartBracketPosition = nPos;
        else
            m_nEndBracketPosition = nPos;
@@ -3256,13 +3241,11 @@ IMPL_LINK( SvxCharTwoLinesPage, CharacterMapHdl_Impl, ListBox&, rBox, void )
    UpdatePreview_Impl();
}


void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet& rSet )
{
    SvxCharBasePage::ActivatePage( rSet );
    CharBasePage::ActivatePage(rSet);
}


DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
{
    if ( _pSet )
@@ -3270,22 +3253,21 @@ DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
    return DeactivateRC::LeavePage;
}


VclPtr<SfxTabPage> SvxCharTwoLinesPage::Create( TabPageParent pParent, const SfxItemSet* rSet )
VclPtr<SfxTabPage> SvxCharTwoLinesPage::Create(TabPageParent pParent, const SfxItemSet* rSet)
{
    return VclPtr<SvxCharTwoLinesPage>::Create( pParent.pParent, *rSet );
    return VclPtr<SvxCharTwoLinesPage>::Create(pParent, *rSet);
}

void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
{
    m_pTwoLinesBtn->Check( false );
    m_xTwoLinesBtn->set_active(false);
    sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
    SfxItemState eState = rSet->GetItemState( nWhich );

    if ( eState >= SfxItemState::DONTCARE )
    {
        const SvxTwoLinesItem& rItem = static_cast<const SvxTwoLinesItem&>(rSet->Get( nWhich ));
        m_pTwoLinesBtn->Check( rItem.GetValue() );
        m_xTwoLinesBtn->set_active(rItem.GetValue());

        if ( rItem.GetValue() )
        {
@@ -3293,7 +3275,7 @@ void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
            SetBracket( rItem.GetEndBracket(), false );
        }
    }
    TwoLinesHdl_Impl( nullptr );
    TwoLinesHdl_Impl(*m_xTwoLinesBtn);

    SetPrevFontWidthScale( *rSet );
}
@@ -3304,11 +3286,11 @@ bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )
    bool bModified = false, bChanged = true;
    sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
    const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_TWO_LINES );
    bool bOn = m_pTwoLinesBtn->IsChecked();
    sal_Unicode cStart = ( bOn && m_pStartBracketLB->GetSelectedEntryPos() > 0 )
        ? m_pStartBracketLB->GetSelectedEntry()[0] : 0;
    sal_Unicode cEnd = ( bOn && m_pEndBracketLB->GetSelectedEntryPos() > 0 )
        ? m_pEndBracketLB->GetSelectedEntry()[0] : 0;
    bool bOn = m_xTwoLinesBtn->get_active();
    sal_Unicode cStart = ( bOn && m_xStartBracketLB->get_selected_index() > 0 )
        ? m_xStartBracketLB->get_selected_text()[0] : 0;
    sal_Unicode cEnd = ( bOn && m_xEndBracketLB->get_selected_index() > 0 )
        ? m_xEndBracketLB->get_selected_text()[0] : 0;

    if ( pOld )
    {
@@ -3331,13 +3313,13 @@ bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )

void    SvxCharTwoLinesPage::UpdatePreview_Impl()
{
    sal_Unicode cStart = m_pStartBracketLB->GetSelectedEntryPos() > 0
        ? m_pStartBracketLB->GetSelectedEntry()[0] : 0;
    sal_Unicode cEnd = m_pEndBracketLB->GetSelectedEntryPos() > 0
        ? m_pEndBracketLB->GetSelectedEntry()[0] : 0;
    m_pPreviewWin->SetBrackets(cStart, cEnd);
    m_pPreviewWin->SetTwoLines(m_pTwoLinesBtn->IsChecked());
    m_pPreviewWin->Invalidate();
    sal_Unicode cStart = m_xStartBracketLB->get_selected_index() > 0
        ? m_xStartBracketLB->get_selected_text()[0] : 0;
    sal_Unicode cEnd = m_xEndBracketLB->get_selected_index() > 0
        ? m_xEndBracketLB->get_selected_text()[0] : 0;
    m_aPreviewWin.SetBrackets(cStart, cEnd);
    m_aPreviewWin.SetTwoLines(m_xTwoLinesBtn->get_active());
    m_aPreviewWin.Invalidate();
}

void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet& aSet)
diff --git a/cui/uiconfig/ui/twolinespage.ui b/cui/uiconfig/ui/twolinespage.ui
index e3a5fac..e5cb2f9 100644
--- a/cui/uiconfig/ui/twolinespage.ui
+++ b/cui/uiconfig/ui/twolinespage.ui
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <!-- interface-requires gtk+ 3.0 -->
  <!-- interface-requires LibreOffice 1.0 -->
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name gint1 -->
      <column type="gint"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
@@ -38,10 +38,10 @@
  </object>
  <object class="GtkListStore" id="liststore2">
    <columns>
      <!-- column-name gchararray1 -->
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name gint1 -->
      <column type="gint"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
@@ -145,8 +145,6 @@
                  <packing>
                    <property name="left_attach">0</property>
                    <property name="top_attach">0</property>
                    <property name="width">1</property>
                    <property name="height">1</property>
                  </packing>
                </child>
                <child>
@@ -158,42 +156,84 @@
                  <packing>
                    <property name="left_attach">1</property>
                    <property name="top_attach">0</property>
                    <property name="width">1</property>
                    <property name="height">1</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkTreeView" id="startbracket:border">
                  <object class="GtkScrolledWindow">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="model">liststore1</property>
                    <property name="search_column">0</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection5"/>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="shadow_type">in</property>
                    <child>
                      <object class="GtkTreeView" id="startbracket">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="model">liststore1</property>
                        <property name="headers_visible">False</property>
                        <property name="headers_clickable">False</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>
                        <child>
                          <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                            <child>
                              <object class="GtkCellRendererText" id="cellrenderertext1"/>
                              <attributes>
                                <attribute name="text">0</attribute>
                              </attributes>
                            </child>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">0</property>
                    <property name="top_attach">1</property>
                    <property name="width">1</property>
                    <property name="height">1</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkTreeView" id="endbracket:border">
                   <object class="GtkScrolledWindow">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="model">liststore2</property>
                    <property name="search_column">0</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection6"/>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="shadow_type">in</property>
                    <child>
                      <object class="GtkTreeView" id="endbracket">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="model">liststore2</property>
                        <property name="headers_visible">False</property>
                        <property name="headers_clickable">False</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection2"/>
                        </child>
                        <child>
                          <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                            <child>
                              <object class="GtkCellRendererText" id="cellrenderertext2"/>
                              <attributes>
                                <attribute name="text">0</attribute>
                              </attributes>
                            </child>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">1</property>
                    <property name="top_attach">1</property>
                    <property name="width">1</property>
                    <property name="height">1</property>
                  </packing>
                </child>
              </object>
@@ -226,12 +266,27 @@
        <property name="left_padding">12</property>
        <property name="right_padding">12</property>
        <child>
          <object class="svxlo-SvxFontPrevWindow" id="preview:border">
          <object class="GtkScrolledWindow">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child internal-child="accessible">
              <object class="AtkObject" id="preview:border-atkobject">
                <property name="AtkObject::accessible-name" translatable="yes" context="twolinespage|preview-atkobject">Preview</property>
            <property name="can_focus">True</property>
            <property name="hscrollbar_policy">never</property>
            <property name="vscrollbar_policy">never</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkViewport">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkDrawingArea" id="preview">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child internal-child="accessible">
                      <object class="AtkObject" id="preview-atkobject">
                        <property name="AtkObject::accessible-name" translatable="yes" context="twolinespage|preview-atkobject">Preview</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx
index 0c1ea3b..ed62d61 100644
--- a/include/vcl/builder.hxx
+++ b/include/vcl/builder.hxx
@@ -217,7 +217,7 @@ private:
    };

    const ListStore* get_model_by_name(const OString& sID) const;
    static void     mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId);
    void     mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId);

    typedef stringmap TextBuffer;
    const TextBuffer* get_buffer_by_name(const OString& sID) const;
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 677bd64..4f070fc 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -3682,8 +3682,16 @@ void VclBuilder::mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt1
        sal_uInt16 nEntry = rTarget.InsertEntry(rRow[0]);
        if (rRow.size() > 1)
        {
            sal_IntPtr nValue = rRow[1].toInt32();
            rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
            if (m_bLegacy)
            {
                sal_IntPtr nValue = rRow[1].toInt32();
                rTarget.SetEntryData(nEntry, reinterpret_cast<void*>(nValue));
            }
            else
            {
                if (!rRow[1].isEmpty())
                    rTarget.SetEntryData(nEntry, new OUString(rRow[1]));
            }
        }
    }
    if (nActiveId < rStore.m_aEntries.size())