1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/beans/XPropertySet.hpp>
21 #include <com/sun/star/container/XChild.hpp>
22 #include <com/sun/star/embed/EmbedMisc.hpp>
23 #include <com/sun/star/embed/EmbedStates.hpp>
24 #include <com/sun/star/embed/EmbedVerbs.hpp>
25 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
26 #include <com/sun/star/chart2/XChartDocument.hpp>
27 #include <com/sun/star/util/XModifiable.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
30 #include <hintids.hxx>
31 #include <sot/exchange.hxx>
32 #include <svx/xfillit0.hxx>
33 #include <svx/hdft.hxx>
34 #include <svx/svdview.hxx>
35 #include <svl/itemiter.hxx>
36 #include <tools/bigint.hxx>
37 #include <svtools/insdlg.hxx>
38 #include <sfx2/ipclient.hxx>
39 #include <editeng/formatbreakitem.hxx>
40 #include <editeng/svxacorr.hxx>
41 #include <editeng/ulspitem.hxx>
42 #include <vcl/graph.hxx>
43 #include <unotools/charclass.hxx>
44 #include <comphelper/storagehelper.hxx>
45 #include <svx/svxdlg.hxx>
46 #include <svx/extrusionbar.hxx>
47 #include <svx/fontworkbar.hxx>
48 #include <dialoghelp.hxx>
51 #include <fmthdft.hxx>
52 #include <fmtpdsc.hxx>
55 #include <swmodule.hxx>
59 #include <pagedesc.hxx>
63 #include <poolfmt.hxx>
66 #include <swtable.hxx>
68 #include <swdtflvr.hxx>
70 #include <IDocumentSettingAccess.hxx>
71 #include <SwCapObjType.hxx>
72 #include <SwStyleNameMapper.hxx>
73 #include <sfx2/request.hxx>
76 #include <editeng/acorrcfg.hxx>
78 #include <sfx2/bindings.hxx>
82 #include <SwRewriter.hxx>
83 #include <strings.hrc>
86 #include <toolkit/helper/vclunohelper.hxx>
87 #include <sfx2/viewfrm.hxx>
88 #include <vcl/uitest/logger.hxx>
89 #include <vcl/uitest/eventdescription.hxx>
90 #include <osl/diagnose.h>
91 #include <o3tl/unit_conversion.hxx>
93 #include <PostItMgr.hxx>
94 #include <FrameControlsManager.hxx>
96 #include <docufld.hxx>
97 #include <IDocumentFieldsAccess.hxx>
100 #include <sfx2/msgpool.hxx>
101 #include <sfx2/msg.hxx>
102 #include <svtools/embedhlp.hxx>
103 #include <svx/postattr.hxx>
104 #include <comphelper/lok.hxx>
105 #include <comphelper/propertyvalue.hxx>
106 #include <svtools/optionsdrawinglayer.hxx>
107 #include <svl/numformat.hxx>
108 #include <svl/zformat.hxx>
111 #include "../../core/crsr/callnk.hxx"
112 #include <frmtool.hxx>
113 #include <viewopt.hxx>
115 #include <IDocumentUndoRedo.hxx>
116 #include <UndoInsert.hxx>
117 #include <UndoCore.hxx>
118 #include <formatlinebreak.hxx>
119 #include <formatcontentcontrol.hxx>
120 #include <textcontentcontrol.hxx>
122 using namespace sw::mark
;
123 using namespace com::sun::star
;
126 void collectUIInformation(const OUString
& rAction
, const OUString
& aParameters
)
128 EventDescription aDescription
;
129 aDescription
.aAction
= rAction
;
130 aDescription
.aParameters
= {{"parameters", aParameters
}};
131 aDescription
.aID
= "writer_edit";
132 aDescription
.aKeyWord
= "SwEditWinUIObject";
133 aDescription
.aParent
= "MainWindow";
134 UITestLogger::getInstance().logEvent(aDescription
);
139 sal_uInt32
MakeAllOutlineContentTemporarilyVisible::nLock
= 0;
141 static bool lcl_IsAllowed(const SwWrtShell
* rSh
)
143 if (rSh
->GetViewOptions()->IsShowOutlineContentVisibilityButton() && rSh
->IsEndPara())
145 SwTextNode
* pTextNode
= rSh
->GetCursor()->GetPointNode().GetTextNode();
146 if (pTextNode
&& pTextNode
->IsOutline())
148 // disallow if this is an outline node having folded content
149 bool bVisible
= true;
150 pTextNode
->GetAttrOutlineContentVisible(bVisible
);
158 #define BITFLD_INI_LIST \
168 m_bRetainSelection = false; \
169 m_bIsInClickToEdit = false;
171 static SvxAutoCorrect
* lcl_IsAutoCorr()
173 SvxAutoCorrect
* pACorr
= SvxAutoCorrCfg::Get().GetAutoCorrect();
174 if( pACorr
&& !pACorr
->IsAutoCorrFlag( ACFlags::CapitalStartSentence
| ACFlags::CapitalStartWord
|
175 ACFlags::AddNonBrkSpace
| ACFlags::ChgOrdinalNumber
| ACFlags::TransliterateRTL
|
176 ACFlags::ChgToEnEmDash
| ACFlags::SetINetAttr
| ACFlags::Autocorrect
|
177 ACFlags::SetDOIAttr
))
182 void SwWrtShell::NoEdit(bool bHideCursor
)
188 void SwWrtShell::Edit()
196 bool SwWrtShell::IsEndWrd()
198 SwMvContext
aMvContext(this);
199 if(IsEndPara() && !IsSttPara())
206 void SwWrtShell::InsertByWord( const OUString
& rStr
)
211 bool bDelim
= GetAppCharClass().isLetterNumeric( rStr
, 0 );
212 sal_Int32 nPos
= 0, nStt
= 0;
213 for( ; nPos
< rStr
.getLength(); nPos
++ )
215 bool bTmpDelim
= GetAppCharClass().isLetterNumeric( rStr
, nPos
);
216 if( bTmpDelim
!= bDelim
)
218 Insert( rStr
.copy( nStt
, nPos
- nStt
));
223 Insert( rStr
.copy( nStt
, nPos
- nStt
));
226 void SwWrtShell::Insert( const OUString
&rStr
)
232 bool bStarted
= false;
233 bool bHasSel
= HasSelection(),
234 bCallIns
= m_bIns
/*|| bHasSel*/;
235 bool bDeleted
= false;
237 if( bHasSel
|| ( !m_bIns
&& IsInHiddenRange(/*bSelect=*/true) ) )
239 // Only here parenthesizing, because the normal
240 // insert is already in parentheses at Editshell.
243 SwRewriter aRewriter
;
245 aRewriter
.AddRule(UndoArg1
, GetCursorDescr());
246 aRewriter
.AddRule(UndoArg2
, SwResId(STR_YIELDS
));
248 OUString aTmpStr
= SwResId(STR_START_QUOTE
) +
249 rStr
+ SwResId(STR_END_QUOTE
);
251 aRewriter
.AddRule(UndoArg3
, aTmpStr
);
254 StartUndo(SwUndoId::REPLACE
, &aRewriter
);
257 // let's interpret a selection within the same node as "replace"
258 bDeleted
= DelRight(GetCursor()->GetPoint()->GetNode() == GetCursor()->GetMark()->GetNode());
259 Pop(SwCursorShell::PopMode::DeleteCurrent
); // Restore selection (if tracking changes)
260 NormalizePam(false); // tdf#127635 put point at the end of deletion
265 SwEditShell::Insert2( rStr
, bDeleted
) : SwEditShell::Overwrite( rStr
);
267 // Check whether node is content control
268 SwTextContentControl
* pTextContentControl
= CursorInsideContentControl();
269 if (pTextContentControl
)
271 std::shared_ptr
<SwContentControl
> pContentControl
=
272 pTextContentControl
->GetContentControl().GetContentControl();
275 // Set showingPlcHdr to false as node has been edited
276 pContentControl
->SetShowingPlaceHolder(false);
287 // Maximum height limit not possible, because the maximum height
288 // of the current frame can not be obtained.
290 void SwWrtShell::InsertGraphic( const OUString
&rPath
, const OUString
&rFilter
,
291 const Graphic
&rGrf
, SwFlyFrameAttrMgr
*pFrameMgr
,
292 RndStdIds nAnchorType
)
300 SwRewriter aRewriter
;
301 aRewriter
.AddRule(UndoArg1
, SwResId(STR_GRAPHIC
));
303 StartUndo(SwUndoId::INSERT
, &aRewriter
);
305 if ( HasSelection() )
307 // Inserted graphics in its own paragraph,
308 // if at the end of a non-empty paragraph.
309 //For i120928,avoid to split node
313 bool bSetGrfSize
= true;
314 bool bOwnMgr
= false;
319 pFrameMgr
= new SwFlyFrameAttrMgr( true, this, Frmmgr_Type::GRF
, nullptr );
322 // GetAttrSet makes an adjustment
323 // While pasting is a SwFrameSize present
324 // because of the DEF-Framesize
325 // These must be removed explicitly for the optimal size.
326 pFrameMgr
->DelAttr(RES_FRM_SIZE
);
328 if (nAnchorType
!= RndStdIds::FLY_AT_PARA
)
329 // Something other than at-para was requested.
330 pFrameMgr
->SetAnchor(nAnchorType
);
334 Size
aSz( pFrameMgr
->GetSize() );
335 if ( !aSz
.Width() || !aSz
.Height() )
337 aSz
.setWidth(o3tl::toTwips(1, o3tl::Length::cm
));
338 aSz
.setHeight(o3tl::toTwips(1, o3tl::Length::cm
));
339 pFrameMgr
->SetSize( aSz
);
341 else if ( aSz
.Width() != DFLT_WIDTH
&& aSz
.Height() != DFLT_HEIGHT
)
344 pFrameMgr
->SetHeightSizeType(SwFrameSize::Fixed
);
347 // during change tracking, insert the image anchored as character
348 // (to create an SwRangeRedline on its anchor point)
349 if ( IsRedlineOn() && nAnchorType
!= RndStdIds::FLY_AS_CHAR
)
350 pFrameMgr
->SetAnchor( RndStdIds::FLY_AS_CHAR
);
352 // Insert the graphic
353 SwFEShell::Insert(rPath
, rFilter
, &rGrf
, &pFrameMgr
->GetAttrSet());
355 pFrameMgr
->UpdateAttrMgr();
359 Size aSizePixel
= rGrf
.GetSizePixel();
360 Size aBound
= GetGraphicDefaultSize();
362 sal_Int32 nPreferredDPI
= mxDoc
->getIDocumentSettingAccess().getImagePreferredDPI();
365 if (nPreferredDPI
> 0)
367 auto nWidth
= o3tl::toTwips(aSizePixel
.Width() / double(nPreferredDPI
), o3tl::Length::in
);
368 auto nHeight
= o3tl::toTwips(aSizePixel
.Height() / double(nPreferredDPI
), o3tl::Length::in
);
369 aGrfSize
= Size(nWidth
, nHeight
);
373 GetGrfSize(aGrfSize
);
376 // Add the margin attributes to GrfSize,
377 // because these counts at the margin additionally
378 aGrfSize
.AdjustWidth(pFrameMgr
->CalcWidthBorder() );
379 aGrfSize
.AdjustHeight(pFrameMgr
->CalcHeightBorder() );
381 const BigInt
aTempWidth( aGrfSize
.Width() );
382 const BigInt
aTempHeight( aGrfSize
.Height());
384 // Fit width if necessary, scale down the height proportional thereafter.
385 if( aGrfSize
.Width() > aBound
.Width() )
387 aGrfSize
.setWidth( aBound
.Width() );
388 aGrfSize
.setHeight( BigInt(aBound
.Width()) * aTempHeight
/ aTempWidth
);
390 // Fit height if necessary, scale down the width proportional thereafter.
391 if( aGrfSize
.Height() > aBound
.Height() )
393 aGrfSize
.setHeight( aBound
.Height() );
394 aGrfSize
.setWidth( BigInt(aBound
.Height()) * aTempWidth
/ aTempHeight
);
396 pFrameMgr
->SetSize( aGrfSize
);
397 pFrameMgr
->UpdateFlyFrame();
406 // Insert an OLE-Object into the CORE.
407 // if no object is transferred, then one will be created.
409 void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef
& xRef
, SvGlobalName
const *pName
,
419 svt::EmbeddedObjectRef xObj
;
420 uno::Reference
< embed::XStorage
> xStor
= comphelper::OStorageHelper::GetTemporaryStorage();
424 comphelper::EmbeddedObjectContainer
aCnt( xStor
);
426 // TODO/LATER: get aspect?
427 xObj
.Assign( aCnt
.CreateEmbeddedObject( pName
->GetByteSequence(), aName
), embed::Aspects::MSOLE_CONTENT
);
431 SvObjectServerList aServerList
;
434 case SID_INSERT_OBJECT
:
436 aServerList
.FillInsertObjects();
437 aServerList
.Remove( SwDocShell::Factory().GetClassId() );
441 // TODO/LATER: recording! Convert properties to items
442 case SID_INSERT_FLOATINGFRAME
:
444 SfxSlotPool
* pSlotPool
= SW_MOD()->GetSlotPool();
445 const SfxSlot
* pSlot
= pSlotPool
->GetSlot(nSlotId
);
446 OUString aCmd
= pSlot
->GetCommand();
447 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
448 ScopedVclPtr
<SfxAbstractInsertObjectDialog
> pDlg(pFact
->CreateInsertObjectDialog(GetFrameWeld(mxDoc
->GetDocShell()),
449 aCmd
, xStor
, &aServerList
));
453 bDoVerb
= pDlg
->IsCreateNew();
454 OUString aIconMediaType
;
455 uno::Reference
< io::XInputStream
> xIconMetaFile
= pDlg
->GetIconIfIconified( &aIconMediaType
);
456 xObj
.Assign( pDlg
->GetObject(),
457 xIconMetaFile
.is() ? embed::Aspects::MSOLE_ICON
: embed::Aspects::MSOLE_CONTENT
);
458 if ( xIconMetaFile
.is() )
459 xObj
.SetGraphicStream( xIconMetaFile
, aIconMediaType
);
472 if( InsertOleObject( xObj
) && bDoVerb
)
474 SfxInPlaceClient
* pClient
= GetView().FindIPClient( xObj
.GetObject(), &GetView().GetEditWin() );
477 pClient
= new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj
);
478 SetCheckForOLEInCaption( true );
481 if ( xObj
.GetViewAspect() == embed::Aspects::MSOLE_ICON
)
483 SwRect aArea
= GetAnyCurRect( CurRectType::FlyEmbeddedPrt
, nullptr, xObj
.GetObject() );
484 aArea
.Pos() += GetAnyCurRect( CurRectType::FlyEmbedded
, nullptr, xObj
.GetObject() ).Pos();
485 MapMode
aMapMode( MapUnit::MapTwip
);
486 Size aSize
= xObj
.GetSize( &aMapMode
);
487 aArea
.Width( aSize
.Width() );
488 aArea
.Height( aSize
.Height() );
489 RequestObjectResize( aArea
, xObj
.GetObject() );
492 CalcAndSetScale( xObj
);
494 //#50270# We don't need to handle error, this is handled by the
495 //DoVerb in the SfxViewShell
496 pClient
->DoVerb(embed::EmbedVerbs::MS_OLEVERB_SHOW
);
498 // TODO/LATER: set document name - should be done in Client
506 InsertOleObject( xRef
);
510 // Insert object into the Core.
511 // From ClipBoard or Insert
513 bool SwWrtShell::InsertOleObject( const svt::EmbeddedObjectRef
& xRef
, SwFlyFrameFormat
**pFlyFrameFormat
)
515 //tdf#125100 Ensure that ole object is initially shown as pictogram
516 comphelper::EmbeddedObjectContainer
& rEmbeddedObjectContainer
= mxDoc
->GetDocShell()->getEmbeddedObjectContainer();
517 bool bSaveUserAllowsLinkUpdate
= rEmbeddedObjectContainer
.getUserAllowsLinkUpdate();
518 rEmbeddedObjectContainer
.setUserAllowsLinkUpdate(true);
523 StartUndo(SwUndoId::INSERT
);
525 //Some differences between StarMath and any other objects:
526 //1. Selections should be deleted. For StarMath the Text should be
527 // passed to the Object
528 //2. If the cursor is at the end of a non empty paragraph a paragraph
529 // break should be inserted. StarMath objects are character bound and
530 // no break should be inserted.
531 //3. If an selection is passed to a StarMath object, this object should
532 // not be activated. false should be returned then.
533 bool bStarMath
= true;
534 bool bActivate
= true;
536 // set parent to get correct VisArea(in case of object needing parent printer)
537 uno::Reference
< container::XChild
> xChild( xRef
.GetObject(), uno::UNO_QUERY
);
539 xChild
->setParent( mxDoc
->GetDocShell()->GetModel() );
541 SvGlobalName
aCLSID( xRef
->getClassID() );
542 bStarMath
= ( SotExchange::IsMath( aCLSID
) != 0 );
548 GetSelectedText( aMathData
, ParaBreakType::ToOnlyCR
);
550 if( !aMathData
.isEmpty() && svt::EmbeddedObjectRef::TryRunningState( xRef
.GetObject() ) )
552 uno::Reference
< beans::XPropertySet
> xSet( xRef
->getComponent(), uno::UNO_QUERY
);
557 xSet
->setPropertyValue("Formula", uno::Any( aMathData
) );
560 catch (const uno::Exception
&)
570 SwFEShell::SplitNode( false, false );
574 const SvGlobalName
* pName
= nullptr;
575 SvGlobalName aObjClsId
;
578 aObjClsId
= SvGlobalName(xRef
.GetObject()->getClassID());
581 SwFlyFrameAttrMgr
aFrameMgr( true, this, Frmmgr_Type::OLE
, pName
);
582 aFrameMgr
.SetHeightSizeType(SwFrameSize::Fixed
);
585 CalcBoundRect( aBound
, aFrameMgr
.GetAnchor() );
587 //The Size should be suggested by the OLE server
588 MapMode
aMapMode( MapUnit::MapTwip
);
589 Size aSz
= xRef
.GetSize( &aMapMode
);
591 //Object size can be limited
592 if ( aSz
.Width() > aBound
.Width() )
594 //Always limit proportional.
595 aSz
.setHeight( aSz
.Height() * aBound
.Width() / aSz
.Width() );
596 aSz
.setWidth( aBound
.Width() );
598 aFrameMgr
.SetSize( aSz
);
599 SwFlyFrameFormat
*pFormat
= SwFEShell::InsertObject( xRef
, &aFrameMgr
.GetAttrSet() );
602 if ( bStarMath
&& mxDoc
->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT
) )
603 AlignFormulaToBaseline( xRef
.GetObject() );
606 *pFlyFrameFormat
= pFormat
;
608 if ( SotExchange::IsChart( aCLSID
) )
610 uno::Reference
< embed::XEmbeddedObject
> xEmbeddedObj
= xRef
.GetObject();
611 if ( xEmbeddedObj
.is() )
613 bool bDisableDataTableDialog
= false;
614 svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj
);
615 uno::Reference
< beans::XPropertySet
> xProps( xEmbeddedObj
->getComponent(), uno::UNO_QUERY
);
617 ( xProps
->getPropertyValue("DisableDataTableDialog") >>= bDisableDataTableDialog
) &&
618 bDisableDataTableDialog
)
620 xProps
->setPropertyValue("DisableDataTableDialog",
622 xProps
->setPropertyValue("DisableComplexChartTypes",
624 uno::Reference
< util::XModifiable
> xModifiable( xProps
, uno::UNO_QUERY
);
625 if ( xModifiable
.is() )
627 xModifiable
->setModified( true );
634 GetView().AutoCaption(OLE_CAP
, &aCLSID
);
636 SwRewriter aRewriter
;
639 aRewriter
.AddRule(UndoArg1
, SwResId(STR_MATH_FORMULA
));
640 else if ( SotExchange::IsChart( aCLSID
) )
641 aRewriter
.AddRule(UndoArg1
, SwResId(STR_CHART
));
643 aRewriter
.AddRule(UndoArg1
, SwResId(STR_OLE
));
645 EndUndo(SwUndoId::INSERT
, &aRewriter
);
647 rEmbeddedObjectContainer
.setUserAllowsLinkUpdate(bSaveUserAllowsLinkUpdate
);
652 // The current selected OLE object will be loaded with the
653 // verb into the server.
654 void SwWrtShell::LaunchOLEObj(sal_Int32 nVerb
)
656 if ( GetCntType() != CNT_OLE
||
657 GetView().GetViewFrame().GetFrame().IsInPlace() )
660 svt::EmbeddedObjectRef
& xRef
= GetOLEObject();
661 OSL_ENSURE( xRef
.is(), "OLE not found" );
663 // LOK: we don't want to handle any other embedded objects than
664 // charts, there are too many problems with eg. embedded spreadsheets
665 // (like it creates a separate view for the calc sheet)
666 if (comphelper::LibreOfficeKit::isActive())
668 const auto classId
= xRef
->getClassID();
669 if (!SotExchange::IsChart(classId
) && !SotExchange::IsMath(classId
))
673 SfxInPlaceClient
* pCli
= GetView().FindIPClient( xRef
.GetObject(), &GetView().GetEditWin() );
675 pCli
= new SwOleClient( &GetView(), &GetView().GetEditWin(), xRef
);
677 uno::Reference
<lang::XInitialization
> xOLEInit(xRef
.GetObject(), uno::UNO_QUERY
);
680 uno::Sequence
<beans::PropertyValue
> aArguments
681 = { comphelper::makePropertyValue("ReadOnly", pCli
->IsProtected()) };
682 xOLEInit
->initialize({ uno::Any(aArguments
) });
685 static_cast<SwOleClient
*>(pCli
)->SetInDoVerb( true );
687 CalcAndSetScale( xRef
);
688 pCli
->DoVerb( nVerb
);
690 static_cast<SwOleClient
*>(pCli
)->SetInDoVerb( false );
691 CalcAndSetScale( xRef
);
694 void SwWrtShell::MoveObjectIfActive( svt::EmbeddedObjectRef
& xObj
, const Point
& rOffset
)
698 sal_Int32 nState
= xObj
->getCurrentState();
699 if ( nState
== css::embed::EmbedStates::INPLACE_ACTIVE
700 || nState
== css::embed::EmbedStates::UI_ACTIVE
)
702 SfxInPlaceClient
* pCli
=
703 GetView().FindIPClient( xObj
.GetObject(), &(GetView().GetEditWin()) );
706 tools::Rectangle aArea
= pCli
->GetObjArea();
708 pCli
->SetObjArea( aArea
);
712 catch (const uno::Exception
&)
717 void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef
& xObj
,
718 const SwRect
*pFlyPrtRect
,
719 const SwRect
*pFlyFrameRect
,
720 const bool bNoTextFramePrtAreaChanged
)
722 // Setting the scale of the client. This arises from the difference
723 // between the VisArea of the object and the ObjArea.
724 OSL_ENSURE( xObj
.is(), "ObjectRef not valid" );
726 sal_Int64 nAspect
= xObj
.GetViewAspect();
727 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
728 return; // the replacement image is completely controlled by container in this case
731 bool bLinkingChart
= false;
735 nMisc
= xObj
->getStatus( nAspect
);
737 // This can surely only be a non-active object, if desired they
738 // get the new size set as VisArea (StarChart).
739 if( embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
& nMisc
)
742 SwRect
aRect( pFlyPrtRect
? *pFlyPrtRect
743 : GetAnyCurRect( CurRectType::FlyEmbeddedPrt
, nullptr, xObj
.GetObject() ));
744 if( !aRect
.IsEmpty() )
746 // TODO/LEAN: getMapUnit can switch object to running state
747 // xObj.TryRunningState();
749 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( nAspect
) );
751 // TODO/LATER: needs complete VisArea?!
752 Size
aSize( OutputDevice::LogicToLogic(aRect
.SVRect(), MapMode(MapUnit::MapTwip
), MapMode(aUnit
)).GetSize() );
754 aSz
.Width
= aSize
.Width();
755 aSz
.Height
= aSize
.Height();
757 // Action 'setVisualAreaSize' doesn't have to turn on the
758 // modified state of the document, either.
759 bool bModified
= false;
760 uno::Reference
<util::XModifiable
> xModifiable(xObj
->getComponent(), uno::UNO_QUERY
);
761 if (xModifiable
.is())
762 bModified
= xModifiable
->isModified();
763 xObj
->setVisualAreaSize( nAspect
, aSz
);
764 xModifiable
.set(xObj
->getComponent(), uno::UNO_QUERY
);
765 if (xModifiable
.is() && xModifiable
->isModified() && !bModified
)
766 xModifiable
->setModified(bModified
);
768 // #i48419# - action 'UpdateReplacement' doesn't
769 // have to change the modified state of the document.
770 // This is only a workaround for the defect, that this action
771 // modifies a document after load, because unnecessarily the
772 // replacement graphic is updated, in spite of the fact that
773 // nothing has been changed.
774 // If the replacement graphic changes by this action, the document
775 // will be already modified via other mechanisms.
777 bool bResetEnableSetModified(false);
778 if ( GetDoc()->GetDocShell()->IsEnableSetModified() )
780 GetDoc()->GetDocShell()->EnableSetModified( false );
781 bResetEnableSetModified
= true;
784 //#i79576# don't destroy chart replacement images on load
785 //#i79578# don't request a new replacement image for charts to often
786 //a chart sends a modified call to the framework if it was changed
787 //thus the replacement update is already handled elsewhere
788 if ( !SotExchange::IsChart( xObj
->getClassID() ) )
789 xObj
.UpdateReplacement();
791 if ( bResetEnableSetModified
)
793 GetDoc()->GetDocShell()->EnableSetModified();
798 // TODO/LATER: this is only a workaround,
799 uno::Reference
< chart2::XChartDocument
> xChartDocument( xObj
->getComponent(), uno::UNO_QUERY
);
800 bLinkingChart
= ( xChartDocument
.is() && !xChartDocument
->hasInternalDataProvider() );
803 catch (const uno::Exception
&)
805 // TODO/LATER: handle the error
809 SfxInPlaceClient
* pCli
= GetView().FindIPClient( xObj
.GetObject(), &GetView().GetEditWin() );
812 if ( (embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY
& nMisc
)
814 // --> OD #i117189# - refine condition for non-resizable objects
815 // non-resizable objects need to be set the size back by this method
816 || ( bNoTextFramePrtAreaChanged
&& nMisc
& embed::EmbedMisc::EMBED_NEVERRESIZE
) )
818 pCli
= new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj
);
824 // TODO/LEAN: getMapUnit can switch object to running state
825 // xObj.TryRunningState();
830 aSize
= xObj
->getVisualAreaSize( nAspect
);
832 catch (const embed::NoVisualAreaSizeException
&)
834 OSL_FAIL("Can't get visual area size!" );
835 // the scaling will not be done
837 catch (const uno::Exception
&)
839 // TODO/LATER: handle the error
840 OSL_FAIL("Can't get visual area size!" );
844 Size
_aVisArea( aSize
.Width
, aSize
.Height
);
846 Fraction
aScaleWidth( 1, 1 );
847 Fraction
aScaleHeight( 1, 1 );
849 bool bUseObjectSize
= false;
851 // As long as there comes no reasonable size from the object,
852 // nothing can be scaled.
853 if( _aVisArea
.Width() && _aVisArea
.Height() )
855 const MapMode
aTmp( MapUnit::MapTwip
);
856 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( nAspect
) );
857 _aVisArea
= OutputDevice::LogicToLogic(_aVisArea
, MapMode(aUnit
), aTmp
);
860 aObjArea
= pFlyPrtRect
->SSize();
862 aObjArea
= GetAnyCurRect( CurRectType::FlyEmbeddedPrt
, nullptr, xObj
.GetObject() ).SSize();
864 // differ the aObjArea and _aVisArea by 1 Pixel then set new VisArea
866 SwSelPaintRects::Get1PixelInLogic( *this, &nX
, &nY
);
867 if( !( _aVisArea
.Width() - nX
<= aObjArea
.Width() &&
868 _aVisArea
.Width() + nX
>= aObjArea
.Width() &&
869 _aVisArea
.Height()- nY
<= aObjArea
.Height()&&
870 _aVisArea
.Height()+ nY
>= aObjArea
.Height() ))
872 if ( nMisc
& embed::EmbedMisc::EMBED_NEVERRESIZE
)
874 // the object must not be scaled,
875 // the size stored in object must be used for restoring
876 bUseObjectSize
= true;
880 aScaleWidth
= Fraction( aObjArea
.Width(), _aVisArea
.Width() );
881 aScaleHeight
= Fraction( aObjArea
.Height(), _aVisArea
.Height());
886 // Now is the favorable time to set the ObjArea.
887 // The Scaling must be considered.
891 aArea
= *pFlyPrtRect
;
892 aArea
+= pFlyFrameRect
->Pos();
896 aArea
= GetAnyCurRect( CurRectType::FlyEmbeddedPrt
, nullptr, xObj
.GetObject() );
897 aArea
.Pos() += GetAnyCurRect( CurRectType::FlyEmbedded
, nullptr, xObj
.GetObject() ).Pos();
900 if ( bUseObjectSize
)
902 // --> this moves non-resizable object so that when adding borders the baseline remains the same
903 const SwFlyFrameFormat
*pFlyFrameFormat
= dynamic_cast< const SwFlyFrameFormat
* >( GetFlyFrameFormat() );
904 OSL_ENSURE( pFlyFrameFormat
, "Could not find fly frame." );
905 if ( pFlyFrameFormat
)
907 const Point
&rPoint
= pFlyFrameFormat
->GetLastFlyFramePrtRectPos();
908 SwRect
aRect( pFlyPrtRect
? *pFlyPrtRect
909 : GetAnyCurRect( CurRectType::FlyEmbeddedPrt
, nullptr, xObj
.GetObject() ));
910 aArea
+= rPoint
- aRect
.Pos(); // adjust area by diff of printing area position in order to keep baseline alignment correct.
912 aArea
.Width ( _aVisArea
.Width() );
913 aArea
.Height( _aVisArea
.Height() );
914 RequestObjectResize( aArea
, xObj
.GetObject() );
918 double nWidth(pCli
->GetScaleWidth());
919 double nHeight(pCli
->GetScaleHeight());
920 if (nWidth
&& nHeight
)
922 aArea
.Width ( aArea
.Width() / nWidth
);
923 aArea
.Height( aArea
.Height() / nHeight
);
927 pCli
->SetObjAreaAndScale( aArea
.SVRect(), aScaleWidth
, aScaleHeight
);
930 void SwWrtShell::ConnectObj( svt::EmbeddedObjectRef
& xObj
, const SwRect
&rPrt
,
931 const SwRect
&rFrame
)
933 SfxInPlaceClient
* pCli
= GetView().FindIPClient( xObj
.GetObject(), &GetView().GetEditWin());
935 new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj
);
936 CalcAndSetScale( xObj
, &rPrt
, &rFrame
);
939 // Insert hard page break;
940 // Selections will be overwritten
941 void SwWrtShell::InsertPageBreak(const OUString
*pPageDesc
, const ::std::optional
<sal_uInt16
>& oPgNum
)
943 if (!lcl_IsAllowed(this))
949 SwActContext
aActContext(this);
950 StartUndo(SwUndoId::UI_INSERT_PAGE_BREAK
);
952 if ( !IsCursorInTable() )
956 SwFEShell::SplitNode();
957 // delete the numbered attribute of the last line if the last line is empty
958 GetDoc()->ClearLineNumAttrs( *GetCursor()->GetPoint() );
961 const SwPageDesc
*pDesc
= pPageDesc
962 ? FindPageDescByName( *pPageDesc
, true ) : nullptr;
965 SwFormatPageDesc
aDesc( pDesc
);
966 aDesc
.SetNumOffset( oPgNum
);
967 SetAttrItem( aDesc
);
970 SetAttrItem( SvxFormatBreakItem(SvxBreak::PageBefore
, RES_BREAK
) );
971 EndUndo(SwUndoId::UI_INSERT_PAGE_BREAK
);
973 collectUIInformation("BREAK_PAGE", "parameter");
976 // Insert hard page break;
977 // Selections will be overwritten
979 void SwWrtShell::InsertLineBreak(std::optional
<SwLineBreakClear
> oClear
)
981 if (!lcl_IsAllowed(this))
990 const sal_Unicode cIns
= 0x0A;
991 SwLineBreakClear eClear
= SwLineBreakClear::NONE
;
992 if (oClear
.has_value())
996 SvxAutoCorrect
* pACorr
= lcl_IsAutoCorr();
997 if (pACorr
&& eClear
== SwLineBreakClear::NONE
)
998 AutoCorrect( *pACorr
, cIns
);
1001 if (eClear
== SwLineBreakClear::NONE
)
1003 SwWrtShell::Insert(OUString(cIns
));
1007 SwFormatLineBreak
aLineBreak(eClear
);
1008 SetAttrItem(aLineBreak
);
1014 // Insert hard column break;
1015 // Selections will be overwritten
1017 void SwWrtShell::InsertColumnBreak()
1019 if (!lcl_IsAllowed(this))
1022 SwActContext
aActContext(this);
1027 StartUndo(SwUndoId::UI_INSERT_COLUMN_BREAK
);
1029 if ( !IsCursorInTable() )
1033 SwFEShell::SplitNode( false, false );
1035 SetAttrItem(SvxFormatBreakItem(SvxBreak::ColumnBefore
, RES_BREAK
));
1037 EndUndo(SwUndoId::UI_INSERT_COLUMN_BREAK
);
1040 void SwWrtShell::InsertContentControl(SwContentControlType eType
)
1042 if (!lcl_IsAllowed(this))
1053 auto pContentControl
= std::make_shared
<SwContentControl
>(nullptr);
1054 OUString aPlaceholder
;
1057 case SwContentControlType::RICH_TEXT
:
1058 case SwContentControlType::PLAIN_TEXT
:
1060 pContentControl
->SetShowingPlaceHolder(true);
1061 if (eType
== SwContentControlType::PLAIN_TEXT
)
1063 pContentControl
->SetPlainText(true);
1065 if (!HasSelection())
1067 aPlaceholder
= SwResId(STR_CONTENT_CONTROL_PLACEHOLDER
);
1071 case SwContentControlType::CHECKBOX
:
1073 pContentControl
->SetCheckbox(true);
1074 // Ballot Box with X
1075 pContentControl
->SetCheckedState(u
"\u2612");
1077 pContentControl
->SetUncheckedState(OUString(u
"\u2610"));
1078 aPlaceholder
= u
"\u2610";
1081 case SwContentControlType::COMBO_BOX
:
1082 case SwContentControlType::DROP_DOWN_LIST
:
1084 if (eType
== SwContentControlType::COMBO_BOX
)
1086 pContentControl
->SetComboBox(true);
1088 else if (eType
== SwContentControlType::DROP_DOWN_LIST
)
1090 pContentControl
->SetDropDown(true);
1093 pContentControl
->SetShowingPlaceHolder(true);
1094 if (!HasSelection())
1096 aPlaceholder
= SwResId(STR_DROPDOWN_CONTENT_CONTROL_PLACEHOLDER
);
1098 SwContentControlListItem aListItem
;
1099 aListItem
.m_aValue
= aPlaceholder
;
1100 pContentControl
->SetListItems({ aListItem
});
1103 case SwContentControlType::PICTURE
:
1105 // Set up the picture content control.
1106 pContentControl
->SetShowingPlaceHolder(true);
1107 pContentControl
->SetPicture(true);
1109 // Create the placeholder bitmap.
1110 BitmapEx
aBitmap(Size(1, 1), vcl::PixelFormat::N24_BPP
);
1111 Color aColor
= SvtOptionsDrawinglayer::getHilightColor();
1112 aColor
.IncreaseLuminance(255 * 0.75);
1113 aBitmap
.Erase(aColor
);
1114 SwRewriter aRewriter
;
1115 aRewriter
.AddRule(UndoArg1
, SwResId(STR_GRAPHIC_DEFNAME
));
1116 StartUndo(SwUndoId::INSERT
, &aRewriter
);
1117 LockPaint(LockPaintReason::InsertGraphic
);
1119 InsertGraphic(OUString(), OUString(), aBitmap
, nullptr, RndStdIds::FLY_AS_CHAR
);
1121 // Set properties on the bitmap.
1122 SfxItemSetFixed
<RES_FRM_SIZE
, RES_FRM_SIZE
> aSet(GetDoc()->GetAttrPool());
1123 GetFlyFrameAttr(aSet
);
1124 SwFormatFrameSize
aSize(SwFrameSize::Fixed
, 3000, 3000);
1126 SetFlyFrameAttr(aSet
);
1127 SwFrameFormat
* pFrameFormat
= GetFlyFrameFormat();
1132 // Go after the anchor position.
1134 LeaveSelFrameMode();
1136 SwCursor
* pCursor
= getShellCursor(true);
1137 pCursor
->DeleteMark();
1138 const SwFormatAnchor
& rFormatAnchor
= pFrameFormat
->GetAnchor();
1139 pCursor
->GetPoint()->Assign( *rFormatAnchor
.GetAnchorContentNode(), rFormatAnchor
.GetAnchorContentOffset() + 1);
1142 // Select before the anchor position.
1143 Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
1146 case SwContentControlType::DATE
:
1148 pContentControl
->SetShowingPlaceHolder(true);
1149 pContentControl
->SetDate(true);
1150 SvNumberFormatter
* pFormatter
= GetDoc()->GetNumberFormatter();
1151 sal_uInt32 nStandardFormat
= pFormatter
->GetStandardFormat(SvNumFormatType::DATE
);
1152 const SvNumberformat
* pFormat
= pFormatter
->GetEntry(nStandardFormat
);
1153 pContentControl
->SetDateFormat(pFormat
->GetFormatstring());
1154 pContentControl
->SetDateLanguage(LanguageTag(pFormat
->GetLanguage()).getBcp47());
1155 if (!HasSelection())
1157 aPlaceholder
= SwResId(STR_DATE_CONTENT_CONTROL_PLACEHOLDER
);
1162 if (aPlaceholder
.getLength())
1164 Insert(aPlaceholder
);
1165 Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, aPlaceholder
.getLength(),
1166 /*bBasicCall=*/false);
1168 SwFormatContentControl
aContentControl(pContentControl
, RES_TXTATR_CONTENTCONTROL
);
1169 SetAttrItem(aContentControl
);
1173 // rStr - optional footnote mark
1175 void SwWrtShell::InsertFootnote(const OUString
&rStr
, bool bEndNote
, bool bEdit
)
1183 //collapse cursor to the end
1184 if(!IsCursorPtAtEnd())
1188 SwPosition aPos
= *GetCursor()->GetPoint();
1189 SwFormatFootnote
aFootNote( bEndNote
);
1191 aFootNote
.SetNumStr( rStr
);
1193 SetAttrItem(aFootNote
);
1197 // For editing the footnote text.
1198 Left(SwCursorSkipMode::Chars
, false, 1, false );
1201 m_aNavigationMgr
.addEntry(aPos
);
1205 static bool lcl_FoldedOutlineNodeEndOfParaSplit(SwWrtShell
*pThis
)
1207 SwTextNode
* pTextNode
= pThis
->GetCursor()->GetPointNode().GetTextNode();
1208 if (pTextNode
&& pTextNode
->IsOutline())
1210 bool bVisible
= true;
1211 pTextNode
->GetAttrOutlineContentVisible(bVisible
);
1214 const SwNodes
& rNodes
= pThis
->GetNodes();
1215 const SwOutlineNodes
& rOutlineNodes
= rNodes
.GetOutLineNds();
1216 SwOutlineNodes::size_type nPos
;
1217 (void) rOutlineNodes
.Seek_Entry(pTextNode
, &nPos
);
1219 SwNode
* pSttNd
= rOutlineNodes
[nPos
];
1221 // determine end node of folded outline content
1222 SwNode
* pEndNd
= &rNodes
.GetEndOfContent();
1223 if (rOutlineNodes
.size() > nPos
+ 1)
1224 pEndNd
= rOutlineNodes
[nPos
+ 1];
1226 if (pThis
->GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
1228 // get the next outline node after the folded outline content (iPos)
1229 // it is the next outline node with the same level or less
1230 int nLevel
= pSttNd
->GetTextNode()->GetAttrOutlineLevel();
1231 SwOutlineNodes::size_type iPos
= nPos
;
1232 while (++iPos
< rOutlineNodes
.size() &&
1233 rOutlineNodes
[iPos
]->GetTextNode()->GetAttrOutlineLevel() > nLevel
);
1235 // get the correct end node
1236 // the outline node may be in frames, headers, footers special section of doc model
1237 SwNode
* pStartOfSectionNodeSttNd
= pSttNd
->StartOfSectionNode();
1238 while (pStartOfSectionNodeSttNd
->StartOfSectionNode()
1239 != pStartOfSectionNodeSttNd
->StartOfSectionNode()->StartOfSectionNode())
1241 pStartOfSectionNodeSttNd
= pStartOfSectionNodeSttNd
->StartOfSectionNode();
1243 pEndNd
= pStartOfSectionNodeSttNd
->EndOfSectionNode();
1245 if (iPos
< rOutlineNodes
.size())
1247 SwNode
* pStartOfSectionNode
= rOutlineNodes
[iPos
]->StartOfSectionNode();
1248 while (pStartOfSectionNode
->StartOfSectionNode()
1249 != pStartOfSectionNode
->StartOfSectionNode()->StartOfSectionNode())
1251 pStartOfSectionNode
= pStartOfSectionNode
->StartOfSectionNode();
1253 if (pStartOfSectionNodeSttNd
== pStartOfSectionNode
)
1254 pEndNd
= rOutlineNodes
[iPos
];
1258 // table, text box, header, footer
1259 if (pSttNd
->GetTableBox() || pSttNd
->GetIndex() < rNodes
.GetEndOfExtras().GetIndex())
1261 // insert before section end node
1262 if (pSttNd
->EndOfSectionIndex() < pEndNd
->GetIndex())
1264 SwNodeIndex
aIdx(*pSttNd
->EndOfSectionNode());
1265 while (aIdx
.GetNode().IsEndNode())
1268 pEndNd
= &aIdx
.GetNode();
1271 // if pSttNd isn't in table but pEndNd is then insert after table
1272 else if (pEndNd
->GetTableBox())
1274 pEndNd
= pEndNd
->FindTableNode();
1275 SwNodeIndex
aIdx(*pEndNd
, -1);
1276 // account for nested tables
1277 while (aIdx
.GetNode().GetTableBox())
1279 pEndNd
= aIdx
.GetNode().FindTableNode();
1280 aIdx
.Assign(*pEndNd
, -1);
1282 aIdx
.Assign(*pEndNd
->EndOfSectionNode(), +1);
1283 pEndNd
= &aIdx
.GetNode();
1285 // end node determined
1287 // now insert the new outline node
1288 SwDoc
* pDoc
= pThis
->GetDoc();
1290 // insert at end of tablebox doesn't work correct without
1291 MakeAllOutlineContentTemporarilyVisible
a(pDoc
);
1293 SwTextNode
* pNd
= pDoc
->GetNodes().MakeTextNode(*pEndNd
, pTextNode
->GetTextColl(), true);
1295 (void) rOutlineNodes
.Seek_Entry(pNd
, &nPos
);
1296 pThis
->GotoOutline(nPos
);
1298 if (pDoc
->GetIDocumentUndoRedo().DoesUndo())
1300 pDoc
->GetIDocumentUndoRedo().ClearRedo();
1301 pDoc
->GetIDocumentUndoRedo().AppendUndo(std::make_unique
<SwUndoInsert
>(*pNd
));
1302 pDoc
->GetIDocumentUndoRedo().AppendUndo(std::make_unique
<SwUndoFormatColl
>
1303 (SwPaM(*pNd
), pNd
->GetTextColl(), true, true));
1306 pThis
->SetModified();
1313 // SplitNode; also, because
1314 // - of deleting selected content;
1315 // - of reset of the Cursorstack if necessary.
1317 void SwWrtShell::SplitNode( bool bAutoFormat
)
1323 SwActContext
aActContext(this);
1325 m_rView
.GetEditWin().FlushInBuffer();
1326 StartUndo(SwUndoId::SPLITNODE
);
1328 bool bHasSel
= HasSelection();
1332 bool bHandled
= false;
1333 if (GetViewOptions()->IsShowOutlineContentVisibilityButton() && IsEndPara())
1334 bHandled
= lcl_FoldedOutlineNodeEndOfParaSplit(this);
1337 SwFEShell::SplitNode( bAutoFormat
);
1339 EndUndo(SwUndoId::SPLITNODE
);
1342 // Turn on numbering
1343 // Parameter: Optional specification of a name for the named list;
1344 // this indicates a position if it is possible to convert them
1345 // into a number and less than nMaxRules.
1347 // To test the CharFormats at the numbering
1348 // external void SetNumChrFormat( SwWrtShell*, SwNumRules& );
1351 // Preconditions (as far as OD has figured out):
1352 // - <SwEditShell::HasNumber()> is false, if <bNum> is true
1353 // - <SwEditShell::HasBullet()> is false, if <bNum> is false
1354 // Behavior of method is determined by the current situation at the current
1355 // cursor position in the document.
1356 void SwWrtShell::NumOrBulletOn(bool bNum
)
1358 StartUndo(SwUndoId::NUMORNONUM
);
1360 const SwNumRule
* pNumRule
= GetNumRuleAtCurrCursorPos();
1362 // - activate outline rule respectively turning on outline rule for
1363 // current text node. But, only for turning on a numbering (<bNum> == true).
1364 // - overwrite found numbering rule at current cursor position, if
1365 // no numbering rule can be retrieved from the paragraph style.
1366 bool bContinueFoundNumRule( false );
1367 bool bActivateOutlineRule( false );
1368 int nActivateOutlineLvl( MAXLEVEL
); // only relevant, if <bActivateOutlineRule> == true
1369 SwTextFormatColl
* pColl
= GetCurTextFormatColl();
1372 // retrieve numbering rule at paragraph
1373 // style, which is found at current cursor position in the document.
1374 SwNumRule
* pCollRule
= mxDoc
->FindNumRulePtr(pColl
->GetNumRule().GetValue());
1375 // #125993# - The outline numbering rule isn't allowed
1376 // to be derived from a parent paragraph style to a derived one.
1377 // Thus check, if the found outline numbering rule is directly
1378 // set at the paragraph style <pColl>. If not, set <pCollRule> to NULL
1379 if ( pCollRule
&& pCollRule
== GetDoc()->GetOutlineNumRule() )
1381 const SwNumRule
* pDirectCollRule
=
1382 mxDoc
->FindNumRulePtr(pColl
->GetNumRule( false ).GetValue());
1383 if ( !pDirectCollRule
)
1385 pCollRule
= nullptr;
1391 pNumRule
= pCollRule
;
1393 // no activation or continuation of outline numbering in Writer/Web document
1395 !dynamic_cast<SwWebDocShell
*>(GetDoc()->GetDocShell()) &&
1396 pCollRule
== GetDoc()->GetOutlineNumRule() )
1398 if ( pNumRule
== pCollRule
)
1400 // check, if text node at current cursor positioned is counted.
1401 // If not, let it been counted. Then it has to be checked,
1402 // of the outline numbering has to be activated or continued.
1403 SwTextNode
const*const pTextNode
= sw::GetParaPropsNode(
1404 *GetLayout(), GetCursor()->GetPoint()->GetNode());
1405 if ( pTextNode
&& !pTextNode
->IsCountedInList() )
1407 // check, if numbering of the outline level of the paragraph
1408 // style is active. If not, activate this outline level.
1409 nActivateOutlineLvl
= pColl
->GetAssignedOutlineStyleLevel();
1410 OSL_ENSURE( pColl
->IsAssignedToListLevelOfOutlineStyle(),
1411 "<SwWrtShell::NumOrBulletOn(..)> - paragraph style with outline rule, but no outline level" );
1412 if ( pColl
->IsAssignedToListLevelOfOutlineStyle() &&
1413 pCollRule
->Get( o3tl::narrowing
<sal_uInt16
>(nActivateOutlineLvl
) ).GetNumberingType()
1414 == SVX_NUM_NUMBER_NONE
)
1416 // activate outline numbering
1417 bActivateOutlineRule
= true;
1421 // turning on outline numbering at current cursor position
1422 bContinueFoundNumRule
= true;
1428 // activate outline numbering, because from the precondition
1429 // it's known, that <SwEdit::HasNumber()> == false
1430 bActivateOutlineRule
= true;
1431 nActivateOutlineLvl
= pColl
->GetAssignedOutlineStyleLevel();
1434 else if ( !pNumRule
)
1437 // Check, if corresponding list level of the outline numbering
1438 // has already a numbering format set.
1439 nActivateOutlineLvl
= pColl
->GetAssignedOutlineStyleLevel();
1440 if ( pCollRule
->Get( o3tl::narrowing
<sal_uInt16
>(nActivateOutlineLvl
) ).GetNumberingType()
1441 == SVX_NUM_NUMBER_NONE
)
1443 // activate outline numbering, because from the precondition
1444 // it's known, that <SwEdit::HasNumber()> == false
1445 bActivateOutlineRule
= true;
1449 // turning on outline numbering at current cursor position
1450 bContinueFoundNumRule
= true;
1455 // check, if numbering of the outline level of the paragraph
1456 // style is active. If not, activate this outline level.
1457 nActivateOutlineLvl
= pColl
->GetAssignedOutlineStyleLevel();
1458 OSL_ENSURE( pColl
->IsAssignedToListLevelOfOutlineStyle(),
1459 "<SwWrtShell::NumOrBulletOn(..)> - paragraph style with outline rule, but no outline level" );
1460 if ( pColl
->IsAssignedToListLevelOfOutlineStyle() &&
1461 pCollRule
->Get( o3tl::narrowing
<sal_uInt16
>(nActivateOutlineLvl
) ).GetNumberingType()
1462 == SVX_NUM_NUMBER_NONE
)
1464 // activate outline numbering
1465 bActivateOutlineRule
= true;
1469 // turning on outline numbering at current cursor position
1470 bContinueFoundNumRule
= true;
1473 pNumRule
= pCollRule
;
1477 // Only automatic numbering/bullet rules should be changed.
1478 // Note: The outline numbering rule is also an automatic one. It's only
1479 // changed, if it has to be activated.
1482 if ( !pNumRule
->IsAutoRule() )
1486 else if ( pNumRule
== GetDoc()->GetOutlineNumRule() &&
1487 !bActivateOutlineRule
&& !bContinueFoundNumRule
)
1493 // Search for a previous numbering/bullet rule to continue it.
1494 OUString sContinuedListId
;
1497 pNumRule
= GetDoc()->SearchNumRule( *GetCursor()->GetPoint(),
1498 false, bNum
, false, 0,
1499 sContinuedListId
, GetLayout() );
1500 bContinueFoundNumRule
= pNumRule
!= nullptr;
1505 SwNumRule
aNumRule(*pNumRule
);
1507 // do not change found numbering/bullet rule, if it should only be continued.
1508 if ( !bContinueFoundNumRule
)
1510 SwTextNode
const*const pTextNode
= sw::GetParaPropsNode(
1511 *GetLayout(), GetCursor()->GetPoint()->GetNode());
1515 // use above retrieve outline level, if outline numbering has to be activated.
1516 int nLevel
= bActivateOutlineRule
1517 ? nActivateOutlineLvl
1518 : pTextNode
->GetActualListLevel();
1523 if (nLevel
>= MAXLEVEL
)
1524 nLevel
= MAXLEVEL
- 1;
1526 SwNumFormat
aFormat(aNumRule
.Get(o3tl::narrowing
<sal_uInt16
>(nLevel
)));
1529 aFormat
.SetNumberingType(SVX_NUM_ARABIC
);
1532 // #i63395# Only apply user defined default bullet font
1533 if ( numfunc::IsDefBulletFontUserDefined() )
1535 const vcl::Font
* pFnt
= &numfunc::GetDefBulletFont();
1536 aFormat
.SetBulletFont( pFnt
);
1538 aFormat
.SetBulletChar( numfunc::GetBulletChar(static_cast<sal_uInt8
>(nLevel
)));
1539 aFormat
.SetNumberingType(SVX_NUM_CHAR_SPECIAL
);
1540 // #i93908# clear suffix for bullet lists
1541 aFormat
.SetListFormat("", "", nLevel
);
1543 aNumRule
.Set(o3tl::narrowing
<sal_uInt16
>(nLevel
), aFormat
);
1547 // reset indent attribute on applying list style
1548 SetCurNumRule( aNumRule
, false, sContinuedListId
, true );
1553 const SvxNumberFormat::SvxNumPositionAndSpaceMode
ePosAndSpaceMode(
1554 numfunc::GetDefaultPositionAndSpaceMode() );
1555 SwNumRule
aNumRule( GetUniqueNumRuleName(), ePosAndSpaceMode
);
1556 // Append the character template at the numbering.
1557 SwCharFormat
* pChrFormat
;
1558 SwDocShell
* pDocSh
= GetView().GetDocShell();
1560 // Only apply user defined default bullet font
1561 const vcl::Font
* pFnt
= numfunc::IsDefBulletFontUserDefined()
1562 ? &numfunc::GetDefBulletFont()
1567 pChrFormat
= GetCharFormatFromPool( RES_POOLCHR_NUM_LEVEL
);
1571 pChrFormat
= GetCharFormatFromPool( RES_POOLCHR_BULLET_LEVEL
);
1574 const SwTextNode
*const pTextNode
= sw::GetParaPropsNode(*GetLayout(),
1575 GetCursor()->GetPoint()->GetNode());
1576 const SwTwips nWidthOfTabs
= pTextNode
1577 ? pTextNode
->GetWidthOfLeadingTabs()
1579 GetDoc()->getIDocumentContentOperations().RemoveLeadingWhiteSpace(*GetCursor());
1581 const bool bHtml
= dynamic_cast<SwWebDocShell
*>( pDocSh
) != nullptr;
1582 const bool bRightToLeft
= IsInRightToLeftText();
1583 for( sal_uInt8 nLvl
= 0; nLvl
< MAXLEVEL
; ++nLvl
)
1585 SwNumFormat
aFormat( aNumRule
.Get( nLvl
) );
1586 aFormat
.SetCharFormat( pChrFormat
);
1591 // Only apply user defined default bullet font
1594 aFormat
.SetBulletFont( pFnt
);
1596 aFormat
.SetBulletChar( numfunc::GetBulletChar(nLvl
) );
1597 aFormat
.SetNumberingType(SVX_NUM_CHAR_SPECIAL
);
1598 // #i93908# clear suffix for bullet lists
1599 aFormat
.SetListFormat("", "", nLvl
);
1603 if ( ePosAndSpaceMode
== SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1608 aFormat
.SetAbsLSpace(nLvl
* 720);
1610 else if ( nWidthOfTabs
> 0 )
1612 aFormat
.SetAbsLSpace(nWidthOfTabs
+ nLvl
* 720);
1616 // #i38904# Default alignment for
1617 // numbering/bullet should be rtl in rtl paragraph:
1620 aFormat
.SetNumAdjust( SvxAdjust::Right
);
1623 aNumRule
.Set( nLvl
, aFormat
);
1628 ePosAndSpaceMode
== SvxNumberFormat::LABEL_ALIGNMENT
)
1631 const SwTwips nTextNodeIndent
= pTextNode
->GetAdditionalIndentForStartingNewList();
1632 if ( ( nTextNodeIndent
+ nWidthOfTabs
) != 0 )
1634 // #i111172#/fdo#85666
1635 // If text node is already inside a list, assure that the indents
1636 // are the same. Thus, adjust the indent change value by subtracting
1637 // indents of to be applied list style.
1638 SwTwips nIndentChange
= nTextNodeIndent
+ nWidthOfTabs
;
1639 if ( pTextNode
->GetNumRule() )
1641 int nLevel
= pTextNode
->GetActualListLevel();
1646 if (nLevel
>= MAXLEVEL
)
1647 nLevel
= MAXLEVEL
- 1;
1649 const SwNumFormat
& aFormat( aNumRule
.Get( nLevel
) );
1650 if ( aFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
1652 nIndentChange
-= aFormat
.GetIndentAt() + aFormat
.GetFirstLineIndent();
1655 aNumRule
.ChangeIndent( nIndentChange
);
1658 // reset indent attribute on applying list style
1660 SetCurNumRule( aNumRule
, true, OUString(), true );
1663 EndUndo(SwUndoId::NUMORNONUM
);
1667 void SwWrtShell::NumOn()
1669 NumOrBulletOn(true);
1672 void SwWrtShell::NumOrBulletOff()
1674 const SwNumRule
* pCurNumRule
= GetNumRuleAtCurrCursorPos();
1679 if (pCurNumRule
->IsOutlineRule())
1681 SwNumRule
aNumRule(*pCurNumRule
);
1683 SwTextNode
* pTextNode
=
1684 sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->GetNode());
1688 int nLevel
= pTextNode
->GetActualListLevel();
1693 if (nLevel
>= MAXLEVEL
)
1694 nLevel
= MAXLEVEL
- 1;
1696 SwNumFormat
aFormat(aNumRule
.Get(o3tl::narrowing
<sal_uInt16
>(nLevel
)));
1698 aFormat
.SetNumberingType(SVX_NUM_NUMBER_NONE
);
1699 aNumRule
.Set(nLevel
, aFormat
);
1701 // no start or continuation of a list - the outline style is only changed.
1702 SetCurNumRule( aNumRule
, false );
1710 // #126346# - Cursor can not be anymore in front of
1711 // a label, because numbering/bullet is switched off.
1712 SetInFrontOfLabel( false );
1716 // Request Default-Bulletlist
1718 void SwWrtShell::BulletOn()
1720 NumOrBulletOn(false);
1723 SelectionType
SwWrtShell::GetSelectionType() const
1725 // ContentType cannot be determined within a Start-/EndAction.
1726 // Because there is no invalid value TEXT will be returned.
1727 // The value does not matter, it may be updated in EndAction anyway.
1730 return IsSelFrameMode() ? SelectionType::Frame
: SelectionType::Text
;
1732 SwView
&_rView
= const_cast<SwView
&>(GetView());
1733 if (_rView
.GetPostItMgr() && _rView
.GetPostItMgr()->HasActiveSidebarWin() )
1734 return SelectionType::PostIt
;
1736 // Inserting a frame is not a DrawMode
1738 if ( !_rView
.GetEditWin().IsFrameAction() &&
1739 (IsObjSelected() || (_rView
.IsDrawMode() && !IsFrameSelected()) ))
1741 if (GetDrawView()->IsTextEdit())
1742 nCnt
= SelectionType::DrawObjectEditMode
;
1745 if (GetView().IsFormMode()) // Only Form selected
1746 nCnt
= SelectionType::DbForm
;
1748 nCnt
= SelectionType::DrawObject
; // Any draw object
1750 if (_rView
.IsBezierEditMode())
1751 nCnt
|= SelectionType::Ornament
;
1752 else if( GetDrawView()->GetContext() == SdrViewContext::Media
)
1753 nCnt
|= SelectionType::Media
;
1755 if (svx::checkForSelectedCustomShapes( GetDrawView(), true /* bOnlyExtruded */ ))
1757 nCnt
|= SelectionType::ExtrudedCustomShape
;
1760 if (svx::checkForSelectedFontWork( GetDrawView() ))
1762 nCnt
|= SelectionType::FontWork
;
1769 nCnt
= static_cast<SelectionType
>(GetCntType());
1771 if ( IsFrameSelected() )
1773 if (_rView
.IsDrawMode())
1774 _rView
.LeaveDrawCreate(); // clean up (Bug #45639)
1775 if ( !(nCnt
& (SelectionType::Graphic
| SelectionType::Ole
)) )
1776 return SelectionType::Frame
;
1779 if ( IsCursorInTable() )
1780 nCnt
|= SelectionType::Table
;
1782 if ( IsTableMode() )
1784 nCnt
|= SelectionType::Table
| SelectionType::TableCell
;
1785 SwTable::SearchType eTableSel
= GetEnhancedTableSelection();
1786 if ( eTableSel
== SwTable::SEARCH_ROW
)
1787 nCnt
|= SelectionType::TableRow
;
1788 else if ( eTableSel
== SwTable::SEARCH_COL
)
1789 nCnt
|= SelectionType::TableCol
;
1792 // Do not pop up numbering toolbar, if the text node has a numbering of type SVX_NUM_NUMBER_NONE.
1793 const SwNumRule
* pNumRule
= GetNumRuleAtCurrCursorPos();
1796 const SwTextNode
* pTextNd
=
1797 sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->GetNode());
1799 if ( pTextNd
&& pTextNd
->IsInList() )
1801 int nLevel
= pTextNd
->GetActualListLevel();
1806 if (nLevel
>= MAXLEVEL
)
1807 nLevel
= MAXLEVEL
- 1;
1809 const SwNumFormat
& rFormat
= pNumRule
->Get(nLevel
);
1810 if ( SVX_NUM_NUMBER_NONE
!= rFormat
.GetNumberingType() )
1811 nCnt
|= SelectionType::NumberList
;
1818 // Find the text collection with the name rCollname
1819 // Returns: Pointer at the collection or 0, if no
1820 // text collection with this name exists, or
1821 // this is a default template.
1823 SwTextFormatColl
*SwWrtShell::GetParaStyle(const OUString
&rCollName
, GetStyle eCreate
)
1825 SwTextFormatColl
* pColl
= FindTextFormatCollByName( rCollName
);
1826 if( !pColl
&& GETSTYLE_NOCREATE
!= eCreate
)
1828 sal_uInt16 nId
= SwStyleNameMapper::GetPoolIdFromUIName( rCollName
, SwGetPoolIdFromName::TxtColl
);
1829 if( USHRT_MAX
!= nId
|| GETSTYLE_CREATEANY
== eCreate
)
1830 pColl
= GetTextCollFromPool( nId
);
1835 // Find the text collection with the name rCollname
1836 // Returns: Pointer at the collection or 0, if no
1837 // character template with this name exists, or
1838 // this is a default template or template is automatic.
1840 SwCharFormat
*SwWrtShell::GetCharStyle(const OUString
&rFormatName
, GetStyle eCreate
)
1842 SwCharFormat
* pFormat
= FindCharFormatByName( rFormatName
);
1843 if( !pFormat
&& GETSTYLE_NOCREATE
!= eCreate
)
1845 sal_uInt16 nId
= SwStyleNameMapper::GetPoolIdFromUIName( rFormatName
, SwGetPoolIdFromName::ChrFmt
);
1846 if( USHRT_MAX
!= nId
|| GETSTYLE_CREATEANY
== eCreate
)
1847 pFormat
= static_cast<SwCharFormat
*>(GetFormatFromPool( nId
));
1852 // Find the table format with the name rFormatname
1853 // Returns: Pointer at the collection or 0, if no
1854 // frame format with this name exists or
1855 // this is a default format or the format is automatic.
1857 SwFrameFormat
*SwWrtShell::GetTableStyle(std::u16string_view rFormatName
)
1859 for( size_t i
= GetTableFrameFormatCount(); i
; )
1861 SwFrameFormat
*pFormat
= &GetTableFrameFormat( --i
);
1862 if( !pFormat
->IsDefault() &&
1863 pFormat
->GetName() == rFormatName
&& IsUsed( *pFormat
) )
1869 void SwWrtShell::addCurrentPosition() {
1870 SwPaM
* pPaM
= GetCursor();
1871 m_aNavigationMgr
.addEntry(*pPaM
->GetPoint());
1874 // Applying templates
1876 void SwWrtShell::SetPageStyle(const OUString
&rCollName
)
1878 if( !SwCursorShell::HasSelection() && !IsSelFrameMode() && !IsObjSelected() )
1880 SwPageDesc
* pDesc
= FindPageDescByName( rCollName
, true );
1882 ChgCurPageDesc( *pDesc
);
1888 OUString
const & SwWrtShell::GetCurPageStyle() const
1890 return GetPageDesc(GetCurPageDesc( false/*bCalcFrame*/ )).GetName();
1893 // Change the current template referring to the existing change.
1895 void SwWrtShell::QuickUpdateStyle()
1897 SwTextFormatColl
*pColl
= GetCurTextFormatColl();
1899 // Default cannot be changed
1900 if(pColl
&& !pColl
->IsDefault())
1903 // Also apply the template to remove hard attribute assignment.
1904 SetTextFormatColl(pColl
);
1908 void SwWrtShell::AutoUpdatePara(SwTextFormatColl
* pColl
, const SfxItemSet
& rStyleSet
, SwPaM
* pPaM
)
1910 SwPaM
* pCursor
= pPaM
? pPaM
: GetCursor( );
1912 RES_CHRATR_BEGIN
, RES_CHRATR_END
- 1,
1913 RES_PARATR_BEGIN
, RES_PARATR_END
- 1,
1914 RES_FRMATR_BEGIN
, RES_FRMATR_END
- 1,
1915 SID_ATTR_TABSTOP_DEFAULTS
,SID_ATTR_TABSTOP_OFFSET
,
1916 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
,
1917 SID_ATTR_PARA_MODEL
, SID_ATTR_PARA_KEEP
,
1918 SID_ATTR_PARA_PAGENUM
, SID_ATTR_PARA_PAGENUM
> aCoreSet( GetAttrPool() );
1919 GetPaMAttr( pCursor
, aCoreSet
);
1920 bool bReset
= false;
1921 SfxItemIter
aParaIter( aCoreSet
);
1922 for (auto pParaItem
= aParaIter
.GetCurItem(); pParaItem
; pParaItem
= aParaIter
.NextItem())
1924 if(!IsInvalidItem(pParaItem
))
1926 sal_uInt16 nWhich
= pParaItem
->Which();
1927 if(SfxItemState::SET
== aParaIter
.GetItemState() &&
1928 SfxItemState::SET
== rStyleSet
.GetItemState(nWhich
))
1930 aParaIter
.ClearItem();
1938 ResetAttr({}, pCursor
);
1939 SetAttrSet(aCoreSet
, SetAttrMode::DEFAULT
, pCursor
);
1941 mxDoc
->ChgFormat(*pColl
, rStyleSet
);
1945 void SwWrtShell::AutoUpdateFrame( SwFrameFormat
* pFormat
, const SfxItemSet
& rStyleSet
)
1949 ResetFlyFrameAttr( &rStyleSet
);
1950 pFormat
->SetFormatAttr( rStyleSet
);
1955 void SwWrtShell::AutoCorrect( SvxAutoCorrect
& rACorr
, sal_Unicode cChar
)
1961 bool bStarted
= false;
1962 SwRewriter aRewriter
;
1966 // Only parentheses here, because the regular insert
1967 // is already clipped to the editshell
1970 OUString aTmpStr1
= SwResId(STR_START_QUOTE
) +
1972 SwResId(STR_END_QUOTE
);
1973 OUString aTmpStr3
= SwResId(STR_START_QUOTE
) +
1974 OUStringChar(cChar
) +
1975 SwResId(STR_END_QUOTE
);
1976 aRewriter
.AddRule( UndoArg1
, aTmpStr1
);
1977 aRewriter
.AddRule( UndoArg2
, SwResId(STR_YIELDS
) );
1978 aRewriter
.AddRule( UndoArg3
, aTmpStr3
);
1980 StartUndo( SwUndoId::REPLACE
, &aRewriter
);
1984 SwEditShell::AutoCorrect( rACorr
, IsInsMode(), cChar
);
1989 EndUndo( SwUndoId::REPLACE
, &aRewriter
);
1993 // Some kind of controlled copy ctor
1995 SwWrtShell::SwWrtShell( SwWrtShell
& rSh
, vcl::Window
*_pWin
, SwView
&rShell
)
1996 : SwFEShell(rSh
, _pWin
)
1998 , m_aNavigationMgr(*this)
2001 CurrShell
aCurr( this );
2003 SetSfxViewShell( static_cast<SfxViewShell
*>(&rShell
) );
2004 SetFlyMacroLnk( LINK(this, SwWrtShell
, ExecFlyMac
) );
2006 // place the cursor on the first field...
2007 IFieldmark
*pBM
= nullptr;
2008 if (IsFormProtected() && (pBM
= GetFieldmarkAfter(/*bLoop=*/true)) !=nullptr) {
2013 SwWrtShell::SwWrtShell( SwDoc
& rDoc
, vcl::Window
*_pWin
, SwView
&rShell
,
2014 const SwViewOption
*pViewOpt
)
2015 : SwFEShell(rDoc
, _pWin
, pViewOpt
)
2017 , m_aNavigationMgr(*this)
2020 CurrShell
aCurr( this );
2021 SetSfxViewShell( static_cast<SfxViewShell
*>(&rShell
) );
2022 SetFlyMacroLnk( LINK(this, SwWrtShell
, ExecFlyMac
) );
2024 // place the cursor on the first field...
2025 IFieldmark
*pBM
= nullptr;
2026 if (IsFormProtected() && (pBM
= GetFieldmarkAfter(/*bLoop=*/true)) !=nullptr) {
2031 SwWrtShell::~SwWrtShell()
2033 CurrShell
aCurr( this );
2034 while(IsModePushed())
2036 while(PopCursor(false))
2038 SwTransferable::ClearSelection( *this );
2041 bool SwWrtShell::Pop(SwCursorShell::PopMode
const eDelete
)
2043 ::std::optional
<SwCallLink
> aLink(std::in_place
, *this);
2044 return Pop(eDelete
, aLink
);
2047 bool SwWrtShell::Pop(SwCursorShell::PopMode
const eDelete
, ::std::optional
<SwCallLink
>& roLink
)
2049 bool bRet
= SwCursorShell::Pop(eDelete
, roLink
);
2050 if( bRet
&& IsSelection() )
2052 m_fnSetCursor
= &SwWrtShell::SetCursorKillSel
;
2053 m_fnKillSel
= &SwWrtShell::ResetSelect
;
2058 bool SwWrtShell::CanInsert()
2060 if(IsSelFrameMode())
2070 if(GetView().GetDrawFuncPtr())
2075 if(GetView().GetPostItMgr()->GetActiveSidebarWin())
2083 void SwWrtShell::ChgDBData(const SwDBData
& aDBData
)
2085 SwEditShell::ChgDBData(aDBData
);
2086 //notify the db-beamer if available
2087 GetView().NotifyDBChanged();
2090 OUString
SwWrtShell::GetSelDescr() const
2094 SelectionType nSelType
= GetSelectionType();
2097 case SelectionType::Graphic
:
2098 aResult
= SwResId(STR_GRAPHIC
);
2101 case SelectionType::Frame
:
2103 const SwFrameFormat
* pFrameFormat
= GetSelectedFrameFormat();
2106 aResult
= pFrameFormat
->GetDescription();
2109 case SelectionType::DrawObject
:
2111 aResult
= SwResId(STR_DRAWING_OBJECTS
);
2116 aResult
= GetCursorDescr();
2122 void SwWrtShell::ApplyViewOptions( const SwViewOption
&rOpt
)
2124 SwFEShell::ApplyViewOptions( rOpt
);
2125 //#i115062# invalidate meta character slot
2126 GetView().GetViewFrame().GetBindings().Invalidate( FN_VIEW_META_CHARS
);
2129 void SwWrtShell::SetReadonlyOption(bool bSet
)
2131 GetView().GetEditWin().GetFrameControlsManager().SetReadonlyControls( bSet
);
2132 SwViewShell::SetReadonlyOption( bSet
);
2135 // Switch on/off header or footer of a page style - if an empty name is
2136 // given all styles are changed
2138 void SwWrtShell::ChangeHeaderOrFooter(
2139 std::u16string_view rStyleName
, bool bHeader
, bool bOn
, bool bShowWarning
)
2141 SdrView
*const pSdrView
= GetDrawView();
2142 if (pSdrView
&& pSdrView
->IsTextEdit())
2143 { // tdf#107474 deleting header may delete active drawing object
2144 pSdrView
->SdrEndTextEdit(true);
2146 addCurrentPosition();
2148 StartUndo( SwUndoId::HEADER_FOOTER
); // #i7983#
2149 bool bExecute
= true;
2150 bool bCursorSet
= false;
2151 for( size_t nFrom
= 0, nTo
= GetPageDescCnt();
2152 nFrom
< nTo
; ++nFrom
)
2154 SwPageDesc
aDesc( GetPageDesc( nFrom
));
2155 OUString
sTmp(aDesc
.GetName());
2156 if( rStyleName
.empty() || rStyleName
== sTmp
)
2160 if( bShowWarning
&& !bOn
&& GetActiveView() && GetActiveView() == &GetView() &&
2161 ( (bHeader
&& aDesc
.GetMaster().GetHeader().IsActive()) ||
2162 (!bHeader
&& aDesc
.GetMaster().GetFooter().IsActive()) ) )
2164 bShowWarning
= false;
2165 //Actions have to be closed while the dialog is showing
2168 weld::Window
* pParent
= GetView().GetFrameWeld();
2171 nResult
= DeleteHeaderDialog(pParent
).run();
2173 nResult
= DeleteFooterDialog(pParent
).run();
2176 bExecute
= nResult
== RET_YES
;
2178 if (nResult
== RET_YES
)
2179 ToggleHeaderFooterEdit();
2184 SwFrameFormat
&rMaster
= aDesc
.GetMaster();
2186 rMaster
.SetFormatAttr( SwFormatHeader( bOn
));
2188 rMaster
.SetFormatAttr( SwFormatFooter( bOn
));
2191 // keep in sync with FN_PGNUMBER_WIZARD
2192 constexpr tools::Long constTwips_5mm
= o3tl::toTwips(5, o3tl::Length::mm
);
2193 SvxULSpaceItem
aUL(bHeader
? 0 : constTwips_5mm
, bHeader
? constTwips_5mm
: 0, RES_UL_SPACE
);
2194 SwFrameFormat
* pFormat
= bHeader
?
2195 const_cast<SwFrameFormat
*>(rMaster
.GetHeader().GetHeaderFormat()) :
2196 const_cast<SwFrameFormat
*>(rMaster
.GetFooter().GetFooterFormat());
2197 pFormat
->SetFormatAttr( aUL
);
2198 XFillStyleItem
aFill(drawing::FillStyle_NONE
);
2199 pFormat
->SetFormatAttr(aFill
);
2204 ChgPageDesc( nFrom
, aDesc
);
2206 if( !bCursorSet
&& bOn
)
2208 if ( !IsHeaderFooterEdit() )
2209 ToggleHeaderFooterEdit();
2210 bCursorSet
= SetCursorInHdFt(
2211 rStyleName
.empty() ? SIZE_MAX
: nFrom
,
2217 EndUndo( SwUndoId::HEADER_FOOTER
); // #i7983#
2221 void SwWrtShell::SetShowHeaderFooterSeparator( FrameControlType eControl
, bool bShow
)
2223 SwViewShell::SetShowHeaderFooterSeparator( eControl
, bShow
);
2225 GetView().GetEditWin().GetFrameControlsManager().HideControls( eControl
);
2228 void SwWrtShell::InsertPostIt(SwFieldMgr
& rFieldMgr
, const SfxRequest
& rReq
)
2230 SwPostItField
* pPostIt
= dynamic_cast<SwPostItField
*>(rFieldMgr
.GetCurField());
2231 bool bNew
= !(pPostIt
&& pPostIt
->GetTyp()->Which() == SwFieldIds::Postit
);
2232 if (bNew
|| GetView().GetPostItMgr()->IsAnswer())
2234 const SvxPostItAuthorItem
* pAuthorItem
= rReq
.GetArg
<SvxPostItAuthorItem
>(SID_ATTR_POSTIT_AUTHOR
);
2237 sAuthor
= pAuthorItem
->GetValue();
2240 std::size_t nAuthor
= SW_MOD()->GetRedlineAuthor();
2241 sAuthor
= SW_MOD()->GetRedlineAuthor(nAuthor
);
2244 const SvxPostItTextItem
* pTextItem
= rReq
.GetArg
<SvxPostItTextItem
>(SID_ATTR_POSTIT_TEXT
);
2247 sText
= pTextItem
->GetValue();
2249 // If we have a text already registered for answer, use that
2250 if (GetView().GetPostItMgr()->IsAnswer() && !GetView().GetPostItMgr()->GetAnswerText().isEmpty())
2252 sText
= GetView().GetPostItMgr()->GetAnswerText();
2253 GetView().GetPostItMgr()->RegisterAnswerText(OUString());
2256 if ( HasSelection() && !IsTableMode() )
2261 // #i120513# Inserting a comment into an autocompletion crashes
2262 // --> suggestion has to be removed before
2263 GetView().GetEditWin().StopQuickHelp();
2265 SwInsertField_Data
aData(SwFieldTypesEnum::Postit
, 0, sAuthor
, sText
, 0);
2267 if (IsSelFrameMode())
2269 SwFlyFrame
* pFly
= GetSelectedFlyFrame();
2271 // Remember the anchor of the selected object before deletion.
2272 std::optional
<SwPosition
> oAnchor
;
2275 SwFrameFormat
* pFormat
= pFly
->GetFormat();
2278 RndStdIds eAnchorId
= pFormat
->GetAnchor().GetAnchorId();
2279 if ((eAnchorId
== RndStdIds::FLY_AS_CHAR
|| eAnchorId
== RndStdIds::FLY_AT_CHAR
) && pFormat
->GetAnchor().GetAnchorNode())
2281 oAnchor
.emplace(*pFormat
->GetAnchor().GetContentAnchor());
2286 // A frame is selected, end frame selection.
2288 GetView().AttrChangedNotify(nullptr);
2290 // Set up text selection, so the anchor of the frame will be the anchor of the
2295 *GetCurrentShellCursor().GetPoint() = *oAnchor
;
2296 SwFrameFormat
* pFormat
= pFly
->GetFormat();
2297 if (pFormat
&& pFormat
->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR
)
2299 Right(SwCursorSkipMode::Cells
, /*bSelect=*/true, 1, /*bBasicCall=*/false, /*bVisual=*/true);
2301 else if (pFormat
&& pFormat
->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR
)
2303 aData
.m_oAnnotationRange
.emplace(*GetCurrentShellCursor().Start(),
2304 *GetCurrentShellCursor().End());
2309 rFieldMgr
.InsertField( aData
);
2312 SwCursorShell::Left(1, SwCursorSkipMode::Chars
);
2313 pPostIt
= static_cast<SwPostItField
*>(rFieldMgr
.GetCurField());
2314 Pop(SwCursorShell::PopMode::DeleteCurrent
); // Restore cursor position
2317 // Client has disabled annotations rendering, no need to
2318 // focus the postit field
2319 if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
2324 SwFieldType
* pType
= GetDoc()->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Postit
, OUString(), false);
2325 if(auto pFormat
= pType
->FindFormatForField(pPostIt
))
2326 pFormat
->Broadcast( SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::FOCUS
, &GetView() ) );
2330 bool SwWrtShell::IsOutlineContentVisible(const size_t nPos
)
2332 const SwOutlineNodes
& rOutlineNodes
= GetDoc()->GetNodes().GetOutLineNds();
2333 const SwNode
* pOutlineNode
= rOutlineNodes
[nPos
];
2335 // no layout frame means outline folding is set to include sub levels and the outline node has
2336 // a parent outline node with outline content visible attribute false (folded outline content)
2337 if (!pOutlineNode
->GetTextNode()->getLayoutFrame(nullptr))
2340 // try the next node to determine if this outline node has visible content
2341 SwNodeIndex
aIdx(*pOutlineNode
, +1);
2342 if (aIdx
.GetNode() == aIdx
.GetNodes().GetEndOfContent()) // end of regular content
2345 if (aIdx
.GetNode().IsTextNode() || aIdx
.GetNode().IsTableNode() ||
2346 aIdx
.GetNode().IsSectionNode())
2348 // * sublevels treated as outline content
2349 // If next node (aIdx) doesn't have a layout frame
2350 // then this outline node does not have visible outline content.
2351 // * sublevels NOT treated as outline content
2352 // If the next node (aIdx) is the next outline node
2353 // then return the outline content visible attribute value.
2354 if (!GetViewOptions()->IsTreatSubOutlineLevelsAsContent() &&
2355 nPos
+ 1 < rOutlineNodes
.size() &&
2356 rOutlineNodes
[nPos
+ 1] == &aIdx
.GetNode())
2357 return GetAttrOutlineContentVisible(nPos
);
2359 if (aIdx
.GetNode().IsTextNode())
2360 return aIdx
.GetNode().GetTextNode()->getLayoutFrame(nullptr);
2361 if (aIdx
.GetNode().IsTableNode())
2363 SwTable
& rTable
= aIdx
.GetNode().GetTableNode()->GetTable();
2364 return rTable
.HasLayout();
2366 if (aIdx
.GetNode().IsSectionNode())
2368 const auto pFormat
= aIdx
.GetNode().GetSectionNode()->GetSection().GetFormat();
2369 return pFormat
&& pFormat
->IsVisible();
2376 void SwWrtShell::MakeOutlineLevelsVisible(const int nLevel
)
2378 MakeAllOutlineContentTemporarilyVisible
a(GetDoc());
2380 m_rView
.SetMaxOutlineLevelShown(nLevel
);
2382 bool bDocChanged
= false;
2384 const SwOutlineNodes
& rOutlineNodes
= GetNodes().GetOutLineNds();
2386 // Make all missing frames.
2387 for (SwOutlineNodes::size_type nPos
= 0; nPos
< rOutlineNodes
.size(); ++nPos
)
2389 SwNode
* pNode
= rOutlineNodes
[nPos
];
2390 if (!pNode
->GetTextNode()->getLayoutFrame(GetLayout()))
2392 SwNodeIndex
aIdx(*pNode
, +1);
2393 // Make the outline paragraph frame
2394 MakeFrames(GetDoc(), *pNode
, aIdx
.GetNode());
2395 // Make the outline content visible but don't set the outline visible attribute and
2396 // don't make outline content made visible not visible that have outline visible
2397 // attribute false. Visibility will be taken care of when
2398 // MakeAllOutlineContentTemporarilyVisible goes out of scope.
2399 MakeOutlineContentVisible(nPos
, true, false);
2403 // Remove outline paragraph frame and outline content frames above given level.
2404 for (SwOutlineNodes::size_type nPos
= 0; nPos
< rOutlineNodes
.size(); ++nPos
)
2406 SwNode
* pNode
= rOutlineNodes
[nPos
];
2407 auto nOutlineLevel
= pNode
->GetTextNode()->GetAttrOutlineLevel();
2408 if (nOutlineLevel
> nLevel
)
2410 // Remove the outline content but don't set the outline visible attribute. Visibility
2411 // will be taken care of when MakeAllOutlineContentTemporarilyVisible goes out of scope.
2412 MakeOutlineContentVisible(nPos
, false, false);
2413 // Remove the outline paragraph frame.
2414 pNode
->GetTextNode()->DelFrames(GetLayout());
2419 // Broadcast DocChanged if document layout has changed so the Navigator will be updated.
2421 GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged
));
2424 void SwWrtShell::MakeOutlineContentVisible(const size_t nPos
, bool bMakeVisible
, bool bSetAttrOutlineVisibility
)
2426 const SwNodes
& rNodes
= GetNodes();
2427 const SwOutlineNodes
& rOutlineNodes
= rNodes
.GetOutLineNds();
2429 SwNode
* pSttNd
= rOutlineNodes
[nPos
];
2431 // determine end node
2432 SwNode
* pEndNd
= &rNodes
.GetEndOfContent();
2433 if (rOutlineNodes
.size() > nPos
+ 1)
2434 pEndNd
= rOutlineNodes
[nPos
+ 1];
2436 if (GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
2438 // get the last outline node to include (iPos)
2439 int nLevel
= pSttNd
->GetTextNode()->GetAttrOutlineLevel();
2440 int nMaxOutlineLevelShown
= m_rView
.GetMaxOutlineLevelShown();
2441 SwOutlineNodes::size_type iPos
= nPos
;
2442 while (++iPos
< rOutlineNodes
.size() &&
2443 rOutlineNodes
[iPos
]->GetTextNode()->GetAttrOutlineLevel() > nLevel
&&
2444 rOutlineNodes
[iPos
]->GetTextNode()->GetAttrOutlineLevel() <= nMaxOutlineLevelShown
);
2446 // get the correct end node
2447 // the outline node may be in frames, headers, footers special section of doc model
2448 SwNode
* pStartOfSectionNodeSttNd
= pSttNd
->StartOfSectionNode();
2449 while (pStartOfSectionNodeSttNd
->StartOfSectionNode()
2450 != pStartOfSectionNodeSttNd
->StartOfSectionNode()->StartOfSectionNode())
2452 pStartOfSectionNodeSttNd
= pStartOfSectionNodeSttNd
->StartOfSectionNode();
2454 pEndNd
= pStartOfSectionNodeSttNd
->EndOfSectionNode();
2456 if (iPos
< rOutlineNodes
.size())
2458 SwNode
* pStartOfSectionNode
= rOutlineNodes
[iPos
]->StartOfSectionNode();
2459 while (pStartOfSectionNode
->StartOfSectionNode()
2460 != pStartOfSectionNode
->StartOfSectionNode()->StartOfSectionNode())
2462 pStartOfSectionNode
= pStartOfSectionNode
->StartOfSectionNode();
2464 if (pStartOfSectionNodeSttNd
== pStartOfSectionNode
)
2465 pEndNd
= rOutlineNodes
[iPos
];
2469 // table, text box, header, footer
2470 if (pSttNd
->GetTableBox() || pSttNd
->GetIndex() < rNodes
.GetEndOfExtras().GetIndex())
2472 // limit to within section
2473 if (pSttNd
->EndOfSectionIndex() < pEndNd
->GetIndex())
2474 pEndNd
= pSttNd
->EndOfSectionNode();
2476 // if pSttNd isn't in table but pEndNd is, skip over all outline nodes in table
2477 else if (pEndNd
->GetTableBox())
2479 pEndNd
= &rNodes
.GetEndOfContent();
2480 for (size_t nOutlinePos
= nPos
+ 2; nOutlinePos
< rOutlineNodes
.size(); nOutlinePos
++)
2482 if (!(rOutlineNodes
[nOutlinePos
]->GetTableBox()))
2484 pEndNd
= rOutlineNodes
[nOutlinePos
];
2489 // end node determined
2491 // Remove content frames from the next node after the starting outline node to
2492 // the determined ending node. Always do this to prevent the chance of duplicate
2493 // frames being made. They will be remade below if needed.
2494 SwNodeIndex
aIdx(*pSttNd
, +1);
2495 while (aIdx
!= *pEndNd
)
2497 SwNode
* pNd
= &aIdx
.GetNode();
2498 if (pNd
->IsContentNode())
2499 pNd
->GetContentNode()->DelFrames(nullptr);
2500 else if (pNd
->IsTableNode())
2501 pNd
->GetTableNode()->DelFrames(nullptr);
2505 if (bMakeVisible
) // make outline nodes outline content visible
2507 // reset the index marker and make frames
2508 aIdx
.Assign(*pSttNd
, +1);
2509 MakeFrames(GetDoc(), aIdx
.GetNode(), *pEndNd
);
2511 if (bSetAttrOutlineVisibility
)
2513 pSttNd
->GetTextNode()->SetAttrOutlineContentVisible(true);
2515 // make outline content made visible that have outline visible attribute false not visible
2516 while (aIdx
!= *pEndNd
)
2518 SwNode
* pNd
= &aIdx
.GetNode();
2519 if (pNd
->IsTextNode() && pNd
->GetTextNode()->IsOutline())
2521 SwTextNode
* pTextNd
= pNd
->GetTextNode();
2522 bool bOutlineContentVisibleAttr
= true;
2523 pTextNd
->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr
);
2524 if (!bOutlineContentVisibleAttr
)
2526 SwOutlineNodes::size_type iPos
;
2527 if (rOutlineNodes
.Seek_Entry(pTextNd
, &iPos
))
2529 if (pTextNd
->getLayoutFrame(nullptr))
2530 MakeOutlineContentVisible(iPos
, false);
2538 else if (bSetAttrOutlineVisibility
)
2539 pSttNd
->GetTextNode()->SetAttrOutlineContentVisible(false);
2542 // make content visible or not visible only if needed
2543 void SwWrtShell::InvalidateOutlineContentVisibility()
2545 GetView().GetEditWin().GetFrameControlsManager().HideControls(FrameControlType::Outline
);
2547 const SwOutlineNodes
& rOutlineNds
= GetNodes().GetOutLineNds();
2548 for (SwOutlineNodes::size_type nPos
= 0; nPos
< rOutlineNds
.size(); ++nPos
)
2550 bool bIsOutlineContentVisible
= IsOutlineContentVisible(nPos
);
2551 bool bOutlineContentVisibleAttr
= true;
2552 rOutlineNds
[nPos
]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr
);
2553 if (!bIsOutlineContentVisible
&& bOutlineContentVisibleAttr
)
2554 MakeOutlineContentVisible(nPos
);
2555 else if (bIsOutlineContentVisible
&& !bOutlineContentVisibleAttr
)
2556 MakeOutlineContentVisible(nPos
, false);
2560 void SwWrtShell::MakeAllFoldedOutlineContentVisible(bool bMakeVisible
)
2564 // make all content visible
2566 // When shortcut is assigned to the show outline content visibility button and used to
2567 // toggle the feature and the mouse pointer is on an outline frame the button will not
2568 // be removed. An easy way to make sure the button does not remain shown is to use the
2569 // HideControls function.
2570 GetView().GetEditWin().GetFrameControlsManager().HideControls(FrameControlType::Outline
);
2572 // temporarily set outline content visible attribute true for folded outline nodes
2573 std::vector
<SwNode
*> aFoldedOutlineNodeArray
;
2574 for (SwNode
* pNd
: GetNodes().GetOutLineNds())
2576 bool bOutlineContentVisibleAttr
= true;
2577 pNd
->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr
);
2578 if (!bOutlineContentVisibleAttr
)
2580 aFoldedOutlineNodeArray
.push_back(pNd
);
2581 pNd
->GetTextNode()->SetAttrOutlineContentVisible(true);
2586 InvalidateOutlineContentVisibility();
2589 // restore outline content visible attribute for folded outline nodes
2590 for (SwNode
* pNd
: aFoldedOutlineNodeArray
)
2591 pNd
->GetTextNode()->SetAttrOutlineContentVisible(false);
2595 if (SdrView
* pSdrView
= GetDrawView(); pSdrView
&& pSdrView
->IsTextEdit() )
2597 bool bLockView
= IsViewLocked();
2600 LockView(bLockView
);
2602 if (IsSelFrameMode() || IsObjSelected())
2605 LeaveSelFrameMode();
2606 GetView().LeaveDrawCreate();
2610 // Get current frame in which the cursor is positioned for use in placing the cursor.
2611 const SwFrame
* pCurrFrame
= GetCurrFrame(false);
2613 SwOutlineNodes::size_type nPos
= GetOutlinePos();
2616 InvalidateOutlineContentVisibility();
2619 // If needed, find visible outline node frame to place cursor.
2620 if (!pCurrFrame
|| !pCurrFrame
->isFrameAreaDefinitionValid() || pCurrFrame
->IsInDtor() ||
2621 (nPos
!= SwOutlineNodes::npos
&&
2622 !GetNodes().GetOutLineNds()[nPos
]->GetTextNode()->getLayoutFrame(nullptr)))
2624 while (nPos
!= SwOutlineNodes::npos
&&
2625 !GetNodes().GetOutLineNds()[nPos
]->GetTextNode()->getLayoutFrame(nullptr))
2627 if (nPos
!= SwOutlineNodes::npos
)
2634 GetView().GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged
));
2637 bool SwWrtShell::GetAttrOutlineContentVisible(const size_t nPos
) const
2639 bool bVisibleAttr
= true;
2640 GetNodes().GetOutLineNds()[nPos
]->GetTextNode()->GetAttrOutlineContentVisible(bVisibleAttr
);
2641 return bVisibleAttr
;
2644 bool SwWrtShell::HasFoldedOutlineContentSelected() const
2646 for(const SwPaM
& rPaM
: GetCursor()->GetRingContainer())
2648 SwPaM
aPaM(*rPaM
.GetMark(), *rPaM
.GetPoint());
2650 SwNodeIndex
aPointIdx(aPaM
.GetPoint()->GetNode());
2651 SwNodeIndex
aMarkIdx(aPaM
.GetMark()->GetNode());
2652 if (aPointIdx
== aMarkIdx
)
2654 // Return true if any nodes in PaM are folded outline content nodes.
2655 SwOutlineNodes::size_type nPos
;
2656 for (SwNodeIndex aIdx
= aPointIdx
; aIdx
<= aMarkIdx
; ++aIdx
)
2658 if (GetDoc()->GetNodes().GetOutLineNds().Seek_Entry(&(aIdx
.GetNode()), &nPos
) &&
2659 !GetAttrOutlineContentVisible(nPos
))
2666 void SwWrtShell::InfoReadOnlyDialog(bool bAsync
) const
2670 auto xInfo
= std::make_shared
<weld::MessageDialogController
>(
2671 GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog");
2672 if (GetViewOptions()->IsShowOutlineContentVisibilityButton() &&
2673 HasFoldedOutlineContentSelected())
2675 xInfo
->set_primary_text(SwResId(STR_INFORODLG_FOLDED_PRIMARY
));
2676 xInfo
->set_secondary_text(SwResId(STR_INFORODLG_FOLDED_SECONDARY
));
2678 weld::DialogController::runAsync(xInfo
, [](int) {});
2682 std::unique_ptr
<weld::Builder
>
2683 xBuilder(Application::CreateBuilder(GetView().GetFrameWeld(),
2684 "modules/swriter/ui/inforeadonlydialog.ui"));
2685 std::unique_ptr
<weld::MessageDialog
>
2686 xInfo(xBuilder
->weld_message_dialog("InfoReadonlyDialog"));
2687 if (GetViewOptions()->IsShowOutlineContentVisibilityButton() &&
2688 HasFoldedOutlineContentSelected())
2690 xInfo
->set_primary_text(SwResId(STR_INFORODLG_FOLDED_PRIMARY
));
2691 xInfo
->set_secondary_text(SwResId(STR_INFORODLG_FOLDED_SECONDARY
));
2697 bool SwWrtShell::WarnHiddenSectionDialog() const
2699 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(
2700 GetView().GetFrameWeld(), "modules/swriter/ui/warnhiddensectiondialog.ui"));
2701 std::unique_ptr
<weld::MessageDialog
> xQuery(
2702 xBuilder
->weld_message_dialog("WarnHiddenSectionDialog"));
2703 if (GetViewOptions()->IsShowOutlineContentVisibilityButton()
2704 && HasFoldedOutlineContentSelected())
2706 xQuery
->set_primary_text(SwResId(STR_INFORODLG_FOLDED_PRIMARY
));
2707 xQuery
->set_secondary_text(SwResId(STR_INFORODLG_FOLDED_SECONDARY
));
2710 return (RET_YES
== xQuery
->run());
2713 bool SwWrtShell::WarnSwitchToDesignModeDialog() const
2715 std::unique_ptr
<weld::MessageDialog
> xQuery(Application::CreateMessageDialog(nullptr,
2716 VclMessageType::Question
, VclButtonsType::YesNo
, SwResId(STR_A11Y_DESIGN_MODE_PRIMARY
)));
2717 xQuery
->set_default_response(RET_YES
);
2718 xQuery
->set_title(SwResId(STR_A11Y_DESIGN_MODE_TITLE
));
2719 xQuery
->set_secondary_text(SwResId(STR_A11Y_DESIGN_MODE_SECONDARY
));
2721 return (RET_YES
== xQuery
->run());
2724 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */