[Libreoffice-commits] core.git: include/vcl sw/source sw/uiconfig vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Dec 12 12:01:53 UTC 2018


 include/vcl/svlbitm.hxx                      |    3 
 include/vcl/weld.hxx                         |   15 +
 sw/source/ui/index/cnttab.cxx                |  340 +++++++++++----------------
 sw/uiconfig/swriter/ui/assignstylesdialog.ui |  251 ++++++++++++++++++-
 vcl/source/app/salvtables.cxx                |   75 +++--
 vcl/source/treelist/svlbitm.cxx              |   15 -
 vcl/unx/gtk3/gtk3gtkinst.cxx                 |   21 +
 7 files changed, 478 insertions(+), 242 deletions(-)

New commits:
commit 6236051a3496278fe2768b40ebf1f4e82a44bb44
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Dec 10 11:32:51 2018 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Dec 12 13:01:28 2018 +0100

    weld SwAddStylesDlg
    
    Change-Id: I1dfdf0cea69585991bc0fa8dc38ebdf78abe97bf
    Reviewed-on: https://gerrit.libreoffice.org/64976
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/svlbitm.hxx b/include/vcl/svlbitm.hxx
index 854c4666d50e..cd8001614195 100644
--- a/include/vcl/svlbitm.hxx
+++ b/include/vcl/svlbitm.hxx
@@ -84,10 +84,11 @@ public:
     // as buttons are not derived from LinkHdl
     void                    CallLink();
 
-    void                    StoreButtonState( SvTreeListEntry* pEntry );
+    void                    StoreButtonState(SvTreeListEntry* pActEntry, SvLBoxButton* pActBox);
     static SvButtonState    ConvertToButtonState( SvItemStateFlags nItemFlags );
 
     SvTreeListEntry*        GetActEntry() const;
+    SvLBoxButton*           GetActBox() const;
 
     void                    SetImage(SvBmp nIndex, const Image& aImage) { aBmps[static_cast<int>(nIndex)] = aImage; }
     Image&                  GetImage(SvBmp nIndex) { return aBmps[static_cast<int>(nIndex)]; }
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 028419f117ab..7edfba8b7496 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -403,12 +403,20 @@ class VCL_DLLPUBLIC TreeView : virtual public Container
 protected:
     Link<TreeView&, void> m_aChangeHdl;
     Link<TreeView&, void> m_aRowActivatedHdl;
+    Link<const std::pair<int, int>&, void> m_aRadioToggleHdl;
     // if handler returns false, the expansion of the row is refused
     Link<TreeIter&, bool> m_aExpandingHdl;
 
+    std::vector<int> m_aRadioIndexes;
+
     void signal_changed() { m_aChangeHdl.Call(*this); }
     void signal_row_activated() { m_aRowActivatedHdl.Call(*this); }
     bool signal_expanding(TreeIter& rIter) { return m_aExpandingHdl.Call(rIter); }
+    // arg is pair<row,col>
+    void signal_radio_toggled(const std::pair<int, int>& rRowCol)
+    {
+        m_aRadioToggleHdl.Call(rRowCol);
+    }
 
 public:
     virtual void insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
@@ -451,6 +459,10 @@ public:
 
     void connect_changed(const Link<TreeView&, void>& rLink) { m_aChangeHdl = rLink; }
     void connect_row_activated(const Link<TreeView&, void>& rLink) { m_aRowActivatedHdl = rLink; }
+    void connect_radio_toggled(const Link<const std::pair<int, int>&, void>& rLink)
+    {
+        m_aRadioToggleHdl = rLink;
+    }
 
     //by index
     virtual int get_selected_index() const = 0;
@@ -531,9 +543,12 @@ public:
 
     virtual void set_column_fixed_widths(const std::vector<int>& rWidths) = 0;
     virtual OUString get_column_title(int nColumn) const = 0;
+    virtual void set_column_title(int nColumn, const OUString& rTitle) = 0;
 
     virtual void set_selection_mode(SelectionMode eMode) = 0;
     virtual int count_selected_rows() const = 0;
+
+    void set_toggle_columns_as_radio(const std::vector<int>& rCols) { m_aRadioIndexes = rCols; }
 };
 
 class VCL_DLLPUBLIC Button : virtual public Container
diff --git a/sw/source/ui/index/cnttab.cxx b/sw/source/ui/index/cnttab.cxx
index 6dac9f18b8c6..279dddd0b5bc 100644
--- a/sw/source/ui/index/cnttab.cxx
+++ b/sw/source/ui/index/cnttab.cxx
@@ -512,249 +512,213 @@ bool SwMultiTOXTabDialog::IsNoNum(SwWrtShell& rSh, const OUString& rName)
         ! rSh.GetTextCollFromPool(nId)->IsAssignedToListLevelOfOutlineStyle();
 }
 
-class SwIndexTreeLB : public SvSimpleTable
+class SwAddStylesDlg_Impl : public SfxDialogController
 {
-public:
-    explicit SwIndexTreeLB(SvSimpleTableContainer& rParent);
-    virtual void KeyInput( const KeyEvent& rKEvt ) override;
-    virtual void Resize() override;
-    virtual sal_IntPtr GetTabPos( SvTreeListEntry*, SvLBoxTab* ) override;
-    void setColSizes();
-};
-
-SwIndexTreeLB::SwIndexTreeLB(SvSimpleTableContainer& rParent)
-    : SvSimpleTable(rParent, 0)
-{
-    HeaderBar& rStylesHB = GetTheHeaderBar();
-    rStylesHB.SetStyle(rStylesHB.GetStyle()|WB_BUTTONSTYLE);
-    SetStyle(GetStyle() & ~(WB_AUTOHSCROLL|WB_HSCROLL));
-}
-
-sal_IntPtr SwIndexTreeLB::GetTabPos( SvTreeListEntry* pEntry, SvLBoxTab* pTab)
-{
-    sal_IntPtr nData = reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
-    if(nData != USHRT_MAX)
-    {
-        HeaderBar& rStylesHB = GetTheHeaderBar();
-        sal_IntPtr  nPos = rStylesHB.GetItemRect( static_cast< sal_uInt16 >(2 + nData) ).TopLeft().X();
-        nData = nPos;
-    }
-    else
-        nData = 0;
-    nData += pTab->GetPos();
-    return nData;
-}
-
-void SwIndexTreeLB::KeyInput( const KeyEvent& rKEvt )
-{
-    SvTreeListEntry* pEntry = FirstSelected();
-    vcl::KeyCode aCode = rKEvt.GetKeyCode();
-    bool bChanged = false;
-    if(pEntry)
-    {
-        sal_IntPtr nLevel = reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
-        if(aCode.GetCode() == KEY_ADD )
-        {
-            if(nLevel < MAXLEVEL - 1)
-                nLevel++;
-            else if(nLevel == USHRT_MAX)
-                nLevel = 0;
-            bChanged = true;
-        }
-        else if(aCode.GetCode() == KEY_SUBTRACT)
-        {
-            if(!nLevel)
-                nLevel = USHRT_MAX;
-            else if(nLevel != USHRT_MAX)
-                nLevel--;
-            bChanged = true;
-        }
-        if(bChanged)
-        {
-            pEntry->SetUserData(reinterpret_cast<void*>(nLevel));
-            Invalidate();
-        }
-    }
-    if(!bChanged)
-        SvTreeListBox::KeyInput(rKEvt);
-}
-
-void SwIndexTreeLB::Resize()
-{
-    SvSimpleTable::Resize();
-    setColSizes();
-}
-
-void SwIndexTreeLB::setColSizes()
-{
-    HeaderBar &rHB = GetTheHeaderBar();
-    if (rHB.GetItemCount() < MAXLEVEL+1)
-        return;
-
-    long nWidth = rHB.GetSizePixel().Width();
-    nWidth /= 14;
-    nWidth--;
-
-    long nTabs[MAXLEVEL+1];
-    nTabs[0] = 3 * nWidth;
-    for(sal_uInt16 i = 1; i <= MAXLEVEL; ++i)
-        nTabs[i] = nTabs[i-1] + nWidth;
-    SvSimpleTable::SetTabs(SAL_N_ELEMENTS(nTabs), nTabs, MapUnit::MapPixel);
-}
-
-class SwAddStylesDlg_Impl : public SfxModalDialog
-{
-    VclPtr<OKButton>       m_pOk;
-
-    VclPtr<SwIndexTreeLB>  m_pHeaderTree;
-    VclPtr<PushButton>     m_pLeftPB;
-    VclPtr<PushButton>     m_pRightPB;
-
     OUString*       pStyleArr;
 
-    DECL_LINK(OkHdl, Button*, void);
-    DECL_LINK(LeftRightHdl, Button*, void);
-    DECL_LINK(HeaderDragHdl, HeaderBar*, void);
+    std::unique_ptr<weld::Button> m_xOk;
+    std::unique_ptr<weld::Button> m_xLeftPB;
+    std::unique_ptr<weld::Button> m_xRightPB;
+    std::unique_ptr<weld::TreeView> m_xHeaderTree;
+
+    DECL_LINK(OkHdl, weld::Button&, void);
+    DECL_LINK(LeftRightHdl, weld::Button&, void);
+    DECL_LINK(KeyInput, const KeyEvent&, bool);
+    DECL_LINK(TreeSizeAllocHdl, const Size&, void);
+    typedef std::pair<int, int> row_col;
+    DECL_LINK(RadioToggleOnHdl, const row_col&, void);
 
 public:
-    SwAddStylesDlg_Impl(vcl::Window* pParent, SwWrtShell const & rWrtSh, OUString rStringArr[]);
-    virtual ~SwAddStylesDlg_Impl() override;
-    virtual void dispose() override;
+    SwAddStylesDlg_Impl(weld::Window* pParent, SwWrtShell const & rWrtSh, OUString rStringArr[]);
 };
 
-SwAddStylesDlg_Impl::SwAddStylesDlg_Impl(vcl::Window* pParent,
+SwAddStylesDlg_Impl::SwAddStylesDlg_Impl(weld::Window* pParent,
             SwWrtShell const & rWrtSh, OUString rStringArr[])
-    : SfxModalDialog(pParent, "AssignStylesDialog",
-        "modules/swriter/ui/assignstylesdialog.ui")
+    : SfxDialogController(pParent, "modules/swriter/ui/assignstylesdialog.ui", "AssignStylesDialog")
     , pStyleArr(rStringArr)
-{
-    get(m_pOk, "ok");
-    get(m_pLeftPB, "left");
-    get(m_pRightPB, "right");
-    OUString sHBFirst = get<FixedText>("notapplied")->GetText();
-    SvSimpleTableContainer *pHeaderTreeContainer = get<SvSimpleTableContainer>("styles");
-    Size aSize = pHeaderTreeContainer->LogicToPixel(Size(273, 164), MapMode(MapUnit::MapAppFont));
-    pHeaderTreeContainer->set_width_request(aSize.Width());
-    pHeaderTreeContainer->set_height_request(aSize.Height());
-    m_pHeaderTree = VclPtr<SwIndexTreeLB>::Create(*pHeaderTreeContainer);
-
-    m_pOk->SetClickHdl(LINK(this, SwAddStylesDlg_Impl, OkHdl));
-    m_pLeftPB->SetClickHdl(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
-    m_pRightPB->SetClickHdl(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
-
-    HeaderBar& rHB = m_pHeaderTree->GetTheHeaderBar();
-    rHB.SetEndDragHdl(LINK(this, SwAddStylesDlg_Impl, HeaderDragHdl));
-
-    for(sal_uInt16 i = 1; i <= MAXLEVEL; ++i)
-        sHBFirst += "\t" + OUString::number(i);
-    m_pHeaderTree->InsertHeaderEntry(sHBFirst);
-    m_pHeaderTree->setColSizes();
-
-    m_pHeaderTree->SetStyle(m_pHeaderTree->GetStyle()|WB_CLIPCHILDREN|WB_SORT);
-    m_pHeaderTree->GetModel()->SetSortMode(SortAscending);
+    , m_xOk(m_xBuilder->weld_button("ok"))
+    , m_xLeftPB(m_xBuilder->weld_button("left"))
+    , m_xRightPB(m_xBuilder->weld_button("right"))
+    , m_xHeaderTree(m_xBuilder->weld_tree_view("styles"))
+{
+    m_xOk->connect_clicked(LINK(this, SwAddStylesDlg_Impl, OkHdl));
+    m_xLeftPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
+    m_xRightPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
+    m_xHeaderTree->connect_size_allocate(LINK(this, SwAddStylesDlg_Impl, TreeSizeAllocHdl));
+
+    std::vector<int> aRadioColumns;
+    for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+        aRadioColumns.push_back(i + 1);
+    m_xHeaderTree->set_toggle_columns_as_radio(aRadioColumns);
+    m_xHeaderTree->connect_radio_toggled(LINK(this, SwAddStylesDlg_Impl, RadioToggleOnHdl));
+
+    std::vector<int> aWidths;
+    aWidths.push_back(m_xHeaderTree->get_approximate_digit_width() * 30);
+    int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
+    OUString sTitle(m_xHeaderTree->get_column_title(1));
+    for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+    {
+        sTitle = OUString::number(i);
+        m_xHeaderTree->set_column_title(i + 1, sTitle);
+        aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
+    }
+    m_xHeaderTree->set_column_fixed_widths(aWidths);
+    auto nWidth = std::accumulate(aWidths.begin(), aWidths.end(), 0);
+    m_xHeaderTree->set_size_request(nWidth, m_xHeaderTree->get_height_rows(15));
+
+    int nRow(0);
     for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
     {
         const OUString &rStyles{rStringArr[i]};
         if (rStyles.isEmpty())
             continue;
-        sal_Int32 nPos {0};
-        do {
-            SvTreeListEntry* pEntry = m_pHeaderTree->InsertEntry(rStyles.getToken(0, TOX_STYLE_DELIMITER, nPos));
-            pEntry->SetUserData(reinterpret_cast<void*>(i));
+        sal_Int32 nPos(0);
+        do
+        {
+            OUString sEntry = rStyles.getToken(0, TOX_STYLE_DELIMITER, nPos);
+            m_xHeaderTree->append_text(sEntry);
+            for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+                m_xHeaderTree->set_toggle(nRow, i == j - 1, j + 1);
+            ++nRow;
         } while (nPos>=0);
     }
     // now the other styles
 
-    const SwTextFormatColl *pColl   = nullptr;
     const sal_uInt16 nSz = rWrtSh.GetTextFormatCollCount();
-
-    for ( sal_uInt16 j = 0;j < nSz; ++j )
+    for (sal_uInt16 j = 0; j < nSz; ++j)
     {
-        pColl = &rWrtSh.GetTextFormatColl(j);
-        if(pColl->IsDefault())
+        const SwTextFormatColl& rColl = rWrtSh.GetTextFormatColl(j);
+        if (rColl.IsDefault())
             continue;
 
-        const OUString aName = pColl->GetName();
+        const OUString aName = rColl.GetName();
         if (!aName.isEmpty())
         {
-            SvTreeListEntry* pEntry = m_pHeaderTree->First();
-            while (pEntry && SvTabListBox::GetEntryText(pEntry, 0) != aName)
+            bool bEntry = false;
+            int nChildren = m_xHeaderTree->n_children();
+            for (int i = 0; i < nChildren; ++i)
             {
-                pEntry = m_pHeaderTree->Next(pEntry);
+                if (m_xHeaderTree->get_text(i, 0) == aName)
+                {
+                    bEntry = true;
+                    break;
+                }
             }
-            if (!pEntry)
+            if (!bEntry)
             {
-                m_pHeaderTree->InsertEntry(aName)->SetUserData(reinterpret_cast<void*>(USHRT_MAX));
+                m_xHeaderTree->append_text(aName);
+                for (sal_uInt16 k = 0; k <= MAXLEVEL; ++k)
+                    m_xHeaderTree->set_toggle(nRow, k == 0, k + 1);
+                ++nRow;
             }
         }
     }
-    m_pHeaderTree->GetModel()->Resort();
+    m_xHeaderTree->make_sorted();
+    m_xHeaderTree->select(0);
+    m_xHeaderTree->connect_key_release(LINK(this, SwAddStylesDlg_Impl, KeyInput));
 }
 
-SwAddStylesDlg_Impl::~SwAddStylesDlg_Impl()
+IMPL_LINK(SwAddStylesDlg_Impl, TreeSizeAllocHdl, const Size&, rSize, void)
 {
-    disposeOnce();
+    auto nWidth = rSize.Width();
+
+    std::vector<int> aWidths;
+    aWidths.push_back(0);
+    int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
+    for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+    {
+        OUString sTitle(m_xHeaderTree->get_column_title(i + 1));
+        aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
+    }
+    auto nOtherWidth = std::accumulate(aWidths.begin(), aWidths.end(), 0);
+    aWidths[0] = nWidth - nOtherWidth;
+    m_xHeaderTree->set_column_fixed_widths(aWidths);
 }
 
-void SwAddStylesDlg_Impl::dispose()
+IMPL_LINK(SwAddStylesDlg_Impl, RadioToggleOnHdl, const row_col&, rRowCol, void)
 {
-    m_pHeaderTree.disposeAndClear();
-    m_pOk.clear();
-    m_pLeftPB.clear();
-    m_pRightPB.clear();
-    SfxModalDialog::dispose();
+    for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+        m_xHeaderTree->set_toggle(rRowCol.first, rRowCol.second == i + 1, i + 1);
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, KeyInput, const KeyEvent&, rKEvt, bool)
+{
+    vcl::KeyCode aCode = rKEvt.GetKeyCode();
+    bool bHandled = false;
+
+    if (aCode.GetCode() == KEY_ADD || aCode.GetCode() == KEY_RIGHT)
+    {
+        LeftRightHdl(*m_xRightPB);
+        bHandled = true;
+    }
+    else if (aCode.GetCode() == KEY_SUBTRACT || aCode.GetCode() == KEY_LEFT)
+    {
+        LeftRightHdl(*m_xLeftPB);
+        bHandled = true;
+    }
+
+    return bHandled;
 }
 
-IMPL_LINK_NOARG(SwAddStylesDlg_Impl, OkHdl, Button*, void)
+IMPL_LINK_NOARG(SwAddStylesDlg_Impl, OkHdl, weld::Button&, void)
 {
     for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
         pStyleArr[i].clear();
 
-    SvTreeListEntry* pEntry = m_pHeaderTree->First();
-    while(pEntry)
+    int nChildren = m_xHeaderTree->n_children();
+    for (int i = 0; i < nChildren; ++i)
     {
-        sal_IntPtr nLevel = reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
-        if(nLevel != USHRT_MAX)
+        int nToggleColumn = 0;
+        for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+        {
+            if (m_xHeaderTree->get_toggle(i, j + 1))
+            {
+                nToggleColumn = j;
+                break;
+            }
+        }
+        if (nToggleColumn)
         {
+            int nLevel = nToggleColumn - 1;
             if(!pStyleArr[nLevel].isEmpty())
                 pStyleArr[nLevel] += OUStringLiteral1(TOX_STYLE_DELIMITER);
-            pStyleArr[nLevel] += SvTabListBox::GetEntryText(pEntry, 0);
+            pStyleArr[nLevel] += m_xHeaderTree->get_text(i, 0);
         }
-        pEntry = m_pHeaderTree->Next(pEntry);
     }
 
     //TODO write back style names
-    EndDialog(RET_OK);
+    m_xDialog->response(RET_OK);
 }
 
-IMPL_LINK_NOARG(SwAddStylesDlg_Impl, HeaderDragHdl, HeaderBar*, void)
+IMPL_LINK(SwAddStylesDlg_Impl, LeftRightHdl, weld::Button&, rBtn, void)
 {
-    m_pHeaderTree->Invalidate();
-}
-
-IMPL_LINK(SwAddStylesDlg_Impl, LeftRightHdl, Button*, pBtn, void)
-{
-    bool bLeft = pBtn == m_pLeftPB;
-    SvTreeListEntry* pEntry = m_pHeaderTree->FirstSelected();
-    if(pEntry)
+    bool bLeft = &rBtn == m_xLeftPB.get();
+    int nEntry = m_xHeaderTree->get_selected_index();
+    if (nEntry != -1)
     {
-        sal_IntPtr nLevel = reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
-        if(bLeft)
+        int nToggleColumn = 0;
+        for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
         {
-            if(!nLevel)
-                nLevel = USHRT_MAX;
-            else if(nLevel != USHRT_MAX)
-                nLevel--;
+            if (m_xHeaderTree->get_toggle(nEntry, j + 1))
+            {
+                nToggleColumn = j;
+                break;
+            }
+        }
+
+        if (bLeft)
+        {
+            if (nToggleColumn)
+                --nToggleColumn;
         }
         else
         {
-            if(nLevel < MAXLEVEL - 1)
-                nLevel++;
-            else if(nLevel == USHRT_MAX)
-                nLevel = 0;
+            if (nToggleColumn < MAXLEVEL)
+                ++nToggleColumn;
         }
-        pEntry->SetUserData(reinterpret_cast<void*>(nLevel));
-        m_pHeaderTree->Invalidate();
+
+        for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+            m_xHeaderTree->set_toggle(nEntry, j == nToggleColumn, j + 1);
     }
 }
 
@@ -1448,13 +1412,11 @@ void SwTOXSelectTabPage::LanguageHdl( ListBox const * pBox )
         ModifyHdl(*m_pTitleED);
 };
 
-IMPL_LINK(SwTOXSelectTabPage, AddStylesHdl, Button*, pButton, void)
+IMPL_LINK_NOARG(SwTOXSelectTabPage, AddStylesHdl, Button*, void)
 {
-    ScopedVclPtrInstance<SwAddStylesDlg_Impl> pDlg(
-        pButton, static_cast<SwMultiTOXTabDialog*>(GetTabDialog())->GetWrtShell(),
+    SwAddStylesDlg_Impl aDlg(GetFrameWeld(), static_cast<SwMultiTOXTabDialog*>(GetTabDialog())->GetWrtShell(),
         aStyleArr);
-    pDlg->Execute();
-    pDlg.disposeAndClear();
+    aDlg.run();
     ModifyHdl(*m_pTitleED);
 }
 
diff --git a/sw/uiconfig/swriter/ui/assignstylesdialog.ui b/sw/uiconfig/swriter/ui/assignstylesdialog.ui
index affe6ae33059..8d70a26af686 100644
--- a/sw/uiconfig/swriter/ui/assignstylesdialog.ui
+++ b/sw/uiconfig/swriter/ui/assignstylesdialog.ui
@@ -2,21 +2,51 @@
 <!-- Generated with glade 3.22.1 -->
 <interface domain="sw">
   <requires lib="gtk+" version="3.18"/>
-  <requires lib="LibreOffice" version="1.0"/>
   <object class="GtkImage" id="image1">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="pixbuf">sw/res/all_left.png</property>
+    <property name="icon_name">sw/res/all_left.png</property>
   </object>
   <object class="GtkImage" id="image2">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="pixbuf">sw/res/all_right.png</property>
+    <property name="icon_name">sw/res/all_right.png</property>
+  </object>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name check -->
+      <column type="gboolean"/>
+      <!-- column-name check2 -->
+      <column type="gboolean"/>
+      <!-- column-name check3 -->
+      <column type="gboolean"/>
+      <!-- column-name check4 -->
+      <column type="gboolean"/>
+      <!-- column-name check5 -->
+      <column type="gboolean"/>
+      <!-- column-name check6 -->
+      <column type="gboolean"/>
+      <!-- column-name check7 -->
+      <column type="gboolean"/>
+      <!-- column-name check8 -->
+      <column type="gboolean"/>
+      <!-- column-name check9 -->
+      <column type="gboolean"/>
+      <!-- column-name check10 -->
+      <column type="gboolean"/>
+      <!-- column-name check11 -->
+      <column type="gboolean"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
   </object>
   <object class="GtkDialog" id="AssignStylesDialog">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes" context="assignstylesdialog|AssignStylesDialog">Assign Styles</property>
+    <property name="modal">True</property>
     <property name="type_hint">dialog</property>
     <child>
       <placeholder/>
@@ -103,6 +133,8 @@
                   <object class="GtkGrid" id="grid1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
                     <property name="row_spacing">6</property>
                     <child>
                       <object class="GtkGrid" id="grid2">
@@ -162,33 +194,214 @@
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">2</property>
+                        <property name="top_attach">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="svtlo-SvSimpleTableContainer" id="styles">
+                      <object class="GtkScrolledWindow">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="hexpand">True</property>
                         <property name="vexpand">True</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection" id="Simple Table Container-selection3"/>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="styles">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="vexpand">True</property>
+                            <property name="model">liststore1</property>
+                            <property name="search_column">0</property>
+                            <property name="show_expanders">False</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="title" translatable="yes" context="assignstylesdialog|stylecolumn">Style</property>
+                                <property name="sort_indicator">True</property>
+                                <property name="sort_column_id">0</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="cellrenderer1"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer2">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">1</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer3">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">2</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer4">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">3</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer5">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">4</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn6">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer6">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">5</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer7">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">6</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn8">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer8">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">7</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn9">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer9">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">8</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn10">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer10">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">9</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn11">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer11">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">10</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="treeviewcolumn12">
+                                <property name="resizable">True</property>
+                                <property name="spacing">6</property>
+                                <property name="alignment">0.5</property>
+                                <child>
+                                  <object class="GtkCellRendererToggle" id="cellrenderer12">
+                                    <property name="radio">True</property>
+                                  </object>
+                                  <attributes>
+                                    <attribute name="active">11</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
                         </child>
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="notapplied">
-                        <property name="can_focus">False</property>
-                        <property name="no_show_all">True</property>
-                        <property name="label" translatable="yes" context="assignstylesdialog|notapplied">Not applied</property>
-                        <property name="xalign">0</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
                         <property name="top_attach">0</property>
                       </packing>
                     </child>
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d4a2c3464171..3dad05c40df9 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1825,17 +1825,19 @@ private:
     std::vector<std::unique_ptr<OUString>> m_aUserData;
     VclPtr<SvTabListBox> m_xTreeView;
     SvLBoxButtonData m_aCheckButtonData;
+    SvLBoxButtonData m_aRadioButtonData;
 
     DECL_LINK(SelectHdl, SvTreeListBox*, void);
     DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
     DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);
     DECL_LINK(EndDragHdl, HeaderBar*, void);
-
+    DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
 public:
     SalInstanceTreeView(SvTabListBox* pTreeView, bool bTakeOwnership)
         : SalInstanceContainer(pTreeView, bTakeOwnership)
         , m_xTreeView(pTreeView)
-        , m_aCheckButtonData(pTreeView)
+        , m_aCheckButtonData(pTreeView, false)
+        , m_aRadioButtonData(pTreeView, true)
     {
         m_xTreeView->SetNodeDefaultImages();
         m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
@@ -1850,6 +1852,7 @@ public:
             pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE);
             pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
         }
+        m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
     }
 
     virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override
@@ -1879,6 +1882,15 @@ public:
         return OUString();
     }
 
+    virtual void set_column_title(int nColumn, const OUString& rTitle) override
+    {
+        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
+        {
+            return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
+        }
+    }
+
     virtual void show() override
     {
         SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
@@ -1915,40 +1927,32 @@ public:
         else
             pUserData = nullptr;
 
-        bool bSimple = !pIconName && !pImageSurface && pStr;
-        SvTreeListEntry* pResult;
-        if (bSimple)
-            pResult = m_xTreeView->InsertEntry(*pStr, iter, false, nInsertPos, pUserData);
+        SvTreeListEntry* pEntry = new SvTreeListEntry;
+        if (pIconName || pImageSurface)
+        {
+            Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
+            pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
+        }
         else
         {
-            SvTreeListEntry* pEntry = new SvTreeListEntry;
-            if (pIconName || pImageSurface)
-            {
-                Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
-                pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
-            }
-            else
-            {
-                Image aDummy;
-                pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
-            }
-            if (pStr)
-                pEntry->AddItem(o3tl::make_unique<SvLBoxString>(*pStr));
-            pEntry->SetUserData(pUserData);
-            m_xTreeView->Insert(pEntry, iter, nInsertPos);
-            pResult = pEntry;
+            Image aDummy;
+            pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
         }
+        if (pStr)
+            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(*pStr));
+        pEntry->SetUserData(pUserData);
+        m_xTreeView->Insert(pEntry, iter, nInsertPos);
 
         if (pExpanderName)
         {
             Image aImage(createImage(*pExpanderName));
-            m_xTreeView->SetExpandedEntryBmp(pResult, aImage);
-            m_xTreeView->SetCollapsedEntryBmp(pResult, aImage);
+            m_xTreeView->SetExpandedEntryBmp(pEntry, aImage);
+            m_xTreeView->SetCollapsedEntryBmp(pEntry, aImage);
         }
 
         if (bChildrenOnDemand)
         {
-            m_xTreeView->InsertEntry("<dummy>", pResult, false, 0, nullptr);
+            m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
         }
     }
 
@@ -2138,6 +2142,7 @@ public:
             return;
         }
 
+        bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
         ++col; //skip dummy/expander column
 
         // blank out missing entries
@@ -2147,7 +2152,7 @@ public:
         if (static_cast<size_t>(col) == pEntry->ItemCount())
         {
             pEntry->AddItem(o3tl::make_unique<SvLBoxButton>(SvLBoxButtonKind::EnabledCheckbox,
-                                                            &m_aCheckButtonData));
+                                                            bRadio ? &m_aRadioButtonData : &m_aCheckButtonData));
             SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
             m_xTreeView->InitViewData(pViewData, pEntry);
         }
@@ -2403,6 +2408,24 @@ public:
     }
 };
 
+IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void)
+{
+    SvTreeListEntry* pEntry = pData->GetActEntry();
+    SvLBoxButton* pBox = pData->GetActBox();
+
+    for (int i = 1, nCount = pEntry->ItemCount(); i < nCount; ++i)
+    {
+        SvLBoxItem& rItem = pEntry->GetItem(i);
+        if (&rItem == pBox)
+        {
+            int nRow = m_xTreeView->GetAbsPos(pEntry);
+            int nCol = i - 1; // less dummy/expander column
+            signal_radio_toggled(std::make_pair(nRow, nCol));
+            break;
+        }
+    }
+}
+
 IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, SvTreeListBox*, void)
 {
     if (notify_events_disabled())
diff --git a/vcl/source/treelist/svlbitm.cxx b/vcl/source/treelist/svlbitm.cxx
index 530113c18177..7f45fdfa89b3 100644
--- a/vcl/source/treelist/svlbitm.cxx
+++ b/vcl/source/treelist/svlbitm.cxx
@@ -29,10 +29,11 @@
 struct SvLBoxButtonData_Impl
 {
     SvTreeListEntry*    pEntry;
+    SvLBoxButton*       pBox;
     bool                bDefaultImages;
     bool                bShowRadioButton;
 
-    SvLBoxButtonData_Impl() : pEntry( nullptr ), bDefaultImages( false ), bShowRadioButton( false ) {}
+    SvLBoxButtonData_Impl() : pEntry(nullptr), pBox(nullptr), bDefaultImages(false), bShowRadioButton(false) {}
 };
 
 void SvLBoxButtonData::InitData( bool _bRadioBtn, const Control* pCtrl )
@@ -97,10 +98,10 @@ void SvLBoxButtonData::SetWidthAndHeight()
     bDataOk = true;
 }
 
-
-void SvLBoxButtonData::StoreButtonState( SvTreeListEntry* pActEntry )
+void SvLBoxButtonData::StoreButtonState(SvTreeListEntry* pActEntry, SvLBoxButton* pActBox)
 {
     pImpl->pEntry = pActEntry;
+    pImpl->pBox = pActBox;
 }
 
 SvButtonState SvLBoxButtonData::ConvertToButtonState( SvItemStateFlags nItemFlags )
@@ -127,6 +128,12 @@ SvTreeListEntry* SvLBoxButtonData::GetActEntry() const
     return pImpl->pEntry;
 }
 
+SvLBoxButton* SvLBoxButtonData::GetActBox() const
+{
+    assert(pImpl && "-SvLBoxButtonData::GetActBox(): don't use me that way!");
+    return pImpl->pBox;
+}
+
 void SvLBoxButtonData::SetDefaultImages( const Control* pCtrl )
 {
     const AllSettings& rSettings = pCtrl? pCtrl->GetSettings() : Application::GetSettings();
@@ -256,7 +263,7 @@ void SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry )
             SetStateUnchecked();
         else
             SetStateChecked();
-        pData->StoreButtonState( pEntry );
+        pData->StoreButtonState(pEntry, this);
         pData->CallLink();
     }
 }
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d48b1883d820..ca4c8e989511 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -4899,7 +4899,7 @@ private:
         pThis->signal_toggled(path, reinterpret_cast<sal_IntPtr>(pData));
     }
 
-    void signal_toggled(const gchar *path, int nIndex)
+    void signal_toggled(const gchar *path, int nCol)
     {
         GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
 
@@ -4908,9 +4908,15 @@ private:
         gtk_tree_model_get_iter(pModel, &iter, tree_path);
 
         gboolean bRet(false);
-        gtk_tree_model_get(pModel, &iter, nIndex, &bRet, -1);
+        gtk_tree_model_get(pModel, &iter, nCol, &bRet, -1);
         bRet = !bRet;
-        gtk_tree_store_set(m_pTreeStore, &iter, nIndex, bRet, -1);
+        gtk_tree_store_set(m_pTreeStore, &iter, nCol, bRet, -1);
+
+        if (std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), nCol) != m_aRadioIndexes.end())
+        {
+            int nRow = gtk_tree_path_get_indices(tree_path)[0];
+            signal_radio_toggled(std::make_pair(nRow, nCol));
+        }
 
         gtk_tree_path_free(tree_path);
     }
@@ -4988,6 +4994,15 @@ public:
         return sRet;
     }
 
+    virtual void set_column_title(int nColumn, const OUString& rTitle) override
+    {
+        GList *pColumns = gtk_tree_view_get_columns(m_pTreeView);
+        GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(g_list_nth_data(pColumns, nColumn));
+        assert(pColumn && "wrong count");
+        gtk_tree_view_column_set_title(pColumn, OUStringToOString(rTitle, RTL_TEXTENCODING_UTF8).getStr());
+        g_list_free(pColumns);
+    }
+
     virtual void insert(weld::TreeIter* pParent, int pos, const OUString* pText, const OUString* pId, const OUString* pIconName,
                         VirtualDevice* pImageSurface, const OUString* pExpanderName, bool bChildrenOnDemand) override
     {


More information about the Libreoffice-commits mailing list