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 .
21 #include <swtypes.hxx>
22 #include <hintids.hxx>
23 #include <strings.hrc>
24 #include <sfx2/objsh.hxx>
25 #include <sfx2/htmlmode.hxx>
26 #include <svl/eitem.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/intitem.hxx>
29 #include <fmtline.hxx>
30 #include <numpara.hxx>
32 #include <officecfg/Office/Common.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/frame.hxx>
35 #include <sfx2/viewsh.hxx>
37 // tdf#115871 - reset outline and list options to parent settings
38 const WhichRangesContainer
SwParagraphNumTabPage::s_aPageRg(
39 svl::Items
<RES_LINENUMBER
, RES_LINENUMBER
, SID_ATTR_PARA_NUMRULE
, SID_ATTR_PARA_NUMRULE
,
40 SID_ATTR_PARA_OUTLINE_LEVEL
, SID_ATTR_PARA_OUTLINE_LEVEL
, FN_NUMBER_NEWSTART
,
41 FN_NUMBER_NEWSTART_AT
>);
43 SwParagraphNumTabPage::SwParagraphNumTabPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rAttr
)
44 : SfxTabPage(pPage
, pController
, u
"modules/swriter/ui/numparapage.ui"_ustr
, u
"NumParaPage"_ustr
, &rAttr
)
45 , msOutlineNumbering(SwResId(STR_OUTLINE_NUMBERING
))
47 , m_bCurNumrule(false)
48 , m_xOutlineStartBX(m_xBuilder
->weld_widget(u
"boxOUTLINE"_ustr
))
49 , m_xOutlineLvLB(m_xBuilder
->weld_combo_box(u
"comboLB_OUTLINE_LEVEL"_ustr
))
50 , m_xNumberStyleBX(m_xBuilder
->weld_widget(u
"boxNUMBER_STYLE"_ustr
))
51 , m_xNumberStyleLB(m_xBuilder
->weld_combo_box(u
"comboLB_NUMBER_STYLE"_ustr
))
52 , m_xEditNumStyleBtn(m_xBuilder
->weld_button(u
"editnumstyle"_ustr
))
53 , m_xListLvBX(m_xBuilder
->weld_widget(u
"boxLIST_LEVEL"_ustr
))
54 , m_xListLvLB(m_xBuilder
->weld_combo_box(u
"comboLB_LIST_LEVEL"_ustr
))
55 , m_xNewStartCB(m_xBuilder
->weld_check_button(u
"checkCB_NEW_START"_ustr
))
56 , m_xNewStartBX(m_xBuilder
->weld_widget(u
"boxNEW_START"_ustr
))
57 , m_xNewStartNumberCB(m_xBuilder
->weld_check_button(u
"checkCB_NUMBER_NEW_START"_ustr
))
58 , m_xNewStartNF(m_xBuilder
->weld_spin_button(u
"spinNF_NEW_START"_ustr
))
59 , m_xCountParaFram(m_xBuilder
->weld_widget(u
"frameFL_COUNT_PARA"_ustr
))
60 , m_xCountParaCB(m_xBuilder
->weld_check_button(u
"checkCB_COUNT_PARA"_ustr
))
61 , m_xRestartParaCountCB(m_xBuilder
->weld_check_button(u
"checkCB_RESTART_PARACOUNT"_ustr
))
62 , m_xRestartBX(m_xBuilder
->weld_widget(u
"boxRESTART_NO"_ustr
))
63 , m_xRestartNF(m_xBuilder
->weld_spin_button(u
"spinNF_RESTART_PARA"_ustr
))
65 m_xNewStartCB
->set_state(TRISTATE_FALSE
);
66 m_xNewStartNumberCB
->set_state(TRISTATE_FALSE
);
67 m_xCountParaCB
->set_state(TRISTATE_FALSE
);
68 m_xRestartParaCountCB
->set_state(TRISTATE_FALSE
);
69 m_xEditNumStyleBtn
->set_sensitive(false);
71 const SfxUInt16Item
* pItem
= rAttr
.GetItemIfSet(SID_HTML_MODE
, false);
74 if (SfxObjectShell
* pObjSh
= SfxObjectShell::Current())
75 pItem
= pObjSh
->GetItem(SID_HTML_MODE
);
79 const sal_uInt16 nHtmlMode
= pItem
->GetValue();
81 if (HTMLMODE_ON
& nHtmlMode
)
82 m_xCountParaFram
->hide();
85 m_xNewStartCB
->connect_toggled(LINK(this, SwParagraphNumTabPage
, NewStartHdl_Impl
));
86 m_xNewStartNumberCB
->connect_toggled(LINK(this, SwParagraphNumTabPage
, NewStartHdl_Impl
));
87 m_xNumberStyleLB
->connect_changed(LINK(this, SwParagraphNumTabPage
, StyleHdl_Impl
));
88 m_xCountParaCB
->connect_toggled(LINK(this, SwParagraphNumTabPage
, LineCountHdl_Impl
));
89 m_xRestartParaCountCB
->connect_toggled(LINK(this, SwParagraphNumTabPage
, LineCountHdl_Impl
));
90 m_xNumberStyleLB
->connect_changed(LINK(this, SwParagraphNumTabPage
, EditNumStyleSelectHdl_Impl
));
91 m_xEditNumStyleBtn
->connect_clicked(LINK(this, SwParagraphNumTabPage
, EditNumStyleHdl_Impl
));
93 if (officecfg::Office::Common::Misc::ExperimentalMode::get())
99 SwParagraphNumTabPage::~SwParagraphNumTabPage()
103 std::unique_ptr
<SfxTabPage
> SwParagraphNumTabPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rSet
)
105 return std::make_unique
<SwParagraphNumTabPage
>(pPage
, pController
, *rSet
);
108 bool SwParagraphNumTabPage::FillItemSet( SfxItemSet
* rSet
)
110 if (m_xOutlineLvLB
->get_value_changed_from_saved())
112 const sal_uInt16 aOutlineLv
= m_xOutlineLvLB
->get_active();
113 const SfxUInt16Item
* pOldOutlineLv
= GetOldItem( *rSet
, SID_ATTR_PARA_OUTLINE_LEVEL
);
116 std::unique_ptr
<SfxUInt16Item
> pOutlineLv(pOldOutlineLv
->Clone());
117 pOutlineLv
->SetValue( aOutlineLv
);
118 rSet
->Put(std::move(pOutlineLv
));
121 // Does List Level need to be set to be the same as Outline Level?
122 if (!m_xListLvLB
->get_active() && m_xListLvBX
->get_visible()
123 && !m_xListLvLB
->get_value_changed_from_saved())
125 sal_Int16 nListLevel
= std::max
<sal_Int16
>(1, aOutlineLv
);
126 --nListLevel
; // Outline Level is 1 based. List Level is zero based.
127 rSet
->Put(SfxInt16Item(RES_PARATR_LIST_LEVEL
, nListLevel
));
132 if (m_xListLvLB
->get_value_changed_from_saved())
134 if (m_xListLvBX
->get_visible())
136 sal_Int16 nListLevel
= m_xListLvLB
->get_active();
137 // Does List Level need to be set to be the same as Outline Level?
140 nListLevel
= std::max
<sal_Int16
>(1, m_xOutlineLvLB
->get_active());
142 --nListLevel
; // List Level is zero based, but both listboxes are 1-based.
144 rSet
->Put(SfxInt16Item(RES_PARATR_LIST_LEVEL
, nListLevel
));
149 if (m_xNumberStyleLB
->get_value_changed_from_saved())
152 if (m_xNumberStyleLB
->get_active())
153 aStyle
= m_xNumberStyleLB
->get_active_text();
154 const SfxStringItem
* pOldRule
= static_cast<const SfxStringItem
*>(GetOldItem( *rSet
, SID_ATTR_PARA_NUMRULE
));
157 std::unique_ptr
<SfxStringItem
> pRule(pOldRule
->Clone());
158 pRule
->SetValue(aStyle
);
159 rSet
->Put(std::move(pRule
));
163 if (m_xNewStartCB
->get_state_changed_from_saved() ||
164 m_xNewStartNumberCB
->get_state_changed_from_saved()||
165 m_xNewStartNF
->get_value_changed_from_saved())
168 bool bNewStartChecked
= TRISTATE_TRUE
== m_xNewStartCB
->get_state();
169 bool bNumberNewStartChecked
= TRISTATE_TRUE
== m_xNewStartNumberCB
->get_state();
170 rSet
->Put(SfxBoolItem(FN_NUMBER_NEWSTART
, bNewStartChecked
));
171 rSet
->Put(SfxUInt16Item(FN_NUMBER_NEWSTART_AT
,
172 bNumberNewStartChecked
&& bNewStartChecked
? o3tl::narrowing
<sal_uInt16
>(m_xNewStartNF
->get_value()) : USHRT_MAX
));
175 if (m_xCountParaCB
->get_state_changed_from_saved()||
176 m_xRestartParaCountCB
->get_state_changed_from_saved() ||
177 m_xRestartNF
->get_value_changed_from_saved())
179 SwFormatLineNumber aFormat
;
180 aFormat
.SetStartValue( static_cast< sal_uLong
>(m_xRestartParaCountCB
->get_state() == TRISTATE_TRUE
?
181 m_xRestartNF
->get_value() : 0 ));
182 aFormat
.SetCountLines(m_xCountParaCB
->get_active());
189 void SwParagraphNumTabPage::ChangesApplied()
191 m_xOutlineLvLB
->save_value();
192 m_xNumberStyleLB
->save_value();
193 m_xListLvLB
->save_value();
194 m_xNewStartCB
->save_state();
195 m_xNewStartNumberCB
->save_state();
196 m_xCountParaCB
->save_state();
197 m_xRestartParaCountCB
->save_state();
198 m_xRestartNF
->save_value();
201 void SwParagraphNumTabPage::Reset(const SfxItemSet
* rSet
)
203 bool bHasNumberStyle
= false;
205 SfxItemState eItemState
= rSet
->GetItemState( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL
) );
207 sal_Int16 nOutlineLv
= 1; // 0 is Text Body, 1 is level 1
208 if( eItemState
>= SfxItemState::DEFAULT
)
210 nOutlineLv
= rSet
->Get( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL
) ).GetValue();
211 m_xOutlineLvLB
->set_active(nOutlineLv
) ;
215 m_xOutlineLvLB
->set_active(-1);
217 m_xOutlineLvLB
->save_value();
219 eItemState
= rSet
->GetItemState(RES_PARATR_LIST_LEVEL
);
220 if (eItemState
>= SfxItemState::DEFAULT
)
222 sal_Int16 nListLevel
= rSet
->Get(RES_PARATR_LIST_LEVEL
).GetValue(); // 0 is level 1
223 // Although listLevel doesn't have outline's "Text Body" level, treat it the same as level 1
224 // so that if the outline level is either 0 or 1, it is considered equal to list level 1.
225 // This is a rather crucial discrepancy - otherwise the user will rarely see
226 // list level using the special "Same as outline level,
227 // and the highly desirable state of keeping the two in sync will rarely be achieved.
228 if ((!nOutlineLv
&& !nListLevel
) || nListLevel
== nOutlineLv
- 1)
229 m_xListLvLB
->set_active(0); // highly encourage using "Same as outline level"
231 m_xListLvLB
->set_active(nListLevel
+ 1);
237 m_xListLvLB
->save_value();
239 eItemState
= rSet
->GetItemState( GetWhich(SID_ATTR_PARA_NUMRULE
) );
241 if( eItemState
>= SfxItemState::DEFAULT
)
243 OUString aStyle
= static_cast<const SfxStringItem
&>(rSet
->Get( GetWhich(SID_ATTR_PARA_NUMRULE
) )).GetValue();
245 aStyle
= m_xNumberStyleLB
->get_text(0);
247 if( aStyle
== "Outline")
249 if (m_xNumberStyleLB
->find_id(u
"pseudo"_ustr
) == -1)
251 // tdf#145804 show "Chapter Numbering"
252 m_xNumberStyleLB
->append(u
"pseudo"_ustr
, msOutlineNumbering
);
254 m_xNumberStyleLB
->set_active_id(u
"pseudo"_ustr
);
255 m_xNumberStyleLB
->save_value();
258 m_xNumberStyleLB
->set_active_text(aStyle
);
260 bHasNumberStyle
= true;
264 m_xNumberStyleLB
->set_active(-1);
267 if (m_xNumberStyleBX
->get_sensitive())
268 EditNumStyleSelectHdl_Impl(*m_xNumberStyleLB
);
270 m_xNumberStyleLB
->save_value();
272 eItemState
= rSet
->GetItemState( FN_NUMBER_NEWSTART
);
273 if(eItemState
> SfxItemState::DEFAULT
)
275 m_bCurNumrule
= true;
276 const SfxBoolItem
& rStart
= static_cast<const SfxBoolItem
&>(rSet
->Get(FN_NUMBER_NEWSTART
));
278 m_xNewStartCB
->set_state(rStart
.GetValue() ? TRISTATE_TRUE
: TRISTATE_FALSE
);
281 m_xNewStartCB
->set_state(bHasNumberStyle
? TRISTATE_FALSE
: TRISTATE_INDET
);
283 m_xNewStartCB
->save_state();
285 eItemState
= rSet
->GetItemState( FN_NUMBER_NEWSTART_AT
);
286 if( eItemState
> SfxItemState::DEFAULT
)
288 const sal_uInt16 nNewStart
= rSet
->Get(FN_NUMBER_NEWSTART_AT
).GetValue();
289 const bool bNotMax
= USHRT_MAX
!= nNewStart
;
290 m_xNewStartNumberCB
->set_active(bNotMax
);
291 m_xNewStartNF
->set_value(bNotMax
? nNewStart
: 1);
294 m_xNewStartCB
->set_state(TRISTATE_INDET
);
295 NewStartHdl_Impl(*m_xNewStartCB
);
296 m_xNewStartNF
->save_value();
297 m_xNewStartNumberCB
->save_state();
298 StyleHdl_Impl(*m_xNumberStyleLB
);
299 if( SfxItemState::DEFAULT
<= rSet
->GetItemState(RES_LINENUMBER
))
301 const SwFormatLineNumber
& rNum
= rSet
->Get(RES_LINENUMBER
);
302 sal_uLong nStartValue
= rNum
.GetStartValue();
303 bool bCount
= rNum
.IsCount();
304 m_xCountParaCB
->set_state(bCount
? TRISTATE_TRUE
: TRISTATE_FALSE
);
305 m_xRestartParaCountCB
->set_state(0 != nStartValue
? TRISTATE_TRUE
: TRISTATE_FALSE
);
306 m_xRestartNF
->set_value(nStartValue
== 0 ? 1 : nStartValue
);
307 LineCountHdl_Impl(*m_xCountParaCB
);
311 m_xCountParaCB
->set_state(TRISTATE_INDET
);
312 m_xRestartParaCountCB
->set_state(TRISTATE_INDET
);
314 m_xCountParaCB
->save_state();
315 m_xRestartParaCountCB
->save_state();
316 m_xRestartNF
->save_value();
321 void SwParagraphNumTabPage::DisableOutline()
323 m_xOutlineStartBX
->set_sensitive(false);
324 m_xOutlineStartBX
->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED
) );
327 void SwParagraphNumTabPage::DisableNumbering()
329 m_xNumberStyleBX
->set_sensitive(false);
330 m_xNumberStyleBX
->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED
) );
331 m_xListLvBX
->set_sensitive(false);
334 void SwParagraphNumTabPage::EnableNewStart()
336 m_xNewStartCB
->show();
337 m_xNewStartBX
->show();
340 IMPL_LINK_NOARG(SwParagraphNumTabPage
, NewStartHdl_Impl
, weld::Toggleable
&, void)
342 bool bEnable
= m_xNewStartCB
->get_active();
343 m_xNewStartNumberCB
->set_sensitive(bEnable
);
344 m_xNewStartNF
->set_sensitive(bEnable
&& m_xNewStartNumberCB
->get_active());
347 IMPL_LINK_NOARG(SwParagraphNumTabPage
, LineCountHdl_Impl
, weld::Toggleable
&, void)
349 m_xRestartParaCountCB
->set_sensitive(m_xCountParaCB
->get_active());
351 bool bEnableRestartValue
= m_xRestartParaCountCB
->get_sensitive() &&
352 m_xRestartParaCountCB
->get_active();
353 m_xRestartBX
->set_sensitive(bEnableRestartValue
);
356 IMPL_LINK_NOARG(SwParagraphNumTabPage
, EditNumStyleSelectHdl_Impl
, weld::ComboBox
&, void)
358 int numSelectPos
= m_xNumberStyleLB
->get_active();
359 // 0 is "None" and -1 is unselected state and a "pseudo" is uneditable "Chapter Numbering"
360 if (numSelectPos
== 0 || numSelectPos
== -1 || m_xNumberStyleLB
->get_active_id() == "pseudo")
362 m_xEditNumStyleBtn
->set_sensitive(false);
363 m_xListLvBX
->set_sensitive(false);
367 m_xEditNumStyleBtn
->set_sensitive(true);
368 m_xListLvBX
->set_sensitive(true);
372 IMPL_LINK_NOARG(SwParagraphNumTabPage
, EditNumStyleHdl_Impl
, weld::Button
&, void)
374 OUString
aTemplName(m_xNumberStyleLB
->get_active_text());
375 ExecuteEditNumStyle_Impl( SID_STYLE_EDIT
, aTemplName
, SfxStyleFamily::Pseudo
);
378 // Internal: Perform functions through the Dispatcher
379 void SwParagraphNumTabPage::ExecuteEditNumStyle_Impl(
380 sal_uInt16 nId
, const OUString
&rStr
, SfxStyleFamily nFamily
)
382 SfxViewShell
* pViewShell
= SfxViewShell::Current();
387 SfxDispatcher
* pDispatcher
= pViewShell
->GetDispatcher();
388 SfxStringItem
aItem(nId
, rStr
);
389 SfxUInt16Item
aFamily(SID_STYLE_FAMILY
, static_cast<sal_uInt16
>(nFamily
));
390 const SfxPoolItem
* pItems
[ 3 ];
391 sal_uInt16 nCount
= 0;
392 if( !rStr
.isEmpty() )
393 pItems
[ nCount
++ ] = &aItem
;
394 pItems
[ nCount
++ ] = &aFamily
;
396 pItems
[ nCount
++ ] = nullptr;
398 // tdf#145363 we want the current dialog to be the parent of the new dialog
399 weld::Window
* pDialogParent
= GetFrameWeld();
400 css::uno::Any
aAny(pDialogParent
->GetXWindow());
401 SfxUnoAnyItem
aDialogParent(SID_DIALOG_PARENT
, aAny
);
402 const SfxPoolItem
* pInternalItems
[ 2 ];
403 pInternalItems
[ 0 ] = &aDialogParent
;
404 pInternalItems
[ 1 ] = nullptr;
406 pDispatcher
->Execute(
407 nId
, SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
,
408 pItems
, 0, pInternalItems
);
411 IMPL_LINK(SwParagraphNumTabPage
, StyleHdl_Impl
, weld::ComboBox
&, rBox
, void)
413 bool bEnable
= m_bCurNumrule
|| rBox
.get_active() > 0;
414 m_xNewStartCB
->set_sensitive(bEnable
);
415 NewStartHdl_Impl(*m_xNewStartCB
);
418 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */