/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // -> #111827# #include #include // <- #111827# #include #include #include "PostItMgr.hxx" #include "FrameControlsManager.hxx" #include #include #include using namespace sw::mark; using namespace com::sun::star; #define COMMON_INI_LIST \ m_fnDrag(&SwWrtShell::BeginDrag),\ m_fnSetCursor(&SwWrtShell::SetCursor),\ m_fnEndDrag(&SwWrtShell::DefaultEndDrag),\ m_fnKillSel(&SwWrtShell::Ignore),\ m_pModeStack(nullptr), \ m_ePageMove(MV_NO),\ m_pCursorStack(nullptr), \ m_rView(rShell),\ m_aNavigationMgr(*this), \ m_bDestOnStack(false) #define BITFLD_INI_LIST \ m_bClearMark = \ m_bIns = true;\ m_bAddMode = \ m_bBlockMode = \ m_bExtMode = \ m_bInSelect = \ m_bCopy = \ m_bLayoutMode = \ m_bSelWrd = \ m_bSelLn = \ m_bRetainSelection = false; \ m_bIsInClickToEdit = false; static SvxAutoCorrect* lcl_IsAutoCorr() { SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect(); if( pACorr && !pACorr->IsAutoCorrFlag( CapitalStartSentence | CapitalStartWord | AddNonBrkSpace | ChgOrdinalNumber | ChgToEnEmDash | SetINetAttr | Autocorrect )) pACorr = nullptr; return pACorr; } void SwWrtShell::NoEdit(bool bHideCursor) { if(bHideCursor) HideCursor(); } void SwWrtShell::Edit() { if (CanInsert()) { ShowCursor(); } } bool SwWrtShell::IsEndWrd() { SwMvContext aMvContext(this); if(IsEndPara() && !IsSttPara()) return true; return IsEndWord(); } // Insert string void SwWrtShell::InsertByWord( const OUString & rStr) { if( !rStr.isEmpty() ) { bool bDelim = GetAppCharClass().isLetterNumeric( rStr, 0 ); sal_Int32 nPos = 0, nStt = 0; for( ; nPos < rStr.getLength(); nPos++ ) { bool bTmpDelim = GetAppCharClass().isLetterNumeric( rStr, nPos ); if( bTmpDelim != bDelim ) { Insert( rStr.copy( nStt, nPos - nStt )); nStt = nPos; } } if( nStt != nPos ) Insert( rStr.copy( nStt, nPos - nStt )); } } void SwWrtShell::Insert( const OUString &rStr ) { ResetCursorStack(); if( !CanInsert() ) return; bool bStarted = false; bool bHasSel = HasSelection(), bCallIns = m_bIns /*|| bHasSel*/; bool bDeleted = false; if( bHasSel || ( !m_bIns && SelectHiddenRange() ) ) { // Only here parenthesizing, because the normal // insert is already in parentheses at Editshell. StartAllAction(); SwRewriter aRewriter; aRewriter.AddRule(UndoArg1, GetCursorDescr()); aRewriter.AddRule(UndoArg2, OUString(SW_RES(STR_YIELDS))); { OUString aTmpStr; aTmpStr += SW_RES(STR_START_QUOTE); aTmpStr += rStr; aTmpStr += SW_RES(STR_END_QUOTE); aRewriter.AddRule(UndoArg3, rStr); } StartUndo(UNDO_REPLACE, &aRewriter); bStarted = true; bDeleted = DelRight() != 0; } bCallIns ? SwEditShell::Insert2( rStr, bDeleted ) : SwEditShell::Overwrite( rStr ); if( bStarted ) { EndAllAction(); EndUndo(); } } // Maximum height limit not possible, because the maximum height // of the current frame can not be obtained. void SwWrtShell::Insert( const OUString &rPath, const OUString &rFilter, const Graphic &rGrf, SwFlyFrameAttrMgr *pFrameMgr, sal_uInt16 nAnchorType ) { ResetCursorStack(); if ( !CanInsert() ) return; StartAllAction(); SwRewriter aRewriter; aRewriter.AddRule(UndoArg1, SW_RES(STR_GRAPHIC)); StartUndo(UNDO_INSERT, &aRewriter); if ( HasSelection() ) DelRight(); // Inserted graphics in its own paragraph, // if at the end of a non-empty paragraph. //For i120928,avoid to split node EnterSelFrameMode(); bool bSetGrfSize = true; bool bOwnMgr = false; if ( !pFrameMgr ) { bOwnMgr = true; pFrameMgr = new SwFlyFrameAttrMgr( true, this, Frmmgr_Type::GRF ); // CAUTION // GetAttrSet makes an adjustment // While pasting is a SwFrameSize present // because of the DEF-Framesize // These must be removed explicitly for the optimal size. pFrameMgr->DelAttr(RES_FRM_SIZE); if (nAnchorType != 0) // Something other than at-para was requested. pFrameMgr->SetAnchor(static_cast(nAnchorType)); } else { Size aSz( pFrameMgr->GetSize() ); if ( !aSz.Width() || !aSz.Height() ) { aSz.Width() = aSz.Height() = 567; pFrameMgr->SetSize( aSz ); } else if ( aSz.Width() != DFLT_WIDTH && aSz.Height() != DFLT_HEIGHT ) bSetGrfSize = false; pFrameMgr->SetHeightSizeType(ATT_FIX_SIZE); } // Insert the graphic SwFEShell::Insert(rPath, rFilter, &rGrf, &pFrameMgr->GetAttrSet()); if ( bOwnMgr ) pFrameMgr->UpdateAttrMgr(); if( bSetGrfSize ) { Size aGrfSize, aBound = GetGraphicDefaultSize(); GetGrfSize( aGrfSize ); // Add the margin attributes to GrfSize, // because these counts at the margin additionally aGrfSize.Width() += pFrameMgr->CalcWidthBorder(); aGrfSize.Height()+= pFrameMgr->CalcHeightBorder(); const BigInt aTempWidth( aGrfSize.Width() ); const BigInt aTempHeight( aGrfSize.Height()); // Fit width if necessary, scale down the height proportional thereafter. if( aGrfSize.Width() > aBound.Width() ) { aGrfSize.Width() = aBound.Width(); aGrfSize.Height() = BigInt(aBound.Width()) * aTempHeight / aTempWidth; } // Fit hight if necessary, scale down the width proportional thereafter. if( aGrfSize.Height() > aBound.Height() ) { aGrfSize.Height() = aBound.Height(); aGrfSize.Width() = BigInt(aBound.Height()) * aTempWidth / aTempHeight; } pFrameMgr->SetSize( aGrfSize ); pFrameMgr->UpdateFlyFrame(); } if ( bOwnMgr ) delete pFrameMgr; EndUndo(); EndAllAction(); } // Insert an OLE-Objekt into the CORE. // if no object is transferred, then one will be created. void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef& xRef, SvGlobalName *pName, sal_uInt16 nSlotId ) { ResetCursorStack(); if( !CanInsert() ) return; if( !xRef.is() ) { // temporary storage svt::EmbeddedObjectRef xObj; uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetTemporaryStorage(); bool bDoVerb = true; if ( pName ) { comphelper::EmbeddedObjectContainer aCnt( xStor ); OUString aName; // TODO/LATER: get aspect? xObj.Assign( aCnt.CreateEmbeddedObject( pName->GetByteSequence(), aName ), embed::Aspects::MSOLE_CONTENT ); } else { SvObjectServerList aServerList; switch (nSlotId) { case SID_INSERT_OBJECT: { aServerList.FillInsertObjects(); aServerList.Remove( SwDocShell::Factory().GetClassId() ); SAL_FALLTHROUGH; } // TODO/LATER: recording! Convert properties to items case SID_INSERT_FLOATINGFRAME: { SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool(); const SfxSlot* pSlot = pSlotPool->GetSlot(nSlotId); OString aCmd(".uno:"); aCmd += pSlot->GetUnoName(); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); std::unique_ptr pDlg( pFact->CreateInsertObjectDialog( GetWin(), OUString::fromUtf8( aCmd ), xStor, &aServerList )); if ( pDlg ) { pDlg->Execute(); bDoVerb = pDlg->IsCreateNew(); OUString aIconMediaType; uno::Reference< io::XInputStream > xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType ); xObj.Assign( pDlg->GetObject(), xIconMetaFile.is() ? embed::Aspects::MSOLE_ICON : embed::Aspects::MSOLE_CONTENT ); if ( xIconMetaFile.is() ) xObj.SetGraphicStream( xIconMetaFile, aIconMediaType ); } break; } default: break; } } if ( xObj.is() ) { if( InsertOleObject( xObj ) && bDoVerb ) { SfxInPlaceClient* pClient = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() ); if ( !pClient ) { pClient = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj ); SetCheckForOLEInCaption( true ); } if ( xObj.GetViewAspect() == embed::Aspects::MSOLE_ICON ) { SwRect aArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, nullptr, xObj.GetObject() ); aArea.Pos() += GetAnyCurRect( RECT_FLY_EMBEDDED, nullptr, xObj.GetObject() ).Pos(); MapMode aMapMode( MapUnit::MapTwip ); Size aSize = xObj.GetSize( &aMapMode ); aArea.Width( aSize.Width() ); aArea.Height( aSize.Height() ); RequestObjectResize( aArea, xObj.GetObject() ); } else CalcAndSetScale( xObj ); //#50270# We don't need to handle error, this is handled by the //DoVerb in the SfxViewShell pClient->DoVerb(embed::EmbedVerbs::MS_OLEVERB_SHOW); // TODO/LATER: set document name - should be done in Client } } } else { if( HasSelection() ) DelRight(); InsertOleObject( xRef ); } } // Insert object into the Core. // From ClipBoard or Insert bool SwWrtShell::InsertOleObject( const svt::EmbeddedObjectRef& xRef, SwFlyFrameFormat **pFlyFrameFormat ) { ResetCursorStack(); StartAllAction(); StartUndo(UNDO_INSERT); //Some differences between StarMath and any other objects: //1. Selections should be deleted. For StarMath the Text should be // passed to the Object //2. If the cursor is at the end of an non empty paragraph a paragraph // break should be insertet. StarMath objects are character bound and // no break should be inserted. //3. If an selection is passed to a StarMath object, this object should // not be activated. false should be returned then. bool bStarMath = true; bool bActivate = true; // set parent to get correct VisArea(in case of object needing parent printer) uno::Reference < container::XChild > xChild( xRef.GetObject(), uno::UNO_QUERY ); if ( xChild.is() ) xChild->setParent( mpDoc->GetDocShell()->GetModel() ); SvGlobalName aCLSID( xRef->getClassID() ); bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 ); if( IsSelection() ) { if( bStarMath ) { OUString aMathData; GetSelectedText( aMathData, GETSELTXT_PARABRK_TO_ONLYCR ); if( !aMathData.isEmpty() && svt::EmbeddedObjectRef::TryRunningState( xRef.GetObject() ) ) { uno::Reference < beans::XPropertySet > xSet( xRef->getComponent(), uno::UNO_QUERY ); if ( xSet.is() ) { try { xSet->setPropertyValue("Formula", uno::makeAny( OUString( aMathData ) ) ); bActivate = false; } catch (const uno::Exception&) { } } } } DelRight(); } if ( !bStarMath ) SwFEShell::SplitNode( false, false ); EnterSelFrameMode(); SwFlyFrameAttrMgr aFrameMgr( true, this, Frmmgr_Type::OLE ); aFrameMgr.SetHeightSizeType(ATT_FIX_SIZE); SwRect aBound; CalcBoundRect( aBound, aFrameMgr.GetAnchor() ); //The Size should be suggested by the OLE server MapMode aMapMode( MapUnit::MapTwip ); Size aSz = xRef.GetSize( &aMapMode ); //Object size can be limited if ( aSz.Width() > aBound.Width() ) { //Always limit proportional. aSz.Height() = aSz.Height() * aBound.Width() / aSz.Width(); aSz.Width() = aBound.Width(); } aFrameMgr.SetSize( aSz ); SwFlyFrameFormat *pFormat = SwFEShell::InsertObject( xRef, &aFrameMgr.GetAttrSet() ); // --> #i972# if ( bStarMath && mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT ) ) AlignFormulaToBaseline( xRef.GetObject() ); if (pFlyFrameFormat) *pFlyFrameFormat = pFormat; if ( SotExchange::IsChart( aCLSID ) ) { uno::Reference< embed::XEmbeddedObject > xEmbeddedObj( xRef.GetObject(), uno::UNO_QUERY ); if ( xEmbeddedObj.is() ) { bool bDisableDataTableDialog = false; svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); if ( xProps.is() && ( xProps->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog ) && bDisableDataTableDialog ) { xProps->setPropertyValue("DisableDataTableDialog", uno::makeAny( false ) ); xProps->setPropertyValue("DisableComplexChartTypes", uno::makeAny( false ) ); uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY ); if ( xModifiable.is() ) { xModifiable->setModified( true ); } } } } EndAllAction(); GetView().AutoCaption(OLE_CAP, &aCLSID); SwRewriter aRewriter; if ( bStarMath ) aRewriter.AddRule(UndoArg1, SW_RES(STR_MATH_FORMULA)); else if ( SotExchange::IsChart( aCLSID ) ) aRewriter.AddRule(UndoArg1, SW_RES(STR_CHART)); else aRewriter.AddRule(UndoArg1, SW_RES(STR_OLE)); EndUndo(UNDO_INSERT, &aRewriter); return bActivate; } // The current selected OLE object will be loaded with the // verb into the server. void SwWrtShell::LaunchOLEObj( long nVerb ) { if ( GetCntType() == CNT_OLE && !GetView().GetViewFrame()->GetFrame().IsInPlace() ) { svt::EmbeddedObjectRef& xRef = GetOLEObject(); OSL_ENSURE( xRef.is(), "OLE not found" ); SfxInPlaceClient* pCli=nullptr; pCli = GetView().FindIPClient( xRef.GetObject(), &GetView().GetEditWin() ); if ( !pCli ) pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xRef ); static_cast(pCli)->SetInDoVerb( true ); CalcAndSetScale( xRef ); pCli->DoVerb( nVerb ); static_cast(pCli)->SetInDoVerb( false ); CalcAndSetScale( xRef ); } } void SwWrtShell::MoveObjectIfActive( svt::EmbeddedObjectRef& xObj, const Point& rOffset ) { try { sal_Int32 nState = xObj->getCurrentState(); if ( nState == css::embed::EmbedStates::INPLACE_ACTIVE || nState == css::embed::EmbedStates::UI_ACTIVE ) { SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &(GetView().GetEditWin()) ); if ( pCli ) { Rectangle aArea = pCli->GetObjArea(); aArea += rOffset; pCli->SetObjArea( aArea ); } } } catch (const uno::Exception&) { } } void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj, const SwRect *pFlyPrtRect, const SwRect *pFlyFrameRect, const bool bNoTextFramePrtAreaChanged ) { // Setting the scale of the client. This arises from the difference // between the VisArea of the object and the ObjArea. OSL_ENSURE( xObj.is(), "ObjectRef not valid" ); sal_Int64 nAspect = xObj.GetViewAspect(); if ( nAspect == embed::Aspects::MSOLE_ICON ) return; // the replacement image is completely controlled by container in this case sal_Int64 nMisc = 0; bool bLinkingChart = false; try { nMisc = xObj->getStatus( nAspect ); // This can surely only be a non-active object, if desired they // get the new size set as VisArea (StarChart). if( embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc ) { // TODO/MBA: testing SwRect aRect( pFlyPrtRect ? *pFlyPrtRect : GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, nullptr, xObj.GetObject() )); if( !aRect.IsEmpty() ) { // TODO/LEAN: getMapUnit can switch object to running state // xObj.TryRunningState(); MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); // TODO/LATER: needs complete VisArea?! Size aSize( OutputDevice::LogicToLogic( aRect.SVRect(), MapUnit::MapTwip, aUnit ).GetSize() ); awt::Size aSz; aSz.Width = aSize.Width(); aSz.Height = aSize.Height(); // Action 'setVisualAreaSize' doesn't have to turn on the // modified state of the document, either. bool bModified = false; uno::Reference xModifiable(xObj->getComponent(), uno::UNO_QUERY); if (xModifiable.is()) bModified = xModifiable->isModified(); xObj->setVisualAreaSize( nAspect, aSz ); xModifiable.set(xObj->getComponent(), uno::UNO_QUERY); if (xModifiable.is() && xModifiable->isModified() && !bModified) xModifiable->setModified(bModified); // #i48419# - action 'UpdateReplacement' doesn't // have to change the modified state of the document. // This is only a workaround for the defect, that this action // modifies a document after load, because unnecessarily the // replacement graphic is updated, in spite of the fact that // nothing has been changed. // If the replacement graphic changes by this action, the document // will be already modified via other mechanisms. { bool bResetEnableSetModified(false); if ( GetDoc()->GetDocShell()->IsEnableSetModified() ) { GetDoc()->GetDocShell()->EnableSetModified( false ); bResetEnableSetModified = true; } //#i79576# don't destroy chart replacement images on load //#i79578# don't request a new replacement image for charts to often //a chart sends a modified call to the framework if it was changed //thus the replacement update is already handled elsewhere if ( !SotExchange::IsChart( xObj->getClassID() ) ) xObj.UpdateReplacement(); if ( bResetEnableSetModified ) { GetDoc()->GetDocShell()->EnableSetModified(); } } } // TODO/LATER: this is only a workaround, uno::Reference< chart2::XChartDocument > xChartDocument( xObj->getComponent(), uno::UNO_QUERY ); bLinkingChart = ( xChartDocument.is() && !xChartDocument->hasInternalDataProvider() ); } } catch (const uno::Exception&) { // TODO/LATER: handle the error return; } SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() ); if ( !pCli ) { if ( (embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY & nMisc) || bLinkingChart // TODO/LATER: ResizeOnPrinterChange //|| SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xObj->GetMiscStatus() // --> OD #i117189# - refine condition for non-resizable objects // non-resizable objects need to be set the size back by this method || ( bNoTextFramePrtAreaChanged && nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE ) ) { pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj ); } else return; } // TODO/LEAN: getMapUnit can switch object to running state // xObj.TryRunningState(); awt::Size aSize; try { aSize = xObj->getVisualAreaSize( nAspect ); } catch (const embed::NoVisualAreaSizeException&) { OSL_FAIL("Can't get visual area size!\n" ); // the scaling will not be done } catch (const uno::Exception&) { // TODO/LATER: handle the error OSL_FAIL("Can't get visual area size!\n" ); return; } Size _aVisArea( aSize.Width, aSize.Height ); Fraction aScaleWidth( 1, 1 ); Fraction aScaleHeight( 1, 1 ); bool bUseObjectSize = false; // As long as there comes no reasonable size from the object, // nothing can be scaled. if( _aVisArea.Width() && _aVisArea.Height() ) { const MapMode aTmp( MapUnit::MapTwip ); MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); _aVisArea = OutputDevice::LogicToLogic( _aVisArea, aUnit, aTmp); Size aObjArea; if ( pFlyPrtRect ) aObjArea = pFlyPrtRect->SSize(); else aObjArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, nullptr, xObj.GetObject() ).SSize(); // differ the aObjArea and _aVisArea by 1 Pixel then set new VisArea long nX, nY; SwSelPaintRects::Get1PixelInLogic( *this, &nX, &nY ); if( !( _aVisArea.Width() - nX <= aObjArea.Width() && _aVisArea.Width() + nX >= aObjArea.Width() && _aVisArea.Height()- nY <= aObjArea.Height()&& _aVisArea.Height()+ nY >= aObjArea.Height() )) { if ( nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE ) { // the object must not be scaled, // the size stored in object must be used for restoring bUseObjectSize = true; } else { aScaleWidth = Fraction( aObjArea.Width(), _aVisArea.Width() ); aScaleHeight = Fraction( aObjArea.Height(), _aVisArea.Height()); } } } // Now is the favorable time to set the ObjArea. // The Scaling must be considered. SwRect aArea; if ( pFlyPrtRect ) { aArea = *pFlyPrtRect; aArea += pFlyFrameRect->Pos(); } else { aArea = GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, nullptr, xObj.GetObject() ); aArea.Pos() += GetAnyCurRect( RECT_FLY_EMBEDDED, nullptr, xObj.GetObject() ).Pos(); } if ( bUseObjectSize ) { // --> this moves non-resizable object so that when adding borders the baseline remains the same const SwFlyFrameFormat *pFlyFrameFormat = dynamic_cast< const SwFlyFrameFormat * >( GetFlyFrameFormat() ); OSL_ENSURE( pFlyFrameFormat, "Could not find fly frame." ); if ( pFlyFrameFormat ) { const Point &rPoint = pFlyFrameFormat->GetLastFlyFramePrtRectPos(); SwRect aRect( pFlyPrtRect ? *pFlyPrtRect : GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, nullptr, xObj.GetObject() )); aArea += rPoint - aRect.Pos(); // adjust area by diff of printing area position in order to keep baseline alignment correct. } aArea.Width ( _aVisArea.Width() ); aArea.Height( _aVisArea.Height() ); RequestObjectResize( aArea, xObj.GetObject() ); } else { aArea.Width ( Fraction( aArea.Width() ) / pCli->GetScaleWidth() ); aArea.Height( Fraction( aArea.Height() ) / pCli->GetScaleHeight()); } pCli->SetObjAreaAndScale( aArea.SVRect(), aScaleWidth, aScaleHeight ); } void SwWrtShell::ConnectObj( svt::EmbeddedObjectRef& xObj, const SwRect &rPrt, const SwRect &rFrame ) { SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin()); if ( !pCli ) new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj ); CalcAndSetScale( xObj, &rPrt, &rFrame ); } // Insert hard page break; // Selections will be overwritten void SwWrtShell::InsertPageBreak(const OUString *pPageDesc, const ::boost::optional& oPgNum ) { ResetCursorStack(); if( CanInsert() ) { SwActContext aActContext(this); StartUndo(UNDO_UI_INSERT_PAGE_BREAK); if ( !IsCursorInTable() ) { if(HasSelection()) DelRight(); SwFEShell::SplitNode(); // delete the numbered attribute of the last line if the last line is empty GetDoc()->ClearLineNumAttrs( *GetCursor()->GetPoint() ); } const SwPageDesc *pDesc = pPageDesc ? FindPageDescByName( *pPageDesc, true ) : nullptr; if( pDesc ) { SwFormatPageDesc aDesc( pDesc ); aDesc.SetNumOffset( oPgNum ); SetAttrItem( aDesc ); } else SetAttrItem( SvxFormatBreakItem(SvxBreak::PageBefore, RES_BREAK) ); EndUndo(UNDO_UI_INSERT_PAGE_BREAK); } } // Insert hard page break; // Selections will be overwritten void SwWrtShell::InsertLineBreak() { ResetCursorStack(); if( CanInsert() ) { if(HasSelection()) DelRight(); const sal_Unicode cIns = 0x0A; SvxAutoCorrect* pACorr = lcl_IsAutoCorr(); if( pACorr ) AutoCorrect( *pACorr, cIns ); else SwWrtShell::Insert( OUString( cIns ) ); } } // Insert hard column break; // Selections will be overwritten void SwWrtShell::InsertColumnBreak() { SwActContext aActContext(this); ResetCursorStack(); if( CanInsert() ) { StartUndo(UNDO_UI_INSERT_COLUMN_BREAK); if ( !IsCursorInTable() ) { if(HasSelection()) DelRight(); SwFEShell::SplitNode( false, false ); } SetAttrItem(SvxFormatBreakItem(SvxBreak::ColumnBefore, RES_BREAK)); EndUndo(UNDO_UI_INSERT_COLUMN_BREAK); } } // Insert footnote // rStr - optional footnote mark void SwWrtShell::InsertFootnote(const OUString &rStr, bool bEndNote, bool bEdit ) { ResetCursorStack(); if( CanInsert() ) { if(HasSelection()) { //collapse cursor to the end if(!IsCursorPtAtEnd()) SwapPam(); ClearMark(); } SwPosition aPos = *GetCursor()->GetPoint(); SwFormatFootnote aFootNote( bEndNote ); if(!rStr.isEmpty()) aFootNote.SetNumStr( rStr ); SetAttrItem(aFootNote); if( bEdit ) { // For editing the footnote text. Left(CRSR_SKIP_CHARS, false, 1, false ); GotoFootnoteText(); } m_aNavigationMgr.addEntry(aPos); } } // SplitNode; also, because // - of deleting selected content; // - of reset of the Cursorstack if necessary. void SwWrtShell::SplitNode( bool bAutoFormat ) { ResetCursorStack(); if( CanInsert() ) { SwActContext aActContext(this); m_rView.GetEditWin().FlushInBuffer(); bool bHasSel = HasSelection(); if( bHasSel ) { StartUndo( UNDO_INSERT ); DelRight(); } SwFEShell::SplitNode( bAutoFormat ); if( bHasSel ) EndUndo( UNDO_INSERT ); } } // Turn on numbering // Parameter: Optional specification of a name for the named list; // this indicates a position if it is possible to convert them // into a number and less than nMaxRules. // To test the CharFormats at the numbering // external void SetNumChrFormat( SwWrtShell*, SwNumRules& ); // -> #i40041# // Preconditions (as far as OD has figured out): // - is false, if is true // - is false, if is false // Behavior of method is determined by the current situation at the current // cursor position in the document. void SwWrtShell::NumOrBulletOn(bool bNum) { // determine numbering rule found at current cursor position in the document. const SwNumRule* pCurRule = GetNumRuleAtCurrCursorPos(); StartUndo(UNDO_NUMORNONUM); const SwNumRule * pNumRule = pCurRule; // - activate outline rule respectively turning on outline rule for // current text node. But, only for turning on a numbering ( == true). // - overwrite found numbering rule at current cursor position, if // no numbering rule can be retrieved from the paragraph style. bool bContinueFoundNumRule( false ); bool bActivateOutlineRule( false ); int nActivateOutlineLvl( MAXLEVEL ); // only relevant, if == true SwTextFormatColl * pColl = GetCurTextFormatColl(); if ( pColl ) { // retrieve numbering rule at paragraph // style, which is found at current cursor position in the document. SwNumRule* pCollRule = mpDoc->FindNumRulePtr(pColl->GetNumRule().GetValue()); // #125993# - The outline numbering rule isn't allowed // to be derived from a parent paragraph style to a derived one. // Thus check, if the found outline numbering rule is directly // set at the paragraph style . If not, set to NULL if ( pCollRule && pCollRule == GetDoc()->GetOutlineNumRule() ) { const SwNumRule* pDirectCollRule = mpDoc->FindNumRulePtr(pColl->GetNumRule( false ).GetValue()); if ( !pDirectCollRule ) { pCollRule = nullptr; } } if ( !pCollRule ) { pNumRule = pCollRule; } // no activation or continuation of outline numbering in Writer/Web document else if ( bNum && !dynamic_cast(GetDoc()->GetDocShell()) && pCollRule == GetDoc()->GetOutlineNumRule() ) { if ( pNumRule == pCollRule ) { // check, if text node at current cursor positioned is counted. // If not, let it been counted. Then it has to be checked, // of the outline numbering has to be activated or continued. SwTextNode* pTextNode = GetCursor()->GetPoint()->nNode.GetNode().GetTextNode(); if ( pTextNode && !pTextNode->IsCountedInList() ) { // check, if numbering of the outline level of the paragraph // style is active. If not, activate this outline level. nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel(); OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(), " - paragraph style with outline rule, but no outline level" ); if ( pColl->IsAssignedToListLevelOfOutlineStyle() && pCollRule->Get( static_cast(nActivateOutlineLvl) ).GetNumberingType() == SVX_NUM_NUMBER_NONE ) { // activate outline numbering bActivateOutlineRule = true; } else { // turning on outline numbering at current cursor position bContinueFoundNumRule = true; } } else { // #i101234# // activate outline numbering, because from the precondition // it's known, that == false bActivateOutlineRule = true; nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel(); } } else if ( !pNumRule ) { // #i101234# // Check, if corresponding list level of the outline numbering // has already a numbering format set. nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel(); if ( pCollRule->Get( static_cast(nActivateOutlineLvl) ).GetNumberingType() == SVX_NUM_NUMBER_NONE ) { // activate outline numbering, because from the precondition // it's known, that == false bActivateOutlineRule = true; } else { // turning on outline numbering at current cursor position bContinueFoundNumRule = true; } } else { // check, if numbering of the outline level of the paragraph // style is active. If not, activate this outline level. nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel(); OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(), " - paragraph style with outline rule, but no outline level" ); if ( pColl->IsAssignedToListLevelOfOutlineStyle() && pCollRule->Get( static_cast(nActivateOutlineLvl) ).GetNumberingType() == SVX_NUM_NUMBER_NONE ) { // activate outline numbering bActivateOutlineRule = true; } else { // turning on outline numbering at current cursor position bContinueFoundNumRule = true; } } pNumRule = pCollRule; } } // Only automatic numbering/bullet rules should be changed. // Note: The outline numbering rule is also an automatic one. It's only // changed, if it has to be activated. if ( pNumRule ) { if ( !pNumRule->IsAutoRule() ) { pNumRule = nullptr; } else if ( pNumRule == GetDoc()->GetOutlineNumRule() && !bActivateOutlineRule && !bContinueFoundNumRule ) { pNumRule = nullptr; } } // Search for a previous numbering/bullet rule to continue it. OUString sContinuedListId; if ( !pNumRule ) { pNumRule = GetDoc()->SearchNumRule( *GetCursor()->GetPoint(), false, bNum, false, 0, sContinuedListId ); bContinueFoundNumRule = pNumRule != nullptr; } if (pNumRule) { SwNumRule aNumRule(*pNumRule); // do not change found numbering/bullet rule, if it should only be continued. if ( !bContinueFoundNumRule ) { SwTextNode * pTextNode = GetCursor()->GetPoint()->nNode.GetNode().GetTextNode(); if (pTextNode) { // use above retrieve outline level, if outline numbering has to be activated. int nLevel = bActivateOutlineRule ? nActivateOutlineLvl : pTextNode->GetActualListLevel(); if (nLevel < 0) nLevel = 0; if (nLevel >= MAXLEVEL) nLevel = MAXLEVEL - 1; SwNumFormat aFormat(aNumRule.Get(static_cast(nLevel))); if (bNum) aFormat.SetNumberingType(SVX_NUM_ARABIC); else { // #i63395# Only apply user defined default bullet font if ( numfunc::IsDefBulletFontUserDefined() ) { const vcl::Font* pFnt = &numfunc::GetDefBulletFont(); aFormat.SetBulletFont( pFnt ); } aFormat.SetBulletChar( numfunc::GetBulletChar(static_cast(nLevel))); aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL); // #i93908# clear suffix for bullet lists aFormat.SetPrefix(OUString()); aFormat.SetSuffix(OUString()); } aNumRule.Set(static_cast(nLevel), aFormat); } } // reset indent attribute on applying list style SetCurNumRule( aNumRule, false, sContinuedListId, true ); } else { // #i95907# const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode( numfunc::GetDefaultPositionAndSpaceMode() ); SwNumRule aNumRule( GetUniqueNumRuleName(), ePosAndSpaceMode ); // Append the character template at the numbering. SwCharFormat* pChrFormat; SwDocShell* pDocSh = GetView().GetDocShell(); // #i63395# // Only apply user defined default bullet font const vcl::Font* pFnt = numfunc::IsDefBulletFontUserDefined() ? &numfunc::GetDefBulletFont() : nullptr; if (bNum) { pChrFormat = GetCharFormatFromPool( RES_POOLCHR_NUM_LEVEL ); } else { pChrFormat = GetCharFormatFromPool( RES_POOLCHR_BUL_LEVEL ); } const SwTextNode* pTextNode = GetCursor()->GetPoint()->nNode.GetNode().GetTextNode(); const SwTwips nWidthOfTabs = pTextNode ? pTextNode->GetWidthOfLeadingTabs() : 0; GetDoc()->getIDocumentContentOperations().RemoveLeadingWhiteSpace( *GetCursor()->GetPoint() ); const bool bHtml = dynamic_cast( pDocSh ) != nullptr; const bool bRightToLeft = IsInRightToLeftText(); for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl ) { SwNumFormat aFormat( aNumRule.Get( nLvl ) ); aFormat.SetCharFormat( pChrFormat ); if (! bNum) { // #i63395# // Only apply user defined default bullet font if ( pFnt ) { aFormat.SetBulletFont( pFnt ); } aFormat.SetBulletChar( numfunc::GetBulletChar(nLvl) ); aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL); // #i93908# clear suffix for bullet lists aFormat.SetPrefix(OUString()); aFormat.SetSuffix(OUString()); } // #i95907# if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { if(bHtml && nLvl) { // 1/2" for HTML aFormat.SetAbsLSpace(nLvl * 720); } else if ( nWidthOfTabs > 0 ) { aFormat.SetAbsLSpace(nWidthOfTabs + nLvl * 720); } } // #i38904# Default alignment for // numbering/bullet should be rtl in rtl paragraph: if ( bRightToLeft ) { aFormat.SetNumAdjust( SVX_ADJUST_RIGHT ); } aNumRule.Set( nLvl, aFormat ); } // #i95907# if ( pTextNode && ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT ) { const SwTwips nTextNodeIndent = pTextNode->GetAdditionalIndentForStartingNewList(); if ( ( nTextNodeIndent + nWidthOfTabs ) != 0 ) { // #i111172#/fdo#85666 // If text node is already inside a list, assure that the indents // are the same. Thus, adjust the indent change value by subtracting // indents of to be applied list style. SwTwips nIndentChange = nTextNodeIndent + nWidthOfTabs; if ( pTextNode->GetNumRule() ) { int nLevel = pTextNode->GetActualListLevel(); if (nLevel < 0) nLevel = 0; if (nLevel >= MAXLEVEL) nLevel = MAXLEVEL - 1; const SwNumFormat aFormat( aNumRule.Get( nLevel ) ); if ( aFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) { nIndentChange -= aFormat.GetIndentAt() + aFormat.GetFirstLineIndent(); } } aNumRule.ChangeIndent( nIndentChange ); } } // reset indent attribute on applying list style // start new list SetCurNumRule( aNumRule, true, OUString(), true ); } EndUndo(UNDO_NUMORNONUM); } // <- #i40041# void SwWrtShell::NumOn() { NumOrBulletOn(true); } void SwWrtShell::NumOrBulletOff() { const SwNumRule * pCurNumRule = GetNumRuleAtCurrCursorPos(); if (pCurNumRule) { if (pCurNumRule->IsOutlineRule()) { SwNumRule aNumRule(*pCurNumRule); SwTextNode * pTextNode = GetCursor()->GetPoint()->nNode.GetNode().GetTextNode(); if (pTextNode) { int nLevel = pTextNode->GetActualListLevel(); if (nLevel < 0) nLevel = 0; if (nLevel >= MAXLEVEL) nLevel = MAXLEVEL - 1; SwNumFormat aFormat(aNumRule.Get(static_cast(nLevel))); aFormat.SetNumberingType(SVX_NUM_NUMBER_NONE); aNumRule.Set(nLevel, aFormat); // no start or continuation of a list - the outline style is only changed. SetCurNumRule( aNumRule, false ); } } else { DelNumRules(); } // #126346# - Cursor can not be anymore in front of // a label, because numbering/bullet is switched off. SetInFrontOfLabel( false ); } } // <- #i29560# // Request Default-Bulletlist void SwWrtShell::BulletOn() { NumOrBulletOn(false); } SelectionType SwWrtShell::GetSelectionType() const { // ContentType cannot be determined within a // Start-/Endaction parentheses. // Because there is no invalid value TEXT will be returned. // The value does not matter, it may be updated in endaction anyway. if ( BasicActionPend() ) return IsSelFrameMode() ? nsSelectionType::SEL_FRM : nsSelectionType::SEL_TXT; SwView &_rView = const_cast(GetView()); if (_rView.GetPostItMgr() && _rView.GetPostItMgr()->HasActiveSidebarWin() ) return nsSelectionType::SEL_POSTIT; // Inserting a frame is not a DrawMode int nCnt; if ( !_rView.GetEditWin().IsFrameAction() && (IsObjSelected() || (_rView.IsDrawMode() && !IsFrameSelected()) )) { if (GetDrawView()->IsTextEdit()) nCnt = nsSelectionType::SEL_DRW_TXT; else { if (GetView().IsFormMode()) // Only Form selected nCnt = nsSelectionType::SEL_DRW_FORM; else nCnt = nsSelectionType::SEL_DRW; // Any draw object if (_rView.IsBezierEditMode()) nCnt |= nsSelectionType::SEL_BEZ; else if( GetDrawView()->GetContext() == SdrViewContext::Media ) nCnt |= nsSelectionType::SEL_MEDIA; if (svx::checkForSelectedCustomShapes( const_cast(GetDrawView()), true /* bOnlyExtruded */ )) { nCnt |= nsSelectionType::SEL_EXTRUDED_CUSTOMSHAPE; } sal_uInt32 nCheckStatus = 0; if (svx::checkForSelectedFontWork( const_cast(GetDrawView()), nCheckStatus )) { nCnt |= nsSelectionType::SEL_FONTWORK; } } return nCnt; } nCnt = GetCntType(); if ( IsFrameSelected() ) { if (_rView.IsDrawMode()) _rView.LeaveDrawCreate(); // clean up (Bug #45639) if ( !(nCnt & (CNT_GRF | CNT_OLE)) ) return nsSelectionType::SEL_FRM; } if ( IsCursorInTable() ) nCnt |= nsSelectionType::SEL_TBL; if ( IsTableMode() ) nCnt |= (nsSelectionType::SEL_TBL | nsSelectionType::SEL_TBL_CELLS); // Do not pop up numbering toolbar, if the text node has a numbering of type SVX_NUM_NUMBER_NONE. const SwNumRule* pNumRule = GetNumRuleAtCurrCursorPos(); if ( pNumRule ) { const SwTextNode* pTextNd = GetCursor()->GetPoint()->nNode.GetNode().GetTextNode(); if ( pTextNd && pTextNd->IsInList() ) { int nLevel = pTextNd->GetActualListLevel(); if (nLevel < 0) nLevel = 0; if (nLevel >= MAXLEVEL) nLevel = MAXLEVEL - 1; const SwNumFormat& rFormat = pNumRule->Get(nLevel); if ( SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType() ) nCnt |= nsSelectionType::SEL_NUM; } } return nCnt; } // Find the text collection with the name rCollname // Returns: Pointer at the collection or 0, if no // text collection with this name exists, or // this is a default template. SwTextFormatColl *SwWrtShell::GetParaStyle(const OUString &rCollName, GetStyle eCreate ) { SwTextFormatColl* pColl = FindTextFormatCollByName( rCollName ); if( !pColl && GETSTYLE_NOCREATE != eCreate ) { sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCollName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ); if( USHRT_MAX != nId || GETSTYLE_CREATEANY == eCreate ) pColl = GetTextCollFromPool( nId ); } return pColl; } // Find the text collection with the name rCollname // Returns: Pointer at the collection or 0, if no // character template with this name exists, or // this is a default template or template is automatic. SwCharFormat *SwWrtShell::GetCharStyle(const OUString &rFormatName, GetStyle eCreate ) { SwCharFormat* pFormat = FindCharFormatByName( rFormatName ); if( !pFormat && GETSTYLE_NOCREATE != eCreate ) { sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rFormatName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); if( USHRT_MAX != nId || GETSTYLE_CREATEANY == eCreate ) pFormat = static_cast(GetFormatFromPool( nId )); } return pFormat; } // Find the table format with the name rFormatname // Returns: Pointer at the collection or 0, if no // frame format with this name exists or // this is a default format or the format is automatic. SwFrameFormat *SwWrtShell::GetTableStyle(const OUString &rFormatName) { for( size_t i = GetTableFrameFormatCount(); i; ) { SwFrameFormat *pFormat = &GetTableFrameFormat( --i ); if( !pFormat->IsDefault() && pFormat->GetName() == rFormatName && IsUsed( *pFormat ) ) return pFormat; } return nullptr; } void SwWrtShell::addCurrentPosition() { SwPaM* pPaM = GetCursor(); m_aNavigationMgr.addEntry(*pPaM->GetPoint()); } // Applying templates void SwWrtShell::SetPageStyle(const OUString &rCollName) { if( !SwCursorShell::HasSelection() && !IsSelFrameMode() && !IsObjSelected() ) { SwPageDesc* pDesc = FindPageDescByName( rCollName, true ); if( pDesc ) ChgCurPageDesc( *pDesc ); } } // Access templates OUString SwWrtShell::GetCurPageStyle() const { return GetPageDesc(GetCurPageDesc( false/*bCalcFrame*/ )).GetName(); } // Change the current template referring to the existing change. void SwWrtShell::QuickUpdateStyle() { SwTextFormatColl *pColl = GetCurTextFormatColl(); // Default cannot be changed if(pColl && !pColl->IsDefault()) { FillByEx(pColl); // Also apply the template to remove hard attribute assignment. SetTextFormatColl(pColl); } } void SwWrtShell::AutoUpdatePara(SwTextFormatColl* pColl, const SfxItemSet& rStyleSet, SwPaM* pPaM ) { SwPaM* pCursor = pPaM ? pPaM : GetCursor( ); SfxItemSet aCoreSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_CHRATR_END - 1, RES_PARATR_BEGIN, RES_PARATR_END - 1, RES_FRMATR_BEGIN, RES_FRMATR_END - 1, SID_ATTR_TABSTOP_POS, SID_ATTR_TABSTOP_POS, SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_OFFSET, SID_ATTR_TABSTOP_OFFSET, SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER, SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP, SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM, 0 ); GetPaMAttr( pCursor, aCoreSet ); bool bReset = false; SfxItemIter aParaIter( aCoreSet ); const SfxPoolItem* pParaItem = aParaIter.FirstItem(); while( pParaItem ) { if(!IsInvalidItem(pParaItem)) { sal_uInt16 nWhich = pParaItem->Which(); if(SfxItemState::SET == aCoreSet.GetItemState(nWhich) && SfxItemState::SET == rStyleSet.GetItemState(nWhich)) { aCoreSet.ClearItem(nWhich); bReset = true; } } pParaItem = aParaIter.NextItem(); } StartAction(); if(bReset) { ResetAttr( std::set(), pCursor ); SetAttrSet(aCoreSet, SetAttrMode::DEFAULT, pCursor); } mpDoc->ChgFormat(*pColl, rStyleSet ); EndAction(); } void SwWrtShell::AutoUpdateFrame( SwFrameFormat* pFormat, const SfxItemSet& rStyleSet ) { StartAction(); ResetFlyFrameAttr( &rStyleSet ); pFormat->SetFormatAttr( rStyleSet ); EndAction(); } void SwWrtShell::AutoCorrect( SvxAutoCorrect& rACorr, sal_Unicode cChar ) { ResetCursorStack(); if(CanInsert()) { bool bStarted = false; SwRewriter aRewriter; if(HasSelection()) { // Only parenthese here, because the regular insert // is already clipped to the editshell StartAllAction(); OUString aTmpStr1; aTmpStr1 += SW_RES(STR_START_QUOTE); aTmpStr1 += GetSelText(); aTmpStr1 += SW_RES(STR_END_QUOTE); OUString aTmpStr3; aTmpStr3 += SW_RES(STR_START_QUOTE); aTmpStr3 += OUStringLiteral1(cChar); aTmpStr3 += SW_RES(STR_END_QUOTE); aRewriter.AddRule( UndoArg1, aTmpStr1 ); aRewriter.AddRule( UndoArg2, SW_RES(STR_YIELDS) ); aRewriter.AddRule( UndoArg3, aTmpStr3 ); StartUndo( UNDO_REPLACE, &aRewriter ); bStarted = true; DelRight(); } SwEditShell::AutoCorrect( rACorr, IsInsMode(), cChar ); if(bStarted) { EndAllAction(); EndUndo( UNDO_REPLACE, &aRewriter ); } } } // Some kind of controlled copy ctor SwWrtShell::SwWrtShell( SwWrtShell& rSh, vcl::Window *_pWin, SwView &rShell ) : SwFEShell( rSh, _pWin ), COMMON_INI_LIST { BITFLD_INI_LIST SET_CURR_SHELL( this ); SetSfxViewShell( static_cast(&rShell) ); SetFlyMacroLnk( LINK(this, SwWrtShell, ExecFlyMac) ); // place the cursor on the first field... IFieldmark *pBM = nullptr; if ( IsFormProtected() && ( pBM = GetFieldmarkAfter( ) ) !=nullptr ) { GotoFieldmark(pBM); } } SwWrtShell::SwWrtShell( SwDoc& rDoc, vcl::Window *_pWin, SwView &rShell, const SwViewOption *pViewOpt ) : SwFEShell( rDoc, _pWin, pViewOpt), COMMON_INI_LIST { BITFLD_INI_LIST SET_CURR_SHELL( this ); SetSfxViewShell( static_cast(&rShell) ); SetFlyMacroLnk( LINK(this, SwWrtShell, ExecFlyMac) ); // place the cursor on the first field... IFieldmark *pBM = nullptr; if ( IsFormProtected() && ( pBM = GetFieldmarkAfter( ) ) !=nullptr ) { GotoFieldmark(pBM); } } SwWrtShell::~SwWrtShell() { SET_CURR_SHELL( this ); while(IsModePushed()) PopMode(); while(PopCursor(false)) ; SwTransferable::ClearSelection( *this ); } bool SwWrtShell::Pop( bool bOldCursor ) { bool bRet = SwCursorShell::Pop( bOldCursor ); if( bRet && IsSelection() ) { m_fnSetCursor = &SwWrtShell::SetCursorKillSel; m_fnKillSel = &SwWrtShell::ResetSelect; } return bRet; } bool SwWrtShell::CanInsert() { if(IsSelFrameMode()) { return false; } if(IsObjSelected()) { return false; } if(GetView().GetDrawFuncPtr()) { return false; } if(GetView().GetPostItMgr()->GetActiveSidebarWin()) { return false; } return true; } void SwWrtShell::ChgDBData(const SwDBData& aDBData) { SwEditShell::ChgDBData(aDBData); //notify the db-beamer if available GetView().NotifyDBChanged(); } OUString SwWrtShell::GetSelDescr() const { OUString aResult; int nSelType = GetSelectionType(); switch (nSelType) { case nsSelectionType::SEL_GRF: aResult = SW_RESSTR(STR_GRAPHIC); break; case nsSelectionType::SEL_FRM: { const SwFrameFormat * pFrameFormat = GetSelectedFrameFormat(); if (pFrameFormat) aResult = pFrameFormat->GetDescription(); } break; case nsSelectionType::SEL_DRW: { aResult = SW_RESSTR(STR_DRAWING_OBJECTS); } break; default: if (nullptr != mpDoc) aResult = GetCursorDescr(); } return aResult; } void SwWrtShell::ApplyViewOptions( const SwViewOption &rOpt ) { SwFEShell::ApplyViewOptions( rOpt ); //#i115062# invalidate meta character slot GetView().GetViewFrame()->GetBindings().Invalidate( FN_VIEW_META_CHARS ); } void SwWrtShell::SetReadonlyOption(bool bSet) { GetView().GetEditWin().GetFrameControlsManager().SetReadonlyControls( bSet ); SwViewShell::SetReadonlyOption( bSet ); } // Switch on/off header or footer of a page style - if an empty name is // given all styles are changed void SwWrtShell::ChangeHeaderOrFooter( const OUString& rStyleName, bool bHeader, bool bOn, bool bShowWarning) { addCurrentPosition(); StartAllAction(); StartUndo( UNDO_HEADER_FOOTER ); // #i7983# bool bExecute = true; bool bCursorSet = false; for( size_t nFrom = 0, nTo = GetPageDescCnt(); nFrom < nTo; ++nFrom ) { SwPageDesc aDesc( GetPageDesc( nFrom )); OUString sTmp(aDesc.GetName()); if( rStyleName.isEmpty() || rStyleName == sTmp ) { bool bChgd = false; if( bShowWarning && !bOn && GetActiveView() && GetActiveView() == &GetView() && ( (bHeader && aDesc.GetMaster().GetHeader().IsActive()) || (!bHeader && aDesc.GetMaster().GetFooter().IsActive()) ) ) { bShowWarning = false; //Actions have to be closed while the dialog is showing EndAllAction(); vcl::Window* pParent = &GetView().GetViewFrame()->GetWindow(); short nResult; if (bHeader) { nResult = ScopedVclPtrInstance(pParent)->Execute(); } else { nResult = ScopedVclPtrInstance(pParent)->Execute(); } bExecute = nResult == RET_YES; StartAllAction(); } if( bExecute ) { bChgd = true; SwFrameFormat &rMaster = aDesc.GetMaster(); if(bHeader) rMaster.SetFormatAttr( SwFormatHeader( bOn )); else rMaster.SetFormatAttr( SwFormatFooter( bOn )); if( bOn ) { SvxULSpaceItem aUL(bHeader ? 0 : MM50, bHeader ? MM50 : 0, RES_UL_SPACE ); SwFrameFormat* pFormat = bHeader ? const_cast(rMaster.GetHeader().GetHeaderFormat()) : const_cast(rMaster.GetFooter().GetFooterFormat()); pFormat->SetFormatAttr( aUL ); } } if( bChgd ) { ChgPageDesc( nFrom, aDesc ); if( !bCursorSet && bOn ) { if ( !IsHeaderFooterEdit() ) ToggleHeaderFooterEdit(); bCursorSet = SetCursorInHdFt( rStyleName.isEmpty() ? SIZE_MAX : nFrom, bHeader ); } } } } EndUndo( UNDO_HEADER_FOOTER ); // #i7983# EndAllAction(); } void SwWrtShell::SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow ) { SwViewShell::SetShowHeaderFooterSeparator( eControl, bShow ); if ( !bShow ) GetView().GetEditWin().GetFrameControlsManager().HideControls( eControl ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */