Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / sidebar / possize / PosSizePropertyPanel.cxx
blobb2c3754c48af4bd8e90a879c30b64de959a2e9a0
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>
41 using namespace css;
42 using namespace cssu;
43 using ::sfx2::sidebar::Theme;
45 const char UNO_FLIPHORIZONTAL[] = ".uno:FlipHorizontal";
46 const char UNO_FLIPVERTICAL[] = ".uno:FlipVertical";
48 const char USERITEM_NAME[] = "FitItem";
50 namespace svx { namespace sidebar {
54 PosSizePropertyPanel::PosSizePropertyPanel(
55 Window* pParent,
56 const cssu::Reference<css::frame::XFrame>& rxFrame,
57 SfxBindings* pBindings,
58 const cssu::Reference<css::ui::XSidebar>& rxSidebar)
59 : PanelLayout(pParent, "PosSizePropertyPanel", "svx/ui/sidebarpossize.ui", rxFrame),
60 maRect(),
61 mpView(0),
62 mlOldWidth(1),
63 mlOldHeight(1),
64 meRP(RP_LT),
65 maAnchorPos(),
66 mlRotX(0),
67 mlRotY(0),
68 maUIScale(),
69 mePoolUnit(),
70 meDlgUnit(FUNIT_INCH), // #i124409# init with fallback default
71 maTransfPosXControl(SID_ATTR_TRANSFORM_POS_X, *pBindings, *this),
72 maTransfPosYControl(SID_ATTR_TRANSFORM_POS_Y, *pBindings, *this),
73 maTransfWidthControl(SID_ATTR_TRANSFORM_WIDTH, *pBindings, *this),
74 maTransfHeightControl(SID_ATTR_TRANSFORM_HEIGHT, *pBindings, *this),
75 maSvxAngleControl( SID_ATTR_TRANSFORM_ANGLE, *pBindings, *this),
76 maRotXControl(SID_ATTR_TRANSFORM_ROT_X, *pBindings, *this),
77 maRotYControl(SID_ATTR_TRANSFORM_ROT_Y, *pBindings, *this),
78 maProPosControl(SID_ATTR_TRANSFORM_PROTECT_POS, *pBindings, *this),
79 maProSizeControl(SID_ATTR_TRANSFORM_PROTECT_SIZE, *pBindings, *this),
80 maAutoWidthControl(SID_ATTR_TRANSFORM_AUTOWIDTH, *pBindings, *this),
81 maAutoHeightControl(SID_ATTR_TRANSFORM_AUTOHEIGHT, *pBindings, *this),
82 m_aMetricCtl(SID_ATTR_METRIC, *pBindings, *this),
83 mxFrame(rxFrame),
84 maContext(),
85 mpBindings(pBindings),
86 mbMtrPosXMirror(false),
87 mbSizeProtected(false),
88 mbPositionProtected(false),
89 mbAutoWidth(false),
90 mbAutoHeight(false),
91 mbAdjustEnabled(false),
92 mbIsFlip(false),
93 mxSidebar(rxSidebar)
95 get( mpFtPosX, "horizontallabel" );
96 get( mpMtrPosX, "horizontalpos" );
97 get( mpFtPosY, "verticallabel" );
98 get( mpMtrPosY, "verticalpos" );
99 get( mpFtWidth, "widthlabel" );
100 get( mpMtrWidth, "selectwidth" );
101 get( mpFtHeight, "heightlabel" );
102 get( mpMtrHeight, "selectheight" );
103 get( mpCbxScale, "ratio" );
104 get( mpFtAngle, "rotationlabel" );
105 get( mpMtrAngle, "rotation" );
106 get( mpDial, "orientationcontrol" );
107 get( mpFtFlip, "fliplabel" );
108 get( mpFlipTbx, "selectrotationtype" );
109 Initialize();
111 mpBindings->Update( SID_ATTR_TRANSFORM_WIDTH );
112 mpBindings->Update( SID_ATTR_TRANSFORM_HEIGHT );
113 mpBindings->Update( SID_ATTR_TRANSFORM_PROTECT_SIZE );
114 mpBindings->Update( SID_ATTR_METRIC );
119 PosSizePropertyPanel::~PosSizePropertyPanel()
123 namespace
125 bool hasText(const SdrView& rSdrView)
127 const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList();
129 if(1 == rMarkList.GetMarkCount())
131 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
132 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
134 if((pObj->GetObjInventor() == SdrInventor) && (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind))
136 const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pObj);
138 if(pSdrTextObj && pSdrTextObj->HasText())
140 return true;
145 return false;
147 } // end of anonymous namespace
151 void PosSizePropertyPanel::Initialize()
153 //Position : Horizontal / Vertical
154 mpMtrPosX->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosXHdl ) );
155 mpMtrPosY->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosYHdl ) );
156 mpMtrPosX->SetAccessibleName(OUString( "Horizontal")); //wj acc
157 mpMtrPosY->SetAccessibleName(OUString( "Vertical")); //wj acc
159 //Size : Width / Height
160 mpMtrWidth->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeWidthHdl ) );
161 mpMtrHeight->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeHeightHdl ) );
162 mpMtrWidth->SetAccessibleName(OUString( "Width")); //wj acc
163 mpMtrHeight->SetAccessibleName(OUString( "Height")); //wj acc
165 //Size : Keep ratio
166 mpCbxScale->SetClickHdl( LINK( this, PosSizePropertyPanel, ClickAutoHdl ) );
168 //rotation:
169 mpMtrAngle->SetModifyHdl(LINK( this, PosSizePropertyPanel, AngleModifiedHdl));
170 mpMtrAngle->EnableAutocomplete( false );
171 mpMtrAngle->SetAccessibleName(OUString( "Rotation")); //wj acc
173 //rotation control
174 mpDial->SetModifyHdl(LINK( this, PosSizePropertyPanel, RotationHdl));
176 //flip:
177 mpFlipTbx->SetSelectHdl( LINK( this, PosSizePropertyPanel, FlipHdl) );
179 mpMtrPosX->SetAccessibleRelationLabeledBy(mpFtPosX);
180 mpMtrPosY->SetAccessibleRelationLabeledBy(mpFtPosY);
181 mpMtrWidth->SetAccessibleRelationLabeledBy(mpFtWidth);
182 mpMtrHeight->SetAccessibleRelationLabeledBy(mpFtHeight);
183 mpMtrAngle->SetAccessibleRelationLabeledBy(mpFtAngle);
184 #ifdef HAS_IA2
185 mpMtrAngle->SetMpSubEditAccLableBy(mpFtAngle);
186 #endif
187 mpFlipTbx->SetAccessibleRelationLabeledBy(mpFtFlip);
189 mpMtrAngle->InsertValue(0, FUNIT_CUSTOM);
190 mpMtrAngle->InsertValue(4500, FUNIT_CUSTOM);
191 mpMtrAngle->InsertValue(9000, FUNIT_CUSTOM);
192 mpMtrAngle->InsertValue(13500, FUNIT_CUSTOM);
193 mpMtrAngle->InsertValue(18000, FUNIT_CUSTOM);
194 mpMtrAngle->InsertValue(22500, FUNIT_CUSTOM);
195 mpMtrAngle->InsertValue(27000, FUNIT_CUSTOM);
196 mpMtrAngle->InsertValue(31500, FUNIT_CUSTOM);
197 mpMtrAngle->AdaptDropDownLineCountToMaximum();
199 SfxViewShell* pCurSh = SfxViewShell::Current();
200 if ( pCurSh )
201 mpView = pCurSh->GetDrawView();
202 else
203 mpView = NULL;
205 if ( mpView != NULL )
207 maUIScale = mpView->GetModel()->GetUIScale();
208 mbAdjustEnabled = hasText(*mpView);
211 mePoolUnit = maTransfWidthControl.GetCoreMetric();
216 void PosSizePropertyPanel::SetupIcons(void)
218 if(Theme::GetBoolean(Theme::Bool_UseSymphonyIcons))
220 // todo
222 else
224 // todo
230 PosSizePropertyPanel* PosSizePropertyPanel::Create (
231 Window* pParent,
232 const cssu::Reference<css::frame::XFrame>& rxFrame,
233 SfxBindings* pBindings,
234 const cssu::Reference<css::ui::XSidebar>& rxSidebar)
236 if (pParent == NULL)
237 throw lang::IllegalArgumentException("no parent Window given to PosSizePropertyPanel::Create", NULL, 0);
238 if ( ! rxFrame.is())
239 throw lang::IllegalArgumentException("no XFrame given to PosSizePropertyPanel::Create", NULL, 1);
240 if (pBindings == NULL)
241 throw lang::IllegalArgumentException("no SfxBindings given to PosSizePropertyPanel::Create", NULL, 2);
243 return new PosSizePropertyPanel(
244 pParent,
245 rxFrame,
246 pBindings,
247 rxSidebar);
252 void PosSizePropertyPanel::DataChanged(
253 const DataChangedEvent& rEvent)
255 (void)rEvent;
257 SetupIcons();
260 void PosSizePropertyPanel::HandleContextChange(
261 const ::sfx2::sidebar::EnumContext aContext)
263 if(maContext == aContext)
265 // Nothing to do.
266 return;
269 maContext = aContext;
271 sal_Int32 nLayoutMode (0);
272 switch (maContext.GetCombinedContext_DI())
274 case CombinedEnumContext(Application_WriterVariants, Context_Draw):
275 nLayoutMode = 0;
276 break;
278 case CombinedEnumContext(Application_WriterVariants, Context_Graphic):
279 case CombinedEnumContext(Application_WriterVariants, Context_Media):
280 case CombinedEnumContext(Application_WriterVariants, Context_Frame):
281 case CombinedEnumContext(Application_WriterVariants, Context_OLE):
282 case CombinedEnumContext(Application_WriterVariants, Context_Form):
283 nLayoutMode = 1;
284 break;
286 case CombinedEnumContext(Application_Calc, Context_Draw):
287 case CombinedEnumContext(Application_Calc, Context_Graphic):
288 case CombinedEnumContext(Application_DrawImpress, Context_Draw):
289 case CombinedEnumContext(Application_DrawImpress, Context_TextObject):
290 case CombinedEnumContext(Application_DrawImpress, Context_Graphic):
291 nLayoutMode = 2;
292 break;
294 case CombinedEnumContext(Application_Calc, Context_Chart):
295 case CombinedEnumContext(Application_Calc, Context_Form):
296 case CombinedEnumContext(Application_Calc, Context_Media):
297 case CombinedEnumContext(Application_Calc, Context_OLE):
298 case CombinedEnumContext(Application_Calc, Context_MultiObject):
299 case CombinedEnumContext(Application_DrawImpress, Context_Media):
300 case CombinedEnumContext(Application_DrawImpress, Context_Form):
301 case CombinedEnumContext(Application_DrawImpress, Context_OLE):
302 case CombinedEnumContext(Application_DrawImpress, Context_3DObject):
303 case CombinedEnumContext(Application_DrawImpress, Context_MultiObject):
304 nLayoutMode = 3;
305 break;
308 switch (nLayoutMode)
310 case 0:
312 mpMtrWidth->SetMin( 2 );
313 mpMtrHeight->SetMin( 2 );
314 mpFtPosX->Hide();
315 mpMtrPosX->Hide();
316 mpFtPosY->Hide();
317 mpMtrPosY->Hide();
319 //rotation
320 mpFtAngle->Show();
321 mpMtrAngle->Show();
322 mpDial->Show();
324 //flip
325 mpFtFlip->Show();
326 mpFlipTbx->Show();
327 mbIsFlip = true;
329 if (mxSidebar.is())
330 mxSidebar->requestLayout();
332 break;
334 case 1:
336 mpMtrWidth->SetMin( 2 );
337 mpMtrHeight->SetMin( 2 );
338 mpFtPosX->Hide();
339 mpMtrPosX->Hide();
340 mpFtPosY->Hide();
341 mpMtrPosY->Hide();
343 //rotation
344 mpFtAngle->Hide();
345 mpMtrAngle->Hide();
346 mpDial->Hide();
348 //flip
349 mpFlipTbx->Hide();
350 mpFtFlip->Hide();
351 mbIsFlip = false;
353 if (mxSidebar.is())
354 mxSidebar->requestLayout();
356 break;
358 case 2:
360 mpMtrWidth->SetMin( 1 );
361 mpMtrHeight->SetMin( 1 );
362 mpFtPosX->Show();
363 mpMtrPosX->Show();
364 mpFtPosY->Show();
365 mpMtrPosY->Show();
367 //rotation
368 mpFtAngle->Show();
369 mpMtrAngle->Show();
370 mpDial->Show();
372 //flip
373 mpFlipTbx->Show();
374 mpFtFlip->Show();
375 mbIsFlip = true;
377 if (mxSidebar.is())
378 mxSidebar->requestLayout();
380 break;
382 case 3:
384 mpMtrWidth->SetMin( 1 );
385 mpMtrHeight->SetMin( 1 );
386 mpFtPosX->Show();
387 mpMtrPosX->Show();
388 mpFtPosY->Show();
389 mpMtrPosY->Show();
391 //rotation
392 mpFtAngle->Hide();
393 mpMtrAngle->Hide();
394 mpDial->Hide();
396 //flip
397 mpFlipTbx->Hide();
398 mpFtFlip->Hide();
399 mbIsFlip = false;
401 if (mxSidebar.is())
402 mxSidebar->requestLayout();
404 break;
410 IMPL_LINK( PosSizePropertyPanel, ChangeWidthHdl, void*, /*pBox*/ )
412 if( mpCbxScale->IsChecked() &&
413 mpCbxScale->IsEnabled() )
415 long nHeight = (long) ( ((double) mlOldHeight * (double) mpMtrWidth->GetValue()) / (double) mlOldWidth );
416 if( nHeight <= mpMtrHeight->GetMax( FUNIT_NONE ) )
418 mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE );
420 else
422 nHeight = (long)mpMtrHeight->GetMax( FUNIT_NONE );
423 mpMtrHeight->SetUserValue( nHeight );
424 const long nWidth = (long) ( ((double) mlOldWidth * (double) nHeight) / (double) mlOldHeight );
425 mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE );
428 executeSize();
429 return 0;
434 IMPL_LINK( PosSizePropertyPanel, ChangeHeightHdl, void *, EMPTYARG )
436 if( mpCbxScale->IsChecked() &&
437 mpCbxScale->IsEnabled() )
439 long nWidth = (long) ( ((double)mlOldWidth * (double)mpMtrHeight->GetValue()) / (double)mlOldHeight );
440 if( nWidth <= mpMtrWidth->GetMax( FUNIT_NONE ) )
442 mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE );
444 else
446 nWidth = (long)mpMtrWidth->GetMax( FUNIT_NONE );
447 mpMtrWidth->SetUserValue( nWidth );
448 const long nHeight = (long) ( ((double)mlOldHeight * (double)nWidth) / (double)mlOldWidth );
449 mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE );
452 executeSize();
453 return 0;
458 IMPL_LINK( PosSizePropertyPanel, ChangePosXHdl, void *, EMPTYARG )
460 executePosX();
461 return 0;
466 IMPL_LINK( PosSizePropertyPanel, ChangePosYHdl, void *, EMPTYARG )
468 executePosY();
469 return 0;
474 IMPL_LINK( PosSizePropertyPanel, ClickAutoHdl, void *, EMPTYARG )
476 if ( mpCbxScale->IsChecked() )
478 mlOldWidth = std::max( GetCoreValue( *mpMtrWidth, mePoolUnit ), 1L );
479 mlOldHeight = std::max( GetCoreValue( *mpMtrHeight, mePoolUnit ), 1L );
482 // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog
483 SvtViewOptions aPageOpt(E_TABPAGE, "cui/ui/possizetabpage/PositionAndSize");
484 aPageOpt.SetUserItem( USERITEM_NAME, ::com::sun::star::uno::makeAny( ::rtl::OUString::number( int(mpCbxScale->IsChecked()) ) ) );
486 return 0;
491 IMPL_LINK( PosSizePropertyPanel, AngleModifiedHdl, void *, EMPTYARG )
493 OUString sTmp = mpMtrAngle->GetText();
494 bool bNegative = false;
495 sal_Unicode nChar = sTmp[0];
497 if( nChar == '-' )
499 bNegative = true;
500 nChar = sTmp[1];
503 if( (nChar < '0') || (nChar > '9') )
504 return 0;
505 double dTmp = sTmp.toDouble();
506 if(bNegative)
508 while(dTmp<0)
509 dTmp += 360;
511 sal_Int64 nTmp = dTmp*100;
513 // #i123993# Need to take UIScale into account when executing rotations
514 const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
515 SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp);
516 SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale));
517 SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale));
519 GetBindings()->GetDispatcher()->Execute(
520 SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L );
522 return 0;
527 IMPL_LINK( PosSizePropertyPanel, RotationHdl, void *, EMPTYARG )
529 sal_Int32 nTmp = mpDial->GetRotation();
531 // #i123993# Need to take UIScale into account when executing rotations
532 const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
533 SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp);
534 SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale));
535 SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale));
537 GetBindings()->GetDispatcher()->Execute(
538 SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L );
540 return 0;
545 IMPL_LINK( PosSizePropertyPanel, FlipHdl, ToolBox*, pBox )
547 const OUString aCommand(pBox->GetItemCommand(pBox->GetCurItemId()));
549 if(aCommand == UNO_FLIPHORIZONTAL)
551 SfxVoidItem aHoriItem(SID_FLIP_HORIZONTAL);
552 GetBindings()->GetDispatcher()->Execute(
553 SID_FLIP_HORIZONTAL, SFX_CALLMODE_RECORD, &aHoriItem, 0L );
555 else if(aCommand == UNO_FLIPVERTICAL)
557 SfxVoidItem aVertItem(SID_FLIP_VERTICAL);
558 GetBindings()->GetDispatcher()->Execute(
559 SID_FLIP_VERTICAL, SFX_CALLMODE_RECORD, &aVertItem, 0L );
562 return 0;
567 void PosSizePropertyPanel::NotifyItemUpdate(
568 sal_uInt16 nSID,
569 SfxItemState eState,
570 const SfxPoolItem* pState,
571 const bool bIsEnabled)
573 (void)bIsEnabled;
575 mpFtAngle->Enable();
576 mpMtrAngle->Enable();
577 mpDial->Enable();
578 mpFtFlip->Enable();
579 mpFlipTbx->Enable();
581 const SfxUInt32Item* pWidthItem;
582 const SfxUInt32Item* pHeightItem;
584 SfxViewShell* pCurSh = SfxViewShell::Current();
585 if ( pCurSh )
586 mpView = pCurSh->GetDrawView();
587 else
588 mpView = NULL;
590 if ( mpView == NULL )
591 return;
593 mbAdjustEnabled = hasText(*mpView);
595 // Pool unit and dialog unit may have changed, make sure that we
596 // have the current values.
597 mePoolUnit = maTransfWidthControl.GetCoreMetric();
599 switch (nSID)
601 case SID_ATTR_TRANSFORM_WIDTH:
602 if ( SFX_ITEM_AVAILABLE == eState )
604 pWidthItem = dynamic_cast< const SfxUInt32Item* >(pState);
606 if(pWidthItem)
608 long mlOldWidth1 = pWidthItem->GetValue();
610 mlOldWidth1 = Fraction( mlOldWidth1 ) / maUIScale;
611 SetFieldUnit( *mpMtrWidth, meDlgUnit, true );
612 SetMetricValue( *mpMtrWidth, mlOldWidth1, mePoolUnit );
613 mlOldWidth = mlOldWidth1;
614 break;
618 mpMtrWidth->SetText( "" );
619 break;
621 case SID_ATTR_TRANSFORM_HEIGHT:
622 if ( SFX_ITEM_AVAILABLE == eState )
624 pHeightItem = dynamic_cast< const SfxUInt32Item* >(pState);
626 if(pHeightItem)
628 long mlOldHeight1 = pHeightItem->GetValue();
630 mlOldHeight1 = Fraction( mlOldHeight1 ) / maUIScale;
631 SetFieldUnit( *mpMtrHeight, meDlgUnit, true );
632 SetMetricValue( *mpMtrHeight, mlOldHeight1, mePoolUnit );
633 mlOldHeight = mlOldHeight1;
634 break;
638 mpMtrHeight->SetText( "");
639 break;
641 case SID_ATTR_TRANSFORM_POS_X:
642 if(SFX_ITEM_AVAILABLE == eState)
644 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
646 if(pItem)
648 long nTmp = pItem->GetValue();
649 nTmp = Fraction( nTmp ) / maUIScale;
650 SetFieldUnit( *mpMtrPosX, meDlgUnit, true );
651 SetMetricValue( *mpMtrPosX, nTmp, mePoolUnit );
652 break;
656 mpMtrPosX->SetText( "" );
657 break;
659 case SID_ATTR_TRANSFORM_POS_Y:
660 if(SFX_ITEM_AVAILABLE == eState)
662 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
664 if(pItem)
666 long nTmp = pItem->GetValue();
667 nTmp = Fraction( nTmp ) / maUIScale;
668 SetFieldUnit( *mpMtrPosY, meDlgUnit, true );
669 SetMetricValue( *mpMtrPosY, nTmp, mePoolUnit );
670 break;
674 mpMtrPosY->SetText( "" );
675 break;
677 case SID_ATTR_TRANSFORM_ROT_X:
678 if (SFX_ITEM_AVAILABLE == eState)
680 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
682 if(pItem)
684 mlRotX = pItem->GetValue();
685 mlRotX = Fraction( mlRotX ) / maUIScale;
688 break;
690 case SID_ATTR_TRANSFORM_ROT_Y:
691 if (SFX_ITEM_AVAILABLE == eState)
693 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
695 if(pItem)
697 mlRotY = pItem->GetValue();
698 mlRotY = Fraction( mlRotY ) / maUIScale;
701 break;
703 case SID_ATTR_TRANSFORM_PROTECT_POS:
704 if(SFX_ITEM_AVAILABLE == eState)
706 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
708 if(pItem)
710 // record the state of position protect
711 mbPositionProtected = pItem->GetValue();
712 break;
716 mbPositionProtected = false;
717 break;
719 case SID_ATTR_TRANSFORM_PROTECT_SIZE:
720 if(SFX_ITEM_AVAILABLE == eState)
722 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
724 if(pItem)
726 // record the state of size protect
727 mbSizeProtected = pItem->GetValue();
728 break;
732 mbSizeProtected = false;
733 break;
735 case SID_ATTR_TRANSFORM_AUTOWIDTH:
736 if(SFX_ITEM_AVAILABLE == eState)
738 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
740 if(pItem)
742 mbAutoWidth = pItem->GetValue();
745 break;
747 case SID_ATTR_TRANSFORM_AUTOHEIGHT:
748 if(SFX_ITEM_AVAILABLE == eState)
750 const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState);
752 if(pItem)
754 mbAutoHeight = pItem->GetValue();
757 break;
759 case SID_ATTR_TRANSFORM_ANGLE:
760 if (eState >= SFX_ITEM_AVAILABLE)
762 const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState);
764 if(pItem)
766 long nTmp = pItem->GetValue();
768 mpMtrAngle->SetValue( nTmp );
769 mpDial->SetRotation( nTmp );
771 switch(nTmp)
773 case 0:
774 mpMtrAngle->SelectEntryPos(0);
775 break;
776 case 4500:
777 mpMtrAngle->SelectEntryPos(1);
778 break;
779 case 9000:
780 mpMtrAngle->SelectEntryPos(2);
781 break;
782 case 13500:
783 mpMtrAngle->SelectEntryPos(3);
784 break;
785 case 18000:
786 mpMtrAngle->SelectEntryPos(4);
787 break;
788 case 22500:
789 mpMtrAngle->SelectEntryPos(5);
790 break;
791 case 27000:
792 mpMtrAngle->SelectEntryPos(6);
793 break;
794 case 315000:
795 mpMtrAngle->SelectEntryPos(7);
796 break;
799 break;
803 mpMtrAngle->SetText( "" );
804 mpDial->SetRotation( 0 );
805 break;
807 case SID_ATTR_METRIC:
808 MetricState( eState, pState );
809 UpdateUIScale();
810 break;
812 default:
813 break;
816 const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI());
817 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
819 switch (rMarkList.GetMarkCount())
821 case 0:
822 break;
824 case 1:
826 const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
827 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
829 if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw)
830 || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject)
831 ) && OBJ_EDGE == eKind)
832 || OBJ_CAPTION == eKind)
834 mpFtAngle->Disable();
835 mpMtrAngle->Disable();
836 mpDial->Disable();
837 mpFlipTbx->Disable();
838 mpFtFlip->Disable();
840 break;
843 default:
845 sal_uInt16 nMarkObj = 0;
846 bool isNoEdge = true;
848 while(isNoEdge && rMarkList.GetMark(nMarkObj))
850 const SdrObject* pObj = rMarkList.GetMark(nMarkObj)->GetMarkedSdrObj();
851 const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
853 if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw)
854 || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject)
855 ) && OBJ_EDGE == eKind)
856 || OBJ_CAPTION == eKind)
858 isNoEdge = false;
859 break;
861 nMarkObj++;
864 if(!isNoEdge)
866 mpFtAngle->Disable();
867 mpMtrAngle->Disable();
868 mpDial->Disable();
869 mpFlipTbx->Disable();
870 mpFtFlip->Disable();
872 break;
876 if(nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject))
878 mpFlipTbx->Disable();
879 mpFtFlip->Disable();
882 DisableControls();
884 // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog
885 SvtViewOptions aPageOpt(E_TABPAGE, "cui/ui/possizetabpage/PositionAndSize");
886 OUString sUserData;
887 ::com::sun::star::uno::Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
888 ::rtl::OUString aTemp;
889 if ( aUserItem >>= aTemp )
890 sUserData = aTemp;
891 mpCbxScale->Check( (bool)sUserData.toInt32() );
897 SfxBindings* PosSizePropertyPanel::GetBindings()
899 return mpBindings;
904 void PosSizePropertyPanel::executeSize()
906 if ( mpMtrWidth->IsValueModified() || mpMtrHeight->IsValueModified())
908 Fraction aUIScale = mpView->GetModel()->GetUIScale();
910 // get Width
911 double nWidth = (double)mpMtrWidth->GetValue( meDlgUnit );
912 nWidth = MetricField::ConvertDoubleValue( nWidth, mpMtrWidth->GetBaseValue(), mpMtrWidth->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
913 long lWidth = (long)(nWidth * (double)aUIScale);
914 lWidth = OutputDevice::LogicToLogic( lWidth, MAP_100TH_MM, (MapUnit)mePoolUnit );
915 lWidth = (long)mpMtrWidth->Denormalize( lWidth );
917 // get Height
918 double nHeight = (double)mpMtrHeight->GetValue( meDlgUnit );
919 nHeight = MetricField::ConvertDoubleValue( nHeight, mpMtrHeight->GetBaseValue(), mpMtrHeight->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
920 long lHeight = (long)(nHeight * (double)aUIScale);
921 lHeight = OutputDevice::LogicToLogic( lHeight, MAP_100TH_MM, (MapUnit)mePoolUnit );
922 lHeight = (long)mpMtrWidth->Denormalize( lHeight );
924 // put Width & Height to itemset
925 SfxUInt32Item aWidthItem( SID_ATTR_TRANSFORM_WIDTH, (sal_uInt32) lWidth);
926 SfxUInt32Item aHeightItem( SID_ATTR_TRANSFORM_HEIGHT, (sal_uInt32) lHeight);
927 SfxAllEnumItem aPointItem (SID_ATTR_TRANSFORM_SIZE_POINT, (sal_uInt16)meRP);
928 const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI());
930 if( nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_Graphic)
931 || nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_OLE)
934 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L );
936 else
938 if ( (mpMtrWidth->IsValueModified()) && (mpMtrHeight->IsValueModified()))
939 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L );
940 else if( mpMtrWidth->IsValueModified())
941 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aPointItem, 0L );
942 else if ( mpMtrHeight->IsValueModified())
943 GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aHeightItem, &aPointItem, 0L );
950 void PosSizePropertyPanel::executePosX()
952 if ( mpMtrPosX->IsValueModified())
954 long lX = GetCoreValue( *mpMtrPosX, mePoolUnit );
955 if( mbMtrPosXMirror )
956 lX = -lX;
957 long lY = GetCoreValue( *mpMtrPosY, mePoolUnit );
959 Rectangle aRect;
960 maRect = mpView->GetAllMarkedRect();
961 aRect = mpView->GetAllMarkedRect();
963 Fraction aUIScale = mpView->GetModel()->GetUIScale();
964 lX += maAnchorPos.X();
965 lX = Fraction( lX ) * aUIScale;
966 lY += maAnchorPos.Y();
967 lY = Fraction( lY ) * aUIScale;
969 SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX);
970 SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY);
972 GetBindings()->GetDispatcher()->Execute(
973 SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosXItem, 0L );
979 void PosSizePropertyPanel::executePosY()
981 if ( mpMtrPosY->IsValueModified() )
983 long lX = GetCoreValue( *mpMtrPosX, mePoolUnit );
984 long lY = GetCoreValue( *mpMtrPosY, mePoolUnit );
986 Rectangle aRect;
987 maRect = mpView->GetAllMarkedRect();
988 aRect = mpView->GetAllMarkedRect();
990 Fraction aUIScale = mpView->GetModel()->GetUIScale();
991 lX += maAnchorPos.X();
992 lX = Fraction( lX ) * aUIScale;
993 lY += maAnchorPos.Y();
994 lY = Fraction( lY ) * aUIScale;
996 SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX);
997 SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY);
999 GetBindings()->GetDispatcher()->Execute(
1000 SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosYItem, 0L );
1006 void PosSizePropertyPanel::MetricState( SfxItemState eState, const SfxPoolItem* pState )
1008 bool bPosXBlank = false;
1009 bool bPosYBlank = false;
1010 bool bWidthBlank = false;
1011 bool bHeightBlank = false;
1013 // #i124409# use the given Item to get the correct UI unit and initialize it
1014 // and the Fields using it
1015 meDlgUnit = GetCurrentUnit(eState,pState);
1017 if (mpMtrPosX->GetText().isEmpty())
1018 bPosXBlank = true;
1019 SetFieldUnit( *mpMtrPosX, meDlgUnit, true );
1020 if(bPosXBlank)
1021 mpMtrPosX->SetText(OUString());
1023 if (mpMtrPosY->GetText().isEmpty())
1024 bPosYBlank = true;
1025 SetFieldUnit( *mpMtrPosY, meDlgUnit, true );
1026 if(bPosYBlank)
1027 mpMtrPosY->SetText(OUString());
1029 if (mpMtrWidth->GetText().isEmpty())
1030 bWidthBlank = true;
1031 SetFieldUnit( *mpMtrWidth, meDlgUnit, true );
1032 if(bWidthBlank)
1033 mpMtrWidth->SetText(OUString());
1035 if (mpMtrHeight->GetText().isEmpty())
1036 bHeightBlank = true;
1037 SetFieldUnit( *mpMtrHeight, meDlgUnit, true );
1038 if(bHeightBlank)
1039 mpMtrHeight->SetText(OUString());
1044 FieldUnit PosSizePropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState )
1046 FieldUnit eUnit = FUNIT_NONE;
1048 if ( pState && eState >= SFX_ITEM_DEFAULT )
1050 eUnit = (FieldUnit)( (const SfxUInt16Item*)pState )->GetValue();
1052 else
1054 SfxViewFrame* pFrame = SfxViewFrame::Current();
1055 SfxObjectShell* pSh = NULL;
1056 if ( pFrame )
1057 pSh = pFrame->GetObjectShell();
1058 if ( pSh )
1060 SfxModule* pModule = pSh->GetModule();
1061 if ( pModule )
1063 const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC );
1064 if ( pItem )
1065 eUnit = (FieldUnit)( (SfxUInt16Item*)pItem )->GetValue();
1067 else
1069 DBG_ERRORFILE( "GetModuleFieldUnit(): no module found" );
1074 return eUnit;
1079 void PosSizePropertyPanel::DisableControls()
1081 if( mbPositionProtected )
1083 // the position is protected("Position protect" option in modal dialog is checked),
1084 // disable all the Position controls in sidebar
1085 mpFtPosX->Disable();
1086 mpMtrPosX->Disable();
1087 mpFtPosY->Disable();
1088 mpMtrPosY->Disable();
1089 mpFtAngle->Disable();
1090 mpMtrAngle->Disable();
1091 mpDial->Disable();
1092 mpFtFlip->Disable();
1093 mpFlipTbx->Disable();
1095 mpFtWidth->Disable();
1096 mpMtrWidth->Disable();
1097 mpFtHeight->Disable();
1098 mpMtrHeight->Disable();
1099 mpCbxScale->Disable();
1101 else
1103 mpFtPosX->Enable();
1104 mpMtrPosX->Enable();
1105 mpFtPosY->Enable();
1106 mpMtrPosY->Enable();
1108 //mpFtAngle->Enable();
1109 //mpMtrAngle->Enable();
1110 //mpDial->Enable();
1111 //mpFtFlip->Enable();
1112 //mpFlipTbx->Enable();
1114 if( mbSizeProtected )
1116 mpFtWidth->Disable();
1117 mpMtrWidth->Disable();
1118 mpFtHeight->Disable();
1119 mpMtrHeight->Disable();
1120 mpCbxScale->Disable();
1122 else
1124 if( mbAdjustEnabled )
1126 if( mbAutoWidth )
1128 mpFtWidth->Disable();
1129 mpMtrWidth->Disable();
1130 mpCbxScale->Disable();
1132 else
1134 mpFtWidth->Enable();
1135 mpMtrWidth->Enable();
1137 if( mbAutoHeight )
1139 mpFtHeight->Disable();
1140 mpMtrHeight->Disable();
1141 mpCbxScale->Disable();
1143 else
1145 mpFtHeight->Enable();
1146 mpMtrHeight->Enable();
1148 if( !mbAutoWidth && !mbAutoHeight )
1149 mpCbxScale->Enable();
1151 else
1153 mpFtWidth->Enable();
1154 mpMtrWidth->Enable();
1155 mpFtHeight->Enable();
1156 mpMtrHeight->Enable();
1157 mpCbxScale->Enable();
1166 void PosSizePropertyPanel::UpdateUIScale()
1168 const Fraction aUIScale (mpView->GetModel()->GetUIScale());
1169 if (maUIScale != aUIScale)
1171 // UI scale has changed.
1173 // Remember the new UI scale.
1174 maUIScale = aUIScale;
1176 // The content of the position and size boxes is only updated when item changes are notified.
1177 // Request such notifications without changing the actual item values.
1178 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_X, true, false);
1179 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_Y, true, false);
1180 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_WIDTH, true, false);
1181 GetBindings()->Invalidate(SID_ATTR_TRANSFORM_HEIGHT, true, false);
1186 } } // end of namespace svx::sidebar
1188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */