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 .
20 #include <hintids.hxx>
21 #include <vcl/settings.hxx>
22 #include <vcl/virdev.hxx>
23 #include <sfx2/tabdlg.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <unotools/configmgr.hxx>
26 #include <SwStyleNameMapper.hxx>
32 #include <swmodule.hxx>
34 #include <outline.hxx>
36 #include <poolfmt.hxx>
37 #include <shellres.hxx>
38 #include <svl/style.hxx>
39 #include <charfmt.hxx>
40 #include <docstyle.hxx>
41 #include <viewopt.hxx>
42 #include <outline.hrc>
43 #include <strings.hrc>
45 #include <svtools/colorcfg.hxx>
47 #include <IDocumentOutlineNodes.hxx>
49 using namespace ::com::sun::star
;
53 class SwNumNamesDlg
: public weld::GenericDialogController
55 std::unique_ptr
<weld::Entry
> m_xFormEdit
;
56 std::unique_ptr
<weld::TreeView
> m_xFormBox
;
57 std::unique_ptr
<weld::Button
> m_xOKBtn
;
59 DECL_LINK( ModifyHdl
, weld::Entry
&, void );
60 DECL_LINK( SelectHdl
, weld::TreeView
&, void );
61 DECL_LINK( DoubleClickHdl
, weld::TreeView
&, bool );
64 explicit SwNumNamesDlg(weld::Window
*pParent
);
65 void SetUserNames(const OUString
*pList
[]);
66 OUString
GetName() const { return m_xFormEdit
->get_text(); }
67 int GetCurEntryPos() const { return m_xFormBox
->get_selected_index(); }
72 // remember selected entry
73 IMPL_LINK( SwNumNamesDlg
, SelectHdl
, weld::TreeView
&, rBox
, void )
75 m_xFormEdit
->set_text(rBox
.get_selected_text());
76 m_xFormEdit
->select_region(0, -1);
79 /** set user defined names
81 * @param pList list of user defined names; unknown positions for the user are 0.
83 void SwNumNamesDlg::SetUserNames(const OUString
*pList
[])
85 sal_uInt16 nSelect
= 0;
86 for (sal_uInt16 i
= 0; i
< SwChapterNumRules::nMaxRules
; ++i
)
90 m_xFormBox
->remove(i
);
91 m_xFormBox
->insert_text(i
, *pList
[i
]);
96 m_xFormBox
->select(std::min(nSelect
, o3tl::narrowing
<sal_uInt16
>(m_xFormBox
->n_children() - 1)));
97 SelectHdl(*m_xFormBox
);
100 // unlock OK-Button when text is in Edit
101 IMPL_LINK( SwNumNamesDlg
, ModifyHdl
, weld::Entry
&, rBox
, void )
103 m_xOKBtn
->set_sensitive(!rBox
.get_text().isEmpty());
107 IMPL_LINK_NOARG(SwNumNamesDlg
, DoubleClickHdl
, weld::TreeView
&, bool)
109 m_xDialog
->response(RET_OK
);
113 SwNumNamesDlg::SwNumNamesDlg(weld::Window
*pParent
)
114 : GenericDialogController(pParent
,
115 "modules/swriter/ui/numberingnamedialog.ui",
116 "NumberingNameDialog")
117 , m_xFormEdit(m_xBuilder
->weld_entry("entry"))
118 , m_xFormBox(m_xBuilder
->weld_tree_view("form"))
119 , m_xOKBtn(m_xBuilder
->weld_button("ok"))
121 for (auto const& aID
: OUTLINE_STYLE
)
122 m_xFormBox
->append_text(SwResId(aID
));
124 m_xFormEdit
->connect_changed(LINK(this, SwNumNamesDlg
, ModifyHdl
));
125 m_xFormBox
->connect_changed(LINK(this, SwNumNamesDlg
, SelectHdl
));
126 m_xFormBox
->connect_row_activated(LINK(this, SwNumNamesDlg
, DoubleClickHdl
));
127 m_xFormBox
->set_size_request(-1, m_xFormBox
->get_height_rows(9));
130 static sal_uInt16
lcl_BitToLevel(sal_uInt16 nActLevel
)
132 constexpr sal_uInt16 MAXLEVEL_MASK
= USHRT_MAX
>> (sizeof(sal_uInt16
) * CHAR_BIT
- MAXLEVEL
);
133 assert((nActLevel
& MAXLEVEL_MASK
) == nActLevel
);
134 sal_uInt16 nTmp
= nActLevel
& MAXLEVEL_MASK
; // a safety measure
135 sal_uInt16 nTmpLevel
= 0;
136 while( 0 != (nTmp
>>= 1) )
141 sal_uInt16
SwOutlineTabDialog::s_nNumLevel
= 1;
143 SwOutlineTabDialog::SwOutlineTabDialog(weld::Window
* pParent
, const SfxItemSet
* pSwItemSet
,
145 : SfxTabDialogController(pParent
, "modules/swriter/ui/outlinenumbering.ui", "OutlineNumberingDialog", pSwItemSet
)
147 , m_pChapterNumRules(SW_MOD()->GetChapterNumRules())
148 , m_bModified(m_rWrtSh
.IsModified())
149 , m_xMenuButton(m_xBuilder
->weld_menu_button("format"))
151 m_xMenuButton
->connect_toggled(LINK(this, SwOutlineTabDialog
, FormHdl
));
152 m_xMenuButton
->connect_selected(LINK(this, SwOutlineTabDialog
, MenuSelectHdl
));
154 m_xNumRule
.reset(new SwNumRule(*rSh
.GetOutlineNumRule()));
155 GetCancelButton().connect_clicked(LINK(this, SwOutlineTabDialog
, CancelHdl
));
157 if (auto nOutlinePos
= m_rWrtSh
.GetOutlinePos(MAXLEVEL
); nOutlinePos
!= SwOutlineNodes::npos
)
159 int nTmp
= m_rWrtSh
.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos
);
160 assert(nTmp
< MAXLEVEL
);
161 SetActNumLevel(nTmp
< 0 ? USHRT_MAX
: (1 << nTmp
));
164 AddTabPage("position", &SwNumPositionTabPage::Create
, nullptr);
165 AddTabPage("numbering", &SwOutlineSettingsTabPage::Create
, nullptr);
170 for( i
= 0; i
< MAXLEVEL
; ++i
)
172 // if the style wasn't created yet, it's still at this position
173 if( !m_rWrtSh
.GetParaStyle( sHeadline
=
174 SwStyleNameMapper::GetUIName( static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
),
176 m_aCollNames
[i
] = sHeadline
;
179 // query the text templates' outlining levels
180 const sal_uInt16 nCount
= m_rWrtSh
.GetTextFormatCollCount();
181 for(i
= 0; i
< nCount
; ++i
)
183 SwTextFormatColl
&rTextColl
= m_rWrtSh
.GetTextFormatColl(i
);
184 if(!rTextColl
.IsDefault())
186 if(rTextColl
.IsAssignedToListLevelOfOutlineStyle())
188 int nOutLevel
= rTextColl
.GetAssignedOutlineStyleLevel();
189 m_aCollNames
[ nOutLevel
] = rTextColl
.GetName();
195 SwOutlineTabDialog::~SwOutlineTabDialog()
199 void SwOutlineTabDialog::PageCreated(const OUString
& rPageId
, SfxTabPage
& rPage
)
201 if (rPageId
== "position")
203 static_cast<SwNumPositionTabPage
&>(rPage
).SetWrtShell(&m_rWrtSh
);
204 static_cast<SwNumPositionTabPage
&>(rPage
).SetOutlineTabDialog(this);
206 else if (rPageId
== "numbering")
208 static_cast<SwOutlineSettingsTabPage
&>(rPage
).SetWrtShell(&m_rWrtSh
);
212 IMPL_LINK_NOARG(SwOutlineTabDialog
, CancelHdl
, weld::Button
&, void)
215 m_rWrtSh
.ResetModified();
216 m_xDialog
->response(RET_CANCEL
);
219 IMPL_LINK_NOARG(SwOutlineTabDialog
, FormHdl
, weld::Toggleable
&, void)
221 if (!m_xMenuButton
->get_active())
225 for(sal_uInt16 i
= 0; i
< SwChapterNumRules::nMaxRules
; ++i
)
227 const SwNumRulesWithName
*pRules
= m_pChapterNumRules
->GetRules(i
);
230 m_xMenuButton
->set_item_label("form" + OUString::number(i
+ 1), pRules
->GetName());
234 IMPL_LINK(SwOutlineTabDialog
, MenuSelectHdl
, const OUString
&, rIdent
, void)
236 sal_uInt8 nLevelNo
= 0;
238 if (rIdent
== "form1")
240 else if (rIdent
== "form2")
242 else if (rIdent
== "form3")
244 else if (rIdent
== "form4")
246 else if (rIdent
== "form5")
248 else if (rIdent
== "form6")
250 else if (rIdent
== "form7")
252 else if (rIdent
== "form8")
254 else if (rIdent
== "form9")
256 else if (rIdent
== "saveas")
258 SwNumNamesDlg
aDlg(m_xDialog
.get());
259 const OUString
*aStrArr
[SwChapterNumRules::nMaxRules
];
260 for(sal_uInt16 i
= 0; i
< SwChapterNumRules::nMaxRules
; ++i
)
262 const SwNumRulesWithName
*pRules
= m_pChapterNumRules
->GetRules(i
);
264 aStrArr
[i
] = &pRules
->GetName();
266 aStrArr
[i
] = nullptr;
268 aDlg
.SetUserNames(aStrArr
);
269 if (aDlg
.run() == RET_OK
)
271 const OUString
aName(aDlg
.GetName());
272 m_pChapterNumRules
->ApplyNumRules( SwNumRulesWithName(
273 *m_xNumRule
, aName
), aDlg
.GetCurEntryPos() );
274 m_xMenuButton
->set_item_label("form" + OUString::number(aDlg
.GetCurEntryPos() + 1), aName
);
281 const SwNumRulesWithName
*pRules
= m_pChapterNumRules
->GetRules( nLevelNo
);
284 pRules
->ResetNumRule(m_rWrtSh
, *m_xNumRule
);
285 m_xNumRule
->SetRuleType( OUTLINE_RULE
);
286 SfxTabPage
* pOutlinePage
= GetTabPage(u
"numbering");
287 assert(pOutlinePage
);
288 static_cast<SwOutlineSettingsTabPage
*>(pOutlinePage
)->SetNumRule(m_xNumRule
.get());
291 *m_xNumRule
= *m_rWrtSh
.GetOutlineNumRule();
294 SfxTabPage
* pPage
= GetCurTabPage();
295 pPage
->Reset(GetOutputItemSet());
298 sal_uInt16
SwOutlineTabDialog::GetLevel(std::u16string_view rFormatName
) const
300 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; ++i
)
302 if(m_aCollNames
[i
] == rFormatName
)
308 short SwOutlineTabDialog::Ok()
310 SfxTabDialogController::Ok();
311 // set levels for all created templates; has to be done in order to
312 // delete possibly cancelled assignments again.
314 // encapsulate changes into an action to avoid effects on the current cursor
315 // position during the changes.
316 m_rWrtSh
.StartAction();
318 const SwNumRule
* pOutlineRule
= m_rWrtSh
.GetOutlineNumRule();
320 sal_uInt16 i
, nCount
= m_rWrtSh
.GetTextFormatCollCount();
321 for( i
= 0; i
< nCount
; ++i
)
323 SwTextFormatColl
&rTextColl
= m_rWrtSh
.GetTextFormatColl(i
);
324 if( !rTextColl
.IsDefault() )
326 const SfxPoolItem
& rItem
=
327 rTextColl
.GetFormatAttr(RES_PARATR_NUMRULE
, false);
329 if (static_cast<sal_uInt8
>(GetLevel(rTextColl
.GetName())) == MAXLEVEL
)
331 if(rTextColl
.IsAssignedToListLevelOfOutlineStyle())
333 rTextColl
.DeleteAssignmentToListLevelOfOutlineStyle();
335 if (static_cast<const SwNumRuleItem
&>(rItem
).GetValue() ==
336 pOutlineRule
->GetName())
338 rTextColl
.ResetFormatAttr(RES_PARATR_NUMRULE
);
343 rTextColl
.AssignToListLevelOfOutlineStyle(GetLevel(rTextColl
.GetName()));
345 if (static_cast<const SwNumRuleItem
&>(rItem
).GetValue() !=
346 pOutlineRule
->GetName())
348 SwNumRuleItem
aItem(pOutlineRule
->GetName());
349 rTextColl
.SetFormatAttr(aItem
);
355 for(i
= 0; i
< MAXLEVEL
; ++i
)
358 ::SwStyleNameMapper::FillUIName( static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
),
360 SwTextFormatColl
* pColl
= m_rWrtSh
.FindTextFormatCollByName( sHeadline
);
361 if( !pColl
&& m_aCollNames
[i
] != sHeadline
)
363 SwTextFormatColl
* pTextColl
= m_rWrtSh
.GetTextCollFromPool(
364 static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
) );
365 pTextColl
->DeleteAssignmentToListLevelOfOutlineStyle();
366 pTextColl
->ResetFormatAttr(RES_PARATR_NUMRULE
);
368 if( !m_aCollNames
[i
].isEmpty() )
370 pTextColl
= m_rWrtSh
.GetParaStyle(
371 m_aCollNames
[i
], SwWrtShell::GETSTYLE_CREATESOME
);
374 pTextColl
->AssignToListLevelOfOutlineStyle(i
);
375 SwNumRuleItem
aItem(pOutlineRule
->GetName());
376 pTextColl
->SetFormatAttr(aItem
);
382 m_rWrtSh
.SetOutlineNumRule(*m_xNumRule
);
385 m_rWrtSh
.EndAction();
390 SwOutlineSettingsTabPage::SwOutlineSettingsTabPage(weld::Container
* pPage
, weld::DialogController
* pController
,
391 const SfxItemSet
& rSet
)
392 : SfxTabPage(pPage
, pController
, "modules/swriter/ui/outlinenumberingpage.ui", "OutlineNumberingPage", &rSet
)
393 , m_aNoFormatName(SwResId(SW_STR_NONE
))
395 , m_pNumRule(nullptr)
396 , m_pCollNames(nullptr)
398 , m_xLevelLB(m_xBuilder
->weld_tree_view("level"))
399 , m_xCollBox(m_xBuilder
->weld_combo_box("style"))
400 , m_xNumberBox(new SwNumberingTypeListBox(m_xBuilder
->weld_combo_box("numbering")))
401 , m_xCharFormatLB(m_xBuilder
->weld_combo_box("charstyle"))
402 , m_xAllLevelFT(m_xBuilder
->weld_label("sublevelsft"))
403 , m_xAllLevelNF(m_xBuilder
->weld_spin_button("sublevelsnf"))
404 , m_xPrefixED(m_xBuilder
->weld_entry("prefix"))
405 , m_xSuffixED(m_xBuilder
->weld_entry("suffix"))
406 , m_xStartEdit(m_xBuilder
->weld_spin_button("startat"))
407 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder
, "preview", m_aPreviewWIN
))
409 SetExchangeSupport();
411 m_xNumberBox
->Reload(SwInsertNumTypes::NoNumbering
| SwInsertNumTypes::Extended
);
412 m_xCollBox
->make_sorted();
413 m_xCollBox
->append_text(m_aNoFormatName
);
414 m_xLevelLB
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, LevelHdl
));
415 m_xAllLevelNF
->connect_value_changed(LINK(this, SwOutlineSettingsTabPage
, ToggleComplete
));
416 m_xCollBox
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, CollSelect
));
417 m_xNumberBox
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, NumberSelect
));
418 m_xPrefixED
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, DelimModify
));
419 m_xSuffixED
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, DelimModify
));
420 m_xStartEdit
->connect_value_changed(LINK(this, SwOutlineSettingsTabPage
, StartModified
));
421 m_xCharFormatLB
->make_sorted();
422 m_xCharFormatLB
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, CharFormatHdl
));
425 void SwOutlineSettingsTabPage::Update()
427 // if a template was already selected for this level, select it in the ListBox
428 m_xCollBox
->set_sensitive(USHRT_MAX
!= m_nActLevel
);
429 if(USHRT_MAX
== m_nActLevel
)
431 bool bSamePrefix
= true;
432 bool bSameSuffix
= true;
433 bool bSameType
= true;
434 bool bSameComplete
= true;
435 bool bSameStart
= true;
436 bool bSameCharFormat
= true;
438 const SwNumFormat
* aNumFormatArr
[MAXLEVEL
];
439 const SwCharFormat
* pFirstFormat
= nullptr;
441 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
444 aNumFormatArr
[ i
] = &m_pNumRule
->Get(i
);
446 pFirstFormat
= aNumFormatArr
[i
]->GetCharFormat();
449 bSameType
&= aNumFormatArr
[i
]->GetNumberingType() == aNumFormatArr
[0]->GetNumberingType();
450 bSameStart
&= aNumFormatArr
[i
]->GetStart() == aNumFormatArr
[0]->GetStart();
451 bSamePrefix
&= aNumFormatArr
[i
]->GetPrefix() == aNumFormatArr
[0]->GetPrefix();
452 bSameSuffix
&= aNumFormatArr
[i
]->GetSuffix() == aNumFormatArr
[0]->GetSuffix();
453 bSameComplete
&= aNumFormatArr
[i
]->GetIncludeUpperLevels() == aNumFormatArr
[0]->GetIncludeUpperLevels();
454 const SwCharFormat
* pFormat
= aNumFormatArr
[i
]->GetCharFormat();
455 bSameCharFormat
&= (!pFirstFormat
&& !pFormat
)
456 || (pFirstFormat
&& pFormat
&& pFormat
->GetName() == pFirstFormat
->GetName());
459 CheckForStartValue_Impl(aNumFormatArr
[0]->GetNumberingType());
461 m_xNumberBox
->SelectNumberingType( aNumFormatArr
[0]->GetNumberingType() );
463 m_xNumberBox
->SetNoSelection();
465 m_xStartEdit
->set_value(aNumFormatArr
[0]->GetStart());
467 m_xStartEdit
->set_text(OUString());
469 m_xPrefixED
->set_text(aNumFormatArr
[0]->GetPrefix());
471 m_xPrefixED
->set_text(OUString());
473 m_xSuffixED
->set_text(aNumFormatArr
[0]->GetSuffix());
475 m_xSuffixED
->set_text(OUString());
480 m_xCharFormatLB
->set_active_text(pFirstFormat
->GetName());
482 m_xCharFormatLB
->set_active_text(SwViewShell::GetShellRes()->aStrNone
);
485 m_xCharFormatLB
->set_active(-1);
487 m_xAllLevelFT
->set_sensitive(true);
488 m_xAllLevelNF
->set_sensitive(true);
489 m_xAllLevelNF
->set_max(MAXLEVEL
);
492 m_xAllLevelNF
->set_value(aNumFormatArr
[0]->GetIncludeUpperLevels());
496 m_xAllLevelNF
->set_text(OUString());
501 sal_uInt16 nTmpLevel
= lcl_BitToLevel(m_nActLevel
);
502 OUString
aColl(m_pCollNames
[nTmpLevel
]);
504 m_xCollBox
->set_active_text(aColl
);
506 m_xCollBox
->set_active_text(m_aNoFormatName
);
507 const SwNumFormat
&rFormat
= m_pNumRule
->Get(nTmpLevel
);
509 m_xNumberBox
->SelectNumberingType( rFormat
.GetNumberingType() );
510 m_xPrefixED
->set_text(rFormat
.GetPrefix());
511 m_xSuffixED
->set_text(rFormat
.GetSuffix());
512 const SwCharFormat
* pFormat
= rFormat
.GetCharFormat();
514 m_xCharFormatLB
->set_active_text(pFormat
->GetName());
516 m_xCharFormatLB
->set_active_text(SwViewShell::GetShellRes()->aStrNone
);
518 if (nTmpLevel
|| rFormat
.HasListFormat())
520 m_xAllLevelFT
->set_sensitive(true);
521 m_xAllLevelNF
->set_sensitive(true);
522 m_xAllLevelNF
->set_max(nTmpLevel
+ 1);
523 m_xAllLevelNF
->set_min(rFormat
.HasListFormat() ? 0 : 1);
524 m_xAllLevelNF
->set_value(rFormat
.GetIncludeUpperLevels());
528 m_xAllLevelNF
->set_text(OUString());
529 m_xAllLevelNF
->set_sensitive(false);
530 m_xAllLevelFT
->set_sensitive(false);
532 CheckForStartValue_Impl(rFormat
.GetNumberingType());
533 m_xStartEdit
->set_value( rFormat
.GetStart() );
538 IMPL_LINK( SwOutlineSettingsTabPage
, LevelHdl
, weld::TreeView
&, rBox
, void )
540 auto aRows
= rBox
.get_selected_rows();
541 assert(aRows
.empty() || aRows
.size() == 1); // Single selection only
542 if (aRows
.empty() || aRows
[0] == MAXLEVEL
)
544 m_nActLevel
= USHRT_MAX
;
548 m_nActLevel
= 1 << aRows
[0];
553 IMPL_LINK(SwOutlineSettingsTabPage
, ToggleComplete
, weld::SpinButton
&, rEdit
, void)
555 sal_uInt16 nMask
= 1;
556 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
558 if(m_nActLevel
& nMask
)
560 SwNumFormat
aNumFormat(m_pNumRule
->Get(i
));
561 aNumFormat
.SetIncludeUpperLevels( std::min( static_cast<sal_uInt8
>(rEdit
.get_value()),
562 static_cast<sal_uInt8
>(i
+ 1)) );
563 // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
564 aNumFormat
.SetListFormat(aNumFormat
.GetPrefix(), aNumFormat
.GetSuffix(), i
);
565 m_pNumRule
->Set(i
, aNumFormat
);
572 IMPL_LINK( SwOutlineSettingsTabPage
, CollSelect
, weld::ComboBox
&, rBox
, void )
576 const OUString
aCollName(rBox
.get_active_text());
577 //0xFFFF not allowed here (disable)
578 sal_uInt16 nTmpLevel
= lcl_BitToLevel(m_nActLevel
);
579 OUString
sOldName( m_pCollNames
[nTmpLevel
] );
581 for( i
= 0; i
< MAXLEVEL
; ++i
)
582 m_pCollNames
[i
] = m_aSaveCollNames
[i
];
584 m_pCollNames
[nTmpLevel
] = aCollName
;
585 // template already in use?
586 for( i
= 0; i
< MAXLEVEL
; ++i
)
587 if(i
!= nTmpLevel
&& m_pCollNames
[i
] == aCollName
)
588 m_pCollNames
[i
].clear();
590 // search the oldname and put it into the current entries
591 if( !sOldName
.isEmpty() )
592 for( i
= 0; i
< MAXLEVEL
; ++i
)
593 if( m_aSaveCollNames
[ i
] == sOldName
&& i
!= nTmpLevel
&&
594 m_pCollNames
[ i
].isEmpty() )
597 for( n
= 0; n
< MAXLEVEL
; ++n
)
598 if( m_pCollNames
[ n
] == sOldName
)
602 // it was an outline level name and the current entries is zero.
603 m_pCollNames
[ i
] = sOldName
;
610 void SwOutlineSettingsTabPage::CollSave()
612 for (sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
613 m_aSaveCollNames
[i
] = m_pCollNames
[i
];
616 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, NumberSelect
, weld::ComboBox
&, void)
618 sal_uInt16 nMask
= 1;
619 SvxNumType nNumberType
= m_xNumberBox
->GetSelectedNumberingType();
620 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
622 if(m_nActLevel
& nMask
)
624 SwNumFormat
aNumFormat(m_pNumRule
->Get(i
));
625 aNumFormat
.SetNumberingType(nNumberType
);
626 m_pNumRule
->Set(i
, aNumFormat
);
627 CheckForStartValue_Impl(nNumberType
);
634 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, DelimModify
, weld::Entry
&, void)
636 sal_uInt16 nMask
= 1;
637 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
639 if(m_nActLevel
& nMask
)
641 SwNumFormat
aNumFormat(m_pNumRule
->Get(i
));
642 aNumFormat
.SetListFormat( m_xPrefixED
->get_text(), m_xSuffixED
->get_text(), i
);
643 m_pNumRule
->Set(i
, aNumFormat
);
650 IMPL_LINK( SwOutlineSettingsTabPage
, StartModified
, weld::SpinButton
&, rEdit
, void )
652 sal_uInt16 nMask
= 1;
653 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
655 if(m_nActLevel
& nMask
)
657 SwNumFormat
aNumFormat(m_pNumRule
->Get(i
));
658 aNumFormat
.SetStart(o3tl::narrowing
<sal_uInt16
>(rEdit
.get_value()));
659 m_pNumRule
->Set(i
, aNumFormat
);
666 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, CharFormatHdl
, weld::ComboBox
&, void)
668 OUString sEntry
= m_xCharFormatLB
->get_active_text();
669 sal_uInt16 nMask
= 1;
670 bool bFormatNone
= sEntry
== SwViewShell::GetShellRes()->aStrNone
;
671 SwCharFormat
* pFormat
= nullptr;
674 sal_uInt16 nChCount
= m_pSh
->GetCharFormatCount();
675 for(sal_uInt16 i
= 0; i
< nChCount
; i
++)
677 SwCharFormat
& rChFormat
= m_pSh
->GetCharFormat(i
);
678 if(rChFormat
.GetName() == sEntry
)
680 pFormat
= &rChFormat
;
686 SfxStyleSheetBasePool
* pPool
= m_pSh
->GetView().GetDocShell()->GetStyleSheetPool();
687 SfxStyleSheetBase
* pBase
;
688 pBase
= pPool
->Find(sEntry
, SfxStyleFamily::Char
);
690 pBase
= &pPool
->Make(sEntry
, SfxStyleFamily::Page
);
691 pFormat
= static_cast<SwDocStyleSheet
*>(pBase
)->GetCharFormat();
696 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
698 if(m_nActLevel
& nMask
)
700 SwNumFormat
aNumFormat(m_pNumRule
->Get(i
));
702 aNumFormat
.SetCharFormat(nullptr);
704 aNumFormat
.SetCharFormat(pFormat
);
705 m_pNumRule
->Set(i
, aNumFormat
);
711 SwOutlineSettingsTabPage::~SwOutlineSettingsTabPage()
715 void SwOutlineSettingsTabPage::SetWrtShell(SwWrtShell
* pShell
)
718 // query this document's NumRules
719 m_pNumRule
= static_cast<SwOutlineTabDialog
*>(GetDialogController())->GetNumRule();
720 m_pCollNames
= static_cast<SwOutlineTabDialog
*>(GetDialogController())->GetCollNames();
724 m_aPreviewWIN
.SetNumRule(m_pNumRule
);
725 m_aPreviewWIN
.SetOutlineNames(m_pCollNames
);
726 // set start value - nActLevel must be 1 here
727 sal_uInt16 nTmpLevel
= lcl_BitToLevel(m_nActLevel
);
728 const SwNumFormat
& rNumFormat
= m_pNumRule
->Get( nTmpLevel
);
729 m_xStartEdit
->set_value( rNumFormat
.GetStart() );
731 // create pool formats for headlines
732 for (sal_uInt16 i
= 0; i
< MAXLEVEL
; ++i
)
734 m_xCollBox
->append_text( SwStyleNameMapper::GetUIName(
735 static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
), OUString()));
736 m_xLevelLB
->append_text( OUString::number(i
+ 1) );
738 OUString sStr
= "1 - " + OUString::number(MAXLEVEL
);
739 m_xLevelLB
->append_text(sStr
);
741 // query the texttemplates' outlining levels
742 const sal_uInt16 nCount
= m_pSh
->GetTextFormatCollCount();
743 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
745 SwTextFormatColl
&rTextColl
= m_pSh
->GetTextFormatColl(i
);
746 if(!rTextColl
.IsDefault())
748 sStr
= rTextColl
.GetName();
749 if (m_xCollBox
->find_text(sStr
) == -1)
750 m_xCollBox
->append_text(sStr
);
754 m_xNumberBox
->SelectNumberingType(rNumFormat
.GetNumberingType());
756 // collect char styles
757 m_xCharFormatLB
->clear();
758 m_xCharFormatLB
->append_text(SwViewShell::GetShellRes()->aStrNone
);
761 ::FillCharStyleListBox(*m_xCharFormatLB
,
762 m_pSh
->GetView().GetDocShell());
766 void SwOutlineSettingsTabPage::ActivatePage(const SfxItemSet
& )
768 m_nActLevel
= SwOutlineTabDialog::GetActNumLevel();
769 if(m_nActLevel
!= USHRT_MAX
)
770 m_xLevelLB
->select(lcl_BitToLevel(m_nActLevel
));
772 m_xLevelLB
->select(MAXLEVEL
);
773 LevelHdl(*m_xLevelLB
);
776 DeactivateRC
SwOutlineSettingsTabPage::DeactivatePage(SfxItemSet
*)
778 SwOutlineTabDialog::SetActNumLevel(m_nActLevel
);
779 return DeactivateRC::LeavePage
;
782 bool SwOutlineSettingsTabPage::FillItemSet( SfxItemSet
* )
787 void SwOutlineSettingsTabPage::Reset( const SfxItemSet
* rSet
)
792 std::unique_ptr
<SfxTabPage
> SwOutlineSettingsTabPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
793 const SfxItemSet
* rAttrSet
)
795 return std::make_unique
<SwOutlineSettingsTabPage
>(pPage
, pController
, *rAttrSet
);
798 void SwOutlineSettingsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType
)
800 bool bIsNull
= m_xStartEdit
->get_value() == 0;
801 bool bNoZeroAllowed
= nNumberingType
< SVX_NUM_ARABIC
||
802 SVX_NUM_CHARS_UPPER_LETTER_N
== nNumberingType
||
803 SVX_NUM_CHARS_LOWER_LETTER_N
== nNumberingType
;
804 m_xStartEdit
->set_min(bNoZeroAllowed
? 1 : 0);
805 if (bIsNull
&& bNoZeroAllowed
)
806 StartModified(*m_xStartEdit
);
809 static tools::Long
lcl_DrawBullet(vcl::RenderContext
* pVDev
, const SwNumFormat
& rFormat
, tools::Long nXStart
, tools::Long nYStart
, const Size
& rSize
)
811 vcl::Font
aTmpFont(pVDev
->GetFont());
813 // via Uno it's possible that no font has been set!
814 vcl::Font
aFont(rFormat
.GetBulletFont() ? *rFormat
.GetBulletFont() : aTmpFont
);
815 Size
aTmpSize(rSize
);
816 aTmpSize
.setWidth( aTmpSize
.Width() * ( rFormat
.GetBulletRelSize()) );
817 aTmpSize
.setWidth( aTmpSize
.Width() / 100 ) ;
818 aTmpSize
.setHeight( aTmpSize
.Height() * ( rFormat
.GetBulletRelSize()) );
819 aTmpSize
.setHeight( aTmpSize
.Height() / 100 ) ;
820 // in case of a height of zero it is drawn in original height
821 if(!aTmpSize
.Height())
822 aTmpSize
.setHeight( 1 );
823 aFont
.SetFontSize(aTmpSize
);
824 aFont
.SetTransparent(true);
825 Color aBulletColor
= rFormat
.GetBulletColor();
826 if(aBulletColor
== COL_AUTO
)
827 aBulletColor
= pVDev
->GetFillColor().IsDark() ? COL_WHITE
: COL_BLACK
;
828 else if(aBulletColor
== pVDev
->GetFillColor())
829 aBulletColor
.Invert();
830 aFont
.SetColor(aBulletColor
);
831 pVDev
->SetFont( aFont
);
832 sal_UCS4 cBullet
= rFormat
.GetBulletChar();
833 OUString
aText(&cBullet
, 1);
834 tools::Long nY
= nYStart
;
835 nY
-= ((aTmpSize
.Height() - rSize
.Height())/ 2);
836 pVDev
->DrawText( Point(nXStart
, nY
), aText
);
837 tools::Long nRet
= pVDev
->GetTextWidth(aText
);
839 pVDev
->SetFont(aTmpFont
);
843 static tools::Long
lcl_DrawGraphic(vcl::RenderContext
& rVDev
, const SwNumFormat
&rFormat
, tools::Long nXStart
, tools::Long nYStart
, tools::Long nDivision
)
845 const SvxBrushItem
* pBrushItem
= rFormat
.GetBrush();
846 tools::Long nRet
= 0;
849 const Graphic
* pGraphic
= pBrushItem
->GetGraphic();
852 Size
aGSize( rFormat
.GetGraphicSize());
853 aGSize
.setWidth( aGSize
.Width() / nDivision
);
854 nRet
= aGSize
.Width();
855 aGSize
.setHeight( aGSize
.Height() / nDivision
);
856 pGraphic
->Draw(rVDev
, Point(nXStart
, nYStart
), rVDev
.PixelToLogic(aGSize
));
862 void NumberingPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
864 const Size
aSize(rRenderContext
.PixelToLogic(GetOutputSizePixel()));
866 ScopedVclPtrInstance
<VirtualDevice
> pVDev(rRenderContext
);
867 pVDev
->SetMapMode(rRenderContext
.GetMapMode());
868 pVDev
->SetOutputSize(aSize
);
870 const SwViewOption
& pOpt
= SwViewOption::GetCurrentViewOptions();
871 const Color
& rDocColor
= pOpt
.GetDocColor();
872 const Color
& rDocBoundariesColor
= pOpt
.GetDocBoundariesColor();
873 const Color
& rFontColor
= pOpt
.GetFontColor();
875 pVDev
->SetFillColor(rDocColor
);
876 pVDev
->SetLineColor(rDocBoundariesColor
);
877 pVDev
->DrawRect(tools::Rectangle(Point(0,0), aSize
));
881 tools::Long nWidthRelation
= 30; // chapter dialog
884 nWidthRelation
= m_nPageWidth
/ aSize
.Width();
886 nWidthRelation
= nWidthRelation
* 2 / 3;
888 nWidthRelation
= nWidthRelation
/ 4;
892 const tools::Long nXStep
= aSize
.Width() / (3 * MAXLEVEL
* ((MAXLEVEL
< 10) ? 2 : 1));
893 const tools::Long nYStep
= (aSize
.Height() - 6)/ MAXLEVEL
;
894 tools::Long nYStart
= 4;
895 m_aStdFont
= OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS
, GetAppLanguage(),
896 GetDefaultFontFlags::OnlyOne
, &rRenderContext
);
898 if (svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR
, false).nColor
== COL_AUTO
)
899 m_aStdFont
.SetColor( rDocColor
.IsDark() ? COL_WHITE
: COL_BLACK
);
901 m_aStdFont
.SetColor( rFontColor
);
903 const tools::Long nFontHeight
= nYStep
* ( m_bPosition
? 15 : 6 ) / 10;
904 m_aStdFont
.SetFontSize(Size( 0, nFontHeight
));
906 tools::Long nPreNum
= m_pActNum
->Get(0).GetStart();
910 const tools::Long nLineHeight
= nFontHeight
* 8 / 7;
911 sal_uInt8 nStart
= 0;
912 while (!(m_nActLevel
& (1 << nStart
)))
916 if(nStart
) // so that possible predecessors and successors are showed
919 SwNumberTree::tNumberVector aNumVector
;
920 sal_uInt8 nEnd
= std::min(sal_uInt8(nStart
+ 3), MAXLEVEL
);
921 for (sal_uInt8 nLevel
= nStart
; nLevel
< nEnd
; ++nLevel
)
923 const SwNumFormat
&rFormat
= m_pActNum
->Get(nLevel
);
924 aNumVector
.push_back(rFormat
.GetStart());
926 tools::Long
nXStart( 0 );
927 tools::Long
nTextOffset( 0 );
928 tools::Long
nNumberXPos( 0 );
929 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
931 nXStart
= rFormat
.GetAbsLSpace() / nWidthRelation
;
932 nTextOffset
= rFormat
.GetCharTextDistance() / nWidthRelation
;
933 nNumberXPos
= nXStart
;
934 const tools::Long nFirstLineOffset
= (-rFormat
.GetFirstLineOffset()) / nWidthRelation
;
936 if(nFirstLineOffset
<= nNumberXPos
)
937 nNumberXPos
-= nFirstLineOffset
;
941 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
943 const tools::Long
nTmpNumberXPos((rFormat
.GetIndentAt() + rFormat
.GetFirstLineIndent()) / nWidthRelation
);
944 nNumberXPos
= (nTmpNumberXPos
< 0) ? 0 : nTmpNumberXPos
;
947 tools::Long nBulletWidth
= 0;
948 if (SVX_NUM_BITMAP
== rFormat
.GetNumberingType())
950 nBulletWidth
= lcl_DrawGraphic(*pVDev
, rFormat
, nNumberXPos
,
951 nYStart
, nWidthRelation
);
953 else if (SVX_NUM_CHAR_SPECIAL
== rFormat
.GetNumberingType())
955 nBulletWidth
= lcl_DrawBullet(pVDev
.get(), rFormat
, nNumberXPos
,
956 nYStart
, m_aStdFont
.GetFontSize());
960 pVDev
->SetFont(m_aStdFont
);
961 if(m_pActNum
->IsContinusNum())
962 aNumVector
[nLevel
] = nPreNum
;
963 OUString
aText(m_pActNum
->MakeNumString( aNumVector
));
964 pVDev
->DrawText( Point(nNumberXPos
, nYStart
), aText
);
965 nBulletWidth
= pVDev
->GetTextWidth(aText
);
968 if ( rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
&&
969 rFormat
.GetLabelFollowedBy() == SvxNumberFormat::SPACE
)
971 pVDev
->SetFont(m_aStdFont
);
973 pVDev
->DrawText( Point(nNumberXPos
, nYStart
), aText
);
974 nBulletWidth
+= pVDev
->GetTextWidth(aText
);
977 tools::Long
nTextXPos(0);
978 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
982 nTextXPos
= nTextXPos
+ nTextOffset
;
983 if (nNumberXPos
+ nBulletWidth
+ nTextOffset
> nTextXPos
)
984 nTextXPos
= nNumberXPos
+ nBulletWidth
+ nTextOffset
;
986 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
988 switch (rFormat
.GetLabelFollowedBy())
990 case SvxNumberFormat::LISTTAB
:
992 nTextXPos
= rFormat
.GetListtabPos() / nWidthRelation
;
993 if (nTextXPos
< nNumberXPos
+ nBulletWidth
)
995 nTextXPos
= nNumberXPos
+ nBulletWidth
;
999 case SvxNumberFormat::SPACE
:
1000 case SvxNumberFormat::NOTHING
:
1001 case SvxNumberFormat::NEWLINE
:
1003 nTextXPos
= nNumberXPos
+ nBulletWidth
;
1008 nXStart
= rFormat
.GetIndentAt() / nWidthRelation
;
1011 tools::Rectangle
aRect1(Point(nTextXPos
, nYStart
+ nFontHeight
/ 2), Size(aSize
.Width() / 2, 2));
1012 pVDev
->SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetWindowColor()); // COL_BLACK );
1013 pVDev
->DrawRect(aRect1
);
1015 tools::Rectangle
aRect2(Point(nXStart
, nYStart
+ nLineHeight
+ nFontHeight
/ 2), Size(aSize
.Width() / 2, 2));
1016 pVDev
->DrawRect(aRect2
);
1017 nYStart
+= 2 * nLineHeight
;
1022 SwNumberTree::tNumberVector aNumVector
;
1023 const tools::Long nLineHeight
= nFontHeight
* 3 / 2;
1024 for (sal_uInt8 nLevel
= 0; nLevel
< MAXLEVEL
; ++nLevel
, nYStart
= nYStart
+ nYStep
)
1026 const SwNumFormat
&rFormat
= m_pActNum
->Get(nLevel
);
1027 aNumVector
.push_back(rFormat
.GetStart());
1028 tools::Long
nXStart(0);
1029 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1031 nXStart
= rFormat
.GetAbsLSpace() / nWidthRelation
;
1033 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
1035 const tools::Long
nTmpXStart((rFormat
.GetIndentAt() + rFormat
.GetFirstLineIndent() ) / nWidthRelation
);
1036 nXStart
= (nTmpXStart
< 0) ? 0 : nTmpXStart
;
1040 tools::Long nTextOffset
;
1041 if (SVX_NUM_BITMAP
== rFormat
.GetNumberingType())
1043 lcl_DrawGraphic(*pVDev
, rFormat
, nXStart
, nYStart
, nWidthRelation
);
1044 nTextOffset
= nLineHeight
+ nXStep
;
1046 else if (SVX_NUM_CHAR_SPECIAL
== rFormat
.GetNumberingType())
1048 nTextOffset
= lcl_DrawBullet(pVDev
.get(), rFormat
, nXStart
, nYStart
, m_aStdFont
.GetFontSize());
1049 nTextOffset
+= nXStep
;
1053 pVDev
->SetFont(m_aStdFont
);
1054 if (m_pActNum
->IsContinusNum())
1055 aNumVector
[nLevel
] = nPreNum
;
1056 OUString
aText(m_pActNum
->MakeNumString( aNumVector
));
1057 pVDev
->DrawText( Point(nXStart
, nYStart
), aText
);
1058 nTextOffset
= pVDev
->GetTextWidth(aText
) + nXStep
;
1061 pVDev
->SetFont(m_aStdFont
);
1063 Point(nXStart
+ nTextOffset
, nYStart
),
1064 (m_pOutlineNames
== nullptr
1065 ? utl::ConfigManager::getProductName()
1066 : m_pOutlineNames
[nLevel
]));
1070 rRenderContext
.DrawOutDev(Point(0,0), aSize
, Point(0,0), aSize
, *pVDev
);
1073 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */