Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / envelp / envfmt.cxx
blobebf99363cd561b45d3208595363e7149d276d59a
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 <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>
30 #include <cmdid.h>
31 #include <IDocumentDrawModelAccess.hxx>
32 #include <drawdoc.hxx>
33 #include <wrtsh.hxx>
34 #include <view.hxx>
35 #include "envfmt.hxx"
36 #include <fmtcol.hxx>
37 #include <swuipardlg.hxx>
38 #include <chrdlgmodes.hxx>
39 #include <pardlg.hxx>
40 #include <poolfmt.hxx>
41 #include <uitool.hxx>
43 #include <vector>
44 #include <algorithm>
46 #include <memory>
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)
56 , m_pDialog(nullptr)
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))
68 SetExchangeSupport();
70 // Metrics
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);
79 // Install handlers
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));
93 // m_xSizeFormatBox
94 for (sal_uInt16 i = PAPER_A3; i <= PAPER_KAI32BIG; i++)
96 if (i != PAPER_USER)
98 const OUString aPaperName = SvxPaperInfo::GetName(static_cast<Paper>(i));
100 if (aPaperName.isEmpty())
101 continue;
103 sal_Int32 nPos = 0;
104 while (nPos < m_xSizeFormatBox->get_count() &&
105 m_xSizeFormatBox->get_text(nPos) < aPaperName)
107 ++nPos;
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)
119 m_pDialog = 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))
148 lUserW = lWidth ;
149 lUserH = lHeight;
152 FormatHdl(*m_xSizeFormatBox);
154 else
156 FillItem(GetParentSwEnvDlg()->m_aEnvItem);
157 SetMinMax();
158 m_xPreview->queue_draw();
162 IMPL_LINK(SwEnvFormatPage, AddrEditHdl, const OUString&, rIdent, void)
164 Edit(rIdent, false);
167 IMPL_LINK(SwEnvFormatPage, SendEditHdl, const OUString&, rIdent, void)
169 Edit(rIdent, true);
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 );
215 // Current tab
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 );
222 aTmpSet.Put( aOff );
224 // set BoxInfo
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());
242 sal_uInt16 nNewDist;
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;
264 if (!pAddrSet)
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(),
282 pRanges));
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)
293 tools::Long lWidth;
294 tools::Long lHeight;
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());
307 else
309 lWidth = lUserW;
310 lHeight = lUserH;
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);
326 SetMinMax();
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);
340 // Min and Max
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);
360 Reset(&aSet);
363 DeactivateRC SwEnvFormatPage::DeactivatePage(SfxItemSet* _pSet)
365 if( _pSet )
366 FillItemSet(_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);
385 else
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);
398 return true;
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);
412 // Metric fields
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));
419 SetMinMax();
421 GetParentSwEnvDlg()->m_pSenderSet.reset();
422 GetParentSwEnvDlg()->m_pAddresseeSet.reset();
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */