ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / ui / frmdlg / column.cxx
blob8352bd72ff661350916303432d714afd18f9a617
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 <column.hxx>
22 #include <hintids.hxx>
23 #include <svx/dialmgr.hxx>
24 #include <svx/strings.hrc>
25 #include <sfx2/htmlmode.hxx>
26 #include <svx/colorbox.hxx>
27 #include <editeng/borderline.hxx>
28 #include <editeng/boxitem.hxx>
29 #include <editeng/lrspitem.hxx>
30 #include <editeng/sizeitem.hxx>
31 #include <editeng/frmdiritem.hxx>
32 #include <editeng/ulspitem.hxx>
33 #include <svl/ctloptions.hxx>
34 #include <svl/itemset.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <vcl/event.hxx>
38 #include <vcl/fieldvalues.hxx>
39 #include <vcl/settings.hxx>
40 #include <vcl/svapp.hxx>
42 #include <swmodule.hxx>
44 #include <swtypes.hxx>
45 #include <wrtsh.hxx>
46 #include <view.hxx>
47 #include <docsh.hxx>
48 #include <uitool.hxx>
49 #include <cmdid.h>
50 #include <viewopt.hxx>
51 #include <fmtclbl.hxx>
52 #include <fmtfsize.hxx>
53 #include <frmatr.hxx>
54 #include <colmgr.hxx>
55 #include <prcntfld.hxx>
56 #include <strings.hrc>
57 #include <section.hxx>
58 #include <pagedesc.hxx>
60 //to match associated data in ColumnPage.ui
61 #define LISTBOX_SELECTION 0
62 #define LISTBOX_SECTION 1
63 #define LISTBOX_SECTIONS 2
64 #define LISTBOX_PAGE 3
65 #define LISTBOX_FRAME 4
67 using namespace ::com::sun::star;
69 #define FRAME_FORMAT_WIDTH 1000
71 // static data
72 const sal_uInt16 nVisCols = 3;
74 static bool IsMarkInSameSection( SwWrtShell& rWrtSh, const SwSection* pSect )
76 rWrtSh.SwapPam();
77 bool bRet = pSect == rWrtSh.GetCurrSection();
78 rWrtSh.SwapPam();
79 return bRet;
82 SwColumnDlg::SwColumnDlg(weld::Window* pParent, SwWrtShell& rSh)
83 : SfxDialogController(pParent, u"modules/swriter/ui/columndialog.ui"_ustr, u"ColumnDialog"_ustr)
84 , m_rWrtShell(rSh)
85 , m_pFrameSet(nullptr)
86 , m_nOldSelection(0)
87 , m_nSelectionWidth(0)
88 , m_bPageChanged(false)
89 , m_bSectionChanged(false)
90 , m_bSelSectionChanged(false)
91 , m_bFrameChanged(false)
92 , m_xContentArea(m_xBuilder->weld_container(u"content"_ustr))
93 , m_xOkButton(m_xBuilder->weld_button(u"ok"_ustr))
95 SwRect aRect;
96 m_rWrtShell.CalcBoundRect(aRect, RndStdIds::FLY_AS_CHAR);
98 m_nSelectionWidth = aRect.Width();
100 SfxItemSet* pColPgSet = nullptr;
101 static const auto aSectIds = svl::Items<RES_FRM_SIZE, RES_FRM_SIZE,
102 RES_COL, RES_COL,
103 RES_COLUMNBALANCE, RES_FRAMEDIR>;
105 const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
106 const sal_uInt16 nFullSectCnt = m_rWrtShell.GetFullSelectedSectionCount();
107 if( pCurrSection && ( !m_rWrtShell.HasSelection() || 0 != nFullSectCnt ))
109 m_nSelectionWidth = rSh.GetSectionWidth(*pCurrSection->GetFormat());
110 if ( !m_nSelectionWidth )
111 m_nSelectionWidth = USHRT_MAX;
112 m_pSectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
113 m_pSectionSet->Put( pCurrSection->GetFormat()->GetAttrSet() );
114 pColPgSet = m_pSectionSet.get();
117 if( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
118 ( !pCurrSection || ( 1 != nFullSectCnt &&
119 IsMarkInSameSection( m_rWrtShell, pCurrSection ) )))
121 m_pSelectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
122 pColPgSet = m_pSelectionSet.get();
125 if( m_rWrtShell.GetFlyFrameFormat() )
127 const SwFrameFormat* pFormat = rSh.GetFlyFrameFormat() ;
128 m_pFrameSet = new SfxItemSet(m_rWrtShell.GetAttrPool(), aSectIds );
129 m_pFrameSet->Put(pFormat->GetFrameSize());
130 m_pFrameSet->Put(pFormat->GetCol());
131 pColPgSet = m_pFrameSet;
134 const SwPageDesc* pPageDesc = m_rWrtShell.GetSelectedPageDescs();
135 if( pPageDesc )
137 m_pPageSet = std::make_unique<SfxItemSetFixed<
138 RES_FRM_SIZE, RES_FRM_SIZE,
139 RES_LR_SPACE, RES_LR_SPACE,
140 RES_COL, RES_COL>>(m_rWrtShell.GetAttrPool());
142 const SwFrameFormat &rFormat = pPageDesc->GetMaster();
143 m_nPageWidth = rFormat.GetFrameSize().GetSize().Width();
145 const SvxLRSpaceItem& rLRSpace = rFormat.GetLRSpace();
146 const SvxBoxItem& rBox = rFormat.GetBox();
147 m_nPageWidth
148 -= rLRSpace.ResolveLeft({}) + rLRSpace.ResolveRight({}) + rBox.GetSmallestDistance();
150 m_pPageSet->Put(rFormat.GetCol());
151 m_pPageSet->Put(rFormat.GetLRSpace());
152 pColPgSet = m_pPageSet.get();
155 assert(pColPgSet);
157 // create TabPage
158 m_xTabPage = std::make_unique<SwColumnPage>(m_xContentArea.get(), this, *pColPgSet);
159 m_xTabPage->GetApplyLabel()->show();
160 weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
161 pApplyToLB->show();
163 if (pCurrSection && (!m_rWrtShell.HasSelection() || 0 != nFullSectCnt))
165 pApplyToLB->remove_id(1 >= nFullSectCnt ? OUString::number(LISTBOX_SECTIONS) : OUString::number(LISTBOX_SECTION));
167 else
169 pApplyToLB->remove_id(OUString::number(LISTBOX_SECTION));
170 pApplyToLB->remove_id(OUString::number(LISTBOX_SECTIONS));
173 if (!( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
174 ( !pCurrSection || ( 1 != nFullSectCnt &&
175 IsMarkInSameSection( m_rWrtShell, pCurrSection ) ))))
176 pApplyToLB->remove_id(OUString::number(LISTBOX_SELECTION));
178 if (!m_rWrtShell.GetFlyFrameFormat())
179 pApplyToLB->remove_id(OUString::number(LISTBOX_FRAME));
181 const int nPagePos = pApplyToLB->find_id(OUString::number(LISTBOX_PAGE));
182 if (m_pPageSet && pPageDesc)
184 const OUString sPageStr = pApplyToLB->get_text(nPagePos) + pPageDesc->GetName();
185 pApplyToLB->remove(nPagePos);
186 OUString sId(OUString::number(LISTBOX_PAGE));
187 pApplyToLB->insert(nPagePos, sPageStr, &sId, nullptr, nullptr);
189 else
190 pApplyToLB->remove( nPagePos );
192 pApplyToLB->set_active(0);
193 ObjectHdl(nullptr);
195 pApplyToLB->connect_changed(LINK(this, SwColumnDlg, ObjectListBoxHdl));
196 m_xOkButton->connect_clicked(LINK(this, SwColumnDlg, OkHdl));
197 //#i80458# if no columns can be set then disable OK
198 if (!pApplyToLB->get_count())
199 m_xOkButton->set_sensitive(false);
200 //#i97810# set focus to the TabPage
201 m_xTabPage->ActivateColumnControl();
204 SwColumnDlg::~SwColumnDlg()
206 m_xTabPage.reset();
209 IMPL_LINK(SwColumnDlg, ObjectListBoxHdl, weld::ComboBox&, rBox, void)
211 ObjectHdl(&rBox);
214 void SwColumnDlg::ObjectHdl(const weld::ComboBox* pBox)
216 SfxItemSet* pSet = EvalCurrentSelection();
218 if (pBox)
220 m_xTabPage->FillItemSet(pSet);
222 weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
223 m_nOldSelection = pApplyToLB->get_active_id().toInt32();
224 tools::Long nWidth = m_nSelectionWidth;
225 switch(m_nOldSelection)
227 case LISTBOX_SELECTION :
228 pSet = m_pSelectionSet.get();
229 if( m_pSelectionSet )
230 pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
231 break;
232 case LISTBOX_SECTION :
233 case LISTBOX_SECTIONS :
234 pSet = m_pSectionSet.get();
235 pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
236 break;
237 case LISTBOX_PAGE :
238 nWidth = m_nPageWidth;
239 pSet = m_pPageSet.get();
240 pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
241 break;
242 case LISTBOX_FRAME:
243 pSet = m_pFrameSet;
244 break;
247 bool bIsSection = pSet == m_pSectionSet.get() || pSet == m_pSelectionSet.get();
248 m_xTabPage->ShowBalance(bIsSection);
249 m_xTabPage->SetInSection(bIsSection);
250 m_xTabPage->SetFrameMode(true);
251 m_xTabPage->SetPageWidth(nWidth);
252 if( pSet )
253 m_xTabPage->Reset(pSet);
256 IMPL_LINK_NOARG(SwColumnDlg, OkHdl, weld::Button&, void)
258 // evaluate current selection
259 SfxItemSet* pSet = EvalCurrentSelection();
260 m_xTabPage->FillItemSet(pSet);
262 if(m_pSelectionSet && SfxItemState::SET == m_pSelectionSet->GetItemState(RES_COL))
264 //insert region with columns
265 const SwFormatCol& rColItem = m_pSelectionSet->Get(RES_COL);
266 //only if there actually are columns!
267 if(rColItem.GetNumCols() > 1)
268 m_rWrtShell.GetView().GetViewFrame().GetDispatcher()->Execute(
269 FN_INSERT_REGION, SfxCallMode::ASYNCHRON, *m_pSelectionSet );
272 if(m_pSectionSet && m_pSectionSet->Count() && m_bSectionChanged )
274 const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
275 const SwSectionFormat* pFormat = pCurrSection->GetFormat();
276 const size_t nNewPos = m_rWrtShell.GetSectionFormatPos( *pFormat );
277 SwSectionData aData(*pCurrSection);
278 m_rWrtShell.UpdateSection( nNewPos, aData, m_pSectionSet.get() );
281 if(m_pSectionSet && m_pSectionSet->Count() && m_bSelSectionChanged )
283 m_rWrtShell.SetSectionAttr( *m_pSectionSet );
286 if(m_pPageSet && SfxItemState::SET == m_pPageSet->GetItemState(RES_COL) && m_bPageChanged)
288 // determine current PageDescriptor and fill the Set with it
289 const size_t nCurIdx = m_rWrtShell.GetCurPageDesc();
290 SwPageDesc aPageDesc(m_rWrtShell.GetPageDesc(nCurIdx));
291 SwFrameFormat &rFormat = aPageDesc.GetMaster();
292 rFormat.SetFormatAttr(m_pPageSet->Get(RES_COL));
293 m_rWrtShell.ChgPageDesc(nCurIdx, aPageDesc);
295 if(m_pFrameSet && SfxItemState::SET == m_pFrameSet->GetItemState(RES_COL) && m_bFrameChanged)
297 SfxItemSetFixed<RES_COL, RES_COL> aTmp(*m_pFrameSet->GetPool());
298 aTmp.Put(*m_pFrameSet);
299 m_rWrtShell.StartAction();
300 m_rWrtShell.Push();
301 m_rWrtShell.SetFlyFrameAttr( aTmp );
302 // undo the frame selection again
303 if(m_rWrtShell.IsFrameSelected())
305 m_rWrtShell.UnSelectFrame();
306 m_rWrtShell.LeaveSelFrameMode();
308 m_rWrtShell.Pop();
309 m_rWrtShell.EndAction();
311 m_xDialog->response(RET_OK);
314 SfxItemSet* SwColumnDlg::EvalCurrentSelection()
316 SfxItemSet* pSet = nullptr;
318 switch(m_nOldSelection)
320 case LISTBOX_SELECTION :
321 pSet = m_pSelectionSet.get();
322 break;
323 case LISTBOX_SECTION :
324 pSet = m_pSectionSet.get();
325 m_bSectionChanged = true;
326 break;
327 case LISTBOX_SECTIONS :
328 pSet = m_pSectionSet.get();
329 m_bSelSectionChanged = true;
330 break;
331 case LISTBOX_PAGE :
332 pSet = m_pPageSet.get();
333 m_bPageChanged = true;
334 break;
335 case LISTBOX_FRAME:
336 pSet = m_pFrameSet;
337 m_bFrameChanged = true;
338 break;
341 return pSet;
344 static
345 sal_uInt16 GetMaxWidth( SwColMgr const * pColMgr, sal_uInt16 nCols )
347 sal_uInt16 nMax = pColMgr->GetActualSize();
348 if( --nCols )
349 nMax -= pColMgr->GetGutterWidth() * nCols;
350 return nMax;
353 const WhichRangesContainer SwColumnPage::s_aPageRg(svl::Items<RES_COL, RES_COL>);
355 void SwColumnPage::ResetColWidth()
357 if( m_nCols )
359 const sal_uInt16 nWidth = GetMaxWidth( m_xColMgr.get(), m_nCols ) / m_nCols;
361 for(sal_uInt16 i = 0; i < m_nCols; ++i)
362 m_nColWidth[i] = static_cast<tools::Long>(nWidth);
367 constexpr sal_uInt16 g_nMinWidth(MINLAY);
369 // Now as TabPage
370 SwColumnPage::SwColumnPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
371 : SfxTabPage(pPage, pController, u"modules/swriter/ui/columnpage.ui"_ustr, u"ColumnPage"_ustr, &rSet)
372 , m_nFirstVis(0)
373 , m_nCols(0)
374 , m_pModifiedField(nullptr)
375 , m_bFormat(false)
376 , m_bFrame(false)
377 , m_bHtmlMode(false)
378 , m_bLockUpdate(false)
379 , m_xCLNrEdt(m_xBuilder->weld_spin_button(u"colsnf"_ustr))
380 , m_xBalanceColsCB(m_xBuilder->weld_check_button(u"balance"_ustr))
381 , m_xBtnBack(m_xBuilder->weld_button(u"back"_ustr))
382 , m_xLbl1(m_xBuilder->weld_label(u"1"_ustr))
383 , m_xLbl2(m_xBuilder->weld_label(u"2"_ustr))
384 , m_xLbl3(m_xBuilder->weld_label(u"3"_ustr))
385 , m_xBtnNext(m_xBuilder->weld_button(u"next"_ustr))
386 , m_xAutoWidthBox(m_xBuilder->weld_check_button(u"autowidth"_ustr))
387 , m_xLineTypeLbl(m_xBuilder->weld_label(u"linestyleft"_ustr))
388 , m_xLineWidthLbl(m_xBuilder->weld_label(u"linewidthft"_ustr))
389 , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button(u"linewidthmf"_ustr, FieldUnit::POINT))
390 , m_xLineColorLbl(m_xBuilder->weld_label(u"linecolorft"_ustr))
391 , m_xLineHeightLbl(m_xBuilder->weld_label(u"lineheightft"_ustr))
392 , m_xLineHeightEdit(m_xBuilder->weld_metric_spin_button(u"lineheightmf"_ustr, FieldUnit::PERCENT))
393 , m_xLinePosLbl(m_xBuilder->weld_label(u"lineposft"_ustr))
394 , m_xLinePosDLB(m_xBuilder->weld_combo_box(u"lineposlb"_ustr))
395 , m_xTextDirectionFT(m_xBuilder->weld_label(u"textdirectionft"_ustr))
396 , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box(u"textdirectionlb"_ustr)))
397 , m_xLineColorDLB(new ColorListBox(m_xBuilder->weld_menu_button(u"colorlb"_ustr),
398 [this]{ return GetFrameWeld(); }))
399 , m_xLineTypeDLB(new SvtLineListBox(m_xBuilder->weld_menu_button(u"linestylelb"_ustr)))
400 , m_xEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width1mf"_ustr, FieldUnit::CM)))
401 , m_xEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width2mf"_ustr, FieldUnit::CM)))
402 , m_xEd3(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"width3mf"_ustr, FieldUnit::CM)))
403 , m_xDistEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"spacing1mf"_ustr, FieldUnit::CM)))
404 , m_xDistEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button(u"spacing2mf"_ustr, FieldUnit::CM)))
405 , m_xDefaultVS(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, m_aDefaultVS))
406 , m_xPgeExampleWN(new weld::CustomWeld(*m_xBuilder, u"pageexample"_ustr, m_aPgeExampleWN))
407 , m_xFrameExampleWN(new weld::CustomWeld(*m_xBuilder, u"frameexample"_ustr, m_aFrameExampleWN))
408 , m_xApplyToFT(m_xBuilder->weld_label(u"applytoft"_ustr))
409 , m_xApplyToLB(m_xBuilder->weld_combo_box(u"applytolb"_ustr))
411 connectPercentField(*m_xEd1);
412 connectPercentField(*m_xEd2);
413 connectPercentField(*m_xEd3);
414 connectPercentField(*m_xDistEd1);
415 connectPercentField(*m_xDistEd2);
417 m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
418 m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
419 m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
421 SetExchangeSupport();
423 m_aDefaultVS.SetColCount(5);
425 for (int i = 0; i < 5; ++i)
426 //Set accessible name one by one
428 OUString aItemText;
429 switch( i )
431 case 0:
432 aItemText = SwResId( STR_COLUMN_VALUESET_ITEM0 ) ;
433 break;
434 case 1:
435 aItemText = SwResId( STR_COLUMN_VALUESET_ITEM1 ) ;
436 break;
437 case 2:
438 aItemText = SwResId( STR_COLUMN_VALUESET_ITEM2 ) ;
439 break;
440 case 3:
441 aItemText = SwResId( STR_COLUMN_VALUESET_ITEM3 );
442 break;
443 default:
444 aItemText = SwResId( STR_COLUMN_VALUESET_ITEM4 );
445 break;
447 m_aDefaultVS.InsertItem( i + 1, aItemText, i );
450 m_aDefaultVS.SetSelectHdl(LINK(this, SwColumnPage, SetDefaultsHdl));
452 Link<weld::SpinButton&,void> aCLNrLk = LINK(this, SwColumnPage, ColModify);
453 m_xCLNrEdt->connect_value_changed(aCLNrLk);
454 Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwColumnPage, GapModify);
455 m_xDistEd1->connect_value_changed(aLk);
456 m_xDistEd2->connect_value_changed(aLk);
458 aLk = LINK(this, SwColumnPage, EdModify);
460 m_xEd1->connect_value_changed(aLk);
461 m_xEd2->connect_value_changed(aLk);
462 m_xEd3->connect_value_changed(aLk);
464 m_xBtnBack->connect_clicked(LINK(this, SwColumnPage, Up));
465 m_xBtnNext->connect_clicked(LINK(this, SwColumnPage, Down));
466 m_xAutoWidthBox->connect_toggled(LINK(this, SwColumnPage, AutoWidthHdl));
468 Link<weld::MetricSpinButton&,void> aLk2 = LINK( this, SwColumnPage, UpdateColMgr );
469 m_xLineTypeDLB->SetSelectHdl(LINK(this, SwColumnPage, UpdateColMgrLineBox));
470 m_xLineWidthEdit->connect_value_changed(aLk2);
471 m_xLineColorDLB->SetSelectHdl(LINK( this, SwColumnPage, UpdateColMgrColorBox));
472 m_xLineHeightEdit->connect_value_changed(aLk2);
473 m_xLinePosDLB->connect_changed(LINK(this, SwColumnPage, UpdateColMgrListBox));
475 // Separator line
476 m_xLineTypeDLB->SetSourceUnit( FieldUnit::TWIP );
478 // Fill the line styles listbox
479 m_xLineTypeDLB->InsertEntry(
480 ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::SOLID),
481 SvxBorderLineStyle::SOLID );
482 m_xLineTypeDLB->InsertEntry(
483 ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DOTTED),
484 SvxBorderLineStyle::DOTTED );
485 m_xLineTypeDLB->InsertEntry(
486 ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DASHED),
487 SvxBorderLineStyle::DASHED );
489 sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::POINT);
490 nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
491 nLineWidth,
492 m_xLineWidthEdit->get_digits(),
493 FieldUnit::POINT, MapUnit::MapTwip ));
494 m_xLineTypeDLB->SetWidth(nLineWidth);
495 m_xLineColorDLB->SelectEntry(COL_BLACK);
498 SwColumnPage::~SwColumnPage()
500 m_xFrameExampleWN.reset();
501 m_xPgeExampleWN.reset();
502 m_xDefaultVS.reset();
503 m_xDistEd2.reset();
504 m_xDistEd1.reset();
505 m_xEd3.reset();
506 m_xEd2.reset();
507 m_xEd1.reset();
508 m_xLineTypeDLB.reset();
509 m_xLineColorDLB.reset();
510 m_xTextDirectionLB.reset();
513 void SwColumnPage::SetPageWidth(tools::Long nPageWidth)
515 tools::Long nNewMaxWidth = static_cast< tools::Long >(m_xEd1->NormalizePercent(nPageWidth));
517 m_xDistEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
518 m_xDistEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
519 m_xEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
520 m_xEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
521 m_xEd3->set_max(nNewMaxWidth, FieldUnit::TWIP);
524 void SwColumnPage::connectPercentField(SwPercentField &rWrap)
526 weld::MetricSpinButton *pField = rWrap.get();
527 assert(pField);
528 m_aPercentFieldsMap[pField] = &rWrap;
531 void SwColumnPage::Reset(const SfxItemSet *rSet)
533 const sal_uInt16 nHtmlMode =
534 ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
535 if(nHtmlMode & HTMLMODE_ON)
537 m_bHtmlMode = true;
538 m_xAutoWidthBox->set_sensitive(false);
540 FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
541 m_xEd1->SetMetric(aMetric);
542 m_xEd2->SetMetric(aMetric);
543 m_xEd3->SetMetric(aMetric);
544 m_xDistEd1->SetMetric(aMetric);
545 m_xDistEd2->SetMetric(aMetric);
546 //default spacing between cols = 0.5cm
547 m_xDistEd1->set_value(50, FieldUnit::CM);
548 m_xDistEd2->set_value(50, FieldUnit::CM);
550 m_xColMgr.reset(new SwColMgr(*rSet));
551 m_nCols = m_xColMgr->GetCount() ;
552 m_xCLNrEdt->set_max(std::max(o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_max()), m_nCols));
554 if(m_bFrame)
556 if(m_bFormat) // there is no size here
557 m_xColMgr->SetActualWidth(FRAME_FORMAT_WIDTH);
558 else
560 const SwFormatFrameSize& rSize = rSet->Get(RES_FRM_SIZE);
561 const SvxBoxItem& rBox = rSet->Get(RES_BOX);
562 m_xColMgr->SetActualWidth(o3tl::narrowing<sal_uInt16>(rSize.GetSize().Width()) - rBox.GetSmallestDistance());
565 if (m_xBalanceColsCB->get_visible())
567 if( const SwFormatNoBalancedColumns* pItem = rSet->GetItemIfSet( RES_COLUMNBALANCE, false ) )
568 m_xBalanceColsCB->set_active(!pItem->GetValue());
569 else
570 m_xBalanceColsCB->set_active(true);
573 //text direction
574 if( SfxItemState::DEFAULT <= rSet->GetItemState( RES_FRAMEDIR ) )
576 const SvxFrameDirectionItem& rItem = rSet->Get(RES_FRAMEDIR);
577 SvxFrameDirection nVal = rItem.GetValue();
578 m_xTextDirectionLB->set_active_id(nVal);
579 m_xTextDirectionLB->save_value();
582 Init();
583 ActivatePage( *rSet );
586 // create TabPage
587 std::unique_ptr<SfxTabPage> SwColumnPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
589 return std::make_unique<SwColumnPage>(pPage, pController, *rSet);
592 // stuff attributes into the Set when OK
593 bool SwColumnPage::FillItemSet(SfxItemSet *rSet)
595 // set in ItemSet;
596 // the current settings are already present
598 const SfxPoolItem* pOldItem;
599 const SwFormatCol& rCol = m_xColMgr->GetColumns();
600 if(nullptr == (pOldItem = GetOldItem( *rSet, RES_COL )) ||
601 rCol != *pOldItem )
602 rSet->Put(rCol);
604 if (m_xBalanceColsCB->get_visible())
606 rSet->Put(SwFormatNoBalancedColumns(!m_xBalanceColsCB->get_active()));
608 if (m_xTextDirectionLB->get_visible())
610 if (m_xTextDirectionLB->get_value_changed_from_saved())
612 rSet->Put(SvxFrameDirectionItem(m_xTextDirectionLB->get_active_id(), RES_FRAMEDIR) );
615 return true;
618 // update ColumnManager
619 IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrListBox, weld::ComboBox&, void )
621 UpdateColMgr(*m_xLineWidthEdit);
624 IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrLineBox, SvtLineListBox&, void )
626 UpdateColMgr(*m_xLineWidthEdit);
629 IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrColorBox, ColorListBox&, void )
631 UpdateColMgr(*m_xLineWidthEdit);
634 IMPL_LINK_NOARG( SwColumnPage, UpdateColMgr, weld::MetricSpinButton&, void )
636 if (!m_xColMgr)
637 return;
638 tools::Long nGutterWidth = m_xColMgr->GetGutterWidth();
639 if (m_nCols > 1)
641 // Determine whether the most narrow column is too narrow
642 // for the adjusted column gap
643 tools::Long nMin = m_nColWidth[0];
645 for( sal_uInt16 i = 1; i < m_nCols; ++i )
646 nMin = std::min(nMin, m_nColWidth[i]);
648 bool bAutoWidth = m_xAutoWidthBox->get_active();
649 if(!bAutoWidth)
651 m_xColMgr->SetAutoWidth(false);
652 // when the user didn't allocate the whole width,
653 // add the missing amount to the last column.
654 tools::Long nSum = 0;
655 for(sal_uInt16 i = 0; i < m_nCols; ++i)
656 nSum += m_nColWidth[i];
657 nGutterWidth = 0;
658 for(sal_uInt16 i = 0; i < m_nCols - 1; ++i)
659 nGutterWidth += m_nColDist[i];
660 nSum += nGutterWidth;
662 tools::Long nMaxW = m_xColMgr->GetActualSize();
664 if( nSum < nMaxW )
665 m_nColWidth[m_nCols - 1] += nMaxW - nSum;
667 m_xColMgr->SetColWidth( 0, static_cast< sal_uInt16 >(m_nColWidth[0] + m_nColDist[0]/2) );
668 for( sal_uInt16 i = 1; i < m_nCols-1; ++i )
670 tools::Long nActDist = (m_nColDist[i] + m_nColDist[i - 1]) / 2;
671 m_xColMgr->SetColWidth( i, static_cast< sal_uInt16 >(m_nColWidth[i] + nActDist ));
673 m_xColMgr->SetColWidth( m_nCols-1, static_cast< sal_uInt16 >(m_nColWidth[m_nCols-1] + m_nColDist[m_nCols -2]/2) );
677 bool bEnable = isLineNotNone();
678 m_xLineHeightEdit->set_sensitive(bEnable);
679 m_xLineHeightLbl->set_sensitive(bEnable);
680 m_xLineWidthLbl->set_sensitive(bEnable);
681 m_xLineWidthEdit->set_sensitive(bEnable);
682 m_xLineColorDLB->set_sensitive(bEnable);
683 m_xLineColorLbl->set_sensitive(bEnable);
685 sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::PERCENT);
686 nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
687 nLineWidth,
688 m_xLineWidthEdit->get_digits(),
689 m_xLineWidthEdit->get_unit(), MapUnit::MapTwip ));
690 if( !bEnable )
691 m_xColMgr->SetNoLine();
692 else
694 m_xColMgr->SetLineWidthAndColor(
695 m_xLineTypeDLB->GetSelectEntryStyle(),
696 nLineWidth,
697 m_xLineColorDLB->GetSelectEntryColor() );
698 m_xColMgr->SetAdjust(SwColLineAdj(m_xLinePosDLB->get_active() + 1));
699 m_xColMgr->SetLineHeightPercent(static_cast<short>(m_xLineHeightEdit->get_value(FieldUnit::PERCENT)));
700 bEnable = m_xColMgr->GetLineHeightPercent() != 100;
702 m_xLinePosLbl->set_sensitive(bEnable);
703 m_xLinePosDLB->set_sensitive(bEnable);
705 //fdo#66815 if the values are going to be the same, don't update
706 //them to avoid the listbox selection resetting
707 if (nLineWidth != m_xLineTypeDLB->GetWidth())
708 m_xLineTypeDLB->SetWidth(nLineWidth);
709 Color aColor(m_xLineColorDLB->GetSelectEntryColor());
710 if (aColor != m_xLineTypeDLB->GetColor())
711 m_xLineTypeDLB->SetColor(aColor);
713 else
715 m_xColMgr->NoCols();
716 m_nCols = 0;
719 //set maximum values
720 m_xCLNrEdt->set_max(std::max(tools::Long(1),
721 std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / (nGutterWidth + MINLAY)) )));
723 //prompt example window
724 if(!m_bLockUpdate)
726 if(m_bFrame)
728 m_aFrameExampleWN.SetColumns(m_xColMgr->GetColumns());
729 m_aFrameExampleWN.Invalidate();
731 else
732 m_aPgeExampleWN.Invalidate();
736 void SwColumnPage::Init()
738 m_xCLNrEdt->set_value(m_nCols);
740 bool bAutoWidth = m_xColMgr->IsAutoWidth() || m_bHtmlMode;
741 m_xAutoWidthBox->set_active(bAutoWidth);
743 sal_Int32 nColumnWidthSum = 0;
744 // set the widths
745 for(sal_uInt16 i = 0; i < m_nCols; ++i)
747 m_nColWidth[i] = m_xColMgr->GetColWidth(i);
748 nColumnWidthSum += m_nColWidth[i];
749 if(i < m_nCols - 1)
750 m_nColDist[i] = m_xColMgr->GetGutterWidth(i);
753 if( 1 < m_nCols )
755 // #97495# make sure that the automatic column width's are always equal
756 if(bAutoWidth)
758 nColumnWidthSum /= m_nCols;
759 for(sal_uInt16 i = 0; i < m_nCols; ++i)
760 m_nColWidth[i] = nColumnWidthSum;
762 SwColLineAdj eAdj = m_xColMgr->GetAdjust();
763 if( COLADJ_NONE == eAdj ) // the dialog doesn't know a NONE!
765 eAdj = COLADJ_TOP;
766 //without Adjust no line type
767 m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
768 m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
770 else
772 // Need to multiply by 100 because of the 2 decimals
773 m_xLineWidthEdit->set_value( m_xColMgr->GetLineWidth() * 100, FieldUnit::TWIP);
774 m_xLineColorDLB->SelectEntry( m_xColMgr->GetLineColor() );
775 m_xLineTypeDLB->SelectEntry( m_xColMgr->GetLineStyle() );
776 m_xLineTypeDLB->SetWidth( m_xColMgr->GetLineWidth( ) );
777 m_xLineHeightEdit->set_value(m_xColMgr->GetLineHeightPercent(), FieldUnit::PERCENT);
780 m_xLinePosDLB->set_active( static_cast< sal_Int32 >(eAdj - 1) );
782 else
784 m_xLinePosDLB->set_active(0);
785 m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
786 m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
789 UpdateCols();
790 Update(nullptr);
792 // set maximum number of columns
793 // values below 1 are not allowed
794 m_xCLNrEdt->set_max(std::max(tools::Long(1),
795 std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / g_nMinWidth) )));
798 bool SwColumnPage::isLineNotNone() const
800 // nothing is turned off
801 return m_xLineTypeDLB->GetSelectEntryStyle() != SvxBorderLineStyle::NONE;
805 * The number of columns has changed -- here the controls for editing of the
806 * columns are en- or disabled according to the column number. In case there are
807 * more than nVisCols (=3) all Edit are being enabled and the buttons for
808 * scrolling too. Otherwise Edits are being enabled according to the column
809 * numbers; one column can not be edited.
811 void SwColumnPage::UpdateCols()
813 bool bEnableBtns= false;
814 bool bEnable12 = false;
815 bool bEnable3 = false;
816 const bool bEdit = !m_xAutoWidthBox->get_active();
817 if ( m_nCols > nVisCols )
819 bEnableBtns = !m_bHtmlMode;
820 bEnable12 = bEnable3 = bEdit;
822 else if( bEdit )
824 // here are purposely hardly any breaks
825 switch(m_nCols)
827 case 3: bEnable3 = true;
828 [[fallthrough]];
829 case 2: bEnable12= true; break;
830 default: /* do nothing */;
833 m_xEd1->set_sensitive(bEnable12);
834 bool bEnable = m_nCols > 1;
835 m_xDistEd1->set_sensitive(bEnable);
836 m_xAutoWidthBox->set_sensitive(bEnable && !m_bHtmlMode);
837 m_xEd2->set_sensitive(bEnable12);
838 m_xDistEd2->set_sensitive(bEnable3);
839 m_xEd3->set_sensitive(bEnable3);
840 m_xLbl1->set_sensitive(bEnable12);
841 m_xLbl2->set_sensitive(bEnable12);
842 m_xLbl3->set_sensitive(bEnable3);
843 m_xBtnBack->set_sensitive(bEnableBtns);
844 m_xBtnNext->set_sensitive(bEnableBtns);
846 m_xLineTypeDLB->set_sensitive( bEnable );
847 m_xLineTypeLbl->set_sensitive( bEnable );
849 if (bEnable)
851 bEnable = isLineNotNone();
854 //all these depend on > 1 column and line style != none
855 m_xLineHeightEdit->set_sensitive(bEnable);
856 m_xLineHeightLbl->set_sensitive(bEnable);
857 m_xLineWidthLbl->set_sensitive(bEnable);
858 m_xLineWidthEdit->set_sensitive(bEnable);
859 m_xLineColorDLB->set_sensitive(bEnable);
860 m_xLineColorLbl->set_sensitive(bEnable);
862 if (bEnable)
863 bEnable = m_xColMgr->GetLineHeightPercent() != 100;
865 //and these additionally depend on line height != 100%
866 m_xLinePosDLB->set_sensitive(bEnable);
867 m_xLinePosLbl->set_sensitive(bEnable);
870 void SwColumnPage::SetLabels( sal_uInt16 nVis )
872 //insert ~ before the last character, e.g. 1 -> ~1, 10 -> 1~0
873 const OUString sLbl( '~' );
875 const OUString sLbl1(OUString::number( nVis + 1 ));
876 m_xLbl1->set_label(sLbl1.replaceAt(sLbl1.getLength()-1, 0, sLbl));
878 const OUString sLbl2(OUString::number( nVis + 2 ));
879 m_xLbl2->set_label(sLbl2.replaceAt(sLbl2.getLength()-1, 0, sLbl));
881 const OUString sLbl3(OUString::number( nVis + 3 ));
882 m_xLbl3->set_label(sLbl3.replaceAt(sLbl3.getLength()-1, 0, sLbl));
884 const OUString sColumnWidth = SwResId( STR_ACCESS_COLUMN_WIDTH ) ;
885 m_xEd1->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl1));
886 m_xEd2->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl2));
887 m_xEd3->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl3));
889 const OUString sDist = SwResId( STR_ACCESS_PAGESETUP_SPACING ) ;
890 m_xDistEd1->set_accessible_name(
891 sDist.replaceFirst("%1", sLbl1).replaceFirst("%2", sLbl2));
893 m_xDistEd2->set_accessible_name(
894 sDist.replaceFirst("%1", sLbl2).replaceFirst("%2", sLbl3));
898 * Handler that is called at alteration of the column number. An alteration of
899 * the column number overwrites potential user's width settings; all columns
900 * are equally wide.
902 IMPL_LINK_NOARG(SwColumnPage, ColModify, weld::SpinButton&, void)
904 ColModify(/*bForceColReset=*/false);
907 void SwColumnPage::ColModify(bool bForceColReset)
909 m_nCols = o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_value());
910 //#107890# the handler is also called from LoseFocus()
911 //then no change has been made and thus no action should be taken
912 // #i17816# changing the displayed types within the ValueSet
913 //from two columns to two columns with different settings doesn't invalidate the
914 // example windows in ::ColModify()
915 if (!bForceColReset && m_xColMgr->GetCount() == m_nCols)
916 return;
918 if (!bForceColReset)
919 m_aDefaultVS.SetNoSelection();
920 tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
921 m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
922 for(sal_uInt16 i = 0; i < m_nCols; i++)
923 m_nColDist[i] = nDist;
924 m_nFirstVis = 0;
925 SetLabels( m_nFirstVis );
926 UpdateCols();
927 ResetColWidth();
928 Update(nullptr);
932 * Modify handler for an alteration of the column width or the column gap.
933 * These changes take effect time-displaced. With an alteration of the column
934 * width the automatic calculation of the column width is overruled; only an
935 * alteration of the column number leads back to that default.
937 IMPL_LINK(SwColumnPage, GapModify, weld::MetricSpinButton&, rMetricField, void)
939 if (m_nCols < 2)
940 return;
941 SwPercentField *pField = m_aPercentFieldsMap[&rMetricField];
942 assert(pField);
943 tools::Long nActValue = static_cast< tools::Long >(pField->DenormalizePercent(pField->get_value(FieldUnit::TWIP)));
944 if (m_xAutoWidthBox->get_active())
946 const tools::Long nMaxGap = static_cast< tools::Long >
947 ((m_xColMgr->GetActualSize() - m_nCols * MINLAY)/(m_nCols - 1));
948 if(nActValue > nMaxGap)
950 nActValue = nMaxGap;
951 m_xDistEd1->set_value(m_xDistEd1->NormalizePercent(nMaxGap), FieldUnit::TWIP);
953 m_xColMgr->SetGutterWidth(o3tl::narrowing<sal_uInt16>(nActValue));
954 for(sal_uInt16 i = 0; i < m_nCols; i++)
955 m_nColDist[i] = nActValue;
957 ResetColWidth();
958 UpdateCols();
960 else
962 const sal_uInt16 nVis = m_nFirstVis + ((pField == m_xDistEd2.get()) ? 1 : 0);
963 tools::Long nDiff = nActValue - m_nColDist[nVis];
964 if(nDiff)
966 tools::Long nLeft = m_nColWidth[nVis];
967 tools::Long nRight = m_nColWidth[nVis + 1];
968 if(nLeft + nRight + 2 * MINLAY < nDiff)
969 nDiff = nLeft + nRight - 2 * MINLAY;
970 if(nDiff < nRight - MINLAY)
972 nRight -= nDiff;
974 else
976 tools::Long nTemp = nDiff - nRight + MINLAY;
977 nRight = MINLAY;
978 if(nLeft > nTemp - MINLAY)
980 nLeft -= nTemp;
981 nTemp = 0;
983 else
985 nTemp -= nLeft + MINLAY;
986 nLeft = MINLAY;
988 nDiff = nTemp;
990 m_nColWidth[nVis] = nLeft;
991 m_nColWidth[nVis + 1] = nRight;
992 m_nColDist[nVis] += nDiff;
994 m_xColMgr->SetColWidth( nVis, sal_uInt16(nLeft) );
995 m_xColMgr->SetColWidth( nVis + 1, sal_uInt16(nRight) );
996 m_xColMgr->SetGutterWidth( sal_uInt16(m_nColDist[nVis]), nVis );
1000 Update(&rMetricField);
1003 IMPL_LINK(SwColumnPage, EdModify, weld::MetricSpinButton&, rEdit, void)
1005 SwPercentField *pField = m_aPercentFieldsMap[&rEdit];
1006 assert(pField);
1007 m_pModifiedField = pField;
1008 Timeout();
1011 // Handler behind the Checkbox for automatic width. When the box is checked
1012 // no explicit values for the column width can be entered.
1013 IMPL_LINK(SwColumnPage, AutoWidthHdl, weld::Toggleable&, rBox, void)
1015 tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
1016 m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
1017 for(sal_uInt16 i = 0; i < m_nCols; i++)
1018 m_nColDist[i] = nDist;
1019 if (rBox.get_active())
1021 m_xColMgr->SetGutterWidth(sal_uInt16(nDist));
1022 ResetColWidth();
1024 m_xColMgr->SetAutoWidth(rBox.get_active(), sal_uInt16(nDist));
1025 UpdateCols();
1026 Update(nullptr);
1029 // scroll up the contents of the edits
1030 IMPL_LINK_NOARG(SwColumnPage, Up, weld::Button&, void)
1032 if( m_nFirstVis )
1034 --m_nFirstVis;
1035 SetLabels( m_nFirstVis );
1036 Update(nullptr);
1040 // scroll down the contents of the edits.
1041 IMPL_LINK_NOARG(SwColumnPage, Down, weld::Button&, void)
1043 if( m_nFirstVis + nVisCols < m_nCols )
1045 ++m_nFirstVis;
1046 SetLabels( m_nFirstVis );
1047 Update(nullptr);
1051 // relict from ancient times - now directly without time handler; triggered by
1052 // an alteration of the column width or the column gap.
1053 void SwColumnPage::Timeout()
1055 SwPercentField *pField = m_pModifiedField;
1056 if (m_pModifiedField)
1058 // find the changed column
1059 sal_uInt16 nChanged = m_nFirstVis;
1060 if (m_pModifiedField == m_xEd2.get())
1061 ++nChanged;
1062 else if (m_pModifiedField == m_xEd3.get())
1063 nChanged += 2;
1065 tools::Long nNewWidth = static_cast< tools::Long >
1066 (m_pModifiedField->DenormalizePercent(m_pModifiedField->get_value(FieldUnit::TWIP)));
1067 tools::Long nDiff = nNewWidth - m_nColWidth[nChanged];
1069 // when it's the last column
1070 if(nChanged == m_nCols - 1)
1072 m_nColWidth[0] -= nDiff;
1073 if(m_nColWidth[0] < static_cast<tools::Long>(g_nMinWidth))
1075 nNewWidth -= g_nMinWidth - m_nColWidth[0];
1076 m_nColWidth[0] = g_nMinWidth;
1080 else if(nDiff)
1082 m_nColWidth[nChanged + 1] -= nDiff;
1083 if(m_nColWidth[nChanged + 1] < static_cast<tools::Long>(g_nMinWidth))
1085 nNewWidth -= g_nMinWidth - m_nColWidth[nChanged + 1];
1086 m_nColWidth[nChanged + 1] = g_nMinWidth;
1089 m_nColWidth[nChanged] = nNewWidth;
1090 m_pModifiedField = nullptr;
1093 Update(pField ? pField->get() : nullptr);
1096 // Update the view
1097 void SwColumnPage::Update(const weld::MetricSpinButton* pInteractiveField)
1099 m_xBalanceColsCB->set_sensitive(m_nCols > 1);
1100 if(m_nCols >= 2)
1102 sal_Int64 nCurrentValue, nNewValue;
1104 nCurrentValue = m_xEd1->NormalizePercent(m_xEd1->DenormalizePercent(m_xEd1->get_value(FieldUnit::TWIP)));
1105 nNewValue = m_xEd1->NormalizePercent(m_nColWidth[m_nFirstVis]);
1107 //fdo#87612 if we're interacting with this widget and the value will be the same
1108 //then leave it alone (i.e. don't change equivalent values of e.g. .8 -> 0.8)
1109 if (nNewValue != nCurrentValue || pInteractiveField != m_xEd1->get())
1110 m_xEd1->set_value(nNewValue, FieldUnit::TWIP);
1112 nCurrentValue = m_xDistEd1->NormalizePercent(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
1113 nNewValue = m_xDistEd1->NormalizePercent(m_nColDist[m_nFirstVis]);
1114 if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd1->get())
1115 m_xDistEd1->set_value(nNewValue, FieldUnit::TWIP);
1117 nCurrentValue = m_xEd2->NormalizePercent(m_xEd2->DenormalizePercent(m_xEd2->get_value(FieldUnit::TWIP)));
1118 nNewValue = m_xEd2->NormalizePercent(m_nColWidth[m_nFirstVis+1]);
1119 if (nNewValue != nCurrentValue || pInteractiveField != m_xEd2->get())
1120 m_xEd2->set_value(nNewValue, FieldUnit::TWIP);
1122 if(m_nCols >= 3)
1124 nCurrentValue = m_xDistEd2->NormalizePercent(m_xDistEd2->DenormalizePercent(m_xDistEd2->get_value(FieldUnit::TWIP)));
1125 nNewValue = m_xDistEd2->NormalizePercent(m_nColDist[m_nFirstVis+1]);
1126 if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd2->get())
1127 m_xDistEd2->set_value(nNewValue, FieldUnit::TWIP);
1129 nCurrentValue = m_xEd3->NormalizePercent(m_xEd3->DenormalizePercent(m_xEd3->get_value(FieldUnit::TWIP)));
1130 nNewValue = m_xEd3->NormalizePercent(m_nColWidth[m_nFirstVis+2]);
1131 if (nNewValue != nCurrentValue || pInteractiveField != m_xEd3->get())
1132 m_xEd3->set_value(nNewValue, FieldUnit::TWIP);
1134 else
1136 m_xEd3->set_text(OUString());
1137 m_xDistEd2->set_text(OUString());
1140 else
1142 m_xEd1->set_text(OUString());
1143 m_xEd2->set_text(OUString());
1144 m_xEd3->set_text(OUString());
1145 m_xDistEd1->set_text(OUString());
1146 m_xDistEd2->set_text(OUString());
1148 UpdateColMgr(*m_xLineWidthEdit);
1151 // Update Bsp
1152 void SwColumnPage::ActivatePage(const SfxItemSet& rSet)
1154 bool bVertical = false;
1155 if (SfxItemState::DEFAULT <= rSet.GetItemState(RES_FRAMEDIR))
1157 const SvxFrameDirectionItem& rDirItem =
1158 rSet.Get(RES_FRAMEDIR);
1159 bVertical = rDirItem.GetValue() == SvxFrameDirection::Vertical_RL_TB||
1160 rDirItem.GetValue() == SvxFrameDirection::Vertical_LR_TB;
1163 if (!m_bFrame)
1165 if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_PAGE_SIZE ))
1167 const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
1169 sal_uInt16 nActWidth;
1171 if (!bVertical)
1173 const SvxLRSpaceItem& rLRSpace = rSet.Get(RES_LR_SPACE);
1174 const SvxBoxItem& rBox = rSet.Get(RES_BOX);
1175 nActWidth = rSize.GetSize().Width() - rLRSpace.ResolveLeft({})
1176 - rLRSpace.ResolveRight({}) - rBox.GetSmallestDistance();
1178 else
1180 const SvxULSpaceItem& rULSpace = rSet.Get( RES_UL_SPACE );
1181 const SvxBoxItem& rBox = rSet.Get(RES_BOX);
1182 nActWidth = rSize.GetSize().Height()
1183 - rULSpace.GetUpper() - rULSpace.GetLower() - rBox.GetSmallestDistance();
1187 if( m_xColMgr->GetActualSize() != nActWidth)
1189 m_xColMgr->SetActualWidth(nActWidth);
1190 ColModify(/*bForceColReset=*/false);
1191 UpdateColMgr( *m_xLineWidthEdit );
1194 m_xFrameExampleWN->hide();
1195 m_aPgeExampleWN.UpdateExample(rSet, m_xColMgr.get());
1196 m_xPgeExampleWN->show();
1199 else
1201 m_xPgeExampleWN->hide();
1202 m_xFrameExampleWN->show();
1204 // Size
1205 const SwFormatFrameSize& rSize = rSet.Get(RES_FRM_SIZE);
1206 const SvxBoxItem& rBox = rSet.Get(RES_BOX);
1208 sal_uInt16 nTotalWish;
1209 if (m_bFormat)
1210 nTotalWish = FRAME_FORMAT_WIDTH;
1211 else
1213 tools::Long const nDistance = rBox.GetSmallestDistance();
1214 nTotalWish = (!bVertical ? rSize.GetWidth() : rSize.GetHeight()) - 2 * nDistance;
1217 // set maximum values of column width
1218 SetPageWidth(nTotalWish);
1220 if(m_xColMgr->GetActualSize() != nTotalWish)
1222 m_xColMgr->SetActualWidth(nTotalWish);
1223 Init();
1225 bool bPercent;
1226 // only relative data in frame format
1227 if ( m_bFormat || (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED) )
1229 // set value for 100%
1230 m_xEd1->SetRefValue(nTotalWish);
1231 m_xEd2->SetRefValue(nTotalWish);
1232 m_xEd3->SetRefValue(nTotalWish);
1233 m_xDistEd1->SetRefValue(nTotalWish);
1234 m_xDistEd2->SetRefValue(nTotalWish);
1236 // switch to %-view
1237 bPercent = true;
1239 else
1240 bPercent = false;
1242 m_xEd1->ShowPercent(bPercent);
1243 m_xEd2->ShowPercent(bPercent);
1244 m_xEd3->ShowPercent(bPercent);
1245 m_xDistEd1->ShowPercent(bPercent);
1246 m_xDistEd2->ShowPercent(bPercent);
1247 m_xDistEd1->SetMetricFieldMin(0);
1248 m_xDistEd2->SetMetricFieldMin(0);
1250 Update(nullptr);
1253 DeactivateRC SwColumnPage::DeactivatePage(SfxItemSet *_pSet)
1255 if(_pSet)
1256 FillItemSet(_pSet);
1258 return DeactivateRC::LeavePage;
1261 IMPL_LINK(SwColumnPage, SetDefaultsHdl, ValueSet *, pVS, void)
1263 const sal_uInt16 nItem = pVS->GetSelectedItemId();
1264 if( nItem < 4 )
1266 m_xCLNrEdt->set_value(nItem);
1267 m_xAutoWidthBox->set_active(true);
1268 m_xDistEd1->set_value(50, FieldUnit::CM);
1269 ColModify(/*bForceColReset=*/true);
1271 else
1273 m_bLockUpdate = true;
1274 m_xCLNrEdt->set_value(2);
1275 m_xAutoWidthBox->set_active(false);
1276 m_xDistEd1->set_value(50, FieldUnit::CM);
1277 ColModify(/*bForceColReset=*/true);
1278 // now set the width ratio to 2 : 1 or 1 : 2 respectively
1279 const tools::Long nSmall = static_cast< tools::Long >(m_xColMgr->GetActualSize() / 3);
1280 if(nItem == 4)
1282 m_xEd2->set_value(m_xEd2->NormalizePercent(nSmall), FieldUnit::TWIP);
1283 m_pModifiedField = m_xEd2.get();
1285 else
1287 m_xEd1->set_value(m_xEd1->NormalizePercent(nSmall), FieldUnit::TWIP);
1288 m_pModifiedField = m_xEd1.get();
1290 m_bLockUpdate = false;
1291 Timeout();
1296 void SwColumnPage::SetFrameMode(bool bMod)
1298 m_bFrame = bMod;
1301 void SwColumnPage::SetInSection(bool bSet)
1303 if(!SvtCTLOptions::IsCTLFontEnabled())
1304 return;
1306 m_xTextDirectionFT->set_visible(bSet);
1307 m_xTextDirectionLB->set_visible(bSet);
1310 void ColumnValueSet::UserDraw(const UserDrawEvent& rUDEvt)
1312 vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
1313 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1315 tools::Rectangle aRect = rUDEvt.GetRect();
1316 const sal_uInt16 nItemId = rUDEvt.GetItemId();
1317 tools::Long nRectWidth = aRect.GetWidth();
1318 tools::Long nRectHeight = aRect.GetHeight();
1320 Point aBLPos = aRect.TopLeft();
1321 pDev->Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
1322 pDev->SetFillColor(rStyleSettings.GetFieldColor());
1323 pDev->SetLineColor(rStyleSettings.GetFieldTextColor());
1325 tools::Long nStep = std::abs(std::abs(nRectHeight * 95 /100) / 11);
1326 tools::Long nTop = (nRectHeight - 11 * nStep ) / 2;
1327 sal_uInt16 nCols = 0;
1328 tools::Long nStarts[3];
1329 tools::Long nEnds[3];
1330 nStarts[0] = nRectWidth * 10 / 100;
1331 switch( nItemId )
1333 case 1:
1334 nEnds[0] = nRectWidth * 9 / 10;
1335 nCols = 1;
1336 break;
1337 case 2: nCols = 2;
1338 nEnds[0] = nRectWidth * 45 / 100;
1339 nStarts[1] = nEnds[0] + nStep;
1340 nEnds[1] = nRectWidth * 9 / 10;
1341 break;
1342 case 3: nCols = 3;
1343 nEnds[0] = nRectWidth * 30 / 100;
1344 nStarts[1] = nEnds[0] + nStep;
1345 nEnds[1] = nRectWidth * 63 / 100;
1346 nStarts[2] = nEnds[1] + nStep;
1347 nEnds[2] = nRectWidth * 9 / 10;
1348 break;
1349 case 4: nCols = 2;
1350 nEnds[0] = nRectWidth * 63 / 100;
1351 nStarts[1] = nEnds[0] + nStep;
1352 nEnds[1] = nRectWidth * 9 / 10;
1353 break;
1354 case 5: nCols = 2;
1355 nEnds[0] = nRectWidth * 30 / 100;
1356 nStarts[1] = nEnds[0] + nStep;
1357 nEnds[1] = nRectWidth * 9 / 10;
1358 break;
1360 for(sal_uInt16 j = 0; j < nCols; j++ )
1362 Point aStart(aBLPos.X() + nStarts[j], 0);
1363 Point aEnd(aBLPos.X() + nEnds[j], 0);
1364 for( sal_uInt16 i = 0; i < 12; i ++)
1366 aStart.setY( aBLPos.Y() + nTop + i * nStep);
1367 aEnd.setY( aStart.Y() );
1368 pDev->DrawLine(aStart, aEnd);
1371 pDev->Pop();
1374 void ColumnValueSet::StyleUpdated()
1376 SetFormat();
1377 Invalidate();
1378 ValueSet::StyleUpdated();
1381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */