Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/ndtxt.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
#pragma once
20
21
#include <cppuhelper/weakref.hxx>
22
#include <com/sun/star/text/XTextContent.hpp>
23
24
#include "swdllapi.h"
25
#include "IDocumentContentOperations.hxx"
26
#include "SwNumberTreeTypes.hxx"
27
#include "hintids.hxx"
28
#include "list.hxx"
29
#include "modeltoviewhelper.hxx"
30
#include "ndhints.hxx"
31
#include "node.hxx"
32
#include "paratr.hxx"
33
34
#include <sfx2/Metadatable.hxx>
35
#include <unotools/weakref.hxx>
36
#include <o3tl/sorted_vector.hxx>
37
#include <memory>
38
#include <vector>
39
#include <functional>
40
#include <map>
41
42
class SfxHint;
43
class SwNumRule;
44
class SwNodeNum;
45
class SvxFirstLineIndentItem;
46
class SvxTextLeftMarginItem;
47
struct SvxFontUnitMetrics;
48
class SwXParagraph;
49
class SwMarkName;
50
51
namespace utl {
52
    class TransliterationWrapper;
53
}
54
namespace vcl
55
{
56
class Font;
57
}
58
59
class SwContentFrame;
60
class SwTextField;
61
class SwTextInputField;
62
class SfxItemSet;
63
class SwUndoTransliterate;
64
struct SwSpellArgs;
65
struct SwConversionArgs;
66
class SwInterHyphInfo;
67
class SwWrongList;
68
class SwGrammarMarkUp;
69
struct SwDocStat;
70
enum class ExpandMode;
71
enum class SwFieldIds : sal_uInt16;
72
class SwField;
73
class SwFormatChangeHint;
74
75
namespace sw {
76
    class TextNodeNotificationSuppressor;
77
    class RemoveUnoObjectHint;
78
    class AttrSetChangeHint;
79
    class UpdateAttrHint;
80
    namespace mark { enum class RestoreMode; }
81
}
82
83
namespace com::sun::star {
84
    namespace uno {
85
        template < class > class Sequence;
86
    }
87
}
88
89
typedef o3tl::sorted_vector< sal_Int32 > SwSoftPageBreakList;
90
91
namespace sw
92
{
93
94
enum class WrongState { TODO, PENDING, DONE };
95
96
struct ParagraphIdleData
97
{
98
    std::unique_ptr<SwWrongList> pWrong;                // for spell checking
99
    std::unique_ptr<SwGrammarMarkUp> pGrammarCheck;     // for grammar checking /  proof reading
100
    std::unique_ptr<SwWrongList> pSmartTags;
101
    sal_uInt32 nNumberOfWords  = 0;
102
    sal_uInt32 nNumberOfAsianWords  = 0;
103
    sal_uInt32 nNumberOfChars  = 0;
104
    sal_uLong nNumberOfCharsExcludingSpaces = 0;
105
    bool bWordCountDirty = true;
106
    WrongState eWrongDirty = WrongState::TODO; ///< online spell checking needed/done?
107
    bool bGrammarCheckDirty = true;
108
    bool bSmartTagDirty = true;
109
    bool bAutoComplDirty = true;               ///< auto complete list dirty
110
};
111
112
} // end namespace sw
113
114
/// SwTextNode is a paragraph in the document model.
115
class SW_DLLPUBLIC SwTextNode final
116
    : public SwContentNode
117
    , public ::sfx2::Metadatable
118
    , public sw::FormatDropDefiner
119
{
120
    friend class SwContentNode;
121
    /// For creating the first TextNode.
122
    friend class SwDoc;         ///< CTOR and AppendTextNode()
123
    friend class SwNodes;
124
    friend class SwTextFrame;
125
    friend class SwScriptInfo;
126
    friend class sw::TextNodeNotificationSuppressor;
127
128
    /** May be 0. It is only then not 0 if it contains hard attributes.
129
       Therefore: never access directly! */
130
    std::unique_ptr<SwpHints> m_pSwpHints;
131
132
    mutable std::unique_ptr<SwNodeNum> mpNodeNum;  ///< Numbering for this paragraph.
133
    mutable std::unique_ptr<SwNodeNum> mpNodeNumRLHidden; ///< Numbering for this paragraph (hidden redlines)
134
    mutable std::unique_ptr<SwNodeNum> mpNodeNumOrig; ///< Numbering for this paragraph (before changes)
135
136
    OUString m_Text;
137
138
    mutable sw::ParagraphIdleData m_aParagraphIdleData;
139
140
    /** Some of the chars this para are hidden. Paragraph has to be reformatted
141
       on changing the view to print preview. */
142
    mutable bool m_bContainsHiddenChars : 1;
143
    /// The whole paragraph is hidden because of the hidden text attribute
144
    mutable bool m_bHiddenCharsHidePara : 1;
145
    /// The last two flags have to be recalculated if this flag is set:
146
    mutable bool m_bRecalcHiddenCharFlags : 1;
147
148
    mutable bool m_bLastOutlineState : 1;
149
    bool m_bNotifiable;
150
151
    bool mbEmptyListStyleSetDueToSetOutlineLevelAttr;
152
153
    /** boolean, indicating that a <SetAttr(..)> or <ResetAttr(..)> or
154
       <ResetAllAttr(..)> method is running.
155
       Needed to avoid duplicate handling of attribute change actions. */
156
    bool mbInSetOrResetAttr;
157
158
    /// Is an undo operation in progress?
159
    bool m_bInUndo;
160
161
    std::optional< OUString > m_oNumStringCache;
162
163
    unotools::WeakReference<SwXParagraph> m_wXParagraph;
164
165
    // DrawingLayer FillAttributes in a preprocessed form for primitive usage
166
    drawinglayer::attribute::SdrAllFillAttributesHelperPtr  maFillAttributes;
167
168
    SAL_DLLPRIVATE SwTextNode( const SwNode& rWhere, SwTextFormatColl *pTextColl,
169
                             const SfxItemSet* pAutoAttr = nullptr );
170
    virtual void SwClientNotify( const SwModify&, const SfxHint& ) override;
171
    /// Copies the attributes at nStart to pDest.
172
    SAL_DLLPRIVATE void CopyAttr( SwTextNode *pDest, const sal_Int32 nStart, const sal_Int32 nOldPos);
173
174
    SAL_DLLPRIVATE SwTextNode* MakeNewTextNode( const SwNode&, bool bNext = true,
175
                                bool bChgFollow = true );
176
177
    SAL_DLLPRIVATE void CutImpl(
178
          SwTextNode * const pDest, const SwContentIndex & rDestStart,
179
          const SwContentIndex & rStart, /*const*/ sal_Int32 nLen,
180
          const bool bUpdate = true );
181
182
    /// Move all comprising hard attributes to the AttrSet of the paragraph.
183
    SAL_DLLPRIVATE void MoveTextAttr_To_AttrSet();  // Called by SplitNode.
184
185
    /// Create the specific AttrSet.
186
    SAL_DLLPRIVATE virtual void NewAttrSet( SwAttrPool& ) override;
187
188
    /// Optimization: Asking for information about hidden characters at SwScriptInfo
189
    /// updates these flags.
190
    bool IsCalcHiddenCharFlags() const
191
54.5k
        { return m_bRecalcHiddenCharFlags; }
192
    void SetHiddenCharAttribute( bool bNewHiddenCharsHidePara, bool bNewContainsHiddenChars ) const
193
133k
    {
194
133k
        m_bHiddenCharsHidePara = bNewHiddenCharsHidePara;
195
133k
        m_bContainsHiddenChars = bNewContainsHiddenChars;
196
133k
        m_bRecalcHiddenCharFlags = false;
197
133k
    }
198
199
    SAL_DLLPRIVATE void CalcHiddenCharFlags() const;
200
201
    SAL_DLLPRIVATE void SetLanguageAndFont( const SwPaM &rPaM,
202
            LanguageType nLang, sal_uInt16 nLangWhichId,
203
            const vcl::Font *pFont,  sal_uInt16 nFontWhichId );
204
205
    inline void TryDeleteSwpHints();
206
207
    SAL_DLLPRIVATE void impl_FormatToTextAttr(const SfxItemSet& i_rAttrSet);
208
209
    const SwTextInputField* GetOverlappingInputField( const SwTextAttr& rTextAttr ) const;
210
211
    void DelFrames_TextNodePart();
212
    void HandleNonLegacyHint(const SfxHint&);
213
214
    SAL_DLLPRIVATE void ImplDestroy();
215
216
public:
217
    bool IsWordCountDirty() const;
218
    sw::WrongState GetWrongDirty() const;
219
    bool IsWrongDirty() const;
220
    bool IsGrammarCheckDirty() const;
221
    bool IsSmartTagDirty() const;
222
    bool IsAutoCompleteWordDirty() const;
223
    void SetWordCountDirty( bool bNew ) const;
224
    void SetWrongDirty(sw::WrongState eNew) const;
225
    void SetGrammarCheckDirty( bool bNew ) const;
226
    void SetSmartTagDirty( bool bNew ) const;
227
    void SetAutoCompleteWordDirty( bool bNew ) const;
228
    void SetWrong( std::unique_ptr<SwWrongList> pNew );
229
    void ClearWrong();
230
    std::unique_ptr<SwWrongList> ReleaseWrong();
231
    SwWrongList* GetWrong();
232
    const SwWrongList* GetWrong() const;
233
    void SetGrammarCheck( std::unique_ptr<SwGrammarMarkUp> pNew );
234
    void ClearGrammarCheck();
235
    std::unique_ptr<SwGrammarMarkUp> ReleaseGrammarCheck();
236
    SwGrammarMarkUp* GetGrammarCheck();
237
    // return SwWrongList because *function pointer* return values aren't covariant
238
    SwWrongList const* GetGrammarCheck() const;
239
    void SetSmartTags( std::unique_ptr<SwWrongList> pNew );
240
    void ClearSmartTags();
241
    std::unique_ptr<SwWrongList> ReleaseSmartTags();
242
    SwWrongList* GetSmartTags();
243
    SwWrongList const* GetSmartTags() const;
244
245
    /// End: Data collected during idle time
246
247
public:
248
    using SwContentNode::GetAttr;
249
    void UpdateDocPos(const SwTwips nDocPos, const sal_uInt32 nIndex);
250
    /// for hanging TextFormatCollections somewhere else (Outline-Numbering!)
251
    void TriggerNodeUpdate(const sw::LegacyModifyHint&);
252
    void TriggerNodeUpdate(const sw::AttrSetChangeHint&);
253
    void TriggerNodeUpdate(const SfxHint&);
254
    void TriggerNodeUpdate(const SwFormatChangeHint&);
255
256
190M
    const OUString& GetText() const { return m_Text; }
257
258
    // returns the maximum number of characters that can still be added to the node
259
    inline sal_Int32 GetSpaceLeft() const;
260
261
    /// getters for SwpHints
262
    inline       SwpHints &GetSwpHints();
263
    inline const SwpHints &GetSwpHints() const;
264
11.5M
          SwpHints *GetpSwpHints()       { return m_pSwpHints.get(); }
265
11.5M
    const SwpHints *GetpSwpHints() const { return m_pSwpHints.get(); }
266
148M
    bool   HasHints() const { return m_pSwpHints != nullptr; }
267
    inline       SwpHints &GetOrCreateSwpHints();
268
269
    virtual ~SwTextNode() override;
270
271
    virtual sal_Int32 Len() const override;
272
273
    /// Is in itratr.
274
    void GetMinMaxSize( SwNodeOffset nIndex, sal_uLong& rMin, sal_uLong &rMax, sal_uLong &rAbs ) const;
275
276
    /// overriding to handle change of certain paragraph attributes
277
    virtual bool SetAttr( const SfxPoolItem& ) override;
278
    virtual bool SetAttr( const SfxItemSet& rSet ) override;
279
    virtual bool ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 = 0 ) override;
280
    virtual bool ResetAttr( const std::vector<sal_uInt16>& rWhichArr ) override;
281
    virtual sal_uInt16 ResetAllAttr() override;
282
283
    /// insert text content
284
    /// @param rStr text to insert; in case it does not fit into the capacity
285
    ///             of the node, the longest prefix that fits is inserted
286
    /// @return the prefix of rStr that was actually inserted
287
    OUString InsertText( const OUString & rStr, const SwContentIndex & rIdx,
288
                     const SwInsertFlags nMode
289
                         = SwInsertFlags::DEFAULT );
290
    OUString InsertText( const OUString & rStr, const SwPosition & rIdx,
291
                     const SwInsertFlags nMode
292
                         = SwInsertFlags::DEFAULT );
293
    /// Add a dummy character to the redline of the table changes
294
0
    void InsertDummy() { m_Text = OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR); }
295
296
    /** delete text content
297
        ATTENTION: must not be called with a range that overlaps the start of
298
                   an attribute with both extent and dummy char
299
     */
300
    void EraseText ( const SwContentIndex &rIdx, const sal_Int32 nCount = SAL_MAX_INT32,
301
                     const SwInsertFlags nMode = SwInsertFlags::DEFAULT );
302
    void EraseText ( const SwPosition& rIdx, const sal_Int32 nCount = SAL_MAX_INT32,
303
                     const SwInsertFlags nMode = SwInsertFlags::DEFAULT );
304
305
    /** delete all attributes.
306
        If neither pSet nor nWhich is given, delete all attributes (except
307
        refmarks, toxmarks, meta) in range.
308
        @param nContentStart start position
309
        @param nLen     range in which attributes will be deleted
310
        @param pSet     if not 0, delete only attributes contained in pSet
311
        @param nWhich   if not 0, delete only attributes with matching which
312
        @param bInclRefToxMark
313
            refmarks, toxmarks, and metas will be ignored unless this is true
314
        ATTENTION: setting bInclRefToxMark is only allowed from UNDO!
315
        @param bExactRange From the attributes included in the range, delete
316
        only the ones which have exactly same range. Don't delete the ones
317
        which are simply included in the range.
318
     */
319
    void RstTextAttr(
320
        const sal_Int32 nContentStart,
321
        const sal_Int32 nLen,
322
        const sal_uInt16 nWhich = 0,
323
        const SfxItemSet* pSet = nullptr,
324
        const bool bInclRefToxMark = false,
325
        const bool bExactRange = false );
326
    void    GCAttr();
327
328
    // Delete text attribute (needs to be deregistered at Pool!)
329
    void    DestroyAttr( SwTextAttr* pAttr );
330
331
    // delete all attributes from SwpHintsArray.
332
    void    ClearSwpHintsArr( bool bDelFields );
333
334
    /// initialize the hints after file loading (which takes shortcuts)
335
    void    FileLoadedInitHints();
336
337
    /// Insert pAttr into hints array. @return true iff inserted successfully
338
    bool    InsertHint( SwTextAttr * const pAttr,
339
                  const SetAttrMode nMode = SetAttrMode::DEFAULT );
340
    /// create new text attribute from rAttr and insert it
341
    /// @return     inserted hint; 0 if not sure the hint is inserted
342
    SwTextAttr* InsertItem( SfxPoolItem& rAttr,
343
                  const sal_Int32 nStart, const sal_Int32 nEnd,
344
                  const SetAttrMode nMode = SetAttrMode::DEFAULT );
345
346
    /** Set these attributes at TextNode. If the whole range is comprised
347
       set them only in AutoAttrSet (SwContentNode::SetAttr). */
348
    bool SetAttr( const SfxItemSet& rSet,
349
                  sal_Int32 nStt, sal_Int32 nEnd,
350
                  const SetAttrMode nMode = SetAttrMode::DEFAULT,
351
                  SwTextAttr **ppNewTextAttr = nullptr);
352
    /** Query the attributes of textnode over the range.
353
       Introduce 4th optional parameter <bMergeIndentValuesOfNumRule>.
354
       If <bMergeIndentValuesOfNumRule> == true, the indent attributes of
355
       the corresponding list level of an applied list style is merged into
356
       the requested item set as a LR-SPACE item, if <bOnlyTextAttr> == false,
357
       corresponding node has not its own indent attributes and the
358
       position-and-space mode of the list level is SvxNumberFormat::LABEL_ALIGNMENT. */
359
    bool GetParaAttr( SfxItemSet& rSet, sal_Int32 nStt, sal_Int32 nEnd,
360
                  const bool bOnlyTextAttr  = false,
361
                  const bool bGetFromChrFormat = true,
362
                  const bool bMergeIndentValuesOfNumRule = false,
363
                  SwRootFrame const* pLayout = nullptr) const;
364
365
    /// Convey attributes of an AttrSet (AutoFormat) to SwpHintsArray.
366
    void FormatToTextAttr( SwTextNode* pNd );
367
368
    /// delete all attributes of type nWhich at nStart (opt. end nEnd)
369
    void DeleteAttributes( const sal_uInt16 nWhich,
370
                  const sal_Int32 nStart, const sal_Int32 nEnd = 0 );
371
    /// delete the attribute pTextAttr
372
    void DeleteAttribute ( SwTextAttr * const pTextAttr );
373
374
    /** Actions on text and attributes.
375
       introduce optional parameter to control, if all attributes have to be copied. */
376
    void CopyText( SwTextNode * const pDest,
377
               const SwContentIndex &rStart,
378
               const sal_Int32 nLen,
379
               const bool bForceCopyOfAllAttrs );
380
    void CopyText( SwTextNode * const pDest,
381
               const SwContentIndex &rDestStart,
382
               const SwContentIndex &rStart,
383
               sal_Int32 nLen,
384
               const bool bForceCopyOfAllAttrs = false );
385
    void CopyText( SwTextNode * const pDest,
386
               const SwContentIndex &rDestStart,
387
               const SwPosition &rStart,
388
               sal_Int32 nLen,
389
               const bool bForceCopyOfAllAttrs = false );
390
    /*
391
        After copying a text portion with its comments, the replies will still reference to their original parent.
392
        We need to set their reference to their copied-parent.
393
        idMapForComments and nameMapForComments variables hold the original ids of comments as keys.
394
        And they hold the new ids and names of comments as values.
395
        So we can find a reply's (child comment) new parent (value) by looking up its original parent (key).
396
    */
397
    static void EstablishParentChildRelationsOfComments(const SwTextNode* pDest,
398
                std::map<sal_Int32, sal_Int32>& idMapForComments,
399
                std::map<sal_Int32, SwMarkName>& nameMapForComments);
400
401
    void        CutText(SwTextNode * const pDest,
402
                    const SwContentIndex & rStart, const sal_Int32 nLen);
403
    inline void CutText(SwTextNode * const pDest, const SwContentIndex &rDestStart,
404
                    const SwContentIndex & rStart, const sal_Int32 nLen);
405
406
    /// replace nDelLen characters at rStart with rText
407
    /// in case the replacement does not fit, it is partially inserted up to
408
    /// the capacity of the node
409
    void ReplaceText( const SwContentIndex& rStart, const sal_Int32 nDelLen,
410
            const OUString & rText );
411
    void ReplaceText( const SwPosition& rStart, const sal_Int32 nDelLen,
412
            const OUString & rText );
413
    void ReplaceTextOnly( sal_Int32 nPos, sal_Int32 nLen,
414
            std::u16string_view aText,
415
            const css::uno::Sequence<sal_Int32>& rOffsets );
416
417
    /// Virtual methods from ContentNode.
418
    virtual SwContentFrame *MakeFrame( SwFrame* ) override;
419
    SwTextNode * SplitContentNode(const SwPosition &,
420
            std::function<void (SwTextNode *, sw::mark::RestoreMode, bool AtStart)> const* pContentIndexRestore);
421
    virtual SwContentNode *JoinNext() override;
422
    void JoinPrev();
423
424
    SwContentNode *AppendNode( const SwPosition & );
425
426
    /// When appropriate set DontExpand-flag at INet or character styles respectively.
427
    bool DontExpandFormat( sal_Int32 nContentIdx, bool bFlag = true,
428
                        bool bFormatToTextAttributes = true );
429
430
    /** get the innermost text attribute covering position nIndex.
431
        @param nWhich   only attribute with this id is returned.
432
        @param eMode    the predicate for matching (@see GetTextAttrMode).
433
434
        ATTENTION: this function is not well-defined for those
435
        hints of which several may cover a single position, like
436
        RES_TXTATR_CHARFMT, RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK
437
     */
438
    SwTextAttr *GetTextAttrAt(
439
        sal_Int32 const nIndex,
440
        sal_uInt16 const nWhich,
441
        ::sw::GetTextAttrMode const eMode = ::sw::GetTextAttrMode::Default) const;
442
443
    /** get the innermost text attributes covering position nIndex.
444
        @param nWhich   only attributes with this id are returned.
445
        @param eMode    the predicate for matching (@see GetTextAttrMode).
446
     */
447
    std::vector<SwTextAttr *> GetTextAttrsAt(
448
        sal_Int32 const nIndex,
449
        sal_uInt16 const nWhich ) const;
450
451
    /** get the text attribute at position nIndex which owns
452
        the dummy character CH_TXTATR_* at that position, if one exists.
453
        @param nIndex   the position in the text
454
        @param nWhich   if different from RES_TXTATR_END, return only
455
                        attribute with given which id
456
        @return the text attribute at nIndex of type nWhich, if it exists
457
    */
458
    SwTextAttr *GetTextAttrForCharAt(
459
        const sal_Int32 nIndex,
460
        const sal_uInt16 nWhich = RES_TXTATR_END ) const;
461
462
    /**
463
     * Get the text attribute of an end dummy character at nIndex. Return the attribute only in
464
     * case its which id is nWhich.
465
     *
466
     * Note that the position of the end dummy character is one less than the end of the attribute.
467
     */
468
    SwTextAttr* GetTextAttrForEndCharAt(sal_Int32 nIndex, sal_uInt16 nWhich) const;
469
470
    SwTextField* GetFieldTextAttrAt(
471
        const sal_Int32 nIndex,
472
        ::sw::GetTextAttrMode const eMode = ::sw::GetTextAttrMode::Expand) const;
473
474
    bool Spell(SwSpellArgs* , bool bIsReadOnly);
475
    bool Convert( SwConversionArgs & );
476
477
    inline SwTextFormatColl *GetTextColl() const;
478
    virtual SwFormatColl *ChgFormatColl( SwFormatColl*, bool bSetListLevel = true ) override;
479
    void ChgTextCollUpdateNum(const SwTextFormatColl* pOld,
480
                              const SwTextFormatColl* pNew,
481
                              bool bSetListLevel = true );
482
483
    /** Copy collection with all auto formats to dest-node.
484
        The latter might be in another document!
485
       (Method in ndcopy.cxx!!). */
486
    void CopyCollFormat(SwTextNode& rDestNd, bool bUndoForChgFormatColl = true);
487
488
    // BEGIN OF BULLET/NUMBERING/OUTLINE STUFF:
489
490
    /**
491
       Returns numbering rule of this text node.
492
493
       @param bInParent     search in parent attributes, too
494
495
       @return numbering rule of this text node or NULL if none is set
496
     */
497
    SwNumRule *GetNumRule(bool bInParent = true) const;
498
499
    const SwNodeNum* GetNum(SwRootFrame const* pLayout = nullptr,
500
             SwListRedlineType eRedline = SwListRedlineType::SHOW) const;
501
    void DoNum(std::function<void (SwNodeNum &)> const&);
502
503
    SwNumberTree::tNumberVector GetNumberVector(SwRootFrame const* pLayout = nullptr,
504
            SwListRedlineType eRedline = SwListRedlineType::SHOW) const;
505
506
    /**
507
       Returns if this text node is an outline.
508
509
       @retval true      this text node is an outline
510
       @retval false     else
511
     */
512
    bool IsOutline() const;
513
514
    bool IsOutlineStateChanged() const;
515
516
    void UpdateOutlineState();
517
518
    /**
519
       Notify this textnode that its numbering rule has changed.
520
     */
521
    void NumRuleChgd();
522
523
    /** Returns outline of numbering string
524
525
        Introduce parameter <_bInclPrefixAndSuffixStrings> in order to control,
526
        if the prefix and the suffix strings have to been included or not.
527
528
        @param _bInclPrefixAndSuffixStrings
529
        optional input parameter - boolean indicating, if the prefix and the
530
        suffix strings have to been included or not. default value = <true>
531
532
        @param _nRestrictToThisLevel
533
        optional input parameter - unsigned integer indicating the maximum outline
534
        level to which the output string must be restricted to. Default value is
535
        MAXLEVEL
536
    */
537
    OUString GetNumString( const bool _bInclPrefixAndSuffixStrings = true,
538
            const unsigned int _nRestrictToThisLevel = MAXLEVEL,
539
            SwRootFrame const* pLayout = nullptr,
540
            SwListRedlineType eRedline = SwListRedlineType::SHOW) const;
541
542
    /**
543
       Returns the additional indents of this text node and its numbering.
544
545
       @param bTextLeft return text-left-margin instead of left-margin
546
                        (include negative first-line-indent, see lrspitem.hxx)
547
548
       @return additional num indents - a delta to be added to node's items
549
     */
550
     tools::Long GetLeftMarginWithNum( bool bTextLeft = false ) const;
551
552
    /**
553
       Returns the combined first line indent of this text node and
554
       its numbering.
555
556
       @param rFirstOffset
557
       the first line indent of this text node taking the numbering into
558
       account (return parameter)
559
560
       @param rMetrics
561
       helper structure containing font metrics, used for resolving font-
562
       relative indentation
563
564
       @retval true   this node has SwNodeNum and has numbering rule
565
       @retval false  else
566
     */
567
    bool GetFirstLineOfsWithNum( short& rFirstOffset, const SvxFontUnitMetrics& rMetrics ) const;
568
569
    SwTwips GetAdditionalIndentForStartingNewList() const;
570
571
    /** return left margin for tab stop position calculation
572
573
        Needed for text formatting
574
        Method considers new list level attributes, which also can provide a left margin value
575
    */
576
    tools::Long GetLeftMarginForTabCalculation() const;
577
578
    /** Returns if this text node has a number.
579
580
        This text node has a number if it has a SwNodeNum and a
581
        numbering rule and the numbering format specified for the
582
        level of the SwNodeNum is of an enumeration type.
583
584
        @retval true    This text node has a number.
585
        @retval false   else
586
     */
587
    bool HasNumber(SwRootFrame const* pLayout = nullptr) const;
588
589
    /** Returns if this text node has a bullet.
590
591
        This text node has a bullet if it has a SwNodeNum and a
592
        numbering rule and the numbering format specified for the
593
        level of the SwNodeNum is of a bullet type.
594
595
        @retval true    This text node has a bullet.
596
        @retval false   else
597
     */
598
    bool HasBullet() const;
599
600
    /** Returns is this text node is numbered.
601
602
        This node is numbered if it has a SwNodeNum and it has a
603
        numbering rule and has not a hidden SwNodeNum.
604
605
        ATTENTION: Returns true even if the SwNumFormat has type
606
        SVX_NUM_NUMBER_NONE.
607
608
        @retval true      This node is numbered.
609
        @retval false     else
610
     */
611
    bool IsNumbered(SwRootFrame const* pLayout = nullptr) const;
612
613
    /** Returns if this text node has a marked label.
614
615
        @retval true       This text node has a marked label.
616
        @retval false      else
617
     */
618
    bool HasMarkedLabel() const;
619
620
    /** Sets the list level of this text node.
621
622
        Side effect, when the text node is a list item:
623
        The text node's representation in the list tree (<SwNodeNum> instance)
624
        is updated.
625
626
        @param nLevel level to set
627
    */
628
    void SetAttrListLevel(int nLevel);
629
630
    bool HasAttrListLevel() const;
631
632
    int GetAttrListLevel() const;
633
634
    /** Returns the actual list level of this text node, when it is a list item
635
636
        @return the actual list level of this text node, if it is a list item,
637
               -1 otherwise
638
    */
639
    int GetActualListLevel(SwListRedlineType eRedline = SwListRedlineType::SHOW) const;
640
641
    /**
642
       Returns outline level of this text node.
643
644
       @param bInlineHeading     it can return the outline level of the inline heading
645
646
       If a text node has an outline number (i.e. it has an SwNodeNum
647
       and an outline numbering rule) the outline level is the level of
648
       this SwNodeNum.
649
650
       If a text node has no outline number and has a paragraph style
651
       attached the outline level is the outline level of the
652
       paragraph style.
653
654
       Otherwise the text node has no outline level (NO_NUMBERING),
655
       except if bInlineHeading is true, and there is an inline heading
656
       at the beginning of the paragraph anchored as character and
657
       with a different outline level.
658
659
       NOTE: The outline level of text nodes is subject to change. The
660
       plan is to have an SwTextNode::nOutlineLevel member that is
661
       updated from a paragraph style upon appliance of that paragraph
662
       style.
663
664
       @return outline level or NO_NUMBERING if there is no outline level
665
     */
666
    int GetAttrOutlineLevel(bool bInlineHeading = false) const;
667
668
    /**
669
       Sets the out line level *at* a text node.
670
671
       @param nLevel     the level to be set
672
673
       If the text node has an outline number the level is set at the
674
       outline number.
675
676
       If the text node has no outline number but has a paragraph
677
       style applied the outline level is set at the paragraph style.
678
679
       NOTE: This is subject to change, see GetOutlineLevel.
680
     */
681
    void SetAttrOutlineLevel(int nLevel);
682
683
    /**
684
     * @brief GetAttrOutlineContentVisible
685
     * @return true if 'OutlineContentVisibleAttr' is found in RES_PARATR_GRABBAG
686
     */
687
    bool GetAttrOutlineContentVisible() const;
688
    void SetAttrOutlineContentVisible(bool bVisible);
689
690
377k
    bool IsEmptyListStyleDueToSetOutlineLevelAttr() const { return mbEmptyListStyleSetDueToSetOutlineLevelAttr;}
691
    void SetEmptyListStyleDueToSetOutlineLevelAttr();
692
    void ResetEmptyListStyleDueToResetOutlineLevelAttr();
693
694
    /**
695
       Returns the width of leading tabs/blanks in this paragraph.
696
       This space will be converted into numbering indent if the paragraph
697
       is set to be numbered.
698
699
       @return     the width of the leading whitespace
700
     */
701
    SwTwips GetWidthOfLeadingTabs() const;
702
703
    /**
704
       Returns if the paragraph has a visible numbering or bullet.
705
       This includes all kinds of numbering/bullet/outlines.
706
       Note: This function returns false, if the numbering format is
707
       SVX_NUM_NUMBER_NONE or if the numbering/bullet has been deleted.
708
709
       @return     true if the paragraph has a visible numbering/bullet/outline
710
     */
711
    bool HasVisibleNumberingOrBullet() const;
712
713
    void SetListId(OUString const& rListId);
714
    OUString GetListId() const;
715
716
    /** Determines, if the list level indent attributes can be applied to the
717
        paragraph.
718
719
        The list level indents can be applied to the paragraph under the one
720
        of following conditions:
721
        - the list style is directly applied to the paragraph and the paragraph
722
          has no own indent attributes.
723
        - the list style is applied to the paragraph through one of its paragraph
724
          styles, the paragraph has no own indent attributes and on the paragraph
725
          style hierarchy from the paragraph to the paragraph style with the
726
          list style no indent attributes are found.
727
728
        @return bitmask
729
    */
730
    ::sw::ListLevelIndents AreListLevelIndentsApplicable() const;
731
    bool AreListLevelIndentsApplicableImpl(sal_uInt16 nWhich) const;
732
733
    /** Retrieves the list tab stop position, if the paragraph's list level defines
734
        one and this list tab stop has to merged into the tap stops of the paragraph
735
736
        @param nListTabStopPosition
737
        output parameter - containing the list tab stop position
738
739
        @return boolean - indicating, if a list tab stop position is provided
740
    */
741
    bool GetListTabStopPosition( tools::Long& nListTabStopPosition ) const;
742
743
    /** Retrieves the character following the list label, if the paragraph's
744
        list level defines one.
745
746
        @return the list tab stop position as string
747
    */
748
    OUString GetLabelFollowedBy() const;
749
750
    // END OF BULLET/NUMBERING/OUTLINE STUFF:
751
752
    void fillSoftPageBreakList( SwSoftPageBreakList& rBreak ) const;
753
754
    LanguageType GetLang( const sal_Int32 nBegin, const sal_Int32 nLen = 0,
755
                    sal_uInt16 nScript = 0, bool bNoneIfNoHyphenation = false ) const;
756
757
    /// in ndcopy.cxx
758
    bool IsSymbolAt(sal_Int32 nBegin) const; // In itratr.cxx.
759
    virtual SwContentNode* MakeCopy(SwDoc&, SwNode& rWhere, bool bNewFrames) const override;
760
761
    /// Interactive hyphenation: we find TextFrame and call its CalcHyph.
762
    bool Hyphenate( SwInterHyphInfo &rHyphInf );
763
    void DelSoftHyph( const sal_Int32 nStart, const sal_Int32 nEnd );
764
765
    /** add 4th optional parameter <bAddSpaceAfterListLabelStr> indicating,
766
       when <bWithNum = true> that a space is inserted after the string for
767
       the list label.
768
       add 5th optional parameter <bWithSpacesForLevel> indicating, if additional
769
       spaces are inserted in front of the expanded text string depending on
770
       the list level. */
771
    OUString GetExpandText( SwRootFrame const* pLayout,
772
                            const sal_Int32 nIdx = 0,
773
                            const sal_Int32 nLen = -1,
774
                            const bool bWithNum = false,
775
                            const bool bAddSpaceAfterListLabelStr = false,
776
                            const bool bWithSpacesForLevel = false,
777
                            const ExpandMode eAdditionalMode = ExpandMode::ExpandFootnote | ExpandMode::HideFieldmarkCommands) const;
778
    bool CopyExpandText( SwTextNode& rDestNd, const SwContentIndex* pDestIdx,
779
                           sal_Int32 nIdx, sal_Int32 nLen,
780
                           SwRootFrame const* pLayout,
781
                           bool bWithFootnote = true,
782
                           bool bReplaceTabsWithSpaces = false ) const;
783
784
    OUString GetRedlineText() const;
785
786
    /** @return actual count of initial chars for initial-function.
787
       If nWishLen == 0 that of first word. */
788
    sal_Int32 GetDropLen(sal_Int32 nWishLen) const;
789
790
    /// Passes back info needed on the dropcap dimensions
791
    bool GetDropSize(int& rFontHeight, int& rDropHeight, int& rDropDescent) const;
792
793
    /// Hidden Paragraph Field:
794
    bool CalcHiddenParaField()
795
24.6k
        { return m_pSwpHints && m_pSwpHints->CalcHiddenParaField(); }
796
    /// set CalcVisible flags
797
    void SetCalcHiddenParaField()
798
673
        { if (m_pSwpHints) m_pSwpHints->SetCalcHiddenParaField(); }
799
800
    /// is the paragraph visible?
801
    bool IsHiddenByParaField() const
802
1.84M
        { return m_pSwpHints && m_pSwpHints->IsHiddenByParaField(); }
803
804
    /// Hidden Paragraph Field:
805
806
    bool HasHiddenCharAttribute( bool bWholePara ) const
807
1.90M
    {
808
1.90M
        if ( m_bRecalcHiddenCharFlags )
809
51.9k
            CalcHiddenCharFlags();
810
1.90M
        return bWholePara ? m_bHiddenCharsHidePara : m_bContainsHiddenChars;
811
1.90M
    }
812
813
    void SetCalcHiddenCharFlags() const
814
36.5M
        { m_bRecalcHiddenCharFlags = true; }
815
816
    /** @return if the node is hidden due to
817
       1. HiddenParaField
818
       2. HiddenCharAttribute
819
       3. HiddenSection */
820
821
    bool IsHidden() const;
822
823
824
    /// override SwContentIndexReg
825
    virtual void Update(
826
        SwContentIndex const & rPos,
827
        const sal_Int32 nChangeLen,
828
        UpdateMode eMode) override;
829
830
    /// change text to Upper/Lower/Hiragana/Katakana/...
831
    void TransliterateText( utl::TransliterationWrapper& rTrans,
832
                            sal_Int32 nStart, sal_Int32 nEnd,
833
                            SwUndoTransliterate* pUndo, bool bUseRedlining = false );
834
835
    /// count words in given range - returns true if we refreshed out count
836
    bool CountWords( SwDocStat& rStat, sal_Int32 nStart, sal_Int32 nEnd ) const;
837
838
    /** Checks some global conditions like loading or destruction of document
839
       to economize notifications */
840
    bool IsNotificationEnabled() const;
841
842
    /// Checks a temporary notification blocker and the global conditions of IsNotificationEnabled()
843
    bool IsNotifiable() const;
844
845
    void SetListRestart( bool bRestart );
846
    bool IsListRestart() const;
847
848
    void SetAttrListRestartValue( SwNumberTree::tSwNumTreeNumber nNum );
849
    bool HasAttrListRestartValue() const;
850
    SwNumberTree::tSwNumTreeNumber GetAttrListRestartValue() const;
851
    SwNumberTree::tSwNumTreeNumber GetActualListStartValue() const;
852
853
    void SetCountedInList( bool bCounted );
854
    bool IsCountedInList() const;
855
856
    void AddToList();
857
    void AddToListRLHidden();
858
    void AddToListOrig();
859
    void RemoveFromList();
860
    void RemoveFromListRLHidden();
861
    void RemoveFromListOrig();
862
    bool IsInList() const;
863
    bool IsInListFromStyle() const;
864
865
    bool IsFirstOfNumRule(SwRootFrame const& rLayout) const;
866
867
    SAL_DLLPRIVATE unotools::WeakReference<SwXParagraph> const& GetXParagraph() const
868
122k
            { return m_wXParagraph; }
869
    SAL_DLLPRIVATE void SetXParagraph(rtl::Reference<SwXParagraph> const& xParagraph);
870
871
    /// sfx2::Metadatable
872
    virtual ::sfx2::IXmlIdRegistry& GetRegistry() override;
873
    virtual bool IsInClipboard() const override;
874
    /// Is this node in the undo array?
875
    virtual bool IsInUndo() const override;
876
    virtual bool IsInContent() const override;
877
    virtual css::uno::Reference< css::rdf::XMetadatable > MakeUnoObject() override;
878
879
    bool IsCollapse() const;
880
881
    virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
882
883
    sal_uInt32 GetRsid( sal_Int32 nStt, sal_Int32 nEnd ) const;
884
    sal_uInt32 GetParRsid() const;
885
886
    bool CompareRsid( const SwTextNode &rTextNode, sal_Int32 nStt1, sal_Int32 nStt2 ) const;
887
    bool CompareParRsid( const SwTextNode &rTextNode ) const;
888
889
    // Access to DrawingLayer FillAttributes in a preprocessed form for primitive usage
890
    virtual drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const override;
891
892
    /// In MS Word, the font underline setting of the paragraph end position won't affect the formatting of numbering, so we ignore it
893
    static bool IsIgnoredCharFormatForNumbering(const sal_uInt16 nWhich, bool bIsCharStyle = false);
894
    void FormatDropNotify(const SwFormatDrop& rDrop) override
895
51
            { TriggerNodeUpdate(sw::LegacyModifyHint(&rDrop, &rDrop)); };
896
897
    void SetInSwUndo(bool bInUndo);
898
};
899
900
inline SwpHints & SwTextNode::GetSwpHints()
901
137k
{
902
137k
    assert( m_pSwpHints );
903
137k
    return *m_pSwpHints;
904
137k
}
905
inline const SwpHints &SwTextNode::GetSwpHints() const
906
7.01k
{
907
7.01k
    assert( m_pSwpHints );
908
7.01k
    return *m_pSwpHints;
909
7.01k
}
910
911
inline SwpHints& SwTextNode::GetOrCreateSwpHints()
912
5.72M
{
913
5.72M
    if ( !m_pSwpHints )
914
494k
    {
915
494k
        m_pSwpHints.reset(new SwpHints(*this));
916
494k
    }
917
5.72M
    return *m_pSwpHints;
918
5.72M
}
919
920
inline void SwTextNode::TryDeleteSwpHints()
921
3.36M
{
922
3.36M
    if ( m_pSwpHints && m_pSwpHints->CanBeDeleted() )
923
270k
    {
924
270k
        m_pSwpHints.reset();
925
270k
    }
926
3.36M
}
927
928
inline SwTextFormatColl* SwTextNode::GetTextColl() const
929
17.7M
{
930
17.7M
    return const_cast<SwTextFormatColl*>(static_cast<const SwTextFormatColl*>(GetRegisteredIn()));
931
17.7M
}
932
933
/// Inline methods from Node.hxx
934
inline SwTextNode *SwNode::GetTextNode()
935
136M
{
936
136M
    return IsTextNode() ? static_cast<SwTextNode*>(this) : nullptr;
937
136M
}
938
939
inline const SwTextNode *SwNode::GetTextNode() const
940
104M
{
941
104M
    return IsTextNode() ? static_cast<const SwTextNode*>(this) : nullptr;
942
104M
}
943
944
inline void
945
SwTextNode::CutText(SwTextNode * const pDest, const SwContentIndex & rDestStart,
946
                    const SwContentIndex & rStart, const sal_Int32 nLen)
947
2.68k
{
948
2.68k
    CutImpl( pDest, rDestStart, rStart, nLen );
949
2.68k
}
950
951
inline sal_Int32 SwTextNode::GetSpaceLeft() const
952
35.4M
{
953
    // do not fill the String up to the max - need to be able to have a
954
    // SwPosition "behind" the last character, i.e., at index TXTNODE_MAX + 1
955
35.4M
    const sal_Int32 TXTNODE_MAX = SAL_MAX_INT32 - 2;
956
35.4M
    return TXTNODE_MAX-m_Text.getLength();
957
35.4M
}
958
959
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */