include/svx/strings.hrc | 1 svx/UIConfig_svx.mk | 1 svx/inc/formnavi.hrc | 53 ++ svx/source/form/filtnav.cxx | 6 svx/source/form/fmexch.cxx | 106 +--- svx/source/form/fmexpl.cxx | 93 +-- svx/source/form/fmshimp.cxx | 16 svx/source/form/navigatortree.cxx | 901 +++++++++++++++++--------------------- svx/source/inc/filtnav.hxx | 2 svx/source/inc/fmexch.hxx | 33 - svx/source/inc/fmexpl.hxx | 101 ++-- svx/source/inc/fmshimp.hxx | 12 svx/uiconfig/ui/formnavigator.ui | 78 +++ svx/uiconfig/ui/formnavimenu.ui | 26 - 14 files changed, 708 insertions(+), 721 deletions(-)
New commits: commit 82cb3eb7389b4ff9b3254f8370379cf6fd81322f Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Tue Jun 23 11:51:32 2020 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Jun 25 20:26:38 2020 +0200 weld NavigatorTree Change-Id: I019021fa5a522b1238d74702c9222afdfd7540c3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96961 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc index 114cbd17bd6e..93f3b016f6df 100644 --- a/include/svx/strings.hrc +++ b/include/svx/strings.hrc @@ -1132,6 +1132,7 @@ #define RID_STR_PROPERTIES_FORM NC_("RID_STR_PROPERTIES_FORM", "Form Properties") #define RID_STR_FMEXPLORER NC_("RID_STR_FMEXPLORER", "Form Navigator") #define RID_STR_FORM NC_("RID_STR_FORM", "Form") +#define RID_STR_HIDDEN NC_("RID_STR_HIDDEN", "Hidden") #define RID_STR_STDFORMNAME NC_("RID_STR_STDFORMNAME", "Form") #define RID_STR_PROPTITLE_HIDDEN NC_("RID_STR_PROPTITLE_HIDDEN", "Hidden Control") #define RID_STR_CONTROL NC_("RID_STR_CONTROL", "Control") diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk index f7f02ad2f126..0658ede63727 100644 --- a/svx/UIConfig_svx.mk +++ b/svx/UIConfig_svx.mk @@ -70,6 +70,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\ svx/uiconfig/ui/formdatamenu \ svx/uiconfig/ui/formfielddialog \ svx/uiconfig/ui/formlinkwarndialog \ + svx/uiconfig/ui/formnavigator \ svx/uiconfig/ui/formnavimenu \ svx/uiconfig/ui/formpropertydialog \ svx/uiconfig/ui/functionmenu \ diff --git a/svx/inc/formnavi.hrc b/svx/inc/formnavi.hrc new file mode 100644 index 000000000000..78271e2f05c4 --- /dev/null +++ b/svx/inc/formnavi.hrc @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SVX_INC_FRMSEL_HRC +#define INCLUDED_SVX_INC_FRMSEL_HRC + +#include <utility> + +#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String) + +const char* RID_SVXSW_CONVERTMENU[] = +{ + NC_("RID_SVXSW_CONVERTMENU|ConvertToEdit", "~Text Box"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToButton", "~Button"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToFixed", "La~bel field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToList", "L~ist Box"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToCheckBox", "~Check Box"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToRadio", "~Radio Button"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToGroup", "G~roup Box"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToCombo", "Combo Bo~x"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToImageBtn", "I~mage Button"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToFileControl", "~File Selection"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToDate", "~Date Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToTime", "Tim~e Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToNumeric", "~Numerical Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToCurrency", "C~urrency Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToPattern", "~Pattern Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToImageControl", "Ima~ge Control"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToFormatted", "Fo~rmatted Field"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToScrollBar", "Scroll bar"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToSpinButton", "Spin Button"), + NC_("RID_SVXSW_CONVERTMENU|ConvertToNavigationBar", "Navigation Bar") +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/form/filtnav.cxx b/svx/source/form/filtnav.cxx index 2b6dee83ebd8..6a5d39fcf6ae 100644 --- a/svx/source/form/filtnav.cxx +++ b/svx/source/form/filtnav.cxx @@ -1054,7 +1054,7 @@ void FmFilterString::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderCo FmFilterNavigator::FmFilterNavigator( vcl::Window* pParent ) :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT ) ,m_pEditingCurrently( nullptr ) - ,m_aControlExchange( this ) + ,m_aControlExchange() ,m_aTimerCounter( 0 ) ,m_aDropActionType( DA_SCROLLUP ) { @@ -1515,7 +1515,6 @@ void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rF m_pModel->EnsureEmptyFilterRows( *_pTargetItems->GetParent() ); } - void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ ) { EndSelection(); @@ -1528,11 +1527,10 @@ void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPi { m_aControlExchange->setDraggedEntries(aItemList); m_aControlExchange->setFormItem(pFirstItem); - m_aControlExchange.startDrag( DND_ACTION_COPYMOVE ); + m_aControlExchange.startDrag(this, DND_ACTION_COPYMOVE); } } - void FmFilterNavigator::Command( const CommandEvent& rEvt ) { bool bHandled = false; diff --git a/svx/source/form/fmexch.cxx b/svx/source/form/fmexch.cxx index c5957cef451d..8d4ddc3647f8 100644 --- a/svx/source/form/fmexch.cxx +++ b/svx/source/form/fmexch.cxx @@ -20,16 +20,11 @@ #include <fmexch.hxx> #include <sot/formats.hxx> -#include <vcl/treelistbox.hxx> -#include <vcl/treelistentry.hxx> #include <tools/debug.hxx> #include <tools/diagnose_ex.h> - namespace svxform { - - using namespace ::com::sun::star::uno; using namespace ::com::sun::star::datatransfer; @@ -39,8 +34,7 @@ namespace svxform { } - - void OLocalExchange::copyToClipboard( vcl::Window* _pWindow, const GrantAccess& ) + void OLocalExchange::copyToClipboard(const GrantAccess&) { if ( m_bClipboardOwner ) { // simulate a lostOwnership to notify parties interested in @@ -48,10 +42,9 @@ namespace svxform } m_bClipboardOwner = true; - CopyToClipboard( _pWindow ); + CopyToClipboard(GetSystemClipboard()); } - void OLocalExchange::clear() { if ( isClipboardOwner() ) @@ -70,50 +63,49 @@ namespace svxform } } - void SAL_CALL OLocalExchange::lostOwnership( const Reference< clipboard::XClipboard >& _rxClipboard, const Reference< XTransferable >& _rxTrans ) { - TransferableHelper::implCallOwnLostOwnership( _rxClipboard, _rxTrans ); + TransferDataContainer::implCallOwnLostOwnership( _rxClipboard, _rxTrans ); m_bClipboardOwner = false; m_aClipboardListener.Call( *this ); } - void OLocalExchange::startDrag( vcl::Window* _pWindow, sal_Int8 _nDragSourceActions, const GrantAccess& ) { - m_bDragging = true; + setDragging(true); StartDrag( _pWindow, _nDragSourceActions ); } + void OLocalExchange::setDragging(bool bDragging) + { + m_bDragging = bDragging; + } void OLocalExchange::DragFinished( sal_Int8 nDropAction ) { - TransferableHelper::DragFinished( nDropAction ); - m_bDragging = false; + TransferDataContainer::DragFinished( nDropAction ); + setDragging(false); } - bool OLocalExchange::hasFormat( const DataFlavorExVector& _rFormats, SotClipboardFormatId _nFormatId ) { return std::any_of(_rFormats.begin(), _rFormats.end(), [&_nFormatId](const DataFlavorEx& rFormat) { return rFormat.mnSotId == _nFormatId; }); } - bool OLocalExchange::GetData( const css::datatransfer::DataFlavor& /*_rFlavor*/, const OUString& /*rDestDoc*/ ) { return false; // do not have any formats by default } OControlTransferData::OControlTransferData( ) - :m_pFocusEntry( nullptr ) + : m_bFocusEntry(false) { } - OControlTransferData::OControlTransferData( const Reference< XTransferable >& _rxTransferable ) - :m_pFocusEntry( nullptr ) + : m_bFocusEntry(false) { TransferableDataHelper aExchangedData( _rxTransferable ); @@ -177,33 +169,34 @@ namespace svxform } } - - size_t OControlTransferData::onEntryRemoved( SvTreeListEntry* _pEntry ) + size_t OControlTransferData::onEntryRemoved(weld::TreeView* pView, weld::TreeIter* _pEntry) { - m_aSelectedEntries.erase( _pEntry ); + auto aIter = std::find_if(m_aSelectedEntries.begin(), m_aSelectedEntries.end(), + [pView, _pEntry](const auto& rElem) { + return pView->iter_compare(*rElem, *_pEntry) == 0; + }); + if (aIter != m_aSelectedEntries.end()) + m_aSelectedEntries.erase(aIter); + return m_aSelectedEntries.size(); } - - void OControlTransferData::addSelectedEntry( SvTreeListEntry* _pEntry ) + void OControlTransferData::addSelectedEntry(std::unique_ptr<weld::TreeIter> xEntry) { - m_aSelectedEntries.insert( _pEntry ); + m_aSelectedEntries.emplace(std::move(xEntry)); } - - void OControlTransferData::setFocusEntry( SvTreeListEntry* _pFocusEntry ) + void OControlTransferData::setFocusEntry(bool _bFocusEntry) { - m_pFocusEntry = _pFocusEntry; + m_bFocusEntry = _bFocusEntry; } - void OControlTransferData::addHiddenControlsFormat(const css::uno::Sequence< css::uno::Reference< css::uno::XInterface > >& seqInterfaces) { m_aHiddenControlModels = seqInterfaces; } - - void OControlTransferData::buildPathFormat(SvTreeListBox const * pTreeBox, SvTreeListEntry const * pRoot) + void OControlTransferData::buildPathFormat(const weld::TreeView* pTreeBox, const weld::TreeIter* pRoot) { m_aControlPaths.realloc(0); @@ -213,19 +206,17 @@ namespace svxform m_aControlPaths.realloc(nEntryCount); css::uno::Sequence<sal_uInt32>* pAllPaths = m_aControlPaths.getArray(); - for (SvTreeListEntry* pCurrentEntry : m_aSelectedEntries) + for (const auto& rCurrentEntry : m_aSelectedEntries) { // first we collect the path in an array ::std::vector< sal_uInt32 > aCurrentPath; - SvTreeListEntry* pLoop = pCurrentEntry; - while (pLoop != pRoot) + std::unique_ptr<weld::TreeIter> xLoop(pTreeBox->make_iterator(rCurrentEntry.get())); + while (pTreeBox->iter_compare(*xLoop, *pRoot) != 0) { - aCurrentPath.push_back(pLoop->GetChildListPos()); - pLoop = pTreeBox->GetParent(pLoop); - DBG_ASSERT((pLoop != nullptr) || (pRoot == nullptr), "OControlTransferData::buildPathFormat: invalid root or entry !"); - // pLoop == NULL means that I am at the top end, then the whole - // thing should abort, which will only be the case with pRoot == NULL + aCurrentPath.push_back(pTreeBox->get_iter_index_in_parent(*xLoop)); + bool bLoop = pTreeBox->iter_parent(*xLoop); + assert(bLoop && "OControlTransferData::buildPathFormat: invalid root or entry !"); (void)bLoop; } // then we can transfer it into css::uno::Sequence @@ -241,19 +232,17 @@ namespace svxform } } - - void OControlTransferData::buildListFromPath(SvTreeListBox const * pTreeBox, SvTreeListEntry* pRoot) + void OControlTransferData::buildListFromPath(const weld::TreeView* pTreeBox, weld::TreeIter* pRoot) { ListBoxEntrySet aEmpty; m_aSelectedEntries.swap( aEmpty ); for (const css::uno::Sequence<sal_uInt32>& rPaths : std::as_const(m_aControlPaths)) { - SvTreeListEntry* pSearch = pRoot; + std::unique_ptr<weld::TreeIter> xSearch(pTreeBox->make_iterator(pRoot)); for (const sal_uInt32 nThisPath : rPaths) - pSearch = pTreeBox->GetEntry(pSearch, nThisPath); - - m_aSelectedEntries.insert( pSearch ); + pTreeBox->iter_nth_child(*xSearch, nThisPath); + m_aSelectedEntries.emplace(std::move(xSearch)); } } @@ -261,7 +250,6 @@ namespace svxform { } - bool OControlExchange::GetData( const DataFlavor& _rFlavor, const OUString& rDestDoc ) { const SotClipboardFormatId nFormatId = SotExchange::GetFormat( _rFlavor ); @@ -287,10 +275,9 @@ namespace svxform return true; } - void OControlExchange::AddSupportedFormats() { - if (m_pFocusEntry && !m_aSelectedEntries.empty()) + if (m_bFocusEntry && !m_aSelectedEntries.empty()) AddFormat(getFieldExchangeFormatId()); if (m_aControlPaths.hasElements()) @@ -300,7 +287,6 @@ namespace svxform AddFormat(getHiddenControlModelsFormatId()); } - SotClipboardFormatId OControlExchange::getControlPathFormatId() { static SotClipboardFormatId s_nFormat = @@ -309,7 +295,6 @@ namespace svxform return s_nFormat; } - SotClipboardFormatId OControlExchange::getHiddenControlModelsFormatId() { static SotClipboardFormatId s_nFormat = @@ -327,40 +312,33 @@ namespace svxform return s_nFormat; } - //= OControlExchangeHelper - OLocalExchange* OControlExchangeHelper::createExchange() const { return new OControlExchange; } - OLocalExchangeHelper::OLocalExchangeHelper(vcl::Window* _pDragSource) - :m_pDragSource(_pDragSource) + OLocalExchangeHelper::OLocalExchangeHelper() { } - OLocalExchangeHelper::~OLocalExchangeHelper() { implReset(); } - - void OLocalExchangeHelper::startDrag( sal_Int8 nDragSourceActions ) + void OLocalExchangeHelper::startDrag(vcl::Window* pDragSource, sal_Int8 nDragSourceActions) { DBG_ASSERT(m_xTransferable.is(), "OLocalExchangeHelper::startDrag: not prepared!"); - m_xTransferable->startDrag( m_pDragSource, nDragSourceActions, OLocalExchange::GrantAccess() ); + m_xTransferable->startDrag( pDragSource, nDragSourceActions, OLocalExchange::GrantAccess() ); } - void OLocalExchangeHelper::copyToClipboard( ) const { DBG_ASSERT( m_xTransferable.is(), "OLocalExchangeHelper::copyToClipboard: not prepared!" ); - m_xTransferable->copyToClipboard( m_pDragSource, OLocalExchange::GrantAccess() ); + m_xTransferable->copyToClipboard(OLocalExchange::GrantAccess()); } - void OLocalExchangeHelper::implReset() { if (m_xTransferable.is()) @@ -370,7 +348,6 @@ namespace svxform } } - void OLocalExchangeHelper::prepareDrag( ) { DBG_ASSERT(!m_xTransferable.is() || !m_xTransferable->isDragging(), "OLocalExchangeHelper::prepareDrag: recursive DnD?"); @@ -378,9 +355,6 @@ namespace svxform implReset(); m_xTransferable = createExchange(); } - - } - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/form/fmexpl.cxx b/svx/source/form/fmexpl.cxx index 6f585dbecea5..b86e2cf7a8a1 100644 --- a/svx/source/form/fmexpl.cxx +++ b/svx/source/form/fmexpl.cxx @@ -219,7 +219,7 @@ FmFormData::FmFormData(const Reference< XForm >& _rxForm, FmFormData* _pParent) , m_xForm(_rxForm) { // set images - m_aNormalImage = Image(RID_SVXBMP_FORM); + m_aNormalImage = RID_SVXBMP_FORM; // set title if (m_xForm.is()) @@ -301,10 +301,10 @@ std::unique_ptr<FmEntryData> FmControlData::Clone() } -Image FmControlData::GetImage() const +OUString FmControlData::GetImage() const { // Default-Image - Image aImage(StockImage::Yes, RID_SVXBMP_CONTROL); + OUString aImage(RID_SVXBMP_CONTROL); Reference< XServiceInfo > xInfo( m_xFormComponent, UNO_QUERY ); if (!m_xFormComponent.is()) @@ -316,91 +316,91 @@ Image FmControlData::GetImage() const switch (nObjectType) { case OBJ_FM_BUTTON: - aImage = Image(StockImage::Yes, RID_SVXBMP_BUTTON); + aImage = RID_SVXBMP_BUTTON; break; case OBJ_FM_FIXEDTEXT: - aImage = Image(StockImage::Yes, RID_SVXBMP_FIXEDTEXT); + aImage = RID_SVXBMP_FIXEDTEXT; break; case OBJ_FM_EDIT: - aImage = Image(StockImage::Yes, RID_SVXBMP_EDITBOX); + aImage = RID_SVXBMP_EDITBOX; break; case OBJ_FM_RADIOBUTTON: - aImage = Image(StockImage::Yes, RID_SVXBMP_RADIOBUTTON); + aImage = RID_SVXBMP_RADIOBUTTON; break; case OBJ_FM_CHECKBOX: - aImage = Image(StockImage::Yes, RID_SVXBMP_CHECKBOX); + aImage = RID_SVXBMP_CHECKBOX; break; case OBJ_FM_LISTBOX: - aImage = Image(StockImage::Yes, RID_SVXBMP_LISTBOX); + aImage = RID_SVXBMP_LISTBOX; break; case OBJ_FM_COMBOBOX: - aImage = Image(StockImage::Yes, RID_SVXBMP_COMBOBOX); + aImage = RID_SVXBMP_COMBOBOX; break; case OBJ_FM_NAVIGATIONBAR: - aImage = Image(StockImage::Yes, RID_SVXBMP_NAVIGATIONBAR); + aImage = RID_SVXBMP_NAVIGATIONBAR; break; case OBJ_FM_GROUPBOX: - aImage = Image(StockImage::Yes, RID_SVXBMP_GROUPBOX); + aImage = RID_SVXBMP_GROUPBOX; break; case OBJ_FM_IMAGEBUTTON: - aImage = Image(StockImage::Yes, RID_SVXBMP_IMAGEBUTTON); + aImage = RID_SVXBMP_IMAGEBUTTON; break; case OBJ_FM_FILECONTROL: - aImage = Image(StockImage::Yes, RID_SVXBMP_FILECONTROL); + aImage = RID_SVXBMP_FILECONTROL; break; case OBJ_FM_HIDDEN: - aImage = Image(StockImage::Yes, RID_SVXBMP_HIDDEN); + aImage = RID_SVXBMP_HIDDEN; break; case OBJ_FM_DATEFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_DATEFIELD); + aImage = RID_SVXBMP_DATEFIELD; break; case OBJ_FM_TIMEFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_TIMEFIELD); + aImage = RID_SVXBMP_TIMEFIELD; break; case OBJ_FM_NUMERICFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_NUMERICFIELD); + aImage = RID_SVXBMP_NUMERICFIELD; break; case OBJ_FM_CURRENCYFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_CURRENCYFIELD); + aImage = RID_SVXBMP_CURRENCYFIELD; break; case OBJ_FM_PATTERNFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_PATTERNFIELD); + aImage = RID_SVXBMP_PATTERNFIELD; break; case OBJ_FM_IMAGECONTROL: - aImage = Image(StockImage::Yes, RID_SVXBMP_IMAGECONTROL); + aImage = RID_SVXBMP_IMAGECONTROL; break; case OBJ_FM_FORMATTEDFIELD: - aImage = Image(StockImage::Yes, RID_SVXBMP_FORMATTEDFIELD); + aImage = RID_SVXBMP_FORMATTEDFIELD; break; case OBJ_FM_GRID: - aImage = Image(StockImage::Yes, RID_SVXBMP_GRID); + aImage = RID_SVXBMP_GRID; break; case OBJ_FM_SCROLLBAR: - aImage = Image(StockImage::Yes, RID_SVXBMP_SCROLLBAR); + aImage = RID_SVXBMP_SCROLLBAR; break; case OBJ_FM_SPINBUTTON: - aImage = Image(StockImage::Yes, RID_SVXBMP_SPINBUTTON); + aImage = RID_SVXBMP_SPINBUTTON; break; } @@ -435,18 +435,16 @@ namespace svxform NavigatorFrame::NavigatorFrame( SfxBindings* _pBindings, SfxChildWindow* _pMgr, vcl::Window* _pParent ) - :SfxDockingWindow( _pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) ) - ,SfxControllerItem( SID_FM_FMEXPLORER_CONTROL, *_pBindings ) + : SfxDockingWindow(_pBindings, _pMgr, _pParent, "FormNavigator", "svx/ui/formnavigator.ui") + , SfxControllerItem( SID_FM_FMEXPLORER_CONTROL, *_pBindings ) + , m_xNavigatorTree(new NavigatorTree(m_xBuilder->weld_tree_view("treeview"))) { SetHelpId( HID_FORM_NAVIGATOR_WIN ); - m_pNavigatorTree = VclPtr<NavigatorTree>::Create( this ); - m_pNavigatorTree->Show(); SetText( SvxResId(RID_STR_FMEXPLORER) ); SfxDockingWindow::SetFloatingSize( Size(200,200) ); } - NavigatorFrame::~NavigatorFrame() { disposeOnce(); @@ -454,18 +452,16 @@ namespace svxform void NavigatorFrame::dispose() { - m_pNavigatorTree.disposeAndClear(); + m_xNavigatorTree.reset(); ::SfxControllerItem::dispose(); SfxDockingWindow::dispose(); } - void NavigatorFrame::UpdateContent( FmFormShell* pFormShell ) { - m_pNavigatorTree->UpdateContent( pFormShell ); + m_xNavigatorTree->UpdateContent(pFormShell); } - void NavigatorFrame::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState ) { if( !pState || SID_FM_FMEXPLORER_CONTROL != nSID ) @@ -480,30 +476,26 @@ namespace svxform UpdateContent( nullptr ); } - void NavigatorFrame::GetFocus() { - if ( m_pNavigatorTree ) - m_pNavigatorTree->GrabFocus(); + if (m_xNavigatorTree ) + m_xNavigatorTree->GrabFocus(); else SfxDockingWindow::GetFocus(); } - bool NavigatorFrame::Close() { UpdateContent( nullptr ); return SfxDockingWindow::Close(); } - void NavigatorFrame::FillInfo( SfxChildWinInfo& rInfo ) const { SfxDockingWindow::FillInfo( rInfo ); rInfo.bVisible = false; } - Size NavigatorFrame::CalcDockingSize( SfxChildAlignment eAlign ) { if ( ( eAlign == SfxChildAlignment::TOP ) || ( eAlign == SfxChildAlignment::BOTTOM ) ) @@ -512,7 +504,6 @@ namespace svxform return SfxDockingWindow::CalcDockingSize( eAlign ); } - SfxChildAlignment NavigatorFrame::CheckAlignment( SfxChildAlignment _eActAlign, SfxChildAlignment _eAlign ) { if ( ( _eAlign == SfxChildAlignment::LEFT ) || ( _eAlign == SfxChildAlignment::RIGHT ) || ( _eAlign == SfxChildAlignment::NOALIGNMENT ) ) @@ -520,28 +511,8 @@ namespace svxform return _eActAlign; } - - void NavigatorFrame::Resize() - { - SfxDockingWindow::Resize(); - - Size aLogOutputSize = PixelToLogic(GetOutputSizePixel(), MapMode(MapUnit::MapAppFont)); - Size aLogExplSize = aLogOutputSize; - aLogExplSize.AdjustWidth( -6 ); - aLogExplSize.AdjustHeight( -6 ); - - Point aExplPos = LogicToPixel(Point(3, 3), MapMode(MapUnit::MapAppFont)); - Size aExplSize = LogicToPixel(aLogExplSize, MapMode(MapUnit::MapAppFont)); - - m_pNavigatorTree->SetPosSizePixel( aExplPos, aExplSize ); - } - - - - SFX_IMPL_DOCKINGWINDOW( NavigatorFrameManager, SID_FM_SHOW_FMEXPLORER ) - NavigatorFrameManager::NavigatorFrameManager( vcl::Window* _pParent, sal_uInt16 _nId, SfxBindings* _pBindings, SfxChildWinInfo* _pInfo ) :SfxChildWindow( _pParent, _nId ) diff --git a/svx/source/form/fmshimp.cxx b/svx/source/form/fmshimp.cxx index 1b4c497ec65e..71bd034bcf84 100644 --- a/svx/source/form/fmshimp.cxx +++ b/svx/source/form/fmshimp.cxx @@ -47,6 +47,7 @@ #include <svx/svxdlg.hxx> #include <svx/svxids.hrc> #include <bitmaps.hlst> +#include <formnavi.hrc> #include <com/sun/star/awt/XWindow2.hpp> #include <com/sun/star/awt/XCheckBox.hpp> @@ -1009,16 +1010,13 @@ void FmXFormShell::ForceUpdateSelection_Lock() } } -std::unique_ptr<VclBuilder> FmXFormShell::GetConversionMenu_Lock() +void FmXFormShell::GetConversionMenu_Lock(weld::Menu& rNewMenu) { - std::unique_ptr<VclBuilder> pBuilder(new VclBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/convertmenu.ui", "")); - VclPtr<PopupMenu> pNewMenu(pBuilder->get_menu("menu")); for (size_t i = 0; i < SAL_N_ELEMENTS(aConvertSlots); ++i) { // the corresponding image at it - pNewMenu->SetItemImage(pNewMenu->GetItemId(aConvertSlots[i]), Image(StockImage::Yes, aImgIds[i])); + rNewMenu.append(OUString::createFromAscii(aConvertSlots[i]), SvxResId(RID_SVXSW_CONVERTMENU[i]), aImgIds[i]); } - return pBuilder; } OString FmXFormShell::SlotToIdent(sal_uInt16 nSlot) @@ -1288,13 +1286,13 @@ bool FmXFormShell::canConvertCurrentSelectionToControl_Lock(const OString& rIden return true; // all other slots: assume "yes" } -void FmXFormShell::checkControlConversionSlotsForCurrentSelection_Lock(Menu& rMenu) +void FmXFormShell::checkControlConversionSlotsForCurrentSelection_Lock(weld::Menu& rMenu) { - for (sal_uInt16 i = 0; i < rMenu.GetItemCount(); ++i) + for (int i = 0, nCount = rMenu.n_children(); i < nCount; ++i) { // the context is already of a type that corresponds to the entry -> disable - const sal_uInt16 nId = rMenu.GetItemId(i); - rMenu.EnableItem(nId, canConvertCurrentSelectionToControl_Lock(rMenu.GetItemIdent(nId))); + OString sIdent(aConvertSlots[i]); + rMenu.set_sensitive(sIdent, canConvertCurrentSelectionToControl_Lock(sIdent)); } } diff --git a/svx/source/form/navigatortree.cxx b/svx/source/form/navigatortree.cxx index e1410282fed3..77300a01b662 100644 --- a/svx/source/form/navigatortree.cxx +++ b/svx/source/form/navigatortree.cxx @@ -54,20 +54,10 @@ #include <tools/diagnose_ex.h> #include <svx/svxids.hrc> #include <bitmaps.hlst> -#include <vcl/treelistentry.hxx> #include <vcl/commandevent.hxx> namespace svxform { - - - #define DROP_ACTION_TIMER_INITIAL_TICKS 10 - // Time until scroll starts - #define DROP_ACTION_TIMER_SCROLL_TICKS 3 - // Time to scroll one line - #define DROP_ACTION_TIMER_TICK_BASE 10 - // factor for both declarations (in ms) - #define EXPLORER_SYNC_DELAY 200 // Time (in ms) until explorer synchronizes the view after select or deselect @@ -113,56 +103,67 @@ namespace svxform } } - NavigatorTree::NavigatorTree( vcl::Window* pParent ) - :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HSCROLL ) // #100258# OJ WB_HSCROLL added - ,m_aControlExchange(this) - ,m_pRootEntry(nullptr) - ,m_pEditEntry(nullptr) + NavigatorTreeDropTarget::NavigatorTreeDropTarget(NavigatorTree& rTreeView) + : DropTargetHelper(rTreeView.get_widget().get_drop_target()) + , m_rTreeView(rTreeView) + { + } + + sal_Int8 NavigatorTreeDropTarget::AcceptDrop(const AcceptDropEvent& rEvt) + { + sal_Int8 nAccept = m_rTreeView.AcceptDrop(rEvt); + + if (nAccept != DND_ACTION_NONE) + { + // to enable the autoscroll when we're close to the edges + weld::TreeView& rWidget = m_rTreeView.get_widget(); + rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true); + } + + return nAccept; + } + + sal_Int8 NavigatorTreeDropTarget::ExecuteDrop(const ExecuteDropEvent& rEvt) + { + return m_rTreeView.ExecuteDrop(rEvt); + } + + NavigatorTree::NavigatorTree(std::unique_ptr<weld::TreeView> xTreeView) + :m_xTreeView(std::move(xTreeView)) + ,m_aDropTargetHelper(*this) + ,m_aControlExchange() ,nEditEvent(nullptr) ,m_sdiState(SDI_DIRTY) - ,m_aTimerTriggered(-1,-1) - ,m_aDropActionType( DA_SCROLLUP ) ,m_nSelectLock(0) ,m_nFormsSelected(0) ,m_nControlsSelected(0) ,m_nHiddenControls(0) - ,m_aTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS ) ,m_bDragDataDirty(false) ,m_bPrevSelectionMixed(false) ,m_bRootSelected(false) ,m_bInitialUpdate(true) ,m_bKeyboardCut( false ) + ,m_bEditing( false ) { - SetHelpId( HID_FORM_NAVIGATOR ); - - SetNodeBitmaps( - Image(StockImage::Yes, RID_SVXBMP_COLLAPSEDNODE), - Image(StockImage::Yes, RID_SVXBMP_EXPANDEDNODE) - ); + m_xTreeView->set_help_id(HID_FORM_NAVIGATOR); - SetDragDropMode(DragDropMode::ALL); - EnableInplaceEditing( true ); - SetSelectionMode(SelectionMode::Multiple); + m_xTreeView->set_selection_mode(SelectionMode::Multiple); m_pNavModel.reset(new NavigatorTreeModel()); Clear(); StartListening( *m_pNavModel ); - m_aDropActionTimer.SetInvokeHandler(LINK(this, NavigatorTree, OnDropActionTimer)); - m_aSynchronizeTimer.SetInvokeHandler(LINK(this, NavigatorTree, OnSynchronizeTimer)); - SetSelectHdl(LINK(this, NavigatorTree, OnEntrySelDesel)); - SetDeselectHdl(LINK(this, NavigatorTree, OnEntrySelDesel)); + m_xTreeView->connect_changed(LINK(this, NavigatorTree, OnEntrySelDesel)); + m_xTreeView->connect_key_press(LINK(this, NavigatorTree, KeyInputHdl)); + m_xTreeView->connect_popup_menu(LINK(this, NavigatorTree, PopupMenuHdl)); + m_xTreeView->connect_editing(LINK(this, NavigatorTree, EditingEntryHdl), + LINK(this, NavigatorTree, EditedEntryHdl)); + m_xTreeView->connect_drag_begin(LINK(this, NavigatorTree, DragBeginHdl)); } - NavigatorTree::~NavigatorTree() - { - disposeOnce(); - } - - void NavigatorTree::dispose() { if( nEditEvent ) Application::RemoveUserEvent( nEditEvent ); @@ -174,16 +175,13 @@ namespace svxform EndListening( *m_pNavModel ); Clear(); m_pNavModel.reset(); - SvTreeListBox::dispose(); } - void NavigatorTree::Clear() { m_pNavModel->Clear(); } - void NavigatorTree::UpdateContent( FmFormShell* pFormShell ) { if (m_bInitialUpdate) @@ -200,29 +198,36 @@ namespace svxform { // new shell during editing if (IsEditingActive()) - CancelTextEditing(); + { + m_xTreeView->end_editing(); + m_bEditing = false; + } m_bDragDataDirty = true; // as a precaution, although I don't drag } GetNavModel()->UpdateContent( pFormShell ); // if there is a form, expand root - if (m_pRootEntry && !IsExpanded(m_pRootEntry)) - Expand(m_pRootEntry); + if (m_xRootEntry && !m_xTreeView->get_row_expanded(*m_xRootEntry)) + m_xTreeView->expand_row(*m_xRootEntry); // if there is EXACTLY ONE form, expand it too - if (m_pRootEntry) + if (m_xRootEntry) { - SvTreeListEntry* pFirst = FirstChild(m_pRootEntry); - if (pFirst && !pFirst->NextSibling()) - Expand(pFirst); + std::unique_ptr<weld::TreeIter> xFirst(m_xTreeView->make_iterator(m_xRootEntry.get())); + bool bFirst = m_xTreeView->iter_children(*xFirst); + if (bFirst) + { + std::unique_ptr<weld::TreeIter> xSibling(m_xTreeView->make_iterator(xFirst.get())); + if (!m_xTreeView->iter_next_sibling(*xSibling)) + m_xTreeView->expand_row(*xFirst); + } } } - bool NavigatorTree::implAllowExchange( sal_Int8 _nAction, bool* _pHasNonHidden ) { - SvTreeListEntry* pCurEntry = GetCurEntry(); - if (!pCurEntry) + bool bCurEntry = m_xTreeView->get_cursor(nullptr); + if (!bCurEntry) return false; // Information for AcceptDrop and Execute Drop @@ -234,8 +239,8 @@ namespace svxform // check whether there are only hidden controls // I may add a format to pCtrlExch bool bHasNonHidden = std::any_of(m_arrCurrentSelection.begin(), m_arrCurrentSelection.end(), - [](const SvTreeListEntry* pEntry) { - FmEntryData* pCurrent = static_cast< FmEntryData* >( pEntry->GetUserData() ); + [this](const auto& rEntry) { + FmEntryData* pCurrent = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rEntry).toInt64()); return !IsHiddenControl( pCurrent ); }); @@ -249,23 +254,20 @@ namespace svxform return true; } - bool NavigatorTree::implPrepareExchange( sal_Int8 _nAction ) { - EndSelection(); - bool bHasNonHidden = false; if ( !implAllowExchange( _nAction, &bHasNonHidden ) ) return false; m_aControlExchange.prepareDrag(); - m_aControlExchange->setFocusEntry( GetCurEntry() ); + m_aControlExchange->setFocusEntry(m_xTreeView->get_cursor(nullptr)); for (const auto& rpEntry : m_arrCurrentSelection) - m_aControlExchange->addSelectedEntry(rpEntry); + m_aControlExchange->addSelectedEntry(m_xTreeView->make_iterator(rpEntry.get())); m_aControlExchange->setFormsRoot( GetNavModel()->GetFormPage()->GetForms() ); - m_aControlExchange->buildPathFormat( this, m_pRootEntry ); + m_aControlExchange->buildPathFormat(m_xTreeView.get(), m_xRootEntry.get()); if (!bHasNonHidden) { @@ -274,7 +276,7 @@ namespace svxform Reference< XInterface >* pArray = seqIFaces.getArray(); for (const auto& rpEntry : m_arrCurrentSelection) { - *pArray = static_cast< FmEntryData* >( rpEntry->GetUserData() )->GetElement(); + *pArray = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rpEntry).toInt64())->GetElement(); ++pArray; } // and the new format @@ -285,21 +287,22 @@ namespace svxform return true; } - - void NavigatorTree::StartDrag( sal_Int8 /*nAction*/, const ::Point& /*rPosPixel*/ ) + IMPL_LINK(NavigatorTree, DragBeginHdl, bool&, rUnsetDragIcon, bool) { - EndSelection(); + rUnsetDragIcon = false; - if ( !implPrepareExchange( DND_ACTION_COPYMOVE ) ) - // nothing to do or something went wrong - return; - - // collected all possible formats for current situation, we can start now - m_aControlExchange.startDrag( DND_ACTION_COPYMOVE ); + bool bSuccess = implPrepareExchange(DND_ACTION_COPYMOVE); + if (bSuccess) + { + OControlExchange& rExchange = *m_aControlExchange; + rtl::Reference<TransferDataContainer> xHelper(&rExchange); + m_xTreeView->enable_drag_source(xHelper, DND_ACTION_COPYMOVE); + rExchange.setDragging(true); + } + return !bSuccess; } - - void NavigatorTree::Command( const CommandEvent& rEvt ) + IMPL_LINK(NavigatorTree, PopupMenuHdl, const CommandEvent&, rEvt, bool) { bool bHandled = false; switch( rEvt.GetCommand() ) @@ -311,14 +314,14 @@ namespace svxform if (rEvt.IsMouseEvent()) { ptWhere = rEvt.GetMousePosPixel(); - SvTreeListEntry* ptClickedOn = GetEntry(ptWhere); - if (ptClickedOn == nullptr) + std::unique_ptr<weld::TreeIter> xClickedOn(m_xTreeView->make_iterator()); + if (!m_xTreeView->get_dest_row_at_pos(ptWhere, xClickedOn.get(), false)) break; - if ( !IsSelected(ptClickedOn) ) + if (!m_xTreeView->is_selected(*xClickedOn)) { - SelectAll(false); - Select(ptClickedOn); - SetCurEntry(ptClickedOn); + m_xTreeView->unselect_all(); + m_xTreeView->select(*xClickedOn); + m_xTreeView->set_cursor(*xClickedOn); } } else @@ -326,10 +329,10 @@ namespace svxform if (m_arrCurrentSelection.empty()) // only happens with context menu via keyboard break; - SvTreeListEntry* pCurrent = GetCurEntry(); - if (!pCurrent) + std::unique_ptr<weld::TreeIter> xCurrent(m_xTreeView->make_iterator()); + if (!m_xTreeView->get_cursor(xCurrent.get())) break; - ptWhere = GetEntryPosition(pCurrent); + ptWhere = m_xTreeView->get_row_area(*xCurrent).Center(); } // update my selection data @@ -338,8 +341,9 @@ namespace svxform // if there is at least one no-root-entry and the root selected, I deselect root if ( (m_arrCurrentSelection.size() > 1) && m_bRootSelected ) { - Select( m_pRootEntry, false ); - SetCursor( *m_arrCurrentSelection.begin(), true); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + m_xTreeView->set_cursor(*rIter); + m_xTreeView->unselect(*m_xRootEntry); } bool bSingleSelection = (m_arrCurrentSelection.size() == 1); @@ -354,94 +358,100 @@ namespace svxform FmFormModel* pFormModel = pFormShell ? pFormShell->GetFormModel() : nullptr; if( pFormShell && pFormModel ) { - VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/formnavimenu.ui", ""); - VclPtr<PopupMenu> aContextMenu(aBuilder.get_menu("menu")); - const sal_uInt16 nNewId = aContextMenu->GetItemId("new"); - PopupMenu* pSubMenuNew = aContextMenu->GetPopupMenu(nNewId); + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "svx/ui/formnavimenu.ui")); + std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu")); + std::unique_ptr<weld::Menu> xSubMenuNew(xBuilder->weld_menu("submenu")); // menu 'New' only exists, if only the root or only one form is selected - aContextMenu->EnableItem(nNewId, bSingleSelection && (m_nFormsSelected || m_bRootSelected)); + bool bShowNew = bSingleSelection && (m_nFormsSelected || m_bRootSelected); + if (!bShowNew) + xContextMenu->remove("new"); // 'New'\'Form' under the same terms - const sal_uInt16 nFormId = pSubMenuNew->GetItemId("form"); - pSubMenuNew->EnableItem(nFormId, bSingleSelection && (m_nFormsSelected || m_bRootSelected)); - pSubMenuNew->SetItemImage(nFormId, Image(StockImage::Yes, RID_SVXBMP_FORM)); + bool bShowForm = bSingleSelection && (m_nFormsSelected || m_bRootSelected); + if (bShowForm) + xSubMenuNew->append("form", SvxResId(RID_STR_FORM), RID_SVXBMP_FORM); // 'New'\'hidden...', if exactly one form is selected - const sal_uInt16 nHiddenId = pSubMenuNew->GetItemId("hidden"); - pSubMenuNew->EnableItem(nHiddenId, bSingleSelection && m_nFormsSelected); - pSubMenuNew->SetItemImage(nHiddenId, Image(StockImage::Yes, RID_SVXBMP_HIDDEN)); + bool bShowHidden = bSingleSelection && m_nFormsSelected; + if (bShowHidden) + xSubMenuNew->append("hidden", SvxResId(RID_STR_HIDDEN), RID_SVXBMP_HIDDEN); // 'Delete': everything which is not root can be removed - aContextMenu->EnableItem(aContextMenu->GetItemId("delete"), !m_bRootSelected); + if (m_bRootSelected) + xContextMenu->remove("delete"); // 'Cut', 'Copy' and 'Paste' - aContextMenu->EnableItem(aContextMenu->GetItemId("cut"), !m_bRootSelected && implAllowExchange(DND_ACTION_MOVE)); - aContextMenu->EnableItem(aContextMenu->GetItemId("copy"), !m_bRootSelected && implAllowExchange(DND_ACTION_COPY)); - aContextMenu->EnableItem(aContextMenu->GetItemId("paste"), implAcceptPaste()); + bool bShowCut = !m_bRootSelected && implAllowExchange(DND_ACTION_MOVE); + if (!bShowCut) + xContextMenu->remove("cut"); + bool bShowCopy = !m_bRootSelected && implAllowExchange(DND_ACTION_COPY); + if (!bShowCopy) + xContextMenu->remove("copy"); + if (!implAcceptPaste()) + xContextMenu->remove("paste"); // TabDialog, if exactly one form - aContextMenu->EnableItem(aContextMenu->GetItemId("taborder"), bSingleSelection && m_nFormsSelected); + bool bShowTabOrder = bSingleSelection && m_nFormsSelected; + if (!bShowTabOrder) + xContextMenu->remove("taborder"); - const sal_uInt16 nBrowserId = aContextMenu->GetItemId("props"); + bool bShowProps = true; // in XML forms, we don't allow for the properties of a form // #i36484# if (pFormShell->GetImpl()->isEnhancedForm_Lock() && !m_nControlsSelected) - aContextMenu->RemoveItem(aContextMenu->GetItemPos(nBrowserId)); - + bShowProps = false; // if the property browser is already open, we don't allow for the properties, too if (pFormShell->GetImpl()->IsPropBrwOpen_Lock()) - aContextMenu->RemoveItem(aContextMenu->GetItemPos(nBrowserId)); + bShowProps = false; + // and finally, if there's a mixed selection of forms and controls, disable the entry, too - else - aContextMenu->EnableItem(nBrowserId, - (m_nControlsSelected && !m_nFormsSelected) || (!m_nControlsSelected && m_nFormsSelected) ); + if (bShowProps && !pFormShell->GetImpl()->IsPropBrwOpen_Lock()) + bShowProps = + (m_nControlsSelected && !m_nFormsSelected) || (!m_nControlsSelected && m_nFormsSelected); + + if (!bShowProps) + xContextMenu->remove("props"); // rename, if one element and no root - aContextMenu->EnableItem(aContextMenu->GetItemId("rename"), bSingleSelection && !m_bRootSelected); + bool bShowRename = bSingleSelection && !m_bRootSelected; + if (!bShowRename) + xContextMenu->remove("rename"); - // Readonly-entry is only for root - aContextMenu->EnableItem(aContextMenu->GetItemId("designmode"), m_bRootSelected); - // the same for automatic control focus - aContextMenu->EnableItem(aContextMenu->GetItemId("controlfocus"), m_bRootSelected); + if (!m_bRootSelected) + { + // Readonly-entry is only for root + xContextMenu->remove("designmode"); + // the same for automatic control focus + xContextMenu->remove("controlfocus"); + } - std::unique_ptr<VclBuilder> xBuilder; - VclPtr<PopupMenu> xConversionMenu; + std::unique_ptr<weld::Menu> xConversionMenu(xBuilder->weld_menu("changemenu")); // ConvertTo-Slots are enabled, if one control is selected // the corresponding slot is disabled - const sal_Int16 nChangeId = aContextMenu->GetItemId("change"); if (!m_bRootSelected && !m_nFormsSelected && (m_nControlsSelected == 1)) { - xBuilder = FmXFormShell::GetConversionMenu_Lock(); - xConversionMenu = xBuilder->get_menu("menu"); - aContextMenu->SetPopupMenu(nChangeId, xConversionMenu); + FmXFormShell::GetConversionMenu_Lock(*xConversionMenu); #if OSL_DEBUG_LEVEL > 0 - FmControlData* pCurrent = static_cast<FmControlData*>((*m_arrCurrentSelection.begin())->GetUserData()); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + FmControlData* pCurrent = reinterpret_cast<FmControlData*>(m_xTreeView->get_id(*rIter).toInt64()); OSL_ENSURE( pFormShell->GetImpl()->isSolelySelected_Lock( pCurrent->GetFormComponent() ), "NavigatorTree::Command: inconsistency between the navigator selection, and the selection as the shell knows it!" ); #endif - pFormShell->GetImpl()->checkControlConversionSlotsForCurrentSelection_Lock(*aContextMenu->GetPopupMenu(nChangeId)); + pFormShell->GetImpl()->checkControlConversionSlotsForCurrentSelection_Lock(*xConversionMenu); } else - aContextMenu->EnableItem(nChangeId, false ); + xContextMenu->remove("change"); - // remove all disabled entries - aContextMenu->RemoveDisabledEntries(true, true); - - // set OpenReadOnly - - aContextMenu->CheckItem("designmode", pFormModel->GetOpenInDesignMode()); - aContextMenu->CheckItem("controlfocus", pFormModel->GetAutoControlFocus()); + if (m_bRootSelected) + { + // set OpenReadOnly + xContextMenu->set_active("designmode", pFormModel->GetOpenInDesignMode()); + xContextMenu->set_active("controlfocus", pFormModel->GetAutoControlFocus()); + } - aContextMenu->Execute(this, ptWhere); - OString sIdent; - if (xConversionMenu) - sIdent = xConversionMenu->GetCurItemIdent(); - if (sIdent.isEmpty()) - sIdent = pSubMenuNew->GetCurItemIdent(); - if (sIdent.isEmpty()) - sIdent = aContextMenu->GetCurItemIdent(); + OString sIdent = xContextMenu->popup_at_rect(m_xTreeView.get(), tools::Rectangle(ptWhere, ::Size(1, 1))); if (sIdent == "form") { OUString aStr(SvxResId(RID_STR_FORM)); @@ -450,7 +460,8 @@ namespace svxform pFormModel->BegUndo(aUndoStr); // slot was only available, if there is only one selected entry, // which is a root or a form - NewForm( *m_arrCurrentSelection.begin() ); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + NewForm(*rIter); pFormModel->EndUndo(); } else if (sIdent == "hidden") @@ -460,7 +471,8 @@ namespace svxform pFormModel->BegUndo(aUndoStr); // slot was valid for (exactly) one selected form - NewControl( FM_COMPONENT_HIDDEN, *m_arrCurrentSelection.begin(), true ); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + NewControl(FM_COMPONENT_HIDDEN, *rIter, true); pFormModel->EndUndo(); } else if (sIdent == "cut") @@ -474,10 +486,10 @@ namespace svxform else if (sIdent == "taborder") { // this slot was effective for exactly one selected form - SvTreeListEntry* pSelectedForm = *m_arrCurrentSelection.begin(); - DBG_ASSERT( IsFormEntry(pSelectedForm), "NavigatorTree::Command: This entry must be a FormEntry." ); + const std::unique_ptr<weld::TreeIter>& rSelectedForm = *m_arrCurrentSelection.begin(); + DBG_ASSERT( IsFormEntry(*rSelectedForm), "NavigatorTree::Command: This entry must be a FormEntry." ); - FmFormData* pFormData = static_cast<FmFormData*>(pSelectedForm->GetUserData()); + FmFormData* pFormData = reinterpret_cast<FmFormData*>(m_xTreeView->get_id(*rSelectedForm).toInt64()); const Reference< XForm >& xForm( pFormData->GetFormIface()); Reference< XTabControllerModel > xTabController(xForm, UNO_QUERY); @@ -490,7 +502,9 @@ namespace svxform else if (sIdent == "rename") { // only allowed for one no-root-entry - EditEntry( *m_arrCurrentSelection.begin() ); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + m_xTreeView->start_editing(*rIter); + m_bEditing = true; } else if (sIdent == "designmode") { @@ -504,7 +518,8 @@ namespace svxform } else if (FmXFormShell::isControlConversionSlot(sIdent)) { - FmControlData* pCurrent = static_cast<FmControlData*>((*m_arrCurrentSelection.begin())->GetUserData()); + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); + FmControlData* pCurrent = reinterpret_cast<FmControlData*>(m_xTreeView->get_id(*rIter).toInt64()); if (pFormShell->GetImpl()->executeControlConversionSlot_Lock(pCurrent->GetFormComponent(), sIdent)) ShowSelectionProperties(); } @@ -515,28 +530,28 @@ namespace svxform default: break; } - if (!bHandled) - SvTreeListBox::Command( rEvt ); + return bHandled; } - - SvTreeListEntry* NavigatorTree::FindEntry( FmEntryData* pEntryData ) + std::unique_ptr<weld::TreeIter> NavigatorTree::FindEntry(FmEntryData* pEntryData) { - if( !pEntryData ) return nullptr; - SvTreeListEntry* pCurEntry = First(); - while( pCurEntry ) - { - FmEntryData* pCurEntryData = static_cast<FmEntryData*>(pCurEntry->GetUserData()); - if( pCurEntryData && pCurEntryData->IsEqualWithoutChildren(pEntryData) ) - return pCurEntry; + std::unique_ptr<weld::TreeIter> xRet; + if(!pEntryData) + return xRet; - pCurEntry = Next( pCurEntry ); - } + m_xTreeView->all_foreach([this, pEntryData, &xRet](weld::TreeIter& rEntry){ + FmEntryData* pCurEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rEntry).toInt64()); + if (pCurEntryData && pCurEntryData->IsEqualWithoutChildren(pEntryData)) + { + xRet = m_xTreeView->make_iterator(&rEntry); + return true; + } + return false; + }); - return nullptr; + return xRet; } - void NavigatorTree::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) { if( dynamic_cast<const FmNavRemovedHint*>(&rHint) ) @@ -557,29 +572,35 @@ namespace svxform else if( dynamic_cast<const FmNavModelReplacedHint*>(&rHint) ) { FmEntryData* pData = static_cast<const FmNavModelReplacedHint*>(&rHint)->GetEntryData(); - SvTreeListEntry* pEntry = FindEntry( pData ); - if (pEntry) - { // reset image - SetCollapsedEntryBmp( pEntry, pData->GetNormalImage() ); - SetExpandedEntryBmp( pEntry, pData->GetNormalImage() ); + std::unique_ptr<weld::TreeIter> xEntry = FindEntry(pData); + if (xEntry) + { + // reset image + m_xTreeView->set_image(*xEntry, pData->GetNormalImage()); } } else if( dynamic_cast<const FmNavNameChangedHint*>(&rHint) ) { const FmNavNameChangedHint* pNameChangedHint = static_cast<const FmNavNameChangedHint*>(&rHint); - SvTreeListEntry* pEntry = FindEntry( pNameChangedHint->GetEntryData() ); - SetEntryText( pEntry, pNameChangedHint->GetNewName() ); + std::unique_ptr<weld::TreeIter> xEntry = FindEntry(pNameChangedHint->GetEntryData()); + m_xTreeView->set_text(*xEntry, pNameChangedHint->GetNewName()); } else if( dynamic_cast<const FmNavClearedHint*>(&rHint) ) { - SvTreeListBox::Clear(); + m_aCutEntries.clear(); + if (m_aControlExchange.isDataExchangeActive()) + m_aControlExchange.clear(); + m_xTreeView->clear(); // default-entry "Forms" - Image aRootImage(StockImage::Yes, RID_SVXBMP_FORMS); - m_pRootEntry = InsertEntry( SvxResId(RID_STR_FORMS), aRootImage, aRootImage, - nullptr, false, 0 ); + OUString sText(SvxResId(RID_STR_FORMS)); + m_xRootEntry = m_xTreeView->make_iterator(); + m_xTreeView->insert(nullptr, -1, &sText, nullptr, nullptr, nullptr, + false, m_xRootEntry.get()); + m_xTreeView->set_image(*m_xRootEntry, RID_SVXBMP_FORMS); + m_xTreeView->set_sensitive(*m_xRootEntry, true); } else if (dynamic_cast<const FmNavRequestSelectHint*>(&rHint)) { @@ -594,29 +615,30 @@ namespace svxform } } - - SvTreeListEntry* NavigatorTree::Insert( FmEntryData* pEntryData, sal_uLong nRelPos ) + std::unique_ptr<weld::TreeIter> NavigatorTree::Insert(FmEntryData* pEntryData, int nRelPos) { - // insert current entry - SvTreeListEntry* pParentEntry = FindEntry( pEntryData->GetParent() ); - SvTreeListEntry* pNewEntry; - - if( !pParentEntry ) - pNewEntry = InsertEntry( pEntryData->GetText(), - pEntryData->GetNormalImage(), pEntryData->GetNormalImage(), - m_pRootEntry, false, nRelPos, pEntryData ); + std::unique_ptr<weld::TreeIter> xParentEntry = FindEntry( pEntryData->GetParent() ); + std::unique_ptr<weld::TreeIter> xNewEntry(m_xTreeView->make_iterator()); + OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntryData))); + if(!xParentEntry) + { + m_xTreeView->insert(m_xRootEntry.get(), nRelPos, &pEntryData->GetText(), &sId, + nullptr, nullptr, false, xNewEntry.get()); + } else - pNewEntry = InsertEntry( pEntryData->GetText(), - pEntryData->GetNormalImage(), pEntryData->GetNormalImage(), - pParentEntry, false, nRelPos, pEntryData ); + { + m_xTreeView->insert(xParentEntry.get(), nRelPos, &pEntryData->GetText(), &sId, + nullptr, nullptr, false, xNewEntry.get()); + } + m_xTreeView->set_image(*xNewEntry, pEntryData->GetNormalImage()); + m_xTreeView->set_sensitive(*xNewEntry, true); // If root-entry, expand root - if( !pParentEntry ) - Expand( m_pRootEntry ); - + if (!xParentEntry) + m_xTreeView->expand_row(*m_xRootEntry); // insert children FmEntryDataList* pChildList = pEntryData->GetChildList(); @@ -624,21 +646,20 @@ namespace svxform for( size_t i = 0; i < nChildCount; i++ ) { FmEntryData* pChildData = pChildList->at( i ); - Insert( pChildData, TREELIST_APPEND ); + Insert(pChildData, -1); } - return pNewEntry; + return xNewEntry; } - void NavigatorTree::Remove( FmEntryData* pEntryData ) { if( !pEntryData ) return; // entry for the data - SvTreeListEntry* pEntry = FindEntry( pEntryData ); - if (!pEntry) + std::unique_ptr<weld::TreeIter> xEntry = FindEntry(pEntryData); + if (!xEntry) return; // delete entry from TreeListBox @@ -650,52 +671,51 @@ namespace svxform // little problem: I remember the selected data, but if somebody deletes one of these entries, // I get inconsistent... this would be bad - Select(pEntry, false); + m_xTreeView->unselect(*xEntry); // selection can be modified during deletion, // but because I disabled SelectionHandling, I have to do it later - sal_uLong nExpectedSelectionCount = GetSelectionCount(); + auto nExpectedSelectionCount = m_xTreeView->count_selected_rows(); - GetModel()->Remove(pEntry); + ModelHasRemoved(xEntry.get()); + m_xTreeView->remove(*xEntry); - if (nExpectedSelectionCount != GetSelectionCount()) + if (nExpectedSelectionCount != m_xTreeView->count_selected_rows()) SynchronizeSelection(); // by default I treat the selection of course UnlockSelectionHandling(); } - - bool NavigatorTree::IsFormEntry( SvTreeListEntry const * pEntry ) + bool NavigatorTree::IsFormEntry(const weld::TreeIter& rEntry) { - FmEntryData* pEntryData = static_cast<FmEntryData*>(pEntry->GetUserData()); + FmEntryData* pEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rEntry).toInt64()); return !pEntryData || dynamic_cast<const FmFormData*>( pEntryData) != nullptr; } - - bool NavigatorTree::IsFormComponentEntry( SvTreeListEntry const * pEntry ) + bool NavigatorTree::IsFormComponentEntry(const weld::TreeIter& rEntry) { - FmEntryData* pEntryData = static_cast<FmEntryData*>(pEntry->GetUserData()); + FmEntryData* pEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rEntry).toInt64()); return dynamic_cast<const FmControlData*>( pEntryData) != nullptr; } - bool NavigatorTree::implAcceptPaste( ) { - SvTreeListEntry* pFirstSelected = FirstSelected(); - if ( !pFirstSelected || NextSelected( pFirstSelected ) ) + auto nSelectedEntries = m_xTreeView->count_selected_rows(); + if (nSelectedEntries != 1) // no selected entry, or at least two selected entries return false; // get the clipboard - TransferableDataHelper aClipboardContent( TransferableDataHelper::CreateFromSystemClipboard( this ) ); + TransferableDataHelper aClipboardContent(TransferableDataHelper::CreateFromClipboard(GetSystemClipboard())); sal_Int8 nAction = m_aControlExchange.isClipboardOwner() && doingKeyboardCut( ) ? DND_ACTION_MOVE : DND_ACTION_COPY; - return ( nAction == implAcceptDataTransfer( aClipboardContent.GetDataFlavorExVector(), nAction, pFirstSelected, false ) ); + std::unique_ptr<weld::TreeIter> xSelected(m_xTreeView->make_iterator()); + m_xTreeView->get_selected(xSelected.get()); + return nAction == implAcceptDataTransfer(aClipboardContent.GetDataFlavorExVector(), nAction, xSelected.get(), false); } - - sal_Int8 NavigatorTree::implAcceptDataTransfer( const DataFlavorExVector& _rFlavors, sal_Int8 _nAction, SvTreeListEntry* _pTargetEntry, bool _bDnD ) + sal_Int8 NavigatorTree::implAcceptDataTransfer( const DataFlavorExVector& _rFlavors, sal_Int8 _nAction, weld::TreeIter* _pTargetEntry, bool _bDnD ) { // no target -> no drop if (!_pTargetEntry) @@ -714,7 +734,7 @@ namespace svxform { // bHasHiddenControlsFormat means that only hidden controls are part of the data // hidden controls can be copied to a form only - if ((_pTargetEntry == m_pRootEntry) || !IsFormEntry(_pTargetEntry)) + if (m_xTreeView->iter_compare(*_pTargetEntry, *m_xRootEntry) == 0 || !IsFormEntry(*_pTargetEntry)) return DND_ACTION_NONE; return bSelfSource ? ( DND_ACTION_COPYMOVE & _nAction ) : DND_ACTION_COPY; @@ -762,16 +782,15 @@ namespace svxform // I must recreate the list of the ExchangeObjects, because the shell was changed during dragging // (there are SvLBoxEntries in it, and we lost them during change) - m_aControlExchange->buildListFromPath(this, m_pRootEntry); + m_aControlExchange->buildListFromPath(m_xTreeView.get(), m_xRootEntry.get()); m_bDragDataDirty = false; } // List of dropped entries from DragServer - const ListBoxEntrySet& aDropped = m_aControlExchange->selected(); - DBG_ASSERT(!aDropped.empty(), "NavigatorTree::implAcceptDataTransfer: no entries !"); + const ListBoxEntrySet& rDropped = m_aControlExchange->selected(); + DBG_ASSERT(!rDropped.empty(), "NavigatorTree::implAcceptDataTransfer: no entries !"); - bool bDropTargetIsComponent = IsFormComponentEntry( _pTargetEntry ); - //SvTreeListEntry* pDropTargetParent = GetParent( _pTargetEntry ); + bool bDropTargetIsComponent = IsFormComponentEntry( *_pTargetEntry ); // conditions to disallow the drop // 0) the root entry is part of the list (can't DnD the root!) @@ -784,112 +803,75 @@ namespace svxform // collect the ancestors of the drop target (speeds up 3) SvLBoxEntrySortedArray arrDropAnchestors; - SvTreeListEntry* pLoop = _pTargetEntry; - while (pLoop) + std::unique_ptr<weld::TreeIter> xLoop(m_xTreeView->make_iterator(_pTargetEntry)); + do { - arrDropAnchestors.insert(pLoop); - pLoop = GetParent(pLoop); + arrDropAnchestors.emplace(m_xTreeView->make_iterator(xLoop.get())); } + while (m_xTreeView->iter_parent(*xLoop)); - for (SvTreeListEntry* pCurrent : aDropped) + for (const auto& rCurrent : rDropped) { - SvTreeListEntry* pCurrentParent = GetParent(pCurrent); - // test for 0) - if (pCurrent == m_pRootEntry) + if (m_xTreeView->iter_compare(*rCurrent, *m_xRootEntry) == 0) return DND_ACTION_NONE; + std::unique_ptr<weld::TreeIter> xCurrentParent(m_xTreeView->make_iterator(rCurrent.get())); + m_xTreeView->iter_parent(*xCurrentParent); + // test for 1) - if ( _pTargetEntry == pCurrentParent ) + if (m_xTreeView->iter_compare(*_pTargetEntry, *xCurrentParent) == 0) return DND_ACTION_NONE; // test for 2) - if (pCurrent == _pTargetEntry) + if (m_xTreeView->iter_compare(*rCurrent, *_pTargetEntry) == 0) return DND_ACTION_NONE; // test for 5) - // if ( bDropTargetIsComponent && (pDropTargetParent != pCurrentParent) ) - if ( bDropTargetIsComponent ) // TODO : the line above can be inserted, if ExecuteDrop can handle inversion + if (bDropTargetIsComponent) return DND_ACTION_NONE; // test for 3) - if ( IsFormEntry(pCurrent) ) + if (IsFormEntry(*rCurrent)) { - if ( arrDropAnchestors.find(pCurrent) != arrDropAnchestors.end() ) + auto aIter = std::find_if(arrDropAnchestors.begin(), arrDropAnchestors.end(), + [this, &rCurrent](const auto& rElem) { + return m_xTreeView->iter_compare(*rElem, *rCurrent) == 0; + }); + + if ( aIter != arrDropAnchestors.end() ) return DND_ACTION_NONE; - } else if ( IsFormComponentEntry(pCurrent) ) + } + else if (IsFormComponentEntry(*rCurrent)) { // test for 4) - if (_pTargetEntry == m_pRootEntry) + if (m_xTreeView->iter_compare(*_pTargetEntry, *m_xRootEntry) == 0) return DND_ACTION_NONE; } } - return DND_ACTION_MOVE; } - sal_Int8 NavigatorTree::AcceptDrop( const AcceptDropEvent& rEvt ) { ::Point aDropPos = rEvt.maPosPixel; - - // first handle possible DropActions (Scroll and swing open) - if (rEvt.mbLeaving) - { - if (m_aDropActionTimer.IsActive()) - m_aDropActionTimer.Stop(); - } else - { - bool bNeedTrigger = false; - // on the first entry ? - if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight())) - { - m_aDropActionType = DA_SCROLLUP; - bNeedTrigger = true; - } else - // on the last one (respectively the area, an entry would tale, if it flush with the bottom ? - if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight())) - { - m_aDropActionType = DA_SCROLLDOWN; - bNeedTrigger = true; - } else - { // on an entry with children, not swang open - SvTreeListEntry* pDroppedOn = GetEntry(aDropPos); - if (pDroppedOn && (GetChildCount(pDroppedOn) > 0) && !IsExpanded(pDroppedOn)) - { - // -> swing open - m_aDropActionType = DA_EXPANDNODE; - bNeedTrigger = true; - } - } - - if (bNeedTrigger && (m_aTimerTriggered != aDropPos)) - { - // restart counting - m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS; - // remember pos, because I get AcceptDrops, although mouse hasn't moved - m_aTimerTriggered = aDropPos; - // start Timer - if (!m_aDropActionTimer.IsActive()) // exist Timer? - { - m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE); - m_aDropActionTimer.Start(); - } - } else if (!bNeedTrigger) - m_aDropActionTimer.Stop(); - } - - return implAcceptDataTransfer( GetDataFlavorExVector(), rEvt.mnAction, GetEntry( aDropPos ), true ); + std::unique_ptr<weld::TreeIter> xDropTarget(m_xTreeView->make_iterator()); + // get_dest_row_at_pos with false cause we must drop exactly "on" a form to paste a control into it + if (!m_xTreeView->get_dest_row_at_pos(aDropPos, xDropTarget.get(), false)) + xDropTarget.reset(); + return implAcceptDataTransfer(m_aDropTargetHelper.GetDataFlavorExVector(), rEvt.mnAction, xDropTarget.get(), true); } - sal_Int8 NavigatorTree::implExecuteDataTransfer( const OControlTransferData& _rData, sal_Int8 _nAction, const ::Point& _rDropPos, bool _bDnD ) { - return implExecuteDataTransfer( _rData, _nAction, GetEntry( _rDropPos ), _bDnD ); + std::unique_ptr<weld::TreeIter> xDrop(m_xTreeView->make_iterator()); + // get_dest_row_at_pos with false cause we must drop exactly "on" a form to paste a control into it + if (!m_xTreeView->get_dest_row_at_pos(_rDropPos, xDrop.get(), false)) + xDrop.reset(); + return implExecuteDataTransfer( _rData, _nAction, xDrop.get(), _bDnD ); } - - sal_Int8 NavigatorTree::implExecuteDataTransfer( const OControlTransferData& _rData, sal_Int8 _nAction, SvTreeListEntry* _pTargetEntry, bool _bDnD ) + sal_Int8 NavigatorTree::implExecuteDataTransfer( const OControlTransferData& _rData, sal_Int8 _nAction, weld::TreeIter* _pTargetEntry, bool _bDnD ) { const DataFlavorExVector& rDataFlavors = _rData.GetDataFlavorExVector(); @@ -897,10 +879,6 @@ namespace svxform // under some platforms, it may happen that ExecuteDrop is called though AcceptDrop returned DND_ACTION_NONE return DND_ACTION_NONE; - // would be bad, if we scroll after drop - if (m_aDropActionTimer.IsActive()) - m_aDropActionTimer.Stop(); - if (!_pTargetEntry) // no target -> no drop return DND_ACTION_NONE; @@ -920,7 +898,7 @@ namespace svxform #ifdef DBG_UTIL DBG_ASSERT( bHasHiddenControlsFormat, "NavigatorTree::implExecuteDataTransfer: copy allowed for hidden controls only!" ); #endif - DBG_ASSERT( _pTargetEntry && ( _pTargetEntry != m_pRootEntry ) && IsFormEntry( _pTargetEntry ), + DBG_ASSERT( _pTargetEntry && m_xTreeView->iter_compare(*_pTargetEntry, *m_xRootEntry) != 0 && IsFormEntry( *_pTargetEntry ), "NavigatorTree::implExecuteDataTransfer: should not be here!" ); // implAcceptDataTransfer should have caught both cases @@ -930,7 +908,7 @@ namespace svxform #endif // because i want to select all targets (and only them) - SelectAll(false); + m_xTreeView->unselect_all(); const Sequence< Reference< XInterface > >& aControls = _rData.hiddenControls(); sal_Int32 nCount = aControls.getLength(); @@ -951,7 +929,7 @@ namespace svxform for (sal_Int32 i=0; i<nCount; ++i) { // create new control - FmControlData* pNewControlData = NewControl( FM_COMPONENT_HIDDEN, _pTargetEntry, false); + FmControlData* pNewControlData = NewControl( FM_COMPONENT_HIDDEN, *_pTargetEntry, false); Reference< XPropertySet > xNewPropSet( pNewControlData->GetPropertySet() ); // copy properties form old control to new one @@ -974,10 +952,10 @@ namespace svxform } } - SvTreeListEntry* pToSelect = FindEntry(pNewControlData); - Select(pToSelect); + std::unique_ptr<weld::TreeIter> xToSelect = FindEntry(pNewControlData); + m_xTreeView->select(*xToSelect); if (i == 0) - SetCurEntry(pToSelect); + m_xTreeView->set_cursor(*xToSelect); } if (pFormModel) @@ -994,14 +972,19 @@ namespace svxform } // some data for the target - bool bDropTargetIsForm = IsFormEntry(_pTargetEntry); - FmFormData* pTargetData = bDropTargetIsForm ? static_cast<FmFormData*>(_pTargetEntry->GetUserData()) : nullptr; + bool bDropTargetIsForm = IsFormEntry(*_pTargetEntry); + FmFormData* pTargetData = bDropTargetIsForm ? reinterpret_cast<FmFormData*>(m_xTreeView->get_id(*_pTargetEntry).toInt64()) : nullptr; DBG_ASSERT( DND_ACTION_COPY != _nAction, "NavigatorTree::implExecuteDataTransfer: somebody changed the logics!" ); // list of dragged entries - const ListBoxEntrySet aDropped = _rData.selected(); - DBG_ASSERT(!aDropped.empty(), "NavigatorTree::implExecuteDataTransfer: no entries!"); + const ListBoxEntrySet& rDropped = _rData.selected(); + DBG_ASSERT(!rDropped.empty(), "NavigatorTree::implExecuteDataTransfer: no entries!"); + + // make a copy because rDropped is updated on deleting an entry which we do in the processing loop + ListBoxEntrySet aDropped; + for (const auto& rEntry : rDropped) + aDropped.emplace(m_xTreeView->make_iterator(rEntry.get())); // shell and model FmFormShell* pFormShell = GetNavModel()->GetFormShell(); @@ -1028,13 +1011,15 @@ namespace svxform ++dropped ) { + bool bFirstEntry = aDropped.begin() == dropped; + // some data of the current element - SvTreeListEntry* pCurrent = *dropped; - DBG_ASSERT(pCurrent != nullptr, "NavigatorTree::implExecuteDataTransfer: invalid entry"); - DBG_ASSERT(GetParent(pCurrent) != nullptr, "NavigatorTree::implExecuteDataTransfer: invalid entry"); + const auto& rCurrent = *dropped; + DBG_ASSERT(rCurrent, "NavigatorTree::implExecuteDataTransfer: invalid entry"); + DBG_ASSERT(m_xTreeView->get_iter_depth(*rCurrent) != 0, "NavigatorTree::implExecuteDataTransfer: invalid entry"); // don't drag root - FmEntryData* pCurrentUserData = static_cast<FmEntryData*>(pCurrent->GetUserData()); + FmEntryData* pCurrentUserData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rCurrent).toInt64()); Reference< XChild > xCurrentChild = pCurrentUserData->GetChildIFace(); Reference< XIndexContainer > xContainer(xCurrentChild->getParent(), UNO_QUERY); @@ -1071,7 +1056,7 @@ namespace svxform xContainer->removeByIndex(nIndex); // remove selection - Select(pCurrent, false); + m_xTreeView->unselect(*rCurrent); // and delete it Remove(pCurrentUserData); @@ -1121,12 +1106,11 @@ namespace svxform GetNavModel()->GetRootList()->insert( std::unique_ptr<FmEntryData>(pCurrentUserData), nIndex ); // announce to myself and reselect - SvTreeListEntry* pNew = Insert( pCurrentUserData, nIndex ); - if ( ( aDropped.begin() == dropped ) && pNew ) + std::unique_ptr<weld::TreeIter> xNew = Insert( pCurrentUserData, nIndex ); + if (bFirstEntry && xNew) { - SvTreeListEntry* pParent = GetParent( pNew ); - if ( pParent ) - Expand( pParent ); + if (m_xTreeView->iter_parent(*xNew)) + m_xTreeView->expand_row(*xNew); } } @@ -1151,11 +1135,9 @@ namespace svxform return _nAction; } - sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& rEvt ) { sal_Int8 nResult( DND_ACTION_NONE ); - if ( m_aControlExchange.isDragSource() ) nResult = implExecuteDataTransfer( *m_aControlExchange, rEvt.mnAction, rEvt.maPosPixel, true ); else @@ -1163,29 +1145,31 @@ namespace svxform OControlTransferData aDroppedData( rEvt.maDropEvent.Transferable ); nResult = implExecuteDataTransfer( aDroppedData, rEvt.mnAction, rEvt.maPosPixel, true ); } - return nResult; } - void NavigatorTree::doPaste() { - try + std::unique_ptr<weld::TreeIter> xSelected(m_xTreeView->make_iterator()); + if (!m_xTreeView->get_selected(xSelected.get())) + xSelected.reset(); + + try { if ( m_aControlExchange.isClipboardOwner() ) { - implExecuteDataTransfer( *m_aControlExchange, doingKeyboardCut( ) ? DND_ACTION_MOVE : DND_ACTION_COPY, FirstSelected(), false ); + implExecuteDataTransfer( *m_aControlExchange, doingKeyboardCut( ) ? DND_ACTION_MOVE : DND_ACTION_COPY, xSelected.get(), false ); } else { // the clipboard content - Reference< XClipboard > xClipboard( GetClipboard() ); + Reference< XClipboard > xClipboard( GetSystemClipboard() ); Reference< XTransferable > xTransferable; if ( xClipboard.is() ) xTransferable = xClipboard->getContents(); OControlTransferData aClipboardContent( xTransferable ); - implExecuteDataTransfer( aClipboardContent, DND_ACTION_COPY, FirstSelected(), false ); + implExecuteDataTransfer( aClipboardContent, DND_ACTION_COPY, xSelected.get(), false ); } } catch( const Exception& ) @@ -1194,7 +1178,6 @@ namespace svxform } } - void NavigatorTree::doCopy() { if ( implPrepareExchange( DND_ACTION_COPY ) ) @@ -1204,16 +1187,21 @@ namespace svxform } } - - void NavigatorTree::ModelHasRemoved( SvTreeListEntry* _pEntry ) + void NavigatorTree::ModelHasRemoved(weld::TreeIter* pTypedEntry) { - SvTreeListEntry* pTypedEntry = _pEntry; - if ( doingKeyboardCut() ) - m_aCutEntries.erase( pTypedEntry ); + if (doingKeyboardCut()) + { + auto aIter = std::find_if(m_aCutEntries.begin(), m_aCutEntries.end(), + [this, pTypedEntry](const auto& rElem) { + return m_xTreeView->iter_compare(*rElem, *pTypedEntry) == 0; + }); + if (aIter != m_aCutEntries.end()) + m_aCutEntries.erase(aIter); + } - if ( m_aControlExchange.isDataExchangeActive() ) + if (m_aControlExchange.isDataExchangeActive()) { - if ( 0 == m_aControlExchange->onEntryRemoved( pTypedEntry ) ) + if (0 == m_aControlExchange->onEntryRemoved(m_xTreeView.get(), pTypedEntry)) { // last of the entries which we put into the clipboard has been deleted from the tree. // Give up the clipboard ownership. @@ -1222,7 +1210,6 @@ namespace svxform } } - void NavigatorTree::doCut() { if ( implPrepareExchange( DND_ACTION_MOVE ) ) @@ -1232,28 +1219,25 @@ namespace svxform m_bKeyboardCut = true; // mark all the entries we just "cut" into the clipboard as "nearly moved" - for ( SvTreeListEntry* pEntry : m_arrCurrentSelection ) + for (const auto& rEntry : m_arrCurrentSelection ) { - if ( pEntry ) - { - m_aCutEntries.insert( pEntry ); - pEntry->SetFlags( pEntry->GetFlags() | SvTLEntryFlags::SEMITRANSPARENT ); - InvalidateEntry( pEntry ); - } + if (!rEntry) + continue; + m_aCutEntries.emplace(m_xTreeView->make_iterator(rEntry.get())); + m_xTreeView->set_sensitive(*rEntry, false); } } } - - void NavigatorTree::KeyInput(const ::KeyEvent& rKEvt) + IMPL_LINK(NavigatorTree, KeyInputHdl, const ::KeyEvent&, rKEvt, bool) { const vcl::KeyCode& rCode = rKEvt.GetKeyCode(); // delete? - if (rKEvt.GetKeyCode().GetCode() == KEY_DELETE && !rKEvt.GetKeyCode().GetModifier()) + if (rCode.GetCode() == KEY_DELETE && !rCode.GetModifier()) { DeleteSelection(); - return; + return true; } // copy'n'paste? @@ -1276,28 +1260,23 @@ namespace svxform break; } - SvTreeListBox::KeyInput(rKEvt); + return false; } - - bool NavigatorTree::EditingEntry( SvTreeListEntry* pEntry, ::Selection& rSelection ) + IMPL_LINK(NavigatorTree, EditingEntryHdl, const weld::TreeIter&, rIter, bool) { - if (!SvTreeListBox::EditingEntry( pEntry, rSelection )) - return false; - - return (pEntry && (pEntry->GetUserData() != nullptr)); - // root, which isn't allowed to be renamed, has UserData=NULL + // root, which isn't allowed to be renamed, has UserData=NULL + m_bEditing = !m_xTreeView->get_id(rIter).isEmpty(); + return m_bEditing; } - - void NavigatorTree::NewForm( SvTreeListEntry const * pParentEntry ) + void NavigatorTree::NewForm(const weld::TreeIter& rParentEntry) { - // get ParentFormData - if( !IsFormEntry(pParentEntry) ) + if (!IsFormEntry(rParentEntry)) return; - FmFormData* pParentFormData = static_cast<FmFormData*>(pParentEntry->GetUserData()); + FmFormData* pParentFormData = reinterpret_cast<FmFormData*>(m_xTreeView->get_id(rParentEntry).toInt64()); // create new form @@ -1345,25 +1324,22 @@ namespace svxform } GetNavModel()->SetModified(); - // switch to EditMode - SvTreeListEntry* pNewEntry = FindEntry( pNewFormData ); - EditEntry( pNewEntry ); + std::unique_ptr<weld::TreeIter> xNewEntry = FindEntry(pNewFormData); + m_xTreeView->start_editing(*xNewEntry); + m_bEditing = true; } - - FmControlData* NavigatorTree::NewControl( const OUString& rServiceName, SvTreeListEntry const * pParentEntry, bool bEditName ) + FmControlData* NavigatorTree::NewControl(const OUString& rServiceName, const weld::TreeIter& rParentEntry, bool bEditName) { - // get ParentForm if (!GetNavModel()->GetFormShell()) return nullptr; - if (!IsFormEntry(pParentEntry)) + if (!IsFormEntry(rParentEntry)) return nullptr; - FmFormData* pParentFormData = static_cast<FmFormData*>(pParentEntry->GetUserData()); - Reference< XForm > xParentForm( pParentFormData->GetFormIface()); - + FmFormData* pParentFormData = reinterpret_cast<FmFormData*>(m_xTreeView->get_id(rParentEntry).toInt64()); + Reference<XForm> xParentForm(pParentFormData->GetFormIface()); // create new component Reference<XComponentContext> xContext = comphelper::getProcessComponentContext(); @@ -1373,36 +1349,33 @@ namespace svxform FmControlData* pNewFormControlData = new FmControlData(xNewComponent, pParentFormData); - // set name OUString sName = FmFormPageImpl::setUniqueName( xNewComponent, xParentForm ); pNewFormControlData->SetText( sName ); - // insert FormComponent GetNavModel()->Insert(pNewFormControlData, SAL_MAX_UINT32, true); GetNavModel()->SetModified(); if (bEditName) { - // switch to EditMode - SvTreeListEntry* pNewEntry = FindEntry( pNewFormControlData ); - Select( pNewEntry ); - EditEntry( pNewEntry ); + std::unique_ptr<weld::TreeIter> xNewEntry = FindEntry( pNewFormControlData ); + m_xTreeView->select(*xNewEntry); + + m_xTreeView->start_editing(*xNewEntry); + m_bEditing = true; } return pNewFormControlData; } - OUString NavigatorTree::GenerateName( FmEntryData const * pEntryData ) { const sal_uInt16 nMaxCount = 99; OUString aNewName; - // create base name OUString aBaseName; if( dynamic_cast<const FmFormData*>( pEntryData) != nullptr ) @@ -1429,70 +1402,32 @@ namespace svxform return aNewName; } - - bool NavigatorTree::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) + IMPL_LINK(NavigatorTree, EditedEntryHdl, const IterString&, rIterString, bool) { - if (EditingCanceled()) - return true; + m_bEditing = false; - GrabFocus(); - FmEntryData* pEntryData = static_cast<FmEntryData*>(pEntry->GetUserData()); - bool bRes = NavigatorTreeModel::Rename( pEntryData, rNewText); - if( !bRes ) + const weld::TreeIter& rIter = rIterString.first; + + FmEntryData* pEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rIter).toInt64()); + bool bRes = NavigatorTreeModel::Rename(pEntryData, rIterString.second); + if (!bRes) { - m_pEditEntry = pEntry; - nEditEvent = Application::PostUserEvent( LINK(this, NavigatorTree, OnEdit), nullptr, true ); - } else - SetCursor(pEntry, true); + m_xEditEntry = m_xTreeView->make_iterator(&rIter); + nEditEvent = Application::PostUserEvent(LINK(this, NavigatorTree, OnEdit)); + } return bRes; } - IMPL_LINK_NOARG(NavigatorTree, OnEdit, void*, void) { nEditEvent = nullptr; - EditEntry( m_pEditEntry ); - m_pEditEntry = nullptr; + m_xTreeView->start_editing(*m_xEditEntry); + m_bEditing = true; + m_xEditEntry.reset(); } - - IMPL_LINK_NOARG(NavigatorTree, OnDropActionTimer, Timer *, void) - { - if (--m_aTimerCounter > 0) - return; - - switch ( m_aDropActionType ) - { - case DA_EXPANDNODE: - { - SvTreeListEntry* pToExpand = GetEntry(m_aTimerTriggered); - if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand)) - // normally, we have to test, if the node is expanded, - // but there is no method for this either in base class nor the model - // the base class should tolerate it anyway - Expand(pToExpand); - - // After expansion there is nothing to do like after scrolling - m_aDropActionTimer.Stop(); - } - break; - - case DA_SCROLLUP : - ScrollOutputArea( 1 ); - m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS; - break; - - case DA_SCROLLDOWN : - ScrollOutputArea( -1 ); - m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS; - break; - - } - } - - - IMPL_LINK_NOARG(NavigatorTree, OnEntrySelDesel, SvTreeListBox*, void) + IMPL_LINK_NOARG(NavigatorTree, OnEntrySelDesel, weld::TreeView&, void) { m_sdiState = SDI_DIRTY; @@ -1506,26 +1441,22 @@ namespace svxform m_aSynchronizeTimer.Start(); } - IMPL_LINK_NOARG(NavigatorTree, OnSynchronizeTimer, Timer *, void) { SynchronizeMarkList(); } - IMPL_LINK_NOARG(NavigatorTree, OnClipboardAction, OLocalExchange&, void) { if ( !m_aControlExchange.isClipboardOwner() ) { if ( doingKeyboardCut() ) { - for (SvTreeListEntry* pEntry : m_aCutEntries) + for (const auto& rEntry : m_aCutEntries) { - if ( !pEntry ) + if (!rEntry) continue; - - pEntry->SetFlags( pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT ); - InvalidateEntry( pEntry ); + m_xTreeView->set_sensitive(*rEntry, true); } ListBoxEntrySet aEmpty; m_aCutEntries.swap( aEmpty ); @@ -1535,7 +1466,6 @@ namespace svxform } } - void NavigatorTree::ShowSelectionProperties(bool bForce) { // at first i need the FormShell @@ -1564,14 +1494,15 @@ namespace svxform { // either only forms, or only controls are selected if (m_arrCurrentSelection.size() == 1) { + const std::unique_ptr<weld::TreeIter>& rIter = *m_arrCurrentSelection.begin(); if (m_nFormsSelected > 0) { // exactly one form is selected - FmFormData* pFormData = static_cast<FmFormData*>((*m_arrCurrentSelection.begin())->GetUserData()); + FmFormData* pFormData = reinterpret_cast<FmFormData*>(m_xTreeView->get_id(*rIter).toInt64()); aSelection.insert( Reference< XInterface >( pFormData->GetFormIface(), UNO_QUERY ) ); } else { // exactly one control is selected (whatever hidden or normal) - FmEntryData* pEntryData = static_cast<FmEntryData*>((*m_arrCurrentSelection.begin())->GetUserData()); + FmEntryData* pEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rIter).toInt64()); aSelection.insert( Reference< XInterface >( pEntryData->GetElement(), UNO_QUERY ) ); } @@ -1584,7 +1515,8 @@ namespace svxform SvLBoxEntrySortedArray::const_iterator it = m_arrCurrentSelection.begin(); for ( sal_Int32 i = 0; i < m_nFormsSelected; ++i ) { - FmFormData* pFormData = static_cast<FmFormData*>((*it)->GetUserData()); + const std::unique_ptr<weld::TreeIter>& rIter = *it; + FmFormData* pFormData = reinterpret_cast<FmFormData*>(m_xTreeView->get_id(*rIter).toInt64()); aSelection.insert( pFormData->GetPropertySet().get() ); ++it; } @@ -1596,7 +1528,8 @@ namespace svxform SvLBoxEntrySortedArray::const_iterator it = m_arrCurrentSelection.begin(); for ( sal_Int32 i = 0; i < m_nHiddenControls; ++i ) { - FmEntryData* pEntryData = static_cast<FmEntryData*>((*it)->GetUserData()); + const std::unique_ptr<weld::TreeIter>& rIter = *it; + FmEntryData* pEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rIter).toInt64()); aSelection.insert( pEntryData->GetPropertySet().get() ); ++it; } @@ -1627,10 +1560,10 @@ namespace svxform void NavigatorTree::DeleteSelection() { // of course, i can't delete root - bool bRootSelected = IsSelected(m_pRootEntry); - sal_uIntPtr nSelectedEntries = GetSelectionCount(); + bool bRootSelected = m_xTreeView->is_selected(*m_xRootEntry); + auto nSelectedEntries = m_xTreeView->count_selected_rows(); if (bRootSelected && (nSelectedEntries > 1)) // root and other elements ? - Select(m_pRootEntry, false); // yes -> remove root from selection + m_xTreeView->unselect(*m_xRootEntry); // yes -> remove root from selection if ((nSelectedEntries == 0) || bRootSelected) // still root ? return; // -> only selected element -> leave @@ -1672,7 +1605,8 @@ namespace svxform for (SvLBoxEntrySortedArray::reverse_iterator it = m_arrCurrentSelection.rbegin(); it != m_arrCurrentSelection.rend(); ) { - FmEntryData* pCurrent = static_cast<FmEntryData*>((*it)->GetUserData()); + const std::unique_ptr<weld::TreeIter>& rIter = *it; + FmEntryData* pCurrent = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rIter).toInt64()); // a form ? bool bIsForm = dynamic_cast<const FmFormData*>( pCurrent) != nullptr; @@ -1741,7 +1675,7 @@ namespace svxform // remove remaining structure for (const auto& rpSelection : m_arrCurrentSelection) { - FmEntryData* pCurrent = static_cast<FmEntryData*>(rpSelection->GetUserData()); + FmEntryData* pCurrent = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(*rpSelection).toInt64()); // if the entry still has children, we skipped deletion of one of those children. // This may for instance be because the shape is in a hidden layer, where we're unable @@ -1773,20 +1707,18 @@ namespace svxform m_nFormsSelected = m_nControlsSelected = m_nHiddenControls = 0; m_bRootSelected = false; - SvTreeListEntry* pSelectionLoop = FirstSelected(); - while (pSelectionLoop) - { + m_xTreeView->selected_foreach([this, sdiHow](weld::TreeIter& rSelectionLoop){ // count different elements - if (pSelectionLoop == m_pRootEntry) + if (m_xTreeView->iter_compare(rSelectionLoop, *m_xRootEntry) == 0) m_bRootSelected = true; else { - if (IsFormEntry(pSelectionLoop)) + if (IsFormEntry(rSelectionLoop)) ++m_nFormsSelected; else { ++m_nControlsSelected; - if (IsHiddenControl(static_cast<FmEntryData*>(pSelectionLoop->GetUserData()))) + if (IsHiddenControl(reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rSelectionLoop).toInt64()))) ++m_nHiddenControls; } } @@ -1794,64 +1726,62 @@ namespace svxform if (sdiHow == SDI_NORMALIZED) { // don't take something with a selected ancestor - if (pSelectionLoop == m_pRootEntry) - m_arrCurrentSelection.insert(pSelectionLoop); + if (m_xTreeView->iter_compare(rSelectionLoop, *m_xRootEntry) == 0) + m_arrCurrentSelection.emplace(m_xTreeView->make_iterator(&rSelectionLoop)); else { - SvTreeListEntry* pParentLoop = GetParent(pSelectionLoop); - while (pParentLoop) + std::unique_ptr<weld::TreeIter> xParentLoop(m_xTreeView->make_iterator(&rSelectionLoop)); + bool bParentLoop = m_xTreeView->iter_parent(*xParentLoop); + while (bParentLoop) { // actually i would have to test, if parent is part of m_arr_CurrentSelection ... // but if it's selected, then it's in m_arrCurrentSelection // or one of its ancestors, which was selected earlier. // In both cases IsSelected is enough - if (IsSelected(pParentLoop)) + if (m_xTreeView->is_selected(*xParentLoop)) break; else { - if (m_pRootEntry == pParentLoop) + if (m_xTreeView->iter_compare(*xParentLoop, *m_xRootEntry) == 0) { // until root (exclusive), there was no selected parent -> entry belongs to normalized list - m_arrCurrentSelection.insert(pSelectionLoop); + m_arrCurrentSelection.emplace(m_xTreeView->make_iterator(&rSelectionLoop)); break; } else - pParentLoop = GetParent(pParentLoop); + bParentLoop = m_xTreeView->iter_parent(*xParentLoop); } } } } else if (sdiHow == SDI_NORMALIZED_FORMARK) { - SvTreeListEntry* pParent = GetParent(pSelectionLoop); - if (!pParent || !IsSelected(pParent) || IsFormEntry(pSelectionLoop)) - m_arrCurrentSelection.insert(pSelectionLoop); + std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rSelectionLoop)); + bool bParent = m_xTreeView->iter_parent(*xParent); + if (!bParent || !m_xTreeView->is_selected(*xParent) || IsFormEntry(rSelectionLoop)) + m_arrCurrentSelection.emplace(m_xTreeView->make_iterator(&rSelectionLoop)); } else - m_arrCurrentSelection.insert(pSelectionLoop); + m_arrCurrentSelection.emplace(m_xTreeView->make_iterator(&rSelectionLoop)); - - pSelectionLoop = NextSelected(pSelectionLoop); - } + return false; + }); m_sdiState = sdiHow; } - void NavigatorTree::SynchronizeSelection(FmEntryDataArray& arredToSelect) { LockSelectionHandling(); if (arredToSelect.empty()) { - SelectAll(false); + m_xTreeView->unselect_all(); } else { // compare current selection with requested SelectList - SvTreeListEntry* pSelection = FirstSelected(); - while (pSelection) - { - FmEntryData* pCurrent = static_cast<FmEntryData*>(pSelection->GetUserData()); + m_xTreeView->selected_foreach([this, &arredToSelect](weld::TreeIter& rSelection) { + FmEntryData* pCurrent = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rSelection).toInt64()); if (pCurrent != nullptr) { FmEntryDataArray::iterator it = arredToSelect.find(pCurrent); @@ -1861,17 +1791,17 @@ namespace svxform arredToSelect.erase(it); } else { // entry selected, but not in SelectList -> remove selection - Select(pSelection, false); + m_xTreeView->unselect(rSelection); // make it visible (maybe it's the only modification i do in this handler // so you should see it - MakeVisible(pSelection); + m_xTreeView->scroll_to_row(rSelection); } } else - Select(pSelection, false); + m_xTreeView->unselect(rSelection); - pSelection = NextSelected(pSelection); - } + return false; + }); // now SelectList contains only entries, which have to be selected // two possibilities : 1) run through SelectList, get SvTreeListEntry for every entry and select it (is more intuitive) @@ -1881,21 +1811,17 @@ namespace svxform // 2) needs =(n*log k), duplicates some code from FindEntry // This may be a frequently used code ( at every change in mark of the view!), // so i use latter one - SvTreeListEntry* pLoop = First(); - FmEntryDataArray::const_iterator aEnd = arredToSelect.end(); - while(pLoop) - { - FmEntryData* pCurEntryData = static_cast<FmEntryData*>(pLoop->GetUserData()); + m_xTreeView->all_foreach([this, &arredToSelect](weld::TreeIter& rLoop){ + FmEntryData* pCurEntryData = reinterpret_cast<FmEntryData*>(m_xTreeView->get_id(rLoop).toInt64()); FmEntryDataArray::iterator it = arredToSelect.find(pCurEntryData); - if (it != aEnd) ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits