/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include #include #include #include #include "PosSizePropertyPanel.hxx" #include "PosSizePropertyPanel.hrc" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace css; using namespace cssu; using ::sfx2::sidebar::Layouter; using ::sfx2::sidebar::Theme; #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) #define USERITEM_NAME rtl::OUString::createFromAscii("FitItem") #define NO_SELECT (65535) namespace svx { namespace sidebar { PosSizePropertyPanel::PosSizePropertyPanel( Window* pParent, const cssu::Reference& rxFrame, SfxBindings* pBindings, const cssu::Reference& rxSidebar) : Control( pParent, SVX_RES(RID_SIDEBAR_POSSIZE_PANEL)), mpFtPosX(new FixedText(this, SVX_RES(FT_SBSHAPE_HORIZONTAL))), mpMtrPosX(new MetricField(this, SVX_RES(MF_SBSHAPE_HORIZONTAL))), mpFtPosY(new FixedText(this, SVX_RES(FT_SBSHAPE_VERTICAL))), mpMtrPosY(new MetricField(this, SVX_RES(MF_SBSHAPE_VERTICAL))), mpFtWidth(new FixedText(this, SVX_RES(FT_WIDTH))), mpMtrWidth(new MetricField(this, SVX_RES(MTR_FLD_WIDTH))), mpFtHeight(new FixedText(this, SVX_RES(FT_HEIGHT))), mpMtrHeight(new MetricField(this, SVX_RES(MTR_FLD_HEIGHT))), mpCbxScale(new CheckBox(this, SVX_RES(CBX_SCALE))), mpFtAngle(new FixedText(this, SVX_RES(FT_ANGLE))), mpMtrAngle(new MetricBox(this, SVX_RES(MTR_FLD_ANGLE))), mpDial(new SidebarDialControl(this, SVX_RES(DIAL_CONTROL))), mpFtFlip(new FixedText(this, SVX_RES(FT_FLIP))), mpFlipTbxBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)), mpFlipTbx(sfx2::sidebar::ControlFactory::CreateToolBox(mpFlipTbxBackground.get(), SVX_RES(TBX_FLIP))), maRect(), mpView(0), mlOldWidth(1), mlOldHeight(1), meRP(RP_LT), maAnchorPos(), mlRotX(0), mlRotY(0), maUIScale(), mePoolUnit(), // #124409# init with fallback default meDlgUnit(FUNIT_INCH), maTransfPosXControl(SID_ATTR_TRANSFORM_POS_X, *pBindings, *this), maTransfPosYControl(SID_ATTR_TRANSFORM_POS_Y, *pBindings, *this), maTransfWidthControl(SID_ATTR_TRANSFORM_WIDTH, *pBindings, *this), maTransfHeightControl(SID_ATTR_TRANSFORM_HEIGHT, *pBindings, *this), maSvxAngleControl( SID_ATTR_TRANSFORM_ANGLE, *pBindings, *this), maRotXControl(SID_ATTR_TRANSFORM_ROT_X, *pBindings, *this), maRotYControl(SID_ATTR_TRANSFORM_ROT_Y, *pBindings, *this), maProPosControl(SID_ATTR_TRANSFORM_PROTECT_POS, *pBindings, *this), maProSizeControl(SID_ATTR_TRANSFORM_PROTECT_SIZE, *pBindings, *this), maAutoWidthControl(SID_ATTR_TRANSFORM_AUTOWIDTH, *pBindings, *this), maAutoHeightControl(SID_ATTR_TRANSFORM_AUTOHEIGHT, *pBindings, *this), m_aMetricCtl(SID_ATTR_METRIC, *pBindings, *this), mxFrame(rxFrame), maContext(), mpBindings(pBindings), maFtWidthOrigPos(mpFtWidth->GetPosPixel()), maMtrWidthOrigPos(mpMtrWidth->GetPosPixel()), maFtHeightOrigPos(mpFtHeight->GetPosPixel()), maMtrHeightOrigPos(mpMtrHeight->GetPosPixel()), maCbxScaleOrigPos(mpCbxScale->GetPosPixel()), maFtAngleOrigPos(mpFtAngle->GetPosPixel()), maMtrAnglOrigPos(mpMtrAngle->GetPosPixel()), maFlipTbxOrigPos(mpFlipTbx->GetPosPixel()), maDialOrigPos(mpDial->GetPosPixel()), maFtFlipOrigPos(mpFtFlip->GetPosPixel()), mbMtrPosXMirror(false), mbSizeProtected(false), mbPositionProtected(false), mbAutoWidth(false), mbAutoHeight(false), mbAdjustEnabled(false), mbIsFlip(false), mxSidebar(rxSidebar), maLayouter(*this) { Initialize(); FreeResource(); mpBindings->Update( SID_ATTR_TRANSFORM_WIDTH ); mpBindings->Update( SID_ATTR_TRANSFORM_HEIGHT ); mpBindings->Update( SID_ATTR_TRANSFORM_PROTECT_SIZE ); mpBindings->Update( SID_ATTR_METRIC ); // Setup the grid layouter. const sal_Int32 nMappedMboxWidth (Layouter::MapWidth(*this, MBOX_WIDTH)); maLayouter.GetCell(0,0).SetControl(*mpFtPosX); maLayouter.GetCell(1,0).SetControl(*mpMtrPosX); maLayouter.GetCell(0,2).SetControl(*mpFtPosY); maLayouter.GetCell(1,2).SetControl(*mpMtrPosY); maLayouter.GetCell(2,0).SetControl(*mpFtWidth); maLayouter.GetCell(3,0).SetControl(*mpMtrWidth); maLayouter.GetCell(2,2).SetControl(*mpFtHeight); maLayouter.GetCell(3,2).SetControl(*mpMtrHeight); maLayouter.GetCell(4,0).SetControl(*mpCbxScale).SetGridWidth(3); maLayouter.GetCell(5,0).SetControl(*mpFtAngle).SetGridWidth(3); maLayouter.GetColumn(0) .SetWeight(1) .SetLeftPadding(Layouter::MapWidth(*this,SECTIONPAGE_MARGIN_HORIZONTAL)) .SetMinimumWidth(nMappedMboxWidth); maLayouter.GetColumn(1) .SetWeight(0) .SetMinimumWidth(Layouter::MapWidth(*this, CONTROL_SPACING_HORIZONTAL)); maLayouter.GetColumn(2) .SetWeight(1) .SetRightPadding(Layouter::MapWidth(*this,SECTIONPAGE_MARGIN_HORIZONTAL)) .SetMinimumWidth(nMappedMboxWidth); // Make controls that display text handle short widths more // graceful. Layouter::PrepareForLayouting(*mpFtPosX); Layouter::PrepareForLayouting(*mpFtPosY); Layouter::PrepareForLayouting(*mpFtWidth); Layouter::PrepareForLayouting(*mpFtHeight); Layouter::PrepareForLayouting(*mpCbxScale); Layouter::PrepareForLayouting(*mpFtAngle); } PosSizePropertyPanel::~PosSizePropertyPanel() { // Destroy the background windows of the toolboxes. mpFlipTbx.reset(); mpFlipTbxBackground.reset(); } void PosSizePropertyPanel::ShowMenu (void) { if (mpBindings != NULL) { SfxDispatcher* pDispatcher = mpBindings->GetDispatcher(); if (pDispatcher != NULL) pDispatcher->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_ASYNCHRON); } } namespace { bool hasText(const SdrView& rSdrView) { const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList(); if(1 == rMarkList.GetMarkCount()) { const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if((pObj->GetObjInventor() == SdrInventor) && (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind)) { const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pObj); if(pSdrTextObj && pSdrTextObj->HasText()) { return true; } } } return false; } } // end of anonymous namespace void PosSizePropertyPanel::Resize (void) { maLayouter.Layout(); } void PosSizePropertyPanel::Initialize() { mpFtPosX->SetBackground(Wallpaper()); mpFtPosY->SetBackground(Wallpaper()); mpFtWidth->SetBackground(Wallpaper()); mpFtHeight->SetBackground(Wallpaper()); mpFtAngle->SetBackground(Wallpaper()); mpFtFlip->SetBackground(Wallpaper()); //Position : Horizontal / Vertical mpMtrPosX->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosXHdl ) ); mpMtrPosY->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangePosYHdl ) ); mpMtrPosX->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Horizontal"))); //wj acc mpMtrPosY->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Vertical"))); //wj acc //Size : Width / Height mpMtrWidth->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeWidthHdl ) ); mpMtrHeight->SetModifyHdl( LINK( this, PosSizePropertyPanel, ChangeHeightHdl ) ); mpMtrWidth->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Width"))); //wj acc mpMtrHeight->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Height"))); //wj acc //Size : Keep ratio mpCbxScale->SetClickHdl( LINK( this, PosSizePropertyPanel, ClickAutoHdl ) ); //rotation: mpMtrAngle->SetModifyHdl(LINK( this, PosSizePropertyPanel, AngleModifiedHdl)); mpMtrAngle->EnableAutocomplete( false ); mpMtrAngle->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Rotation"))); //wj acc //rotation control mpDial->SetModifyHdl(LINK( this, PosSizePropertyPanel, RotationHdl)); //flip: mpFlipTbx->SetSelectHdl( LINK( this, PosSizePropertyPanel, FlipHdl) ); mpFlipTbx->SetItemImage( FLIP_HORIZONTAL, GetImage(mxFrame, A2S(".uno:FlipHorizontal"), sal_False, Theme::IsHighContrastMode())); mpFlipTbx->SetItemImage( FLIP_VERTICAL, GetImage(mxFrame, A2S(".uno:FlipVertical"), sal_False, Theme::IsHighContrastMode())); mpFlipTbx->SetQuickHelpText(FLIP_HORIZONTAL,String(SVX_RES(STR_QH_HORI_FLIP))); //Add mpFlipTbx->SetQuickHelpText(FLIP_VERTICAL,String(SVX_RES(STR_QH_VERT_FLIP))); //Add mpMtrPosX->SetAccessibleRelationLabeledBy(mpFtPosX.get()); mpMtrPosY->SetAccessibleRelationLabeledBy(mpFtPosY.get()); mpMtrWidth->SetAccessibleRelationLabeledBy(mpFtWidth.get()); mpMtrHeight->SetAccessibleRelationLabeledBy(mpFtHeight.get()); mpMtrAngle->SetAccessibleRelationLabeledBy(mpFtAngle.get()); #ifdef HAS_IA2 mpMtrAngle->SetMpSubEditAccLableBy(mpFtAngle.get()); #endif mpFlipTbx->SetAccessibleRelationLabeledBy(mpFtFlip.get()); mpMtrAngle->InsertValue(0, FUNIT_CUSTOM); mpMtrAngle->InsertValue(4500, FUNIT_CUSTOM); mpMtrAngle->InsertValue(9000, FUNIT_CUSTOM); mpMtrAngle->InsertValue(13500, FUNIT_CUSTOM); mpMtrAngle->InsertValue(18000, FUNIT_CUSTOM); mpMtrAngle->InsertValue(22500, FUNIT_CUSTOM); mpMtrAngle->InsertValue(27000, FUNIT_CUSTOM); mpMtrAngle->InsertValue(31500, FUNIT_CUSTOM); mpMtrAngle->AdaptDropDownLineCountToMaximum(); SfxViewShell* pCurSh = SfxViewShell::Current(); if ( pCurSh ) mpView = pCurSh->GetDrawView(); else mpView = NULL; if ( mpView != NULL ) { maUIScale = mpView->GetModel()->GetUIScale(); mbAdjustEnabled = hasText(*mpView); } mePoolUnit = maTransfWidthControl.GetCoreMetric(); // #124409# no need to do this, the mpBindings->Update( SID_ATTR_METRIC ) // call in the constructor will trigger MetricState and will get the correct unit // // meDlgUnit = GetModuleFieldUnit(); // SetFieldUnit( *mpMtrPosX, meDlgUnit, true ); // SetFieldUnit( *mpMtrPosY, meDlgUnit, true ); // SetFieldUnit( *mpMtrWidth, meDlgUnit, true ); // SetFieldUnit( *mpMtrHeight, meDlgUnit, true ); } void PosSizePropertyPanel::SetupIcons(void) { if(Theme::GetBoolean(Theme::Bool_UseSymphonyIcons)) { // todo } else { // todo } } PosSizePropertyPanel* PosSizePropertyPanel::Create ( Window* pParent, const cssu::Reference& rxFrame, SfxBindings* pBindings, const cssu::Reference& rxSidebar) { if (pParent == NULL) throw lang::IllegalArgumentException(A2S("no parent Window given to PosSizePropertyPanel::Create"), NULL, 0); if ( ! rxFrame.is()) throw lang::IllegalArgumentException(A2S("no XFrame given to PosSizePropertyPanel::Create"), NULL, 1); if (pBindings == NULL) throw lang::IllegalArgumentException(A2S("no SfxBindings given to PosSizePropertyPanel::Create"), NULL, 2); return new PosSizePropertyPanel( pParent, rxFrame, pBindings, rxSidebar); } void PosSizePropertyPanel::DataChanged( const DataChangedEvent& rEvent) { (void)rEvent; SetupIcons(); } void PosSizePropertyPanel::AdaptWidthHeightScalePosition(bool bOriginal) { if(bOriginal) { mpFtWidth->SetPosPixel(maFtWidthOrigPos); mpMtrWidth->SetPosPixel(maMtrWidthOrigPos); mpFtHeight->SetPosPixel(maFtHeightOrigPos); mpMtrHeight->SetPosPixel(maMtrHeightOrigPos); mpCbxScale->SetPosPixel(maCbxScaleOrigPos); } else { mpFtWidth->SetPosPixel(Point(LogicToPixel(Point(FT_POSITION_X_X,FT_POSITION_X_Y), MAP_APPFONT))); mpMtrWidth->SetPosPixel(Point(LogicToPixel(Point(MF_POSITION_X_X,MF_POSITION_X_Y), MAP_APPFONT))); mpFtHeight->SetPosPixel(Point(LogicToPixel(Point(FT_POSITION_Y_X,FT_POSITION_Y_Y), MAP_APPFONT))); mpMtrHeight->SetPosPixel(Point(LogicToPixel(Point(MF_POSITION_Y_X,MF_POSITION_Y_Y), MAP_APPFONT))); mpCbxScale->SetPosPixel(Point(LogicToPixel(Point(FT_WIDTH_X,FT_WIDTH_Y), MAP_APPFONT))); } } void PosSizePropertyPanel::AdaptAngleFlipDialPosition(bool bOriginal) { if(bOriginal) { mpFtAngle->SetPosPixel(maFtAngleOrigPos); mpMtrAngle->SetPosPixel(maMtrAnglOrigPos); mpFlipTbx->SetPosPixel(maFlipTbxOrigPos); mpDial->SetPosPixel(maDialOrigPos); mpFtFlip->SetPosPixel(maFtFlipOrigPos); } else { mpFtAngle->SetPosPixel(Point(LogicToPixel(Point(FT_ANGLE_X,FT_ANGLE_Y), MAP_APPFONT))); mpMtrAngle->SetPosPixel(Point(LogicToPixel(Point(MF_ANGLE_X2,MF_ANGLE_Y2), MAP_APPFONT))); mpFlipTbx->SetPosPixel(Point(LogicToPixel(Point(FLIP_HORI_X2,FLIP_HORI_Y2), MAP_APPFONT))); mpDial->SetPosPixel(Point(LogicToPixel(Point(ROTATE_CONTROL_X2,ROTATE_CONTROL_Y2), MAP_APPFONT))); mpFtFlip->SetPosPixel(Point(LogicToPixel(Point(FT_FLIP_X2,FT_FLIP_Y2), MAP_APPFONT))); } } void PosSizePropertyPanel::HandleContextChange( const ::sfx2::sidebar::EnumContext aContext) { if(maContext == aContext) { // Nothing to do. return; } maContext = aContext; sal_Int32 nLayoutMode (0); switch (maContext.GetCombinedContext_DI()) { case CombinedEnumContext(Application_WriterVariants, Context_Draw): nLayoutMode = 0; break; case CombinedEnumContext(Application_WriterVariants, Context_Graphic): case CombinedEnumContext(Application_WriterVariants, Context_Media): case CombinedEnumContext(Application_WriterVariants, Context_Frame): case CombinedEnumContext(Application_WriterVariants, Context_OLE): case CombinedEnumContext(Application_WriterVariants, Context_Form): nLayoutMode = 1; break; case CombinedEnumContext(Application_Calc, Context_Draw): case CombinedEnumContext(Application_Calc, Context_Graphic): case CombinedEnumContext(Application_DrawImpress, Context_Draw): case CombinedEnumContext(Application_DrawImpress, Context_TextObject): case CombinedEnumContext(Application_DrawImpress, Context_Graphic): nLayoutMode = 2; break; case CombinedEnumContext(Application_Calc, Context_Chart): case CombinedEnumContext(Application_Calc, Context_Form): case CombinedEnumContext(Application_Calc, Context_Media): case CombinedEnumContext(Application_Calc, Context_OLE): case CombinedEnumContext(Application_Calc, Context_MultiObject): case CombinedEnumContext(Application_DrawImpress, Context_Media): case CombinedEnumContext(Application_DrawImpress, Context_Form): case CombinedEnumContext(Application_DrawImpress, Context_OLE): case CombinedEnumContext(Application_DrawImpress, Context_3DObject): case CombinedEnumContext(Application_DrawImpress, Context_MultiObject): nLayoutMode = 3; break; } switch (nLayoutMode) { case 0: { mpMtrWidth->SetMin( 2 ); mpMtrHeight->SetMin( 2 ); mpFtPosX->Hide(); mpMtrPosX->Hide(); mpFtPosY->Hide(); mpMtrPosY->Hide(); //rotation mpFtAngle->Show(); mpMtrAngle->Show(); mpDial->Show(); //flip mpFtFlip->Show(); mpFlipTbx->Show(); Size aTbxSize = mpFlipTbx->CalcWindowSizePixel(); mpFlipTbx->SetOutputSizePixel( aTbxSize ); mbIsFlip = true; AdaptWidthHeightScalePosition(false); AdaptAngleFlipDialPosition(false); mpFtAngle->SetPosPixel(Point(LogicToPixel(Point(FT_ANGLE_X,FT_ANGLE_Y), MAP_APPFONT))); mpMtrAngle->SetPosPixel(Point(LogicToPixel(Point(MF_ANGLE_X2,MF_ANGLE_Y2), MAP_APPFONT))); mpFlipTbx->SetPosPixel(Point(LogicToPixel(Point(FLIP_HORI_X2,FLIP_HORI_Y2), MAP_APPFONT))); mpDial->SetPosPixel(Point(LogicToPixel(Point(ROTATE_CONTROL_X2,ROTATE_CONTROL_Y2), MAP_APPFONT))); mpFtFlip->SetPosPixel(Point(LogicToPixel(Point(FT_FLIP_X2,FT_FLIP_Y2), MAP_APPFONT))); Size aSize(GetOutputSizePixel().Width(),PS_SECTIONPAGE_HEIGHT2); aSize = LogicToPixel( aSize, MapMode(MAP_APPFONT) ); SetSizePixel(aSize); if (mxSidebar.is()) mxSidebar->requestLayout(); } break; case 1: { mpMtrWidth->SetMin( 2 ); mpMtrHeight->SetMin( 2 ); mpFtPosX->Hide(); mpMtrPosX->Hide(); mpFtPosY->Hide(); mpMtrPosY->Hide(); //rotation mpFtAngle->Hide(); mpMtrAngle->Hide(); mpDial->Hide(); //flip mpFlipTbx->Hide(); mpFtFlip->Hide(); mbIsFlip = false; AdaptWidthHeightScalePosition(false); AdaptAngleFlipDialPosition(true); Size aSize(GetOutputSizePixel().Width(),PS_SECTIONPAGE_HEIGHT3); aSize = LogicToPixel( aSize, MapMode(MAP_APPFONT) ); SetSizePixel(aSize); if (mxSidebar.is()) mxSidebar->requestLayout(); } break; case 2: { mpMtrWidth->SetMin( 1 ); mpMtrHeight->SetMin( 1 ); mpFtPosX->Show(); mpMtrPosX->Show(); mpFtPosY->Show(); mpMtrPosY->Show(); //rotation mpFtAngle->Show(); mpMtrAngle->Show(); mpDial->Show(); //flip mpFlipTbx->Show(); mpFtFlip->Show(); Size aTbxSize = mpFlipTbx->CalcWindowSizePixel(); mpFlipTbx->SetOutputSizePixel( aTbxSize ); mbIsFlip = true; AdaptWidthHeightScalePosition(true); AdaptAngleFlipDialPosition(true); Size aSize(GetOutputSizePixel().Width(),PS_SECTIONPAGE_HEIGHT); aSize = LogicToPixel( aSize, MapMode(MAP_APPFONT) ); SetSizePixel(aSize); if (mxSidebar.is()) mxSidebar->requestLayout(); } break; case 3: { mpMtrWidth->SetMin( 1 ); mpMtrHeight->SetMin( 1 ); mpFtPosX->Show(); mpMtrPosX->Show(); mpFtPosY->Show(); mpMtrPosY->Show(); //rotation mpFtAngle->Hide(); mpMtrAngle->Hide(); mpDial->Hide(); //flip mpFlipTbx->Hide(); mpFtFlip->Hide(); mbIsFlip = false; AdaptWidthHeightScalePosition(true); AdaptAngleFlipDialPosition(true); Size aSize(GetOutputSizePixel().Width(),PS_SECTIONPAGE_HEIGHT4); aSize = LogicToPixel( aSize, MapMode(MAP_APPFONT) ); SetSizePixel(aSize); if (mxSidebar.is()) mxSidebar->requestLayout(); } break; } //Added for windows classic theme mpFlipTbx->SetBackground(Wallpaper()); mpFlipTbx->SetPaintTransparent(true); } IMPL_LINK( PosSizePropertyPanel, ChangeWidthHdl, void*, /*pBox*/ ) { if( mpCbxScale->IsChecked() && mpCbxScale->IsEnabled() ) { long nHeight = (long) ( ((double) mlOldHeight * (double) mpMtrWidth->GetValue()) / (double) mlOldWidth ); if( nHeight <= mpMtrHeight->GetMax( FUNIT_NONE ) ) { mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE ); } else { nHeight = (long)mpMtrHeight->GetMax( FUNIT_NONE ); mpMtrHeight->SetUserValue( nHeight ); const long nWidth = (long) ( ((double) mlOldWidth * (double) nHeight) / (double) mlOldHeight ); mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE ); } } executeSize(); return 0; } IMPL_LINK( PosSizePropertyPanel, ChangeHeightHdl, void *, EMPTYARG ) { if( mpCbxScale->IsChecked() && mpCbxScale->IsEnabled() ) { long nWidth = (long) ( ((double)mlOldWidth * (double)mpMtrHeight->GetValue()) / (double)mlOldHeight ); if( nWidth <= mpMtrWidth->GetMax( FUNIT_NONE ) ) { mpMtrWidth->SetUserValue( nWidth, FUNIT_NONE ); } else { nWidth = (long)mpMtrWidth->GetMax( FUNIT_NONE ); mpMtrWidth->SetUserValue( nWidth ); const long nHeight = (long) ( ((double)mlOldHeight * (double)nWidth) / (double)mlOldWidth ); mpMtrHeight->SetUserValue( nHeight, FUNIT_NONE ); } } executeSize(); return 0; } IMPL_LINK( PosSizePropertyPanel, ChangePosXHdl, void *, EMPTYARG ) { executePosX(); return 0; } IMPL_LINK( PosSizePropertyPanel, ChangePosYHdl, void *, EMPTYARG ) { executePosY(); return 0; } IMPL_LINK( PosSizePropertyPanel, ClickAutoHdl, void *, EMPTYARG ) { if ( mpCbxScale->IsChecked() ) { mlOldWidth = Max( GetCoreValue( *mpMtrWidth, mePoolUnit ), 1L ); mlOldHeight = Max( GetCoreValue( *mpMtrHeight, mePoolUnit ), 1L ); } // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( RID_SVXPAGE_POSITION_SIZE ) ); aPageOpt.SetUserItem( USERITEM_NAME, ::com::sun::star::uno::makeAny( ::rtl::OUString( String::CreateFromInt32( mpCbxScale->IsChecked() ) ) ) ); return 0; } IMPL_LINK( PosSizePropertyPanel, AngleModifiedHdl, void *, EMPTYARG ) { String sTmp = mpMtrAngle->GetText(); bool bNegative = 0; sal_Unicode nChar = sTmp.GetChar( 0 ); if( nChar == '-' ) { bNegative = 1; nChar = sTmp.GetChar( 1 ); } if( (nChar < '0') || (nChar > '9') ) return 0; double dTmp = sTmp.ToDouble(); if(bNegative) { while(dTmp<0) dTmp += 360; } sal_Int64 nTmp = dTmp*100; // #123993# Need to take UIScale into account when executing rotations const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0); SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp); SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale)); SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale)); GetBindings()->GetDispatcher()->Execute( SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L ); return 0; } IMPL_LINK( PosSizePropertyPanel, RotationHdl, void *, EMPTYARG ) { sal_Int32 nTmp = mpDial->GetRotation(); // #123993# Need to take UIScale into account when executing rotations const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0); SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,(sal_uInt32) nTmp); SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale)); SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale)); GetBindings()->GetDispatcher()->Execute( SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aAngleItem, &aRotXItem, &aRotYItem, 0L ); return 0; } IMPL_LINK( PosSizePropertyPanel, FlipHdl, ToolBox*, pBox ) { switch (pBox->GetCurItemId()) { case FLIP_HORIZONTAL: { SfxVoidItem aHoriItem (SID_FLIP_HORIZONTAL); GetBindings()->GetDispatcher()->Execute( SID_FLIP_HORIZONTAL, SFX_CALLMODE_RECORD, &aHoriItem, 0L ); } break; case FLIP_VERTICAL: { SfxVoidItem aVertItem (SID_FLIP_VERTICAL ); GetBindings()->GetDispatcher()->Execute( SID_FLIP_VERTICAL, SFX_CALLMODE_RECORD, &aVertItem, 0L ); } break; } return 0; } void PosSizePropertyPanel::NotifyItemUpdate( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState, const bool /* bIsEnabled */) { mpFtAngle->Enable(); mpMtrAngle->Enable(); mpDial->Enable(); mpFtFlip->Enable(); mpFlipTbx->Enable(); const SfxUInt32Item* pWidthItem; const SfxUInt32Item* pHeightItem; SfxViewShell* pCurSh = SfxViewShell::Current(); if ( pCurSh ) mpView = pCurSh->GetDrawView(); else mpView = NULL; if ( mpView == NULL ) return; mbAdjustEnabled = hasText(*mpView); // Pool unit and dialog unit may have changed, make sure that we // have the current values. mePoolUnit = maTransfWidthControl.GetCoreMetric(); // #124409# do not change; GetModuleFieldUnit uses SfxModule::GetCurrentFieldUnit() // which uses GetActiveModule() and if no items are set there (which is the case e.g. // for writer), will just return the system fallback of FUNIT_INCH which is wrong. // Anyways, with multiple open views the static call GetActiveModule is ambigious // // meDlgUnit = GetModuleFieldUnit(); switch (nSID) { case SID_ATTR_TRANSFORM_WIDTH: if ( SFX_ITEM_AVAILABLE == eState ) { pWidthItem = dynamic_cast< const SfxUInt32Item* >(pState); if(pWidthItem) { long mlOldWidth1 = pWidthItem->GetValue(); mlOldWidth1 = Fraction( mlOldWidth1 ) / maUIScale; SetFieldUnit( *mpMtrWidth, meDlgUnit, true ); SetMetricValue( *mpMtrWidth, mlOldWidth1, mePoolUnit ); mlOldWidth = mlOldWidth1; break; } } mpMtrWidth->SetText( String()); break; case SID_ATTR_TRANSFORM_HEIGHT: if ( SFX_ITEM_AVAILABLE == eState ) { pHeightItem = dynamic_cast< const SfxUInt32Item* >(pState); if(pHeightItem) { long mlOldHeight1 = pHeightItem->GetValue(); mlOldHeight1 = Fraction( mlOldHeight1 ) / maUIScale; SetFieldUnit( *mpMtrHeight, meDlgUnit, true ); SetMetricValue( *mpMtrHeight, mlOldHeight1, mePoolUnit ); mlOldHeight = mlOldHeight1; break; } } mpMtrHeight->SetText( String()); break; case SID_ATTR_TRANSFORM_POS_X: if(SFX_ITEM_AVAILABLE == eState) { const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); if(pItem) { long nTmp = pItem->GetValue(); nTmp = Fraction( nTmp ) / maUIScale; SetFieldUnit( *mpMtrPosX, meDlgUnit, true ); SetMetricValue( *mpMtrPosX, nTmp, mePoolUnit ); break; } } mpMtrPosX->SetText( String()); break; case SID_ATTR_TRANSFORM_POS_Y: if(SFX_ITEM_AVAILABLE == eState) { const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); if(pItem) { long nTmp = pItem->GetValue(); nTmp = Fraction( nTmp ) / maUIScale; SetFieldUnit( *mpMtrPosY, meDlgUnit, true ); SetMetricValue( *mpMtrPosY, nTmp, mePoolUnit ); break; } } mpMtrPosY->SetText( String()); break; case SID_ATTR_TRANSFORM_ROT_X: if (SFX_ITEM_AVAILABLE == eState) { const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); if(pItem) { mlRotX = pItem->GetValue(); mlRotX = Fraction( mlRotX ) / maUIScale; } } break; case SID_ATTR_TRANSFORM_ROT_Y: if (SFX_ITEM_AVAILABLE == eState) { const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); if(pItem) { mlRotY = pItem->GetValue(); mlRotY = Fraction( mlRotY ) / maUIScale; } } break; case SID_ATTR_TRANSFORM_PROTECT_POS: if(SFX_ITEM_AVAILABLE == eState) { const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); if(pItem) { // record the state of position protect mbPositionProtected = pItem->GetValue(); break; } } mbPositionProtected = false; break; case SID_ATTR_TRANSFORM_PROTECT_SIZE: if(SFX_ITEM_AVAILABLE == eState) { const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); if(pItem) { // record the state of size protect mbSizeProtected = pItem->GetValue(); break; } } mbSizeProtected = false; break; case SID_ATTR_TRANSFORM_AUTOWIDTH: if(SFX_ITEM_AVAILABLE == eState) { const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); if(pItem) { mbAutoWidth = pItem->GetValue(); } } break; case SID_ATTR_TRANSFORM_AUTOHEIGHT: if(SFX_ITEM_AVAILABLE == eState) { const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); if(pItem) { mbAutoHeight = pItem->GetValue(); } } break; case SID_ATTR_TRANSFORM_ANGLE: if (eState >= SFX_ITEM_AVAILABLE) { const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); if(pItem) { long nTmp = pItem->GetValue(); mpMtrAngle->SetValue( nTmp ); mpDial->SetRotation( nTmp ); switch(nTmp) { case 0: mpMtrAngle->SelectEntryPos(0); break; case 4500: mpMtrAngle->SelectEntryPos(1); break; case 9000: mpMtrAngle->SelectEntryPos(2); break; case 13500: mpMtrAngle->SelectEntryPos(3); break; case 18000: mpMtrAngle->SelectEntryPos(4); break; case 22500: mpMtrAngle->SelectEntryPos(5); break; case 27000: mpMtrAngle->SelectEntryPos(6); break; case 315000: mpMtrAngle->SelectEntryPos(7); break; } break; } } mpMtrAngle->SetText( String() ); mpDial->SetRotation( 0 ); break; case SID_ATTR_METRIC: MetricState( eState, pState ); UpdateUIScale(); break; default: break; } const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI()); const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); switch (rMarkList.GetMarkCount()) { case 0: break; case 1: { const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw) || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject) ) && OBJ_EDGE == eKind) || OBJ_CAPTION == eKind) { mpFtAngle->Disable(); mpMtrAngle->Disable(); mpDial->Disable(); mpFlipTbx->Disable(); mpFtFlip->Disable(); } break; } default: { sal_uInt16 nMarkObj = 0; bool isNoEdge = true; while(isNoEdge && rMarkList.GetMark(nMarkObj)) { const SdrObject* pObj = rMarkList.GetMark(nMarkObj)->GetMarkedSdrObj(); const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier()); if(((nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_Draw) || nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject) ) && OBJ_EDGE == eKind) || OBJ_CAPTION == eKind) { isNoEdge = false; break; } nMarkObj++; } if(!isNoEdge) { mpFtAngle->Disable(); mpMtrAngle->Disable(); mpDial->Disable(); mpFlipTbx->Disable(); mpFtFlip->Disable(); } break; } } if(nCombinedContext == CombinedEnumContext(Application_DrawImpress, Context_TextObject)) { mpFlipTbx->Disable(); mpFtFlip->Disable(); } DisableControls(); // mpCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( RID_SVXPAGE_POSITION_SIZE ) ); String sUserData; ::com::sun::star::uno::Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); ::rtl::OUString aTemp; if ( aUserItem >>= aTemp ) sUserData = String( aTemp ); mpCbxScale->Check( (bool)sUserData.ToInt32() ); } SfxBindings* PosSizePropertyPanel::GetBindings() { return mpBindings; } void PosSizePropertyPanel::executeSize() { if ( mpMtrWidth->IsValueModified() || mpMtrHeight->IsValueModified()) { Fraction aUIScale = mpView->GetModel()->GetUIScale(); // get Width double nWidth = (double)mpMtrWidth->GetValue( meDlgUnit ); nWidth = MetricField::ConvertDoubleValue( nWidth, mpMtrWidth->GetBaseValue(), mpMtrWidth->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM ); long lWidth = (long)(nWidth * (double)aUIScale); lWidth = OutputDevice::LogicToLogic( lWidth, MAP_100TH_MM, (MapUnit)mePoolUnit ); lWidth = (long)mpMtrWidth->Denormalize( lWidth ); // get Height double nHeight = (double)mpMtrHeight->GetValue( meDlgUnit ); nHeight = MetricField::ConvertDoubleValue( nHeight, mpMtrHeight->GetBaseValue(), mpMtrHeight->GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM ); long lHeight = (long)(nHeight * (double)aUIScale); lHeight = OutputDevice::LogicToLogic( lHeight, MAP_100TH_MM, (MapUnit)mePoolUnit ); lHeight = (long)mpMtrWidth->Denormalize( lHeight ); // put Width & Height to itemset SfxUInt32Item aWidthItem( SID_ATTR_TRANSFORM_WIDTH, (sal_uInt32) lWidth); SfxUInt32Item aHeightItem( SID_ATTR_TRANSFORM_HEIGHT, (sal_uInt32) lHeight); SfxAllEnumItem aPointItem (SID_ATTR_TRANSFORM_SIZE_POINT, (sal_uInt16)meRP); const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI()); if( nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_Graphic) || nCombinedContext == CombinedEnumContext(Application_WriterVariants, Context_OLE) ) { GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L ); } else { if ( (mpMtrWidth->IsValueModified()) && (mpMtrHeight->IsValueModified())) GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aHeightItem, &aPointItem, 0L ); else if( mpMtrWidth->IsValueModified()) GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aWidthItem, &aPointItem, 0L ); else if ( mpMtrHeight->IsValueModified()) GetBindings()->GetDispatcher()->Execute(SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aHeightItem, &aPointItem, 0L ); } } } void PosSizePropertyPanel::executePosX() { if ( mpMtrPosX->IsValueModified()) { long lX = GetCoreValue( *mpMtrPosX, mePoolUnit ); if( mbMtrPosXMirror ) lX = -lX; long lY = GetCoreValue( *mpMtrPosY, mePoolUnit ); Size aPageSize; Rectangle aRect; maRect = mpView->GetAllMarkedRect(); aRect = mpView->GetAllMarkedRect(); Fraction aUIScale = mpView->GetModel()->GetUIScale(); lX += maAnchorPos.X(); lX = Fraction( lX ) * aUIScale; lY += maAnchorPos.Y(); lY = Fraction( lY ) * aUIScale; SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX); SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY); GetBindings()->GetDispatcher()->Execute( SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosXItem, 0L ); } } void PosSizePropertyPanel::executePosY() { if ( mpMtrPosY->IsValueModified() ) { long lX = GetCoreValue( *mpMtrPosX, mePoolUnit ); long lY = GetCoreValue( *mpMtrPosY, mePoolUnit ); Size aPageSize; Rectangle aRect; maRect = mpView->GetAllMarkedRect(); aRect = mpView->GetAllMarkedRect(); Fraction aUIScale = mpView->GetModel()->GetUIScale(); lX += maAnchorPos.X(); lX = Fraction( lX ) * aUIScale; lY += maAnchorPos.Y(); lY = Fraction( lY ) * aUIScale; SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,(sal_uInt32) lX); SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,(sal_uInt32) lY); GetBindings()->GetDispatcher()->Execute( SID_ATTR_TRANSFORM, SFX_CALLMODE_RECORD, &aPosYItem, 0L ); } } void PosSizePropertyPanel::MetricState( SfxItemState eState, const SfxPoolItem* pState ) { bool bPosXBlank = false; bool bPosYBlank = false; bool bWidthBlank = false; bool bHeightBlank = false; String sNull = String::CreateFromAscii(""); // #124409# use the given Item to get the correct UI unit and initialize it // and the Fields using it meDlgUnit = GetCurrentUnit(eState,pState); if( mpMtrPosX->GetText() == sNull ) bPosXBlank = true; SetFieldUnit( *mpMtrPosX, meDlgUnit, true ); if(bPosXBlank) mpMtrPosX->SetText(String()); if( mpMtrPosY->GetText() == sNull ) bPosYBlank = true; SetFieldUnit( *mpMtrPosY, meDlgUnit, true ); if(bPosYBlank) mpMtrPosY->SetText(String()); if( mpMtrWidth->GetText() == sNull ) bWidthBlank = true; SetFieldUnit( *mpMtrWidth, meDlgUnit, true ); if(bWidthBlank) mpMtrWidth->SetText(String()); if( mpMtrHeight->GetText() == sNull ) bHeightBlank = true; SetFieldUnit( *mpMtrHeight, meDlgUnit, true ); if(bHeightBlank) mpMtrHeight->SetText(String()); } FieldUnit PosSizePropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ) { FieldUnit eUnit = FUNIT_NONE; if ( pState && eState >= SFX_ITEM_DEFAULT ) { eUnit = (FieldUnit)( (const SfxUInt16Item*)pState )->GetValue(); } else { SfxViewFrame* pFrame = SfxViewFrame::Current(); SfxObjectShell* pSh = NULL; if ( pFrame ) pSh = pFrame->GetObjectShell(); if ( pSh ) { SfxModule* pModule = pSh->GetModule(); if ( pModule ) { const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC ); if ( pItem ) eUnit = (FieldUnit)( (SfxUInt16Item*)pItem )->GetValue(); } else { DBG_ERRORFILE( "GetModuleFieldUnit(): no module found" ); } } } return eUnit; } void PosSizePropertyPanel::DisableControls() { if( mbPositionProtected ) { // the position is protected("Position protect" option in modal dialog is checked), // disable all the Position controls in sidebar mpFtPosX->Disable(); mpMtrPosX->Disable(); mpFtPosY->Disable(); mpMtrPosY->Disable(); mpFtAngle->Disable(); mpMtrAngle->Disable(); mpDial->Disable(); mpFtFlip->Disable(); mpFlipTbx->Disable(); mpFtWidth->Disable(); mpMtrWidth->Disable(); mpFtHeight->Disable(); mpMtrHeight->Disable(); mpCbxScale->Disable(); } else { mpFtPosX->Enable(); mpMtrPosX->Enable(); mpFtPosY->Enable(); mpMtrPosY->Enable(); //mpFtAngle->Enable(); //mpMtrAngle->Enable(); //mpDial->Enable(); //mpFtFlip->Enable(); //mpFlipTbx->Enable(); if( mbSizeProtected ) { mpFtWidth->Disable(); mpMtrWidth->Disable(); mpFtHeight->Disable(); mpMtrHeight->Disable(); mpCbxScale->Disable(); } else { if( mbAdjustEnabled ) { if( mbAutoWidth ) { mpFtWidth->Disable(); mpMtrWidth->Disable(); mpCbxScale->Disable(); } else { mpFtWidth->Enable(); mpMtrWidth->Enable(); } if( mbAutoHeight ) { mpFtHeight->Disable(); mpMtrHeight->Disable(); mpCbxScale->Disable(); } else { mpFtHeight->Enable(); mpMtrHeight->Enable(); } if( !mbAutoWidth && !mbAutoHeight ) mpCbxScale->Enable(); } else { mpFtWidth->Enable(); mpMtrWidth->Enable(); mpFtHeight->Enable(); mpMtrHeight->Enable(); mpCbxScale->Enable(); } } } } void PosSizePropertyPanel::UpdateUIScale (void) { const Fraction aUIScale (mpView->GetModel()->GetUIScale()); if (maUIScale != aUIScale) { // UI scale has changed. // Remember the new UI scale. maUIScale = aUIScale; // The content of the position and size boxes is only updated when item changes are notified. // Request such notifications without changing the actual item values. GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_X, sal_True, sal_False); GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_Y, sal_True, sal_False); GetBindings()->Invalidate(SID_ATTR_TRANSFORM_WIDTH, sal_True, sal_False); GetBindings()->Invalidate(SID_ATTR_TRANSFORM_HEIGHT, sal_True, sal_False); } } } } // end of namespace svx::sidebar // eof