/************************************************************** * * 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_sd.hxx" #include #include #include "View.hxx" #include #include #include #include #include #ifndef _SVX_SVXIDS_HRC #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "app.hrc" #include "strings.hrc" #include "Window.hxx" #include "Client.hxx" #include "drawdoc.hxx" #include "DrawDocShell.hxx" #include "app.hxx" #include "sdpage.hxx" #include "glob.hrc" #include "sdresid.hxx" #include "DrawViewShell.hxx" #include "futext.hxx" #include "fuinsfil.hxx" #include "slideshow.hxx" #include "stlpool.hxx" #include "FrameView.hxx" #include "ViewClipboard.hxx" #include "undo/undomanager.hxx" #include #include #include #include #include "EventMultiplexer.hxx" #include "ViewShellBase.hxx" #include "ViewShellManager.hxx" #include #include #include #include #include #include #include #include #include #include #include #include "DrawController.hxx" #include using namespace com::sun::star; using namespace com::sun::star::uno; using namespace sdr::table; namespace sd { #ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED #define SO2_DECL_SVINPLACEOBJECT_DEFINED SO2_DECL_REF(SvInPlaceObject) #endif TYPEINIT1(View, FmFormView); /************************************************************************* |* |* Ctor |* \************************************************************************/ View::View(SdDrawDocument* pDrawDoc, OutputDevice* pOutDev, ViewShell* pViewShell) : FmFormView(pDrawDoc, pOutDev), mpDoc(pDrawDoc), mpDocSh( pDrawDoc->GetDocSh() ), mpViewSh(pViewShell), mpDragSrcMarkList(NULL), mpDropMarkerObj(NULL), mpDropMarker(NULL), mnDragSrcPgNum(SDRPAGE_NOTFOUND), mnAction(DND_ACTION_NONE), mnLockRedrawSmph(0), mpLockedRedraws(NULL), mbIsDropAllowed(sal_True), maSmartTags(*this), mpClipboard (new ViewClipboard (*this)) { // #i73602# Use default from the configuration SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_DrawImpress()); // #i74769#, #i75172# Use default from the configuration SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_DrawImpress()); EnableExtendedKeyInputDispatcher(sal_False); EnableExtendedMouseEventDispatcher(sal_False); EnableExtendedCommandEventDispatcher(sal_False); SetUseIncompatiblePathCreateInterface(sal_False); SetMarkHdlWhenTextEdit(sal_True); EnableTextEditOnObjectsWithoutTextIfTextTool(sal_True); SetMinMoveDistancePixel(2); SetHitTolerancePixel(2); SetMeasureLayer(String(SdResId(STR_LAYER_MEASURELINES))); // Timer fuer verzoegertes Drop (muss fuer MAC sein) maDropErrorTimer.SetTimeoutHdl( LINK(this, View, DropErrorHdl) ); maDropErrorTimer.SetTimeout(50); maDropInsertFileTimer.SetTimeoutHdl( LINK(this, View, DropInsertFileHdl) ); maDropInsertFileTimer.SetTimeout(50); } void View::ImplClearDrawDropMarker() { if(mpDropMarker) { delete mpDropMarker; mpDropMarker = 0L; } } /************************************************************************* |* |* Dtor |* \************************************************************************/ View::~View() { maSmartTags.Dispose(); // release content of selection clipboard, if we own the content UpdateSelectionClipboard( sal_True ); maDropErrorTimer.Stop(); maDropInsertFileTimer.Stop(); ImplClearDrawDropMarker(); while(PaintWindowCount()) { // Alle angemeldeten OutDevs entfernen DeleteWindowFromPaintView(GetFirstOutputDevice() /*GetWin(0)*/); } // gespeicherte Redraws loeschen if (mpLockedRedraws) { SdViewRedrawRec* pRec = (SdViewRedrawRec*)mpLockedRedraws->First(); while (pRec) { delete pRec; pRec = (SdViewRedrawRec*)mpLockedRedraws->Next(); } delete mpLockedRedraws; } } class ViewRedirector : public ::sdr::contact::ViewObjectContactRedirector { public: ViewRedirector(); virtual ~ViewRedirector(); // all default implementations just call the same methods at the original. To do something // different, overload the method and at least do what the method does. virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence( const sdr::contact::ViewObjectContact& rOriginal, const sdr::contact::DisplayInfo& rDisplayInfo); }; ViewRedirector::ViewRedirector() { } ViewRedirector::~ViewRedirector() { } drawinglayer::primitive2d::Primitive2DSequence ViewRedirector::createRedirectedPrimitive2DSequence( const sdr::contact::ViewObjectContact& rOriginal, const sdr::contact::DisplayInfo& rDisplayInfo) { SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); drawinglayer::primitive2d::Primitive2DSequence xRetval; if(pObject && pObject->GetPage()) { const bool bDoCreateGeometry(pObject->GetPage()->checkVisibility( rOriginal, rDisplayInfo, true )); if(!bDoCreateGeometry && !(( pObject->GetObjInventor() == SdrInventor ) && ( pObject->GetObjIdentifier() == OBJ_PAGE )) ) return xRetval; PresObjKind eKind(PRESOBJ_NONE); const bool bSubContentProcessing(rDisplayInfo.GetSubContentActive()); const bool bIsMasterPageObject(pObject->GetPage()->IsMasterPage()); const bool bIsPrinting(rOriginal.GetObjectContact().isOutputToPrinter()); const SdrPageView* pPageView = rOriginal.GetObjectContact().TryToGetSdrPageView(); const SdrPage* pVisualizedPage = GetSdrPageFromXDrawPage(rOriginal.GetObjectContact().getViewInformation2D().getVisualizedPage()); const SdPage* pObjectsSdPage = dynamic_cast< SdPage* >(pObject->GetPage()); const bool bIsInsidePageObj(pPageView && pPageView->GetPage() != pVisualizedPage); // check if we need to draw a placeholder border. Never do it for // objects inside a SdrPageObj and never when printing if(!bIsInsidePageObj && !bIsPrinting) { bool bCreateOutline(false); if( pObject->IsEmptyPresObj() && pObject->ISA(SdrTextObj) ) { if( !bSubContentProcessing || !pObject->IsNotVisibleAsMaster() ) { eKind = pObjectsSdPage ? pObjectsSdPage->GetPresObjKind(pObject) : PRESOBJ_NONE; bCreateOutline = true; } } else if( ( pObject->GetObjInventor() == SdrInventor ) && ( pObject->GetObjIdentifier() == OBJ_TEXT ) ) { if( pObjectsSdPage ) { eKind = pObjectsSdPage->GetPresObjKind(pObject); if((eKind == PRESOBJ_FOOTER) || (eKind == PRESOBJ_HEADER) || (eKind == PRESOBJ_DATETIME) || (eKind == PRESOBJ_SLIDENUMBER) ) { if( !bSubContentProcessing ) { // only draw a boundary for header&footer objects on the masterpage itself bCreateOutline = true; } } } } else if( ( pObject->GetObjInventor() == SdrInventor ) && ( pObject->GetObjIdentifier() == OBJ_PAGE ) ) { // only for handout page, else this frame will be created for each // page preview object in SlideSorter and PagePane if(pObjectsSdPage && PK_HANDOUT == pObjectsSdPage->GetPageKind()) { bCreateOutline = true; } } if(bCreateOutline) { // empty presentation objects get a gray frame const svtools::ColorConfig aColorConfig; const svtools::ColorConfigValue aColor( aColorConfig.GetColorValue( svtools::OBJECTBOUNDARIES ) ); if( aColor.bIsVisible ) { // get basic object transformation const basegfx::BColor aRGBColor(Color(aColor.nColor).getBColor()); basegfx::B2DHomMatrix aObjectMatrix; basegfx::B2DPolyPolygon aObjectPolyPolygon; pObject->TRGetBaseGeometry(aObjectMatrix, aObjectPolyPolygon); // create dashed border { // create object polygon basegfx::B2DPolygon aPolygon(basegfx::tools::createUnitPolygon()); aPolygon.transform(aObjectMatrix); // create line and stroke attribute ::std::vector< double > aDotDashArray; aDotDashArray.push_back(160.0); aDotDashArray.push_back(80.0); const double fFullDotDashLen(::std::accumulate(aDotDashArray.begin(), aDotDashArray.end(), 0.0)); const drawinglayer::attribute::LineAttribute aLine(aRGBColor); const drawinglayer::attribute::StrokeAttribute aStroke(aDotDashArray, fFullDotDashLen); // create primitive and add const drawinglayer::primitive2d::Primitive2DReference xRef(new drawinglayer::primitive2d::PolygonStrokePrimitive2D( aPolygon, aLine, aStroke)); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xRef); } // now paint the placeholder description, but only when masterpage // is displayed as page directly (MasterPage view) if(!bSubContentProcessing && bIsMasterPageObject) { String aObjectString; switch( eKind ) { case PRESOBJ_TITLE: { if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PK_STANDARD) { static String aTitleAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_TITLE ) ); aObjectString = aTitleAreaStr; } break; } case PRESOBJ_OUTLINE: { static String aOutlineAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_OUTLINE ) ); aObjectString = aOutlineAreaStr; break; } case PRESOBJ_FOOTER: { static String aFooterAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_FOOTER ) ); aObjectString = aFooterAreaStr; break; } case PRESOBJ_HEADER: { static String aHeaderAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_HEADER ) ); aObjectString = aHeaderAreaStr; break; } case PRESOBJ_DATETIME: { static String aDateTimeStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_DATETIME ) ); aObjectString = aDateTimeStr; break; } case PRESOBJ_NOTES: { static String aDateTimeStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_NOTES ) ); aObjectString = aDateTimeStr; break; } case PRESOBJ_SLIDENUMBER: { if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PK_STANDARD) { static String aSlideAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_SLIDE ) ); aObjectString = aSlideAreaStr; } else { static String aNumberAreaStr( SdResId( STR_PLACEHOLDER_DESCRIPTION_NUMBER ) ); aObjectString = aNumberAreaStr; } break; } default: { break; } } if( aObjectString.Len() ) { // decompose object matrix to be able to place text correctly basegfx::B2DTuple aScale; basegfx::B2DTuple aTranslate; double fRotate, fShearX; aObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); // create font SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObject ); const SdrTextVertAdjust eTVA(pTextObj ? pTextObj->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_CENTER); Font aScaledVclFont; // use a text size factor to get more reliable text sizes from the text layouter // (and from vcl), tipp from HDU static sal_uInt32 nTextSizeFactor(100); // use a factor to get more linear text size calculations aScaledVclFont.SetHeight( 500 * nTextSizeFactor ); // get basic geometry and get text size drawinglayer::primitive2d::TextLayouterDevice aTextLayouter; aTextLayouter.setFont(aScaledVclFont); const xub_StrLen nTextLength(aObjectString.Len()); // do not forget to use the factor again to get the width for the 500 const double fTextWidth(aTextLayouter.getTextWidth(aObjectString, 0, nTextLength) * (1.0 / nTextSizeFactor)); const double fTextHeight(aTextLayouter.getTextHeight() * (1.0 / nTextSizeFactor)); // calculate text primitive position. If text is at bottom, use top for // the extra text and vice versa const double fHorDist(125); const double fVerDist(125); const double fPosX((aTranslate.getX() + aScale.getX()) - fTextWidth - fHorDist); const double fPosY((SDRTEXTVERTADJUST_BOTTOM == eTVA) ? aTranslate.getY() - fVerDist + fTextHeight : (aTranslate.getY() + aScale.getY()) - fVerDist); // get font attributes; use normally scaled font const basegfx::BColor aFontColor(aRGBColor); Font aVclFont; basegfx::B2DVector aTextSizeAttribute; aVclFont.SetHeight( 500 ); const drawinglayer::attribute::FontAttribute aFontAttribute( drawinglayer::primitive2d::getFontAttributeFromVclFont( aTextSizeAttribute, aVclFont, false, false)); // fill text matrix const basegfx::B2DHomMatrix aTextMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( aTextSizeAttribute.getX(), aTextSizeAttribute.getY(), fShearX, fRotate, fPosX, fPosY)); // create DXTextArray (can be empty one) const ::std::vector< double > aDXArray; // create locale; this may need some more information in the future const ::com::sun::star::lang::Locale aLocale; // create primitive and add const drawinglayer::primitive2d::Primitive2DReference xRef( new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( aTextMatrix, aObjectString, 0, nTextLength, aDXArray, aFontAttribute, aLocale, aFontColor)); drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xRef); } } } } } if(bDoCreateGeometry) { drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence( xRetval, sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( rOriginal, rDisplayInfo)); } } else { // not a SdrObject visualisation (maybe e.g. page) or no page xRetval = sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo); } return xRetval; } /************************************************************************* |* |* Paint-Methode: das Ereignis wird an die View weitergeleitet |* \************************************************************************/ void View::CompleteRedraw(OutputDevice* pOutDev, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector /*=0L*/) { // ausfuehren ?? if (mnLockRedrawSmph == 0) { SdrPageView* pPgView = GetSdrPageView(); if (pPgView) { SdPage* pPage = (SdPage*) pPgView->GetPage(); if( pPage ) { SdrOutliner& rOutl=mpDoc->GetDrawOutliner(NULL); bool bScreenDisplay(true); if(bScreenDisplay && pOutDev && OUTDEV_PRINTER == pOutDev->GetOutDevType()) { // #i75566# printing; suppress AutoColor BackgroundColor generation // for visibility reasons by giving GetPageBackgroundColor() // the needed hint bScreenDisplay = false; } if(bScreenDisplay && pOutDev && pOutDev->GetPDFWriter()) { // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see above) bScreenDisplay = false; } // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and // hint value if screen display. Only then the AutoColor mechanisms shall be applied rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor(pPgView, bScreenDisplay) ); } } ViewRedirector aViewRedirector; FmFormView::CompleteRedraw(pOutDev, rReg, pRedirector ? pRedirector : &aViewRedirector); } // oder speichern? else { if (!mpLockedRedraws) mpLockedRedraws = new List; SdViewRedrawRec* pRec = new SdViewRedrawRec; pRec->mpOut = pOutDev; pRec->aRect = rReg.GetBoundRect(); mpLockedRedraws->Insert(pRec, LIST_APPEND); } } /************************************************************************* |* |* Selektion hat sich geaendert |* \************************************************************************/ void View::MarkListHasChanged() { FmFormView::MarkListHasChanged(); if( GetMarkedObjectCount() > 0 ) maSmartTags.deselect(); } /************************************************************************* |* |* Attribute setzen |* \************************************************************************/ sal_Bool View::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll) { sal_Bool bOk = FmFormView::SetAttributes(rSet, bReplaceAll); return (bOk); } /************************************************************************* |* |* Attribute holen |* \************************************************************************/ sal_Bool View::GetAttributes( SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr ) const { return( FmFormView::GetAttributes( rTargetSet, bOnlyHardAttr ) ); } /************************************************************************* |* |* Ist ein Praesentationsobjekt selektiert? |* \************************************************************************/ sal_Bool View::IsPresObjSelected(sal_Bool bOnPage, sal_Bool bOnMasterPage, sal_Bool bCheckPresObjListOnly, sal_Bool bCheckLayoutOnly) const { /************************************************************************** * Ist ein Presentationsobjekt selektiert? **************************************************************************/ SdrMarkList* pMarkList; if (mnDragSrcPgNum != SDRPAGE_NOTFOUND && mnDragSrcPgNum != GetSdrPageView()->GetPage()->GetPageNum()) { // Es laeuft gerade Drag&Drop // Source- und Destination-Page unterschiedlich: // es wird die gemerkte MarkList verwendet pMarkList = mpDragSrcMarkList; } else { // Es wird die aktuelle MarkList verwendet pMarkList = new SdrMarkList(GetMarkedObjectList()); } SdrMark* pMark; SdPage* pPage; SdrObject* pObj; sal_Bool bSelected = sal_False; sal_Bool bMasterPage = sal_False; long nMark; long nMarkMax = long(pMarkList->GetMarkCount()) - 1; for (nMark = nMarkMax; (nMark >= 0) && !bSelected; nMark--) { // Rueckwaerts durch die Marklist pMark = pMarkList->GetMark(nMark); pObj = pMark->GetMarkedSdrObj(); if ( pObj && ( bCheckPresObjListOnly || pObj->IsEmptyPresObj() || pObj->GetUserCall() ) ) { pPage = (SdPage*) pObj->GetPage(); bMasterPage = pPage->IsMasterPage(); if ( (bMasterPage && bOnMasterPage) || (!bMasterPage && bOnPage) ) { if ( pPage && pPage->IsPresObj(pObj) ) { if( bCheckLayoutOnly ) { PresObjKind eKind = pPage->GetPresObjKind(pObj); if((eKind != PRESOBJ_FOOTER) && (eKind != PRESOBJ_HEADER) && (eKind != PRESOBJ_DATETIME) && (eKind != PRESOBJ_SLIDENUMBER) ) bSelected = sal_True; } else { bSelected = sal_True; } } } } } if (pMarkList != mpDragSrcMarkList) { delete pMarkList; } return (bSelected); } /************************************************************************* |* |* Alles selektieren |* \************************************************************************/ void View::SelectAll() { if ( IsTextEdit() ) { OutlinerView* pOLV = GetTextEditOutlinerView(); const ::Outliner* pOutliner = GetTextEditOutliner(); pOLV->SelectRange( 0, pOutliner->GetParagraphCount() ); } else { MarkAll(); } } /************************************************************************* |* |* Dokument hat sich geaendert |* \************************************************************************/ void View::ModelHasChanged() { // Erst SdrView benachrichtigen FmFormView::ModelHasChanged(); } /************************************************************************* |* |* StyleSheet setzen |* \************************************************************************/ sal_Bool View::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr) { // weiter an SdrView return FmFormView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr); } /************************************************************************* |* |* Texteingabe beginnen |* \************************************************************************/ static void SetSpellOptions( SdDrawDocument* pDoc, sal_uLong& rCntrl ) { sal_Bool bOnlineSpell = pDoc->GetOnlineSpell(); if( bOnlineSpell ) rCntrl |= EE_CNTRL_ONLINESPELLING; else rCntrl &= ~EE_CNTRL_ONLINESPELLING; } sal_Bool View::SdrBeginTextEdit( SdrObject* pObj, SdrPageView* pPV, ::Window* pWin, sal_Bool bIsNewObj, SdrOutliner* pOutl, OutlinerView* pGivenOutlinerView, sal_Bool bDontDeleteOutliner, sal_Bool bOnlyOneView, sal_Bool bGrabFocus ) { GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent( sd::tools::EventMultiplexerEvent::EID_BEGIN_TEXT_EDIT, (void*)pObj ); if( pOutl==NULL && pObj ) pOutl = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pObj->GetModel() ); // make draw&impress specific initialisations if( pOutl ) { pOutl->SetStyleSheetPool((SfxStyleSheetPool*) mpDoc->GetStyleSheetPool()); pOutl->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl)); sal_uLong nCntrl = pOutl->GetControlWord(); nCntrl |= EE_CNTRL_ALLOWBIGOBJS; nCntrl |= EE_CNTRL_URLSFXEXECUTE; nCntrl |= EE_CNTRL_MARKFIELDS; nCntrl |= EE_CNTRL_AUTOCORRECT; nCntrl &= ~EE_CNTRL_ULSPACESUMMATION; if ( mpDoc->IsSummationOfParagraphs() ) nCntrl |= EE_CNTRL_ULSPACESUMMATION; SetSpellOptions( mpDoc, nCntrl ); pOutl->SetControlWord(nCntrl); Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() ); if ( xSpellChecker.is() ) pOutl->SetSpeller( xSpellChecker ); Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() ); if( xHyphenator.is() ) pOutl->SetHyphenator( xHyphenator ); pOutl->SetDefaultLanguage( Application::GetSettings().GetLanguage() ); } sal_Bool bReturn = FmFormView::SdrBeginTextEdit( pObj, pPV, pWin, bIsNewObj, pOutl, pGivenOutlinerView, bDontDeleteOutliner, bOnlyOneView, bGrabFocus); if ( mpViewSh ) { mpViewSh->GetViewShellBase().GetDrawController().FireSelectionChangeListener(); } if (bReturn) { ::Outliner* pOL = GetTextEditOutliner(); if( pObj && pObj->GetPage() ) { Color aBackground; if( pObj->GetObjInventor() == SdrInventor && pObj->GetObjIdentifier() == OBJ_TABLE ) { aBackground = GetTextEditBackgroundColor(*this); } else { aBackground = pObj->GetPage()->GetPageBackgroundColor(pPV); } if (pOL != NULL) pOL->SetBackgroundColor( aBackground ); } if (pOL != NULL) { pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl)); pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl)); } } return(bReturn); } /** ends current text editing */ SdrEndTextEditKind View::SdrEndTextEdit(sal_Bool bDontDeleteReally ) { SdrObjectWeakRef xObj( GetTextEditObject() ); sal_Bool bDefaultTextRestored = RestoreDefaultText( dynamic_cast< SdrTextObj* >( GetTextEditObject() ) ); SdrEndTextEditKind eKind = FmFormView::SdrEndTextEdit(bDontDeleteReally); if( bDefaultTextRestored ) { if( xObj.is() && !xObj->IsEmptyPresObj() ) { xObj->SetEmptyPresObj( sal_True ); } else { eKind = SDRENDTEXTEDIT_UNCHANGED; } } else if( xObj.is() && xObj->IsEmptyPresObj() ) { SdrTextObj* pObj = dynamic_cast< SdrTextObj* >( xObj.get() ); if( pObj && pObj->HasText() ) { SdrPage* pPage = pObj->GetPage(); if( !pPage || !pPage->IsMasterPage() ) pObj->SetEmptyPresObj( sal_False ); } } GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent( sd::tools::EventMultiplexerEvent::EID_END_TEXT_EDIT, (void*)xObj.get() ); if( xObj.is() ) { if ( mpViewSh ) { mpViewSh->GetViewShellBase().GetDrawController().FireSelectionChangeListener(); } SdPage* pPage = dynamic_cast< SdPage* >( xObj->GetPage() ); if( pPage ) pPage->onEndTextEdit( xObj.get() ); } return(eKind); } // -------------------------------------------------------------------- /** restores the default text if the given text object is currently in edit mode and no text has been entered already. Is only useful just before text edit ends. */ bool View::RestoreDefaultText( SdrTextObj* pTextObj ) { bool bRestored = false; if( pTextObj && (pTextObj == GetTextEditObject()) ) { if( !pTextObj->HasText() ) { SdPage* pPage = dynamic_cast< SdPage* >( pTextObj->GetPage() ); if(pPage) { bRestored = pPage->RestoreDefaultText( pTextObj ); if( bRestored ) { SdrOutliner* pOutliner = GetTextEditOutliner(); pTextObj->SetTextEditOutliner( pOutliner ); OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); if (pOutliner) pOutliner->SetText(*pParaObj); } } } } return bRestored; } /************************************************************************* |* |* Originalgroesse der markierten Objekte setzen |* \************************************************************************/ void View::SetMarkedOriginalSize() { SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*mpDoc); sal_uLong nCount = GetMarkedObjectCount(); sal_Bool bOK = sal_False; for( sal_uInt32 i = 0; i < nCount; i++ ) { SdrObject* pObj = GetMarkedObjectByIndex(i); if( pObj->GetObjInventor() == SdrInventor ) { if( pObj->GetObjIdentifier() == OBJ_OLE2 ) { uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObj)->GetObjRef(); if( xObj.is() ) { // TODO/LEAN: working with VisualArea can switch object to running state sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect(); Size aOleSize; if ( nAspect == embed::Aspects::MSOLE_ICON ) { MapMode aMap100( MAP_100TH_MM ); aOleSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMap100 ); bOK = sal_True; } else { MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); try { awt::Size aSz = xObj->getVisualAreaSize( nAspect ); aOleSize = OutputDevice::LogicToLogic( Size( aSz.Width, aSz.Height ), aUnit, MAP_100TH_MM ); bOK = sal_True; } catch( embed::NoVisualAreaSizeException& ) {} } if ( bOK ) { Rectangle aDrawRect( pObj->GetLogicRect() ); pUndoGroup->AddAction( mpDoc->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) ); pObj->Resize( aDrawRect.TopLeft(), Fraction( aOleSize.Width(), aDrawRect.GetWidth() ), Fraction( aOleSize.Height(), aDrawRect.GetHeight() ) ); } } } else if( pObj->GetObjIdentifier() == OBJ_GRAF ) { const MapMode aMap100( MAP_100TH_MM ); Size aSize; if ( static_cast< SdrGrafObj* >( pObj )->GetGrafPrefMapMode().GetMapUnit() == MAP_PIXEL ) aSize = Application::GetDefaultDevice()->PixelToLogic( static_cast< SdrGrafObj* >( pObj )->GetGrafPrefSize(), aMap100 ); else { aSize = OutputDevice::LogicToLogic( static_cast< SdrGrafObj* >( pObj )->GetGrafPrefSize(), static_cast< SdrGrafObj* >( pObj )->GetGrafPrefMapMode(), aMap100 ); } pUndoGroup->AddAction( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj ) ); Rectangle aRect( pObj->GetLogicRect() ); aRect.SetSize( aSize ); pObj->SetLogicRect( aRect ); bOK = sal_True; } } } if( bOK ) { pUndoGroup->SetComment( String(SdResId(STR_UNDO_ORIGINALSIZE)) ); mpDocSh->GetUndoManager()->AddUndoAction(pUndoGroup); } else delete pUndoGroup; } /************************************************************************* |* |* OLE-Obj am Client connecten |* \************************************************************************/ void View::DoConnect(SdrOle2Obj* pObj) { if (mpViewSh) { uno::Reference < embed::XEmbeddedObject > xObj( pObj->GetObjRef() ); if( xObj.is() ) { ::sd::Window* pWindow = mpViewSh->GetActiveWindow(); SfxInPlaceClient* pSdClient = mpViewSh-> GetViewShellBase().FindIPClient( xObj, pWindow ); if ( !pSdClient ) { pSdClient = new Client(pObj, mpViewSh, pWindow); Rectangle aRect = pObj->GetLogicRect(); { // TODO/LEAN: working with visual area can switch object to running state Size aDrawSize = aRect.GetSize(); awt::Size aSz; MapMode aMapMode( mpDoc->GetScaleUnit() ); Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode ); Fraction aScaleWidth (aDrawSize.Width(), aObjAreaSize.Width() ); Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() ); aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj aScaleHeight.ReduceInaccurate(10); pSdClient->SetSizeScale(aScaleWidth, aScaleHeight); // sichtbarer Ausschnitt wird nur inplace veraendert! // the object area must be set after the scaling, since it triggers resize aRect.SetSize(aObjAreaSize); pSdClient->SetObjArea(aRect); } } } } } /************************************************************************* |* |* |* \************************************************************************/ sal_Bool View::IsMorphingAllowed() const { const SdrMarkList& rMarkList = GetMarkedObjectList(); sal_Bool bRet = sal_False; if ( rMarkList.GetMarkCount() == 2 ) { const SdrObject* pObj1 = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); const SdrObject* pObj2 = rMarkList.GetMark( 1 )->GetMarkedSdrObj(); const sal_uInt16 nKind1 = pObj1->GetObjIdentifier(); const sal_uInt16 nKind2 = pObj2->GetObjIdentifier(); if ( ( nKind1 != OBJ_TEXT && nKind2 != OBJ_TEXT ) && ( nKind1 != OBJ_TITLETEXT && nKind2 != OBJ_TITLETEXT ) && ( nKind1 != OBJ_OUTLINETEXT && nKind2 != OBJ_OUTLINETEXT ) && ( nKind1 != OBJ_GRUP && nKind2 != OBJ_GRUP ) && ( nKind1 != OBJ_LINE && nKind2 != OBJ_LINE ) && ( nKind1 != OBJ_PLIN && nKind2 != OBJ_PLIN ) && ( nKind1 != OBJ_PATHLINE && nKind2 != OBJ_PATHLINE ) && ( nKind1 != OBJ_FREELINE && nKind2 != OBJ_FREELINE ) && ( nKind1 != OBJ_PATHPLIN && nKind2 != OBJ_PATHPLIN ) && ( nKind1 != OBJ_MEASURE && nKind2 != OBJ_MEASURE ) && ( nKind1 != OBJ_EDGE && nKind2 != OBJ_EDGE ) && ( nKind1 != OBJ_GRAF && nKind2 != OBJ_GRAF ) && ( nKind1 != OBJ_OLE2 && nKind2 != OBJ_OLE2 ) && ( nKind1 != OBJ_CAPTION && nKind2 != OBJ_CAPTION ) && !pObj1->ISA( E3dObject) && !pObj2->ISA( E3dObject) ) { SfxItemSet aSet1( mpDoc->GetPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE ); SfxItemSet aSet2( mpDoc->GetPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE ); aSet1.Put(pObj1->GetMergedItemSet()); aSet2.Put(pObj2->GetMergedItemSet()); const XFillStyle eFillStyle1 = ( (const XFillStyleItem&) aSet1.Get( XATTR_FILLSTYLE ) ).GetValue(); const XFillStyle eFillStyle2 = ( (const XFillStyleItem&) aSet2.Get( XATTR_FILLSTYLE ) ).GetValue(); if( ( eFillStyle1 == XFILL_NONE || eFillStyle1 == XFILL_SOLID ) && ( eFillStyle2 == XFILL_NONE || eFillStyle2 == XFILL_SOLID ) ) bRet = sal_True; } } return bRet; } /************************************************************************* |* |* |* \************************************************************************/ sal_Bool View::IsVectorizeAllowed() const { const SdrMarkList& rMarkList = GetMarkedObjectList(); sal_Bool bRet = sal_False; if( rMarkList.GetMarkCount() == 1 ) { const SdrGrafObj* pObj = dynamic_cast< const SdrGrafObj* >(rMarkList.GetMark( 0 )->GetMarkedSdrObj()); if(pObj) { if(GRAPHIC_BITMAP == pObj->GetGraphicType() && !pObj->isEmbeddedSvg()) { bRet = sal_True; } } } return bRet; } void View::onAccessibilityOptionsChanged() { if( mpViewSh ) { ::sd::Window* pWindow = mpViewSh->GetActiveWindow(); if( pWindow ) { const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings(); sal_uInt16 nOutputSlot, nPreviewSlot; SvtAccessibilityOptions& aAccOptions = getAccessibilityOptions(); if( mpViewSh->GetViewFrame() && mpViewSh->GetViewFrame()->GetDispatcher() ) { if( rStyleSettings.GetHighContrastMode() ) { nOutputSlot = SID_OUTPUT_QUALITY_CONTRAST; } else { nOutputSlot = SID_OUTPUT_QUALITY_COLOR; } if( rStyleSettings.GetHighContrastMode() && aAccOptions.GetIsForPagePreviews() ) { nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST; } else { nPreviewSlot = SID_PREVIEW_QUALITY_COLOR; } mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nOutputSlot, SFX_CALLMODE_ASYNCHRON ); mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nPreviewSlot, SFX_CALLMODE_ASYNCHRON ); } mpViewSh->Invalidate(); } } } IMPL_LINK( View, OnParagraphInsertedHdl, ::Outliner *, pOutliner ) { Paragraph* pPara = pOutliner->GetHdlParagraph(); SdrObject* pObj = GetTextEditObject(); if( pPara && pObj ) { SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() ); if( pPage ) pPage->onParagraphInserted( pOutliner, pPara, pObj ); } return 0; } /************************************************************************* |* |* Handler fuer das Loeschen von Seiten (Absaetzen) |* \************************************************************************/ IMPL_LINK( View, OnParagraphRemovingHdl, ::Outliner *, pOutliner ) { Paragraph* pPara = pOutliner->GetHdlParagraph(); SdrObject* pObj = GetTextEditObject(); if( pPara && pObj ) { SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() ); if( pPage ) pPage->onParagraphRemoving( pOutliner, pPara, pObj ); } return 0; } bool View::isRecordingUndo() const { if( mpDoc && mpDoc->IsUndoEnabled() ) { sd::UndoManager* pUndoManager = mpDoc ? mpDoc->GetUndoManager() : 0; return pUndoManager && pUndoManager->IsInListAction(); } else { return false; } } void View::AddCustomHdl() { maSmartTags.addCustomHandles( aHdl ); } void View::updateHandles() { AdjustMarkHdl(); } SdrViewContext View::GetContext() const { SdrViewContext eContext = SDRCONTEXT_STANDARD; if( maSmartTags.getContext( eContext ) ) return eContext; else return FmFormView::GetContext(); } sal_Bool View::HasMarkablePoints() const { if( maSmartTags.HasMarkablePoints() ) return true; else return FmFormView::HasMarkablePoints(); } sal_uLong View::GetMarkablePointCount() const { sal_uLong nCount = FmFormView::GetMarkablePointCount(); nCount += maSmartTags.GetMarkablePointCount(); return nCount; } sal_Bool View::HasMarkedPoints() const { if( maSmartTags.HasMarkedPoints() ) return true; else return FmFormView::HasMarkedPoints(); } sal_uLong View::GetMarkedPointCount() const { sal_uLong nCount = FmFormView::GetMarkedPointCount(); nCount += maSmartTags.GetMarkedPointCount(); return nCount; } sal_Bool View::IsPointMarkable(const SdrHdl& rHdl) const { if( maSmartTags.IsPointMarkable( rHdl ) ) return true; else return FmFormView::IsPointMarkable( rHdl ); } sal_Bool View::MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark ) { if( maSmartTags.MarkPoint( rHdl, bUnmark ) ) return true; else return FmFormView::MarkPoint( rHdl, bUnmark ); } sal_Bool View::MarkPoints(const Rectangle* pRect, sal_Bool bUnmark) { if( maSmartTags.MarkPoints( pRect, bUnmark ) ) return true; else return FmFormView::MarkPoints( pRect, bUnmark ); } void View::CheckPossibilities() { FmFormView::CheckPossibilities(); maSmartTags.CheckPossibilities(); } void View::OnBeginPasteOrDrop( PasteOrDropInfos* /*pInfos*/ ) { } /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs get the correct style sheet. */ void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfos ) { SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( GetTextEditObject() ); SdrOutliner* pOutliner = GetTextEditOutliner(); if( pOutliner && pTextObj && pTextObj->GetPage() ) { SdPage* pPage = static_cast< SdPage* >( pTextObj->GetPage() ); SfxStyleSheet* pStyleSheet = 0; const PresObjKind eKind = pPage->GetPresObjKind(pTextObj); if( eKind != PRESOBJ_NONE ) pStyleSheet = pPage->GetStyleSheetForPresObj(eKind); else pStyleSheet = pTextObj->GetStyleSheet(); if( eKind == PRESOBJ_OUTLINE ) { // for outline shapes, set the correct outline style sheet for each // new paragraph, depending on the paragraph depth SfxStyleSheetBasePool* pStylePool = GetDoc()->GetStyleSheetPool(); for ( sal_uInt16 nPara = pInfos->nStartPara; nPara <= pInfos->nEndPara; nPara++ ) { sal_Int16 nDepth = pOutliner->GetDepth( nPara ); SfxStyleSheet* pStyle = 0; if( nDepth > 0 ) { String aStyleSheetName( pStyleSheet->GetName() ); aStyleSheetName.Erase( aStyleSheetName.Len() - 1, 1 ); aStyleSheetName += String::CreateFromInt32( nDepth ); pStyle = static_cast( pStylePool->Find( aStyleSheetName, pStyleSheet->GetFamily() ) ); DBG_ASSERT( pStyle, "sd::View::OnEndPasteOrDrop(), Style not found!" ); } if( !pStyle ) pStyle = pStyleSheet; pOutliner->SetStyleSheet( nPara, pStyle ); } } else { // just put the object style on each new paragraph for ( sal_uInt16 nPara = pInfos->nStartPara; nPara <= pInfos->nEndPara; nPara++ ) { pOutliner->SetStyleSheet( nPara, pStyleSheet ); } } } } bool View::ShouldToggleOn( const bool bBulletOnOffMode, const bool bNormalBullet) { // If setting bullets/numbering by the dialog, always should toggle on. if (!bBulletOnOffMode) return sal_True; SdrModel* pSdrModel = GetModel(); if (!pSdrModel) return sal_False; sal_Bool bToggleOn = sal_False; SdrOutliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, pSdrModel); sal_uInt32 nMarkCount = GetMarkedObjectCount(); for (sal_uInt32 nIndex = 0; nIndex < nMarkCount && !bToggleOn; nIndex++) { SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex)); if (!pTextObj || pTextObj->IsTextEditActive()) continue; if (pTextObj->ISA(SdrTableObj)) { SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj); if (!pTableObj) continue; CellPos aStart, aEnd; SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get()); if (pTableController) { pTableController->getSelectedCells(aStart, aEnd); } else { aStart = pTableObj->getFirstCell(); aEnd = pTableObj->getLastCell(); } sal_Int32 nColCount = pTableObj->getColumnCount(); for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow && !bToggleOn; nRow++) { for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol && !bToggleOn; nCol++) { sal_Int32 nIndex = nRow * nColCount + nCol; SdrText* pText = pTableObj->getText(nIndex); if (!pText || !pText->GetOutlinerParaObject()) continue; pOutliner->SetText(*(pText->GetOutlinerParaObject())); sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus(); bToggleOn = ((bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1)) ? sal_True : bToggleOn; pOutliner->Clear(); } } } else { OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); if (!pParaObj) continue; pOutliner->SetText(*pParaObj); sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus(); bToggleOn = ((bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1)) ? sal_True : bToggleOn; pOutliner->Clear(); } } delete pOutliner; return bToggleOn; } void View::ChangeMarkedObjectsBulletsNumbering( const bool bToggle, const bool bHandleBullets, const SvxNumRule* pNumRule, const bool bSwitchOff ) { SdrModel* pSdrModel = GetModel(); Window* pWindow = dynamic_cast< Window* >(GetFirstOutputDevice()); if (!pSdrModel || !pWindow) return; const bool bUndoEnabled = pSdrModel->IsUndoEnabled(); SdrUndoGroup* pUndoGroup = bUndoEnabled ? new SdrUndoGroup(*pSdrModel) : 0; const bool bToggleOn = bSwitchOff ? false : ShouldToggleOn( bToggle, bHandleBullets ); SdrOutliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, pSdrModel); OutlinerView* pOutlinerView = new OutlinerView(pOutliner, pWindow); const sal_uInt32 nMarkCount = GetMarkedObjectCount(); for (sal_uInt32 nIndex = 0; nIndex < nMarkCount; nIndex++) { SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex)); if (!pTextObj || pTextObj->IsTextEditActive()) continue; if (pTextObj->ISA(SdrTableObj)) { SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj); if (!pTableObj) continue; CellPos aStart, aEnd; SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get()); if (pTableController) { pTableController->getSelectedCells(aStart, aEnd); } else { aStart = pTableObj->getFirstCell(); aEnd = pTableObj->getLastCell(); } sal_Int32 nColCount = pTableObj->getColumnCount(); for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++) { for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++) { sal_Int32 nIndex = nRow * nColCount + nCol; SdrText* pText = pTableObj->getText(nIndex); if (!pText || !pText->GetOutlinerParaObject()) continue; pOutliner->SetText(*(pText->GetOutlinerParaObject())); if (bUndoEnabled) { SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nIndex)); pUndoGroup->AddAction(pTxtUndo); } if ( !bToggleOn ) { pOutlinerView->SwitchOffBulletsNumbering(); } else { pOutlinerView->ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle ); } sal_uInt32 nParaCount = pOutliner->GetParagraphCount(); pText->SetOutlinerParaObject(pOutliner->CreateParaObject(0, nParaCount)); pOutliner->Clear(); } } // Broadcast the object change event. if (!pTextObj->AdjustTextFrameWidthAndHeight()) { pTextObj->SetChanged(); pTextObj->BroadcastObjectChange(); } } else { OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); if (!pParaObj) continue; pOutliner->SetText(*pParaObj); if (bUndoEnabled) { SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, 0)); pUndoGroup->AddAction(pTxtUndo); } if ( !bToggleOn ) { pOutlinerView->SwitchOffBulletsNumbering(); } else { pOutlinerView->ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle ); } sal_uInt32 nParaCount = pOutliner->GetParagraphCount(); pTextObj->SetOutlinerParaObject(pOutliner->CreateParaObject(0, nParaCount)); pOutliner->Clear(); } } if ( bUndoEnabled && pUndoGroup->GetActionCount() > 0 ) { pSdrModel->BegUndo(); pSdrModel->AddUndo(pUndoGroup); pSdrModel->EndUndo(); } delete pOutliner; delete pOutlinerView; } } // end of namespace sd