Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/uiview/formatclipboard.cxx
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
20
#include <memory>
21
#include <utility>
22
23
#include <formatclipboard.hxx>
24
25
#include <cmdid.h>
26
#include <cellatr.hxx>
27
#include <charfmt.hxx>
28
#include <frmfmt.hxx>
29
#include <docstyle.hxx>
30
#include <fchrfmt.hxx>
31
#include <svx/svdview.hxx>
32
#include <editeng/brushitem.hxx>
33
#include <editeng/shaditem.hxx>
34
#include <editeng/boxitem.hxx>
35
#include <editeng/formatbreakitem.hxx>
36
#include <fmtlsplt.hxx>
37
#include <editeng/keepitem.hxx>
38
#include <editeng/frmdiritem.hxx>
39
#include <fmtpdsc.hxx>
40
#include <fmtrowsplt.hxx>
41
#include <frmatr.hxx>
42
43
namespace
44
{
45
46
std::unique_ptr<SfxItemSet> lcl_CreateEmptyItemSet( SelectionType nSelectionType, SfxItemPool& rPool, bool bNoParagraphFormats = false )
47
0
{
48
0
    std::unique_ptr<SfxItemSet> pItemSet;
49
0
    if( nSelectionType & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic) )
50
0
    {
51
0
        pItemSet = std::make_unique<SfxItemSet>(SfxItemSet::makeFixedSfxItemSet<
52
0
                RES_FRMATR_BEGIN, RES_FILL_ORDER,
53
                // no RES_FRM_SIZE
54
0
                RES_PAPER_BIN, RES_SURROUND,
55
                // no RES_VERT_ORIENT
56
                // no RES_HORI_ORIENT
57
                // no RES_ANCHOR
58
0
                RES_BACKGROUND, RES_SHADOW,
59
                // no RES_FRMMACRO
60
0
                RES_COL, RES_KEEP,
61
                // no RES_URL
62
0
                RES_EDIT_IN_READONLY, RES_LAYOUT_SPLIT,
63
                // no RES_CHAIN
64
0
                RES_TEXTGRID, RES_FRMATR_END - 1>(rPool));
65
0
    }
66
0
    else if( nSelectionType & SelectionType::DrawObject )
67
0
    {
68
        //is handled different
69
0
    }
70
0
    else if( nSelectionType & SelectionType::Text )
71
0
    {
72
0
        if( bNoParagraphFormats )
73
0
            pItemSet = std::make_unique<SfxItemSet>(SfxItemSet::makeFixedSfxItemSet
74
0
                    <RES_CHRATR_BEGIN, RES_CHRATR_END - 1>(rPool));
75
0
        else
76
0
            pItemSet = std::make_unique<SfxItemSet>(SfxItemSet::makeFixedSfxItemSet<
77
0
                    RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
78
0
                    RES_PARATR_BEGIN, RES_FILL_ORDER,
79
                    // no RES_FRM_SIZE
80
0
                    RES_PAPER_BIN, RES_SURROUND,
81
                    // no RES_VERT_ORIENT
82
                    // no RES_HORI_ORIENT
83
                    // no RES_ANCHOR
84
0
                    RES_BACKGROUND, RES_SHADOW,
85
                    // no RES_FRMMACRO
86
0
                    RES_COL, RES_KEEP,
87
                    // no RES_URL
88
0
                    RES_EDIT_IN_READONLY, RES_LAYOUT_SPLIT,
89
                    // no RES_CHAIN
90
0
                    RES_TEXTGRID, RES_FRMATR_END - 1>(rPool));
91
0
    }
92
0
    return pItemSet;
93
0
}
94
95
void lcl_getTableAttributes( SfxItemSet& rSet, SwWrtShell &rSh, bool bAllCellAttrs )
96
0
{
97
0
    if (bAllCellAttrs)
98
0
    {
99
0
        std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
100
0
        rSh.GetBoxBackground(aBrush);
101
0
        rSet.Put( *aBrush );
102
0
        if(rSh.GetRowBackground(aBrush))
103
0
        {
104
0
            aBrush->SetWhich(SID_ATTR_BRUSH_ROW);
105
0
            rSet.Put( *aBrush );
106
0
        }
107
0
        else
108
0
            rSet.InvalidateItem(SID_ATTR_BRUSH_ROW);
109
0
        rSh.GetTabBackground(aBrush);
110
0
        aBrush->SetWhich(SID_ATTR_BRUSH_TABLE);
111
0
        rSet.Put( *aBrush );
112
113
0
        SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
114
0
        rSet.Put(aBoxInfo);
115
0
        rSh.GetTabBorders( rSet );
116
117
0
        std::unique_ptr<SvxFrameDirectionItem> aBoxDirection(std::make_unique<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR));
118
0
        if(rSh.GetBoxDirection( aBoxDirection ))
119
0
        {
120
0
            aBoxDirection->SetWhich(FN_TABLE_BOX_TEXTORIENTATION);
121
0
            rSet.Put(std::move(aBoxDirection));
122
0
        }
123
124
0
        rSet.Put(SfxUInt16Item(FN_TABLE_SET_VERT_ALIGN, rSh.GetBoxAlign()));
125
126
0
        rSet.Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE, rSh.GetRowsToRepeat() ) );
127
128
0
        SwFrameFormat *pFrameFormat = rSh.GetTableFormat();
129
0
        if(pFrameFormat)
130
0
        {
131
0
            rSet.Put( pFrameFormat->GetShadow() );
132
0
            rSet.Put( pFrameFormat->GetBreak() );
133
0
            rSet.Put( pFrameFormat->GetPageDesc() );
134
0
            rSet.Put( pFrameFormat->GetLayoutSplit() );
135
0
            rSet.Put( pFrameFormat->GetKeep() );
136
0
            rSet.Put( pFrameFormat->GetFrameDir() );
137
0
        }
138
139
0
        std::unique_ptr<SwFormatRowSplit> pSplit = rSh.GetRowSplit();
140
0
        if(pSplit)
141
0
            rSet.Put(std::move(pSplit));
142
0
    }
143
144
0
    SfxItemSet aBoxSet(SfxItemSet::makeFixedSfxItemSet<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT, RES_BOXATR_VALUE, RES_BOXATR_VALUE>(*rSet.GetPool()));
145
0
    rSh.GetTableBoxFormulaAttrs(aBoxSet);
146
0
    rSet.Put(aBoxSet);
147
0
}
148
149
void lcl_setTableAttributes( const SfxItemSet& rSet, SwWrtShell &rSh )
150
0
{
151
0
    bool bBorder = ( SfxItemState::SET == rSet.GetItemState( RES_BOX ) ||
152
0
            SfxItemState::SET == rSet.GetItemState( SID_ATTR_BORDER_INNER ) );
153
0
    const SvxBrushItem* pBackgroundItem = rSet.GetItemIfSet( RES_BACKGROUND, false );
154
0
    const SvxBrushItem* pRowItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_ROW, false );
155
0
    const SvxBrushItem* pTableItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_TABLE, false );
156
0
    bool bBackground = pBackgroundItem || pRowItem || pTableItem;
157
158
0
    if(bBackground)
159
0
    {
160
0
        if(pBackgroundItem)
161
0
            rSh.SetBoxBackground( *pBackgroundItem );
162
0
        if(pRowItem)
163
0
        {
164
0
            std::unique_ptr<SvxBrushItem> aBrush(pRowItem->Clone());
165
0
            aBrush->SetWhich(RES_BACKGROUND);
166
0
            rSh.SetRowBackground(*aBrush);
167
0
        }
168
0
        if(pTableItem)
169
0
        {
170
0
            std::unique_ptr<SvxBrushItem> aBrush(pTableItem->Clone());
171
0
            aBrush->SetWhich(RES_BACKGROUND);
172
0
            rSh.SetTabBackground(*aBrush);
173
0
        }
174
0
    }
175
0
    if(bBorder)
176
0
        rSh.SetTabBorders( rSet );
177
178
0
    if( const SfxUInt16Item* pHeadlineItem = rSet.GetItemIfSet( FN_PARAM_TABLE_HEADLINE, false) )
179
0
        rSh.SetRowsToRepeat( pHeadlineItem->GetValue() );
180
181
0
    SwFrameFormat* pFrameFormat = rSh.GetTableFormat();
182
0
    if(pFrameFormat)
183
0
    {
184
        //RES_SHADOW
185
0
        const SfxPoolItem* pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_SHADOW), false);
186
0
        if(pItem)
187
0
            pFrameFormat->SetFormatAttr( *pItem );
188
189
        //RES_BREAK
190
0
        pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_BREAK), false);
191
0
        if(pItem)
192
0
            pFrameFormat->SetFormatAttr( *pItem );
193
194
        //RES_PAGEDESC
195
0
        pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_PAGEDESC), false);
196
0
        if(pItem)
197
0
            pFrameFormat->SetFormatAttr( *pItem );
198
199
        //RES_LAYOUT_SPLIT
200
0
        pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_LAYOUT_SPLIT), false);
201
0
        if(pItem)
202
0
            pFrameFormat->SetFormatAttr( *pItem );
203
204
        //RES_KEEP
205
0
        pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_KEEP), false);
206
0
        if(pItem)
207
0
            pFrameFormat->SetFormatAttr( *pItem );
208
209
        //RES_FRAMEDIR
210
0
        pItem = rSet.GetItemIfSet(rSet.GetPool()->GetWhichIDFromSlotID(RES_FRAMEDIR), false);
211
0
        if(pItem)
212
0
            pFrameFormat->SetFormatAttr( *pItem );
213
0
    }
214
215
0
    if( const SvxFrameDirectionItem* pTextOriItem = rSet.GetItemIfSet( FN_TABLE_BOX_TEXTORIENTATION, false ) )
216
0
    {
217
0
        SvxFrameDirectionItem aDirection( SvxFrameDirection::Environment, RES_FRAMEDIR );
218
0
        aDirection.SetValue(pTextOriItem->GetValue());
219
0
        rSh.SetBoxDirection(aDirection);
220
0
    }
221
222
0
    if( const SfxUInt16Item* pVertAlignItem = rSet.GetItemIfSet( FN_TABLE_SET_VERT_ALIGN, false ))
223
0
        rSh.SetBoxAlign(pVertAlignItem->GetValue());
224
225
0
    if( const SwFormatRowSplit* pSplitItem = rSet.GetItemIfSet( RES_ROW_SPLIT, false ) )
226
0
        rSh.SetRowSplit(*pSplitItem);
227
228
0
    if (rSet.GetItemIfSet( RES_BOXATR_FORMAT, false ))
229
0
        rSh.SetTableBoxFormulaAttrs(rSet);
230
231
0
}
232
}//end anonymous namespace
233
234
SwFormatClipboard::SwFormatClipboard()
235
4.01k
        : m_nSelectionType(SelectionType::NONE)
236
4.01k
        , m_bPersistentCopy(false)
237
4.01k
{
238
4.01k
}
239
240
bool SwFormatClipboard::HasContent() const
241
0
{
242
0
    return m_pItemSet_TextAttr!=nullptr
243
0
        || m_pItemSet_ParAttr!=nullptr
244
0
        || m_pTableItemSet != nullptr
245
0
        || !m_aCharStyle.isEmpty()
246
0
        || !m_aParaStyle.isEmpty()
247
0
        ;
248
0
}
249
bool SwFormatClipboard::HasContentForThisType( SelectionType nSelectionType ) const
250
0
{
251
0
    if( !HasContent() )
252
0
        return false;
253
254
0
    if( m_nSelectionType == nSelectionType )
255
0
        return true;
256
257
0
    if(   ( nSelectionType   & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic) )
258
0
        &&
259
0
          ( m_nSelectionType & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic) )
260
0
        )
261
0
        return true;
262
263
0
    if( nSelectionType & SelectionType::Text && m_nSelectionType & SelectionType::Text )
264
0
        return true;
265
266
0
    return false;
267
0
}
268
269
bool SwFormatClipboard::CanCopyThisType( SelectionType nSelectionType )
270
0
{
271
0
    return bool(nSelectionType
272
0
                & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic
273
0
                   | SelectionType::Text | SelectionType::DrawObject | SelectionType::Table | SelectionType::TableCell ));
274
0
}
275
276
void SwFormatClipboard::Copy( SwWrtShell& rWrtShell, SfxItemPool& rPool, bool bPersistentCopy )
277
0
{
278
    // first clear the previously stored attributes
279
0
    Erase();
280
0
    m_bPersistentCopy = bPersistentCopy;
281
282
0
    SelectionType nSelectionType = rWrtShell.GetSelectionType();
283
0
    auto pItemSet_TextAttr = lcl_CreateEmptyItemSet( nSelectionType, rPool, true );
284
0
    auto pItemSet_ParAttr = lcl_CreateEmptyItemSet( nSelectionType, rPool );
285
286
0
    rWrtShell.StartAction();
287
0
    rWrtShell.Push();
288
289
    // modify the "Point and Mark" of the cursor
290
    // in order to select only the last character of the
291
    // selection(s) and then to get the attributes of this single character
292
0
    if( nSelectionType == SelectionType::Text )
293
0
    {
294
        // get the current PaM, the cursor
295
        // if there several selection it currently point
296
        // on the last (sort by there creation time) selection
297
0
        SwPaM* pCursor = rWrtShell.GetCursor();
298
299
0
        bool bHasSelection = pCursor->HasMark();
300
0
        bool bForwardSelection = false;
301
302
0
        if(!bHasSelection && pCursor->IsMultiSelection())
303
0
        {
304
            // if cursor has multiple selections
305
306
            // clear all the selections except the last
307
0
            rWrtShell.KillPams();
308
309
            // reset the cursor to the remaining selection
310
0
            pCursor = rWrtShell.GetCursor();
311
0
            bHasSelection = true;
312
0
        }
313
314
0
        bool dontMove = false;
315
0
        if (bHasSelection)
316
0
        {
317
0
            bForwardSelection = (*pCursor->GetPoint()) > (*pCursor->GetMark());
318
319
            // clear the selection leaving just the cursor
320
0
            pCursor->DeleteMark();
321
0
            pCursor->SetMark();
322
0
        }
323
0
        else
324
0
        {
325
0
            bool rightToLeft = rWrtShell.IsInRightToLeftText();
326
            // if there were no selection (only a cursor) and the cursor was at
327
            // the end of the paragraph then don't move
328
0
            if ( rWrtShell.IsEndPara() && !rightToLeft )
329
0
                dontMove = true;
330
331
            // revert left and right
332
0
            if ( rightToLeft )
333
0
            {
334
0
                if (pCursor->GetPoint()->GetContentIndex() == 0)
335
0
                    dontMove = true;
336
0
                else
337
0
                    bForwardSelection = !bForwardSelection;
338
0
            }
339
0
        }
340
341
        // move the cursor in order to select one character
342
0
        if (!dontMove)
343
0
            pCursor->Move( bForwardSelection ? fnMoveBackward : fnMoveForward );
344
0
    }
345
346
0
    if(pItemSet_TextAttr)
347
0
    {
348
0
        if( nSelectionType & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic) )
349
0
            rWrtShell.GetFlyFrameAttr(*pItemSet_TextAttr);
350
0
        else
351
0
        {
352
            // get the text attributes from named and automatic formatting
353
0
            rWrtShell.GetCurAttr(*pItemSet_TextAttr);
354
355
0
            if( nSelectionType & SelectionType::Text )
356
0
            {
357
                // get the paragraph attributes (could be character properties)
358
                // from named and automatic formatting
359
0
                rWrtShell.GetCurParAttr(*pItemSet_ParAttr);
360
0
            }
361
0
        }
362
0
    }
363
0
    else if ( nSelectionType & SelectionType::DrawObject )
364
0
    {
365
0
        SdrView* pDrawView = rWrtShell.GetDrawView();
366
0
        if(pDrawView)
367
0
        {
368
0
            if( pDrawView->GetMarkedObjectList().GetMarkCount() != 0 )
369
0
            {
370
0
                pItemSet_TextAttr = std::make_unique<SfxItemSet>( pDrawView->GetAttrFromMarked(true/*bOnlyHardAttr*/) );
371
                //remove attributes defining the type/data of custom shapes
372
0
                pItemSet_TextAttr->ClearItem(SDRATTR_CUSTOMSHAPE_ENGINE);
373
0
                pItemSet_TextAttr->ClearItem(SDRATTR_CUSTOMSHAPE_DATA);
374
0
                pItemSet_TextAttr->ClearItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
375
0
            }
376
0
        }
377
0
    }
378
379
0
    if(nSelectionType & (SelectionType::Table | SelectionType::TableCell))
380
0
    {
381
0
        if (nSelectionType & SelectionType::TableCell)
382
0
        {
383
            //only copy all table attributes if really cells are selected (not only text in tables)
384
0
            m_pTableItemSet = std::make_unique<SfxItemSet>(SfxItemSet::makeFixedSfxItemSet<
385
0
                RES_PAGEDESC, RES_BREAK,
386
0
                RES_BACKGROUND, RES_SHADOW, // RES_BOX is inbetween
387
0
                RES_KEEP, RES_KEEP,
388
0
                RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT,
389
0
                RES_FRAMEDIR, RES_FRAMEDIR,
390
0
                RES_ROW_SPLIT, RES_ROW_SPLIT,
391
0
                RES_BOXATR_FORMAT, RES_BOXATR_FORMAT,
392
0
                SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
393
                    // SID_ATTR_BORDER_OUTER is inbetween
394
0
                SID_ATTR_BRUSH_ROW, SID_ATTR_BRUSH_TABLE,
395
0
                FN_TABLE_SET_VERT_ALIGN, FN_TABLE_SET_VERT_ALIGN,
396
0
                FN_TABLE_BOX_TEXTORIENTATION, FN_TABLE_BOX_TEXTORIENTATION,
397
0
                FN_PARAM_TABLE_HEADLINE, FN_PARAM_TABLE_HEADLINE>(rPool));
398
0
        }
399
0
        else
400
0
        {
401
            //selection in table should copy number format
402
0
            m_pTableItemSet = std::make_unique<SfxItemSet>(SfxItemSet::makeFixedSfxItemSet<
403
0
                RES_BOXATR_FORMAT, RES_BOXATR_FORMAT>(rPool));
404
0
        }
405
406
0
        lcl_getTableAttributes( *m_pTableItemSet, rWrtShell, nSelectionType & SelectionType::TableCell ? true : false);
407
0
    }
408
409
0
    m_nSelectionType = nSelectionType;
410
0
    m_pItemSet_TextAttr = std::move(pItemSet_TextAttr);
411
0
    m_pItemSet_ParAttr = std::move(pItemSet_ParAttr);
412
413
0
    if( nSelectionType & SelectionType::Text )
414
0
    {
415
        // if text is selected save the named character format
416
0
        SwFormat* pFormat = rWrtShell.GetCurCharFormat();
417
0
        if( pFormat )
418
0
            m_aCharStyle = pFormat->GetName();
419
420
        // and the named paragraph format
421
0
        pFormat = rWrtShell.GetCurTextFormatColl();
422
0
        if( pFormat )
423
0
            m_aParaStyle = pFormat->GetName();
424
0
    }
425
426
0
    rWrtShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
427
0
    rWrtShell.EndAction();
428
0
}
429
430
typedef std::vector< std::unique_ptr< SfxPoolItem > > ItemVector;
431
// collect all PoolItems from the applied styles
432
static void lcl_AppendSetItems( ItemVector& rItemVector, const SfxItemSet& rStyleAttrSet )
433
0
{
434
0
    const WhichRangesContainer& pRanges = rStyleAttrSet.GetRanges();
435
0
    for(const auto & rPair : pRanges)
436
0
    {
437
0
        for ( sal_uInt16 nWhich = rPair.first; nWhich <= rPair.second; ++nWhich )
438
0
        {
439
0
            const SfxPoolItem* pItem;
440
0
            if( SfxItemState::SET == rStyleAttrSet.GetItemState( nWhich, false, &pItem ) )
441
0
            {
442
0
                rItemVector.emplace_back( pItem->Clone() );
443
0
            }
444
0
        }
445
0
    }
446
0
}
447
// remove all items that are inherited from the styles
448
static void lcl_RemoveEqualItems( SfxItemSet& rTemplateItemSet, const ItemVector& rItemVector )
449
0
{
450
0
    for( const auto& rItem : rItemVector )
451
0
    {
452
0
        const SfxPoolItem* pItem;
453
0
        if( SfxItemState::SET == rTemplateItemSet.GetItemState( rItem->Which(), true, &pItem ) &&
454
0
            *pItem == *rItem )
455
0
        {
456
0
            rTemplateItemSet.ClearItem( rItem->Which() );
457
0
        }
458
0
    }
459
0
}
460
461
void SwFormatClipboard::Paste( SwWrtShell& rWrtShell, SfxStyleSheetBasePool* pPool
462
                              , bool bNoCharacterFormats, bool bNoParagraphFormats )
463
0
{
464
0
    SelectionType nSelectionType = rWrtShell.GetSelectionType();
465
0
    if( !HasContentForThisType(nSelectionType) )
466
0
    {
467
0
        if(!m_bPersistentCopy)
468
0
            Erase();
469
0
        return;
470
0
    }
471
472
0
    rWrtShell.StartAction();
473
0
    rWrtShell.StartUndo(SwUndoId::INSATTR);
474
475
0
    ItemVector aItemVector;
476
477
0
    if (m_pItemSet_TextAttr && !( nSelectionType & SelectionType::DrawObject))
478
0
    {
479
        // reset all direct formatting before applying anything
480
0
        o3tl::sorted_vector<sal_uInt16> aAttrs;
481
0
        for (sal_uInt16 nWhich = RES_CHRATR_BEGIN; nWhich < RES_CHRATR_END; nWhich++)
482
0
            aAttrs.insert(nWhich);
483
0
        rWrtShell.ResetAttr({ aAttrs });
484
0
    }
485
486
0
    if( nSelectionType & SelectionType::Text )
487
0
    {
488
        // apply the named text and paragraph formatting
489
0
        if( pPool )
490
0
        {
491
            // if there is a named text format recorded and the user wants to apply it
492
0
            if(!m_aCharStyle.isEmpty() && !bNoCharacterFormats )
493
0
            {
494
                // look for the named text format in the pool
495
0
                SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>(pPool->Find(m_aCharStyle.toString(), SfxStyleFamily::Char));
496
497
                // if the style is found
498
0
                if( pStyle )
499
0
                {
500
0
                    SwFormatCharFormat aFormat(pStyle->GetCharFormat());
501
                    // store the attributes from this style in aItemVector in order
502
                    // not to apply them as automatic formatting attributes later in the code
503
0
                    lcl_AppendSetItems( aItemVector, aFormat.GetCharFormat()->GetAttrSet());
504
505
                    // apply the named format
506
0
                    rWrtShell.SetAttrItem( aFormat );
507
0
                }
508
0
            }
509
510
0
            if (!bNoParagraphFormats)
511
0
            {
512
0
                const SwNumRule* pNumRule
513
0
                    = rWrtShell.GetNumRuleAtCurrCursorPos();
514
0
                if (pNumRule && !pNumRule->IsOutlineRule())
515
0
                {
516
0
                    rWrtShell.NumOrBulletOff();
517
0
                }
518
                // if there is a named paragraph format recorded and the user wants to apply it
519
0
                if(!m_aParaStyle.isEmpty())
520
0
                {
521
                    // look for the named paragraph format in the pool
522
0
                    SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>(pPool->Find(m_aParaStyle.toString(), SfxStyleFamily::Para));
523
0
                    if( pStyle )
524
0
                    {
525
                        // store the attributes from this style in aItemVector in order
526
                        // not to apply them as automatic formatting attributes later in the code
527
0
                        lcl_AppendSetItems( aItemVector, pStyle->GetCollection()->GetAttrSet());
528
529
                        // apply the named format
530
0
                        rWrtShell.SetTextFormatColl( pStyle->GetCollection() );
531
0
                    }
532
0
                }
533
0
            }
534
0
        }
535
536
        // apply the paragraph automatic attributes
537
0
        if ( m_pItemSet_ParAttr && m_pItemSet_ParAttr->Count() != 0 && !bNoParagraphFormats )
538
0
        {
539
            // temporary SfxItemSet
540
0
            std::unique_ptr<SfxItemSet> pTemplateItemSet(lcl_CreateEmptyItemSet(
541
0
                    nSelectionType, *m_pItemSet_ParAttr->GetPool()));
542
            // no need to verify the existence of pTemplateItemSet as we
543
            // know that here the selection type is SEL_TXT
544
545
0
            pTemplateItemSet->Put( *m_pItemSet_ParAttr );
546
547
            // remove attribute that were applied by named text and paragraph formatting
548
0
            lcl_RemoveEqualItems( *pTemplateItemSet, aItemVector );
549
550
            // apply the paragraph automatic attributes to all the nodes in the selection
551
0
            rWrtShell.SetAttrSet(*pTemplateItemSet);
552
553
            // store the attributes in aItemVector in order not to apply them as
554
            // text automatic formatting attributes later in the code
555
0
            lcl_AppendSetItems( aItemVector, *pTemplateItemSet);
556
0
        }
557
0
    }
558
559
0
    if(m_pItemSet_TextAttr)
560
0
    {
561
0
        if( nSelectionType & SelectionType::DrawObject )
562
0
        {
563
0
            SdrView* pDrawView = rWrtShell.GetDrawView();
564
0
            if(pDrawView)
565
0
            {
566
0
                pDrawView->SetAttrToMarked(*m_pItemSet_TextAttr, true/*bReplaceAll*/);
567
0
            }
568
0
        }
569
0
        else
570
0
        {
571
            // temporary SfxItemSet
572
0
            std::unique_ptr<SfxItemSet> pTemplateItemSet(lcl_CreateEmptyItemSet(
573
0
                    nSelectionType, *m_pItemSet_TextAttr->GetPool(), true ));
574
575
0
            if(pTemplateItemSet)
576
0
            {
577
                // copy the stored automatic text attributes in a temporary SfxItemSet
578
0
                pTemplateItemSet->Put( *m_pItemSet_TextAttr );
579
580
                // only attributes that were not apply by named style attributes and automatic
581
                // paragraph attributes should be applied
582
0
                lcl_RemoveEqualItems( *pTemplateItemSet, aItemVector );
583
584
                // apply the character automatic attributes
585
0
                if( nSelectionType & (SelectionType::Frame | SelectionType::Ole | SelectionType::Graphic) )
586
0
                    rWrtShell.SetFlyFrameAttr(*pTemplateItemSet);
587
0
                else if ( !bNoCharacterFormats )
588
0
                {
589
0
                    rWrtShell.SetAttrSet(*pTemplateItemSet);
590
0
                }
591
0
            }
592
0
        }
593
0
    }
594
595
0
    if( m_pTableItemSet && nSelectionType & (SelectionType::Table | SelectionType::TableCell) )
596
0
        lcl_setTableAttributes( *m_pTableItemSet, rWrtShell );
597
598
0
    rWrtShell.EndUndo(SwUndoId::INSATTR);
599
0
    rWrtShell.EndAction();
600
601
0
    if(!m_bPersistentCopy)
602
0
        Erase();
603
0
}
604
605
void SwFormatClipboard::Erase()
606
0
{
607
0
    m_nSelectionType = SelectionType::NONE;
608
609
0
    m_pItemSet_TextAttr.reset();
610
611
0
    m_pItemSet_ParAttr.reset();
612
613
0
    m_pTableItemSet.reset();
614
615
0
    if( !m_aCharStyle.isEmpty() )
616
0
        m_aCharStyle = UIName();
617
0
    if( !m_aParaStyle.isEmpty() )
618
0
        m_aParaStyle = UIName();
619
620
0
    m_bPersistentCopy = false;
621
0
}
622
623
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */