| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_chart2.hxx" |
| #include "DrawViewWrapper.hxx" |
| #include "chartview/DrawModelWrapper.hxx" |
| #include "ConfigurationAccess.hxx" |
| #include "macros.hxx" |
| |
| #include <unotools/lingucfg.hxx> |
| #include <editeng/langitem.hxx> |
| // header for class SdrPage |
| #include <svx/svdpage.hxx> |
| //header for class SdrPageView |
| #include <svx/svdpagv.hxx> |
| // header for class SdrModel |
| #include <svx/svdmodel.hxx> |
| // header for class E3dScene |
| #include <svx/scene3d.hxx> |
| #include <svx/svdetc.hxx> |
| #include <svx/svdoutl.hxx> |
| |
| // header for class SvxForbiddenCharactersTable |
| #include <editeng/forbiddencharacterstable.hxx> |
| |
| #ifndef _SVX_SVXIDS_HRC |
| #include <svx/svxids.hrc> |
| #endif |
| |
| // header for class SvxShape |
| #include <svx/unoshape.hxx> |
| #include <editeng/fhgtitem.hxx> |
| |
| #include <com/sun/star/container/XChild.hpp> |
| #include <com/sun/star/lang/XUnoTunnel.hpp> |
| |
| #include <sfx2/objsh.hxx> |
| #include <svx/helperhittest3d.hxx> |
| |
| using namespace ::com::sun::star; |
| |
| //............................................................................. |
| namespace chart |
| { |
| //............................................................................. |
| |
| namespace |
| { |
| short lcl_getHitTolerance( OutputDevice* pOutDev ) |
| { |
| const short HITPIX=2; //hit-tolerance in pixel |
| short nHitTolerance = 50; |
| if(pOutDev) |
| nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width()); |
| return nHitTolerance; |
| } |
| |
| // this code is copied from sfx2/source/doc/objembed.cxx |
| SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel ) |
| { |
| SfxObjectShell* pResult = NULL; |
| |
| try |
| { |
| uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY ); |
| if ( xChildModel.is() ) |
| { |
| uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY ); |
| if ( xParentTunnel.is() ) |
| { |
| SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID ); |
| pResult = reinterpret_cast< SfxObjectShell * >( |
| xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) ); |
| } |
| } |
| } |
| catch( uno::Exception& ) |
| { |
| // TODO: error handling |
| } |
| |
| return pResult; |
| } |
| |
| // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to |
| // get the reference device (e.g. printer) fromthe parent document |
| OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel ) |
| { |
| SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel ); |
| if ( pParent ) |
| return pParent->GetDocumentRefDev(); |
| return NULL; |
| } |
| |
| } |
| |
| /* |
| void lcl_initOutliner( SdrOutliner* pTargetOutliner, SdrOutliner* pSourceOutliner ) |
| { |
| //just an unsuccessful try to initialize the text edit outliner correctly |
| //if( bInit ) |
| { |
| pTargetOutliner->EraseVirtualDevice(); |
| pTargetOutliner->SetUpdateMode(sal_False); |
| pTargetOutliner->SetEditTextObjectPool( pSourceOutliner->GetEditTextObjectPool() ); |
| pTargetOutliner->SetDefTab( pSourceOutliner->GetDefTab() ); |
| } |
| |
| pTargetOutliner->SetRefDevice( pSourceOutliner->GetRefDevice() ); |
| pTargetOutliner->SetForbiddenCharsTable( pSourceOutliner->GetForbiddenCharsTable() ); |
| pTargetOutliner->SetAsianCompressionMode( pSourceOutliner->GetAsianCompressionMode() ); |
| pTargetOutliner->SetKernAsianPunctuation( pSourceOutliner->IsKernAsianPunctuation() ); |
| pTargetOutliner->SetStyleSheetPool( pSourceOutliner->GetStyleSheetPool() ); |
| pTargetOutliner->SetRefMapMode( pSourceOutliner->GetRefMapMode() ); |
| pTargetOutliner->SetDefaultLanguage( pSourceOutliner->GetDefaultLanguage() ); |
| pTargetOutliner->SetHyphenator( pSourceOutliner->GetHyphenator() ); |
| |
| sal_uInt16 nX, nY; |
| pSourceOutliner->GetGlobalCharStretching( nX, nY ); |
| pTargetOutliner->SetGlobalCharStretching( nX, nY ); |
| |
| *//* |
| if ( !GetRefDevice() ) |
| { |
| MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit); |
| pTargetOutliner->SetRefMapMode(aMapMode); |
| } |
| *//* |
| } |
| */ |
| |
| DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut, bool bPaintPageForEditMode) |
| : E3dView(pSdrModel, pOut) |
| , m_pMarkHandleProvider(NULL) |
| , m_apOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pSdrModel ) ) |
| , m_bRestoreMapMode( false ) |
| { |
| // #114898# |
| SetBufferedOutputAllowed(true); |
| SetBufferedOverlayAllowed(true); |
| |
| SetPagePaintingAllowed(bPaintPageForEditMode); |
| |
| // #i12587# support for shapes in chart |
| SdrOutliner* pOutliner = getOutliner(); |
| SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : NULL ); |
| if ( pOutlinerPool ) |
| { |
| SvtLinguConfig aLinguConfig; |
| SvtLinguOptions aLinguOptions; |
| if ( aLinguConfig.GetOptions( aLinguOptions ) ) |
| { |
| pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) ); |
| pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) ); |
| pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) ); |
| } |
| |
| // set font height without changing SdrEngineDefaults |
| pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt |
| } |
| |
| // #121463# Use big handles by default |
| SetMarkHdlSizePixel(9); |
| |
| ReInit(); |
| } |
| |
| void DrawViewWrapper::ReInit() |
| { |
| OutputDevice* pOutDev = this->GetFirstOutputDevice(); |
| Size aOutputSize(100,100); |
| if(pOutDev) |
| aOutputSize = pOutDev->GetOutputSize(); |
| |
| bPageVisible = false; |
| bPageBorderVisible = false; |
| bBordVisible = false; |
| bGridVisible = false; |
| bHlplVisible = false; |
| |
| this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object) |
| //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix |
| |
| //a correct work area is at least necessary for correct values in the position and size dialog |
| Rectangle aRect(Point(0,0), aOutputSize); |
| this->SetWorkArea(aRect); |
| |
| this->ShowSdrPage(this->GetModel()->GetPage(0)); |
| } |
| |
| DrawViewWrapper::~DrawViewWrapper() |
| { |
| aComeBackTimer.Stop();//@todo this should be done in destructor of base class |
| UnmarkAllObj();//necessary to aavoid a paint call during the destructor hierarchy |
| } |
| |
| SdrPageView* DrawViewWrapper::GetPageView() const |
| { |
| SdrPageView* pSdrPageView = this->GetSdrPageView(); |
| return pSdrPageView; |
| }; |
| |
| //virtual |
| void DrawViewWrapper::SetMarkHandles() |
| { |
| if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) ) |
| return; |
| else |
| SdrView::SetMarkHandles(); |
| } |
| |
| SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const |
| { |
| SdrObject* pRet = NULL; |
| //sal_uLong nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST; |
| sal_uLong nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE; |
| |
| SdrPageView* pSdrPageView = this->GetPageView(); |
| this->SdrView::PickObj(rPnt, lcl_getHitTolerance( this->GetFirstOutputDevice() ), pRet, pSdrPageView, nOptions); |
| |
| if( pRet ) |
| { |
| //ignore some special shapes |
| rtl::OUString aShapeName = pRet->GetName(); |
| if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) ) |
| { |
| pRet->SetMarkProtect( true ); |
| return getHitObject( rPnt ); |
| } |
| |
| //3d objects need a special treatment |
| //because the simple PickObj method is not accurate in this case for performance reasons |
| E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet); |
| if( pE3d ) |
| { |
| E3dScene* pScene = pE3d->GetScene(); |
| if( pScene ) |
| { |
| // prepare result vector and call helper |
| ::std::vector< const E3dCompoundObject* > aHitList; |
| const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y()); |
| getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList); |
| |
| if(aHitList.size()) |
| { |
| // choose the frontmost hit 3D object of the scene |
| pRet = const_cast< E3dCompoundObject* >(aHitList[0]); |
| } |
| } |
| } |
| } |
| return pRet; |
| } |
| |
| void DrawViewWrapper::MarkObject( SdrObject* pObj ) |
| { |
| bool bFrameDragSingles = true;//true == green == surrounding handles |
| if(pObj) |
| pObj->SetMarkProtect(false); |
| if( m_pMarkHandleProvider ) |
| bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles(); |
| |
| this->SetFrameDragSingles(bFrameDragSingles);//decide wether each single object should get handles |
| this->SdrView::MarkObj( pObj, this->GetPageView() ); |
| this->showMarkHandles(); |
| } |
| |
| |
| void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider ) |
| { |
| m_pMarkHandleProvider = pMarkHandleProvider; |
| } |
| |
| void DrawViewWrapper::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* /* pRedirector */) |
| { |
| svtools::ColorConfig aColorConfig; |
| Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor ); |
| this->SetApplicationBackgroundColor(aFillColor); |
| this->E3dView::CompleteRedraw( pOut, rReg ); |
| } |
| |
| SdrObject* DrawViewWrapper::getSelectedObject() const |
| { |
| SdrObject* pObj(NULL); |
| const SdrMarkList& rMarkList = this->GetMarkedObjectList(); |
| if(rMarkList.GetMarkCount() == 1) |
| { |
| SdrMark* pMark = rMarkList.GetMark(0); |
| pObj = pMark->GetMarkedSdrObj(); |
| } |
| return pObj; |
| } |
| |
| SdrObject* DrawViewWrapper::getTextEditObject() const |
| { |
| SdrObject* pObj = this->getSelectedObject(); |
| SdrObject* pTextObj = NULL; |
| if( pObj && pObj->HasTextEdit()) |
| pTextObj = (SdrTextObj*)pObj; |
| return pTextObj; |
| } |
| |
| void DrawViewWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel ) |
| { |
| OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel )); |
| SdrOutliner * pOutliner( getOutliner()); |
| if( pParentRefDev && pOutliner ) |
| { |
| pOutliner->SetRefDevice( pParentRefDev ); |
| } |
| } |
| |
| SdrOutliner* DrawViewWrapper::getOutliner() const |
| { |
| // lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() ); |
| return m_apOutliner.get(); |
| } |
| |
| SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const |
| { |
| SfxItemSet aFullSet( GetModel()->GetItemPool(), |
| SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_ANGLE, |
| SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_AUTOHEIGHT, |
| SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, |
| SID_ATTR_METRIC, SID_ATTR_METRIC, |
| 0); |
| SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() ); |
| aFullSet.Put( aGeoSet ); |
| aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,static_cast< sal_uInt16 >( ConfigurationAccess::getFieldUnit()))); |
| return aFullSet; |
| } |
| |
| SdrObject* DrawViewWrapper::getNamedSdrObject( const rtl::OUString& rName ) const |
| { |
| if( rName.isEmpty() ) |
| return 0; |
| SdrPageView* pSdrPageView = this->GetPageView(); |
| if( pSdrPageView ) |
| { |
| return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() ); |
| } |
| return 0; |
| } |
| |
| bool DrawViewWrapper::IsObjectHit( SdrObject* pObj, const Point& rPnt ) const |
| { |
| if(pObj) |
| { |
| Rectangle aRect(pObj->GetCurrentBoundRect()); |
| return aRect.IsInside(rPnt); |
| } |
| return false; |
| } |
| |
| void DrawViewWrapper::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) |
| { |
| //prevent wrong reselection of objects |
| SdrModel* pSdrModel( this->GetModel() ); |
| if( pSdrModel && pSdrModel->isLocked() ) |
| return; |
| |
| const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint ); |
| |
| //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created ) |
| SdrPageView* pSdrPageView = this->GetPageView(); |
| if( pSdrHint && pSdrPageView ) |
| { |
| if( pSdrPageView->GetPage() != pSdrHint->GetPage() ) |
| return; |
| } |
| |
| E3dView::Notify(rBC, rHint); |
| |
| if( pSdrHint != 0 ) |
| { |
| SdrHintKind eKind = pSdrHint->GetKind(); |
| if( eKind == HINT_BEGEDIT ) |
| { |
| // #i79965# remember map mode |
| OSL_ASSERT( ! m_bRestoreMapMode ); |
| OutputDevice* pOutDev = this->GetFirstOutputDevice(); |
| if( pOutDev ) |
| { |
| m_aMapModeToRestore = pOutDev->GetMapMode(); |
| m_bRestoreMapMode = true; |
| } |
| } |
| else if( eKind == HINT_ENDEDIT ) |
| { |
| // #i79965# scroll back view when ending text edit |
| OSL_ASSERT( m_bRestoreMapMode ); |
| if( m_bRestoreMapMode ) |
| { |
| OutputDevice* pOutDev = this->GetFirstOutputDevice(); |
| if( pOutDev ) |
| { |
| pOutDev->SetMapMode( m_aMapModeToRestore ); |
| m_bRestoreMapMode = false; |
| } |
| } |
| } |
| } |
| } |
| |
| SdrObject* DrawViewWrapper::getSdrObject( const uno::Reference< |
| drawing::XShape >& xShape ) |
| { |
| SdrObject* pRet = 0; |
| uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY ); |
| uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY ); |
| if(xUnoTunnel.is()&&xTypeProvider.is()) |
| { |
| SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() )); |
| if(pSvxShape) |
| pRet = pSvxShape->GetSdrObject(); |
| } |
| return pRet; |
| } |
| |
| //............................................................................. |
| } //namespace chart |
| //............................................................................. |