diff options
-rw-r--r-- | include/vcl/svlbitm.hxx | 3 | ||||
-rw-r--r-- | include/vcl/weld.hxx | 15 | ||||
-rw-r--r-- | sw/source/ui/index/cnttab.cxx | 340 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/assignstylesdialog.ui | 251 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 75 | ||||
-rw-r--r-- | vcl/source/treelist/svlbitm.cxx | 15 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 21 |
7 files changed, 478 insertions, 242 deletions
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 { |