android: Update app-specific/MIME type icons
[LibreOffice.git] / cui / source / tabpages / transfrm.cxx
blob05fd9e56704f5b3dfc0d8753edcac721b304d68d
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>
22 #include <algorithm>
24 #include <svx/EnhancedCustomShape2d.hxx>
25 #include <svx/sdangitm.hxx>
26 #include <svx/svdundo.hxx>
27 #include <svx/svdview.hxx>
28 #include <svx/svdobj.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/svdoashp.hxx>
31 #include <svx/sderitm.hxx>
32 #include <svx/svxids.hrc>
33 #include <svx/transfrmhelper.hxx>
34 #include <svtools/unitconv.hxx>
36 #include <transfrm.hxx>
37 #include <svx/dlgutil.hxx>
38 #include <svx/anchorid.hxx>
39 #include <svl/rectitem.hxx>
40 #include <swpossizetabpage.hxx>
41 #include <vcl/canvastools.hxx>
42 #include <vcl/fieldvalues.hxx>
44 // static ----------------------------------------------------------------
46 const WhichRangesContainer SvxPositionSizeTabPage::pPosSizeRanges(svl::Items<
47 SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
48 SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
49 SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
50 SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_AUTOHEIGHT,
51 SID_ATTR_TRANSFORM_ANCHOR, SID_ATTR_TRANSFORM_VERT_ORIENT
52 >);
54 const WhichRangesContainer SvxAngleTabPage::pAngleRanges(svl::Items<
55 SID_ATTR_TRANSFORM_ROT_X, SID_ATTR_TRANSFORM_ANGLE,
56 SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN
57 >);
59 const WhichRangesContainer SvxSlantTabPage::pSlantRanges(svl::Items<
60 SDRATTR_CORNER_RADIUS, SDRATTR_CORNER_RADIUS,
61 SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN,
62 SID_ATTR_TRANSFORM_SHEAR, SID_ATTR_TRANSFORM_SHEAR_VERTICAL
63 >);
65 /*************************************************************************
67 |* constructor of the tab dialog: adds the pages to the dialog
69 \************************************************************************/
71 SvxTransformTabDialog::SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
72 const SdrView* pSdrView, SvxAnchorIds nAnchorTypes)
73 : SfxTabDialogController(pParent, "cui/ui/positionsizedialog.ui", "PositionAndSizeDialog", pAttr)
74 , pView(pSdrView)
75 , nAnchorCtrls(nAnchorTypes)
77 DBG_ASSERT(pView, "no valid view (!)");
79 //different positioning page in Writer
80 if(nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
82 AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create, SvxSwPosSizeTabPage::GetRanges);
83 RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
85 else
87 AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create, SvxPositionSizeTabPage::GetRanges);
88 RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
91 AddTabPage("RID_SVXPAGE_ANGLE", SvxAngleTabPage::Create, SvxAngleTabPage::GetRanges);
92 AddTabPage("RID_SVXPAGE_SLANT", SvxSlantTabPage::Create, SvxSlantTabPage::GetRanges);
96 void SvxTransformTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
98 if (rId == "RID_SVXPAGE_POSITION_SIZE")
100 SvxPositionSizeTabPage& rSvxPos = static_cast<SvxPositionSizeTabPage&>(rPage);
101 rSvxPos.SetView(pView);
102 rSvxPos.Construct();
104 if(nAnchorCtrls & SvxAnchorIds::NoResize)
106 rSvxPos.DisableResize();
109 if(nAnchorCtrls & SvxAnchorIds::NoProtect)
111 rSvxPos.DisableProtect();
112 rSvxPos.UpdateControlStates();
115 else if (rId == "RID_SVXPAGE_SWPOSSIZE")
117 SvxSwPosSizeTabPage& rSwPos = static_cast<SvxSwPosSizeTabPage&>(rPage);
119 rSwPos.EnableAnchorTypes(nAnchorCtrls);
120 rSwPos.SetValidateFramePosLink(aValidateLink);
121 rSwPos.SetView(pView);
123 else if (rId == "RID_SVXPAGE_ANGLE")
125 SvxAngleTabPage& rSvxAng = static_cast<SvxAngleTabPage&>(rPage);
127 rSvxAng.SetView( pView );
128 rSvxAng.Construct();
130 else if (rId == "RID_SVXPAGE_SLANT")
132 SvxSlantTabPage& rSvxSlnt = static_cast<SvxSlantTabPage&>(rPage);
134 rSvxSlnt.SetView( pView );
135 rSvxSlnt.Construct();
139 void SvxTransformTabDialog::SetValidateFramePosLink(const Link<SvxSwFrameValidation&,void>& rLink)
141 aValidateLink = rLink;
144 /*************************************************************************
146 |* dialog for changing the positions of the rotation
147 |* angle and the rotation angle of the graphic objects
149 \************************************************************************/
150 SvxAngleTabPage::SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
151 : SvxTabPage(pPage, pController, "cui/ui/rotationtabpage.ui", "Rotation", rInAttrs)
152 , pView(nullptr)
153 , eDlgUnit(FieldUnit::NONE)
154 , m_aCtlRect(this)
155 , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
156 , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
157 , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
158 , m_xCtlRect(new weld::CustomWeld(*m_xBuilder, "CTL_RECT", m_aCtlRect))
159 , m_xFlAngle(m_xBuilder->weld_widget("FL_ANGLE"))
160 , m_xNfAngle(m_xBuilder->weld_metric_spin_button("NF_ANGLE", FieldUnit::DEGREE))
161 , m_xCtlAngle(new svx::DialControl)
162 , m_xCtlAngleWin(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", *m_xCtlAngle))
164 // calculate PoolUnit
165 SfxItemPool* pPool = rInAttrs.GetPool();
166 DBG_ASSERT( pPool, "no pool (!)" );
167 ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X);
169 m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
172 SvxAngleTabPage::~SvxAngleTabPage()
176 void SvxAngleTabPage::Construct()
178 DBG_ASSERT(pView, "No valid view (!)");
179 eDlgUnit = GetModuleFieldUnit(GetItemSet());
180 SetFieldUnit(*m_xMtrPosX, eDlgUnit, true);
181 SetFieldUnit(*m_xMtrPosY, eDlgUnit, true);
183 if (FieldUnit::MILE == eDlgUnit || FieldUnit::KM == eDlgUnit)
185 m_xMtrPosX->set_digits(3);
186 m_xMtrPosY->set_digits(3);
189 { // #i75273#
190 ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
191 pView->GetSdrPageView()->LogicToPagePos(aTempRect);
192 maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
195 // Take anchor into account (Writer)
196 const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
198 if(rMarkList.GetMarkCount())
200 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
201 maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
203 if(!maAnchor.equalZero()) // -> Writer
205 maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
209 // take scale into account
210 const Fraction aUIScale(pView->GetModel().GetUIScale());
211 TransfrmHelper::ScaleRect(maRange, aUIScale);
213 // take UI units into account
214 sal_uInt16 nDigits(m_xMtrPosX->get_digits());
215 TransfrmHelper::ConvertRect(maRange, nDigits, ePoolUnit, eDlgUnit);
217 if(!pView->IsRotateAllowed())
219 m_xFlPosition->set_sensitive(false);
220 m_xFlAngle->set_sensitive(false);
224 bool SvxAngleTabPage::FillItemSet(SfxItemSet* rSet)
226 bool bModified = false;
228 if (m_xCtlAngle->IsValueModified() || m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
230 const double fUIScale(double(pView->GetModel().GetUIScale()));
231 const double fTmpX((GetCoreValue(*m_xMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale);
232 const double fTmpY((GetCoreValue(*m_xMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale);
234 rSet->Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, m_xCtlAngle->GetRotation()));
235 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(fTmpX)));
236 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(fTmpY)));
238 bModified = true;
241 return bModified;
245 void SvxAngleTabPage::Reset(const SfxItemSet* rAttrs)
247 const double fUIScale(double(pView->GetModel().GetUIScale()));
249 const SfxPoolItem* pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ROT_X );
250 if(pItem)
252 const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getX()) / fUIScale);
253 SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), ePoolUnit);
255 else
257 m_xMtrPosX->set_text(OUString());
260 pItem = GetItem(*rAttrs, SID_ATTR_TRANSFORM_ROT_Y);
261 if(pItem)
263 const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getY()) / fUIScale);
264 SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), ePoolUnit);
266 else
268 m_xMtrPosY->set_text(OUString());
271 pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ANGLE );
272 if(pItem)
274 m_xCtlAngle->SetRotation(static_cast<const SdrAngleItem*>(pItem)->GetValue());
276 else
278 m_xCtlAngle->SetRotation(0_deg100);
280 m_xCtlAngle->SaveValue();
281 m_xMtrPosX->save_value();
282 m_xMtrPosY->save_value();
285 std::unique_ptr<SfxTabPage> SvxAngleTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
287 return std::make_unique<SvxAngleTabPage>(pPage, pController, *rSet);
290 void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet)
292 if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
294 m_xFlPosition->set_sensitive(!bPosProtect->GetValue());
295 m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
299 DeactivateRC SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet )
301 if(_pSet)
303 FillItemSet(_pSet);
306 return DeactivateRC::LeavePage;
309 void SvxAngleTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
311 if (pDrawingArea != m_aCtlRect.GetDrawingArea())
312 return;
314 switch(eRP)
316 case RectPoint::LT:
318 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
319 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
320 break;
322 case RectPoint::MT:
324 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
325 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
326 break;
328 case RectPoint::RT:
330 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
331 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
332 break;
334 case RectPoint::LM:
336 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
337 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
338 break;
340 case RectPoint::MM:
342 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
343 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
344 break;
346 case RectPoint::RM:
348 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
349 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
350 break;
352 case RectPoint::LB:
354 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
355 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
356 break;
358 case RectPoint::MB:
360 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
361 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
362 break;
364 case RectPoint::RB:
366 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
367 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
368 break;
373 /*************************************************************************
375 |* dialog for changing slant and corner radius
377 \************************************************************************/
378 SvxSlantTabPage::SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
379 : SfxTabPage(pPage, pController, "cui/ui/slantcornertabpage.ui", "SlantAndCornerRadius", &rInAttrs)
380 , pView(nullptr)
381 , eDlgUnit(FieldUnit::NONE)
382 , m_xFlRadius(m_xBuilder->weld_widget("FL_RADIUS"))
383 , m_xMtrRadius(m_xBuilder->weld_metric_spin_button("MTR_FLD_RADIUS", FieldUnit::CM))
384 , m_xFlAngle(m_xBuilder->weld_widget("FL_SLANT"))
385 , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("MTR_FLD_ANGLE", FieldUnit::DEGREE))
387 for (int i = 0; i < 2; ++i)
389 m_aControlGroups[i] = m_xBuilder->weld_widget("controlgroups" + OUString::number(i+1));
390 m_aControlGroupX[i] = m_xBuilder->weld_widget("controlgroupx" + OUString::number(i+1));
391 m_aControlX[i] = m_xBuilder->weld_metric_spin_button("controlx" + OUString::number(i+1), FieldUnit::CM);
392 m_aControlGroupY[i] = m_xBuilder->weld_widget("controlgroupy" + OUString::number(i+1));
393 m_aControlY[i] = m_xBuilder->weld_metric_spin_button("controly" + OUString::number(i+1), FieldUnit::CM);
396 // this page needs ExchangeSupport
397 SetExchangeSupport();
399 // evaluate PoolUnit
400 SfxItemPool* pPool = rInAttrs.GetPool();
401 assert(pPool && "no pool (!)");
402 ePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
405 SvxSlantTabPage::~SvxSlantTabPage()
409 void SvxSlantTabPage::Construct()
411 // get the range
412 DBG_ASSERT(pView, "no valid view (!)");
413 eDlgUnit = GetModuleFieldUnit(GetItemSet());
414 SetFieldUnit(*m_xMtrRadius, eDlgUnit, true);
415 for (int i = 0; i < 2; ++i)
417 SetFieldUnit(*m_aControlX[i], eDlgUnit, true);
418 SetFieldUnit(*m_aControlY[i], eDlgUnit, true);
421 { // #i75273#
422 ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
423 pView->GetSdrPageView()->LogicToPagePos(aTempRect);
427 bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
429 bool bModified = false;
431 if (m_xMtrRadius->get_value_changed_from_saved())
433 Fraction aUIScale = pView->GetModel().GetUIScale();
434 tools::Long nTmp = tools::Long(GetCoreValue(*m_xMtrRadius, ePoolUnit) * aUIScale);
436 rAttrs->Put( makeSdrEckenradiusItem( nTmp ) );
437 bModified = true;
440 if (m_xMtrAngle->get_value_changed_from_saved())
442 sal_Int32 nValue = static_cast<sal_Int32>(m_xMtrAngle->get_value(FieldUnit::NONE));
443 rAttrs->Put( SdrAngleItem( SID_ATTR_TRANSFORM_SHEAR, Degree100(nValue) ) );
444 bModified = true;
447 if( bModified )
449 // set reference points
450 ::tools::Rectangle aObjectRect(pView->GetAllMarkedRect());
451 pView->GetSdrPageView()->LogicToPagePos(aObjectRect);
452 Point aPt = aObjectRect.Center();
454 rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X, aPt.X()));
455 rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y, aPt.Y()));
456 rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) );
459 bool bControlPointsChanged = false;
460 for (int i = 0; i < 2; ++i)
462 bControlPointsChanged |= (m_aControlX[i]->get_value_changed_from_saved() ||
463 m_aControlY[i]->get_value_changed_from_saved());
466 if (!bControlPointsChanged)
467 return bModified;
469 bool bSelectionIsSdrObjCustomShape(false);
471 while(true)
473 if(nullptr == pView)
475 break;
478 if(0 == pView->GetMarkedObjectList().GetMarkCount())
480 break;
483 SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
485 if(nullptr == pCandidate)
487 break;
490 if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
492 break;
495 bSelectionIsSdrObjCustomShape = true;
496 break;
499 if(bSelectionIsSdrObjCustomShape)
501 SdrObjCustomShape& rSdrObjCustomShape(
502 static_cast< SdrObjCustomShape& >(
503 *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
504 SdrModel& rModel(rSdrObjCustomShape.getSdrModelFromSdrObject());
505 std::unique_ptr<SdrUndoAction> pUndo;
506 if (rModel.IsUndoEnabled())
507 pUndo = rModel.GetSdrUndoFactory().CreateUndoAttrObject(rSdrObjCustomShape);
509 if(pUndo)
511 rModel.BegUndo(pUndo->GetComment());
514 EnhancedCustomShape2d aShape(rSdrObjCustomShape);
515 ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
517 for (int i = 0; i < 2; ++i)
519 if (m_aControlX[i]->get_value_changed_from_saved() || m_aControlY[i]->get_value_changed_from_saved())
521 Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
522 GetCoreValue(*m_aControlY[i], ePoolUnit));
523 aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
525 css::awt::Point aPosition;
526 aPosition.X = aNewPosition.X();
527 aPosition.Y = aNewPosition.Y();
529 aShape.SetHandleControllerPosition(i, aPosition);
533 rSdrObjCustomShape.SetChanged();
534 rSdrObjCustomShape.BroadcastObjectChange();
535 bModified = true;
537 if (pUndo)
539 rModel.AddUndo(std::move(pUndo));
540 rModel.EndUndo();
544 return bModified;
547 void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
549 // if the view has selected objects, items with SfxItemState::DEFAULT need to be disabled
550 const SfxPoolItem* pItem;
552 // corner radius
553 if(!pView->IsEdgeRadiusAllowed())
555 m_xMtrRadius->set_text("");
556 m_xFlRadius->set_sensitive(false);
558 else
560 pItem = GetItem( *rAttrs, SDRATTR_CORNER_RADIUS );
562 if( pItem )
564 const double fUIScale(double(pView->GetModel().GetUIScale()));
565 const double fTmp(static_cast<double>(static_cast<const SdrMetricItem*>(pItem)->GetValue()) / fUIScale);
566 SetMetricValue(*m_xMtrRadius, basegfx::fround(fTmp), ePoolUnit);
568 else
570 m_xMtrRadius->set_text("");
574 m_xMtrRadius->save_value();
576 // slant: angle
577 if( !pView->IsShearAllowed() )
579 m_xMtrAngle->set_text( "" );
580 m_xFlAngle->set_sensitive(false);
582 else
584 pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_SHEAR );
586 if( pItem )
588 m_xMtrAngle->set_value(static_cast<const SdrAngleItem*>(pItem)->GetValue().get(), FieldUnit::NONE);
590 else
592 m_xMtrAngle->set_text("");
596 m_xMtrAngle->save_value();
598 bool bSelectionIsSdrObjCustomShape(false);
600 while(true)
602 if(1 != pView->GetMarkedObjectList().GetMarkCount())
604 break;
607 SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
609 if(nullptr == pCandidate)
611 break;
614 if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
616 break;
619 bSelectionIsSdrObjCustomShape = true;
620 break;
623 if(bSelectionIsSdrObjCustomShape)
625 SdrObjCustomShape& rSdrObjCustomShape(
626 static_cast< SdrObjCustomShape& >(
627 *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
629 //save geometry
630 const bool bOrigModelChangeState = pView->GetModel().IsChanged();
631 SdrCustomShapeGeometryItem aInitialGeometry(rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
632 EnhancedCustomShape2d aShape(rSdrObjCustomShape);
634 for (int i = 0; i < 2; ++i)
636 Point aInitialPosition;
637 if (!aShape.GetHandlePosition(i, aInitialPosition))
638 break;
639 m_aControlGroups[i]->set_sensitive(true);
640 css::awt::Point aPosition;
642 aPosition.X = SAL_MAX_INT32/2;
643 aPosition.Y = SAL_MAX_INT32/2;
644 aShape.SetHandleControllerPosition(i, aPosition);
645 Point aMaxPosition;
646 aShape.GetHandlePosition(i, aMaxPosition);
648 aPosition.X = SAL_MIN_INT32/2;
649 aPosition.Y = SAL_MIN_INT32/2;
650 aShape.SetHandleControllerPosition(i, aPosition);
651 Point aMinPosition;
652 aShape.GetHandlePosition(i, aMinPosition);
654 ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
655 aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
656 aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
657 aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
659 SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
660 SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
662 if (aMaxPosition.X() == aMinPosition.X())
663 m_aControlGroupX[i]->set_sensitive(false);
664 else
665 m_aControlX[i]->set_range(aMinPosition.X(), aMaxPosition.X(), FieldUnit::MM);
666 if (aMaxPosition.Y() == aMinPosition.Y())
667 m_aControlGroupY[i]->set_sensitive(false);
668 else
669 m_aControlY[i]->set_range(aMinPosition.Y(), aMaxPosition.Y(), FieldUnit::MM);
672 //restore geometry
673 rSdrObjCustomShape.SetMergedItem(aInitialGeometry);
674 pView->GetModel().SetChanged(bOrigModelChangeState);
677 for (int i = 0; i < 2; ++i)
679 m_aControlX[i]->save_value();
680 m_aControlY[i]->save_value();
684 std::unique_ptr<SfxTabPage> SvxSlantTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
686 return std::make_unique<SvxSlantTabPage>(pPage, pController, *rOutAttrs);
689 void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
691 if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
693 m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
695 if(SfxBoolItem const * bSizeProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_SIZE, false ))
697 m_xFlAngle->set_sensitive(!bSizeProtect->GetValue());
702 DeactivateRC SvxSlantTabPage::DeactivatePage( SfxItemSet* _pSet )
704 if(_pSet)
706 FillItemSet(_pSet);
709 return DeactivateRC::LeavePage;
713 /*************************************************************************
715 |* Dialog for changing position and size of graphic objects
717 \************************************************************************/
718 SvxPositionSizeTabPage::SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
719 : SvxTabPage(pPage, pController, "cui/ui/possizetabpage.ui", "PositionAndSize", rInAttrs)
720 , mrOutAttrs(rInAttrs)
721 , mpView(nullptr)
722 , meDlgUnit(FieldUnit::NONE)
723 , mnProtectSizeState(TRISTATE_FALSE)
724 , mbPageDisabled(false)
725 , mbProtectDisabled(false)
726 , mbSizeDisabled(false)
727 , mbAdjustDisabled(true)
728 , mbIgnoreAutoGrowWidth(true)
729 , mbIgnoreAutoGrowHeight(true)
730 , mfOldWidth(0.0)
731 , mfOldHeight(0.0)
732 , m_aCtlPos(this)
733 , m_aCtlSize(this)
734 , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
735 , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
736 , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
737 , m_xCtlPos(new weld::CustomWeld(*m_xBuilder, "CTL_POSRECT", m_aCtlPos))
738 , m_xFlSize(m_xBuilder->weld_widget("FL_SIZE"))
739 , m_xFtWidth(m_xBuilder->weld_label("FT_WIDTH"))
740 , m_xMtrWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_WIDTH", FieldUnit::CM))
741 , m_xFtHeight(m_xBuilder->weld_label("FT_HEIGHT"))
742 , m_xMtrHeight(m_xBuilder->weld_metric_spin_button("MTR_FLD_HEIGHT", FieldUnit::CM))
743 , m_xCbxScale(m_xBuilder->weld_check_button("CBX_SCALE"))
744 , m_xCtlSize(new weld::CustomWeld(*m_xBuilder, "CTL_SIZERECT", m_aCtlSize))
745 , m_xFlProtect(m_xBuilder->weld_widget("FL_PROTECT"))
746 , m_xTsbPosProtect(m_xBuilder->weld_check_button("TSB_POSPROTECT"))
747 , m_xTsbSizeProtect(m_xBuilder->weld_check_button("TSB_SIZEPROTECT"))
748 , m_xFlAdjust(m_xBuilder->weld_widget("FL_ADJUST"))
749 , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
750 , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
752 // this page needs ExchangeSupport
753 SetExchangeSupport();
755 // evaluate PoolUnit
756 SfxItemPool* pPool = mrOutAttrs.GetPool();
757 DBG_ASSERT( pPool, "no pool (!)" );
758 mePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
760 m_aCtlPos.SetActualRP(RectPoint::LT);
761 m_aCtlSize.SetActualRP(RectPoint::LT);
762 meRP = RectPoint::LT; // see above
764 m_xMtrWidth->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeWidthHdl ) );
765 m_xMtrHeight->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeHeightHdl ) );
766 m_xCbxScale->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickAutoHdl ) );
768 m_xFlAdjust->set_sensitive(false);
770 // #i2379# disable controls when protected
771 m_xTsbPosProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangePosProtectHdl ) );
772 m_xTsbSizeProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangeSizeProtectHdl ) );
775 SvxPositionSizeTabPage::~SvxPositionSizeTabPage()
779 void SvxPositionSizeTabPage::Construct()
781 // get range and work area
782 DBG_ASSERT( mpView, "no valid view (!)" );
783 meDlgUnit = GetModuleFieldUnit( GetItemSet() );
784 SetFieldUnit( *m_xMtrPosX, meDlgUnit, true );
785 SetFieldUnit( *m_xMtrPosY, meDlgUnit, true );
786 SetFieldUnit( *m_xMtrWidth, meDlgUnit, true );
787 SetFieldUnit( *m_xMtrHeight, meDlgUnit, true );
789 if(FieldUnit::MILE == meDlgUnit || FieldUnit::KM == meDlgUnit)
791 m_xMtrPosX->set_digits( 3 );
792 m_xMtrPosY->set_digits( 3 );
793 m_xMtrWidth->set_digits( 3 );
794 m_xMtrHeight->set_digits( 3 );
797 { // #i75273#
798 ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
799 mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
800 maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
803 { // #i75273#
804 ::tools::Rectangle aTempRect(mpView->GetWorkArea());
805 mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
806 maWorkRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
809 // take anchor into account (Writer)
810 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
812 if(rMarkList.GetMarkCount())
814 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
815 maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
817 if(!maAnchor.equalZero()) // -> Writer
819 for(size_t i = 1; i < rMarkList.GetMarkCount(); ++i)
821 pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
823 if(maAnchor != basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y()))
825 // different anchor positions
826 m_xMtrPosX->set_text("");
827 m_xMtrPosY->set_text("");
828 mbPageDisabled = true;
829 return;
833 // translate ranges about anchor
834 maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
835 maWorkRange = basegfx::B2DRange(maWorkRange.getMinimum() - maAnchor, maWorkRange.getMaximum() - maAnchor);
839 // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
840 if(1 == rMarkList.GetMarkCount())
842 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
843 const SdrObjKind eKind(pObj->GetObjIdentifier());
845 if((pObj->GetObjInventor() == SdrInventor::Default) &&
846 (SdrObjKind::Text == eKind || SdrObjKind::TitleText == eKind || SdrObjKind::OutlineText == eKind) &&
847 pObj->HasText())
849 mbAdjustDisabled = false;
851 m_xFlAdjust->set_sensitive(true);
853 m_xTsbAutoGrowWidth->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
854 m_xTsbAutoGrowHeight->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
856 // is used as flag to evaluate if it's selectable
857 mbIgnoreAutoGrowWidth = false;
858 mbIgnoreAutoGrowHeight = false;
862 // take scale into account
863 const Fraction aUIScale(mpView->GetModel().GetUIScale());
864 TransfrmHelper::ScaleRect( maWorkRange, aUIScale );
865 TransfrmHelper::ScaleRect( maRange, aUIScale );
867 // take UI units into account
868 const sal_uInt16 nDigits(m_xMtrPosX->get_digits());
869 TransfrmHelper::ConvertRect( maWorkRange, nDigits, mePoolUnit, meDlgUnit );
870 TransfrmHelper::ConvertRect( maRange, nDigits, mePoolUnit, meDlgUnit );
872 SetMinMaxPosition();
876 bool SvxPositionSizeTabPage::FillItemSet( SfxItemSet* rOutAttrs )
878 bool bModified(false);
880 if ( m_xMtrWidth->has_focus() )
882 ChangeWidthHdl( *m_xMtrWidth );
885 if ( m_xMtrHeight->has_focus() )
887 ChangeHeightHdl( *m_xMtrHeight );
890 if( !mbPageDisabled )
892 if (m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
894 const double fUIScale(double(mpView->GetModel().GetUIScale()));
895 double fX((GetCoreValue( *m_xMtrPosX, mePoolUnit ) + maAnchor.getX()) * fUIScale);
896 double fY((GetCoreValue( *m_xMtrPosY, mePoolUnit ) + maAnchor.getY()) * fUIScale);
898 { // #i75273#
899 ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
900 mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
901 maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
904 // #101581# GetTopLeftPosition(...) needs coordinates after UI scaling, in real PagePositions
905 GetTopLeftPosition(fX, fY, maRange);
907 rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X, basegfx::fround(fX)));
908 rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y, basegfx::fround(fY)));
910 bModified = true;
913 if (m_xTsbPosProtect->get_state_changed_from_saved())
915 if( m_xTsbPosProtect->get_inconsistent() )
917 rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
919 else
921 rOutAttrs->Put(
922 SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
923 m_xTsbPosProtect->get_active() ) );
926 bModified = true;
930 if (m_xMtrWidth->get_value_changed_from_saved() || m_xMtrHeight->get_value_changed_from_saved())
932 Fraction aUIScale = mpView->GetModel().GetUIScale();
934 // get Width
935 double nWidth = static_cast<double>(m_xMtrWidth->get_value(FieldUnit::MM_100TH));
936 tools::Long lWidth = tools::Long(nWidth * static_cast<double>(aUIScale));
937 lWidth = OutputDevice::LogicToLogic( lWidth, MapUnit::Map100thMM, mePoolUnit );
938 lWidth = static_cast<tools::Long>(m_xMtrWidth->denormalize( lWidth ));
940 // get Height
941 double nHeight = static_cast<double>(m_xMtrHeight->get_value(FieldUnit::MM_100TH));
942 tools::Long lHeight = tools::Long(nHeight * static_cast<double>(aUIScale));
943 lHeight = OutputDevice::LogicToLogic( lHeight, MapUnit::Map100thMM, mePoolUnit );
944 lHeight = static_cast<tools::Long>(m_xMtrHeight->denormalize( lHeight ));
946 // put Width & Height to itemset
947 rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, static_cast<sal_uInt32>(lWidth) ) );
948 rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, static_cast<sal_uInt32>(lHeight) ) );
949 rOutAttrs->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal::static_int_cast< sal_uInt16 >( meRP ) ) );
950 bModified = true;
953 if (m_xTsbSizeProtect->get_state_changed_from_saved())
955 if ( m_xTsbSizeProtect->get_inconsistent() )
956 rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
957 else
958 rOutAttrs->Put(
959 SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
960 m_xTsbSizeProtect->get_active() ) );
961 bModified = true;
964 if (m_xTsbAutoGrowWidth->get_state_changed_from_saved())
966 if (!mbIgnoreAutoGrowWidth)
968 if( m_xTsbAutoGrowWidth->get_inconsistent() )
969 rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOWIDTH );
970 else
971 rOutAttrs->Put(
972 SfxBoolItem( SID_ATTR_TRANSFORM_AUTOWIDTH,
973 m_xTsbAutoGrowWidth->get_active() ) );
975 bModified = true;
978 if (m_xTsbAutoGrowHeight->get_state_changed_from_saved())
980 if (!mbIgnoreAutoGrowHeight)
982 if (m_xTsbAutoGrowHeight->get_inconsistent())
984 rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOHEIGHT );
986 else
988 rOutAttrs->Put(
989 SfxBoolItem( SID_ATTR_TRANSFORM_AUTOHEIGHT,
990 m_xTsbAutoGrowHeight->get_active() ) );
993 bModified = true;
996 return bModified;
999 void SvxPositionSizeTabPage::Reset( const SfxItemSet* )
1001 const SfxPoolItem* pItem;
1002 const double fUIScale(double(mpView->GetModel().GetUIScale()));
1004 if ( !mbPageDisabled )
1006 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_X );
1007 if ( pItem )
1009 const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getX()) / fUIScale);
1010 SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), mePoolUnit);
1013 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_Y );
1014 if ( pItem )
1016 const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getY()) / fUIScale);
1017 SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), mePoolUnit);
1020 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_POS );
1021 if ( pItem )
1023 bool bProtected = static_cast<const SfxBoolItem*>( pItem )->GetValue();
1024 m_xTsbPosProtect->set_active(bProtected);
1026 else
1028 m_xTsbPosProtect->set_inconsistent(true);
1031 m_xTsbPosProtect->save_state();
1032 m_aCtlPos.Reset();
1034 // #i2379# Disable controls for protected objects
1035 ChangePosProtectHdl(*m_xTsbPosProtect);
1038 { // #i75273# set width
1039 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_WIDTH );
1040 mfOldWidth = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
1041 double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldWidth), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
1042 if (m_xMtrWidth->get_digits())
1043 fTmpWidth *= pow(10.0, m_xMtrWidth->get_digits());
1044 m_xMtrWidth->set_value(fTmpWidth, FieldUnit::MM_100TH);
1047 { // #i75273# set height
1048 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_HEIGHT );
1049 mfOldHeight = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
1050 double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldHeight), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
1051 if (m_xMtrHeight->get_digits())
1052 fTmpHeight *= pow(10.0, m_xMtrHeight->get_digits());
1053 m_xMtrHeight->set_value(fTmpHeight, FieldUnit::MM_100TH);
1056 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_SIZE );
1057 if ( pItem )
1059 m_xTsbSizeProtect->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1061 else
1062 m_xTsbSizeProtect->set_inconsistent(true);
1064 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOWIDTH );
1065 if ( pItem )
1067 m_xTsbAutoGrowWidth->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
1069 else
1070 m_xTsbAutoGrowWidth->set_inconsistent(true);
1072 pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOHEIGHT );
1073 if ( pItem )
1075 m_xTsbAutoGrowHeight->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
1077 else
1078 m_xTsbAutoGrowHeight->set_inconsistent(true);
1080 // Is matching set?
1081 OUString aStr = GetUserData();
1082 m_xCbxScale->set_active(aStr.toInt32() != 0);
1084 m_xMtrPosX->save_value();
1085 m_xMtrPosY->save_value();
1086 m_xMtrWidth->save_value();
1087 m_xMtrHeight->save_value();
1089 m_xTsbSizeProtect->save_state();
1090 m_xTsbAutoGrowWidth->save_state();
1091 m_xTsbAutoGrowHeight->save_state();
1092 ClickSizeProtectHdl(*m_xTsbAutoGrowHeight);
1094 // #i2379# Disable controls for protected objects
1095 ChangeSizeProtectHdl(*m_xTsbSizeProtect);
1098 std::unique_ptr<SfxTabPage> SvxPositionSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
1100 return std::make_unique<SvxPositionSizeTabPage>(pPage, pController, *rOutAttrs);
1103 void SvxPositionSizeTabPage::ActivatePage( const SfxItemSet& rSet )
1105 if( SfxRectangleItem const * pRectItem = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_INTERN, false ) )
1107 { // #i75273#
1108 const ::tools::Rectangle aTempRect(pRectItem->GetValue());
1109 maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
1112 SetMinMaxPosition();
1117 DeactivateRC SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
1119 if( _pSet )
1121 double fX(static_cast<double>(m_xMtrPosX->get_value(FieldUnit::NONE)));
1122 double fY(static_cast<double>(m_xMtrPosY->get_value(FieldUnit::NONE)));
1124 GetTopLeftPosition(fX, fY, maRange);
1125 const ::tools::Rectangle aOutRectangle(
1126 basegfx::fround(fX), basegfx::fround(fY),
1127 basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight()));
1128 _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle));
1129 _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
1130 m_xTsbPosProtect->get_state() == TRISTATE_TRUE ));
1131 _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
1132 m_xTsbSizeProtect->get_state() == TRISTATE_TRUE ));
1133 FillItemSet(_pSet);
1136 return DeactivateRC::LeavePage;
1140 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangePosProtectHdl, weld::Toggleable&, void)
1142 // #106572# Remember user's last choice
1143 m_xTsbSizeProtect->set_state(m_xTsbPosProtect->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : mnProtectSizeState);
1144 UpdateControlStates();
1148 void SvxPositionSizeTabPage::UpdateControlStates()
1150 const bool bPosProtect = m_xTsbPosProtect->get_state() == TRISTATE_TRUE;
1151 const bool bSizeProtect = m_xTsbSizeProtect->get_state() == TRISTATE_TRUE;
1152 const bool bHeightChecked = !mbIgnoreAutoGrowHeight && (m_xTsbAutoGrowHeight->get_active());
1153 const bool bWidthChecked = !mbIgnoreAutoGrowWidth && (m_xTsbAutoGrowWidth->get_active());
1155 m_xFlPosition->set_sensitive(!bPosProtect && !mbPageDisabled);
1157 m_xTsbPosProtect->set_sensitive( !mbProtectDisabled && !mbPageDisabled );
1159 m_xFlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect );
1161 m_xFtWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
1162 m_xMtrWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
1164 m_xFtHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
1165 m_xMtrHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
1167 m_xCbxScale->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked && !bWidthChecked );
1168 m_xCtlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect && (!bHeightChecked || !bWidthChecked) );
1170 m_xFlProtect->set_sensitive( !mbProtectDisabled );
1171 m_xTsbSizeProtect->set_sensitive( !mbProtectDisabled && !bPosProtect );
1173 m_xFlAdjust->set_sensitive( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
1175 m_aCtlSize.Invalidate();
1176 m_aCtlPos.Invalidate();
1179 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeSizeProtectHdl, weld::Toggleable&, void)
1181 if (m_xTsbSizeProtect->get_sensitive())
1183 // #106572# Remember user's last choice
1185 // Note: this works only as long as the dialog is open. When
1186 // the user closes the dialog, there is no way to remember
1187 // whether size was enabled or disabled before pos protect was
1188 // clicked. Thus, if pos protect is selected, the dialog is
1189 // closed and reopened again, unchecking pos protect will
1190 // always uncheck size protect, too. That's life.
1191 mnProtectSizeState = m_xTsbSizeProtect->get_state();
1194 UpdateControlStates();
1197 void SvxPositionSizeTabPage::SetMinMaxPosition()
1199 // position
1200 double fLeft(maWorkRange.getMinX());
1201 double fTop(maWorkRange.getMinY());
1202 double fRight(maWorkRange.getMaxX());
1203 double fBottom(maWorkRange.getMaxY());
1205 switch (m_aCtlPos.GetActualRP())
1207 case RectPoint::LT:
1209 fRight -= maRange.getWidth();
1210 fBottom -= maRange.getHeight();
1211 break;
1213 case RectPoint::MT:
1215 fLeft += maRange.getWidth() / 2.0;
1216 fRight -= maRange.getWidth() / 2.0;
1217 fBottom -= maRange.getHeight();
1218 break;
1220 case RectPoint::RT:
1222 fLeft += maRange.getWidth();
1223 fBottom -= maRange.getHeight();
1224 break;
1226 case RectPoint::LM:
1228 fRight -= maRange.getWidth();
1229 fTop += maRange.getHeight() / 2.0;
1230 fBottom -= maRange.getHeight() / 2.0;
1231 break;
1233 case RectPoint::MM:
1235 fLeft += maRange.getWidth() / 2.0;
1236 fRight -= maRange.getWidth() / 2.0;
1237 fTop += maRange.getHeight() / 2.0;
1238 fBottom -= maRange.getHeight() / 2.0;
1239 break;
1241 case RectPoint::RM:
1243 fLeft += maRange.getWidth();
1244 fTop += maRange.getHeight() / 2.0;
1245 fBottom -= maRange.getHeight() / 2.0;
1246 break;
1248 case RectPoint::LB:
1250 fRight -= maRange.getWidth();
1251 fTop += maRange.getHeight();
1252 break;
1254 case RectPoint::MB:
1256 fLeft += maRange.getWidth() / 2.0;
1257 fRight -= maRange.getWidth() / 2.0;
1258 fTop += maRange.getHeight();
1259 break;
1261 case RectPoint::RB:
1263 fLeft += maRange.getWidth();
1264 fTop += maRange.getHeight();
1265 break;
1269 const double fMaxLong(vcl::ConvertValue(std::numeric_limits<sal_Int64>::max(), 0, MapUnit::Map100thMM, meDlgUnit) - 1);
1270 fLeft = std::clamp(fLeft, -fMaxLong, fMaxLong);
1271 fRight = std::clamp(fRight, -fMaxLong, fMaxLong);
1272 fTop = std::clamp(fTop, - fMaxLong, fMaxLong);
1273 fBottom = std::clamp(fBottom, -fMaxLong, fMaxLong);
1275 // #i75273# normalizing when setting the min/max values was wrong, removed
1276 m_xMtrPosX->set_range(basegfx::fround64(fLeft), basegfx::fround64(fRight), FieldUnit::NONE);
1277 m_xMtrPosY->set_range(basegfx::fround64(fTop), basegfx::fround64(fBottom), FieldUnit::NONE);
1279 // size
1280 fLeft = maWorkRange.getMinX();
1281 fTop = maWorkRange.getMinY();
1282 fRight = maWorkRange.getMaxX();
1283 fBottom = maWorkRange.getMaxY();
1284 double fNewX(0);
1285 double fNewY(0);
1287 switch (m_aCtlSize.GetActualRP())
1289 case RectPoint::LT:
1291 fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
1292 fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
1293 break;
1295 case RectPoint::MT:
1297 fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
1298 fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
1299 break;
1301 case RectPoint::RT:
1303 fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
1304 fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
1305 break;
1307 case RectPoint::LM:
1309 fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
1310 fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
1311 break;
1313 case RectPoint::MM:
1315 const double f1(maRange.getCenter().getX() - fLeft);
1316 const double f2(fRight - maRange.getCenter().getX());
1317 const double f3(std::min(f1, f2));
1318 const double f4(maRange.getCenter().getY() - fTop);
1319 const double f5(fBottom - maRange.getCenter().getY());
1320 const double f6(std::min(f4, f5));
1322 fNewX = f3 * 2.0;
1323 fNewY = f6 * 3.0;
1325 break;
1327 case RectPoint::RM:
1329 fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
1330 fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
1331 break;
1333 case RectPoint::LB:
1335 fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
1336 fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
1337 break;
1339 case RectPoint::MB:
1341 fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
1342 fNewY = maWorkRange.getHeight() - ( maRange.getMaxY() - fBottom );
1343 break;
1345 case RectPoint::RB:
1347 fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
1348 fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
1349 break;
1353 // #i75273# normalizing when setting the min/max values was wrong, removed
1354 m_xMtrWidth->set_max(basegfx::fround64(fNewX), FieldUnit::NONE);
1355 m_xMtrHeight->set_max(basegfx::fround64(fNewY), FieldUnit::NONE);
1358 void SvxPositionSizeTabPage::GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange)
1360 switch (m_aCtlPos.GetActualRP())
1362 case RectPoint::LT:
1364 break;
1366 case RectPoint::MT:
1368 rfX -= rRange.getCenter().getX() - rRange.getMinX();
1369 break;
1371 case RectPoint::RT:
1373 rfX -= rRange.getWidth();
1374 break;
1376 case RectPoint::LM:
1378 rfY -= rRange.getCenter().getY() - rRange.getMinY();
1379 break;
1381 case RectPoint::MM:
1383 rfX -= rRange.getCenter().getX() - rRange.getMinX();
1384 rfY -= rRange.getCenter().getY() - rRange.getMinY();
1385 break;
1387 case RectPoint::RM:
1389 rfX -= rRange.getWidth();
1390 rfY -= rRange.getCenter().getY() - rRange.getMinY();
1391 break;
1393 case RectPoint::LB:
1395 rfY -= rRange.getHeight();
1396 break;
1398 case RectPoint::MB:
1400 rfX -= rRange.getCenter().getX() - rRange.getMinX();
1401 rfY -= rRange.getHeight();
1402 break;
1404 case RectPoint::RB:
1406 rfX -= rRange.getWidth();
1407 rfY -= rRange.getHeight();
1408 break;
1413 void SvxPositionSizeTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
1415 if (pDrawingArea == m_aCtlPos.GetDrawingArea())
1417 SetMinMaxPosition();
1418 switch( eRP )
1420 case RectPoint::LT:
1422 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
1423 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
1424 break;
1426 case RectPoint::MT:
1428 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
1429 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
1430 break;
1432 case RectPoint::RT:
1434 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
1435 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
1436 break;
1438 case RectPoint::LM:
1440 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
1441 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
1442 break;
1444 case RectPoint::MM:
1446 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
1447 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
1448 break;
1450 case RectPoint::RM:
1452 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
1453 m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
1454 break;
1456 case RectPoint::LB:
1458 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
1459 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
1460 break;
1462 case RectPoint::MB:
1464 m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
1465 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
1466 break;
1468 case RectPoint::RB:
1470 m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
1471 m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
1472 break;
1476 else
1478 meRP = eRP;
1479 SetMinMaxPosition();
1483 void SvxPositionSizeTabPage::DisableResize()
1485 mbSizeDisabled = true;
1489 void SvxPositionSizeTabPage::DisableProtect()
1491 mbProtectDisabled = true;
1495 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeWidthHdl, weld::MetricSpinButton&, void)
1497 if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
1498 return;
1500 sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(m_xMtrWidth->get_value(FieldUnit::NONE))) / mfOldWidth));
1501 sal_Int64 nMin, nMax;
1502 m_xMtrHeight->get_range(nMin, nMax, FieldUnit::NONE);
1504 if (nHeight <= nMax)
1506 m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
1508 else
1510 nHeight = nMax;
1511 m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
1513 const sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(nHeight)) / mfOldHeight));
1514 m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
1518 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeHeightHdl, weld::MetricSpinButton&, void)
1520 if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
1521 return;
1523 sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(m_xMtrHeight->get_value(FieldUnit::NONE))) / mfOldHeight));
1524 sal_Int64 nMin, nMax;
1525 m_xMtrWidth->get_range(nMin, nMax, FieldUnit::NONE);
1527 if (nWidth <= nMax)
1529 m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
1531 else
1533 nWidth = nMax;
1534 m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
1536 const sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(nWidth)) / mfOldWidth));
1537 m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
1541 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickSizeProtectHdl, weld::Toggleable&, void)
1543 UpdateControlStates();
1546 IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickAutoHdl, weld::Toggleable&, void)
1548 if (m_xCbxScale->get_active())
1550 mfOldWidth = std::max( static_cast<double>(GetCoreValue( *m_xMtrWidth, mePoolUnit )), 1.0 );
1551 mfOldHeight = std::max( static_cast<double>(GetCoreValue( *m_xMtrHeight, mePoolUnit )), 1.0 );
1555 void SvxPositionSizeTabPage::FillUserData()
1557 // matching is saved in the Ini-file
1558 OUString aStr = m_xCbxScale->get_active() ? OUString("1") : OUString("0");
1559 SetUserData( aStr );
1562 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */