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 <hintids.hxx>
21 #include <vcl/commandevent.hxx>
22 #include <unotools/charclass.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <comphelper/string.hxx>
25 #include <unotools/transliterationwrapper.hxx>
26 #include <fmtsrnd.hxx>
27 #include <fmtinfmt.hxx>
28 #include <txtinet.hxx>
30 #include <charfmt.hxx>
32 #include <IDocumentUndoRedo.hxx>
33 #include <IDocumentSettingAccess.hxx>
34 #include <IDocumentLinksAdministration.hxx>
35 #include <IDocumentFieldsAccess.hxx>
36 #include <IDocumentStatistics.hxx>
37 #include <IDocumentState.hxx>
50 #include <rootfrm.hxx>
51 #include <extinput.hxx>
52 #include <scriptinfo.hxx>
53 #include <unocrsrhelper.hxx>
54 #include <section.hxx>
55 #include <numrule.hxx>
56 #include <SwNodeNum.hxx>
57 #include <unocrsr.hxx>
60 using namespace com::sun::star
;
62 void SwEditShell::Insert( sal_Unicode c
, bool bOnlyCurrCursor
)
65 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
67 const bool bSuccess
= GetDoc()->getIDocumentContentOperations().InsertString(rPaM
, OUString(c
));
68 OSL_ENSURE( bSuccess
, "Doc->Insert() failed." );
70 SaveTableBoxContent( rPaM
.GetPoint() );
79 void SwEditShell::Insert2(const OUString
&rStr
, const bool bForceExpandHints
)
83 const SwInsertFlags nInsertFlags
=
85 ? (SwInsertFlags::FORCEHINTEXPAND
| SwInsertFlags::EMPTYEXPAND
)
86 : SwInsertFlags::EMPTYEXPAND
;
88 for(SwPaM
& rCurrentCursor
: getShellCursor( true )->GetRingContainer())
90 //OPT: GetSystemCharSet
92 GetDoc()->getIDocumentContentOperations().InsertString(rCurrentCursor
, rStr
, nInsertFlags
);
93 OSL_ENSURE( bSuccess
, "Doc->Insert() failed." );
97 GetDoc()->UpdateRsid( rCurrentCursor
, rStr
.getLength() );
99 // Set paragraph rsid if beginning of paragraph
100 SwTextNode
*const pTextNode
=
101 rCurrentCursor
.GetPoint()->nNode
.GetNode().GetTextNode();
102 if( pTextNode
&& pTextNode
->Len() == 1)
103 GetDoc()->UpdateParRsid( pTextNode
);
106 SaveTableBoxContent( rCurrentCursor
.GetPoint() );
111 // calculate cursor bidi level
112 SwCursor
* pTmpCursor
= GetCursor_();
113 const bool bDoNotSetBidiLevel
= ! pTmpCursor
||
114 ( dynamic_cast<SwUnoCursor
*>(pTmpCursor
) != nullptr );
116 if ( ! bDoNotSetBidiLevel
)
118 SwNode
& rNode
= pTmpCursor
->GetPoint()->nNode
.GetNode();
119 if ( rNode
.IsTextNode() )
121 SwIndex
& rIdx
= pTmpCursor
->GetPoint()->nContent
;
122 sal_Int32 nPrevPos
= rIdx
.GetIndex();
126 SwTextFrame
const* pFrame
;
127 SwScriptInfo
*const pSI
= SwScriptInfo::GetScriptInfo(
128 static_cast<SwTextNode
&>(rNode
), &pFrame
, true);
130 sal_uInt8 nLevel
= 0;
133 // seems to be an empty paragraph.
135 std::pair
<Point
, bool> const tmp(aPt
, false);
136 pFrame
= static_cast<SwTextFrame
*>(
137 static_cast<SwTextNode
&>(rNode
).getLayoutFrame(
138 GetLayout(), pTmpCursor
->GetPoint(), &tmp
));
140 SwScriptInfo aScriptInfo
;
141 aScriptInfo
.InitScriptInfo(static_cast<SwTextNode
&>(rNode
),
142 pFrame
->GetMergedPara(), pFrame
->IsRightToLeft());
143 TextFrameIndex
const iPrevPos(pFrame
->MapModelToView(
144 &static_cast<SwTextNode
&>(rNode
), nPrevPos
));
145 nLevel
= aScriptInfo
.DirType( iPrevPos
);
149 if (TextFrameIndex(COMPLETE_STRING
) != pSI
->GetInvalidityA())
151 // mystery why this doesn't use the other overload?
152 pSI
->InitScriptInfo(static_cast<SwTextNode
&>(rNode
), pFrame
->GetMergedPara());
154 TextFrameIndex
const iPrevPos(pFrame
->MapModelToView(
155 &static_cast<SwTextNode
&>(rNode
), nPrevPos
));
156 nLevel
= pSI
->DirType(iPrevPos
);
159 pTmpCursor
->SetCursorBidiLevel( nLevel
);
163 SetInFrontOfLabel( false ); // #i27615#
168 void SwEditShell::Overwrite(const OUString
&rStr
)
171 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
173 if( !GetDoc()->getIDocumentContentOperations().Overwrite(rPaM
, rStr
) )
175 OSL_FAIL( "Doc->getIDocumentContentOperations().Overwrite(Str) failed." );
177 SaveTableBoxContent( rPaM
.GetPoint() );
182 void SwEditShell::SplitNode( bool bAutoFormat
, bool bCheckTableStart
)
185 GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY
, nullptr);
187 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
189 // Here, a table cell becomes a normal text cell.
190 GetDoc()->ClearBoxNumAttrs( rPaM
.GetPoint()->nNode
);
191 GetDoc()->getIDocumentContentOperations().SplitNode( *rPaM
.GetPoint(), bCheckTableStart
);
194 GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY
, nullptr);
197 AutoFormatBySplitNode();
199 ClearTableBoxContent();
204 bool SwEditShell::AppendTextNode()
208 GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY
, nullptr);
210 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
212 GetDoc()->ClearBoxNumAttrs( rPaM
.GetPoint()->nNode
);
213 bRet
= GetDoc()->getIDocumentContentOperations().AppendTextNode( *rPaM
.GetPoint()) || bRet
;
216 GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY
, nullptr);
218 ClearTableBoxContent();
224 // the returned SwGrfNode pointer is used in GetGraphic() and GetGraphicSize()
225 SwGrfNode
* SwEditShell::GetGrfNode_() const
227 SwGrfNode
*pGrfNode
= nullptr;
228 SwPaM
* pCursor
= GetCursor();
229 if( !pCursor
->HasMark() ||
230 pCursor
->GetPoint()->nNode
== pCursor
->GetMark()->nNode
)
231 pGrfNode
= pCursor
->GetPoint()->nNode
.GetNode().GetGrfNode();
236 // returns a Graphic pointer if CurrentCursor->GetPoint() points to a SwGrfNode and
237 // GetMark is not set or points to the same Graphic
238 const Graphic
* SwEditShell::GetGraphic( bool bWait
) const
240 SwGrfNode
* pGrfNode
= GetGrfNode_();
241 const Graphic
* pGrf( nullptr );
244 pGrf
= &(pGrfNode
->GetGrf(bWait
&& GraphicType::Default
== pGrfNode
->GetGrf().GetType()));
249 bool SwEditShell::IsLinkedGrfSwapOut() const
251 SwGrfNode
*pGrfNode
= GetGrfNode_();
253 pGrfNode
->IsLinkedFile() &&
254 GraphicType::Default
== pGrfNode
->GetGrfObj().GetType();
257 const GraphicObject
* SwEditShell::GetGraphicObj() const
259 SwGrfNode
* pGrfNode
= GetGrfNode_();
260 return pGrfNode
? &(pGrfNode
->GetGrfObj()) : nullptr;
263 const GraphicAttr
* SwEditShell::GetGraphicAttr( GraphicAttr
& rGA
) const
265 SwGrfNode
* pGrfNode
= GetGrfNode_();
266 const SwFrame
* pFrame
= GetCurrFrame(false);
267 return pGrfNode
? &(pGrfNode
->GetGraphicAttr( rGA
, pFrame
)) : nullptr;
270 GraphicType
SwEditShell::GetGraphicType() const
272 SwGrfNode
*pGrfNode
= GetGrfNode_();
273 return pGrfNode
? pGrfNode
->GetGrfObj().GetType() : GraphicType::NONE
;
276 // returns the size of a graphic in <rSz> if CurrentCursor->GetPoint() points to a SwGrfNode and
277 // GetMark is not set or points to the same graphic
278 bool SwEditShell::GetGrfSize(Size
& rSz
) const
280 SwNoTextNode
* pNoTextNd
;
281 SwPaM
* pCurrentCursor
= GetCursor();
282 if( ( !pCurrentCursor
->HasMark()
283 || pCurrentCursor
->GetPoint()->nNode
== pCurrentCursor
->GetMark()->nNode
)
284 && nullptr != ( pNoTextNd
= pCurrentCursor
->GetNode().GetNoTextNode() ) )
286 rSz
= pNoTextNd
->GetTwipSize();
293 /// Read again if graphic is not OK and replace old one
294 void SwEditShell::ReRead( const OUString
& rGrfName
, const OUString
& rFltName
,
295 const Graphic
* pGraphic
)
298 mxDoc
->getIDocumentContentOperations().ReRead( *GetCursor(), rGrfName
, rFltName
, pGraphic
);
302 /// Returns the name and the filter name of a graphic if the pointer is on a graphic.
303 /// If a String-pointer is != 0 then return corresponding name.
304 void SwEditShell::GetGrfNms( OUString
* pGrfName
, OUString
* pFltName
,
305 const SwFlyFrameFormat
* pFormat
) const
307 OSL_ENSURE( pGrfName
|| pFltName
, "No parameters" );
309 SwDoc::GetGrfNms( *pFormat
, pGrfName
, pFltName
);
312 SwGrfNode
*pGrfNode
= GetGrfNode_();
313 if( pGrfNode
&& pGrfNode
->IsLinkedFile() )
314 pGrfNode
->GetFileFilterNms( pGrfName
, pFltName
);
318 const tools::PolyPolygon
*SwEditShell::GetGraphicPolygon() const
320 SwNoTextNode
*pNd
= GetCursor()->GetNode().GetNoTextNode();
321 return pNd
->HasContour();
324 void SwEditShell::SetGraphicPolygon( const tools::PolyPolygon
*pPoly
)
326 SwNoTextNode
*pNd
= GetCursor()->GetNode().GetNoTextNode();
328 pNd
->SetContour( pPoly
);
329 SwFlyFrame
*pFly
= static_cast<SwFlyFrame
*>(pNd
->getLayoutFrame(GetLayout())->GetUpper());
330 const SwFormatSurround
&rSur
= pFly
->GetFormat()->GetSurround();
331 pFly
->GetFormat()->NotifyClients( &rSur
, &rSur
);
332 GetDoc()->getIDocumentState().SetModified();
336 void SwEditShell::ClearAutomaticContour()
338 SwNoTextNode
*pNd
= GetCursor()->GetNode().GetNoTextNode();
339 OSL_ENSURE( pNd
, "is no NoTextNode!" );
340 if( pNd
->HasAutomaticContour() )
343 pNd
->SetContour( nullptr );
344 SwFlyFrame
*pFly
= static_cast<SwFlyFrame
*>(pNd
->getLayoutFrame(GetLayout())->GetUpper());
345 const SwFormatSurround
&rSur
= pFly
->GetFormat()->GetSurround();
346 pFly
->GetFormat()->NotifyClients( &rSur
, &rSur
);
347 GetDoc()->getIDocumentState().SetModified();
352 /** Get OLE object at pointer.
354 * Returns a pointer to a SvInPlaceObjectRef if CurrentCursor->GetPoint() points to a SwOLENode and
355 * GetMark is not set or points to the same object reference. Gets this pointer from the Doc
356 * if the object should be searched by name.
358 svt::EmbeddedObjectRef
& SwEditShell::GetOLEObject() const
360 OSL_ENSURE( CNT_OLE
== GetCntType(), "GetOLEObj: no OLENode." );
361 OSL_ENSURE( !GetCursor()->HasMark() ||
362 (GetCursor()->HasMark() &&
363 GetCursor()->GetPoint()->nNode
== GetCursor()->GetMark()->nNode
),
364 "GetOLEObj: no OLENode." );
366 SwOLENode
*pOLENode
= GetCursor()->GetNode().GetOLENode();
367 OSL_ENSURE( pOLENode
, "GetOLEObj: no OLENode." );
368 SwOLEObj
& rOObj
= pOLENode
->GetOLEObj();
369 return rOObj
.GetObject();
372 bool SwEditShell::HasOLEObj( const OUString
&rName
) const
375 SwNodeIndex
aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
376 while ( nullptr != (pStNd
= aIdx
.GetNode().GetStartNode()) )
379 SwNode
& rNd
= aIdx
.GetNode();
380 if( rNd
.IsOLENode() &&
381 rName
== static_cast<SwOLENode
&>(rNd
).GetChartTableName() &&
382 static_cast<SwOLENode
&>(rNd
).getLayoutFrame( GetLayout() ) )
385 aIdx
.Assign( *pStNd
->EndOfSectionNode(), + 1 );
390 void SwEditShell::SetChartName( const OUString
&rName
)
392 SwOLENode
*pONd
= GetCursor()->GetNode().GetOLENode();
393 OSL_ENSURE( pONd
, "ChartNode not found" );
394 pONd
->SetChartTableName( rName
);
397 void SwEditShell::UpdateCharts( const OUString
&rName
)
399 GetDoc()->UpdateCharts( rName
);
402 /// change table name
403 void SwEditShell::SetTableName( SwFrameFormat
& rTableFormat
, const OUString
&rNewName
)
405 GetDoc()->SetTableName( rTableFormat
, rNewName
);
408 /// request current word
409 OUString
SwEditShell::GetCurWord() const
411 const SwPaM
& rPaM
= *GetCursor();
412 const SwTextNode
* pNd
= rPaM
.GetNode().GetTextNode();
417 SwTextFrame
const*const pFrame(static_cast<SwTextFrame
*>(pNd
->getLayoutFrame(GetLayout())));
420 return pFrame
->GetCurWord(*rPaM
.GetPoint());
425 void SwEditShell::UpdateDocStat( )
428 GetDoc()->getIDocumentStatistics().UpdateDocStat( false, true );
432 const SwDocStat
& SwEditShell::GetUpdatedDocStat()
435 const SwDocStat
&rRet
= GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true );
440 /// get the reference of a given name in the Doc
441 const SwFormatRefMark
* SwEditShell::GetRefMark( const OUString
& rName
) const
443 return GetDoc()->GetRefMark( rName
);
446 /// get the names of all references in a Doc
447 sal_uInt16
SwEditShell::GetRefMarks( std::vector
<OUString
>* pStrings
) const
449 return GetDoc()->GetRefMarks( pStrings
);
452 OUString
SwEditShell::GetDropText( const sal_Int32 nChars
) const
455 * pb: made changes for #i74939#
457 * always return a string even though there is a selection
461 SwPaM
* pCursor
= GetCursor();
462 if ( IsMultiSelection() )
464 // if a multi selection exists, search for the first line
465 // -> it is the cursor with the lowest index
466 sal_uLong nIndex
= pCursor
->GetMark()->nNode
.GetIndex();
468 SwPaM
* pLast
= pCursor
;
469 SwPaM
* pTemp
= pCursor
;
472 SwPaM
* pPrev2
= pTemp
->GetPrev();
473 bPrev
= ( pPrev2
&& pPrev2
!= pLast
);
477 sal_uLong nTemp
= pPrev2
->GetMark()->nNode
.GetIndex();
478 if ( nTemp
< nIndex
)
487 SwTextNode
const*const pTextNd
= pCursor
->GetNode(false).GetTextNode();
490 SwTextFrame
const*const pTextFrame(static_cast<SwTextFrame
const*>(
491 pTextNd
->getLayoutFrame(GetLayout())));
492 SAL_WARN_IF(!pTextFrame
, "sw.core", "GetDropText cursor has no frame?");
495 TextFrameIndex
const nDropLen(pTextFrame
->GetDropLen(TextFrameIndex(nChars
)));
496 aText
= pTextFrame
->GetText().copy(0, sal_Int32(nDropLen
));
503 void SwEditShell::ReplaceDropText( const OUString
&rStr
, SwPaM
* pPaM
)
505 SwPaM
* pCursor
= pPaM
? pPaM
: GetCursor();
506 if( !(pCursor
->GetPoint()->nNode
== pCursor
->GetMark()->nNode
&&
507 pCursor
->GetNode().GetTextNode()->IsTextNode()) )
512 const SwNodeIndex
& rNd
= pCursor
->GetPoint()->nNode
;
513 SwPaM
aPam( rNd
, rStr
.getLength(), rNd
, 0 );
514 SwTextFrame
const*const pTextFrame(static_cast<SwTextFrame
const*>(
515 rNd
.GetNode().GetTextNode()->getLayoutFrame(GetLayout())));
518 *aPam
.GetPoint() = pTextFrame
->MapViewToModelPos(TextFrameIndex(0));
519 *aPam
.GetMark() = pTextFrame
->MapViewToModelPos(TextFrameIndex(
520 std::min(rStr
.getLength(), pTextFrame
->GetText().getLength())));
522 if( !GetDoc()->getIDocumentContentOperations().Overwrite( aPam
, rStr
) )
524 OSL_FAIL( "Doc->getIDocumentContentOperations().Overwrite(Str) failed." );
530 OUString
SwEditShell::Calculate()
532 OUStringBuffer aFormel
; // the final formula
533 SwCalc
aCalc( *GetDoc() );
534 const CharClass
& rCC
= GetAppCharClass();
536 for(SwPaM
& rCurrentPaM
: GetCursor()->GetNext()->GetRingContainer())
538 SwTextNode
* pTextNd
= rCurrentPaM
.GetNode().GetTextNode();
541 const SwPosition
*pStart
= rCurrentPaM
.Start(), *pEnd
= rCurrentPaM
.End();
542 const sal_Int32 nStt
= pStart
->nContent
.GetIndex();
543 OUString aStr
= pTextNd
->GetExpandText(GetLayout(),
544 nStt
, pEnd
->nContent
.GetIndex() - nStt
);
546 aStr
= rCC
.lowercase( aStr
);
548 bool bValidFields
= false;
551 while( nPos
< aStr
.getLength() )
553 sal_Unicode ch
= aStr
[ nPos
++ ];
554 if( rCC
.isLetter( aStr
, nPos
-1 ) || ch
== '_' )
556 sal_Int32 nTmpStt
= nPos
-1;
557 while( nPos
< aStr
.getLength() &&
558 0 != ( ch
= aStr
[ nPos
++ ]) &&
559 (rCC
.isLetterNumeric( aStr
, nPos
- 1 ) ||
560 ch
== '_'|| ch
== '.' ))
563 if( nPos
< aStr
.getLength() )
566 OUString sVar
= aStr
.copy( nTmpStt
, nPos
- nTmpStt
);
567 if( !::FindOperator( sVar
) &&
568 (aCalc
.GetVarTable().Find(sVar
) ||
569 aCalc
.VarLook( sVar
)) )
573 GetDoc()->getIDocumentFieldsAccess().FieldsToCalc( aCalc
,
574 pStart
->nNode
.GetIndex(),
575 pStart
->nContent
.GetIndex() );
578 aFormel
.append("(").append(aCalc
.GetStrResult( aCalc
.VarLook( sVar
)->nValue
)).append(")");
581 aFormel
.append(sVar
);
589 return aCalc
.GetStrResult( aCalc
.Calculate(aFormel
.makeStringAndClear()) );
592 sfx2::LinkManager
& SwEditShell::GetLinkManager()
594 return mxDoc
->getIDocumentLinksAdministration().GetLinkManager();
597 void *SwEditShell::GetIMapInventor() const
599 // The node on which the cursor points should be sufficient as a unique identifier
600 return static_cast<void*>(&(GetCursor()->GetNode()));
604 Graphic
SwEditShell::GetIMapGraphic() const
606 // returns always a graphic if the cursor is in a Fly
607 CurrShell
aCurr( const_cast<SwEditShell
*>(this) );
609 SwPaM
* pCursor
= GetCursor();
610 if ( !pCursor
->HasMark() )
612 SwNode
& rNd
=pCursor
->GetNode();
613 if( rNd
.IsGrfNode() )
615 SwGrfNode
& rGrfNode(static_cast<SwGrfNode
&>(rNd
));
616 aRet
= rGrfNode
.GetGrf(GraphicType::Default
== rGrfNode
.GetGrf().GetType());
618 else if ( rNd
.IsOLENode() )
620 if (const Graphic
* pGraphic
= static_cast<SwOLENode
&>(rNd
).GetGraphic())
625 SwFlyFrame
* pFlyFrame
= rNd
.GetContentNode()->getLayoutFrame( GetLayout() )->FindFlyFrame();
627 aRet
= pFlyFrame
->GetFormat()->MakeGraphic();
633 bool SwEditShell::InsertURL( const SwFormatINetFormat
& rFormat
, const OUString
& rStr
, bool bKeepSelection
)
635 // URL and hint text (directly or via selection) necessary
636 if( rFormat
.GetValue().isEmpty() || ( rStr
.isEmpty() && !HasSelection() ) )
639 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::UI_INSERT_URLTXT
, nullptr);
640 bool bInsText
= true;
642 if( !rStr
.isEmpty() )
644 SwPaM
* pCursor
= GetCursor();
645 if( pCursor
->HasMark() && *pCursor
->GetPoint() != *pCursor
->GetMark() )
647 // Selection existent, multi selection?
648 bool bDelText
= true;
649 if( !pCursor
->IsMultiSelection() )
651 // simple selection -> check the text
652 const OUString
sText(comphelper::string::stripEnd(GetSelText(), ' '));
654 bDelText
= bInsText
= false;
656 else if( rFormat
.GetValue() == rStr
) // Are Name and URL equal?
657 bDelText
= bInsText
= false;
662 else if( pCursor
->IsMultiSelection() && rFormat
.GetValue() == rStr
)
669 ExtendSelection( false, rStr
.getLength() );
675 SetAttrItem( rFormat
);
676 if (bInsText
&& !IsCursorPtAtEnd())
682 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::UI_INSERT_URLTXT
, nullptr );
687 void SwEditShell::GetINetAttrs( SwGetINetAttrs
& rArr
)
691 const SwCharFormats
* pFormats
= GetDoc()->GetCharFormats();
692 for( auto n
= pFormats
->size(); 1 < n
; )
694 SwIterator
<SwTextINetFormat
,SwCharFormat
> aIter(*(*pFormats
)[--n
]);
695 for( SwTextINetFormat
* pFnd
= aIter
.First(); pFnd
; pFnd
= aIter
.Next() )
697 SwTextNode
const*const pTextNd(pFnd
->GetpTextNode());
698 SwTextFrame
const*const pFrame(pTextNd
699 ? static_cast<SwTextFrame
const*>(pTextNd
->getLayoutFrame(GetLayout()))
701 if (nullptr != pTextNd
&& nullptr != pFrame
702 && pTextNd
->GetNodes().IsDocNodes()
703 // check it's not fully deleted
704 && pFrame
->MapModelToView(pTextNd
, pFnd
->GetStart())
705 != pFrame
->MapModelToView(pTextNd
, *pFnd
->GetEnd()))
707 SwTextINetFormat
& rAttr
= *pFnd
;
708 OUString
sText( pTextNd
->GetExpandText(GetLayout(),
709 rAttr
.GetStart(), *rAttr
.GetEnd() - rAttr
.GetStart()) );
711 sText
= sText
.replaceAll("\x0a", "");
712 sText
= comphelper::string::strip(sText
, ' ');
714 if( !sText
.isEmpty() )
716 rArr
.emplace_back(sText
, rAttr
);
723 /// If the cursor is in an INetAttribute then it will be deleted completely (incl. hint text, the
724 /// latter is needed for drag & drop)
725 void SwEditShell::DelINetAttrWithText()
727 bool bRet
= SelectTextAttr( RES_TXTATR_INETFMT
, false );
729 DeleteSel( *GetCursor() );
732 /// Set the DontExpand flag at the text character attributes
733 bool SwEditShell::DontExpandFormat()
736 if( !IsTableMode() && GetDoc()->DontExpandFormat( *GetCursor()->GetPoint() ))
744 SvNumberFormatter
* SwEditShell::GetNumberFormatter()
746 return GetDoc()->GetNumberFormatter();
749 bool SwEditShell::ConvertFieldsToText()
752 bool bRet
= GetDoc()->ConvertFieldsToText(*GetLayout());
757 void SwEditShell::SetNumberingRestart()
761 // iterate over all text contents - body, frames, header, footer, footnote text
762 SwPaM
* pCursor
= GetCursor();
763 for(int i
= 0; i
< 2; i
++)
766 MakeFindRange(SwDocPositions::Start
, SwDocPositions::End
, pCursor
); // body content
768 MakeFindRange(SwDocPositions::OtherStart
, SwDocPositions::OtherEnd
, pCursor
); // extra content
769 SwPosition
* pSttPos
= pCursor
->Start(), *pEndPos
= pCursor
->End();
770 sal_uLong nCurrNd
= pSttPos
->nNode
.GetIndex();
771 sal_uLong nEndNd
= pEndPos
->nNode
.GetIndex();
772 if( nCurrNd
<= nEndNd
)
774 SwContentFrame
* pContentFrame
;
776 // iterate over all paragraphs
779 SwNode
* pNd
= GetDoc()->GetNodes()[ nCurrNd
];
780 switch( pNd
->GetNodeType() )
782 case SwNodeType::Text
:
783 pContentFrame
= static_cast<SwTextNode
*>(pNd
)->getLayoutFrame( GetLayout() );
784 if( nullptr != pContentFrame
)
786 // skip hidden frames - ignore protection!
787 if( !static_cast<SwTextFrame
*>(pContentFrame
)->IsHiddenNow() )
789 // if the node is numbered and the starting value of the numbering equals the
790 // start value of the numbering rule then set this value as hard starting value
794 SwTextNode
* pTextNd( pNd
->GetTextNode() );
795 SwNumRule
* pNumRule( pTextNd
->GetNumRule() );
797 // sw_redlinehide: not sure what this should do, only called from mail-merge
799 ( pNumRule
&& pTextNd
->GetNum() &&
800 ( pTextNd
->HasNumber() || pTextNd
->HasBullet() ) &&
801 pTextNd
->IsCountedInList() &&
802 !pTextNd
->IsListRestart() );
805 int nListLevel
= pTextNd
->GetActualListLevel();
810 if (nListLevel
>= MAXLEVEL
)
811 nListLevel
= MAXLEVEL
- 1;
813 bIsNodeNum
= pTextNd
->GetNum()->GetNumber() ==
814 pNumRule
->Get( static_cast<sal_uInt16
>(nListLevel
) ).GetStart();
818 // now set the start value as attribute
819 SwPosition
aCurrentNode(*pNd
);
820 GetDoc()->SetNumRuleStart( aCurrentNode
);
825 case SwNodeType::Section
:
826 // skip hidden sections - ignore protection!
827 if(static_cast<SwSectionNode
*>(pNd
)->GetSection().IsHidden() )
828 nCurrNd
= pNd
->EndOfSectionIndex();
833 bGoOn
= nCurrNd
< nEndNd
;
839 Pop(PopMode::DeleteCurrent
);
843 sal_uInt16
SwEditShell::GetLineCount()
847 SwPaM
* pPam
= GetCursor();
848 SwNodeIndex
& rPtIdx
= pPam
->GetPoint()->nNode
;
849 SwNodeIndex
aStart( rPtIdx
);
851 SwContentFrame
*pContentFrame
= nullptr;
855 while( nullptr != ( pCNd
= GetDoc()->GetNodes().GoNextSection(
856 &aStart
, true, false )) )
858 if( nullptr != ( pContentFrame
= pCNd
->getLayoutFrame( GetLayout() ) ) && pContentFrame
->IsTextFrame() )
860 SwTextFrame
*const pFrame(static_cast<SwTextFrame
*>(pContentFrame
));
861 nRet
= nRet
+ pFrame
->GetLineCount(TextFrameIndex(COMPLETE_STRING
));
862 if (GetLayout()->HasMergedParas())
864 if (auto const*const pMerged
= pFrame
->GetMergedPara())
866 aStart
= *pMerged
->pLastNode
;
874 tools::Long
SwEditShell::CompareDoc( const SwDoc
& rDoc
)
877 tools::Long nRet
= GetDoc()->CompareDoc( rDoc
);
882 tools::Long
SwEditShell::MergeDoc( const SwDoc
& rDoc
)
885 tools::Long nRet
= GetDoc()->MergeDoc( rDoc
);
890 const SwFootnoteInfo
& SwEditShell::GetFootnoteInfo() const
892 return GetDoc()->GetFootnoteInfo();
895 void SwEditShell::SetFootnoteInfo(const SwFootnoteInfo
& rInfo
)
898 CurrShell
aCurr( this );
899 GetDoc()->SetFootnoteInfo(rInfo
);
904 const SwEndNoteInfo
& SwEditShell::GetEndNoteInfo() const
906 return GetDoc()->GetEndNoteInfo();
909 void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo
& rInfo
)
912 CurrShell
aCurr( this );
913 GetDoc()->SetEndNoteInfo(rInfo
);
917 const SwLineNumberInfo
& SwEditShell::GetLineNumberInfo() const
919 return GetDoc()->GetLineNumberInfo();
922 void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo
& rInfo
)
925 CurrShell
aCurr( this );
926 GetDoc()->SetLineNumberInfo(rInfo
);
927 AddPaintRect( GetLayout()->getFrameArea() );
931 sal_uInt16
SwEditShell::GetLinkUpdMode() const
933 return getIDocumentSettingAccess().getLinkUpdateMode( false );
936 void SwEditShell::SetLinkUpdMode( sal_uInt16 nMode
)
938 getIDocumentSettingAccess().setLinkUpdateMode( nMode
);
941 // Interface for TextInputData - (for text input of japanese/chinese characters)
942 void SwEditShell::CreateExtTextInput(LanguageType eInputLanguage
)
944 SwExtTextInput
* pRet
= GetDoc()->CreateExtTextInput( *GetCursor() );
945 pRet
->SetLanguage(eInputLanguage
);
946 pRet
->SetOverwriteCursor( SwCursorShell::IsOverwriteCursor() );
949 OUString
SwEditShell::DeleteExtTextInput( bool bInsText
)
951 const SwPosition
& rPos
= *GetCursor()->GetPoint();
952 SwExtTextInput
* pDel
= GetDoc()->GetExtTextInput( rPos
.nNode
.GetNode(),
953 rPos
.nContent
.GetIndex() );
956 //JP 25.10.2001: under UNIX the cursor is moved before the Input-
957 // Engine event comes in. So take any - normally there
958 // exist only one at the time. -- Task 92016
959 pDel
= GetDoc()->GetExtTextInput();
965 SwUnoCursorHelper::GetTextFromPam(*pDel
, sTmp
);
967 CurrShell
aCurr( this );
969 pDel
->SetInsText( bInsText
);
970 SetOverwriteCursor( pDel
->IsOverwriteCursor() );
971 const SwPosition
aPos( *pDel
->GetPoint() );
972 GetDoc()->DeleteExtTextInput( pDel
);
974 // In this case, the "replace" function did not set the cursor
975 // to the original position. Therefore we have to do this manually.
976 if ( ! bInsText
&& IsOverwriteCursor() )
977 *GetCursor()->GetPoint() = aPos
;
984 void SwEditShell::SetExtTextInputData( const CommandExtTextInputData
& rData
)
986 SwPaM
* pCurrentCursor
= GetCursor();
987 const SwPosition
& rPos
= *pCurrentCursor
->GetPoint();
988 SwExtTextInput
* pInput
= GetDoc()->GetExtTextInput( rPos
.nNode
.GetNode() );
993 CurrShell
aCurr( this );
995 if( !rData
.IsOnlyCursorChanged() )
996 pInput
->SetInputData( rData
);
998 const SwPosition
& rStt
= *pInput
->Start();
999 const sal_Int32 nNewCursorPos
= rStt
.nContent
.GetIndex() + rData
.GetCursorPos();
1003 const sal_Int32 nDiff
= nNewCursorPos
- rPos
.nContent
.GetIndex();
1006 bool bLeft
= nDiff
< 0;
1007 sal_Int32 nMaxGuard
= std::abs(nDiff
);
1010 auto nOldPos
= pCurrentCursor
->GetPoint()->nContent
.GetIndex();
1012 Left(1, CRSR_SKIP_CHARS
);
1014 Right(1, CRSR_SKIP_CHARS
);
1015 auto nNewPos
= pCurrentCursor
->GetPoint()->nContent
.GetIndex();
1018 if (nNewPos
== nNewCursorPos
)
1021 if (nNewPos
== nOldPos
)
1023 // if there was no movement, we have failed for some reason
1024 SAL_WARN("sw.core", "IM cursor move failed");
1028 if (--nMaxGuard
== 0)
1030 // if it takes more cursor moves than there are utf-16 chars to move past
1031 // something has probably gone wrong
1032 SAL_WARN("sw.core", "IM abandoning cursor positioning");
1038 SetOverwriteCursor( rData
.IsCursorOverwrite() );
1042 if( !rData
.IsCursorVisible() ) // must be called after the EndAction
1047 void SwEditShell::TransliterateText( TransliterationFlags nType
)
1049 utl::TransliterationWrapper
aTrans( ::comphelper::getProcessComponentContext(), nType
);
1051 CurrShell
aCurr( this );
1053 SwPaM
* pCursor
= GetCursor();
1054 if( pCursor
->GetNext() != pCursor
)
1056 GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY
, nullptr);
1057 for(const SwPaM
& rPaM
: GetCursor()->GetRingContainer())
1059 if( rPaM
.HasMark() )
1060 GetDoc()->getIDocumentContentOperations().TransliterateText( rPaM
, aTrans
);
1062 GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY
, nullptr);
1065 GetDoc()->getIDocumentContentOperations().TransliterateText( *pCursor
, aTrans
);
1070 void SwEditShell::CountWords( SwDocStat
& rStat
) const
1072 for(const SwPaM
& rPaM
: GetCursor()->GetRingContainer())
1074 if( rPaM
.HasMark() )
1075 SwDoc::CountWords( rPaM
, rStat
);
1080 void SwEditShell::ApplyViewOptions( const SwViewOption
&rOpt
)
1082 SwCursorShell::StartAction();
1083 SwViewShell::ApplyViewOptions( rOpt
);
1084 SwEditShell::EndAction();
1087 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */