xref: /core/sw/source/ui/chrdlg/numpara.cxx (revision 88afa134)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <cmdid.h>
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>
31 
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/frame.hxx>
34 #include <sfx2/viewsh.hxx>
35 
36 const WhichRangesContainer SwParagraphNumTabPage::aPageRg(svl::Items<FN_NUMBER_NEWSTART, FN_NUMBER_NEWSTART_AT>);
37 
38 SwParagraphNumTabPage::SwParagraphNumTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
39     : SfxTabPage(pPage, pController, "modules/swriter/ui/numparapage.ui", "NumParaPage", &rAttr)
40     , msOutlineNumbering(SwResId(STR_OUTLINE_NUMBERING ))
41     , bModified(false)
42     , bCurNumrule(false)
43     , m_xOutlineStartBX(m_xBuilder->weld_widget("boxOUTLINE"))
44     , m_xOutlineLvLB(m_xBuilder->weld_combo_box("comboLB_OUTLINE_LEVEL"))
45     , m_xNumberStyleBX(m_xBuilder->weld_widget("boxNUMBER_STYLE"))
46     , m_xNumberStyleLB(m_xBuilder->weld_combo_box("comboLB_NUMBER_STYLE"))
47     , m_xEditNumStyleBtn(m_xBuilder->weld_button("editnumstyle"))
48     , m_xNewStartCB(m_xBuilder->weld_check_button("checkCB_NEW_START"))
49     , m_xNewStartBX(m_xBuilder->weld_widget("boxNEW_START"))
50     , m_xNewStartNumberCB(m_xBuilder->weld_check_button("checkCB_NUMBER_NEW_START"))
51     , m_xNewStartNF(m_xBuilder->weld_spin_button("spinNF_NEW_START"))
52     , m_xCountParaFram(m_xBuilder->weld_widget("frameFL_COUNT_PARA"))
53     , m_xCountParaCB(m_xBuilder->weld_check_button("checkCB_COUNT_PARA"))
54     , m_xRestartParaCountCB(m_xBuilder->weld_check_button("checkCB_RESTART_PARACOUNT"))
55     , m_xRestartBX(m_xBuilder->weld_widget("boxRESTART_NO"))
56     , m_xRestartNF(m_xBuilder->weld_spin_button("spinNF_RESTART_PARA"))
57 {
58     m_xNewStartCB->set_state(TRISTATE_FALSE);
59     m_xNewStartNumberCB->set_state(TRISTATE_FALSE);
60     m_xCountParaCB->set_state(TRISTATE_FALSE);
61     m_xRestartParaCountCB->set_state(TRISTATE_FALSE);
62     m_xEditNumStyleBtn->set_sensitive(false);
63 
64     const SfxPoolItem* pItem;
65     SfxObjectShell* pObjSh;
66     if(SfxItemState::SET == rAttr.GetItemState(SID_HTML_MODE, false, &pItem) ||
67         ( nullptr != ( pObjSh = SfxObjectShell::Current()) &&
68           nullptr != (pItem = pObjSh->GetItem(SID_HTML_MODE))))
69     {
70         const sal_uInt16 nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
71 
72         if (HTMLMODE_ON & nHtmlMode)
73             m_xCountParaFram->hide();
74     }
75 
76     m_xNewStartCB->connect_toggled(LINK(this, SwParagraphNumTabPage, NewStartHdl_Impl));
77     m_xNewStartNumberCB->connect_toggled(LINK(this, SwParagraphNumTabPage, NewStartHdl_Impl));
78     m_xNumberStyleLB->connect_changed(LINK(this, SwParagraphNumTabPage, StyleHdl_Impl));
79     m_xCountParaCB->connect_toggled(LINK(this, SwParagraphNumTabPage, LineCountHdl_Impl));
80     m_xRestartParaCountCB->connect_toggled(LINK(this, SwParagraphNumTabPage, LineCountHdl_Impl));
81     m_xNumberStyleLB->connect_changed(LINK(this, SwParagraphNumTabPage, EditNumStyleSelectHdl_Impl));
82     m_xEditNumStyleBtn->connect_clicked(LINK(this, SwParagraphNumTabPage, EditNumStyleHdl_Impl));
83 }
84 
85 SwParagraphNumTabPage::~SwParagraphNumTabPage()
86 {
87 }
88 
89 std::unique_ptr<SfxTabPage> SwParagraphNumTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
90 {
91     return std::make_unique<SwParagraphNumTabPage>(pPage, pController, *rSet);
92 }
93 
94 bool SwParagraphNumTabPage::FillItemSet( SfxItemSet* rSet )
95 {
96     if (m_xOutlineLvLB->get_value_changed_from_saved())
97     {
98         const sal_uInt16 aOutlineLv = m_xOutlineLvLB->get_active();
99         const SfxUInt16Item* pOldOutlineLv = static_cast<const SfxUInt16Item*>(GetOldItem( *rSet, SID_ATTR_PARA_OUTLINE_LEVEL));
100         if (pOldOutlineLv)
101         {
102             std::unique_ptr<SfxUInt16Item> pOutlineLv(pOldOutlineLv->Clone());
103             pOutlineLv->SetValue( aOutlineLv );
104             rSet->Put(std::move(pOutlineLv));
105             bModified = true;
106         }
107     }
108 
109     if (m_xNumberStyleLB->get_value_changed_from_saved())
110     {
111         OUString aStyle;
112         if (m_xNumberStyleLB->get_active())
113             aStyle = m_xNumberStyleLB->get_active_text();
114         const SfxStringItem* pOldRule = static_cast<const SfxStringItem*>(GetOldItem( *rSet, SID_ATTR_PARA_NUMRULE));
115         if (pOldRule)
116         {
117             std::unique_ptr<SfxStringItem> pRule(pOldRule->Clone());
118             pRule->SetValue(aStyle);
119             rSet->Put(std::move(pRule));
120             bModified = true;
121         }
122     }
123     if (m_xNewStartCB->get_state_changed_from_saved() ||
124         m_xNewStartNumberCB->get_state_changed_from_saved()||
125         m_xNewStartNF->get_value_changed_from_saved())
126     {
127         bModified = true;
128         bool bNewStartChecked = TRISTATE_TRUE == m_xNewStartCB->get_state();
129         bool bNumberNewStartChecked = TRISTATE_TRUE == m_xNewStartNumberCB->get_state();
130         rSet->Put(SfxBoolItem(FN_NUMBER_NEWSTART, bNewStartChecked));
131         rSet->Put(SfxUInt16Item(FN_NUMBER_NEWSTART_AT,
132                   bNumberNewStartChecked && bNewStartChecked ? o3tl::narrowing<sal_uInt16>(m_xNewStartNF->get_value()) : USHRT_MAX));
133     }
134 
135     if (m_xCountParaCB->get_state_changed_from_saved()||
136         m_xRestartParaCountCB->get_state_changed_from_saved() ||
137         m_xRestartNF->get_value_changed_from_saved())
138     {
139         SwFormatLineNumber aFormat;
140         aFormat.SetStartValue( static_cast< sal_uLong >(m_xRestartParaCountCB->get_state() == TRISTATE_TRUE ?
141                                 m_xRestartNF->get_value() : 0 ));
142         aFormat.SetCountLines(m_xCountParaCB->get_active());
143         rSet->Put(aFormat);
144         bModified = true;
145     }
146     return bModified;
147 }
148 
149 void SwParagraphNumTabPage::ChangesApplied()
150 {
151     m_xOutlineLvLB->save_value();
152     m_xNumberStyleLB->save_value();
153     m_xNewStartCB->save_state();
154     m_xNewStartNumberCB->save_state();
155     m_xCountParaCB->save_state();
156     m_xRestartParaCountCB->save_state();
157     m_xRestartNF->save_value();
158 }
159 
160 void SwParagraphNumTabPage::Reset(const SfxItemSet* rSet)
161 {
162     bool bHasNumberStyle = false;
163 
164     SfxItemState eItemState = rSet->GetItemState( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL) );
165 
166     if( eItemState >= SfxItemState::DEFAULT )
167     {
168         sal_Int16 nOutlineLv = static_cast<const SfxUInt16Item &>(rSet->Get( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL) )).GetValue();
169         m_xOutlineLvLB->set_active(nOutlineLv) ;
170     }
171     else
172     {
173         m_xOutlineLvLB->set_active(-1);
174     }
175     m_xOutlineLvLB->save_value();
176 
177     eItemState = rSet->GetItemState( GetWhich(SID_ATTR_PARA_NUMRULE) );
178 
179     if( eItemState >= SfxItemState::DEFAULT )
180     {
181         OUString aStyle = static_cast<const SfxStringItem &>(rSet->Get( GetWhich(SID_ATTR_PARA_NUMRULE) )).GetValue();
182         if(aStyle.isEmpty())
183             aStyle = m_xNumberStyleLB->get_text(0);
184 
185         if( aStyle == "Outline")
186         {
187             // tdf#145804 show "Chapter Numbering"
188             assert(!m_xNumberStyleBX->get_sensitive() && "pseudo entry shouldn't be editable");
189             m_xNumberStyleLB->append_text(msOutlineNumbering);
190             m_xNumberStyleLB->set_active_text(msOutlineNumbering);
191             m_xNumberStyleLB->save_value();
192         }
193         else
194             m_xNumberStyleLB->set_active_text(aStyle);
195 
196         bHasNumberStyle = true;
197     }
198     else
199     {
200         m_xNumberStyleLB->set_active(-1);
201     }
202 
203     EditNumStyleSelectHdl_Impl(*m_xNumberStyleLB);
204 
205     m_xNumberStyleLB->save_value();
206 
207     eItemState = rSet->GetItemState( FN_NUMBER_NEWSTART );
208     if(eItemState > SfxItemState::DEFAULT )
209     {
210         bCurNumrule = true;
211         const SfxBoolItem& rStart = static_cast<const SfxBoolItem&>(rSet->Get(FN_NUMBER_NEWSTART));
212 
213         m_xNewStartCB->set_state(rStart.GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
214     }
215     else
216         m_xNewStartCB->set_state(bHasNumberStyle ? TRISTATE_FALSE : TRISTATE_INDET);
217 
218     m_xNewStartCB->save_state();
219 
220     eItemState = rSet->GetItemState( FN_NUMBER_NEWSTART_AT);
221     if( eItemState > SfxItemState::DEFAULT )
222     {
223         const sal_uInt16 nNewStart = static_cast<const SfxUInt16Item&>(rSet->Get(FN_NUMBER_NEWSTART_AT)).GetValue();
224         const bool bNotMax = USHRT_MAX != nNewStart;
225         m_xNewStartNumberCB->set_active(bNotMax);
226         m_xNewStartNF->set_value(bNotMax ? nNewStart : 1);
227     }
228     else
229         m_xNewStartCB->set_state(TRISTATE_INDET);
230     NewStartHdl_Impl(*m_xNewStartCB);
231     m_xNewStartNF->save_value();
232     m_xNewStartNumberCB->save_state();
233     StyleHdl_Impl(*m_xNumberStyleLB);
234     if( SfxItemState::DEFAULT <= rSet->GetItemState(RES_LINENUMBER))
235     {
236         const SwFormatLineNumber& rNum = rSet->Get(RES_LINENUMBER);
237         sal_uLong nStartValue = rNum.GetStartValue();
238         bool bCount = rNum.IsCount();
239         m_xCountParaCB->set_state(bCount ? TRISTATE_TRUE : TRISTATE_FALSE);
240         m_xRestartParaCountCB->set_state(0 != nStartValue ? TRISTATE_TRUE : TRISTATE_FALSE);
241         m_xRestartNF->set_value(nStartValue == 0 ? 1 : nStartValue);
242         LineCountHdl_Impl(*m_xCountParaCB);
243     }
244     else
245     {
246         m_xCountParaCB->set_state(TRISTATE_INDET);
247         m_xRestartParaCountCB->set_state(TRISTATE_INDET);
248     }
249     m_xCountParaCB->save_state();
250     m_xRestartParaCountCB->save_state();
251     m_xRestartNF->save_value();
252 
253     bModified = false;
254 }
255 
256 void SwParagraphNumTabPage::DisableOutline()
257 {
258     m_xOutlineStartBX->set_sensitive(false);
259     m_xOutlineStartBX->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED) );
260 }
261 
262 void SwParagraphNumTabPage::DisableNumbering()
263 {
264     m_xNumberStyleBX->set_sensitive(false);
265     m_xNumberStyleBX->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED) );
266 }
267 
268 void SwParagraphNumTabPage::EnableNewStart()
269 {
270     m_xNewStartCB->show();
271     m_xNewStartBX->show();
272 }
273 
274 IMPL_LINK_NOARG(SwParagraphNumTabPage, NewStartHdl_Impl, weld::Toggleable&, void)
275 {
276     bool bEnable = m_xNewStartCB->get_active();
277     m_xNewStartNumberCB->set_sensitive(bEnable);
278     m_xNewStartNF->set_sensitive(bEnable && m_xNewStartNumberCB->get_active());
279 }
280 
281 IMPL_LINK_NOARG(SwParagraphNumTabPage, LineCountHdl_Impl, weld::Toggleable&, void)
282 {
283     m_xRestartParaCountCB->set_sensitive(m_xCountParaCB->get_active());
284 
285     bool bEnableRestartValue = m_xRestartParaCountCB->get_sensitive() &&
286                                m_xRestartParaCountCB->get_active();
287     m_xRestartBX->set_sensitive(bEnableRestartValue);
288 }
289 
290 IMPL_LINK_NOARG(SwParagraphNumTabPage, EditNumStyleSelectHdl_Impl, weld::ComboBox&, void)
291 {
292     int numSelectPos = m_xNumberStyleLB->get_active();
293     // 0 is "None" and -1 is unselected state
294     if (numSelectPos == 0 || numSelectPos == -1)
295         m_xEditNumStyleBtn->set_sensitive(false);
296     else
297         m_xEditNumStyleBtn->set_sensitive(true);
298 }
299 
300 IMPL_LINK_NOARG(SwParagraphNumTabPage, EditNumStyleHdl_Impl, weld::Button&, void)
301 {
302     OUString aTemplName(m_xNumberStyleLB->get_active_text());
303     ExecuteEditNumStyle_Impl( SID_STYLE_EDIT, aTemplName, SfxStyleFamily::Pseudo );
304 }
305 
306 // Internal: Perform functions through the Dispatcher
307 bool SwParagraphNumTabPage::ExecuteEditNumStyle_Impl(
308     sal_uInt16 nId, const OUString &rStr, SfxStyleFamily nFamily)
309 {
310     SfxDispatcher &rDispatcher = *SfxViewShell::Current()->GetDispatcher();
311     SfxStringItem aItem(nId, rStr);
312     SfxUInt16Item aFamily(SID_STYLE_FAMILY, static_cast<sal_uInt16>(nFamily));
313     const SfxPoolItem* pItems[ 3 ];
314     sal_uInt16 nCount = 0;
315     if( !rStr.isEmpty() )
316         pItems[ nCount++ ] = &aItem;
317     pItems[ nCount++ ] = &aFamily;
318 
319     pItems[ nCount++ ] = nullptr;
320 
321     // tdf#145363 we want the current dialog to be the parent of the new dialog
322     weld::Window* pDialogParent = GetFrameWeld();
323     css::uno::Any aAny(pDialogParent->GetXWindow());
324     SfxUnoAnyItem aDialogParent(SID_DIALOG_PARENT, aAny);
325     const SfxPoolItem* pInternalItems[ 1 ];
326     pInternalItems[ 0 ] = &aDialogParent;
327 
328     const SfxPoolItem* pItem = rDispatcher.Execute(
329         nId, SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
330         pItems, 0, pInternalItems);
331 
332     return pItem != nullptr;
333 
334 }
335 
336 IMPL_LINK(SwParagraphNumTabPage, StyleHdl_Impl, weld::ComboBox&, rBox, void)
337 {
338     bool bEnable = bCurNumrule || rBox.get_active() > 0;
339     m_xNewStartCB->set_sensitive(bEnable);
340     NewStartHdl_Impl(*m_xNewStartCB);
341 }
342 
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
344