LCOV - code coverage report
Current view: top level - libreoffice/svx/source/form - fmobj.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 55 300 18.3 %
Date: 2012-12-27 Functions: 14 30 46.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "fmobj.hxx"
      21             : #include "fmprop.hrc"
      22             : #include "fmvwimp.hxx"
      23             : #include "fmpgeimp.hxx"
      24             : #include "svx/fmresids.hrc"
      25             : #include "svx/fmview.hxx"
      26             : #include "svx/fmglob.hxx"
      27             : #include "svx/fmpage.hxx"
      28             : #include "editeng/editeng.hxx"
      29             : #include "svx/svdovirt.hxx"
      30             : #include "svx/fmmodel.hxx"
      31             : #include "svx/dialmgr.hxx"
      32             : 
      33             : #include <com/sun/star/awt/XDevice.hpp>
      34             : #include <com/sun/star/script/XEventAttacherManager.hpp>
      35             : #include <com/sun/star/io/XPersistObject.hpp>
      36             : #include <com/sun/star/awt/XControlContainer.hpp>
      37             : #include <com/sun/star/util/XCloneable.hpp>
      38             : #include "svx/fmtools.hxx"
      39             : 
      40             : #include <tools/shl.hxx>
      41             : #include <comphelper/property.hxx>
      42             : #include <comphelper/processfactory.hxx>
      43             : #include <toolkit/awt/vclxdevice.hxx>
      44             : #include <vcl/svapp.hxx>
      45             : #include <tools/diagnose_ex.h>
      46             : 
      47             : using namespace ::com::sun::star::io;
      48             : using namespace ::com::sun::star::uno;
      49             : using namespace ::com::sun::star::awt;
      50             : using namespace ::com::sun::star::lang;
      51             : using namespace ::com::sun::star::util;
      52             : using namespace ::com::sun::star::form;
      53             : using namespace ::com::sun::star::beans;
      54             : using namespace ::com::sun::star::script;
      55             : using namespace ::com::sun::star::container;
      56             : using namespace ::svxform;
      57             : 
      58         221 : TYPEINIT1(FmFormObj, SdrUnoObj);
      59             : DBG_NAME(FmFormObj);
      60             : //------------------------------------------------------------------
      61           0 : FmFormObj::FmFormObj(const ::rtl::OUString& rModelName)
      62             :           :SdrUnoObj                ( rModelName    )
      63             :           ,m_nPos                   ( -1            )
      64           0 :           ,m_pLastKnownRefDevice    ( NULL          )
      65             : {
      66             :     DBG_CTOR(FmFormObj, NULL);
      67             : 
      68             :     // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor,
      69             :     // then our incarnation of it was not called (since we were not constructed at this time).
      70           0 :     impl_checkRefDevice_nothrow( true );
      71           0 : }
      72             : 
      73             : //------------------------------------------------------------------
      74           9 : FmFormObj::FmFormObj()
      75             :           :SdrUnoObj                ( String()  )
      76             :           ,m_nPos                   ( -1        )
      77           9 :           ,m_pLastKnownRefDevice    ( NULL      )
      78             : {
      79             :     DBG_CTOR(FmFormObj, NULL);
      80           9 : }
      81             : 
      82             : //------------------------------------------------------------------
      83          27 : FmFormObj::~FmFormObj()
      84             : {
      85             :     DBG_DTOR(FmFormObj, NULL);
      86             : 
      87           9 :     Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
      88           9 :     if (xHistory.is())
      89           0 :         xHistory->dispose();
      90             : 
      91           9 :     m_xEnvironmentHistory = NULL;
      92           9 :     m_aEventsHistory.realloc(0);
      93          18 : }
      94             : 
      95             : //------------------------------------------------------------------
      96           0 : void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx,
      97             :                           const Sequence< ScriptEventDescriptor >& rEvts)
      98             : {
      99           0 :     m_xParent = xForm;
     100           0 :     aEvts     = rEvts;
     101           0 :     m_nPos    = nIdx;
     102           0 : }
     103             : 
     104             : //------------------------------------------------------------------
     105           0 : void FmFormObj::ClearObjEnv()
     106             : {
     107           0 :     m_xParent.clear();
     108           0 :     aEvts.realloc( 0 );
     109           0 :     m_nPos = -1;
     110           0 : }
     111             : 
     112             : //------------------------------------------------------------------
     113          18 : void FmFormObj::impl_checkRefDevice_nothrow( bool _force )
     114             : {
     115          18 :     const FmFormModel* pFormModel = PTR_CAST( FmFormModel, GetModel() );
     116          18 :     if ( !pFormModel || !pFormModel->ControlsUseRefDevice() )
     117             :         return;
     118             : 
     119           0 :     OutputDevice* pCurrentRefDevice = pFormModel ? pFormModel->GetRefDevice() : NULL;
     120           0 :     if ( ( m_pLastKnownRefDevice == pCurrentRefDevice ) && !_force )
     121             :         return;
     122             : 
     123           0 :     Reference< XControlModel > xControlModel( GetUnoControlModel() );
     124           0 :     if ( !xControlModel.is() )
     125             :         return;
     126             : 
     127           0 :     m_pLastKnownRefDevice = pCurrentRefDevice;
     128           0 :     if ( m_pLastKnownRefDevice == NULL )
     129             :         return;
     130             : 
     131             :     try
     132             :     {
     133           0 :         Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW );
     134           0 :         Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW );
     135             : 
     136           0 :         static const ::rtl::OUString sRefDevicePropName( RTL_CONSTASCII_USTRINGPARAM( "ReferenceDevice" ) );
     137           0 :         if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) )
     138             :         {
     139           0 :             VCLXDevice* pUnoRefDevice = new VCLXDevice;
     140           0 :             pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice );
     141           0 :             Reference< XDevice > xRefDevice( pUnoRefDevice );
     142           0 :             xModelProps->setPropertyValue( sRefDevicePropName, makeAny( xRefDevice ) );
     143           0 :         }
     144             :     }
     145           0 :     catch( const Exception& )
     146             :     {
     147             :         DBG_UNHANDLED_EXCEPTION();
     148           0 :     }
     149             : }
     150             : 
     151             : //------------------------------------------------------------------
     152           0 : void FmFormObj::impl_isolateControlModel_nothrow()
     153             : {
     154             :     try
     155             :     {
     156           0 :         Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY );
     157           0 :         if ( xControlModel.is() )
     158             :         {
     159           0 :             Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY );
     160           0 :             if ( xParent.is() )
     161             :             {
     162           0 :                 sal_Int32 nPos = getElementPos( xParent.get(), xControlModel );
     163           0 :                 xParent->removeByIndex( nPos );
     164           0 :             }
     165           0 :         }
     166             :     }
     167           0 :     catch( const Exception& )
     168             :     {
     169             :         DBG_UNHANDLED_EXCEPTION();
     170             :     }
     171           0 : }
     172             : 
     173             : //------------------------------------------------------------------
     174           9 : void FmFormObj::SetPage(SdrPage* _pNewPage)
     175             : {
     176           9 :     if ( GetPage() == _pNewPage )
     177             :     {
     178           0 :         SdrUnoObj::SetPage(_pNewPage);
     179             :         return;
     180             :     }
     181             : 
     182           9 :     FmFormPage* pOldFormPage = PTR_CAST( FmFormPage, GetPage() );
     183           9 :     if ( pOldFormPage )
     184           0 :         pOldFormPage->GetImpl().formObjectRemoved( *this );
     185             : 
     186           9 :     FmFormPage* pNewFormPage = PTR_CAST( FmFormPage, _pNewPage );
     187           9 :     if ( !pNewFormPage )
     188             :     {   // Maybe it makes sense to create an environment history here : if somebody set's our page to NULL, and we have a valid page before,
     189             :         // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it.
     190             :         // So the next SetPage with a valid new page would restore that environment within the new page.
     191             :         // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later.
     192           0 :         impl_isolateControlModel_nothrow();
     193           0 :         SdrUnoObj::SetPage(_pNewPage);
     194             :         return;
     195             :     }
     196             : 
     197           9 :     Reference< XIndexContainer >        xNewPageForms( pNewFormPage->GetForms( true ), UNO_QUERY );
     198           9 :     Reference< XIndexContainer >        xNewParent;
     199           9 :     Sequence< ScriptEventDescriptor>    aNewEvents;
     200             : 
     201             :     // calc the new parent for my model (within the new page's forms hierarchy)
     202             :     // do we have a history ? (from :Clone)
     203           9 :     if ( m_xEnvironmentHistory.is() )
     204             :     {
     205             :         // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within _pNewPage->GetForms)
     206             :         // is the right-most element in the tree.
     207           0 :         Reference< XIndexContainer > xRightMostLeaf = m_xEnvironmentHistory;
     208             :         try
     209             :         {
     210           0 :             while ( xRightMostLeaf->getCount() )
     211             :             {
     212             :                 xRightMostLeaf.set(
     213           0 :                     xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ),
     214             :                     UNO_QUERY_THROW
     215           0 :                 );
     216             :             }
     217             : 
     218           0 :             xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW );
     219             : 
     220             :             // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory
     221             :             // (which describes the events of our model at the moment m_xEnvironmentHistory was created)
     222           0 :             aNewEvents = m_aEventsHistory;
     223             :         }
     224           0 :         catch( const Exception& )
     225             :         {
     226             :             DBG_UNHANDLED_EXCEPTION();
     227           0 :         }
     228             :     }
     229             : 
     230           9 :     if ( !xNewParent.is() )
     231             :     {
     232             :         // are we a valid part of our current page forms ?
     233           9 :         Reference< XIndexContainer > xOldForms;
     234           9 :         if ( pOldFormPage )
     235           0 :             xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW );
     236             : 
     237           9 :         if ( xOldForms.is() )
     238             :         {
     239             :             // search (upward from our model) for xOldForms
     240           0 :             Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY );
     241           0 :             while (xSearch.is())
     242             :             {
     243           0 :                 if ( xSearch == xOldForms )
     244           0 :                     break;
     245           0 :                 xSearch = Reference< XChild >( xSearch->getParent(), UNO_QUERY );
     246             :             }
     247           0 :             if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy
     248             :             {
     249           0 :                 Reference< XChild >  xMeAsChild( GetUnoControlModel(), UNO_QUERY );
     250           0 :                 xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY );
     251             : 
     252           0 :                 if ( xNewParent.is() )
     253             :                 {
     254             :                     try
     255             :                     {
     256             :                         // transfer the events from our (model's) parent to the new (model's) parent, too
     257           0 :                         Reference< XEventAttacherManager >  xEventManager(xMeAsChild->getParent(), UNO_QUERY);
     258           0 :                         Reference< XIndexAccess >  xManagerAsIndex(xEventManager, UNO_QUERY);
     259           0 :                         if (xManagerAsIndex.is())
     260             :                         {
     261           0 :                             sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild);
     262           0 :                             if (nPos >= 0)
     263           0 :                                 aNewEvents = xEventManager->getScriptEvents(nPos);
     264             :                         }
     265             :                         else
     266           0 :                             aNewEvents = aEvts;
     267             :                     }
     268           0 :                     catch( const Exception& )
     269             :                     {
     270             :                         DBG_UNHANDLED_EXCEPTION();
     271             :                     }
     272           0 :                 }
     273           0 :             }
     274           9 :         }
     275             :     }
     276             : 
     277             :     // now set the page
     278           9 :     SdrUnoObj::SetPage(_pNewPage);
     279             : 
     280             :     // place my model within the new parent container
     281           9 :     if (xNewParent.is())
     282             :     {
     283           0 :         Reference< XFormComponent >  xMeAsFormComp(GetUnoControlModel(), UNO_QUERY);
     284           0 :         if (xMeAsFormComp.is())
     285             :         {
     286             :             // check if I have another parent (and remove me, if neccessary)
     287           0 :             Reference< XIndexContainer >  xOldParent(xMeAsFormComp->getParent(), UNO_QUERY);
     288           0 :             if (xOldParent.is())
     289             :             {
     290           0 :                 sal_Int32 nPos = getElementPos(Reference< XIndexAccess > (xOldParent, UNO_QUERY), xMeAsFormComp);
     291           0 :                 if (nPos > -1)
     292           0 :                     xOldParent->removeByIndex(nPos);
     293             :             }
     294             :             // and insert into the new container
     295           0 :             xNewParent->insertByIndex(xNewParent->getCount(), makeAny(xMeAsFormComp));
     296             : 
     297             :             // transfer the events
     298           0 :             if (aNewEvents.getLength())
     299             :             {
     300             :                 try
     301             :                 {
     302           0 :                     Reference< XEventAttacherManager >  xEventManager(xNewParent, UNO_QUERY);
     303           0 :                     Reference< XIndexAccess >  xManagerAsIndex(xEventManager, UNO_QUERY);
     304           0 :                     if (xManagerAsIndex.is())
     305             :                     {
     306           0 :                         sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp);
     307             :                         DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?");
     308           0 :                         xEventManager->registerScriptEvents(nPos, aNewEvents);
     309           0 :                     }
     310             :                 }
     311           0 :                 catch( const Exception& )
     312             :                 {
     313             :                     DBG_UNHANDLED_EXCEPTION();
     314             :                 }
     315             : 
     316           0 :             }
     317           0 :         }
     318             :     }
     319             : 
     320             :     // delete my history
     321           9 :     Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
     322           9 :     if (xHistory.is())
     323           0 :         xHistory->dispose();
     324             : 
     325           9 :     m_xEnvironmentHistory = NULL;
     326           9 :     m_aEventsHistory.realloc(0);
     327             : 
     328           9 :     if ( pNewFormPage )
     329           9 :         pNewFormPage->GetImpl().formObjectInserted( *this );
     330             : }
     331             : 
     332             : //------------------------------------------------------------------
     333          31 : sal_uInt32 FmFormObj::GetObjInventor()   const
     334             : {
     335          31 :     return FmFormInventor;
     336             : }
     337             : 
     338             : //------------------------------------------------------------------
     339          17 : sal_uInt16 FmFormObj::GetObjIdentifier() const
     340             : {
     341          17 :     return OBJ_UNO;
     342             : }
     343             : 
     344             : //------------------------------------------------------------------
     345           0 : void FmFormObj::clonedFrom(const FmFormObj* _pSource)
     346             : {
     347             :     DBG_ASSERT(_pSource != NULL, "FmFormObj::clonedFrom : invalid source !");
     348           0 :     Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY);
     349           0 :     if (xHistory.is())
     350           0 :         xHistory->dispose();
     351             : 
     352           0 :     m_xEnvironmentHistory = NULL;
     353           0 :     m_aEventsHistory.realloc(0);
     354             : 
     355           0 :     Reference< XChild >  xSourceAsChild(_pSource->GetUnoControlModel(), UNO_QUERY);
     356           0 :     if (!xSourceAsChild.is())
     357           0 :         return;
     358             : 
     359           0 :     Reference< XInterface >  xSourceContainer = xSourceAsChild->getParent();
     360             : 
     361             :     m_xEnvironmentHistory = Reference< XIndexContainer >(
     362           0 :         ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.Forms")) ),
     363           0 :         UNO_QUERY);
     364             :     DBG_ASSERT(m_xEnvironmentHistory.is(), "FmFormObj::clonedFrom : could not create a forms collection !");
     365             : 
     366           0 :     if (m_xEnvironmentHistory.is())
     367             :     {
     368           0 :         ensureModelEnv(xSourceContainer, m_xEnvironmentHistory);
     369           0 :         m_aEventsHistory = aEvts;
     370             :             // if we we're clone there was a call to operator=, so aEvts are excatly the events we need here ...
     371           0 :     }
     372             : }
     373             : 
     374             : //------------------------------------------------------------------
     375           0 : FmFormObj* FmFormObj::Clone() const
     376             : {
     377           0 :     FmFormObj* pFormObject = CloneHelper< FmFormObj >();
     378             :     DBG_ASSERT(pFormObject != NULL, "FmFormObj::Clone : invalid clone !");
     379           0 :     if (pFormObject)
     380           0 :         pFormObject->clonedFrom(this);
     381             : 
     382           0 :     return pFormObject;
     383             : }
     384             : 
     385             : //------------------------------------------------------------------
     386           0 : void FmFormObj::NbcReformatText()
     387             : {
     388           0 :     impl_checkRefDevice_nothrow( false );
     389           0 :     SdrUnoObj::NbcReformatText();
     390           0 : }
     391             : 
     392             : //------------------------------------------------------------------
     393           0 : FmFormObj& FmFormObj::operator= (const FmFormObj& rObj)
     394             : {
     395           0 :     if( this == &rObj )
     396           0 :         return *this;
     397           0 :     SdrUnoObj::operator= (rObj);
     398             : 
     399             :     // liegt das UnoControlModel in einer Eventumgebung,
     400             :     // dann koennen noch Events zugeordnet sein
     401           0 :     Reference< XFormComponent >  xContent(rObj.xUnoControlModel, UNO_QUERY);
     402           0 :     if (xContent.is())
     403             :     {
     404           0 :         Reference< XEventAttacherManager >  xManager(xContent->getParent(), UNO_QUERY);
     405           0 :         Reference< XIndexAccess >  xManagerAsIndex(xManager, UNO_QUERY);
     406           0 :         if (xManagerAsIndex.is())
     407             :         {
     408           0 :             sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent );
     409           0 :             if ( nPos >= 0 )
     410           0 :                 aEvts = xManager->getScriptEvents( nPos );
     411           0 :         }
     412             :     }
     413             :     else
     414           0 :         aEvts = rObj.aEvts;
     415           0 :     return *this;
     416             : }
     417             : 
     418             : //------------------------------------------------------------------
     419             : namespace
     420             : {
     421           0 :     rtl::OUString lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement)
     422             :     {
     423           0 :         Reference< ::com::sun::star::form::XFormComponent> xChild(_xElement, UNO_QUERY);
     424           0 :         Reference< ::com::sun::star::container::XIndexAccess> xParent;
     425           0 :         if (xChild.is())
     426           0 :             xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
     427             : 
     428             :         // while the current content is a form
     429           0 :         String sReturn;
     430           0 :         String sCurrentIndex;
     431           0 :         while (xChild.is())
     432             :         {
     433             :             // get the content's relative pos within it's parent container
     434           0 :             sal_Int32 nPos = getElementPos(xParent, xChild);
     435             : 
     436             :             // prepend this current relaive pos
     437           0 :             sCurrentIndex = String::CreateFromInt32(nPos);
     438           0 :             if (sReturn.Len() != 0)
     439             :             {
     440           0 :                 sCurrentIndex += '\\';
     441           0 :                 sCurrentIndex += sReturn;
     442             :             }
     443             : 
     444           0 :             sReturn = sCurrentIndex;
     445             : 
     446             :             // travel up
     447           0 :             if (::comphelper::query_interface((Reference< XInterface >)xParent,xChild))
     448           0 :                 xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY);
     449             :         }
     450             : 
     451           0 :         _rTopLevelElement = xParent;
     452           0 :         return sReturn;
     453             :     }
     454             : }
     455             : 
     456             : //------------------------------------------------------------------
     457           0 : Reference< XInterface >  FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >  _rTopLevelDestContainer)
     458             : {
     459           0 :     Reference< XInterface >  xTopLevelSouce;
     460           0 :     rtl::OUString sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSouce);
     461           0 :     if (!xTopLevelSouce.is())
     462             :         // somthing went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy
     463           0 :         return Reference< XInterface > ();
     464             : 
     465           0 :     Reference< XIndexContainer >  xDestContainer(_rTopLevelDestContainer);
     466           0 :     Reference< XIndexContainer >  xSourceContainer(xTopLevelSouce, UNO_QUERY);
     467             :     DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !");
     468             : 
     469           0 :     sal_Int32 nTokIndex = 0;
     470           0 :     do
     471             :     {
     472           0 :         rtl::OUString aToken = sAccessPath.getToken( 0, '\\', nTokIndex );
     473           0 :         sal_uInt16 nIndex = (sal_uInt16)aToken.toInt32();
     474             : 
     475             :         // get the DSS of the source form (we have to find an aquivalent for)
     476             :         DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !");
     477           0 :         Reference< XPropertySet >  xSourceForm;
     478           0 :         xSourceContainer->getByIndex(nIndex) >>= xSourceForm;
     479             :         DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !");
     480             : 
     481           0 :         Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource;
     482             :         DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm)
     483             :             && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !");
     484             :             // the parent access path should refer to a row set
     485             :         try
     486             :         {
     487           0 :             aSrcCursorSource        = xSourceForm->getPropertyValue(FM_PROP_COMMAND);
     488           0 :             aSrcCursorSourceType    = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE);
     489           0 :             aSrcDataSource          = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE);
     490             :         }
     491           0 :         catch(Exception&)
     492             :         {
     493             :             OSL_FAIL("FmFormObj::ensureModelEnv : could not retrieve a source DSS !");
     494             :         }
     495             : 
     496             : 
     497             :         // calc the number of (source) form siblings with the same DSS
     498           0 :         Reference< XPropertySet >  xCurrentSourceForm, xCurrentDestForm;
     499           0 :         sal_Int16 nCurrentSourceIndex = 0, nCurrentDestIndex = 0;
     500           0 :         while (nCurrentSourceIndex <= nIndex)
     501             :         {
     502           0 :             sal_Bool bEqualDSS = sal_False;
     503           0 :             while (!bEqualDSS)  // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex)
     504             :             {
     505           0 :                 xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm;
     506             :                 DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !");
     507           0 :                 bEqualDSS = sal_False;
     508           0 :                 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm))
     509             :                 {   // it is a form
     510             :                     try
     511             :                     {
     512           0 :                         if  (   ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
     513           0 :                             &&  ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
     514           0 :                             &&  ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
     515             :                             )
     516             :                         {
     517           0 :                             bEqualDSS = sal_True;
     518             :                         }
     519             :                     }
     520           0 :                     catch(Exception&)
     521             :                     {
     522             :                         OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a sibling's DSS !");
     523             :                     }
     524             : 
     525             :                 }
     526           0 :                 ++nCurrentSourceIndex;
     527             :             }
     528             : 
     529             :             DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !");
     530             :             // ??? at least the nIndex-th one should have been found ???
     531             : 
     532             :             // now search the next one with the given DSS (within the destination container)
     533           0 :             bEqualDSS = sal_False;
     534           0 :             while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount()))
     535             :             {
     536           0 :                 xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm;
     537             :                 DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !");
     538           0 :                 bEqualDSS = sal_False;
     539           0 :                 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm))
     540             :                 {   // it is a form
     541             :                     try
     542             :                     {
     543           0 :                         if  (   ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource)
     544           0 :                             &&  ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType)
     545           0 :                             &&  ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource)
     546             :                             )
     547             :                         {
     548           0 :                             bEqualDSS = sal_True;
     549             :                         }
     550             :                     }
     551           0 :                     catch(Exception&)
     552             :                     {
     553             :                         OSL_FAIL("FmFormObj::ensureModelEnv : exception while getting a destination DSS !");
     554             :                     }
     555             : 
     556             :                 }
     557           0 :                 ++nCurrentDestIndex;
     558             :             }
     559             : 
     560           0 :             if (!bEqualDSS)
     561             :             {   // There is at least one more source form with the given DSS than destination forms are.
     562             :                 // correct this ...
     563             :                 try
     564             :                 {
     565             :                     // create and insert (into the destination) a copy of the form
     566             :                     xCurrentDestForm.set(
     567           0 :                         ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.component.DataForm" )) ),
     568           0 :                         UNO_QUERY_THROW );
     569           0 :                     ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm );
     570             : 
     571             :                     DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !");
     572           0 :                     xDestContainer->insertByIndex(nCurrentDestIndex, makeAny(xCurrentDestForm));
     573             : 
     574           0 :                     ++nCurrentDestIndex;
     575             :                         // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actally means
     576             :                 }
     577           0 :                 catch(Exception&)
     578             :                 {
     579             :                     OSL_FAIL("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !");
     580             :                     // no more options anymore ...
     581           0 :                     return Reference< XInterface > ();
     582             :                 }
     583             : 
     584             :             }
     585             :         }
     586             : 
     587             :         // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number
     588             :         // of left siblings with the same DSS, which counts for all their ancestors, too)
     589             : 
     590             :         // go down
     591           0 :         xDestContainer = Reference< XIndexContainer > (xCurrentDestForm, UNO_QUERY);
     592           0 :         xSourceContainer = Reference< XIndexContainer > (xSourceForm, UNO_QUERY);
     593           0 :         DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !");
     594             :     }
     595             :     while ( nTokIndex >= 0 );
     596             : 
     597           0 :     return Reference< XInterface > (xDestContainer, UNO_QUERY);
     598             : }
     599             : 
     600             : //------------------------------------------------------------------
     601           9 : void FmFormObj::SetModel( SdrModel* _pNewModel )
     602             : {
     603           9 :     SdrUnoObj::SetModel( _pNewModel );
     604           9 :     impl_checkRefDevice_nothrow();
     605           9 : }
     606             : 
     607             : //------------------------------------------------------------------
     608           0 : FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject )
     609             : {
     610           0 :     FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject );
     611           0 :     if ( !pFormObject )
     612             :     {
     613           0 :         SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject );
     614           0 :         if ( pVirtualObject )
     615           0 :             pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() );
     616             :     }
     617           0 :     return pFormObject;
     618             : }
     619             : 
     620             : //------------------------------------------------------------------
     621           0 : const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject )
     622             : {
     623           0 :     const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject );
     624           0 :     if ( !pFormObject )
     625             :     {
     626           0 :         const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject );
     627           0 :         if ( pVirtualObject )
     628           0 :             pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() );
     629             :     }
     630           0 :     return pFormObject;
     631             : }
     632             : 
     633             : //------------------------------------------------------------------
     634           9 : void FmFormObj::SetUnoControlModel( const Reference< com::sun::star::awt::XControlModel >& _rxModel )
     635             : {
     636           9 :     SdrUnoObj::SetUnoControlModel( _rxModel );
     637             : 
     638           9 :     FmFormPage* pFormPage = PTR_CAST( FmFormPage, GetPage() );
     639           9 :     if ( pFormPage )
     640           1 :         pFormPage->GetImpl().formModelAssigned( *this );
     641             : 
     642           9 :     impl_checkRefDevice_nothrow( true );
     643           9 : }
     644             : 
     645             : //------------------------------------------------------------------
     646           0 : bool FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
     647             : {
     648           0 :     bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
     649           0 :     if ( bResult && SDRCREATE_FORCEEND == eCmd && rStat.GetView() )
     650             :     {
     651           0 :         if ( pPage )
     652             :         {
     653           0 :             FmFormPage& rPage = dynamic_cast< FmFormPage& >( *pPage );
     654             : 
     655             :             try
     656             :             {
     657           0 :                 Reference< XFormComponent >  xContent( xUnoControlModel, UNO_QUERY_THROW );
     658           0 :                 Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY );
     659             : 
     660           0 :                 Reference< XIndexContainer > xFormToInsertInto;
     661             : 
     662           0 :                 if ( !xParentForm.is() )
     663             :                 {   // model is not yet part of a form component hierachy
     664           0 :                     xParentForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW );
     665           0 :                     xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW );
     666             :                 }
     667             : 
     668           0 :                 rPage.GetImpl().setUniqueName( xContent, xParentForm );
     669             : 
     670           0 :                 if ( xFormToInsertInto.is() )
     671           0 :                     xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), makeAny( xContent ) );
     672             :             }
     673           0 :             catch( const Exception& )
     674             :             {
     675             :                 DBG_UNHANDLED_EXCEPTION();
     676             :             }
     677             :         }
     678             : 
     679           0 :         FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) );
     680           0 :         FmXFormView* pViewImpl = pView ? pView->GetImpl() : NULL;
     681             :         OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" );
     682           0 :         if ( pViewImpl )
     683           0 :             pViewImpl->onCreatedFormObject( *this );
     684             :     }
     685           0 :     return bResult;
     686             : }
     687             : 
     688             : //------------------------------------------------------------------------------
     689           0 : void FmFormObj::BrkCreate( SdrDragStat& rStat )
     690             : {
     691           0 :     SdrUnoObj::BrkCreate( rStat );
     692           0 :     impl_isolateControlModel_nothrow();
     693           0 : }
     694             : 
     695             : // -----------------------------------------------------------------------------
     696             : // #i70852# overload Layer interface to force to FormColtrol layer
     697             : 
     698          32 : SdrLayerID FmFormObj::GetLayer() const
     699             : {
     700             :     // #i72535#
     701             :     // i70852 was too radical, in SW obects (and thus, FormControls, too)
     702             :     // get moved to invisible layers to hide them (e.g. in hidden sections).
     703             :     // This means that form controls ARE allowed to be on other layers than
     704             :     // the form control layer ATM and that being member of form control layer
     705             :     // is no criteria to find all FormControls of a document.
     706             :     // To fix, use parent functionality
     707          32 :     return SdrUnoObj::GetLayer();
     708             : }
     709             : 
     710          16 : void FmFormObj::NbcSetLayer(SdrLayerID nLayer)
     711             : {
     712             :     // #i72535#
     713             :     // See above. To fix, use parent functionality
     714          16 :     return SdrUnoObj::NbcSetLayer(nLayer);
     715             : }
     716             : 
     717             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10