fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / svx / source / sidebar / possize / PosSizePropertyPanel.cxx
blob0b313ef6debfa9a02f28233f1cbf42e1760e3481
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 .
19 #include <sfx2/sidebar/ResourceDefinitions.hrc>
20 #include <sfx2/sidebar/Theme.hxx>
21 #include <sfx2/sidebar/ControlFactory.hxx>
22 #include "PosSizePropertyPanel.hxx"
23 #include <svx/sidebar/SidebarDialControl.hxx>
24 #include <svx/dialogs.hrc>
25 #include <svx/dialmgr.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/viewsh.hxx>
29 #include <sfx2/objsh.hxx>
30 #include <sfx2/imagemgr.hxx>
31 #include <svx/dlgutil.hxx>
32 #include <unotools/viewoptions.hxx>
33 #include <vcl/virdev.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/field.hxx>
36 #include <vcl/fixed.hxx>
37 #include <vcl/toolbox.hxx>
38 #include <svl/aeitem.hxx>
39 #include <svx/svdview.hxx>
40 #include <svx/transfrmhelper.hxx>
42 using namespace css;
43 using namespace css::uno;
44 using ::sfx2::sidebar::Theme;
46 const char UNO_FLIPHORIZONTAL[] = ".uno:FlipHorizontal";
47 const char UNO_FLIPVERTICAL[] = ".uno:FlipVertical";
49 const char USERITEM_NAME[] = "FitItem";
51 namespace svx { namespace sidebar {
55 PosSizePropertyPanel::PosSizePropertyPanel(
56 vcl::Window* pParent,
57 const css::uno::Reference<css::frame::XFrame>& rxFrame,
58 SfxBindings* pBindings,
59 const css::uno::Reference<css::ui::XSidebar>& rxSidebar)
60 : PanelLayout(pParent, "PosSizePropertyPanel", "svx/ui/sidebarpossize.ui", rxFrame),
61 maRect(),
62 mpView(0),
63 mlOldWidth(1),
64 mlOldHeight(1),
65 meRP(RP_LT),
66 maAnchorPos(),
67 mlRotX(0),
68 mlRotY(0),
69 maUIScale(),
70 mePoolUnit(),
71 meDlgUnit(FUNIT_INCH), // #i124409# init with fallback default
72 maTransfPosXControl(SID_ATTR_TRANSFORM_POS_X, *pBindings, *this),
73 maTransfPosYControl(SID_ATTR_TRANSFORM_POS_Y, *pBindings, *this),
74 maTransfWidthControl(SID_ATTR_TRANSFORM_WIDTH, *pBindings, *this),
75 maTransfHeightControl(SID_ATTR_TRANSFORM_HEIGHT, *pBindings, *this),
76 maSvxAngleControl( SID_ATTR_TRANSFORM_ANGLE, *pBindings, *this),
77 maRotXControl(SID_ATTR_TRANSFORM_ROT_X, *pBindings, *this),
78 maRotYControl(SID_ATTR_TRANSFORM_ROT_Y, *pBindings, *this),
79 maProPosControl(SID_ATTR_TRANSFORM_PROTECT_POS, *pBindings, *this),
80 maProSizeControl(SID_ATTR_TRANSFORM_PROTECT_SIZE, *pBindings, *this),
81 maAutoWidthControl(SID_ATTR_TRANSFORM_AUTOWIDTH, *pBindings, *this),
82 maAutoHeightControl(SID_ATTR_TRANSFORM_AUTOHEIGHT, *pBindings, *this),
83 m_aMetricCtl(SID_ATTR_METRIC, *pBindings, *this),
84 mxFrame(rxFrame),
85 maContext(),
86 mpBindings(pBindings),
87 mbMtrPosXMirror(false),
88 mbSizeProtected(false),
89 mbPositionProtected(false),
90 mbAutoWidth(false),
91 mbAutoHeight(false),
92 mbAdjustEnabled(false),
93 mbIsFlip(false),
94 mxSidebar(rxSidebar)
96 get( mpFtPosX, "horizontallabel" );
97 get( mpMtrPosX, "horizontalpos" );
98 get( mpFtPosY, "verticallabel" );
99 get( mpMtrPosY, "verticalpos" );
100 get( mpFtWidth, "widthlabel" );
101 get( mpMtrWidth, "selectwidth" );
102 get( mpFtHeight, "heightlabel" );
103 get( mpMtrHeight, "selectheight" );
104 get( mpCbxScale, "ratio" );
105 get( mpFtAngle, "rotationlabel" );
106 get( mpMtrAngle, "rotation" );
107 get( mpDial, "orientationcontrol" );
108 get( mpFtFlip, "fliplabel" );
109 get( mpFlipTbx, "selectrotationtype" );
110 Initialize();
112 mpBindings->Update( SID_ATTR_TRANSFORM_WIDTH );
113 mpBindings->Update( SID_ATTR_TRANSFORM_HEIGHT );
114 mpBindings->Update( SID_ATTR_TRANSFORM_PROTECT_SIZE );
115 mpBindings->Update( SID_ATTR_METRIC );
118 PosSizePropertyPanel::~PosSizePropertyPanel()
120 disposeOnce();
123 void PosSizePropertyPanel::dispose()
125 mpFtPosX.clear();
126 mpMtrPosX.clear();
127 mpFtPosY.clear();
128 mpMtrPosY.clear();
129 mpFtWidth.clear();
130 mpMtrWidth.clear();
131 mpFtHeight.clear();
132 mpMtrHeight.clear();
133 mpCbxScale.clear();
134 mpFtAngle.clear();
135 mpMtrAngle.clear();
136 mpDial.clear();
137 mpFtFlip.clear();
138 mpFlipTbx.clear();
140 maTransfPosXControl.dispose();
141 maTransfPosYControl.dispose();
142 maTransfWidthControl.dispose();
143 maTransfHeightControl.dispose();
145 maSvxAngleControl.dispose();
146 maRotXControl.dispose();
147 maRotYControl.dispose();
148 maProPosControl.dispose();
149 maProSizeControl.dispose();
150 maAutoWidthControl.dispose();
151 maAutoHeightControl.dispose();
152 m_aMetricCtl.dispose();
154 PanelLayout::dispose();
158 namespace
160 bool hasText(const SdrView& rSdrView)
162 const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
164 if(1 == rMarkList.GetMarkCount())
166 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
167 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
169 if((pObj->GetObjInventor() == SdrInventor) && (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind))
171 const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pObj);
173 if(pSdrTextObj && pSdrTextObj->HasText())
175 return true;
180 return false;
182 } // end of anonymous namespace
186 void PosSizePropertyPanel::Initialize()
188 //Position : Horizontal / Vertical
189 mpMtrPosX->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosXHdl ) );
190 mpMtrPosY->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosYHdl ) );
192 //Size : Width / Height
193 mpMtrWidth->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeWidthHdl ) );
194 mpMtrHeight->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeHeightHdl ) );
196 //Size : Keep ratio
197 mpCbxScale->SetClickHdl( LINK( this, PosSizePropertyPanel, ClickAutoHdl ) );
199 //rotation:
200 mpMtrAngle->SetModifyHdl(LINK( this, PosSizePropertyPanel, AngleModifiedHdl));
201 mpMtrAngle->EnableAutocomplete( false );
203 //rotation control
204 mpDial->SetModifyHdl(LINK( this, PosSizePropertyPanel, RotationHdl));
206 //flip:
207 mpFlipTbx->SetSelectHdl( LINK( this, PosSizePropertyPanel, FlipHdl) );
209 mpMtrAngle->InsertValue(0, FUNIT_CUSTOM);
210 mpMtrAngle->InsertValue(4500, FUNIT_CUSTOM);
211 mpMtrAngle->InsertValue(9000, FUNIT_CUSTOM);
212 mpMtrAngle->InsertValue(13500, FUNIT_CUSTOM);
213 mpMtrAngle->InsertValue(18000, FUNIT_CUSTOM);
214 mpMtrAngle->InsertValue(22500, FUNIT_CUSTOM);
215 mpMtrAngle->InsertValue(27000, FUNIT_CUSTOM);
216 mpMtrAngle->InsertValue(31500, FUNIT_CUSTOM);
217 mpMtrAngle->AdaptDropDownLineCountToMaximum();
219 SfxViewShell* pCurSh = SfxViewShell::Current();
220 if ( pCurSh )
221 mpView = pCurSh->GetDrawView();
222 else
223 mpView = NULL;
225 if ( mpView != NULL )
227 maUIScale = mpView->GetModel()->GetUIScale();
228 mbAdjustEnabled = hasText(*mpView);
231 mePoolUnit = maTransfWidthControl.GetCoreMetric();
236 void PosSizePropertyPanel::SetupIcons()
238 if(Theme::GetBoolean(Theme::Bool_UseSymphonyIcons))
240 // todo
242 else
244 // todo
250 VclPtr<vcl::Window> PosSizePropertyPanel::Create (
251 vcl::Window* pParent,
252 const css::uno::Reference<css::frame::XFrame>& rxFrame,
253 SfxBindings* pBindings,
254 const css::uno::Reference<css::ui::XSidebar>& rxSidebar)
256 if (pParent == NULL)
257 throw lang::IllegalArgumentException("no parent Window given to PosSizePropertyPanel::Create", NULL, 0);
258 if ( ! rxFrame.is())
259 throw lang::IllegalArgumentException("no XFrame given to PosSizePropertyPanel::Create", NULL, 1);
260 if (pBindings == NULL)
261 throw lang::IllegalArgumentException("no SfxBindings given to PosSizePropertyPanel::Create", NULL, 2);
263 return VclPtr<PosSizePropertyPanel>::Create(
264 pParent,
265 rxFrame,
266 pBindings,
267 rxSidebar);
272 void PosSizePropertyPanel::DataChanged(
273 const DataChangedEvent& rEvent)
275 (void)rEvent;
277 SetupIcons();
280 void PosSizePropertyPanel::HandleContextChange(
281 const ::sfx2::sidebar::EnumContext& rContext)
283 if (maContext == rContext)
285 // Nothing to do.
286 return;
289 maContext = rContext;
291 sal_Int32 nLayoutMode (0);
292 switch (maContext.GetCombinedContext_DI())
294 case CombinedEnumContext(Application_WriterVariants, Context_Draw):
295 nLayoutMode = 0;
296 break;
298 case CombinedEnumContext(Application_WriterVariants, Context_Graphic):
299 case CombinedEnumContext(Application_WriterVariants, Context_Media):
300 case CombinedEnumContext(Application_WriterVariants, Context_Frame):
301 case CombinedEnumContext(Application_WriterVariants, Context_OLE):
302 case CombinedEnumContext(Application_WriterVariants, Context_Form):
303 nLayoutMode = 1;
304 break;
306 case CombinedEnumContext(Application_Calc, Context_Draw):
307 case CombinedEnumContext(Application_Calc, Context_Graphic):
308 case CombinedEnumContext(Application_DrawImpress, Context_Draw):
309 case CombinedEnumContext(Application_DrawImpress, Context_TextObject):
310 case CombinedEnumContext(Application_DrawImpress, Context_Graphic):
311 nLayoutMode = 2;
312 break;
314 case CombinedEnumContext(Application_Calc, Context_Chart):
315 case CombinedEnumContext(Application_Calc, Context_Form):
316 case CombinedEnumContext(Application_Calc, Context_Media):
317 case CombinedEnumContext(Application_Calc, Context_OLE):
318 case CombinedEnumContext(Application_Calc, Context_MultiObject):
319 case CombinedEnumContext(Application_DrawImpress, Context_Media):
320 case CombinedEnumContext(Application_DrawImpress, Context_Form):
321 case CombinedEnumContext(Application_DrawImpress, Context_OLE):
322 case CombinedEnumContext(Application_DrawImpress, Context_3DObject):
323 case CombinedEnumContext(Application_DrawImpress, Context_MultiObject):
324 nLayoutMode = 3;
325 break;
328 switch (nLayoutMode)
330 case 0:
332 mpMtrWidth->SetMin( 2 );
333 mpMtrHeight->SetMin( 2 );
334 mpFtPosX->Hide();
335 mpMtrPosX->Hide();
336 mpFtPosY->Hide();
337 mpMtrPosY->Hide();
339 //rotation
340 mpFtAngle->Show();
341 mpMtrAngle->Show();
342 mpDial->Show();
344 //flip
345 mpFtFlip->Show();
346 mpFlipTbx->Show();
347 mbIsFlip = true;
349 if (mxSidebar.is())
350 mxSidebar->requestLayout();
352 break;
354 case 1:
356 mpMtrWidth->SetMin( 2 );
357 mpMtrHeight->SetMin( 2 );
358 mpFtPosX->Hide();
359 mpMtrPosX->Hide();
360 mpFtPosY->Hide();
361 mpMtrPosY->Hide();
363 //rotation
364 mpFtAngle->Hide();
365 mpMtrAngle->Hide();
366 mpDial->Hide();
368 //flip
369 mpFlipTbx->Hide();
370 mpFtFlip->Hide();
371 mbIsFlip = false;
373 if (mxSidebar.is())
374 mxSidebar->requestLayout();
376 break;
378 case 2:
380 mpMtrWidth->SetMin( 1 );
381 mpMtrHeight->SetMin( 1 );
382 mpFtPosX->Show();
383 mpMtrPosX->Show();
384 mpFtPosY->Show();
385 mpMtrPosY->Show();
387 //rotation
388 mpFtAngle->Show();
389 mpMtrAngle->Show();
390 mpDial->Show();
392 //flip
393 mpFlipTbx->Show();
394 mpFtFlip->Show();
395 mbIsFlip = true;
397 if (mxSidebar.is())
398 mxSidebar->requestLayout();
400 break;
402 case 3:
404 mpMtrWidth->SetMin( 1 );
405 mpMtrHeight->SetMin( 1 );
406 mpFtPosX->Show();
407 mpMtrPosX->Show();
408 mpFtPosY->Show();
409 mpMtrPosY->Show();
411 //rotation
412 mpFtAngle->Hide();
413 mpMtrAngle->Hide();
414 mpDial->Hide();
416 //flip
417 mpFlipTbx->Hide();
418 mpFtFlip->Hide();
419 mbIsFlip = false;
421 if (mxSidebar.is())
422 mxSidebar->requestLayout();
424 break;
430 IMPL_LINK_NOARG( PosSizePropertyPanel, ChangeWidthHdl )
432 if( mpCbxScale->IsChecked() &&
433 mpCbxScale->IsEnabled() )
435 long nHeight = (long) ( ((double) mlOldHeight * (double) mpMtrWidth->GetValue()) / (double) mlOldWidth );
436 if( nHeight <= mpMtrHeight->GetMax( FUNIT_NONE ) )
438 mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE );
440 else
442 nHeight = (long)mpMtrHeight->GetMax( FUNIT_NONE );
443 mpMtrHeight->SetUserValue( nHeight );
444 const long nWidth = (long) ( ((double) mlOldWidth * (double) nHeight) / (double) mlOldHeight );
445 mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE );
448 executeSize();
449 return 0;
454 IMPL_LINK_NOARG( PosSizePropertyPanel, ChangeHeightHdl )
456 if( mpCbxScale->IsChecked() &&
457 mpCbxScale->IsEnabled() )
459 long nWidth = (long) ( ((double)mlOldWidth * (double)mpMtrHeight->GetValue()) / (double)mlOldHeight );
460 if( nWidth <= mpMtrWidth->GetMax( FUNIT_NONE ) )
462 mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE );
464 else
466 nWidth = (long)mpMtrWidth->GetMax( FUNIT_NONE );
467 mpMtrWidth->SetUserValue( nWidth );
468 const long nHeight = (long) ( ((double)mlOldHeight * (double)nWidth) / (double)mlOldWidth );
469 mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE );
472 executeSize();
473 return 0;
478 IMPL_LINK_NOARG( PosSizePropertyPanel, ChangePosXHdl )
480 executePosX();
481 return 0;
486 IMPL_LINK_NOARG( PosSizePropertyPanel, ChangePosYHdl )
488 executePosY();
489 return 0;
494 IMPL_LINK_NOARG( PosSizePropertyPanel, ClickAutoHdl )
496 if ( mpCbxScale->IsChecked() )
498 mlOldWidth = std::max( GetCoreValue( *mpMtrWidth, mePoolUnit ), 1L );
499 mlOldHeight = std::max( GetCoreValue( *mpMtrHeight, mePoolUnit ), 1L );
502 // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog
503 SvtViewOptions aPageOpt(E_TABPAGE, "cui/ui/possizetabpage/PositionAndSize");
504 aPageOpt.SetUserItem( USERITEM_NAME, ::com::sun::star::uno::makeAny( ::rtl::OUString::number( int(mpCbxScale->IsChecked()) ) ) );
506 return 0;
511 IMPL_LINK_NOARG( PosSizePropertyPanel, AngleModifiedHdl )
513 OUString sTmp = mpMtrAngle->GetText();
514 if (sTmp.isEmpty())
515 return 0;
516 sal_Unicode nChar = sTmp[0];
517 if( nChar == '-' )
519 if (sTmp.getLength() < 2)
520 return 0;
521 nChar = sTmp[1];
524 if( (nChar < '0') || (nChar > '9') )
525 return 0;
527 const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
528 const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0];
530 // Do not check that the entire string was parsed up to its end, there may
531 // be a degree symbol following the number. Note that this also means that
532 // the number recognized just stops at any non-matching character.
533 /* TODO: we could check for the degree symbol stop if there are no other
534 * cases with different symbol characters in any language? */
535 rtl_math_ConversionStatus eStatus;
536 double fTmp = rtl::math::stringToDouble( sTmp, cSep, 0, &eStatus);
537 if (eStatus != rtl_math_ConversionStatus_Ok)
538 return 0;
540 while (fTmp < 0)
541 fTmp += 360;
543 sal_Int64 nTmp = fTmp*100;
545 // #i123993# Need to take UIScale into account when executing rotations
546 const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
547 SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp);
548 SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale));
549 SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale));
551 GetBindings()->GetDispatcher()->Execute(
552 SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L );
554 return 0;
559 IMPL_LINK_NOARG( PosSizePropertyPanel, RotationHdl )
561 sal_Int32 nTmp = mpDial->GetRotation();
563 // #i123993# Need to take UIScale into account when executing rotations
564 const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
565 SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp);
566 SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale));
567 SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale));
569 GetBindings()->GetDispatcher()->Execute(
570 SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L );
572 return 0;
577 IMPL_LINK_TYPED( PosSizePropertyPanel, FlipHdl, ToolBox*, pBox, void )
579 const OUString aCommand(pBox->GetItemCommand(pBox->GetCurItemId()));
581 if(aCommand == UNO_FLIPHORIZONTAL)
583 SfxVoidItem aHoriItem(SID_FLIP_HORIZONTAL);
584 GetBindings()->GetDispatcher()->Execute(
585 SID_FLIP_HORIZONTAL, SfxCallMode::RECORD, &aHoriItem, 0L );
587 else if(aCommand == UNO_FLIPVERTICAL)
589 SfxVoidItem aVertItem(SID_FLIP_VERTICAL);
590 GetBindings()->GetDispatcher()->Execute(
591 SID_FLIP_VERTICAL, SfxCallMode::RECORD, &aVertItem, 0L );
597 void PosSizePropertyPanel::NotifyItemUpdate(
598 sal_uInt16 nSID,
599 SfxItemState eState,
600 const SfxPoolItem* pState,
601 const bool bIsEnabled)
603 (void)bIsEnabled;
605 mpFtAngle->Enable();
606 mpMtrAngle->Enable();
607 mpDial->Enable();
608 mpFtFlip->Enable();
609 mpFlipTbx->Enable();
611 const SfxUInt32Item* pWidthItem;
612 const SfxUInt32Item* pHeightItem;
614 SfxViewShell* pCurSh = SfxViewShell::Current();
615 if ( pCurSh )
616 mpView = pCurSh->GetDrawView();
617 else
618 mpView = NULL;
620 if ( mpView == NULL )
621 return;
623 mbAdjustEnabled = hasText(*mpView);
625 // Pool unit and dialog unit may have changed, make sure that we
626 // have the current values.
627 mePoolUnit = maTransfWidthControl.GetCoreMetric();
629 switch (nSID)
631 case SID_ATTR_TRANSFORM_WIDTH:
632 if ( SfxItemState::DEFAULT == eState )
634 pWidthItem = dynamic_cast< const SfxUInt32Item* >(pState);
636 if(pWidthItem)
638 long mlOldWidth1 = pWidthItem->GetValue();
640 mlOldWidth1 = Fraction( mlOldWidth1 ) / maUIScale;
641 SetFieldUnit( *mpMtrWidth, meDlgUnit, true );
642 SetMetricValue( *mpMtrWidth, mlOldWidth1, mePoolUnit );
643 mlOldWidth = mlOldWidth1;
644 break;
648 mpMtrWidth->SetText( "" );
649 break;
651 case SID_ATTR_TRANSFORM_HEIGHT:
652 if ( SfxItemState::DEFAULT == eState )
654 pHeightItem = dynamic_cast< const SfxUInt32Item* >(pState);
656 if(pHeightItem)
658 long mlOldHeight1 = pHeightItem->GetValue();
660 mlOldHeight1 = Fraction( mlOldHeight1 ) / maUIScale;
661 SetFieldUnit( *mpMtrHeight, meDlgUnit, true );
662 SetMetricValue( *mpMtrHeight, mlOldHeight1, mePoolUnit );
663 mlOldHeight = mlOldHeight1;
664 break;
668 mpMtrHeight->SetText( "");
669 break;
671 case SID_ATTR_TRANSFORM_POS_X:
672 if(SfxItemState::DEFAULT == eState)
674 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
676 if(pItem)
678 long nTmp = pItem->GetValue();
679 nTmp = Fraction( nTmp ) / maUIScale;
680 SetFieldUnit( *mpMtrPosX, meDlgUnit, true );
681 SetMetricValue( *mpMtrPosX, nTmp, mePoolUnit );
682 break;
686 mpMtrPosX->SetText( "" );
687 break;
689 case SID_ATTR_TRANSFORM_POS_Y:
690 if(SfxItemState::DEFAULT == eState)
692 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
694 if(pItem)
696 long nTmp = pItem->GetValue();
697 nTmp = Fraction( nTmp ) / maUIScale;
698 SetFieldUnit( *mpMtrPosY, meDlgUnit, true );
699 SetMetricValue( *mpMtrPosY, nTmp, mePoolUnit );
700 break;
704 mpMtrPosY->SetText( "" );
705 break;
707 case SID_ATTR_TRANSFORM_ROT_X:
708 if (SfxItemState::DEFAULT == eState)
710 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
712 if(pItem)
714 mlRotX = pItem->GetValue();
715 mlRotX = Fraction( mlRotX ) / maUIScale;
718 break;
720 case SID_ATTR_TRANSFORM_ROT_Y:
721 if (SfxItemState::DEFAULT == eState)
723 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
725 if(pItem)
727 mlRotY = pItem->GetValue();
728 mlRotY = Fraction( mlRotY ) / maUIScale;
731 break;
733 case SID_ATTR_TRANSFORM_PROTECT_POS:
734 if(SfxItemState::DEFAULT == eState)
736 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
738 if(pItem)
740 // record the state of position protect
741 mbPositionProtected = pItem->GetValue();
742 break;
746 mbPositionProtected = false;
747 break;
749 case SID_ATTR_TRANSFORM_PROTECT_SIZE:
750 if(SfxItemState::DEFAULT == eState)
752 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
754 if(pItem)
756 // record the state of size protect
757 mbSizeProtected = pItem->GetValue();
758 break;
762 mbSizeProtected = false;
763 break;
765 case SID_ATTR_TRANSFORM_AUTOWIDTH:
766 if(SfxItemState::DEFAULT == eState)
768 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
770 if(pItem)
772 mbAutoWidth = pItem->GetValue();
775 break;
777 case SID_ATTR_TRANSFORM_AUTOHEIGHT:
778 if(SfxItemState::DEFAULT == eState)
780 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
782 if(pItem)
784 mbAutoHeight = pItem->GetValue();
787 break;
789 case SID_ATTR_TRANSFORM_ANGLE:
790 if (eState >= SfxItemState::DEFAULT)
792 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
794 if(pItem)
796 long nTmp = pItem->GetValue();
798 mpMtrAngle->SetValue( nTmp );
799 mpDial->SetRotation( nTmp );
801 switch(nTmp)
803 case 0:
804 mpMtrAngle->SelectEntryPos(0);
805 break;
806 case 4500:
807 mpMtrAngle->SelectEntryPos(1);
808 break;
809 case 9000:
810 mpMtrAngle->SelectEntryPos(2);
811 break;
812 case 13500:
813 mpMtrAngle->SelectEntryPos(3);
814 break;
815 case 18000:
816 mpMtrAngle->SelectEntryPos(4);
817 break;
818 case 22500:
819 mpMtrAngle->SelectEntryPos(5);
820 break;
821 case 27000:
822 mpMtrAngle->SelectEntryPos(6);
823 break;
824 case 315000:
825 mpMtrAngle->SelectEntryPos(7);
826 break;
829 break;
833 mpMtrAngle->SetText( "" );
834 mpDial->SetRotation( 0 );
835 break;
837 case SID_ATTR_METRIC:
838 MetricState( eState, pState );
839 UpdateUIScale();
840 break;
842 default:
843 break;
846 const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI());
847 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
849 switch (rMarkList.GetMarkCount())
851 case 0:
852 break;
854 case 1:
856 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
857 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
859 if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw)
860 || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject)
861 ) && OBJ_EDGE == eKind)
862 || OBJ_CAPTION == eKind)
864 mpFtAngle->Disable();
865 mpMtrAngle->Disable();
866 mpDial->Disable();
867 mpFlipTbx->Disable();
868 mpFtFlip->Disable();
870 break;
873 default:
875 sal_uInt16 nMarkObj = 0;
876 bool isNoEdge = true;
878 while(isNoEdge && rMarkList.GetMark(nMarkObj))
880 const SdrObject* pObj = rMarkList.GetMark(nMarkObj)->GetMarkedSdrObj();
881 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
883 if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw)
884 || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject)
885 ) && OBJ_EDGE == eKind)
886 || OBJ_CAPTION == eKind)
888 isNoEdge = false;
889 break;
891 nMarkObj++;
894 if(!isNoEdge)
896 mpFtAngle->Disable();
897 mpMtrAngle->Disable();
898 mpDial->Disable();
899 mpFlipTbx->Disable();
900 mpFtFlip->Disable();
902 break;
906 if(nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject))
908 mpFlipTbx->Disable();
909 mpFtFlip->Disable();
912 DisableControls();
914 // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog
915 SvtViewOptions aPageOpt(E_TABPAGE, "cui/ui/possizetabpage/PositionAndSize");
916 OUString sUserData;
917 ::com::sun::star::uno::Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
918 ::rtl::OUString aTemp;
919 if ( aUserItem >>= aTemp )
920 sUserData = aTemp;
921 mpCbxScale->Check( (bool)sUserData.toInt32() );
930 void PosSizePropertyPanel::executeSize()
932 if ( mpMtrWidth->IsValueModified() || mpMtrHeight->IsValueModified())
934 Fraction aUIScale = mpView->GetModel()->GetUIScale();
936 // get Width
937 double nWidth = (double)mpMtrWidth->GetValue( meDlgUnit );
938 nWidth = MetricField::ConvertDoubleValue( nWidth, mpMtrWidth->GetBaseValue(), mpMtrWidth->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
939 long lWidth = (long)(nWidth * (double)aUIScale);
940 lWidth = OutputDevice::LogicToLogic( lWidth, MAP_100TH_MM, (MapUnit)mePoolUnit );
941 lWidth = (long)mpMtrWidth->Denormalize( lWidth );
943 // get Height
944 double nHeight = (double)mpMtrHeight->GetValue( meDlgUnit );
945 nHeight = MetricField::ConvertDoubleValue( nHeight, mpMtrHeight->GetBaseValue(), mpMtrHeight->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
946 long lHeight = (long)(nHeight * (double)aUIScale);
947 lHeight = OutputDevice::LogicToLogic( lHeight, MAP_100TH_MM, (MapUnit)mePoolUnit );
948 lHeight = (long)mpMtrWidth->Denormalize( lHeight );
950 // put Width & Height to itemset
951 SfxUInt32Item aWidthItem( SID_ATTR_TRANSFORM_WIDTH, (sal_uInt32) lWidth);
952 SfxUInt32Item aHeightItem( SID_ATTR_TRANSFORM_HEIGHT, (sal_uInt32) lHeight);
953 SfxAllEnumItem aPointItem (SID_ATTR_TRANSFORM_SIZE_POINT, (sal_uInt16)meRP);
954 const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI());
956 if( nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_Graphic)
957 || nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_OLE)
960 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L );
962 else
964 if ( (mpMtrWidth->IsValueModified()) && (mpMtrHeight->IsValueModified()))
965 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L );
966 else if( mpMtrWidth->IsValueModified())
967 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aWidthItem, &aPointItem, 0L );
968 else if ( mpMtrHeight->IsValueModified())
969 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aHeightItem, &aPointItem, 0L );
976 void PosSizePropertyPanel::executePosX()
978 if ( mpMtrPosX->IsValueModified())
980 long lX = GetCoreValue( *mpMtrPosX, mePoolUnit );
981 if( mbMtrPosXMirror )
982 lX = -lX;
983 long lY = GetCoreValue( *mpMtrPosY, mePoolUnit );
985 Fraction aUIScale = mpView->GetModel()->GetUIScale();
986 lX += maAnchorPos.X();
987 lX = Fraction( lX ) * aUIScale;
988 lY += maAnchorPos.Y();
989 lY = Fraction( lY ) * aUIScale;
991 SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX);
992 SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY);
994 GetBindings()->GetDispatcher()->Execute(
995 SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aPosXItem, 0L );
1001 void PosSizePropertyPanel::executePosY()
1003 if ( mpMtrPosY->IsValueModified() )
1005 long lX = GetCoreValue( *mpMtrPosX, mePoolUnit );
1006 long lY = GetCoreValue( *mpMtrPosY, mePoolUnit );
1008 Fraction aUIScale = mpView->GetModel()->GetUIScale();
1009 lX += maAnchorPos.X();
1010 lX = Fraction( lX ) * aUIScale;
1011 lY += maAnchorPos.Y();
1012 lY = Fraction( lY ) * aUIScale;
1014 SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX);
1015 SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY);
1017 GetBindings()->GetDispatcher()->Execute(
1018 SID_ATTR_TRANSFORM, SfxCallMode::RECORD, &aPosYItem, 0L );
1024 void PosSizePropertyPanel::MetricState( SfxItemState eState, const SfxPoolItem* pState )
1026 bool bPosXBlank = false;
1027 bool bPosYBlank = false;
1028 bool bWidthBlank = false;
1029 bool bHeightBlank = false;
1031 // #i124409# use the given Item to get the correct UI unit and initialize it
1032 // and the Fields using it
1033 meDlgUnit = GetCurrentUnit(eState,pState);
1035 if (mpMtrPosX->GetText().isEmpty())
1036 bPosXBlank = true;
1037 SetFieldUnit( *mpMtrPosX, meDlgUnit, true );
1038 if(bPosXBlank)
1039 mpMtrPosX->SetText(OUString());
1041 if (mpMtrPosY->GetText().isEmpty())
1042 bPosYBlank = true;
1043 SetFieldUnit( *mpMtrPosY, meDlgUnit, true );
1044 if(bPosYBlank)
1045 mpMtrPosY->SetText(OUString());
1046 SetPosXYMinMax();
1048 if (mpMtrWidth->GetText().isEmpty())
1049 bWidthBlank = true;
1050 SetFieldUnit( *mpMtrWidth, meDlgUnit, true );
1051 if(bWidthBlank)
1052 mpMtrWidth->SetText(OUString());
1054 if (mpMtrHeight->GetText().isEmpty())
1055 bHeightBlank = true;
1056 SetFieldUnit( *mpMtrHeight, meDlgUnit, true );
1057 if(bHeightBlank)
1058 mpMtrHeight->SetText(OUString());
1063 FieldUnit PosSizePropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState )
1065 FieldUnit eUnit = FUNIT_NONE;
1067 if ( pState && eState >= SfxItemState::DEFAULT )
1069 eUnit = (FieldUnit) static_cast<const SfxUInt16Item*>(pState)->GetValue();
1071 else
1073 SfxViewFrame* pFrame = SfxViewFrame::Current();
1074 SfxObjectShell* pSh = NULL;
1075 if ( pFrame )
1076 pSh = pFrame->GetObjectShell();
1077 if ( pSh )
1079 SfxModule* pModule = pSh->GetModule();
1080 if ( pModule )
1082 const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC );
1083 if ( pItem )
1084 eUnit = (FieldUnit) static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1086 else
1088 SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found");
1093 return eUnit;
1098 void PosSizePropertyPanel::DisableControls()
1100 if( mbPositionProtected )
1102 // the position is protected("Position protect" option in modal dialog is checked),
1103 // disable all the Position controls in sidebar
1104 mpFtPosX->Disable();
1105 mpMtrPosX->Disable();
1106 mpFtPosY->Disable();
1107 mpMtrPosY->Disable();
1108 mpFtAngle->Disable();
1109 mpMtrAngle->Disable();
1110 mpDial->Disable();
1111 mpFtFlip->Disable();
1112 mpFlipTbx->Disable();
1114 mpFtWidth->Disable();
1115 mpMtrWidth->Disable();
1116 mpFtHeight->Disable();
1117 mpMtrHeight->Disable();
1118 mpCbxScale->Disable();
1120 else
1122 mpFtPosX->Enable();
1123 mpMtrPosX->Enable();
1124 mpFtPosY->Enable();
1125 mpMtrPosY->Enable();
1127 //mpFtAngle->Enable();
1128 //mpMtrAngle->Enable();
1129 //mpDial->Enable();
1130 //mpFtFlip->Enable();
1131 //mpFlipTbx->Enable();
1133 if( mbSizeProtected )
1135 mpFtWidth->Disable();
1136 mpMtrWidth->Disable();
1137 mpFtHeight->Disable();
1138 mpMtrHeight->Disable();
1139 mpCbxScale->Disable();
1141 else
1143 if( mbAdjustEnabled )
1145 if( mbAutoWidth )
1147 mpFtWidth->Disable();
1148 mpMtrWidth->Disable();
1149 mpCbxScale->Disable();
1151 else
1153 mpFtWidth->Enable();
1154 mpMtrWidth->Enable();
1156 if( mbAutoHeight )
1158 mpFtHeight->Disable();
1159 mpMtrHeight->Disable();
1160 mpCbxScale->Disable();
1162 else
1164 mpFtHeight->Enable();
1165 mpMtrHeight->Enable();
1167 if( !mbAutoWidth && !mbAutoHeight )
1168 mpCbxScale->Enable();
1170 else
1172 mpFtWidth->Enable();
1173 mpMtrWidth->Enable();
1174 mpFtHeight->Enable();
1175 mpMtrHeight->Enable();
1176 mpCbxScale->Enable();
1182 void PosSizePropertyPanel::SetPosXYMinMax()
1184 SdrPageView* pPV = mpView->GetSdrPageView();
1185 if (!pPV)
1186 return;
1187 Rectangle aTmpRect(mpView->GetAllMarkedRect());
1188 pPV->LogicToPagePos(aTmpRect);
1189 maRect = basegfx::B2DRange(aTmpRect.Left(), aTmpRect.Top(), aTmpRect.Right(), aTmpRect.Bottom());
1191 Rectangle aTmpRect2(mpView->GetWorkArea());
1192 pPV->LogicToPagePos(aTmpRect2);
1193 maWorkArea = basegfx::B2DRange(aTmpRect2.Left(), aTmpRect2.Top(), aTmpRect2.Right(), aTmpRect2.Bottom());
1195 const Fraction aUIScale(mpView->GetModel()->GetUIScale());
1196 TransfrmHelper::ScaleRect( maWorkArea, aUIScale );
1197 TransfrmHelper::ScaleRect( maRect, aUIScale );
1199 const sal_uInt16 nDigits(mpMtrPosX->GetDecimalDigits());
1200 TransfrmHelper::ConvertRect( maWorkArea, nDigits, (MapUnit) mePoolUnit, meDlgUnit );
1201 TransfrmHelper::ConvertRect( maRect, nDigits, (MapUnit) mePoolUnit, meDlgUnit );
1203 double fLeft(maWorkArea.getMinX());
1204 double fTop(maWorkArea.getMinY());
1205 double fRight(maWorkArea.getMaxX());
1206 double fBottom(maWorkArea.getMaxY());
1208 // seems that sidebar defaults to top left reference point
1209 // and there's no way to set it to something else
1210 fRight -= maRect.getWidth();
1211 fBottom -= maRect.getHeight();
1213 const double fMaxLong((double)(MetricField::ConvertValue( LONG_MAX, 0, MAP_100TH_MM, meDlgUnit ) - 1L));
1214 fLeft = basegfx::clamp(fLeft, -fMaxLong, fMaxLong);
1215 fRight = basegfx::clamp(fRight, -fMaxLong, fMaxLong);
1216 fTop = basegfx::clamp(fTop, - fMaxLong, fMaxLong);
1217 fBottom = basegfx::clamp(fBottom, -fMaxLong, fMaxLong);
1219 mpMtrPosX->SetMin(basegfx::fround64(fLeft));
1220 mpMtrPosX->SetFirst(basegfx::fround64(fLeft));
1221 mpMtrPosX->SetMax(basegfx::fround64(fRight));
1222 mpMtrPosX->SetLast(basegfx::fround64(fRight));
1223 mpMtrPosY->SetMin(basegfx::fround64(fTop));
1224 mpMtrPosY->SetFirst(basegfx::fround64(fTop));
1225 mpMtrPosY->SetMax(basegfx::fround64(fBottom));
1226 mpMtrPosY->SetLast(basegfx::fround64(fBottom));
1229 void PosSizePropertyPanel::UpdateUIScale()
1231 const Fraction aUIScale (mpView->GetModel()->GetUIScale());
1232 if (maUIScale != aUIScale)
1234 // UI scale has changed.
1236 // Remember the new UI scale.
1237 maUIScale = aUIScale;
1239 // The content of the position and size boxes is only updated when item changes are notified.
1240 // Request such notifications without changing the actual item values.
1241 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_X, true, false);
1242 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_Y, true, false);
1243 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_WIDTH, true, false);
1244 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_HEIGHT, true, false);
1249 } } // end of namespace svx::sidebar
1251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */