docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / sw / source / uibase / utlui / uitool.cxx
blob64b15924a168e4adeed647a7a7d8927491c6baef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
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>
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>
73 // 50 cm 28350
74 #define MAXHEIGHT 28350
75 #define MAXWIDTH 28350
77 using namespace ::com::sun::star;
79 // General list of string pointer
81 // Set boxinfo attribute
83 void PrepareBoxInfo(SfxItemSet& rSet, const SwWrtShell& rSh)
85 std::shared_ptr<SvxBoxInfoItem> aBoxInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
87 if ( const SvxBoxInfoItem *pBoxInfo = rSet.GetItemIfSet( SID_ATTR_BORDER_INNER ))
89 aBoxInfo.reset(pBoxInfo->Clone());
92 // Table variant: If more than one table cells are selected
93 rSh.GetCursor(); //So that GetCursorCnt() returns the right thing
94 aBoxInfo->SetTable (rSh.IsTableMode() && rSh.GetCursorCnt() > 1);
95 // Always show the distance field
96 aBoxInfo->SetDist (true);
97 // Set minimal size in tables and paragraphs
98 aBoxInfo->SetMinDist (rSh.IsTableMode() || rSh.GetSelectionType() & (SelectionType::Text | SelectionType::Table));
99 // Set always the default distance
100 aBoxInfo->SetDefDist (MIN_BORDER_DIST);
101 // Single lines can have only in tables DontCare-Status
102 aBoxInfo->SetValid(SvxBoxInfoItemValidFlags::DISABLE, !rSh.IsTableMode());
104 rSet.Put(*aBoxInfo);
107 void ConvertAttrCharToGen(SfxItemSet& rSet, bool bIsPara)
109 // Background / highlight
111 // Always use the visible background
112 if( const SvxBrushItem *pTmpBrush = rSet.GetItemIfSet( RES_CHRATR_HIGHLIGHT ) )
114 SvxBrushItem aTmpBrush( *pTmpBrush );
115 if( aTmpBrush.GetColor() != COL_TRANSPARENT )
117 aTmpBrush.SetWhich( RES_CHRATR_BACKGROUND );
118 rSet.Put( aTmpBrush );
123 if ( bIsPara )
124 return;
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 assert(SfxItemState::SET != rSet.GetItemState(RES_PARATR_GRABBAG, false));
130 std::map<OUString, css::uno::Any> aGrabBagMap;
131 aGrabBagMap[u"DialogUseCharAttr"_ustr] <<= true;
132 // Store initial ranges to allow restoring later
133 uno::Sequence<sal_uInt16> aOrigRanges(rSet.GetRanges().size() * 2 + 1);
134 int i = 0;
135 for (const auto& rPair : rSet.GetRanges())
137 aOrigRanges.getArray()[i++] = rPair.first;
138 aOrigRanges.getArray()[i++] = rPair.second;
140 aOrigRanges.getArray()[i++] = 0;
141 aGrabBagMap[u"OrigItemSetRanges"_ustr] <<= aOrigRanges;
142 rSet.MergeRange(RES_PARATR_GRABBAG, RES_PARATR_GRABBAG);
143 rSet.Put(SfxGrabBagItem(RES_PARATR_GRABBAG, std::move(aGrabBagMap)));
146 void ConvertAttrGenToChar(SfxItemSet& rSet, const SfxItemSet& rOrigSet, bool bIsPara)
148 // Background / highlighting
149 if( SfxItemState::SET == rSet.GetItemState( RES_CHRATR_BACKGROUND, false ) )
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 rSet.Put( SvxBrushItem(RES_CHRATR_HIGHLIGHT) );
155 // Remove shading marker
156 if (const SfxGrabBagItem* pGrabBagItem = rOrigSet.GetItemIfSet(RES_CHRATR_GRABBAG, false))
158 if( pGrabBagItem->GetGrabBag().count(u"CharShadingMarker"_ustr) )
160 std::map<OUString, css::uno::Any> aGrabBagMap = pGrabBagItem->GetGrabBag();
161 aGrabBagMap[u"CharShadingMarker"_ustr] <<= false;
162 rSet.Put( SfxGrabBagItem(RES_CHRATR_GRABBAG, std::move(aGrabBagMap)) );
167 if ( bIsPara )
168 return;
170 rSet.ClearItem( RES_BACKGROUND );
172 if (const SfxGrabBagItem* pGrabBagItem = rOrigSet.GetItemIfSet(RES_PARATR_GRABBAG, false))
174 const std::map<OUString, css::uno::Any>& rMap = pGrabBagItem->GetGrabBag();
175 auto aIterator = rMap.find(u"OrigItemSetRanges"_ustr);
176 if (aIterator != rMap.end())
178 uno::Sequence<sal_uInt16> aOrigRanges;
179 if ( aIterator->second >>= aOrigRanges )
181 assert(aOrigRanges.getLength() % 2 == 1);
182 int numPairs = (aOrigRanges.getLength()-1)/2;
183 std::unique_ptr<WhichPair[]> xPairs(new WhichPair[numPairs]);
184 for(int i=0; i<aOrigRanges.getLength()-1; i += 2)
186 xPairs[i/2] = { aOrigRanges[i], aOrigRanges[i+1] };
188 rSet.SetRanges(WhichRangesContainer(std::move(xPairs), numPairs));
192 assert(SfxItemState::SET != rSet.GetItemState(RES_PARATR_GRABBAG, false));
195 void ApplyCharBackground(Color const& rBackgroundColor, model::ComplexColor const& rComplexColor, SwWrtShell& rShell)
197 rShell.StartUndo(SwUndoId::INSATTR);
199 SfxItemSetFixed<RES_CHRATR_GRABBAG, RES_CHRATR_GRABBAG> aCoreSet(rShell.GetView().GetPool());
201 rShell.GetCurAttr(aCoreSet);
203 // Set char background
204 rShell.SetAttrItem(SvxBrushItem(rBackgroundColor, rComplexColor, RES_CHRATR_BACKGROUND));
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 rShell.SetAttrItem(SvxBrushItem(RES_CHRATR_HIGHLIGHT));
210 // Remove shading marker
211 if (const SfxGrabBagItem* pGrabBagItem = aCoreSet.GetItemIfSet(RES_CHRATR_GRABBAG, false))
213 if (pGrabBagItem->GetGrabBag().count(u"CharShadingMarker"_ustr))
215 std::map<OUString, css::uno::Any> aGrabBagMap = pGrabBagItem->GetGrabBag();
216 aGrabBagMap[u"CharShadingMarker"_ustr] <<= false;
217 rShell.SetAttrItem(SfxGrabBagItem(RES_CHRATR_GRABBAG, std::move(aGrabBagMap)));
221 rShell.EndUndo(SwUndoId::INSATTR);
224 // Fill header footer
226 static void FillHdFt(SwFrameFormat* pFormat, const SfxItemSet& rSet)
228 SwAttrSet aSet(pFormat->GetAttrSet());
229 aSet.Put(rSet);
231 const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
232 const SfxBoolItem& rDynamic = rSet.Get(SID_ATTR_PAGE_DYNAMIC);
234 // Convert size
235 SwFormatFrameSize aFrameSize(rDynamic.GetValue() ? SwFrameSize::Minimum : SwFrameSize::Fixed,
236 rSize.GetSize().Width(),
237 rSize.GetSize().Height());
238 aSet.Put(aFrameSize);
239 pFormat->SetFormatAttr(aSet);
242 /// Convert from UseOnPage to SvxPageUsage.
243 static SvxPageUsage lcl_convertUseToSvx(UseOnPage nUse)
245 SvxPageUsage nRet = SvxPageUsage::NONE;
246 if (nUse & UseOnPage::Left)
247 nRet = SvxPageUsage::Left;
248 if (nUse & UseOnPage::Right)
249 nRet = SvxPageUsage::Right;
250 if ((nUse & UseOnPage::All) == UseOnPage::All)
251 nRet = SvxPageUsage::All;
252 if ((nUse & UseOnPage::Mirror) == UseOnPage::Mirror)
253 nRet = SvxPageUsage::Mirror;
254 return nRet;
257 /// Convert from SvxPageUsage to UseOnPage.
258 static UseOnPage lcl_convertUseFromSvx(SvxPageUsage nUse)
260 UseOnPage nRet = UseOnPage::NONE;
261 if (nUse == SvxPageUsage::Left)
262 nRet = UseOnPage::Left;
263 else if (nUse == SvxPageUsage::Right)
264 nRet = UseOnPage::Right;
265 else if (nUse == SvxPageUsage::All)
266 nRet = UseOnPage::All;
267 else if (nUse == SvxPageUsage::Mirror)
268 nRet = UseOnPage::Mirror;
269 return nRet;
272 // PageDesc <-> convert into sets and back
274 void ItemSetToPageDesc( const SfxItemSet& rSet, SwPageDesc& rPageDesc )
276 SwFrameFormat& rMaster = rPageDesc.GetMaster();
277 bool bFirstShare = false;
279 // before SetFormatAttr() in case it contains RES_BACKGROUND_FULL_SIZE
280 // itself, as it does when called from SwXPageStyle
281 if (const SfxGrabBagItem* pGrabBag = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
283 bool bValue;
284 const auto& rGrabBagInner = pGrabBag->GetGrabBag();
285 const auto iter = rGrabBagInner.find(u"BackgroundFullSize"_ustr);
286 assert(iter != rGrabBagInner.end());
287 if (iter->second >>= bValue)
289 rMaster.SetFormatAttr(SfxBoolItem(RES_BACKGROUND_FULL_SIZE, bValue));
291 auto it = rGrabBagInner.find(u"RtlGutter"_ustr);
292 if (it != rGrabBagInner.end() && (it->second >>= bValue))
294 rMaster.SetFormatAttr(SfxBoolItem(RES_RTL_GUTTER, bValue));
298 // Transfer all general frame attributes
299 rMaster.SetFormatAttr(rSet);
301 // PageData
302 if(rSet.GetItemState(SID_ATTR_PAGE) == SfxItemState::SET)
304 const SvxPageItem& rPageItem = rSet.Get(SID_ATTR_PAGE);
306 const SvxPageUsage nUse = rPageItem.GetPageUsage();
307 if(nUse != SvxPageUsage::NONE)
308 rPageDesc.SetUseOn( lcl_convertUseFromSvx(nUse) );
309 rPageDesc.SetLandscape(rPageItem.IsLandscape());
310 SvxNumberType aNumType;
311 aNumType.SetNumberingType( rPageItem.GetNumType() );
312 rPageDesc.SetNumType(aNumType);
314 // Size
315 if(rSet.GetItemState(SID_ATTR_PAGE_SIZE) == SfxItemState::SET)
317 const SvxSizeItem& rSizeItem = rSet.Get(SID_ATTR_PAGE_SIZE);
318 SwFormatFrameSize aSize(SwFrameSize::Fixed);
319 aSize.SetSize(rSizeItem.GetSize());
320 rMaster.SetFormatAttr(aSize);
322 // Evaluate header attributes
323 if( const SvxSetItem* pHeaderSetItem = rSet.GetItemIfSet( SID_ATTR_PAGE_HEADERSET,
324 false ) )
326 const SfxItemSet& rHeaderSet = pHeaderSetItem->GetItemSet();
327 const SfxBoolItem& rHeaderOn = rHeaderSet.Get(SID_ATTR_PAGE_ON);
329 if(rHeaderOn.GetValue())
331 // Take over values
332 if(!rMaster.GetHeader().IsActive())
333 rMaster.SetFormatAttr(SwFormatHeader(true));
335 // Pick out everything and adapt the header format
336 SwFormatHeader aHeaderFormat(rMaster.GetHeader());
337 SwFrameFormat *pHeaderFormat = aHeaderFormat.GetHeaderFormat();
338 OSL_ENSURE(pHeaderFormat != nullptr, "no header format");
340 ::FillHdFt(pHeaderFormat, rHeaderSet);
342 rPageDesc.ChgHeaderShare(rHeaderSet.Get(SID_ATTR_PAGE_SHARED).GetValue());
343 rPageDesc.ChgFirstShare(static_cast<const SfxBoolItem&>(
344 rHeaderSet.Get(SID_ATTR_PAGE_SHARED_FIRST)).GetValue());
345 bFirstShare = true;
347 else
349 // Disable header
350 if(rMaster.GetHeader().IsActive())
352 rMaster.SetFormatAttr(SwFormatHeader(false));
353 rPageDesc.ChgHeaderShare(false);
358 // Evaluate footer attributes
359 if( const SvxSetItem* pFooterSetItem = rSet.GetItemIfSet( SID_ATTR_PAGE_FOOTERSET,
360 false ) )
362 const SfxItemSet& rFooterSet = pFooterSetItem->GetItemSet();
363 const SfxBoolItem& rFooterOn = rFooterSet.Get(SID_ATTR_PAGE_ON);
365 if(rFooterOn.GetValue())
367 // Take over values
368 if(!rMaster.GetFooter().IsActive())
369 rMaster.SetFormatAttr(SwFormatFooter(true));
371 // Pick out everything and adapt the footer format
372 SwFormatFooter aFooterFormat(rMaster.GetFooter());
373 SwFrameFormat *pFooterFormat = aFooterFormat.GetFooterFormat();
374 OSL_ENSURE(pFooterFormat != nullptr, "no footer format");
376 ::FillHdFt(pFooterFormat, rFooterSet);
378 rPageDesc.ChgFooterShare(rFooterSet.Get(SID_ATTR_PAGE_SHARED).GetValue());
379 if (!bFirstShare)
381 rPageDesc.ChgFirstShare(static_cast<const SfxBoolItem&>(
382 rFooterSet.Get(SID_ATTR_PAGE_SHARED_FIRST)).GetValue());
385 else
387 // Disable footer
388 if(rMaster.GetFooter().IsActive())
390 rMaster.SetFormatAttr(SwFormatFooter(false));
391 // why reset this? but not doing it causes testTdf112694 to fail
392 rPageDesc.ChgFooterShare(false);
397 // Footnotes
399 if( const SwPageFootnoteInfoItem* pFootnoteItem = rSet.GetItemIfSet( FN_PARAM_FTN_INFO,
400 false ) )
401 rPageDesc.SetFootnoteInfo( pFootnoteItem->GetPageFootnoteInfo() );
403 // Columns
405 // Register compliant
407 const SfxBoolItem* pRegisterModeItem = rSet.GetItemIfSet(
408 SID_SWREGISTER_MODE, false);
409 if(!pRegisterModeItem)
410 return;
412 bool bSet = pRegisterModeItem->GetValue();
413 if(!bSet)
414 rPageDesc.SetRegisterFormatColl(nullptr);
415 else if(const SfxStringItem* pCollectionItem = rSet.GetItemIfSet(
416 SID_SWREGISTER_COLLECTION, false))
418 const OUString& rColl = pCollectionItem->GetValue();
419 SwDoc& rDoc = *rMaster.GetDoc();
420 SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( rColl );
421 if( !pColl )
423 const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
424 rColl, SwGetPoolIdFromName::TxtColl );
425 if( USHRT_MAX != nId )
426 pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
427 else
428 pColl = rDoc.MakeTextFormatColl( rColl,
429 rDoc.GetDfltTextFormatColl() );
431 if( pColl )
432 pColl->SetFormatAttr( SwRegisterItem ( true ));
433 rPageDesc.SetRegisterFormatColl( pColl );
437 namespace
439 bool IsOwnFormat(const SwDoc& rDoc)
441 const SwDocShell* pDocShell = rDoc.GetDocShell();
442 if (!pDocShell)
443 return false;
445 SfxMedium* pMedium = pDocShell->GetMedium();
446 if (!pMedium)
448 return false;
451 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
452 if (!pFilter)
454 return false;
457 return pFilter->IsOwnFormat();
461 void PageDescToItemSet( const SwPageDesc& rPageDesc, SfxItemSet& rSet)
463 const SwFrameFormat& rMaster = rPageDesc.GetMaster();
465 // Page data
466 SvxPageItem aPageItem(SID_ATTR_PAGE);
467 aPageItem.SetDescName(rPageDesc.GetName());
468 aPageItem.SetPageUsage(lcl_convertUseToSvx(rPageDesc.GetUseOn()));
469 aPageItem.SetLandscape(rPageDesc.GetLandscape());
470 aPageItem.SetNumType(rPageDesc.GetNumType().GetNumberingType());
471 rSet.Put(aPageItem);
473 // Size
474 SvxSizeItem aSizeItem(SID_ATTR_PAGE_SIZE, rMaster.GetFrameSize().GetSize());
475 rSet.Put(aSizeItem);
477 // Maximum size
478 SvxSizeItem aMaxSizeItem(SID_ATTR_PAGE_MAXSIZE, Size(MAXWIDTH, MAXHEIGHT));
479 rSet.Put(aMaxSizeItem);
481 // Margins, border and the other stuff.
482 rSet.Put(rMaster.GetAttrSet());
484 std::shared_ptr<SvxBoxInfoItem> aBoxInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
486 if ( const SvxBoxInfoItem *pBoxInfo = rSet.GetItemIfSet( SID_ATTR_BORDER_INNER ) )
488 aBoxInfo.reset(pBoxInfo->Clone());
491 aBoxInfo->SetTable( false );
492 // Show always the distance field
493 aBoxInfo->SetDist( true);
494 // Set minimal size in tables and paragraphs
495 aBoxInfo->SetMinDist( false );
496 // Set always the default distance
497 aBoxInfo->SetDefDist( MIN_BORDER_DIST );
498 // Single lines can have only in tables DontCare-Status
499 aBoxInfo->SetValid( SvxBoxInfoItemValidFlags::DISABLE );
500 rSet.Put( *aBoxInfo );
502 SfxStringItem aFollow(SID_ATTR_PAGE_EXT1, OUString());
503 if(rPageDesc.GetFollow())
504 aFollow.SetValue(rPageDesc.GetFollow()->GetName());
505 rSet.Put(aFollow);
507 // Header
508 if(rMaster.GetHeader().IsActive())
510 const SwFormatHeader &rHeaderFormat = rMaster.GetHeader();
511 const SwFrameFormat *pHeaderFormat = rHeaderFormat.GetHeaderFormat();
512 assert(pHeaderFormat && "no header format");
514 // HeaderInfo, margins, background, border
515 SfxItemSetFixed<RES_FRMATR_BEGIN,RES_FRMATR_END - 1, // [82
517 // FillAttribute support
518 XATTR_FILL_FIRST, XATTR_FILL_LAST, // [1014
520 SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER, // [10023
521 SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE, // [10051
522 SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED, // [10060
523 SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST> aHeaderSet(*rSet.GetPool());
525 // set correct parent to get the XFILL_NONE FillStyle as needed
526 aHeaderSet.SetParent(&rMaster.GetDoc()->GetDfltFrameFormat()->GetAttrSet());
528 // Dynamic or fixed height
529 SfxBoolItem aOn(SID_ATTR_PAGE_ON, true);
530 aHeaderSet.Put(aOn);
532 const SwFormatFrameSize &rFrameSize = pHeaderFormat->GetFrameSize();
533 const SwFrameSize eSizeType = rFrameSize.GetHeightSizeType();
534 SfxBoolItem aDynamic(SID_ATTR_PAGE_DYNAMIC, eSizeType != SwFrameSize::Fixed);
535 aHeaderSet.Put(aDynamic);
537 // Left equal right
538 SfxBoolItem aShared(SID_ATTR_PAGE_SHARED, rPageDesc.IsHeaderShared());
539 aHeaderSet.Put(aShared);
540 SfxBoolItem aFirstShared(SID_ATTR_PAGE_SHARED_FIRST, rPageDesc.IsFirstShared());
541 aHeaderSet.Put(aFirstShared);
543 // Size
544 SvxSizeItem aSize(SID_ATTR_PAGE_SIZE, rFrameSize.GetSize());
545 aHeaderSet.Put(aSize);
547 // Shifting frame attributes
548 aHeaderSet.Put(pHeaderFormat->GetAttrSet());
549 aHeaderSet.Put( *aBoxInfo );
551 // Create SetItem
552 SvxSetItem aSetItem(SID_ATTR_PAGE_HEADERSET, aHeaderSet);
553 rSet.Put(aSetItem);
556 // Footer
557 if(rMaster.GetFooter().IsActive())
559 const SwFormatFooter &rFooterFormat = rMaster.GetFooter();
560 const SwFrameFormat *pFooterFormat = rFooterFormat.GetFooterFormat();
561 assert(pFooterFormat && "no footer format");
563 // FooterInfo, margins, background, border
564 SfxItemSetFixed<RES_FRMATR_BEGIN,RES_FRMATR_END - 1, // [82
566 // FillAttribute support
567 XATTR_FILL_FIRST, XATTR_FILL_LAST, // [1014
569 SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER, // [10023
570 SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE, // [10051
571 SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED, // [10060
572 SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST> aFooterSet(*rSet.GetPool());
574 // set correct parent to get the XFILL_NONE FillStyle as needed
575 aFooterSet.SetParent(&rMaster.GetDoc()->GetDfltFrameFormat()->GetAttrSet());
577 // Dynamic or fixed height
578 SfxBoolItem aOn(SID_ATTR_PAGE_ON, true);
579 aFooterSet.Put(aOn);
581 const SwFormatFrameSize &rFrameSize = pFooterFormat->GetFrameSize();
582 const SwFrameSize eSizeType = rFrameSize.GetHeightSizeType();
583 SfxBoolItem aDynamic(SID_ATTR_PAGE_DYNAMIC, eSizeType != SwFrameSize::Fixed);
584 aFooterSet.Put(aDynamic);
586 // Left equal right
587 SfxBoolItem aShared(SID_ATTR_PAGE_SHARED, rPageDesc.IsFooterShared());
588 aFooterSet.Put(aShared);
589 SfxBoolItem aFirstShared(SID_ATTR_PAGE_SHARED_FIRST, rPageDesc.IsFirstShared());
590 aFooterSet.Put(aFirstShared);
592 // Size
593 SvxSizeItem aSize(SID_ATTR_PAGE_SIZE, rFrameSize.GetSize());
594 aFooterSet.Put(aSize);
596 // Shifting Frame attributes
597 aFooterSet.Put(pFooterFormat->GetAttrSet());
598 aFooterSet.Put( *aBoxInfo );
600 // Create SetItem
601 SvxSetItem aSetItem(SID_ATTR_PAGE_FOOTERSET, aFooterSet);
602 rSet.Put(aSetItem);
605 // Integrate footnotes
606 SwPageFootnoteInfo& rInfo = const_cast<SwPageFootnoteInfo&>(rPageDesc.GetFootnoteInfo());
607 SwPageFootnoteInfoItem aFootnoteItem(rInfo);
608 rSet.Put(aFootnoteItem);
610 // Register compliant
611 const SwTextFormatColl* pCol = rPageDesc.GetRegisterFormatColl();
612 SwRegisterItem aReg(pCol != nullptr);
613 aReg.SetWhich(SID_SWREGISTER_MODE);
614 rSet.Put(aReg);
615 if(pCol)
616 rSet.Put(SfxStringItem(SID_SWREGISTER_COLLECTION, pCol->GetName()));
618 std::map<OUString, css::uno::Any> aGrabBagMap;
619 if (SfxGrabBagItem const* pItem = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
620 aGrabBagMap = pItem->GetGrabBag();
621 aGrabBagMap[u"BackgroundFullSize"_ustr] <<=
622 rMaster.GetAttrSet().GetItem<SfxBoolItem>(RES_BACKGROUND_FULL_SIZE)->GetValue();
624 if (IsOwnFormat(*rMaster.GetDoc()))
626 aGrabBagMap[u"RtlGutter"_ustr]
627 <<= rMaster.GetAttrSet().GetItem<SfxBoolItem>(RES_RTL_GUTTER)->GetValue();
630 const IDocumentSettingAccess& rIDSA = rMaster.getIDocumentSettingAccess();
631 if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
633 aGrabBagMap[u"ContinuousEndnotes"_ustr] <<= true;
636 rSet.Put(SfxGrabBagItem(SID_ATTR_CHAR_GRABBAG, std::move(aGrabBagMap)));
639 // Set DefaultTabs
641 void MakeDefTabs(SwTwips nDefDist, SvxTabStopItem& rTabs)
643 if( rTabs.Count() )
644 return;
646 SvxTabStop aSwTabStop( nDefDist, SvxTabAdjust::Default );
647 rTabs.Insert( aSwTabStop );
651 // Distance between two tabs
653 SwTwips GetTabDist(const SvxTabStopItem& rTabs)
655 return rTabs.Count() ? rTabs[0].GetTabPos() : 1134; // 1134 = 2 cm
658 // Inquire if in the set is a Sfx-PageDesc combination present and return it.
659 void SfxToSwPageDescAttr( const SwWrtShell& rShell, SfxItemSet& rSet )
661 const SfxPoolItem* pItem;
662 SwFormatPageDesc aPgDesc;
664 bool bChanged = false;
665 // Page number
666 switch (rSet.GetItemState(SID_ATTR_PARA_PAGENUM, false, &pItem))
668 case SfxItemState::SET:
670 aPgDesc.SetNumOffset(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
671 bChanged = true;
672 break;
674 case SfxItemState::DISABLED:
676 bChanged = true; // default initialised aPgDesc clears the number
677 break;
679 case SfxItemState::UNKNOWN:
680 case SfxItemState::DEFAULT:
681 break;
682 default:
683 assert(false); // unexpected
684 break;
686 if( const SvxPageModelItem* pModelItem = rSet.GetItemIfSet( SID_ATTR_PARA_MODEL, false ))
688 const OUString& rDescName = pModelItem->GetValue();
689 if( !rDescName.isEmpty() ) // No name -> disable PageDesc!
691 // Delete only, if PageDesc will be enabled!
692 rSet.ClearItem( RES_BREAK );
693 SwPageDesc* pDesc = const_cast<SwWrtShell&>(rShell).FindPageDescByName(
694 rDescName, true );
695 if( pDesc )
696 aPgDesc.RegisterToPageDesc( *pDesc );
698 rSet.ClearItem( SID_ATTR_PARA_MODEL );
699 bChanged = true;
701 else
703 SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aCoreSet(rShell.GetView().GetPool());
704 rShell.GetCurAttr( aCoreSet );
705 if(const SwFormatPageDesc* pPageDescItem = aCoreSet.GetItemIfSet( RES_PAGEDESC ) )
707 const SwPageDesc* pPageDesc = pPageDescItem->GetPageDesc();
708 if( pPageDesc )
710 aPgDesc.RegisterToPageDesc( *const_cast<SwPageDesc*>(pPageDesc) );
715 if(bChanged)
716 rSet.Put( aPgDesc );
719 // Inquire if in the set is a Sfx-PageDesc combination present and return it.
720 void SwToSfxPageDescAttr( SfxItemSet& rCoreSet )
722 const SwFormatPageDesc* pPageDescItem = nullptr;
723 OUString aName;
724 ::std::optional<sal_uInt16> oNumOffset;
725 bool bPut = true;
726 switch( rCoreSet.GetItemState( RES_PAGEDESC, true, &pPageDescItem ) )
728 case SfxItemState::SET:
730 if( pPageDescItem->GetPageDesc() )
732 aName = pPageDescItem->GetPageDesc()->GetName();
733 oNumOffset = pPageDescItem->GetNumOffset();
735 rCoreSet.ClearItem( RES_PAGEDESC );
736 // Page number
738 break;
740 case SfxItemState::DEFAULT:
741 break;
743 default:
744 bPut = false;
747 if (oNumOffset)
749 SfxUInt16Item aPageNum( SID_ATTR_PARA_PAGENUM, *oNumOffset );
750 rCoreSet.Put( aPageNum );
753 if(bPut)
754 rCoreSet.Put( SvxPageModelItem( aName, true, SID_ATTR_PARA_MODEL ) );
757 // Determine metric
759 FieldUnit GetDfltMetric(bool bWeb)
761 return SwModule::get()->GetUsrPref(bWeb)->GetMetric();
764 // Determine metric
766 void SetDfltMetric( FieldUnit eMetric, bool bWeb )
768 SwModule::get()->ApplyUserMetric(eMetric, bWeb);
771 void InsertStringSorted(const OUString& rId, const OUString& rEntry, weld::ComboBox& rToFill, int nOffset)
773 CollatorWrapper& rCaseColl = ::GetAppCaseCollator();
774 const int nCount = rToFill.get_count();
775 while (nOffset < nCount)
777 if (0 < rCaseColl.compareString(rToFill.get_text(nOffset), rEntry))
778 break;
779 ++nOffset;
781 rToFill.insert(nOffset, rEntry, &rId, nullptr, nullptr);
784 void FillCharStyleListBox(weld::ComboBox& rToFill, SwDocShell* pDocSh, bool bSorted, bool bWithDefault)
786 const int nOffset = rToFill.get_count() > 0 ? 1 : 0;
787 rToFill.freeze();
788 SfxStyleSheetBasePool* pPool = pDocSh->GetStyleSheetPool();
789 SwDoc* pDoc = pDocSh->GetDoc();
790 const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Char);
791 const OUString sStandard(SwResId(STR_POOLCHR_STANDARD));
792 while(pBase)
794 if(bWithDefault || pBase->GetName() != sStandard)
796 sal_IntPtr nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( pBase->GetName(), SwGetPoolIdFromName::ChrFmt );
797 OUString sId(OUString::number(nPoolId));
798 if (bSorted)
799 InsertStringSorted(sId, pBase->GetName(), rToFill, nOffset);
800 else
801 rToFill.append(sId, pBase->GetName());
803 pBase = pPool->Next();
805 // non-pool styles
806 for(const auto pFormat : *pDoc->GetCharFormats())
808 if(pFormat->IsDefault())
809 continue;
810 const OUString& rName = pFormat->GetName();
811 if (rToFill.find_text(rName) == -1)
813 OUString sId(OUString::number(USHRT_MAX));
814 if (bSorted)
815 InsertStringSorted(sId, rName, rToFill, nOffset);
816 else
817 rToFill.append(sId, rName);
820 rToFill.thaw();
823 SwTwips GetTableWidth( SwFrameFormat const * pFormat, SwTabCols const & rCols, sal_uInt16 *pPercent,
824 SwWrtShell* pSh )
826 // To get the width is slightly more complicated.
827 SwTwips nWidth = 0;
828 const sal_Int16 eOri = pFormat->GetHoriOrient().GetHoriOrient();
829 switch(eOri)
831 case text::HoriOrientation::FULL: nWidth = rCols.GetRight(); break;
832 case text::HoriOrientation::LEFT_AND_WIDTH:
833 case text::HoriOrientation::LEFT:
834 case text::HoriOrientation::RIGHT:
835 case text::HoriOrientation::CENTER:
836 nWidth = pFormat->GetFrameSize().GetWidth();
837 break;
838 default:
840 if(pSh)
842 if ( nullptr == pSh->GetFlyFrameFormat() )
844 nWidth = pSh->GetAnyCurRect(CurRectType::PagePrt).Width();
846 else
848 nWidth = pSh->GetAnyCurRect(CurRectType::FlyEmbeddedPrt).Width();
851 else
853 OSL_FAIL("where to get the actual width from?");
855 const SvxLRSpaceItem& rLRSpace = pFormat->GetLRSpace();
856 nWidth -= (rLRSpace.ResolveRight({}) + rLRSpace.ResolveLeft({}));
859 if (pPercent)
860 *pPercent = pFormat->GetFrameSize().GetWidthPercent();
861 return nWidth;
864 OUString GetAppLangDateTimeString( const DateTime& rDT )
866 const SvtSysLocale aSysLocale;
867 const LocaleDataWrapper& rAppLclData = aSysLocale.GetLocaleData();
868 OUString sRet = rAppLclData.getDate( rDT ) + " " + rAppLclData.getTime( rDT );
869 return sRet;
872 // Add a new function which can get and set the current "SID_ATTR_APPLYCHARUNIT" value
874 bool HasCharUnit( bool bWeb)
876 return SwModule::get()->GetUsrPref(bWeb)->IsApplyCharUnit();
879 void SetApplyCharUnit(bool bApplyChar, bool bWeb)
881 SwModule::get()->ApplyUserCharUnit(bApplyChar, bWeb);
884 bool ExecuteMenuCommand(const css::uno::Reference<css::awt::XPopupMenu>& rMenu, const SfxViewFrame& rViewFrame, sal_uInt16 nId)
886 bool bRet = false;
887 const sal_uInt16 nItemCount = rMenu->getItemCount();
888 OUString sCommand;
889 for (sal_uInt16 nItem = 0; nItem < nItemCount; ++nItem)
891 sal_Int16 nItemId = rMenu->getItemId(nItem);
892 css::uno::Reference<css::awt::XPopupMenu> xPopup = rMenu->getPopupMenu(nItemId);
893 if (xPopup.is())
895 sCommand = xPopup->getCommand(nId);
896 if(!sCommand.isEmpty())
897 break;
900 if(!sCommand.isEmpty())
902 uno::Reference< frame::XFrame > xFrame = rViewFrame.GetFrame().GetFrameInterface();
903 uno::Reference < frame::XDispatchProvider > xProv( xFrame, uno::UNO_QUERY );
904 util::URL aURL;
905 aURL.Complete = sCommand;
906 uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create(::comphelper::getProcessComponentContext() ) );
907 xTrans->parseStrict( aURL );
908 uno::Reference< frame::XDispatch > xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
909 if( xDisp.is() )
911 uno::Sequence< beans::PropertyValue > aSeq;
912 xDisp->dispatch( aURL, aSeq );
913 bRet = true;
916 return bRet;
919 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */