Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sw/source/uibase/utlui/uitool.cxx
Line
Count
Source (jump to first uncovered line)
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 <hintids.hxx>
21
22
#include <osl/diagnose.h>
23
#include <tools/datetime.hxx>
24
#include <vcl/weld.hxx>
25
#include <unotools/collatorwrapper.hxx>
26
#include <svl/stritem.hxx>
27
#include <svl/grabbagitem.hxx>
28
#include <unotools/syslocale.hxx>
29
#include <IDocumentStylePoolAccess.hxx>
30
#include <editeng/pmdlitem.hxx>
31
#include <editeng/tstpitem.hxx>
32
#include <editeng/boxitem.hxx>
33
#include <editeng/sizeitem.hxx>
34
#include <editeng/brushitem.hxx>
35
#include <svx/pageitem.hxx>
36
#include <editeng/lrspitem.hxx>
37
#include <svl/style.hxx>
38
#include <unotools/localedatawrapper.hxx>
39
#include <com/sun/star/awt/XPopupMenu.hpp>
40
#include <com/sun/star/frame/XDispatch.hpp>
41
#include <com/sun/star/frame/XDispatchProvider.hpp>
42
#include <com/sun/star/frame/XFrame.hpp>
43
#include <com/sun/star/util/URLTransformer.hpp>
44
#include <com/sun/star/util/XURLTransformer.hpp>
45
#include <comphelper/processfactory.hxx>
46
#include <sfx2/viewfrm.hxx>
47
#include <sfx2/docfile.hxx>
48
#include <sfx2/docfilt.hxx>
49
#include <fmtornt.hxx>
50
#include <tabcol.hxx>
51
#include <fmtfsize.hxx>
52
#include <fmthdft.hxx>
53
#include <fmtpdsc.hxx>
54
#include <uiitems.hxx>
55
#include <docsh.hxx>
56
#include <wrtsh.hxx>
57
#include <swmodule.hxx>
58
#include <view.hxx>
59
#include <uitool.hxx>
60
#include <frmatr.hxx>
61
#include <paratr.hxx>
62
#include <fmtcol.hxx>
63
#include <usrpref.hxx>
64
65
#include <cmdid.h>
66
#include <doc.hxx>
67
#include <charfmt.hxx>
68
#include <SwStyleNameMapper.hxx>
69
#include <strings.hrc>
70
#include <docmodel/color/ComplexColor.hxx>
71
#include <IDocumentSettingAccess.hxx>
72
73
// 50 cm 28350
74
275k
#define MAXHEIGHT 28350
75
275k
#define MAXWIDTH  28350
76
77
using namespace ::com::sun::star;
78
79
// General list of string pointer
80
81
// Set boxinfo attribute
82
83
void PrepareBoxInfo(SfxItemSet& rSet, const SwWrtShell& rSh)
84
0
{
85
0
    std::shared_ptr<SvxBoxInfoItem> aBoxInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
86
87
0
    if ( const SvxBoxInfoItem *pBoxInfo = rSet.GetItemIfSet( SID_ATTR_BORDER_INNER ))
88
0
    {
89
0
        aBoxInfo.reset(pBoxInfo->Clone());
90
0
    }
91
92
        // Table variant: If more than one table cells are selected
93
0
    rSh.GetCursor();                  //So that GetCursorCnt() returns the right thing
94
0
    aBoxInfo->SetTable          (rSh.IsTableMode() && rSh.GetCursorCnt() > 1);
95
        // Always show the distance field
96
0
    aBoxInfo->SetDist           (true);
97
        // Set minimal size in tables and paragraphs
98
0
    aBoxInfo->SetMinDist        (rSh.IsTableMode() || rSh.GetSelectionType() & (SelectionType::Text | SelectionType::Table));
99
        // Set always the default distance
100
0
    aBoxInfo->SetDefDist        (MIN_BORDER_DIST);
101
        // Single lines can have only in tables DontCare-Status
102
0
    aBoxInfo->SetValid(SvxBoxInfoItemValidFlags::DISABLE, !rSh.IsTableMode());
103
104
0
    rSet.Put(*aBoxInfo);
105
0
}
106
107
void ConvertAttrCharToGen(SfxItemSet& rSet, bool bIsPara)
108
0
{
109
    // Background / highlight
110
0
    {
111
        // Always use the visible background
112
0
        if( const SvxBrushItem *pTmpBrush = rSet.GetItemIfSet( RES_CHRATR_HIGHLIGHT ) )
113
0
        {
114
0
            SvxBrushItem aTmpBrush( *pTmpBrush );
115
0
            if( aTmpBrush.GetColor() != COL_TRANSPARENT )
116
0
            {
117
0
                aTmpBrush.SetWhich( RES_CHRATR_BACKGROUND );
118
0
                rSet.Put( aTmpBrush );
119
0
            }
120
0
        }
121
0
    }
122
123
0
    if ( bIsPara )
124
0
        return;
125
126
    // Tell dialogs to use character-specific slots/whichIds
127
    // tdf#126684: We use RES_PARATR_GRABBAG, because RES_CHRATR_GRABBAG may be overwritten later in
128
    // SwDocStyleSheet::GetItemSet when applying attributes from char format
129
0
    assert(SfxItemState::SET != rSet.GetItemState(RES_PARATR_GRABBAG, false));
130
0
    std::map<OUString, css::uno::Any> aGrabBagMap;
131
0
    aGrabBagMap[u"DialogUseCharAttr"_ustr] <<= true;
132
    // Store initial ranges to allow restoring later
133
0
    uno::Sequence<sal_uInt16> aOrigRanges(rSet.GetRanges().size() * 2 + 1);
134
0
    int i = 0;
135
0
    for (const auto& rPair : rSet.GetRanges())
136
0
    {
137
0
        aOrigRanges.getArray()[i++] = rPair.first;
138
0
        aOrigRanges.getArray()[i++] = rPair.second;
139
0
    }
140
0
    aOrigRanges.getArray()[i++] = 0;
141
0
    aGrabBagMap[u"OrigItemSetRanges"_ustr] <<= aOrigRanges;
142
0
    rSet.MergeRange(RES_PARATR_GRABBAG, RES_PARATR_GRABBAG);
143
0
    rSet.Put(SfxGrabBagItem(RES_PARATR_GRABBAG, std::move(aGrabBagMap)));
144
0
}
145
146
void ConvertAttrGenToChar(SfxItemSet& rSet, const SfxItemSet& rOrigSet, bool bIsPara)
147
0
{
148
    // Background / highlighting
149
0
    if( SfxItemState::SET == rSet.GetItemState( RES_CHRATR_BACKGROUND, false ) )
150
0
    {
151
        // Highlight is an MS specific thing, so remove it at the first time when LO modifies
152
        // this part of the imported document.
153
0
        rSet.Put( SvxBrushItem(RES_CHRATR_HIGHLIGHT) );
154
155
        // Remove shading marker
156
0
        if (const SfxGrabBagItem* pGrabBagItem = rOrigSet.GetItemIfSet(RES_CHRATR_GRABBAG, false))
157
0
        {
158
0
            if( pGrabBagItem->GetGrabBag().count(u"CharShadingMarker"_ustr) )
159
0
            {
160
0
                std::map<OUString, css::uno::Any> aGrabBagMap = pGrabBagItem->GetGrabBag();
161
0
                aGrabBagMap[u"CharShadingMarker"_ustr] <<= false;
162
0
                rSet.Put( SfxGrabBagItem(RES_CHRATR_GRABBAG, std::move(aGrabBagMap)) );
163
0
            }
164
0
        }
165
0
    }
166
167
0
    if ( bIsPara )
168
0
        return;
169
170
0
    rSet.ClearItem( RES_BACKGROUND );
171
172
0
    if (const SfxGrabBagItem* pGrabBagItem = rOrigSet.GetItemIfSet(RES_PARATR_GRABBAG, false))
173
0
    {
174
0
        const std::map<OUString, css::uno::Any>& rMap = pGrabBagItem->GetGrabBag();
175
0
        auto aIterator = rMap.find(u"OrigItemSetRanges"_ustr);
176
0
        if (aIterator != rMap.end())
177
0
        {
178
0
            uno::Sequence<sal_uInt16> aOrigRanges;
179
0
            if ( aIterator->second >>= aOrigRanges )
180
0
            {
181
0
                assert(aOrigRanges.getLength() % 2 == 1);
182
0
                int numPairs = (aOrigRanges.getLength()-1)/2;
183
0
                std::unique_ptr<WhichPair[]> xPairs(new WhichPair[numPairs]);
184
0
                for(int i=0; i<aOrigRanges.getLength()-1; i += 2)
185
0
                {
186
0
                    xPairs[i/2] = { aOrigRanges[i], aOrigRanges[i+1] };
187
0
                }
188
0
                rSet.SetRanges(WhichRangesContainer(std::move(xPairs), numPairs));
189
0
            }
190
0
        }
191
0
    }
192
0
    assert(SfxItemState::SET != rSet.GetItemState(RES_PARATR_GRABBAG, false));
193
0
}
194
195
void ApplyCharBackground(Color const& rBackgroundColor, model::ComplexColor const& rComplexColor, SwWrtShell& rShell)
196
0
{
197
0
    rShell.StartUndo(SwUndoId::INSATTR);
198
199
0
    SfxItemSetFixed<RES_CHRATR_GRABBAG, RES_CHRATR_GRABBAG> aCoreSet(rShell.GetView().GetPool());
200
201
0
    rShell.GetCurAttr(aCoreSet);
202
203
    // Set char background
204
0
    rShell.SetAttrItem(SvxBrushItem(rBackgroundColor, rComplexColor, RES_CHRATR_BACKGROUND));
205
206
    // Highlight is an MS specific thing, so remove it at the first time when LO modifies
207
    // this part of the imported document.
208
0
    rShell.SetAttrItem(SvxBrushItem(RES_CHRATR_HIGHLIGHT));
209
210
    // Remove shading marker
211
0
    if (const SfxGrabBagItem* pGrabBagItem = aCoreSet.GetItemIfSet(RES_CHRATR_GRABBAG, false))
212
0
    {
213
0
        if (pGrabBagItem->GetGrabBag().count(u"CharShadingMarker"_ustr))
214
0
        {
215
0
            std::map<OUString, css::uno::Any> aGrabBagMap = pGrabBagItem->GetGrabBag();
216
0
            aGrabBagMap[u"CharShadingMarker"_ustr] <<= false;
217
0
            rShell.SetAttrItem(SfxGrabBagItem(RES_CHRATR_GRABBAG, std::move(aGrabBagMap)));
218
0
        }
219
0
    }
220
221
0
    rShell.EndUndo(SwUndoId::INSATTR);
222
0
}
223
224
// Fill header footer
225
226
static void FillHdFt(SwFrameFormat* pFormat, const  SfxItemSet& rSet)
227
29.7k
{
228
29.7k
    SwAttrSet aSet(pFormat->GetAttrSet());
229
29.7k
    aSet.Put(rSet);
230
231
29.7k
    const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
232
29.7k
    const SfxBoolItem& rDynamic = rSet.Get(SID_ATTR_PAGE_DYNAMIC);
233
234
    // Convert size
235
29.7k
    SwFormatFrameSize aFrameSize(rDynamic.GetValue() ? SwFrameSize::Minimum : SwFrameSize::Fixed,
236
29.7k
                            rSize.GetSize().Width(),
237
29.7k
                            rSize.GetSize().Height());
238
29.7k
    aSet.Put(aFrameSize);
239
29.7k
    pFormat->SetFormatAttr(aSet);
240
29.7k
}
241
242
/// Convert from UseOnPage to SvxPageUsage.
243
static SvxPageUsage lcl_convertUseToSvx(UseOnPage nUse)
244
275k
{
245
275k
    SvxPageUsage nRet = SvxPageUsage::NONE;
246
275k
    if (nUse & UseOnPage::Left)
247
275k
        nRet = SvxPageUsage::Left;
248
275k
    if (nUse & UseOnPage::Right)
249
275k
        nRet = SvxPageUsage::Right;
250
275k
    if ((nUse & UseOnPage::All) == UseOnPage::All)
251
275k
        nRet = SvxPageUsage::All;
252
275k
    if ((nUse & UseOnPage::Mirror) == UseOnPage::Mirror)
253
127
        nRet = SvxPageUsage::Mirror;
254
275k
    return nRet;
255
275k
}
256
257
/// Convert from SvxPageUsage to UseOnPage.
258
static UseOnPage lcl_convertUseFromSvx(SvxPageUsage nUse)
259
143k
{
260
143k
    UseOnPage nRet = UseOnPage::NONE;
261
143k
    if (nUse == SvxPageUsage::Left)
262
198
        nRet = UseOnPage::Left;
263
143k
    else if (nUse == SvxPageUsage::Right)
264
211
        nRet = UseOnPage::Right;
265
142k
    else if (nUse == SvxPageUsage::All)
266
142k
        nRet = UseOnPage::All;
267
142
    else if (nUse == SvxPageUsage::Mirror)
268
142
        nRet = UseOnPage::Mirror;
269
143k
    return nRet;
270
143k
}
271
272
// PageDesc <-> convert into sets and back
273
274
void ItemSetToPageDesc( const SfxItemSet& rSet, SwPageDesc& rPageDesc )
275
143k
{
276
143k
    SwFrameFormat& rMaster = rPageDesc.GetMaster();
277
143k
    bool bFirstShare = false;
278
279
    // before SetFormatAttr() in case it contains RES_BACKGROUND_FULL_SIZE
280
    // itself, as it does when called from SwXPageStyle
281
143k
    if (const SfxGrabBagItem* pGrabBag = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
282
143k
    {
283
143k
        bool bValue;
284
143k
        const auto& rGrabBagInner = pGrabBag->GetGrabBag();
285
143k
        const auto iter = rGrabBagInner.find(u"BackgroundFullSize"_ustr);
286
143k
        assert(iter != rGrabBagInner.end());
287
143k
        if (iter->second >>= bValue)
288
143k
        {
289
143k
            rMaster.SetFormatAttr(SfxBoolItem(RES_BACKGROUND_FULL_SIZE, bValue));
290
143k
        }
291
143k
        auto it = rGrabBagInner.find(u"RtlGutter"_ustr);
292
143k
        if (it != rGrabBagInner.end() && (it->second >>= bValue))
293
0
        {
294
0
            rMaster.SetFormatAttr(SfxBoolItem(RES_RTL_GUTTER, bValue));
295
0
        }
296
143k
    }
297
298
    // Transfer all general frame attributes
299
143k
    rMaster.SetFormatAttr(rSet);
300
301
    // PageData
302
143k
    if(rSet.GetItemState(SID_ATTR_PAGE) == SfxItemState::SET)
303
143k
    {
304
143k
        const SvxPageItem& rPageItem = rSet.Get(SID_ATTR_PAGE);
305
306
143k
        const SvxPageUsage nUse = rPageItem.GetPageUsage();
307
143k
        if(nUse != SvxPageUsage::NONE)
308
143k
            rPageDesc.SetUseOn( lcl_convertUseFromSvx(nUse) );
309
143k
        rPageDesc.SetLandscape(rPageItem.IsLandscape());
310
143k
        SvxNumberType aNumType;
311
143k
        aNumType.SetNumberingType( rPageItem.GetNumType() );
312
143k
        rPageDesc.SetNumType(aNumType);
313
143k
    }
314
    // Size
315
143k
    if(rSet.GetItemState(SID_ATTR_PAGE_SIZE) == SfxItemState::SET)
316
143k
    {
317
143k
        const SvxSizeItem& rSizeItem = rSet.Get(SID_ATTR_PAGE_SIZE);
318
143k
        SwFormatFrameSize aSize(SwFrameSize::Fixed);
319
143k
        aSize.SetSize(rSizeItem.GetSize());
320
143k
        rMaster.SetFormatAttr(aSize);
321
143k
    }
322
    // Evaluate header attributes
323
143k
    if( const SvxSetItem* pHeaderSetItem = rSet.GetItemIfSet( SID_ATTR_PAGE_HEADERSET,
324
143k
            false ) )
325
16.8k
    {
326
16.8k
        const SfxItemSet& rHeaderSet = pHeaderSetItem->GetItemSet();
327
16.8k
        const SfxBoolItem& rHeaderOn = rHeaderSet.Get(SID_ATTR_PAGE_ON);
328
329
16.8k
        if(rHeaderOn.GetValue())
330
16.8k
        {
331
            // Take over values
332
16.8k
            if(!rMaster.GetHeader().IsActive())
333
4.45k
                rMaster.SetFormatAttr(SwFormatHeader(true));
334
335
            // Pick out everything and adapt the header format
336
16.8k
            SwFormatHeader aHeaderFormat(rMaster.GetHeader());
337
16.8k
            SwFrameFormat *pHeaderFormat = aHeaderFormat.GetHeaderFormat();
338
16.8k
            OSL_ENSURE(pHeaderFormat != nullptr, "no header format");
339
340
16.8k
            ::FillHdFt(pHeaderFormat, rHeaderSet);
341
342
16.8k
            rPageDesc.ChgHeaderShare(rHeaderSet.Get(SID_ATTR_PAGE_SHARED).GetValue());
343
16.8k
            rPageDesc.ChgFirstShare(static_cast<const SfxBoolItem&>(
344
16.8k
                            rHeaderSet.Get(SID_ATTR_PAGE_SHARED_FIRST)).GetValue());
345
16.8k
            bFirstShare = true;
346
16.8k
        }
347
38
        else
348
38
        {
349
            // Disable header
350
38
            if(rMaster.GetHeader().IsActive())
351
38
            {
352
38
                rMaster.SetFormatAttr(SwFormatHeader(false));
353
38
                rPageDesc.ChgHeaderShare(false);
354
38
            }
355
38
        }
356
16.8k
    }
357
358
    // Evaluate footer attributes
359
143k
    if( const SvxSetItem* pFooterSetItem = rSet.GetItemIfSet( SID_ATTR_PAGE_FOOTERSET,
360
143k
            false ) )
361
12.9k
    {
362
12.9k
        const SfxItemSet& rFooterSet = pFooterSetItem->GetItemSet();
363
12.9k
        const SfxBoolItem& rFooterOn = rFooterSet.Get(SID_ATTR_PAGE_ON);
364
365
12.9k
        if(rFooterOn.GetValue())
366
12.9k
        {
367
            // Take over values
368
12.9k
            if(!rMaster.GetFooter().IsActive())
369
1.57k
                rMaster.SetFormatAttr(SwFormatFooter(true));
370
371
            // Pick out everything and adapt the footer format
372
12.9k
            SwFormatFooter aFooterFormat(rMaster.GetFooter());
373
12.9k
            SwFrameFormat *pFooterFormat = aFooterFormat.GetFooterFormat();
374
12.9k
            OSL_ENSURE(pFooterFormat != nullptr, "no footer format");
375
376
12.9k
            ::FillHdFt(pFooterFormat, rFooterSet);
377
378
12.9k
            rPageDesc.ChgFooterShare(rFooterSet.Get(SID_ATTR_PAGE_SHARED).GetValue());
379
12.9k
            if (!bFirstShare)
380
5.37k
            {
381
5.37k
                rPageDesc.ChgFirstShare(static_cast<const SfxBoolItem&>(
382
5.37k
                            rFooterSet.Get(SID_ATTR_PAGE_SHARED_FIRST)).GetValue());
383
5.37k
            }
384
12.9k
        }
385
0
        else
386
0
        {
387
            // Disable footer
388
0
            if(rMaster.GetFooter().IsActive())
389
0
            {
390
0
                rMaster.SetFormatAttr(SwFormatFooter(false));
391
                // why reset this? but not doing it causes testTdf112694 to fail
392
0
                rPageDesc.ChgFooterShare(false);
393
0
            }
394
0
        }
395
12.9k
    }
396
397
    // Footnotes
398
399
143k
    if( const SwPageFootnoteInfoItem* pFootnoteItem = rSet.GetItemIfSet( FN_PARAM_FTN_INFO,
400
143k
            false ) )
401
143k
        rPageDesc.SetFootnoteInfo( pFootnoteItem->GetPageFootnoteInfo() );
402
403
    // Columns
404
405
    // Register compliant
406
407
143k
    const SfxBoolItem* pRegisterModeItem = rSet.GetItemIfSet(
408
143k
                            SID_SWREGISTER_MODE, false);
409
143k
    if(!pRegisterModeItem)
410
0
        return;
411
412
143k
    bool bSet = pRegisterModeItem->GetValue();
413
143k
    if(!bSet)
414
143k
        rPageDesc.SetRegisterFormatColl(nullptr);
415
0
    else if(const SfxStringItem* pCollectionItem = rSet.GetItemIfSet(
416
0
                            SID_SWREGISTER_COLLECTION, false))
417
0
    {
418
0
        const OUString& rColl = pCollectionItem->GetValue();
419
0
        SwDoc& rDoc = rMaster.GetDoc();
420
0
        SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( UIName(rColl) );
421
0
        if( !pColl )
422
0
        {
423
0
            const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
424
0
                UIName(rColl), SwGetPoolIdFromName::TxtColl );
425
0
            if( USHRT_MAX != nId )
426
0
                pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
427
0
            else
428
0
                pColl = rDoc.MakeTextFormatColl( UIName(rColl),
429
0
                            rDoc.GetDfltTextFormatColl() );
430
0
        }
431
0
        if( pColl )
432
0
            pColl->SetFormatAttr( SwRegisterItem ( true ));
433
0
        rPageDesc.SetRegisterFormatColl( pColl );
434
0
    }
435
143k
}
436
437
namespace
438
{
439
bool IsOwnFormat(const SwDoc& rDoc)
440
275k
{
441
275k
    const SwDocShell* pDocShell = rDoc.GetDocShell();
442
275k
    if (!pDocShell)
443
0
        return false;
444
445
275k
    SfxMedium* pMedium = pDocShell->GetMedium();
446
275k
    if (!pMedium)
447
0
    {
448
0
        return false;
449
0
    }
450
451
275k
    std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
452
275k
    if (!pFilter)
453
275k
    {
454
275k
        return false;
455
275k
    }
456
457
0
    return pFilter->IsOwnFormat();
458
275k
}
459
}
460
461
void PageDescToItemSet( const SwPageDesc& rPageDesc, SfxItemSet& rSet)
462
275k
{
463
275k
    const SwFrameFormat& rMaster = rPageDesc.GetMaster();
464
465
    // Page data
466
275k
    SvxPageItem aPageItem(SID_ATTR_PAGE);
467
275k
    aPageItem.SetDescName(rPageDesc.GetName().toString());
468
275k
    aPageItem.SetPageUsage(lcl_convertUseToSvx(rPageDesc.GetUseOn()));
469
275k
    aPageItem.SetLandscape(rPageDesc.GetLandscape());
470
275k
    aPageItem.SetNumType(rPageDesc.GetNumType().GetNumberingType());
471
275k
    rSet.Put(aPageItem);
472
473
    // Size
474
275k
    SvxSizeItem aSizeItem(SID_ATTR_PAGE_SIZE, rMaster.GetFrameSize().GetSize());
475
275k
    rSet.Put(aSizeItem);
476
477
    // Maximum size
478
275k
    SvxSizeItem aMaxSizeItem(SID_ATTR_PAGE_MAXSIZE, Size(MAXWIDTH, MAXHEIGHT));
479
275k
    rSet.Put(aMaxSizeItem);
480
481
    // Margins, border and the other stuff.
482
275k
    rSet.Put(rMaster.GetAttrSet());
483
484
275k
    std::shared_ptr<SvxBoxInfoItem> aBoxInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
485
486
275k
    if ( const SvxBoxInfoItem *pBoxInfo = rSet.GetItemIfSet( SID_ATTR_BORDER_INNER ) )
487
20.8k
    {
488
20.8k
        aBoxInfo.reset(pBoxInfo->Clone());
489
20.8k
    }
490
491
275k
    aBoxInfo->SetTable( false );
492
        // Show always the distance field
493
275k
    aBoxInfo->SetDist( true);
494
        // Set minimal size in tables and paragraphs
495
275k
    aBoxInfo->SetMinDist( false );
496
        // Set always the default distance
497
275k
    aBoxInfo->SetDefDist( MIN_BORDER_DIST );
498
        // Single lines can have only in tables DontCare-Status
499
275k
    aBoxInfo->SetValid( SvxBoxInfoItemValidFlags::DISABLE );
500
275k
    rSet.Put( *aBoxInfo );
501
502
275k
    SfxStringItem aFollow(SID_ATTR_PAGE_EXT1, OUString());
503
275k
    if(rPageDesc.GetFollow())
504
275k
        aFollow.SetValue(rPageDesc.GetFollow()->GetName().toString());
505
275k
    rSet.Put(aFollow);
506
507
    // Header
508
275k
    if(rMaster.GetHeader().IsActive())
509
37.3k
    {
510
37.3k
        const SwFormatHeader &rHeaderFormat = rMaster.GetHeader();
511
37.3k
        const SwFrameFormat *pHeaderFormat = rHeaderFormat.GetHeaderFormat();
512
37.3k
        assert(pHeaderFormat && "no header format");
513
514
        // HeaderInfo, margins, background, border
515
37.3k
        SfxItemSetFixed<RES_FRMATR_BEGIN,RES_FRMATR_END - 1,            // [82
516
517
            // FillAttribute support
518
37.3k
            XATTR_FILL_FIRST, XATTR_FILL_LAST,              // [1014
519
520
37.3k
            SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER,    // [10023
521
37.3k
            SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE,          // [10051
522
37.3k
            SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED,          // [10060
523
37.3k
            SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST>  aHeaderSet(*rSet.GetPool());
524
525
        // set correct parent to get the XFILL_NONE FillStyle as needed
526
37.3k
        aHeaderSet.SetParent(&rMaster.GetDoc().GetDfltFrameFormat()->GetAttrSet());
527
528
        // Dynamic or fixed height
529
37.3k
        SfxBoolItem aOn(SID_ATTR_PAGE_ON, true);
530
37.3k
        aHeaderSet.Put(aOn);
531
532
37.3k
        const SwFormatFrameSize &rFrameSize = pHeaderFormat->GetFrameSize();
533
37.3k
        const SwFrameSize eSizeType = rFrameSize.GetHeightSizeType();
534
37.3k
        SfxBoolItem aDynamic(SID_ATTR_PAGE_DYNAMIC, eSizeType != SwFrameSize::Fixed);
535
37.3k
        aHeaderSet.Put(aDynamic);
536
537
        // Left equal right
538
37.3k
        SfxBoolItem aShared(SID_ATTR_PAGE_SHARED, rPageDesc.IsHeaderShared());
539
37.3k
        aHeaderSet.Put(aShared);
540
37.3k
        SfxBoolItem aFirstShared(SID_ATTR_PAGE_SHARED_FIRST, rPageDesc.IsFirstShared());
541
37.3k
        aHeaderSet.Put(aFirstShared);
542
543
        // Size
544
37.3k
        SvxSizeItem aSize(SID_ATTR_PAGE_SIZE, rFrameSize.GetSize());
545
37.3k
        aHeaderSet.Put(aSize);
546
547
        // Shifting frame attributes
548
37.3k
        aHeaderSet.Put(pHeaderFormat->GetAttrSet());
549
37.3k
        aHeaderSet.Put( *aBoxInfo );
550
551
        // Create SetItem
552
37.3k
        SvxSetItem aSetItem(SID_ATTR_PAGE_HEADERSET, aHeaderSet);
553
37.3k
        rSet.Put(aSetItem);
554
37.3k
    }
555
556
    // Footer
557
275k
    if(rMaster.GetFooter().IsActive())
558
29.9k
    {
559
29.9k
        const SwFormatFooter &rFooterFormat = rMaster.GetFooter();
560
29.9k
        const SwFrameFormat *pFooterFormat = rFooterFormat.GetFooterFormat();
561
29.9k
        assert(pFooterFormat && "no footer format");
562
563
        // FooterInfo, margins, background, border
564
29.9k
        SfxItemSetFixed<RES_FRMATR_BEGIN,RES_FRMATR_END - 1,            // [82
565
566
            // FillAttribute support
567
29.9k
            XATTR_FILL_FIRST, XATTR_FILL_LAST,              // [1014
568
569
29.9k
            SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER,    // [10023
570
29.9k
            SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE,          // [10051
571
29.9k
            SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED,          // [10060
572
29.9k
            SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST>  aFooterSet(*rSet.GetPool());
573
574
        // set correct parent to get the XFILL_NONE FillStyle as needed
575
29.9k
        aFooterSet.SetParent(&rMaster.GetDoc().GetDfltFrameFormat()->GetAttrSet());
576
577
        // Dynamic or fixed height
578
29.9k
        SfxBoolItem aOn(SID_ATTR_PAGE_ON, true);
579
29.9k
        aFooterSet.Put(aOn);
580
581
29.9k
        const SwFormatFrameSize &rFrameSize = pFooterFormat->GetFrameSize();
582
29.9k
        const SwFrameSize eSizeType = rFrameSize.GetHeightSizeType();
583
29.9k
        SfxBoolItem aDynamic(SID_ATTR_PAGE_DYNAMIC, eSizeType != SwFrameSize::Fixed);
584
29.9k
        aFooterSet.Put(aDynamic);
585
586
        // Left equal right
587
29.9k
        SfxBoolItem aShared(SID_ATTR_PAGE_SHARED, rPageDesc.IsFooterShared());
588
29.9k
        aFooterSet.Put(aShared);
589
29.9k
        SfxBoolItem aFirstShared(SID_ATTR_PAGE_SHARED_FIRST, rPageDesc.IsFirstShared());
590
29.9k
        aFooterSet.Put(aFirstShared);
591
592
        // Size
593
29.9k
        SvxSizeItem aSize(SID_ATTR_PAGE_SIZE, rFrameSize.GetSize());
594
29.9k
        aFooterSet.Put(aSize);
595
596
        // Shifting Frame attributes
597
29.9k
        aFooterSet.Put(pFooterFormat->GetAttrSet());
598
29.9k
        aFooterSet.Put( *aBoxInfo );
599
600
        // Create SetItem
601
29.9k
        SvxSetItem aSetItem(SID_ATTR_PAGE_FOOTERSET, aFooterSet);
602
29.9k
        rSet.Put(aSetItem);
603
29.9k
    }
604
605
    // Integrate footnotes
606
275k
    SwPageFootnoteInfo& rInfo = const_cast<SwPageFootnoteInfo&>(rPageDesc.GetFootnoteInfo());
607
275k
    SwPageFootnoteInfoItem aFootnoteItem(rInfo);
608
275k
    rSet.Put(aFootnoteItem);
609
610
    // Register compliant
611
275k
    const SwTextFormatColl* pCol = rPageDesc.GetRegisterFormatColl();
612
275k
    SwRegisterItem aReg(pCol != nullptr);
613
275k
    aReg.SetWhich(SID_SWREGISTER_MODE);
614
275k
    rSet.Put(aReg);
615
275k
    if(pCol)
616
0
        rSet.Put(SfxStringItem(SID_SWREGISTER_COLLECTION, pCol->GetName().toString()));
617
618
275k
    std::map<OUString, css::uno::Any> aGrabBagMap;
619
275k
    if (SfxGrabBagItem const* pItem = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
620
20.8k
        aGrabBagMap = pItem->GetGrabBag();
621
275k
    aGrabBagMap[u"BackgroundFullSize"_ustr] <<=
622
275k
        rMaster.GetAttrSet().GetItem<SfxBoolItem>(RES_BACKGROUND_FULL_SIZE)->GetValue();
623
624
275k
    if (IsOwnFormat(rMaster.GetDoc()))
625
0
    {
626
0
        aGrabBagMap[u"RtlGutter"_ustr]
627
0
            <<= rMaster.GetAttrSet().GetItem<SfxBoolItem>(RES_RTL_GUTTER)->GetValue();
628
0
    }
629
630
275k
    const IDocumentSettingAccess& rIDSA = rMaster.getIDocumentSettingAccess();
631
275k
    if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
632
70.9k
    {
633
70.9k
        aGrabBagMap[u"ContinuousEndnotes"_ustr] <<= true;
634
70.9k
    }
635
636
275k
    rSet.Put(SfxGrabBagItem(SID_ATTR_CHAR_GRABBAG, std::move(aGrabBagMap)));
637
275k
}
638
639
// Set DefaultTabs
640
641
void MakeDefTabs(SwTwips nDefDist, SvxTabStopItem& rTabs)
642
0
{
643
0
    if( rTabs.Count() )
644
0
        return;
645
0
    {
646
0
        SvxTabStop aSwTabStop( nDefDist, SvxTabAdjust::Default );
647
0
        rTabs.Insert( aSwTabStop );
648
0
    }
649
0
}
650
651
// Distance between two tabs
652
653
SwTwips GetTabDist(const SvxTabStopItem& rTabs)
654
0
{
655
0
    return rTabs.Count() ? rTabs[0].GetTabPos() : 1134; // 1134 = 2 cm
656
0
}
657
658
// Inquire if in the set is a Sfx-PageDesc combination present and return it.
659
void SfxToSwPageDescAttr( const SwWrtShell& rShell, SfxItemSet& rSet )
660
0
{
661
0
    const SfxPoolItem* pItem;
662
0
    SwFormatPageDesc aPgDesc;
663
664
0
    bool bChanged = false;
665
0
    bool bRemoveNumOffset = false;
666
    // Page number
667
0
    switch (rSet.GetItemState(SID_ATTR_PARA_PAGENUM, false, &pItem))
668
0
    {
669
0
        case SfxItemState::SET:
670
0
        {
671
0
            aPgDesc.SetNumOffset(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
672
0
            bChanged = true;
673
0
            break;
674
0
        }
675
0
        case SfxItemState::DISABLED:
676
0
        {
677
0
            bChanged = true; // default initialised aPgDesc clears the number
678
0
            break;
679
0
        }
680
0
        case SfxItemState::UNKNOWN:
681
0
        case SfxItemState::DEFAULT:
682
0
            bRemoveNumOffset = true;
683
0
            break;
684
0
        default:
685
0
            assert(false); // unexpected
686
0
            break;
687
0
    }
688
0
    if( const SvxPageModelItem* pModelItem = rSet.GetItemIfSet( SID_ATTR_PARA_MODEL, false ))
689
0
    {
690
0
        const OUString& rDescName = pModelItem->GetValue();
691
0
        if( !rDescName.isEmpty() )   // No name -> disable PageDesc!
692
0
        {
693
            // Delete only, if PageDesc will be enabled!
694
0
            rSet.ClearItem( RES_BREAK );
695
0
            SwPageDesc* pDesc = const_cast<SwWrtShell&>(rShell).FindPageDescByName(
696
0
                                                    UIName(rDescName), true );
697
0
            if( pDesc )
698
0
                aPgDesc.RegisterToPageDesc( *pDesc );
699
0
        }
700
0
        rSet.ClearItem( SID_ATTR_PARA_MODEL );
701
0
        bChanged = true;
702
0
    }
703
0
    else
704
0
    {
705
0
        SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aCoreSet(rShell.GetView().GetPool());
706
0
        rShell.GetCurAttr( aCoreSet );
707
0
        if(const SwFormatPageDesc* pPageDescItem = aCoreSet.GetItemIfSet( RES_PAGEDESC ) )
708
0
        {
709
0
            const SwPageDesc* pPageDesc = pPageDescItem->GetPageDesc();
710
0
            if (bRemoveNumOffset && pPageDescItem->GetNumOffset())
711
0
                bChanged = true;
712
0
            if( pPageDesc )
713
0
            {
714
0
                aPgDesc.RegisterToPageDesc( *const_cast<SwPageDesc*>(pPageDesc) );
715
0
            }
716
0
        }
717
0
    }
718
0
    if(bChanged)
719
0
        rSet.Put( aPgDesc );
720
0
}
721
722
// Inquire if in the set is a Sfx-PageDesc combination present and return it.
723
void SwToSfxPageDescAttr( SfxItemSet& rCoreSet )
724
0
{
725
0
    const SwFormatPageDesc* pPageDescItem = nullptr;
726
0
    UIName aName;
727
0
    ::std::optional<sal_uInt16> oNumOffset;
728
0
    bool bPut = true;
729
0
    switch( rCoreSet.GetItemState( RES_PAGEDESC, true, &pPageDescItem ) )
730
0
    {
731
0
    case SfxItemState::SET:
732
0
        {
733
0
            if( pPageDescItem->GetPageDesc() )
734
0
            {
735
0
                aName = pPageDescItem->GetPageDesc()->GetName();
736
0
                oNumOffset = pPageDescItem->GetNumOffset();
737
0
            }
738
0
            rCoreSet.ClearItem( RES_PAGEDESC );
739
            // Page number
740
0
        }
741
0
        break;
742
743
0
    case SfxItemState::DEFAULT:
744
0
        break;
745
746
0
    default:
747
0
        bPut = false;
748
0
    }
749
750
0
    if (oNumOffset)
751
0
    {
752
0
        SfxUInt16Item aPageNum( SID_ATTR_PARA_PAGENUM, *oNumOffset );
753
0
        rCoreSet.Put( aPageNum );
754
0
    }
755
756
0
    if(bPut)
757
0
        rCoreSet.Put( SvxPageModelItem( aName.toString(), true, SID_ATTR_PARA_MODEL ) );
758
0
}
759
760
// Determine metric
761
762
FieldUnit   GetDfltMetric(bool bWeb)
763
0
{
764
0
    return SwModule::get()->GetUsrPref(bWeb)->GetMetric();
765
0
}
766
767
// Determine metric
768
769
void    SetDfltMetric( FieldUnit eMetric, bool bWeb )
770
0
{
771
0
    SwModule::get()->ApplyUserMetric(eMetric, bWeb);
772
0
}
773
774
void InsertStringSorted(const OUString& rId, const OUString& rEntry, weld::ComboBox& rToFill, int nOffset)
775
0
{
776
0
    CollatorWrapper& rCaseColl = ::GetAppCaseCollator();
777
0
    const int nCount = rToFill.get_count();
778
0
    while (nOffset < nCount)
779
0
    {
780
0
        if (0 < rCaseColl.compareString(rToFill.get_text(nOffset), rEntry))
781
0
            break;
782
0
        ++nOffset;
783
0
    }
784
0
    rToFill.insert(nOffset, rEntry, &rId, nullptr, nullptr);
785
0
}
786
787
void FillCharStyleListBox(weld::ComboBox& rToFill, SwDocShell* pDocSh, bool bSorted, bool bWithDefault)
788
0
{
789
0
    const int nOffset = rToFill.get_count() > 0 ? 1 : 0;
790
0
    rToFill.freeze();
791
0
    SfxStyleSheetBasePool* pPool = pDocSh->GetStyleSheetPool();
792
0
    SwDoc* pDoc = pDocSh->GetDoc();
793
0
    const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Char);
794
0
    const OUString sStandard(SwResId(STR_POOLCHR_STANDARD));
795
0
    while(pBase)
796
0
    {
797
0
        if(bWithDefault || pBase->GetName() !=  sStandard)
798
0
        {
799
0
            sal_IntPtr nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( UIName(pBase->GetName()), SwGetPoolIdFromName::ChrFmt );
800
0
            OUString sId(OUString::number(nPoolId));
801
0
            if (bSorted)
802
0
                InsertStringSorted(sId, pBase->GetName(), rToFill, nOffset);
803
0
            else
804
0
                rToFill.append(sId, pBase->GetName());
805
0
        }
806
0
        pBase = pPool->Next();
807
0
    }
808
    // non-pool styles
809
0
    for(const auto pFormat : *pDoc->GetCharFormats())
810
0
    {
811
0
        if(pFormat->IsDefault())
812
0
            continue;
813
0
        const UIName& rName = pFormat->GetName();
814
0
        if (rToFill.find_text(rName.toString()) == -1)
815
0
        {
816
0
            OUString sId(OUString::number(USHRT_MAX));
817
0
            if (bSorted)
818
0
                InsertStringSorted(sId, rName.toString(), rToFill, nOffset);
819
0
            else
820
0
                rToFill.append(sId, rName.toString());
821
0
        }
822
0
    }
823
0
    rToFill.thaw();
824
0
};
825
826
SwTwips GetTableWidth( SwFrameFormat const * pFormat, SwTabCols const & rCols, sal_uInt16 *pPercent,
827
            SwWrtShell* pSh )
828
0
{
829
    // To get the width is slightly more complicated.
830
0
    SwTwips nWidth = 0;
831
0
    const sal_Int16 eOri = pFormat->GetHoriOrient().GetHoriOrient();
832
0
    switch(eOri)
833
0
    {
834
0
        case text::HoriOrientation::FULL: nWidth = rCols.GetRight(); break;
835
0
        case text::HoriOrientation::LEFT_AND_WIDTH:
836
0
        case text::HoriOrientation::LEFT:
837
0
        case text::HoriOrientation::RIGHT:
838
0
        case text::HoriOrientation::CENTER:
839
0
            nWidth = pFormat->GetFrameSize().GetWidth();
840
0
        break;
841
0
        default:
842
0
        {
843
0
            if(pSh)
844
0
            {
845
0
                if ( nullptr == pSh->GetFlyFrameFormat() )
846
0
                {
847
0
                    nWidth = pSh->GetAnyCurRect(CurRectType::PagePrt).Width();
848
0
                }
849
0
                else
850
0
                {
851
0
                    nWidth = pSh->GetAnyCurRect(CurRectType::FlyEmbeddedPrt).Width();
852
0
                }
853
0
            }
854
0
            else
855
0
            {
856
0
                OSL_FAIL("where to get the actual width from?");
857
0
            }
858
0
            const SvxLRSpaceItem& rLRSpace = pFormat->GetLRSpace();
859
0
            nWidth -= (rLRSpace.ResolveRight({}) + rLRSpace.ResolveLeft({}));
860
0
        }
861
0
    }
862
0
    if (pPercent)
863
0
        *pPercent = pFormat->GetFrameSize().GetWidthPercent();
864
0
    return nWidth;
865
0
}
866
867
OUString GetAppLangDateTimeString( const DateTime& rDT )
868
0
{
869
0
    const SvtSysLocale aSysLocale;
870
0
    const LocaleDataWrapper& rAppLclData = aSysLocale.GetLocaleData();
871
0
    OUString sRet = rAppLclData.getDate( rDT ) + " " + rAppLclData.getTime( rDT );
872
0
    return sRet;
873
0
}
874
875
// Add a new function which can get and set the current "SID_ATTR_APPLYCHARUNIT" value
876
877
bool HasCharUnit( bool bWeb)
878
0
{
879
0
    return SwModule::get()->GetUsrPref(bWeb)->IsApplyCharUnit();
880
0
}
881
882
void SetApplyCharUnit(bool bApplyChar, bool bWeb)
883
0
{
884
0
    SwModule::get()->ApplyUserCharUnit(bApplyChar, bWeb);
885
0
}
886
887
bool ExecuteMenuCommand(const css::uno::Reference<css::awt::XPopupMenu>& rMenu, const SfxViewFrame& rViewFrame, sal_uInt16 nId)
888
0
{
889
0
    bool bRet = false;
890
0
    const sal_uInt16 nItemCount = rMenu->getItemCount();
891
0
    OUString sCommand;
892
0
    for (sal_uInt16 nItem = 0; nItem < nItemCount; ++nItem)
893
0
    {
894
0
        sal_Int16 nItemId = rMenu->getItemId(nItem);
895
0
        css::uno::Reference<css::awt::XPopupMenu> xPopup = rMenu->getPopupMenu(nItemId);
896
0
        if (xPopup.is())
897
0
        {
898
0
            sCommand = xPopup->getCommand(nId);
899
0
            if(!sCommand.isEmpty())
900
0
                break;
901
0
        }
902
0
    }
903
0
    if(!sCommand.isEmpty())
904
0
    {
905
0
        uno::Reference< frame::XFrame >  xFrame = rViewFrame.GetFrame().GetFrameInterface();
906
0
        uno::Reference < frame::XDispatchProvider > xProv( xFrame, uno::UNO_QUERY );
907
0
        util::URL aURL;
908
0
        aURL.Complete = sCommand;
909
0
        uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create(::comphelper::getProcessComponentContext() ) );
910
0
        xTrans->parseStrict( aURL );
911
0
        uno::Reference< frame::XDispatch >  xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
912
0
        if( xDisp.is() )
913
0
        {
914
0
            uno::Sequence< beans::PropertyValue > aSeq;
915
0
            xDisp->dispatch( aURL, aSeq );
916
0
            bRet = true;
917
0
        }
918
0
    }
919
0
    return bRet;
920
0
}
921
922
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */