/* -*- 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 .
*/
usingnamespace ::com::sun::star; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Type; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::XComponentContext; using ::com::sun::star::form::FormButtonType_SUBMIT; using ::com::sun::star::form::binding::XValueBinding; using ::com::sun::star::form::binding::XBindableValue; using ::com::sun::star::lang::XComponent; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::form::runtime::FormController; using ::com::sun::star::form::runtime::XFormController; using ::com::sun::star::script::XEventAttacherManager; using ::com::sun::star::awt::XTabControllerModel; using ::com::sun::star::container::XChild; using ::com::sun::star::task::XInteractionHandler; using ::com::sun::star::awt::XTabController; using ::com::sun::star::awt::XControlContainer; using ::com::sun::star::awt::XControl; using ::com::sun::star::form::XFormComponent; using ::com::sun::star::form::XForm; using ::com::sun::star::lang::IndexOutOfBoundsException; using ::com::sun::star::container::XContainer; using ::com::sun::star::container::ContainerEvent; using ::com::sun::star::lang::EventObject; using ::com::sun::star::sdb::SQLErrorEvent; using ::com::sun::star::sdbc::XRowSet; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::container::XElementAccess; using ::com::sun::star::awt::XWindow; using ::com::sun::star::awt::FocusEvent; using ::com::sun::star::ui::dialogs::XExecutableDialog; using ::com::sun::star::sdbc::XDataSource; using ::com::sun::star::container::XIndexContainer; using ::com::sun::star::sdbc::XConnection; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::sdbc::SQLException; using ::com::sun::star::util::XNumberFormatsSupplier; using ::com::sun::star::util::XNumberFormats; using ::com::sun::star::beans::XPropertySetInfo;
// create an XFormController for every form
FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" ); if ( !pFormPage ) return;
for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); )
{
xIndex->getByIndex(n) >>= xController; if (xModel.get() == xController->getModel().get()) return xController; else
{
xController = getControllerSearchChildren(xController, xModel); if ( xController.is() ) return xController;
}
}
} return Reference< XFormController > ();
}
// Search the according controller
Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const
{
Reference< XTabControllerModel > xModel(xForm, UNO_QUERY); for (constauto& rpController : m_aControllerList)
{ if (rpController->getModel().get() == xModel.get()) return rpController;
// the current-round controller isn't the right one. perhaps one of its children ?
Reference< XFormController > xChildSearch = getControllerSearchChildren(Reference< XIndexAccess > (rpController, UNO_QUERY), xModel); if (xChildSearch.is()) return xChildSearch;
} return Reference< XFormController > ();
}
void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, constReference< XFormController >& _rxParentController )
{
DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" );
Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY); if (!xFormCps.is()) return;
// create a form controller
Reference< XFormController > xController( FormController::create(m_xContext) );
Reference< XInteractionHandler > xHandler; if ( _rxParentController.is() )
xHandler = _rxParentController->getInteractionHandler(); else
{ // TODO: should we create a default handler? Not really necessary, since the // FormController itself has a default fallback
} if ( xHandler.is() )
xController->setInteractionHandler( xHandler );
// now go through the subforms
sal_uInt32 nLength = xFormCps->getCount();
Reference< XForm > xSubForm; for (sal_uInt32 i = 0; i < nLength; i++)
{ if ( xFormCps->getByIndex(i) >>= xSubForm )
setController( xSubForm, xController );
}
}
try
{
Reference< XTabController > xTabCtrl( getController( _rxForm ) ); if ( xTabCtrl.is() )
{ // if there already is a TabController for this form, then delegate the "updateTabOrder" request
xTabCtrl->activateTabOrder();
} else
{ // otherwise, create a TabController
// if it's a sub form, then we must ensure there exist TabControllers // for all its ancestors, too
Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY ); // there is a parent form -> look for the respective controller
Reference< XFormController > xParentController; if ( xParentForm.is() )
xParentController = getController( xParentForm );
if ( m_isTabOrderUpdateSuspended )
{ // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm );
} else
{
rtl::Reference< FormViewPageWindowAdapter > pAdapter = findWindow( xControlContainer ); if ( pAdapter.is() )
pAdapter->updateTabOrder( xForm );
}
} catch (const Exception&)
{
DBG_UNHANDLED_EXCEPTION("svx");
}
}
// listen at the ControlContainer to notice changes
Reference< XContainer > xContainer( xCC, UNO_QUERY ); if ( xContainer.is() )
xContainer->addContainerListener( this );
}
}
void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC )
{ // Is called if // - the design mode is being switched to // - a window is deleted while in the design mode // - the control container for a window is removed while the active mode is on
auto i = std::find_if(m_aPageWindowAdapters.begin(), m_aPageWindowAdapters.end(),
[&_rxCC](const rtl::Reference< FormViewPageWindowAdapter >& rpAdapter) { return _rxCC == rpAdapter->getControlContainer(); }); if (i != m_aPageWindowAdapters.end())
{
Reference< XContainer > xContainer( _rxCC, UNO_QUERY ); if ( xContainer.is() )
xContainer->removeContainerListener( this );
(*i)->dispose();
m_aPageWindowAdapters.erase( i );
}
}
void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent )
{
DBG_ASSERT( nullptr == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" ); // This should not happen - usually, the PostUserEvent is faster than any possible user // interaction which could trigger a new error. If it happens, we need a queue for the events.
m_aAsyncError = _rEvent;
m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) );
}
// update the tab orders for all components which were collected since the suspendTabOrderUpdate call. for (constauto& rContainer : m_aNeedTabOrderUpdate)
{
rtl::Reference< FormViewPageWindowAdapter > pAdapter = findWindow( rContainer.first ); if ( !pAdapter.is() ) continue;
namespace
{ bool isActivableDatabaseForm(const Reference< XFormController > &xController)
{ // only database forms are to be activated
Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY); if ( !xForm.is() || !getConnection( xForm ).is() ) returnfalse;
Reference< XPropertySet > xFormSet( xForm, UNO_QUERY ); if ( !xFormSet.is() )
{
SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" ); returnfalse;
}
if ( !m_pView )
{
OSL_FAIL( "FmXFormView::OnActivate: well... seems we have a timing problem (the view already died)!" ); return;
}
// setting the controller to activate if (!(m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)) return;
// only enabled controls are allowed to participate bool bEnabled = false;
OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled ); if ( !bEnabled ) returnfalse;
// check the class id of the control model
sal_Int16 nClassId = FormComponentType::CONTROL;
OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
ENSURE_OR_RETURN_VOID( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!" );
try
{ // go for the tab controller of the first form if ( !xForms->getCount() ) return;
Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW );
Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW );
// go for the first control of the controller
Sequence< Reference< XControl > > aControls( xTabController->getControls() ); if ( !aControls.hasElements() )
{
Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW ); if (xFormElementAccess->hasElements() && pPage && m_pView)
{ // there are control models in the form, but no controls, yet. // Well, since some time controls are created on demand only. In particular, // they're normally created when they're first painted. // Unfortunately, the FormController does not have any way to // trigger the creation itself, so we must hack this ...
lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm );
aControls = xTabController->getControls();
OSL_ENSURE( aControls.hasElements(), "FmXFormView::OnAutoFocus: no controls at all!" );
}
}
// set the focus to this first control
Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY ); if ( !xControlWindow.is() ) return;
xControlWindow->setFocus();
// ensure that the control is visible // 80210 - 12/07/00 - FS const OutputDevice* pOut = m_pView ? m_pView->GetActualOutDev() : nullptr; const vcl::Window* pCurrentWindow = pOut ? pOut->GetOwnerWindow() : nullptr; if ( pCurrentWindow )
{
awt::Rectangle aRect = xControlWindow->getPosSize();
::tools::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< vcl::Window* >( pCurrentWindow ) );
}
} catch (const Exception&)
{
DBG_UNHANDLED_EXCEPTION("svx");
}
}
// it is valid that the form shell's forms collection is not initialized, yet
pShellImpl->UpdateForms_Lock(true);
m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY ); if ( !m_xLastCreatedControlModel.is() ) return;
// some initial property defaults
FormControlFactory aControlFactory;
aControlFactory.initializeControlModel(pShellImpl->getDocumentType_Lock(), _rFormObject);
if (!pShellImpl->GetWizardUsing_Lock()) return;
// #i31958# don't call wizards in XForms mode if (pShellImpl->isEnhancedForm_Lock()) return;
// #i46898# no wizards if there is no Base installed - currently, all wizards are // database related if (!SvtModuleOptions().IsDataBaseInstalled()) return;
rtl::Reference<SdrObject> FmXFormView::implCreateFieldControl( const svx::ODataAccessDescriptor& _rColumnDescriptor )
{ // not if we're in design mode if ( !m_pView->IsDesignMode() ) return nullptr;
// obtain the data source if ( !xDataSource.is() )
xDataSource = getDataSource( sDataSource, comphelper::getProcessComponentContext() );
// and the connection, if necessary if ( !xConnection.is() )
xConnection.reset( getConnection_withFeedback(
sDataSource,
OUString(),
OUString(),
comphelper::getProcessComponentContext(),
nullptr
) );
} catch (const SQLException&)
{
aError.Reason = ::cppu::getCaughtException();
} catch (const Exception& )
{ /* will be asserted below */
} if (aError.Reason.hasValue())
{
displayAsyncErrorMessage( aError ); return nullptr;
}
// need a data source and a connection here if (!xDataSource.is() || !xConnection.is())
{
OSL_FAIL("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!"); return nullptr;
}
Reference< XComponent > xKeepFieldsAlive; // go try
{ // determine the table/query field which we should create a control for
Reference< XPropertySet > xField;
// determine the control type by examining the data type of the bound column
SdrObjKind nOBJID = SdrObjKind::NONE; bool bDateNTimeField = false;
bool bIsCurrency = false; if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField))
bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY));
if (bIsCurrency)
nOBJID = SdrObjKind::FormCurrencyField; else switch (nDataType)
{ case DataType::BLOB: case DataType::LONGVARBINARY:
nOBJID = SdrObjKind::FormImageControl; break; case DataType::LONGVARCHAR: case DataType::CLOB:
nOBJID = SdrObjKind::FormEdit; break; case DataType::BINARY: case DataType::VARBINARY: return nullptr; case DataType::BIT: case DataType::BOOLEAN:
nOBJID = SdrObjKind::FormCheckbox; break; case DataType::TINYINT: case DataType::SMALLINT: case DataType::INTEGER:
nOBJID = SdrObjKind::FormNumericField; break; case DataType::REAL: case DataType::DOUBLE: case DataType::NUMERIC: case DataType::DECIMAL:
nOBJID = SdrObjKind::FormFormattedField; break; case DataType::TIMESTAMP:
bDateNTimeField = true;
sLabelPostfix = SvxResId(RID_STR_POSTFIX_DATE);
[[fallthrough]]; case DataType::DATE:
nOBJID = SdrObjKind::FormDateField; break; case DataType::TIME:
nOBJID = SdrObjKind::FormTimeField; break; case DataType::CHAR: case DataType::VARCHAR: default:
nOBJID = SdrObjKind::FormEdit; break;
} if (nOBJID == SdrObjKind::NONE) return nullptr;
// group objects bool bCheckbox = ( SdrObjKind::FormCheckbox == nOBJID );
OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" ); if ( bCheckbox ) return pControl;
if ( bDateNTimeField )
{ // so far we created a date field only, but we also need a time field if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, SdrObjKind::FormTimeField,
SvxResId(RID_STR_POSTFIX_TIME), pLabel, pControl,
xDataSource, sDataSource, sCommand, nCommandType )
)
{
pObjList->InsertObject( pLabel.get() );
pObjList->InsertObject( pControl.get() );
}
}
rtl::Reference<SdrObject> FmXFormView::implCreateXFormsControl( const svx::OXFormsDescriptor &_rDesc )
{ // not if we're in design mode if ( !m_pView->IsDesignMode() ) return nullptr;
// go try
{ // determine the table/query field which we should create a control for
Reference< XNumberFormats > xNumberFormats;
OUString sLabelPostfix = _rDesc.szName;
// only for text size
OutputDevice* pOutDev = nullptr; if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev()); else
{// find OutDev if (SdrPageView* pPageView = m_pView->GetSdrPageView())
{ // const SdrPageViewWinList& rWinList = pPageView->GetWinList(); // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
for( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); i++ )
{ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
// The service name decides which control should be created
SdrObjKind nOBJID = SdrObjKind::FormEdit; if(_rDesc.szServiceName == FM_SUN_COMPONENT_NUMERICFIELD)
nOBJID = SdrObjKind::FormNumericField; if(_rDesc.szServiceName == FM_SUN_COMPONENT_CHECKBOX)
nOBJID = SdrObjKind::FormCheckbox; if(_rDesc.szServiceName == FM_COMPONENT_COMMANDBUTTON)
nOBJID = SdrObjKind::FormButton;
// xform control or submission button? if ( !xSubmission.is() )
{
rtl::Reference<SdrUnoObj> pLabel;
rtl::Reference<SdrUnoObj> pControl; if ( !createControlLabelPair( *pOutDev, 0, 0, nullptr, xNumberFormats, nOBJID, sLabelPostfix,
pLabel, pControl, nullptr, u""_ustr, u""_ustr, -1 )
)
{ return nullptr;
}
// Now build the connection between the control and the data item.
Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY);
Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY);
DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" ); if ( xBindableValue.is() )
xBindableValue->setValueBinding(xValueBinding);
bool bCheckbox = ( SdrObjKind::FormCheckbox == nOBJID );
OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" ); if ( bCheckbox ) return pControl;
// group objects
rtl::Reference<SdrObjGroup> pGroup = new SdrObjGroup(getView()->getSdrModelFromSdrView());
SdrObjList* pObjList = pGroup->GetSubList();
pObjList->InsertObject(pLabel.get());
pObjList->InsertObject(pControl.get());
// set the button label
Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY);
xControlSet->setPropertyValue(FM_PROP_LABEL, Any(_rDesc.szName));
// connect the submission with the submission supplier (aka the button)
xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE,
Any( FormButtonType_SUBMIT ) );
Reference< css::form::submission::XSubmissionSupplier > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY);
xSubmissionSupplier->setSubmission(xSubmission);
return rtl::Reference<SdrObject>(pControl);
}
} catch (const Exception&)
{
TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while creating the control !");
}
// tdf#118963 Hand over a SdrModel to SdrObject-creation. It uses the local m_pView // and already returning false when nullptr == getView() could be done, but m_pView // is already dereferenced here in many places (see below), so just use it for now.
getView()->getSdrModelFromSdrView(),
_rpLabel,
_rpControl))
{ returnfalse;
}
// insert the control model(s) into the form component hierarchy if ( _rpLabel )
lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
// some context-dependent initializations
FormControlFactory aControlFactory; if ( _rpLabel )
aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel );
aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl );
// calculate the positions, respecting the settings of the target device
::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() );
// text width is at least 4 centimeters // text height is always half a centimeter
::Size aDefTxtSize(4000, 500);
::Size aDefSize(4000, 500);
::Size aDefImageSize(4000, 4000);
// size of the control
::Size aControlSize( aDefSize ); switch ( nDataType )
{ case DataType::BIT: case DataType::BOOLEAN:
aControlSize = aDefSize; break; case DataType::LONGVARCHAR: case DataType::CLOB: case DataType::LONGVARBINARY: case DataType::BLOB:
aControlSize = aDefImageSize; break;
}
if ( SdrObjKind::FormImageControl == _nControlObjectID )
aControlSize = aDefImageSize;
// some initializations
Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
if ( aFieldName.hasValue() )
{
xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName ); if ( !bNeedLabel )
{ // no dedicated label control => use the label property if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
xControlSet->setPropertyValue( FM_PROP_LABEL, Any( sFieldName + _rFieldPostfix ) ); else
OSL_FAIL( "FmXFormView::createControlLabelPair: can't set a label for the control!" );
}
}
void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject )
{ // if the remote object in my MarkList, which I have memorized when switching to the // Alive mode, I have to take it out now, because I otherwise try to set the mark // again when switching back (interestingly, this fails only with grouped objects // (when accessing their ObjList GPF), not with individual ones)
const size_t nCount = m_aMark.GetMarkCount(); for (size_t i = 0; i < nCount; ++i)
{
SdrMark* pMark = m_aMark.GetMark(i);
SdrObject* pCurrent = pMark->GetMarkedSdrObj(); if (pObject == pCurrent)
{
m_aMark.DeleteMark(i); return;
} // I do not need to descend into GroupObjects: if an object is deleted there, // then the pointer, which I have, to the GroupObject still remains valid ...
}
}
if (rCurrentList.GetMarkCount())
{ // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList? bool bMisMatch = false;
// loop through all current marks const size_t nCurrentCount = rCurrentList.GetMarkCount(); for ( size_t i=0; i<nCurrentCount && !bMisMatch; ++i )
{ const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
// loop through all saved marks, check for equality bool bFound = false; const size_t nSavedCount = m_aMark.GetMarkCount(); for ( size_t j=0; j<nSavedCount && !bFound; ++j )
{ if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
bFound = true;
}
// did not find a current mark in the saved marks if ( !bFound )
bMisMatch = true;
}
if ( bMisMatch )
{
m_aMark.Clear();
_rRestoredMarkList = rCurrentList; return;
}
} // it is important that the objects of the mark list are not accessed, // because they can be already destroyed
SdrPageView* pCurPageView = m_pView->GetSdrPageView();
SdrObjListIter aPageIter( pPage ); bool bFound = true;
// do all objects still exist const size_t nCount = m_aMark.GetMarkCount(); for (size_t i = 0; i < nCount && bFound; ++i)
{
SdrMark* pMark = m_aMark.GetMark(i);
SdrObject* pObj = pMark->GetMarkedSdrObj(); if (pObj->IsGroupObject())
{
SdrObjListIter aIter(pObj->GetSubList()); while (aIter.IsMore() && bFound)
bFound = lcl_hasObject(aPageIter, aIter.Next());
} else
bFound = lcl_hasObject(aPageIter, pObj);
if (bFound)
{ // evaluate the LastObject if (nCount) // now mark the objects
{ for (size_t i = 0; i < nCount; ++i)
{
SdrMark* pMark = m_aMark.GetMark(i);
SdrObject* pObj = pMark->GetMarkedSdrObj(); if ( pObj->GetObjInventor() == SdrInventor::FmForm ) if ( !m_pView->IsObjMarked( pObj ) )
m_pView->MarkObj( pObj, pMark->GetPageView() );
}
void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ )
{ // when switch the focus outside the office the mark didn't change // so we can not remove us as focus listener if ( m_xWindow.is() && m_pView )
{
m_pView->SetMoveOutside( false, FmFormView::ImplAccess() );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.