1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <editeng/paperinf.hxx>
23 #include <editeng/tstpitem.hxx>
24 #include <editeng/lrspitem.hxx>
25 #include <svtools/unitconv.hxx>
26 #include <svx/drawitem.hxx>
27 #include <o3tl/string_view.hxx>
28 #include <osl/diagnose.h>
31 #include <IDocumentDrawModelAccess.hxx>
32 #include <drawdoc.hxx>
37 #include <swuipardlg.hxx>
38 #include <chrdlgmodes.hxx>
40 #include <poolfmt.hxx>
48 #include <swabstdlg.hxx>
49 #include <swuiexp.hxx>
51 static tools::Long lUserW
= 5669; // 10 cm
52 static tools::Long lUserH
= 5669; // 10 cm
54 SwEnvFormatPage::SwEnvFormatPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
55 : SfxTabPage(pPage
, pController
, "modules/swriter/ui/envformatpage.ui", "EnvFormatPage", &rSet
)
57 , m_xAddrLeftField(m_xBuilder
->weld_metric_spin_button("leftaddr", FieldUnit::CM
))
58 , m_xAddrTopField(m_xBuilder
->weld_metric_spin_button("topaddr", FieldUnit::CM
))
59 , m_xAddrEditButton(m_xBuilder
->weld_menu_button("addredit"))
60 , m_xSendLeftField(m_xBuilder
->weld_metric_spin_button("leftsender", FieldUnit::CM
))
61 , m_xSendTopField(m_xBuilder
->weld_metric_spin_button("topsender", FieldUnit::CM
))
62 , m_xSendEditButton(m_xBuilder
->weld_menu_button("senderedit"))
63 , m_xSizeFormatBox(m_xBuilder
->weld_combo_box("format"))
64 , m_xSizeWidthField(m_xBuilder
->weld_metric_spin_button("width", FieldUnit::CM
))
65 , m_xSizeHeightField(m_xBuilder
->weld_metric_spin_button("height", FieldUnit::CM
))
66 , m_xPreview(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreview
))
71 FieldUnit aMetric
= ::GetDfltMetric(false);
72 ::SetFieldUnit(*m_xAddrLeftField
, aMetric
);
73 ::SetFieldUnit(*m_xAddrTopField
, aMetric
);
74 ::SetFieldUnit(*m_xSendLeftField
, aMetric
);
75 ::SetFieldUnit(*m_xSendTopField
, aMetric
);
76 ::SetFieldUnit(*m_xSizeWidthField
, aMetric
);
77 ::SetFieldUnit(*m_xSizeHeightField
, aMetric
);
80 Link
<weld::MetricSpinButton
&,void> aLk
= LINK(this, SwEnvFormatPage
, ModifyHdl
);
81 m_xAddrLeftField
->connect_value_changed( aLk
);
82 m_xAddrTopField
->connect_value_changed( aLk
);
83 m_xSendLeftField
->connect_value_changed( aLk
);
84 m_xSendTopField
->connect_value_changed( aLk
);
85 m_xSizeWidthField
->connect_value_changed( aLk
);
86 m_xSizeHeightField
->connect_value_changed( aLk
);
88 m_xAddrEditButton
->connect_selected(LINK(this, SwEnvFormatPage
, AddrEditHdl
));
89 m_xSendEditButton
->connect_selected(LINK(this, SwEnvFormatPage
, SendEditHdl
));
91 m_xSizeFormatBox
->connect_changed(LINK(this, SwEnvFormatPage
, FormatHdl
));
94 for (sal_uInt16 i
= PAPER_A3
; i
<= PAPER_KAI32BIG
; i
++)
98 const OUString aPaperName
= SvxPaperInfo::GetName(static_cast<Paper
>(i
));
100 if (aPaperName
.isEmpty())
104 while (nPos
< m_xSizeFormatBox
->get_count() &&
105 m_xSizeFormatBox
->get_text(nPos
) < aPaperName
)
109 m_xSizeFormatBox
->insert_text(nPos
, aPaperName
);
110 m_aIDs
.insert( m_aIDs
.begin() + nPos
, i
);
113 m_xSizeFormatBox
->append_text(SvxPaperInfo::GetName(PAPER_USER
));
114 m_aIDs
.push_back( sal_uInt16(PAPER_USER
) );
117 void SwEnvFormatPage::Init(SwEnvDlg
* pDialog
)
120 m_aPreview
.SetDialog(m_pDialog
);
123 SwEnvFormatPage::~SwEnvFormatPage()
127 IMPL_LINK( SwEnvFormatPage
, ModifyHdl
, weld::MetricSpinButton
&, rEdit
, void )
129 int lWVal
= getfieldval(*m_xSizeWidthField
);
130 int lHVal
= getfieldval(*m_xSizeHeightField
);
132 int lWidth
= std::max(lWVal
, lHVal
);
133 int lHeight
= std::min(lWVal
, lHVal
);
135 if (&rEdit
== m_xSizeWidthField
.get() || &rEdit
== m_xSizeHeightField
.get())
137 int nRotatedWidth
= lHeight
;
138 int nRotatedHeight
= lWidth
;
139 Paper ePaper
= SvxPaperInfo::GetSvxPaper(
140 Size(nRotatedWidth
, nRotatedHeight
), MapUnit::MapTwip
);
141 for (size_t i
= 0; i
< m_aIDs
.size(); ++i
)
142 if (m_aIDs
[i
] == o3tl::narrowing
<sal_uInt16
>(ePaper
))
143 m_xSizeFormatBox
->set_active(i
);
145 // remember user size
146 if (m_aIDs
[m_xSizeFormatBox
->get_active()] == sal_uInt16(PAPER_USER
))
152 FormatHdl(*m_xSizeFormatBox
);
156 FillItem(GetParentSwEnvDlg()->m_aEnvItem
);
158 m_xPreview
->queue_draw();
162 IMPL_LINK(SwEnvFormatPage
, AddrEditHdl
, const OUString
&, rIdent
, void)
167 IMPL_LINK(SwEnvFormatPage
, SendEditHdl
, const OUString
&, rIdent
, void)
172 void SwEnvFormatPage::Edit(std::u16string_view rIdent
, bool bSender
)
174 SwWrtShell
* pSh
= GetParentSwEnvDlg()->m_pSh
;
175 OSL_ENSURE(pSh
, "Shell missing");
177 SwTextFormatColl
* pColl
= pSh
->GetTextCollFromPool( static_cast< sal_uInt16
>(
178 bSender
? RES_POOLCOLL_SEND_ADDRESS
: RES_POOLCOLL_ENVELOPE_ADDRESS
));
179 OSL_ENSURE(pColl
, "Text collection missing");
181 if (o3tl::starts_with(rIdent
, u
"character"))
183 SfxItemSet
*pCollSet
= GetCollItemSet(pColl
, bSender
);
185 // In order for the background color not to get ironed over:
186 SfxAllItemSet
aTmpSet(*pCollSet
);
187 ::ConvertAttrCharToGen(aTmpSet
);
189 SwAbstractDialogFactory
& rFact
= swui::GetFactory();
191 const OUString sFormatStr
= pColl
->GetName();
192 ScopedVclPtr
<SfxAbstractTabDialog
> pDlg(rFact
.CreateSwCharDlg(GetFrameWeld(), pSh
->GetView(), aTmpSet
, SwCharDlgMode::Env
, &sFormatStr
));
193 if (pDlg
->Execute() == RET_OK
)
195 SfxItemSet
aOutputSet( *pDlg
->GetOutputItemSet() );
196 ::ConvertAttrGenToChar(aOutputSet
, aTmpSet
);
197 pCollSet
->Put(aOutputSet
);
200 else if (o3tl::starts_with(rIdent
, u
"paragraph"))
202 SfxItemSet
*pCollSet
= GetCollItemSet(pColl
, bSender
);
204 // In order for the tabulators not to get ironed over:
205 SfxAllItemSet
aTmpSet(*pCollSet
);
207 // Insert tabs, default tabs into ItemSet
208 const SvxTabStopItem
& rDefTabs
=
209 pSh
->GetView().GetCurShell()->GetPool().GetDefaultItem(RES_PARATR_TABSTOP
);
211 const sal_uInt16 nDefDist
= o3tl::narrowing
<sal_uInt16
>(::GetTabDist( rDefTabs
));
212 SfxUInt16Item
aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS
, nDefDist
);
213 aTmpSet
.Put( aDefDistItem
);
216 SfxUInt16Item
aTabPos( SID_ATTR_TABSTOP_POS
, 0 );
217 aTmpSet
.Put( aTabPos
);
219 // left border as offset
220 const tools::Long nOff
= aTmpSet
.Get(RES_MARGIN_TEXTLEFT
).GetTextLeft();
221 SfxInt32Item
aOff( SID_ATTR_TABSTOP_OFFSET
, nOff
);
225 ::PrepareBoxInfo( aTmpSet
, *pSh
);
227 SwDrawModel
* pDrawModel
= pSh
->GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
228 aTmpSet
.Put(SvxColorListItem(pDrawModel
->GetColorList(), SID_COLOR_TABLE
));
229 aTmpSet
.Put(SvxGradientListItem(pDrawModel
->GetGradientList(), SID_GRADIENT_LIST
));
230 aTmpSet
.Put(SvxHatchListItem(pDrawModel
->GetHatchList(), SID_HATCH_LIST
));
231 aTmpSet
.Put(SvxBitmapListItem(pDrawModel
->GetBitmapList(), SID_BITMAP_LIST
));
232 aTmpSet
.Put(SvxPatternListItem(pDrawModel
->GetPatternList(), SID_PATTERN_LIST
));
234 const OUString sFormatStr
= pColl
->GetName();
235 SwParaDlg
aDlg(GetFrameWeld(), pSh
->GetView(), aTmpSet
, DLG_ENVELOP
, &sFormatStr
);
237 if (aDlg
.run() == RET_OK
)
239 // maybe relocate defaults
240 const SfxUInt16Item
* pDefaultsItem
= nullptr;
241 SfxItemSet
* pOutputSet
= const_cast<SfxItemSet
*>(aDlg
.GetOutputItemSet());
244 if( (pDefaultsItem
= pOutputSet
->GetItemIfSet( SID_ATTR_TABSTOP_DEFAULTS
, false )) &&
245 nDefDist
!= (nNewDist
= pDefaultsItem
->GetValue()) )
247 SvxTabStopItem
aDefTabs( 0, 0, SvxTabAdjust::Default
, RES_PARATR_TABSTOP
);
248 MakeDefTabs( nNewDist
, aDefTabs
);
249 pSh
->SetDefault( aDefTabs
);
250 pOutputSet
->ClearItem( SID_ATTR_TABSTOP_DEFAULTS
);
252 if( pOutputSet
->Count() )
254 pCollSet
->Put(*pOutputSet
);
260 // A temporary Itemset that gets discarded at abort
261 SfxItemSet
*SwEnvFormatPage::GetCollItemSet(SwTextFormatColl
const * pColl
, bool bSender
)
263 std::unique_ptr
<SfxItemSet
>& pAddrSet
= bSender
? GetParentSwEnvDlg()->m_pSenderSet
: GetParentSwEnvDlg()->m_pAddresseeSet
;
266 // determine range (merge both Itemsets' ranges)
267 const WhichRangesContainer
& pRanges
= pColl
->GetAttrSet().GetRanges();
269 static WhichRangesContainer
const aRanges(svl::Items
<
270 RES_PARATR_BEGIN
, RES_PARATR_ADJUST
,
271 RES_PARATR_TABSTOP
, RES_PARATR_END
-1,
272 RES_MARGIN_FIRSTLINE
, RES_MARGIN_RIGHT
,
273 RES_UL_SPACE
, RES_UL_SPACE
,
274 RES_BACKGROUND
, RES_SHADOW
,
275 SID_ATTR_TABSTOP_DEFAULTS
, SID_ATTR_TABSTOP_DEFAULTS
,
276 SID_ATTR_TABSTOP_POS
, SID_ATTR_TABSTOP_POS
,
277 SID_ATTR_TABSTOP_OFFSET
, SID_ATTR_TABSTOP_OFFSET
,
278 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
281 pAddrSet
.reset(new SfxItemSet(GetParentSwEnvDlg()->m_pSh
->GetView().GetCurShell()->GetPool(),
283 for (const auto& rPair
: aRanges
)
284 pAddrSet
->MergeRange(rPair
.first
, rPair
.second
);
285 pAddrSet
->Put(pColl
->GetAttrSet());
288 return pAddrSet
.get();
291 IMPL_LINK_NOARG(SwEnvFormatPage
, FormatHdl
, weld::ComboBox
&, void)
295 tools::Long lSendFromLeft
;
296 tools::Long lSendFromTop
;
297 tools::Long lAddrFromLeft
;
298 tools::Long lAddrFromTop
;
300 const sal_uInt16 nPaper
= m_aIDs
[m_xSizeFormatBox
->get_active()];
301 if (nPaper
!= sal_uInt16(PAPER_USER
))
303 Size aSz
= SvxPaperInfo::GetPaperSize(static_cast<Paper
>(nPaper
));
304 lWidth
= std::max(aSz
.Width(), aSz
.Height());
305 lHeight
= std::min(aSz
.Width(), aSz
.Height());
313 lSendFromLeft
= 566; // 1cm
314 lSendFromTop
= 566; // 1cm
315 lAddrFromLeft
= lWidth
/ 2;
316 lAddrFromTop
= lHeight
/ 2;
318 setfieldval(*m_xAddrLeftField
, lAddrFromLeft
);
319 setfieldval(*m_xAddrTopField
, lAddrFromTop
);
320 setfieldval(*m_xSendLeftField
, lSendFromLeft
);
321 setfieldval(*m_xSendTopField
, lSendFromTop
);
323 setfieldval(*m_xSizeWidthField
, lWidth
);
324 setfieldval(*m_xSizeHeightField
, lHeight
);
328 FillItem(GetParentSwEnvDlg()->m_aEnvItem
);
329 m_xPreview
->queue_draw();
332 void SwEnvFormatPage::SetMinMax()
334 tools::Long lWVal
= static_cast< tools::Long
>(getfieldval(*m_xSizeWidthField
));
335 tools::Long lHVal
= static_cast< tools::Long
>(getfieldval(*m_xSizeHeightField
));
337 tools::Long lWidth
= std::max(lWVal
, lHVal
),
338 lHeight
= std::min(lWVal
, lHVal
);
341 m_xAddrLeftField
->set_range(100 * (getfieldval(*m_xSendLeftField
) + 566),
342 100 * (lWidth
- 2 * 566), FieldUnit::TWIP
);
343 m_xAddrTopField
->set_range(100 * (getfieldval(*m_xSendTopField
) + 2 * 566),
344 100 * (lHeight
- 2 * 566), FieldUnit::TWIP
);
345 m_xSendLeftField
->set_range(100 * 566,
346 100 * (getfieldval(*m_xAddrLeftField
) - 566), FieldUnit::TWIP
);
347 m_xSendTopField
->set_range(100 * 566,
348 100 * (getfieldval(*m_xAddrTopField
) - 2 * 566), FieldUnit::TWIP
);
351 std::unique_ptr
<SfxTabPage
> SwEnvFormatPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
353 return std::make_unique
<SwEnvFormatPage
>(pPage
, pController
, *rSet
);
356 void SwEnvFormatPage::ActivatePage(const SfxItemSet
& rSet
)
358 SfxItemSet
aSet(rSet
);
359 aSet
.Put(GetParentSwEnvDlg()->m_aEnvItem
);
363 DeactivateRC
SwEnvFormatPage::DeactivatePage(SfxItemSet
* _pSet
)
367 return DeactivateRC::LeavePage
;
370 void SwEnvFormatPage::FillItem(SwEnvItem
& rItem
)
372 rItem
.m_nAddrFromLeft
= static_cast< sal_Int32
>(getfieldval(*m_xAddrLeftField
));
373 rItem
.m_nAddrFromTop
= static_cast< sal_Int32
>(getfieldval(*m_xAddrTopField
));
374 rItem
.m_nSendFromLeft
= static_cast< sal_Int32
>(getfieldval(*m_xSendLeftField
));
375 rItem
.m_nSendFromTop
= static_cast< sal_Int32
>(getfieldval(*m_xSendTopField
));
377 const sal_uInt16 nPaper
= m_aIDs
[m_xSizeFormatBox
->get_active()];
378 if (nPaper
== sal_uInt16(PAPER_USER
))
380 tools::Long lWVal
= static_cast< tools::Long
>(getfieldval(*m_xSizeWidthField
));
381 tools::Long lHVal
= static_cast< tools::Long
>(getfieldval(*m_xSizeHeightField
));
382 rItem
.m_nWidth
= std::max(lWVal
, lHVal
);
383 rItem
.m_nHeight
= std::min(lWVal
, lHVal
);
387 tools::Long lWVal
= SvxPaperInfo::GetPaperSize(static_cast<Paper
>(nPaper
)).Width ();
388 tools::Long lHVal
= SvxPaperInfo::GetPaperSize(static_cast<Paper
>(nPaper
)).Height();
389 rItem
.m_nWidth
= std::max(lWVal
, lHVal
);
390 rItem
.m_nHeight
= std::min(lWVal
, lHVal
);
394 bool SwEnvFormatPage::FillItemSet(SfxItemSet
* rSet
)
396 FillItem(GetParentSwEnvDlg()->m_aEnvItem
);
397 rSet
->Put(GetParentSwEnvDlg()->m_aEnvItem
);
401 void SwEnvFormatPage::Reset(const SfxItemSet
* rSet
)
403 const SwEnvItem
& rItem
= static_cast<const SwEnvItem
&>( rSet
->Get(FN_ENVELOP
));
405 Paper ePaper
= SvxPaperInfo::GetSvxPaper(
406 Size( std::min(rItem
.m_nWidth
, rItem
.m_nHeight
),
407 std::max(rItem
.m_nWidth
, rItem
.m_nHeight
)), MapUnit::MapTwip
);
408 for (size_t i
= 0; i
< m_aIDs
.size(); ++i
)
409 if (m_aIDs
[i
] == o3tl::narrowing
<sal_uInt16
>(ePaper
))
410 m_xSizeFormatBox
->set_active(i
);
413 setfieldval(*m_xAddrLeftField
, rItem
.m_nAddrFromLeft
);
414 setfieldval(*m_xAddrTopField
, rItem
.m_nAddrFromTop
);
415 setfieldval(*m_xSendLeftField
, rItem
.m_nSendFromLeft
);
416 setfieldval(*m_xSendTopField
, rItem
.m_nSendFromTop
);
417 setfieldval(*m_xSizeWidthField
, std::max(rItem
.m_nWidth
, rItem
.m_nHeight
));
418 setfieldval(*m_xSizeHeightField
, std::min(rItem
.m_nWidth
, rItem
.m_nHeight
));
421 GetParentSwEnvDlg()->m_pSenderSet
.reset();
422 GetParentSwEnvDlg()->m_pAddresseeSet
.reset();
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */