diff options
Diffstat (limited to '')
-rw-r--r-- | svx/source/form/navigatortreemodel.cxx | 907 |
1 files changed, 907 insertions, 0 deletions
diff --git a/svx/source/form/navigatortreemodel.cxx b/svx/source/form/navigatortreemodel.cxx new file mode 100644 index 000000000..218e2ba4a --- /dev/null +++ b/svx/source/form/navigatortreemodel.cxx @@ -0,0 +1,907 @@ +/* -*- 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 . + */ + +#include <svx/dialmgr.hxx> +#include <svx/fmshell.hxx> +#include <svx/fmmodel.hxx> +#include <svx/fmpage.hxx> +#include <svx/svditer.hxx> +#include <svx/svdogrp.hxx> + +#include <fmprop.hxx> + +#include <fmundo.hxx> +#include <fmexpl.hxx> +#include <svx/strings.hrc> +#include <fmshimp.hxx> +#include <fmobj.hxx> +#include <o3tl/safeint.hxx> +#include <sfx2/objsh.hxx> +#include <tools/diagnose_ex.h> +#include <com/sun/star/container/XContainer.hpp> +#include <comphelper/types.hxx> + + +namespace svxform +{ + + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::form; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::container; + using namespace ::com::sun::star::script; + using namespace ::com::sun::star::sdb; + + OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel) + :m_pNavModel(_pModel) + ,m_nLocks(0) + ,m_bCanUndo(true) + { + } + + // XPropertyChangeListener + + void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) + { + Remove( Source.Source ); + } + + + void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) + { + if( !m_pNavModel ) return; + if( evt.PropertyName != FM_PROP_NAME ) return; + + Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY); + Reference< XForm > xForm(evt.Source, UNO_QUERY); + + FmEntryData* pEntryData( nullptr ); + if( xForm.is() ) + pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() ); + else if( xFormComponent.is() ) + pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() ); + + if( pEntryData ) + { + OUString aNewName = ::comphelper::getString(evt.NewValue); + pEntryData->SetText( aNewName ); + FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName ); + m_pNavModel->Broadcast( aNameChangedHint ); + } + } + + // XContainerListener + + void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) + { + if (IsLocked() || !m_pNavModel) + return; + + // insert no Undoaction + m_bCanUndo = false; + + Reference< XInterface > xTemp; + evt.Element >>= xTemp; + Insert(xTemp, ::comphelper::getINT32(evt.Accessor)); + + m_bCanUndo = true; + } + + + void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex) + { + Reference< XForm > xForm(xIface, UNO_QUERY); + if (xForm.is()) + { + m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex)); + Reference< XIndexContainer > xContainer(xForm, UNO_QUERY); + Reference< XInterface > xTemp; + for (sal_Int32 i = 0; i < xContainer->getCount(); i++) + { + xContainer->getByIndex(i) >>= xTemp; + Insert(xTemp, i); + } + } + else + { + Reference< XFormComponent > xFormComp(xIface, UNO_QUERY); + if (xFormComp.is()) + m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex)); + } + } + + + void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) + { + if (IsLocked() || !m_pNavModel) + return; + + m_bCanUndo = false; + + // delete EntryData + Reference< XFormComponent > xReplaced; + evt.ReplacedElement >>= xReplaced; + FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList()); + if (pEntryData) + { + if (dynamic_cast<const FmControlData*>( pEntryData) != nullptr) + { + Reference< XFormComponent > xComp; + evt.Element >>= xComp; + DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !"); + // FmControlData should be coupled with XFormComponent + m_pNavModel->ReplaceFormComponent(xReplaced, xComp); + } + else if (dynamic_cast<const FmFormData*>( pEntryData) != nullptr) + { + OSL_FAIL("replacing forms not implemented yet !"); + } + } + + m_bCanUndo = true; + } + + + void OFormComponentObserver::Remove( const css::uno::Reference< css::uno::XInterface >& _rxElement ) + { + if (IsLocked() || !m_pNavModel) + return; + + m_bCanUndo = false; + + + // delete EntryData + FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList() ); + if (pEntryData) + m_pNavModel->Remove(pEntryData); + + m_bCanUndo = true; + } + + + void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) + { + Reference< XInterface > xElement; + evt.Element >>= xElement; + Remove( xElement ); + } + + NavigatorTreeModel::NavigatorTreeModel() + :m_pFormShell(nullptr) + ,m_pFormPage(nullptr) + ,m_pFormModel(nullptr) + { + m_pPropChangeList = new OFormComponentObserver(this); + m_pRootList.reset( new FmEntryDataList() ); + } + + NavigatorTreeModel::~NavigatorTreeModel() + { + + // unregister Listener + if( m_pFormShell) + { + FmFormModel* pFormModel = m_pFormShell->GetFormModel(); + if( pFormModel && IsListening(*pFormModel)) + EndListening( *pFormModel ); + + if (IsListening(*m_pFormShell)) + EndListening(*m_pFormShell); + } + + Clear(); + m_pRootList.reset(); + m_pPropChangeList->ReleaseModel(); + } + + + void NavigatorTreeModel::SetModified() + { + if( !m_pFormShell ) return; + SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell(); + if( !pObjShell ) return; + pObjShell->SetModified(); + } + + + void NavigatorTreeModel::Clear() + { + Reference< css::form::XForms > xForms( GetForms()); + if(xForms.is()) + xForms->removeContainerListener(m_pPropChangeList); + + + // delete RootList + GetRootList()->clear(); + + + // notify UI + FmNavClearedHint aClearedHint; + Broadcast( aClearedHint ); + } + + + Reference< css::form::XForms > NavigatorTreeModel::GetForms() const + { + if( !m_pFormShell || !m_pFormShell->GetCurPage()) + return nullptr; + else + return m_pFormShell->GetCurPage()->GetForms(); + } + + + void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uInt32 nRelPos, bool bAlterModel) + { + if (IsListening(*m_pFormModel)) + EndListening(*m_pFormModel); + + m_pPropChangeList->Lock(); + FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() ); + Reference< XChild > xElement( pEntry->GetChildIFace() ); + if (bAlterModel) + { + OUString aStr; + if (dynamic_cast<const FmFormData*>( pEntry) != nullptr) + aStr = SvxResId(RID_STR_FORM); + else + aStr = SvxResId(RID_STR_CONTROL); + + Reference< XIndexContainer > xContainer; + if (pFolder) + xContainer.set(pFolder->GetFormIface(), UNO_QUERY); + else + xContainer = GetForms(); + + bool bUndo = m_pFormModel->IsUndoEnabled(); + + if( bUndo ) + { + OUString aUndoStr(SvxResId(RID_STR_UNDO_CONTAINER_INSERT)); + aUndoStr = aUndoStr.replaceFirst("#", aStr); + m_pFormModel->BegUndo(aUndoStr); + } + + if (nRelPos >= o3tl::make_unsigned(xContainer->getCount())) + nRelPos = static_cast<sal_uInt32>(xContainer->getCount()); + + // UndoAction + if ( bUndo && m_pPropChangeList->CanUndo()) + { + m_pFormModel->AddUndo(std::make_unique<FmUndoContainerAction>(*m_pFormModel, + FmUndoContainerAction::Inserted, + xContainer, + xElement, + nRelPos)); + } + + // Element has to be of the expected type by the container + if (xContainer->getElementType() == + cppu::UnoType<XForm>::get()) + + { + Reference< XForm > xElementAsForm(xElement, UNO_QUERY); + xContainer->insertByIndex(nRelPos, Any(xElementAsForm)); + } + else if (xContainer->getElementType() == + cppu::UnoType<XFormComponent>::get()) + + { + Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY); + xContainer->insertByIndex(nRelPos, Any(xElementAsComponent)); + } + else + { + OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !"); + } + + if( bUndo ) + m_pFormModel->EndUndo(); + } + + // register as PropertyChangeListener + Reference< XPropertySet > xSet(xElement, UNO_QUERY); + if( xSet.is() ) + xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList ); + + + // Remove data from model + if (dynamic_cast<const FmFormData*>( pEntry) != nullptr) + { + Reference< XContainer > xContainer(xElement, UNO_QUERY); + if (xContainer.is()) + xContainer->addContainerListener(m_pPropChangeList); + } + + if (pFolder) + pFolder->GetChildList()->insert( std::unique_ptr<FmEntryData>(pEntry), nRelPos ); + else + GetRootList()->insert( std::unique_ptr<FmEntryData>(pEntry), nRelPos ); + + + // notify UI + FmNavInsertedHint aInsertedHint( pEntry, nRelPos ); + Broadcast( aInsertedHint ); + + m_pPropChangeList->UnLock(); + if (IsListening(*m_pFormModel)) + StartListening(*m_pFormModel); + } + + + void NavigatorTreeModel::Remove(FmEntryData* pEntry, bool bAlterModel) + { + + // get form and parent + if (!pEntry || !m_pFormModel) + return; + + if (IsListening(*m_pFormModel)) + EndListening(*m_pFormModel); + + const bool bUndo = m_pFormModel->IsUndoEnabled(); + + m_pPropChangeList->Lock(); + FmFormData* pFolder = static_cast<FmFormData*>( pEntry->GetParent() ); + Reference< XChild > xElement ( pEntry->GetChildIFace() ); + if (bAlterModel) + { + OUString aStr; + if (dynamic_cast<const FmFormData*>( pEntry) != nullptr) + aStr = SvxResId(RID_STR_FORM); + else + aStr = SvxResId(RID_STR_CONTROL); + + if( bUndo ) + { + OUString aUndoStr(SvxResId(RID_STR_UNDO_CONTAINER_REMOVE)); + aUndoStr = aUndoStr.replaceFirst("#", aStr); + m_pFormModel->BegUndo(aUndoStr); + } + } + + // now real deletion of data form model + if (auto pFormData = dynamic_cast<FmFormData*>( pEntry)) + RemoveForm(pFormData); + else + RemoveFormComponent(static_cast<FmControlData*>(pEntry)); + + + if (bAlterModel) + { + Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY); + // remove from Container + sal_Int32 nContainerIndex = getElementPos(xContainer, xElement); + // UndoAction + if (nContainerIndex >= 0) + { + if ( bUndo && m_pPropChangeList->CanUndo()) + { + m_pFormModel->AddUndo(std::make_unique<FmUndoContainerAction>(*m_pFormModel, + FmUndoContainerAction::Removed, + xContainer, + xElement, nContainerIndex )); + } + else if( !m_pPropChangeList->CanUndo() ) + { + FmUndoContainerAction::DisposeElement( xElement ); + } + + xContainer->removeByIndex(nContainerIndex ); + } + + if( bUndo ) + m_pFormModel->EndUndo(); + } + + // remove from parent + if (pFolder) + pFolder->GetChildList()->removeNoDelete( pEntry ); + else + { + GetRootList()->removeNoDelete( pEntry ); + + // If root has no more form, reset CurForm at shell + if ( !GetRootList()->size() ) + m_pFormShell->GetImpl()->forgetCurrentForm_Lock(); + } + + + // notify UI + FmNavRemovedHint aRemovedHint( pEntry ); + Broadcast( aRemovedHint ); + + // delete entry + delete pEntry; + + m_pPropChangeList->UnLock(); + StartListening(*m_pFormModel); + } + + + void NavigatorTreeModel::RemoveForm(FmFormData const * pFormData) + { + + // get form and parent + if (!pFormData || !m_pFormModel) + return; + + FmEntryDataList* pChildList = pFormData->GetChildList(); + for ( size_t i = pChildList->size(); i > 0; ) + { + FmEntryData* pEntryData = pChildList->at( --i ); + + + // Child is form -> recursive call + if( auto pChildFormData = dynamic_cast<FmFormData*>( pEntryData) ) + RemoveForm(pChildFormData); + else if( auto pChildControlData = dynamic_cast<FmControlData*>( pEntryData) ) + RemoveFormComponent(pChildControlData); + } + + + // unregister as PropertyChangeListener + Reference< XPropertySet > xSet( pFormData->GetPropertySet() ); + if ( xSet.is() ) + xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList ); + } + + + void NavigatorTreeModel::RemoveFormComponent(FmControlData const * pControlData) + { + + // get control and parent + if (!pControlData) + return; + + + // unregister as PropertyChangeListener + Reference< XPropertySet > xSet( pControlData->GetPropertySet() ); + if (xSet.is()) + xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList); + } + + + void NavigatorTreeModel::FillBranch( FmFormData* pFormData ) + { + + // insert forms from root + if( pFormData == nullptr ) + { + Reference< XIndexContainer > xForms = GetForms(); + if (!xForms.is()) + return; + + Reference< XForm > xSubForm; + for (sal_Int32 i=0; i<xForms->getCount(); ++i) + { + DBG_ASSERT( xForms->getByIndex(i).getValueType() == cppu::UnoType<XForm>::get(), + "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm"); + + xForms->getByIndex(i) >>= xSubForm; + FmFormData* pSubFormData = new FmFormData(xSubForm, pFormData); + Insert( pSubFormData ); + + // new branch, if SubForm contains Subforms itself + FillBranch( pSubFormData ); + } + } + + + // insert components + else + { + Reference< XIndexContainer > xComponents( GetFormComponents(pFormData)); + if( !xComponents.is() ) return; + + FmControlData* pNewControlData; + FmFormData* pSubFormData; + + Reference< XFormComponent > xCurrentComponent; + for (sal_Int32 j=0; j<xComponents->getCount(); ++j) + { + xComponents->getByIndex(j) >>= xCurrentComponent; + Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY); + + if (xSubForm.is()) + { // actual component is a form + pSubFormData = new FmFormData(xSubForm, pFormData); + Insert(pSubFormData); + + + // new branch, if SubForm contains Subforms itself + FillBranch(pSubFormData); + } + else + { + pNewControlData = new FmControlData(xCurrentComponent, pFormData); + Insert(pNewControlData); + } + } + } + } + + + void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos) + { + FmFormData* pFormData = static_cast<FmFormData*>(FindData( xForm, GetRootList() )); + if (pFormData) + return; + + + // set ParentData + Reference< XInterface > xIFace( xForm->getParent()); + Reference< XForm > xParentForm(xIFace, UNO_QUERY); + FmFormData* pParentData = nullptr; + if (xParentForm.is()) + pParentData = static_cast<FmFormData*>(FindData( xParentForm, GetRootList() )); + + pFormData = new FmFormData(xForm, pParentData); + Insert( pFormData, nRelPos ); + } + + + void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos) + { + + // set ParentData + Reference< XInterface > xIFace( xComp->getParent()); + Reference< XForm > xForm(xIFace, UNO_QUERY); + if (!xForm.is()) + return; + + FmFormData* pParentData = static_cast<FmFormData*>(FindData( xForm, GetRootList() )); + if( !pParentData ) + { + pParentData = new FmFormData(xForm, nullptr); + Insert( pParentData ); + } + + if (!FindData(xComp, pParentData->GetChildList(),false)) + { + + // set new EntryData + FmEntryData* pNewEntryData = new FmControlData(xComp, pParentData); + + + // insert new EntryData + Insert( pNewEntryData, nRelPos ); + } + } + + void NavigatorTreeModel::ReplaceFormComponent( + const Reference< XFormComponent > & xOld, + const Reference< XFormComponent > & xNew + ) + { + FmEntryData* pData = FindData(xOld, GetRootList()); + assert(dynamic_cast<const FmControlData*>( pData)); //NavigatorTreeModel::ReplaceFormComponent : invalid argument + auto pControlData = dynamic_cast<FmControlData*>( pData); + if (!pControlData) + return; + pControlData->ModelReplaced(xNew); + + FmNavModelReplacedHint aReplacedHint( pData ); + Broadcast( aReplacedHint ); + } + + FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, bool bRecurs) + { + // normalize + Reference< XInterface > xIFace( xElement, UNO_QUERY ); + + for ( size_t i = 0; i < pDataList->size(); i++ ) + { + FmEntryData* pEntryData = pDataList->at( i ); + if ( pEntryData->GetElement().get() == xIFace.get() ) + return pEntryData; + else if (bRecurs) + { + pEntryData = FindData( xElement, pEntryData->GetChildList() ); + if (pEntryData) + return pEntryData; + } + } + return nullptr; + } + + + FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData const * pParentData, bool bRecurs ) + { + FmEntryDataList* pDataList; + if( !pParentData ) + pDataList = GetRootList(); + else + pDataList = pParentData->GetChildList(); + + OUString aEntryText; + FmEntryData* pEntryData; + FmEntryData* pChildData; + + for( size_t i = 0; i < pDataList->size(); i++ ) + { + pEntryData = pDataList->at( i ); + aEntryText = pEntryData->GetText(); + + if (rText == aEntryText) + return pEntryData; + + if (FmFormData* pFormData = bRecurs ? dynamic_cast<FmFormData*>(pEntryData) : nullptr) + { + pChildData = FindData(rText, pFormData, true); + if( pChildData ) + return pChildData; + } + } + + return nullptr; + } + + void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) + { + if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint) + { + const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint); + switch( pSdrHint->GetKind() ) + { + case SdrHintKind::ObjectInserted: + InsertSdrObj(pSdrHint->GetObject()); + break; + case SdrHintKind::ObjectRemoved: + RemoveSdrObj(pSdrHint->GetObject()); + break; + default: + break; + } + } + // is shell gone? + else if (rHint.GetId() == SfxHintId::Dying) + { + UpdateContent(nullptr); + } + // changed mark of controls? + else if (const FmNavViewMarksChanged* pvmcHint = dynamic_cast<const FmNavViewMarksChanged*>(&rHint)) + { + BroadcastMarkedObjects(pvmcHint->GetAffectedView()->GetMarkedObjectList()); + } + } + + void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj ) + { + const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj ); + if ( pFormObject ) + { + try + { + Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); + Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW ); + + sal_Int32 nPos = getElementPos( xContainer, xFormComponent ); + InsertFormComponent( xFormComponent, nPos ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svx"); + } + } + else if ( pObj->IsGroupObject() ) + { + SdrObjListIter aIter( pObj->GetSubList() ); + while ( aIter.IsMore() ) + InsertSdrObj( aIter.Next() ); + } + } + + + void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj ) + { + const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj ); + if ( pFormObject ) + { + try + { + Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); + FmEntryData* pEntryData = FindData( xFormComponent, GetRootList() ); + if ( pEntryData ) + Remove( pEntryData ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svx"); + } + } + else if ( pObj->IsGroupObject() ) + { + SdrObjListIter aIter( pObj->GetSubList() ); + while ( aIter.IsMore() ) + RemoveSdrObj( aIter.Next() ); + } + } + + bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject) + { + if ( auto pObjGroup = dynamic_cast<const SdrObjGroup*>( pObject) ) + { // descend recursively + const SdrObjList *pChildren = pObjGroup->GetSubList(); + for ( size_t i=0; i<pChildren->GetObjCount(); ++i ) + { + SdrObject* pCurrent = pChildren->GetObj(i); + if (!InsertFormComponent(rHint, pCurrent)) + return false; + } + } + else + { + FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject ); + if ( !pFormObject ) + return false; + + try + { + Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); + FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() ); + if ( !pControlData ) + return false; + + rHint.AddItem( pControlData ); + return true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("svx"); + return false; + } + } + + return true; + } + + void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked) + { + // search all objects, which can be handled, out of marked objects + FmNavRequestSelectHint rshRequestSelection; + bool bIsMixedSelection = false; + + for (size_t i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; ++i) + { + SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj(); + bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent); + // if Not-Form-Control, InsertFormComponent returns sal_False ! + } + + rshRequestSelection.SetMixedSelection(bIsMixedSelection); + if (bIsMixedSelection) + rshRequestSelection.ClearItems(); + + Broadcast(rshRequestSelection); + // an empty list causes NavigatorTree to remove his selection + } + + + void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms ) + { + + // refill model form root upward + Clear(); + if (!xForms.is()) + return; + + xForms->addContainerListener(m_pPropChangeList); + + FillBranch(nullptr); + + // select same control in tree as in view + // (or all of them), if there is one ... + if(!m_pFormShell) return; // no shell + + FmFormView* pFormView = m_pFormShell->GetFormView(); + DBG_ASSERT(pFormView != nullptr, "NavigatorTreeModel::UpdateContent : no FormView"); + BroadcastMarkedObjects(pFormView->GetMarkedObjectList()); + } + + + void NavigatorTreeModel::UpdateContent( FmFormShell* pShell ) + { + + // If shell is unchanged, do nothing + FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : nullptr; + if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage)) + return; + + + // unregister as Listener + if( m_pFormShell ) + { + if (m_pFormModel) + EndListening( *m_pFormModel ); + m_pFormModel = nullptr; + EndListening( *m_pFormShell ); + Clear(); + } + + + // entire update + m_pFormShell = pShell; + if (m_pFormShell) + { + m_pFormPage = pNewPage; + UpdateContent(m_pFormPage->GetForms()); + } else + m_pFormPage = nullptr; + + + // register as Listener again + if( m_pFormShell ) + { + StartListening( *m_pFormShell ); + m_pFormModel = m_pFormShell->GetFormModel(); + if( m_pFormModel ) + StartListening( *m_pFormModel ); + } + } + + + Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData const * pFormData ) + { + + // get components from form + if (pFormData) + return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY); + + return Reference< XIndexContainer > (); + } + + + bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText ) + { + + // If name already exist, error message + pEntryData->SetText( rNewText ); + + + // get PropertySet + Reference< XFormComponent > xFormComponent; + + if( auto pFormData = dynamic_cast<FmFormData*>( pEntryData)) + { + xFormComponent = pFormData->GetFormIface(); + } + + if( auto pControlData = dynamic_cast<FmControlData*>( pEntryData) ) + { + xFormComponent = pControlData->GetFormComponent(); + } + + if( !xFormComponent.is() ) return false; + Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY); + if( !xSet.is() ) return false; + + + // set name + xSet->setPropertyValue( FM_PROP_NAME, Any(rNewText) ); + + return true; + } + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |