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
