cid#1636693 COPY_INSTEAD_OF_MOVE
[LibreOffice.git] / basctl / source / dlged / dlgedobj.cxx
blobbc714d51c76848046923b36ed72387f73f7a1d20
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <cassert>
25 #include <dlged.hxx>
26 #include <dlgeddef.hxx>
27 #include <dlgedlist.hxx>
28 #include <dlgedobj.hxx>
29 #include <dlgedpage.hxx>
30 #include <dlgedview.hxx>
31 #include <localizationmgr.hxx>
32 #include <strings.hxx>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/form/binding/XBindableValue.hpp>
36 #include <com/sun/star/form/binding/XValueBinding.hpp>
37 #include <com/sun/star/form/binding/XListEntrySink.hpp>
38 #include <com/sun/star/awt/XUnoControlContainer.hpp>
39 #include <com/sun/star/awt/XVclContainerPeer.hpp>
40 #include <com/sun/star/container/XContainer.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
43 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
44 #include <com/sun/star/table/CellAddress.hpp>
45 #include <com/sun/star/table/CellRangeAddress.hpp>
46 #include <cppuhelper/exc_hlp.hxx>
47 #include <o3tl/functional.hxx>
48 #include <svx/svdpagv.hxx>
49 #include <unotools/sharedunocomponent.hxx>
50 #include <vcl/svapp.hxx>
51 #include <tools/debug.hxx>
53 namespace basctl
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::beans;
59 using namespace ::com::sun::star::container;
60 using namespace ::com::sun::star::script;
63 DlgEditor& DlgEdObj::GetDialogEditor ()
65 if (DlgEdForm* pFormThis = dynamic_cast<DlgEdForm*>(this))
66 return pFormThis->GetDlgEditor();
67 else
68 return pDlgEdForm->GetDlgEditor();
71 DlgEdObj::DlgEdObj(SdrModel& rSdrModel)
72 : SdrUnoObj(rSdrModel, OUString())
73 ,bIsListening(false)
77 DlgEdObj::DlgEdObj(SdrModel& rSdrModel, DlgEdObj const & rSource)
78 : SdrUnoObj(rSdrModel, rSource)
79 ,bIsListening(false)
81 // set parent form
82 pDlgEdForm = rSource.pDlgEdForm;
84 // add child to parent form
85 pDlgEdForm->AddChild( this );
87 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
88 if ( xPSet.is() )
90 // set new name
91 OUString aOUniqueName( GetUniqueName() );
92 Any aUniqueName;
93 aUniqueName <<= aOUniqueName;
94 xPSet->setPropertyValue( DLGED_PROP_NAME, aUniqueName );
96 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
97 if ( xCont.is() )
99 // set tabindex
100 Sequence< OUString > aNames = xCont->getElementNames();
101 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames.getLength())) );
103 // insert control model in dialog model
104 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
105 xCont->insertByName( aOUniqueName, Any(xCtrl) );
107 pDlgEdForm->UpdateTabOrderAndGroups();
111 // start listening
112 StartListening();
115 DlgEdObj::DlgEdObj(
116 SdrModel& rSdrModel,
117 const OUString& rModelName,
118 const css::uno::Reference< css::lang::XMultiServiceFactory >& rxSFac)
119 : SdrUnoObj(rSdrModel, rModelName, rxSFac)
120 ,bIsListening(false)
124 DlgEdObj::~DlgEdObj()
126 if ( isListening() )
127 EndListening(true);
130 namespace
132 /* returns the DlgEdForm which the given DlgEdObj belongs to
133 (which might in fact be the object itself)
135 Failure to obtain the form will be reported with an assertion in the non-product
136 version.
138 bool lcl_getDlgEdForm( DlgEdObj* _pObject, DlgEdForm*& _out_pDlgEdForm )
140 _out_pDlgEdForm = dynamic_cast< DlgEdForm* >( _pObject );
141 if ( !_out_pDlgEdForm )
142 _out_pDlgEdForm = _pObject->GetDlgEdForm();
143 DBG_ASSERT( _out_pDlgEdForm, "lcl_getDlgEdForm: no form!" );
144 return ( _out_pDlgEdForm != nullptr );
148 uno::Reference< awt::XControl > DlgEdObj::GetControl() const
150 uno::Reference< awt::XControl > xControl;
151 if (DlgEdForm const* pForm = GetDlgEdForm())
153 DlgEditor const& rEditor = pForm->GetDlgEditor();
154 xControl = GetUnoControl(rEditor.GetView(), *rEditor.GetWindow().GetOutDev());
156 return xControl;
159 bool DlgEdObj::TransformSdrToControlCoordinates(
160 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
161 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
163 // input position and size
164 Size aPos( nXIn, nYIn );
165 Size aSize( nWidthIn, nHeightIn );
167 // form position
168 DlgEdForm* pForm = nullptr;
169 if ( !lcl_getDlgEdForm( this, pForm ) )
170 return false;
171 tools::Rectangle aFormRect = pForm->GetSnapRect();
172 Size aFormPos( aFormRect.Left(), aFormRect.Top() );
174 // convert 100th_mm to pixel
175 OutputDevice* pDevice = Application::GetDefaultDevice();
176 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToControlCoordinates: missing default device!" );
177 if ( !pDevice )
178 return false;
179 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
180 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
181 aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MapUnit::Map100thMM ) );
183 // subtract form position
184 aPos.AdjustWidth( -(aFormPos.Width()) );
185 aPos.AdjustHeight( -(aFormPos.Height()) );
187 // take window borders into account
188 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
189 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
190 if ( !xPSetForm.is() )
191 return false;
192 bool bDecoration = true;
193 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
194 if( bDecoration )
196 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
197 aPos.AdjustWidth( -(aDeviceInfo.LeftInset) );
198 aPos.AdjustHeight( -(aDeviceInfo.TopInset) );
201 // convert pixel to logic units
202 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
203 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
205 // set out parameters
206 nXOut = aPos.Width();
207 nYOut = aPos.Height();
208 nWidthOut = aSize.Width();
209 nHeightOut = aSize.Height();
211 return true;
214 bool DlgEdObj::TransformSdrToFormCoordinates(
215 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
216 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
218 // input position and size
219 Size aPos( nXIn, nYIn );
220 Size aSize( nWidthIn, nHeightIn );
222 // convert 100th_mm to pixel
223 OutputDevice* pDevice = Application::GetDefaultDevice();
224 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToFormCoordinates: missing default device!" );
225 if ( !pDevice )
226 return false;
227 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
228 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
230 // take window borders into account
231 DlgEdForm* pForm = nullptr;
232 if ( !lcl_getDlgEdForm( this, pForm ) )
233 return false;
235 // take window borders into account
236 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
237 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
238 if ( !xPSetForm.is() )
239 return false;
240 bool bDecoration = true;
241 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
242 if( bDecoration )
244 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
245 aSize.AdjustWidth( -(aDeviceInfo.LeftInset + aDeviceInfo.RightInset) );
246 aSize.AdjustHeight( -(aDeviceInfo.TopInset + aDeviceInfo.BottomInset) );
248 // convert pixel to logic units
249 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
250 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
252 // set out parameters
253 nXOut = aPos.Width();
254 nYOut = aPos.Height();
255 nWidthOut = aSize.Width();
256 nHeightOut = aSize.Height();
258 return true;
261 bool DlgEdObj::TransformControlToSdrCoordinates(
262 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
263 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
265 // input position and size
266 Size aPos( nXIn, nYIn );
267 Size aSize( nWidthIn, nHeightIn );
269 // form position
270 DlgEdForm* pForm = nullptr;
271 if ( !lcl_getDlgEdForm( this, pForm ) )
272 return false;
274 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
275 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformControlToSdrCoordinates: no form property set!" );
276 if ( !xPSetForm.is() )
277 return false;
278 sal_Int32 nFormX = 0, nFormY = 0;
279 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormX;
280 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormY;
281 Size aFormPos( nFormX, nFormY );
283 // convert logic units to pixel
284 OutputDevice* pDevice = Application::GetDefaultDevice();
285 DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
286 if ( !pDevice )
287 return false;
288 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
289 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
290 aFormPos = pDevice->LogicToPixel(aFormPos, MapMode(MapUnit::MapAppFont));
292 // add form position
293 aPos.AdjustWidth(aFormPos.Width() );
294 aPos.AdjustHeight(aFormPos.Height() );
296 // take window borders into account
297 bool bDecoration = true;
298 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
299 if( bDecoration )
301 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
302 aPos.AdjustWidth(aDeviceInfo.LeftInset );
303 aPos.AdjustHeight(aDeviceInfo.TopInset );
306 // convert pixel to 100th_mm
307 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
308 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
310 // set out parameters
311 nXOut = aPos.Width();
312 nYOut = aPos.Height();
313 nWidthOut = aSize.Width();
314 nHeightOut = aSize.Height();
316 return true;
319 bool DlgEdObj::TransformFormToSdrCoordinates(
320 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
321 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
323 // input position and size
324 Size aPos( nXIn, nYIn );
325 Size aSize( nWidthIn, nHeightIn );
327 // convert logic units to pixel
328 OutputDevice* pDevice = Application::GetDefaultDevice();
329 DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
330 if ( !pDevice )
331 return false;
333 // take window borders into account
334 DlgEdForm* pForm = nullptr;
335 if ( !lcl_getDlgEdForm( this, pForm ) )
336 return false;
338 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
339 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
341 // take window borders into account
342 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
343 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
344 if ( !xPSetForm.is() )
345 return false;
346 bool bDecoration = true;
347 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
348 if( bDecoration )
350 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
351 aSize.AdjustWidth(aDeviceInfo.LeftInset + aDeviceInfo.RightInset );
352 aSize.AdjustHeight(aDeviceInfo.TopInset + aDeviceInfo.BottomInset );
355 // convert pixel to 100th_mm
356 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
357 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
359 // set out parameters
360 nXOut = aPos.Width();
361 nYOut = aPos.Height();
362 nWidthOut = aSize.Width();
363 nHeightOut = aSize.Height();
365 return true;
368 void DlgEdObj::SetRectFromProps()
370 // get control position and size from properties
371 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
372 if ( !xPSet.is() )
373 return;
375 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
376 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
377 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
378 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
379 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
381 // transform coordinates
382 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
383 if ( TransformControlToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
385 // set rectangle position and size
386 Point aPoint( nXOut, nYOut );
387 Size aSize( nWidthOut, nHeightOut );
388 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
392 void DlgEdObj::SetPropsFromRect()
394 // get control position and size from rectangle
395 tools::Rectangle aRect_ = GetSnapRect();
396 sal_Int32 nXIn = aRect_.Left();
397 sal_Int32 nYIn = aRect_.Top();
398 sal_Int32 nWidthIn = aRect_.GetWidth();
399 sal_Int32 nHeightIn = aRect_.GetHeight();
401 // transform coordinates
402 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
403 if ( TransformSdrToControlCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
405 // set properties
406 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
407 if ( xPSet.is() )
409 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
410 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
411 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
412 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
417 void DlgEdObj::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
419 DBG_ASSERT( pDlgEdForm, "DlgEdObj::PositionAndSizeChange: no form!" );
420 DlgEdPage& rPage = pDlgEdForm->GetDlgEditor().GetPage();
422 Size aPageSize = rPage.GetSize();
423 sal_Int32 nPageWidthIn = aPageSize.Width();
424 sal_Int32 nPageHeightIn = aPageSize.Height();
425 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
426 if ( TransformSdrToControlCoordinates( 0/*nPageXIn*/, 0/*nPageYIn*/, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
428 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
429 if ( xPSet.is() )
431 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
432 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
433 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
434 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
435 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
437 sal_Int32 nValue = 0;
438 evt.NewValue >>= nValue;
439 sal_Int32 nNewValue = nValue;
441 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
443 if ( nNewValue + nWidth > nPageX + nPageWidth )
444 nNewValue = nPageX + nPageWidth - nWidth;
445 if ( nNewValue < nPageX )
446 nNewValue = nPageX;
448 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
450 if ( nNewValue + nHeight > nPageY + nPageHeight )
451 nNewValue = nPageY + nPageHeight - nHeight;
452 if ( nNewValue < nPageY )
453 nNewValue = nPageY;
455 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
457 if ( nX + nNewValue > nPageX + nPageWidth )
458 nNewValue = nPageX + nPageWidth - nX;
459 if ( nNewValue < 1 )
460 nNewValue = 1;
462 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
464 if ( nY + nNewValue > nPageY + nPageHeight )
465 nNewValue = nPageY + nPageHeight - nY;
466 if ( nNewValue < 1 )
467 nNewValue = 1;
470 if ( nNewValue != nValue )
472 EndListening( false );
473 xPSet->setPropertyValue( evt.PropertyName, Any(nNewValue) );
474 StartListening();
480 SetRectFromProps();
483 void DlgEdObj::NameChange( const css::beans::PropertyChangeEvent& evt )
485 // get old name
486 OUString aOldName;
487 evt.OldValue >>= aOldName;
489 // get new name
490 OUString aNewName;
491 evt.NewValue >>= aNewName;
493 if ( aNewName == aOldName )
494 return;
496 Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), UNO_QUERY);
497 if ( !(xNameAcc.is() && xNameAcc->hasByName(aOldName)) )
498 return;
500 if (!xNameAcc->hasByName(aNewName) && !aNewName.isEmpty())
502 // remove the control by the old name and insert the control by the new name in the container
503 Reference< container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
504 if ( xCont.is() )
506 Reference< awt::XControlModel > xCtrl = GetUnoControlModel();
507 Any aAny;
508 aAny <<= xCtrl;
509 xCont->removeByName( aOldName );
510 xCont->insertByName( aNewName , aAny );
512 LocalizationMgr::renameControlResourceIDsForEditorObject(
513 &GetDialogEditor(), aAny, aNewName
517 else
519 // set old name property
520 EndListening(false);
521 Reference< beans::XPropertySet > xPSet(GetUnoControlModel(), UNO_QUERY);
522 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOldName) );
523 StartListening();
527 sal_Int32 DlgEdObj::GetStep() const
529 // get step property
530 sal_Int32 nStep = 0;
531 uno::Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), uno::UNO_QUERY );
532 if (xPSet.is())
534 xPSet->getPropertyValue( DLGED_PROP_STEP ) >>= nStep;
536 return nStep;
539 void DlgEdObj::UpdateStep()
541 sal_Int32 nCurStep = GetDlgEdForm()->GetStep();
542 sal_Int32 nStep = GetStep();
544 SdrLayerAdmin& rLayerAdmin(getSdrModelFromSdrObject().GetLayerAdmin());
545 SdrLayerID nHiddenLayerId = rLayerAdmin.GetLayerID( u"HiddenLayer"_ustr );
546 SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName() );
548 if( nCurStep )
550 if ( nStep && (nStep != nCurStep) )
552 SetLayer( nHiddenLayerId );
554 else
556 SetLayer( nControlLayerId );
559 else
561 SetLayer( nControlLayerId );
565 void DlgEdObj::TabIndexChange( const beans::PropertyChangeEvent& evt )
567 DlgEdForm* pForm = GetDlgEdForm();
568 if ( !pForm )
569 return;
571 // stop listening with all children
572 std::vector<DlgEdObj*> aChildList = pForm->GetChildren();
573 for (auto const& child : aChildList)
575 child->EndListening( false );
578 Reference< container::XNameAccess > xNameAcc( pForm->GetUnoControlModel() , UNO_QUERY );
579 if ( xNameAcc.is() )
581 // get sequence of control names
582 Sequence< OUString > aNames = xNameAcc->getElementNames();
583 sal_Int32 nCtrls = aNames.getLength();
585 // create a map of tab indices and control names, sorted by tab index
586 IndexToNameMap aIndexToNameMap;
587 for (auto& aName : aNames)
589 // get tab index
590 sal_Int16 nTabIndex = -1;
591 Any aCtrl = xNameAcc->getByName( aName );
592 Reference< beans::XPropertySet > xPSet;
593 aCtrl >>= xPSet;
594 if ( xPSet.is() && xPSet == Reference< beans::XPropertySet >( evt.Source, UNO_QUERY ) )
595 evt.OldValue >>= nTabIndex;
596 else if ( xPSet.is() )
597 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
599 // insert into map
600 aIndexToNameMap.emplace( nTabIndex, aName );
603 // create a helper list of control names, sorted by tab index
604 std::vector< OUString > aNameList( aIndexToNameMap.size() );
605 std::transform(
606 aIndexToNameMap.begin(), aIndexToNameMap.end(),
607 aNameList.begin(),
608 ::o3tl::select2nd< IndexToNameMap::value_type >( )
611 // check tab index
612 sal_Int16 nOldTabIndex = 0;
613 evt.OldValue >>= nOldTabIndex;
614 sal_Int16 nNewTabIndex = 0;
615 evt.NewValue >>= nNewTabIndex;
616 if ( nNewTabIndex < 0 )
617 nNewTabIndex = 0;
618 else if ( nNewTabIndex > nCtrls - 1 )
619 nNewTabIndex = sal::static_int_cast<sal_Int16>( nCtrls - 1 );
621 // reorder helper list
622 OUString aCtrlName = aNameList[nOldTabIndex];
623 aNameList.erase( aNameList.begin() + nOldTabIndex );
624 aNameList.insert( aNameList.begin() + nNewTabIndex , aCtrlName );
626 // set new tab indices
627 for ( sal_Int32 i = 0; i < nCtrls; ++i )
629 Any aCtrl = xNameAcc->getByName( aNameList[i] );
630 Reference< beans::XPropertySet > xPSet;
631 aCtrl >>= xPSet;
632 if ( xPSet.is() )
634 assert(i >= SAL_MIN_INT16);
635 if (i > SAL_MAX_INT16)
637 SAL_WARN("basctl", "tab " << i << " > SAL_MAX_INT16");
638 continue;
640 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(i)) );
644 // reorder objects in drawing page
645 getSdrModelFromSdrObject().GetPage(0)->SetObjectOrdNum( nOldTabIndex + 1, nNewTabIndex + 1 );
647 pForm->UpdateTabOrderAndGroups();
650 // start listening with all children
651 for (auto const& child : aChildList)
653 child->StartListening();
657 bool DlgEdObj::supportsService( OUString const & serviceName ) const
659 bool bSupports = false;
661 Reference< lang::XServiceInfo > xServiceInfo( GetUnoControlModel() , UNO_QUERY );
662 // TODO: cache xServiceInfo as member?
663 if ( xServiceInfo.is() )
664 bSupports = xServiceInfo->supportsService( serviceName );
666 return bSupports;
669 OUString DlgEdObj::GetDefaultName() const
671 OUString sResId;
672 OUString aDefaultName;
673 if ( supportsService( u"com.sun.star.awt.UnoControlDialogModel"_ustr ) )
675 sResId = RID_STR_CLASS_DIALOG;
677 else if ( supportsService( u"com.sun.star.awt.UnoControlButtonModel"_ustr ) )
679 sResId = RID_STR_CLASS_BUTTON;
681 else if ( supportsService( u"com.sun.star.awt.UnoControlRadioButtonModel"_ustr ) )
683 sResId = RID_STR_CLASS_RADIOBUTTON;
685 else if ( supportsService( u"com.sun.star.awt.UnoControlCheckBoxModel"_ustr ) )
687 sResId = RID_STR_CLASS_CHECKBOX;
689 else if ( supportsService( u"com.sun.star.awt.UnoControlListBoxModel"_ustr ) )
691 sResId = RID_STR_CLASS_LISTBOX;
693 else if ( supportsService( u"com.sun.star.awt.UnoControlComboBoxModel"_ustr ) )
695 sResId = RID_STR_CLASS_COMBOBOX;
697 else if ( supportsService( u"com.sun.star.awt.UnoControlGroupBoxModel"_ustr ) )
699 sResId = RID_STR_CLASS_GROUPBOX;
701 else if ( supportsService( u"com.sun.star.awt.UnoControlEditModel"_ustr ) )
703 sResId = RID_STR_CLASS_EDIT;
705 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedTextModel"_ustr ) )
707 sResId = RID_STR_CLASS_FIXEDTEXT;
709 else if ( supportsService( u"com.sun.star.awt.UnoControlImageControlModel"_ustr ) )
711 sResId = RID_STR_CLASS_IMAGECONTROL;
713 else if ( supportsService( u"com.sun.star.awt.UnoControlProgressBarModel"_ustr ) )
715 sResId = RID_STR_CLASS_PROGRESSBAR;
717 else if ( supportsService( u"com.sun.star.awt.UnoControlScrollBarModel"_ustr ) )
719 sResId = RID_STR_CLASS_SCROLLBAR;
721 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedLineModel"_ustr ) )
723 sResId = RID_STR_CLASS_FIXEDLINE;
725 else if ( supportsService( u"com.sun.star.awt.UnoControlDateFieldModel"_ustr ) )
727 sResId = RID_STR_CLASS_DATEFIELD;
729 else if ( supportsService( u"com.sun.star.awt.UnoControlTimeFieldModel"_ustr ) )
731 sResId = RID_STR_CLASS_TIMEFIELD;
733 else if ( supportsService( u"com.sun.star.awt.UnoControlNumericFieldModel"_ustr ) )
735 sResId = RID_STR_CLASS_NUMERICFIELD;
737 else if ( supportsService( u"com.sun.star.awt.UnoControlCurrencyFieldModel"_ustr ) )
739 sResId = RID_STR_CLASS_CURRENCYFIELD;
741 else if ( supportsService( u"com.sun.star.awt.UnoControlFormattedFieldModel"_ustr ) )
743 sResId = RID_STR_CLASS_FORMATTEDFIELD;
745 else if ( supportsService( u"com.sun.star.awt.UnoControlPatternFieldModel"_ustr ) )
747 sResId = RID_STR_CLASS_PATTERNFIELD;
749 else if ( supportsService( u"com.sun.star.awt.UnoControlFileControlModel"_ustr ) )
751 sResId = RID_STR_CLASS_FILECONTROL;
753 else if ( supportsService( u"com.sun.star.awt.tree.TreeControlModel"_ustr ) )
755 sResId = RID_STR_CLASS_TREECONTROL;
757 else if ( supportsService( u"com.sun.star.awt.grid.UnoControlGridModel"_ustr ) )
759 sResId = RID_STR_CLASS_GRIDCONTROL;
761 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedHyperlinkModel"_ustr ) )
763 sResId = RID_STR_CLASS_HYPERLINKCONTROL;
765 else if ( supportsService( u"com.sun.star.awt.UnoControlSpinButtonModel"_ustr ) )
767 sResId = RID_STR_CLASS_SPINCONTROL;
769 else
771 sResId = RID_STR_CLASS_CONTROL;
774 if (!sResId.isEmpty())
775 aDefaultName = sResId;
777 return aDefaultName;
780 OUString DlgEdObj::GetUniqueName() const
782 OUString aUniqueName;
783 uno::Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), uno::UNO_QUERY);
785 if ( xNameAcc.is() )
787 sal_Int32 n = 0;
788 OUString aDefaultName = GetDefaultName();
792 aUniqueName = aDefaultName + OUString::number(++n);
793 } while (xNameAcc->hasByName(aUniqueName));
796 return aUniqueName;
799 SdrInventor DlgEdObj::GetObjInventor() const
801 return SdrInventor::BasicDialog;
804 SdrObjKind DlgEdObj::GetObjIdentifier() const
806 if ( supportsService( u"com.sun.star.awt.UnoControlDialogModel"_ustr ))
808 return SdrObjKind::BasicDialogDialog;
810 else if ( supportsService( u"com.sun.star.awt.UnoControlButtonModel"_ustr ))
812 return SdrObjKind::BasicDialogPushButton;
814 else if ( supportsService( u"com.sun.star.awt.UnoControlRadioButtonModel"_ustr ))
816 return SdrObjKind::BasicDialogRadioButton;
818 else if ( supportsService( u"com.sun.star.awt.UnoControlCheckBoxModel"_ustr ))
820 return SdrObjKind::BasicDialogCheckbox;
822 else if ( supportsService( u"com.sun.star.awt.UnoControlListBoxModel"_ustr ))
824 return SdrObjKind::BasicDialogListbox;
826 else if ( supportsService( u"com.sun.star.awt.UnoControlComboBoxModel"_ustr ))
828 return SdrObjKind::BasicDialogCombobox;
830 else if ( supportsService( u"com.sun.star.awt.UnoControlGroupBoxModel"_ustr ))
832 return SdrObjKind::BasicDialogGroupBox;
834 else if ( supportsService( u"com.sun.star.awt.UnoControlEditModel"_ustr ))
836 return SdrObjKind::BasicDialogEdit;
838 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedTextModel"_ustr ))
840 return SdrObjKind::BasicDialogFixedText;
842 else if ( supportsService( u"com.sun.star.awt.UnoControlImageControlModel"_ustr ))
844 return SdrObjKind::BasicDialogImageControl;
846 else if ( supportsService( u"com.sun.star.awt.UnoControlProgressBarModel"_ustr ))
848 return SdrObjKind::BasicDialogProgressbar;
850 else if ( supportsService( u"com.sun.star.awt.UnoControlScrollBarModel"_ustr ))
852 return SdrObjKind::BasicDialogHorizontalScrollbar;
854 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedLineModel"_ustr ))
856 return SdrObjKind::BasicDialogHorizontalFixedLine;
858 else if ( supportsService( u"com.sun.star.awt.UnoControlDateFieldModel"_ustr ))
860 return SdrObjKind::BasicDialogDateField;
862 else if ( supportsService( u"com.sun.star.awt.UnoControlTimeFieldModel"_ustr ))
864 return SdrObjKind::BasicDialogTimeField;
866 else if ( supportsService( u"com.sun.star.awt.UnoControlNumericFieldModel"_ustr ))
868 return SdrObjKind::BasicDialogNumericField;
870 else if ( supportsService( u"com.sun.star.awt.UnoControlCurrencyFieldModel"_ustr ))
872 return SdrObjKind::BasicDialogCurencyField;
874 else if ( supportsService( u"com.sun.star.awt.UnoControlFormattedFieldModel"_ustr ))
876 return SdrObjKind::BasicDialogFormattedField;
878 else if ( supportsService( u"com.sun.star.awt.UnoControlPatternFieldModel"_ustr ))
880 return SdrObjKind::BasicDialogPatternField;
882 else if ( supportsService( u"com.sun.star.awt.UnoControlFileControlModel"_ustr ))
884 return SdrObjKind::BasicDialogFileControl;
886 else if ( supportsService( u"com.sun.star.awt.tree.TreeControlModel"_ustr ))
888 return SdrObjKind::BasicDialogTreeControl;
890 else if ( supportsService( u"com.sun.star.awt.grid.UnoControlGridModel"_ustr ))
892 return SdrObjKind::BasicDialogGridControl;
894 else if ( supportsService( u"com.sun.star.awt.UnoControlFixedHyperlinkModel"_ustr ))
896 return SdrObjKind::BasicDialogHyperlinkControl;
898 else
900 return SdrObjKind::BasicDialogControl;
904 rtl::Reference<SdrObject> DlgEdObj::CloneSdrObject(SdrModel& rTargetModel) const
906 return new DlgEdObj(rTargetModel, *this);
909 rtl::Reference<SdrObject> DlgEdObj::getFullDragClone() const
911 // no need to really add the clone for dragging, it's a temporary
912 // object
913 return rtl::Reference<SdrObject>(new SdrUnoObj(getSdrModelFromSdrObject(), *this));
916 void DlgEdObj::NbcMove( const Size& rSize )
918 SdrUnoObj::NbcMove( rSize );
920 // stop listening
921 EndListening(false);
923 // set geometry properties
924 SetPropsFromRect();
926 // start listening
927 StartListening();
929 // dialog model changed
930 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
933 void DlgEdObj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
935 SdrUnoObj::NbcResize( rRef, xFract, yFract );
937 // stop listening
938 EndListening(false);
940 // set geometry properties
941 SetPropsFromRect();
943 // start listening
944 StartListening();
946 // dialog model changed
947 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
950 bool DlgEdObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
952 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
954 // tdf#120674 after interactive creation, the SdrObject (this) has no SdrPage yet
955 // due to not being inserted. Usually this should be handled in a ::handlePageChange
956 // implementation. For historical reasons, the SdrPage (which is the DlgEdPage) was
957 // already set. For now, get it from the SdrDragStat and use it to access and set
958 // the local pDlgEdForm
959 if(!pDlgEdForm && nullptr != rStat.GetPageView())
961 const DlgEdPage* pDlgEdPage(dynamic_cast<const DlgEdPage*>(rStat.GetPageView()->GetPage()));
963 if(nullptr != pDlgEdPage)
965 // set parent form
966 pDlgEdForm = pDlgEdPage->GetDlgEdForm();
970 SetDefaults();
971 StartListening();
973 return bResult;
976 void DlgEdObj::SetDefaults()
978 if ( !pDlgEdForm )
979 return;
981 // add child to parent form
982 pDlgEdForm->AddChild( this );
984 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
985 if ( xPSet.is() )
987 // get unique name
988 OUString aOUniqueName( GetUniqueName() );
990 // set name property
991 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
993 // set labels
994 if ( supportsService( u"com.sun.star.awt.UnoControlButtonModel"_ustr ) ||
995 supportsService( u"com.sun.star.awt.UnoControlRadioButtonModel"_ustr ) ||
996 supportsService( u"com.sun.star.awt.UnoControlCheckBoxModel"_ustr ) ||
997 supportsService( u"com.sun.star.awt.UnoControlGroupBoxModel"_ustr ) ||
998 supportsService( u"com.sun.star.awt.UnoControlFixedTextModel"_ustr ) )
1000 xPSet->setPropertyValue( DLGED_PROP_LABEL, Any(aOUniqueName) );
1003 // set number formats supplier for formatted field
1004 if ( supportsService( u"com.sun.star.awt.UnoControlFormattedFieldModel"_ustr ) )
1006 Reference< util::XNumberFormatsSupplier > xSupplier = GetDlgEdForm()->GetDlgEditor().GetNumberFormatsSupplier();
1007 if ( xSupplier.is() )
1009 xPSet->setPropertyValue( DLGED_PROP_FORMATSSUPPLIER, Any(xSupplier) );
1013 // set geometry properties
1014 SetPropsFromRect();
1016 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
1017 if ( xCont.is() )
1019 // set tabindex
1020 Sequence< OUString > aNames = xCont->getElementNames();
1021 uno::Any aTabIndex;
1022 aTabIndex <<= static_cast<sal_Int16>(aNames.getLength());
1023 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, aTabIndex );
1025 // set step
1026 Reference< beans::XPropertySet > xPSetForm( xCont, UNO_QUERY );
1027 if ( xPSetForm.is() )
1029 Any aStep = xPSetForm->getPropertyValue( DLGED_PROP_STEP );
1030 xPSet->setPropertyValue( DLGED_PROP_STEP, aStep );
1033 // insert control model in dialog model
1034 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
1035 Any aAny;
1036 aAny <<= xCtrl;
1037 xCont->insertByName( aOUniqueName , aAny );
1039 LocalizationMgr::setControlResourceIDsForNewEditorObject(
1040 &GetDialogEditor(), aAny, aOUniqueName
1043 pDlgEdForm->UpdateTabOrderAndGroups();
1047 // dialog model changed
1048 pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
1051 void DlgEdObj::StartListening()
1053 DBG_ASSERT(!isListening(), "DlgEdObj::StartListening: already listening!");
1055 if (isListening())
1056 return;
1058 bIsListening = true;
1060 // XPropertyChangeListener
1061 Reference< XPropertySet > xControlModel( GetUnoControlModel() , UNO_QUERY );
1062 if (!m_xPropertyChangeListener.is() && xControlModel.is())
1064 // create listener
1065 m_xPropertyChangeListener = new DlgEdPropListenerImpl(*this);
1067 // register listener to properties
1068 xControlModel->addPropertyChangeListener( OUString() , m_xPropertyChangeListener );
1071 // XContainerListener
1072 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1073 if( !m_xContainerListener.is() && xEventsSupplier.is() )
1075 // create listener
1076 m_xContainerListener = new DlgEdEvtContListenerImpl(*this);
1078 // register listener to script event container
1079 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1080 DBG_ASSERT(xEventCont.is(), "DlgEdObj::StartListening: control model has no script event container!");
1081 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1082 if (xCont.is())
1083 xCont->addContainerListener( m_xContainerListener );
1087 void DlgEdObj::EndListening(bool bRemoveListener)
1089 DBG_ASSERT(isListening(), "DlgEdObj::EndListening: not listening currently!");
1091 if (!isListening())
1092 return;
1094 bIsListening = false;
1096 if (!bRemoveListener)
1097 return;
1099 // XPropertyChangeListener
1100 Reference< XPropertySet > xControlModel(GetUnoControlModel(), UNO_QUERY);
1101 if ( m_xPropertyChangeListener.is() && xControlModel.is() )
1103 // remove listener
1104 xControlModel->removePropertyChangeListener( OUString() , m_xPropertyChangeListener );
1106 m_xPropertyChangeListener.clear();
1108 // XContainerListener
1109 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1110 if( m_xContainerListener.is() && xEventsSupplier.is() )
1112 // remove listener
1113 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1114 DBG_ASSERT(xEventCont.is(), "DlgEdObj::EndListening: control model has no script event container!");
1115 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1116 if (xCont.is())
1117 xCont->removeContainerListener( m_xContainerListener );
1119 m_xContainerListener.clear();
1122 void DlgEdObj::_propertyChange( const css::beans::PropertyChangeEvent& evt )
1124 if (!isListening())
1125 return;
1127 DlgEdForm* pRealDlgEdForm = dynamic_cast<DlgEdForm*>(this);
1128 if (!pRealDlgEdForm)
1129 pRealDlgEdForm = GetDlgEdForm();
1130 if (!pRealDlgEdForm)
1131 return;
1132 DlgEditor& rDlgEditor = pRealDlgEdForm->GetDlgEditor();
1133 if (rDlgEditor.isInPaint())
1134 return;
1136 // dialog model changed
1137 rDlgEditor.SetDialogModelChanged();
1139 // update position and size
1140 if ( evt.PropertyName == DLGED_PROP_POSITIONX || evt.PropertyName == DLGED_PROP_POSITIONY ||
1141 evt.PropertyName == DLGED_PROP_WIDTH || evt.PropertyName == DLGED_PROP_HEIGHT ||
1142 evt.PropertyName == DLGED_PROP_DECORATION )
1144 PositionAndSizeChange( evt );
1146 if ( evt.PropertyName == DLGED_PROP_DECORATION )
1147 GetDialogEditor().ResetDialog();
1149 // change name of control in dialog model
1150 else if ( evt.PropertyName == DLGED_PROP_NAME )
1152 if (!dynamic_cast<DlgEdForm*>(this))
1156 NameChange(evt);
1158 catch (container::NoSuchElementException const&)
1160 css::uno::Any anyEx = cppu::getCaughtException();
1161 throw lang::WrappedTargetRuntimeException(u""_ustr, nullptr,
1162 anyEx);
1166 // update step
1167 else if ( evt.PropertyName == DLGED_PROP_STEP )
1169 UpdateStep();
1171 // change tabindex
1172 else if ( evt.PropertyName == DLGED_PROP_TABINDEX )
1174 if (!dynamic_cast<DlgEdForm*>(this))
1175 TabIndexChange(evt);
1179 void DlgEdObj::_elementInserted()
1181 if (isListening())
1183 // dialog model changed
1184 GetDialogEditor().SetDialogModelChanged();
1188 void DlgEdObj::_elementReplaced()
1190 if (isListening())
1192 // dialog model changed
1193 GetDialogEditor().SetDialogModelChanged();
1197 void DlgEdObj::_elementRemoved()
1199 if (isListening())
1201 // dialog model changed
1202 GetDialogEditor().SetDialogModelChanged();
1206 void DlgEdObj::SetLayer(SdrLayerID nLayer)
1208 SdrLayerID nOldLayer = GetLayer();
1210 if ( nLayer != nOldLayer )
1212 SdrUnoObj::SetLayer( nLayer );
1214 DlgEdHint aHint( DlgEdHint::LAYERCHANGED, this );
1215 GetDlgEdForm()->GetDlgEditor().Broadcast( aHint );
1219 DlgEdForm::DlgEdForm(
1220 SdrModel& rSdrModel,
1221 DlgEditor& rDlgEditor_)
1222 : DlgEdObj(rSdrModel),
1223 rDlgEditor(rDlgEditor_)
1227 DlgEdForm::~DlgEdForm()
1231 void DlgEdForm::SetRectFromProps()
1233 // get form position and size from properties
1234 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1235 if ( !xPSet.is() )
1236 return;
1238 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
1239 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
1240 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
1241 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
1242 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
1244 // transform coordinates
1245 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1246 if ( TransformFormToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1248 // set rectangle position and size
1249 Point aPoint( nXOut, nYOut );
1250 Size aSize( nWidthOut, nHeightOut );
1251 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
1255 void DlgEdForm::SetPropsFromRect()
1257 // get form position and size from rectangle
1258 tools::Rectangle aRect_ = GetSnapRect();
1259 sal_Int32 nXIn = aRect_.Left();
1260 sal_Int32 nYIn = aRect_.Top();
1261 sal_Int32 nWidthIn = aRect_.GetWidth();
1262 sal_Int32 nHeightIn = aRect_.GetHeight();
1264 // transform coordinates
1265 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1266 if ( TransformSdrToFormCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1268 // set properties
1269 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1270 if ( xPSet.is() )
1272 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
1273 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
1274 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
1275 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
1280 void DlgEdForm::AddChild( DlgEdObj* pDlgEdObj )
1282 pChildren.push_back( pDlgEdObj );
1285 void DlgEdForm::RemoveChild( DlgEdObj* pDlgEdObj )
1287 std::erase(pChildren, pDlgEdObj);
1290 void DlgEdForm::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
1292 DlgEditor& rEditor = GetDlgEditor();
1293 DlgEdPage& rPage = rEditor.GetPage();
1295 sal_Int32 nPageXIn = 0;
1296 sal_Int32 nPageYIn = 0;
1297 Size aPageSize = rPage.GetSize();
1298 sal_Int32 nPageWidthIn = aPageSize.Width();
1299 sal_Int32 nPageHeightIn = aPageSize.Height();
1300 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
1301 if ( TransformSdrToFormCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1303 Reference< beans::XPropertySet > xPSetForm( GetUnoControlModel(), UNO_QUERY );
1304 if ( xPSetForm.is() )
1306 sal_Int32 nValue = 0;
1307 evt.NewValue >>= nValue;
1308 sal_Int32 nNewValue = nValue;
1310 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
1312 if ( nNewValue < nPageX )
1313 nNewValue = nPageX;
1315 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
1317 if ( nNewValue < nPageY )
1318 nNewValue = nPageY;
1320 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
1322 if ( nNewValue < 1 )
1323 nNewValue = 1;
1325 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
1327 if ( nNewValue < 1 )
1328 nNewValue = 1;
1331 if ( nNewValue != nValue )
1333 EndListening( false );
1334 xPSetForm->setPropertyValue( evt.PropertyName, Any(nNewValue) );
1335 StartListening();
1340 bool bAdjustedPageSize = rEditor.AdjustPageSize();
1341 SetRectFromProps();
1342 std::vector<DlgEdObj*> const& aChildList = GetChildren();
1344 if ( bAdjustedPageSize )
1346 rEditor.InitScrollBars();
1347 aPageSize = rPage.GetSize();
1348 nPageWidthIn = aPageSize.Width();
1349 nPageHeightIn = aPageSize.Height();
1350 if ( TransformSdrToControlCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1352 for (auto const& child : aChildList)
1354 Reference< beans::XPropertySet > xPSet( child->GetUnoControlModel(), UNO_QUERY );
1355 if ( xPSet.is() )
1357 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1358 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
1359 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
1360 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
1361 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
1363 sal_Int32 nNewX = nX;
1364 if ( nX + nWidth > nPageX + nPageWidth )
1366 nNewX = nPageX + nPageWidth - nWidth;
1367 if ( nNewX < nPageX )
1368 nNewX = nPageX;
1370 if ( nNewX != nX )
1372 EndListening( false );
1373 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nNewX) );
1374 StartListening();
1377 sal_Int32 nNewY = nY;
1378 if ( nY + nHeight > nPageY + nPageHeight )
1380 nNewY = nPageY + nPageHeight - nHeight;
1381 if ( nNewY < nPageY )
1382 nNewY = nPageY;
1384 if ( nNewY != nY )
1386 EndListening( false );
1387 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nNewY) );
1388 StartListening();
1395 for (auto const& child : aChildList)
1396 child->SetRectFromProps();
1399 void DlgEdForm::UpdateStep()
1401 SdrPage* pSdrPage = getSdrPageFromSdrObject();
1403 if ( pSdrPage )
1405 for (const rtl::Reference<SdrObject>& pObj : *pSdrPage)
1407 DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pObj.get());
1408 if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
1409 pDlgEdObj->UpdateStep();
1414 void DlgEdForm::UpdateTabIndices()
1416 // stop listening with all children
1417 for (auto const& child : pChildren)
1419 child->EndListening( false );
1422 Reference< css::container::XNameAccess > xNameAcc( GetUnoControlModel() , UNO_QUERY );
1423 if ( xNameAcc.is() )
1425 // get sequence of control names
1426 // create a map of tab indices and control names, sorted by tab index
1427 IndexToNameMap aIndexToNameMap;
1428 for (auto& aName : xNameAcc->getElementNames())
1430 // get tab index
1431 sal_Int16 nTabIndex = -1;
1432 Any aCtrl = xNameAcc->getByName( aName );
1433 Reference< css::beans::XPropertySet > xPSet;
1434 aCtrl >>= xPSet;
1435 if ( xPSet.is() )
1436 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
1438 // insert into map
1439 aIndexToNameMap.emplace( nTabIndex, aName );
1442 // set new tab indices
1443 sal_Int16 nNewTabIndex = 0;
1444 for (auto const& indexToName : aIndexToNameMap)
1446 Any aCtrl = xNameAcc->getByName( indexToName.second );
1447 Reference< beans::XPropertySet > xPSet;
1448 aCtrl >>= xPSet;
1449 if ( xPSet.is() )
1451 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(nNewTabIndex) );
1452 nNewTabIndex++;
1456 UpdateTabOrderAndGroups();
1459 // start listening with all children
1460 for (auto const& child : pChildren)
1462 child->StartListening();
1466 void DlgEdForm::UpdateTabOrder()
1468 // When the tabindex of a control model changes, the dialog control is
1469 // notified about those changes. Due to #109067# (bad performance of
1470 // dialog editor) the dialog control doesn't activate the tab order
1471 // in design mode. When the dialog editor has reordered all
1472 // tabindices, this method allows to activate the taborder afterwards.
1474 Reference< awt::XUnoControlContainer > xCont( GetControl(), UNO_QUERY );
1475 if ( xCont.is() )
1477 for (auto& xTabController : xCont->getTabControllers())
1478 xTabController->activateTabOrder();
1482 void DlgEdForm::UpdateGroups()
1484 // The grouping of radio buttons in a dialog is done by vcl.
1485 // In the dialog editor we have two views (=controls) for one
1486 // radio button model. One control is owned by the dialog control,
1487 // but not visible in design mode. The other control is owned by
1488 // the drawing layer object. Whereas the grouping of the first
1489 // control is done by vcl, the grouping of the control in the
1490 // drawing layer has to be done here.
1492 Reference< awt::XTabControllerModel > xTabModel( GetUnoControlModel() , UNO_QUERY );
1493 if ( !xTabModel.is() )
1494 return;
1496 // create a global list of controls that belong to the dialog
1497 std::vector<DlgEdObj*> aChildList = GetChildren();
1498 sal_uInt32 nSize = aChildList.size();
1499 Sequence< Reference< awt::XControl > > aSeqControls( nSize );
1500 auto* pSeqControlsData = aSeqControls.getArray();
1501 for ( sal_uInt32 i = 0; i < nSize; ++i )
1502 pSeqControlsData[i] = aChildList[i]->GetControl();
1504 sal_Int32 nGroupCount = xTabModel->getGroupCount();
1505 for ( sal_Int32 nGroup = 0; nGroup < nGroupCount; ++nGroup )
1507 // get a list of control models that belong to this group
1508 OUString aName;
1509 Sequence< Reference< awt::XControlModel > > aSeqModels;
1510 xTabModel->getGroup( nGroup, aSeqModels, aName );
1511 sal_Int32 nModelCount = aSeqModels.getLength();
1513 // create a list of peers that belong to this group
1514 Sequence< Reference< awt::XWindow > > aSeqPeers( nModelCount );
1515 auto* pSeqPeersData = aSeqPeers.getArray();
1516 for ( sal_Int32 nModel = 0; nModel < nModelCount; ++nModel )
1518 // for each control model find the corresponding control in the global list
1519 for (auto& xCtrl : aSeqControls)
1521 if ( xCtrl.is() )
1523 Reference< awt::XControlModel > xCtrlModel( xCtrl->getModel() );
1524 if (xCtrlModel.get() == aSeqModels[nModel].get())
1526 // get the control peer and insert into the list of peers
1527 pSeqPeersData[nModel].set(xCtrl->getPeer(), UNO_QUERY);
1528 break;
1534 // set the group at the dialog peer
1535 Reference< awt::XControl > xDlg = GetControl();
1536 if ( xDlg.is() )
1538 Reference< awt::XVclContainerPeer > xDlgPeer( xDlg->getPeer(), UNO_QUERY );
1539 if ( xDlgPeer.is() )
1540 xDlgPeer->setGroup( aSeqPeers );
1545 void DlgEdForm::UpdateTabOrderAndGroups()
1547 UpdateTabOrder();
1548 UpdateGroups();
1551 void DlgEdForm::NbcMove( const Size& rSize )
1553 SdrUnoObj::NbcMove( rSize );
1555 // set geometry properties of form
1556 EndListening(false);
1557 SetPropsFromRect();
1558 StartListening();
1560 // set geometry properties of all children
1561 for (auto const& child : pChildren)
1563 child->EndListening(false);
1564 child->SetPropsFromRect();
1565 child->StartListening();
1568 // dialog model changed
1569 GetDlgEditor().SetDialogModelChanged();
1572 void DlgEdForm::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
1574 SdrUnoObj::NbcResize( rRef, xFract, yFract );
1576 // set geometry properties of form
1577 EndListening(false);
1578 SetPropsFromRect();
1579 StartListening();
1581 // set geometry properties of all children
1582 for (auto const& child : pChildren)
1584 child->EndListening(false);
1585 child->SetPropsFromRect();
1586 child->StartListening();
1589 // dialog model changed
1590 GetDlgEditor().SetDialogModelChanged();
1593 bool DlgEdForm::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1595 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
1597 // stop listening
1598 EndListening(false);
1600 // set geometry properties
1601 SetPropsFromRect();
1603 // dialog model changed
1604 GetDlgEditor().SetDialogModelChanged();
1606 // start listening
1607 StartListening();
1609 return bResult;
1612 awt::DeviceInfo DlgEdForm::getDeviceInfo() const
1614 awt::DeviceInfo aDeviceInfo;
1616 DlgEditor& rEditor = GetDlgEditor();
1617 vcl::Window& rWindow = rEditor.GetWindow();
1619 // obtain an XControl
1620 ::utl::SharedUNOComponent< awt::XControl > xDialogControl; // ensures auto-disposal, if needed
1621 xDialogControl.reset( GetControl(), ::utl::SharedUNOComponent< awt::XControl >::NoTakeOwnership );
1622 if ( !xDialogControl.is() )
1624 // don't create a temporary control all the time, this method here is called
1625 // way too often. Instead, use a cached DeviceInfo.
1626 // #i74065#
1627 if ( !!mpDeviceInfo )
1628 return *mpDeviceInfo;
1630 Reference< awt::XControlContainer > xEditorControlContainer( rEditor.GetWindowControlContainer() );
1631 xDialogControl.reset(
1632 GetTemporaryControlForWindow(rWindow, xEditorControlContainer),
1633 utl::SharedUNOComponent< awt::XControl >::TakeOwnership
1637 Reference< awt::XDevice > xDialogDevice;
1638 if ( xDialogControl.is() )
1639 xDialogDevice.set( xDialogControl->getPeer(), UNO_QUERY );
1640 DBG_ASSERT( xDialogDevice.is(), "DlgEdForm::getDeviceInfo: no device!" );
1641 if ( xDialogDevice.is() )
1642 aDeviceInfo = xDialogDevice->getInfo();
1644 mpDeviceInfo = aDeviceInfo;
1646 return aDeviceInfo;
1648 void DlgEdObj::MakeDataAware( const Reference< frame::XModel >& xModel )
1650 // Need to flesh this out, currently we will only support data-aware controls for calc
1651 // and only handle a subset of functionality e.g. linked-cell and cell range data source. Of course later
1652 // we need to disambiguate for writer ( and others ? ) and also support the generic form (db) bindings
1653 // we need some more work in xmlscript to be able to handle that
1654 Reference< lang::XMultiServiceFactory > xFac( xModel, UNO_QUERY );
1655 Reference< form::binding::XBindableValue > xBindable( GetUnoControlModel(), UNO_QUERY );
1656 Reference< form::binding::XListEntrySink > xListEntrySink( GetUnoControlModel(), UNO_QUERY );
1657 if ( !xFac.is() )
1658 return;
1660 //tdf#90361 and tdf#104011 CellValueBinding and CellRangeListSource are unusable
1661 //without being initialized, so use createInstanceWithArguments with a
1662 //dummy BoundCell and CellRange instead of createInstance. This at least results in
1663 //the dialog editor not falling.
1664 css::beans::NamedValue aCellValue;
1665 aCellValue.Name = "BoundCell";
1666 css::table::CellAddress aCellAddress;
1667 aCellValue.Value <<= aCellAddress;
1669 css::beans::NamedValue aCellRange;
1670 aCellRange.Name = "CellRange";
1671 css::table::CellRangeAddress aRangeAddress;
1672 aCellRange.Value <<= aRangeAddress;
1674 Sequence< Any > aArgs{ Any(aCellValue), Any(aCellRange) };
1676 if ( xBindable.is() )
1678 Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( u"com.sun.star.table.CellValueBinding"_ustr, aArgs ), UNO_QUERY );
1679 xBindable->setValueBinding( xBinding );
1681 if ( xListEntrySink.is() )
1683 Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( u"com.sun.star.table.CellRangeListSource"_ustr, aArgs ), UNO_QUERY );
1684 xListEntrySink->setListEntrySource( xSource );
1687 } // namespace basctl
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */