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/menu.hxx>
22 #include <vcl/settings.hxx>
23 #include <vcl/virdev.hxx>
24 #include <sfx2/tabdlg.hxx>
25 #include <editeng/brushitem.hxx>
26 #include <unotools/configmgr.hxx>
27 #include <SwStyleNameMapper.hxx>
33 #include <swmodule.hxx>
35 #include <outline.hxx>
37 #include <poolfmt.hxx>
38 #include <shellres.hxx>
39 #include <svl/style.hxx>
40 #include <charfmt.hxx>
41 #include <docstyle.hxx>
42 #include <viewopt.hxx>
43 #include <svtools/ctrlbox.hxx>
44 #include <globals.hrc>
45 #include <outline.hrc>
46 #include <strings.hrc>
51 #include <IDocumentOutlineNodes.hxx>
54 #include <com/sun/star/accessibility/AccessibleRole.hpp>
56 using namespace ::com::sun::star
;
58 class SwNumNamesDlg
: public weld::GenericDialogController
60 std::unique_ptr
<weld::Entry
> m_xFormEdit
;
61 std::unique_ptr
<weld::TreeView
> m_xFormBox
;
62 std::unique_ptr
<weld::Button
> m_xOKBtn
;
64 DECL_LINK( ModifyHdl
, weld::Entry
&, void );
65 DECL_LINK( SelectHdl
, weld::TreeView
&, void );
66 DECL_LINK( DoubleClickHdl
, weld::TreeView
&, bool );
69 explicit SwNumNamesDlg(weld::Window
*pParent
);
70 void SetUserNames(const OUString
*pList
[]);
71 OUString
GetName() const { return m_xFormEdit
->get_text(); }
72 int GetCurEntryPos() const { return m_xFormBox
->get_selected_index(); }
75 // remember selected entry
76 IMPL_LINK( SwNumNamesDlg
, SelectHdl
, weld::TreeView
&, rBox
, void )
78 m_xFormEdit
->set_text(rBox
.get_selected_text());
79 m_xFormEdit
->select_region(0, -1);
82 /** set user defined names
84 * @param pList list of user defined names; unknown positions for the user are 0.
86 void SwNumNamesDlg::SetUserNames(const OUString
*pList
[])
88 sal_uInt16 nSelect
= 0;
89 for (sal_uInt16 i
= 0; i
< SwChapterNumRules::nMaxRules
; ++i
)
93 m_xFormBox
->remove(i
);
94 m_xFormBox
->insert_text(i
, *pList
[i
]);
99 m_xFormBox
->select(nSelect
);
100 SelectHdl(*m_xFormBox
);
103 // unlock OK-Button when text is in Edit
104 IMPL_LINK( SwNumNamesDlg
, ModifyHdl
, weld::Entry
&, rBox
, void )
106 m_xOKBtn
->set_sensitive(!rBox
.get_text().isEmpty());
110 IMPL_LINK_NOARG(SwNumNamesDlg
, DoubleClickHdl
, weld::TreeView
&, bool)
112 m_xDialog
->response(RET_OK
);
116 SwNumNamesDlg::SwNumNamesDlg(weld::Window
*pParent
)
117 : GenericDialogController(pParent
,
118 "modules/swriter/ui/numberingnamedialog.ui",
119 "NumberingNameDialog")
120 , m_xFormEdit(m_xBuilder
->weld_entry("entry"))
121 , m_xFormBox(m_xBuilder
->weld_tree_view("form"))
122 , m_xOKBtn(m_xBuilder
->weld_button("ok"))
124 for (size_t i
= 0; i
< SAL_N_ELEMENTS(OUTLINE_STYLE
); ++i
)
125 m_xFormBox
->append_text(SwResId(OUTLINE_STYLE
[i
]));
127 m_xFormEdit
->connect_changed(LINK(this, SwNumNamesDlg
, ModifyHdl
));
128 m_xFormBox
->connect_changed(LINK(this, SwNumNamesDlg
, SelectHdl
));
129 m_xFormBox
->connect_row_activated(LINK(this, SwNumNamesDlg
, DoubleClickHdl
));
130 m_xFormBox
->set_size_request(-1, m_xFormBox
->get_height_rows(9));
133 static sal_uInt16
lcl_BitToLevel(sal_uInt16 nActLevel
)
135 sal_uInt16 nTmp
= nActLevel
;
136 sal_uInt16 nTmpLevel
= 0;
137 while( 0 != (nTmp
>>= 1) )
142 sal_uInt16
SwOutlineTabDialog::nNumLevel
= 1;
144 SwOutlineTabDialog::SwOutlineTabDialog(weld::Window
* pParent
, const SfxItemSet
* pSwItemSet
,
146 : SfxTabDialogController(pParent
, "modules/swriter/ui/outlinenumbering.ui", "OutlineNumberingDialog", pSwItemSet
)
148 , pChapterNumRules(SW_MOD()->GetChapterNumRules())
149 , bModified(rWrtSh
.IsModified())
150 , m_xMenuButton(m_xBuilder
->weld_menu_button("format"))
152 m_xMenuButton
->connect_toggled(LINK(this, SwOutlineTabDialog
, FormHdl
));
153 m_xMenuButton
->connect_selected(LINK(this, SwOutlineTabDialog
, MenuSelectHdl
));
155 xNumRule
.reset(new SwNumRule(*rSh
.GetOutlineNumRule()));
156 GetCancelButton().connect_clicked(LINK(this, SwOutlineTabDialog
, CancelHdl
));
158 AddTabPage("position", &SwNumPositionTabPage::Create
, nullptr);
159 AddTabPage("numbering", &SwOutlineSettingsTabPage::Create
, nullptr);
164 for( i
= 0; i
< MAXLEVEL
; ++i
)
166 // if the style wasn't created yet, it's still at this position
167 if( !rWrtSh
.GetParaStyle( sHeadline
=
168 SwStyleNameMapper::GetUIName( static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
),
170 aCollNames
[i
] = sHeadline
;
173 // query the text templates' outlining levels
174 const sal_uInt16 nCount
= rWrtSh
.GetTextFormatCollCount();
175 for(i
= 0; i
< nCount
; ++i
)
177 SwTextFormatColl
&rTextColl
= rWrtSh
.GetTextFormatColl(i
);
178 if(!rTextColl
.IsDefault())
180 if(rTextColl
.IsAssignedToListLevelOfOutlineStyle())
182 int nOutLevel
= rTextColl
.GetAssignedOutlineStyleLevel();
183 aCollNames
[ nOutLevel
] = rTextColl
.GetName();
189 SwOutlineTabDialog::~SwOutlineTabDialog()
193 void SwOutlineTabDialog::PageCreated(const OString
& rPageId
, SfxTabPage
& rPage
)
195 if (rPageId
== "position")
197 static_cast<SwNumPositionTabPage
&>(rPage
).SetWrtShell(&rWrtSh
);
198 static_cast<SwNumPositionTabPage
&>(rPage
).SetOutlineTabDialog(this);
200 else if (rPageId
== "numbering")
202 static_cast<SwOutlineSettingsTabPage
&>(rPage
).SetWrtShell(&rWrtSh
);
206 IMPL_LINK_NOARG(SwOutlineTabDialog
, CancelHdl
, weld::Button
&, void)
209 rWrtSh
.ResetModified();
210 m_xDialog
->response(RET_CANCEL
);
213 IMPL_LINK_NOARG(SwOutlineTabDialog
, FormHdl
, weld::ToggleButton
&, void)
215 if (!m_xMenuButton
->get_active())
219 for(sal_uInt16 i
= 0; i
< SwChapterNumRules::nMaxRules
; ++i
)
221 const SwNumRulesWithName
*pRules
= pChapterNumRules
->GetRules(i
);
224 m_xMenuButton
->set_item_label("form" + OString::number(i
+ 1), pRules
->GetName());
227 OString
sHelpId(m_xMenuButton
->get_item_help_id("form1"));
228 for (sal_Int32 i
= 2; i
<= 9; ++i
)
230 m_xMenuButton
->set_item_help_id("form" + OString::number(i
), sHelpId
);
234 IMPL_LINK(SwOutlineTabDialog
, MenuSelectHdl
, const OString
&, 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
= 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 pChapterNumRules
->ApplyNumRules( SwNumRulesWithName(
273 *xNumRule
, aName
), aDlg
.GetCurEntryPos() );
274 m_xMenuButton
->set_item_label("form" + OString::number(aDlg
.GetCurEntryPos() + 1), aName
);
281 const SwNumRulesWithName
*pRules
= pChapterNumRules
->GetRules( nLevelNo
);
284 xNumRule
= pRules
->MakeNumRule(rWrtSh
);
285 xNumRule
->SetRuleType( OUTLINE_RULE
);
286 SfxTabPage
* pOutlinePage
= GetTabPage("numbering");
287 assert(pOutlinePage
);
288 static_cast<SwOutlineSettingsTabPage
*>(pOutlinePage
)->SetNumRule(xNumRule
.get());
291 *xNumRule
= *rWrtSh
.GetOutlineNumRule();
294 SfxTabPage
* pPage
= GetCurTabPage();
295 pPage
->Reset(GetOutputItemSet());
298 sal_uInt16
SwOutlineTabDialog::GetLevel(const OUString
&rFormatName
) const
300 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; ++i
)
302 if(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 rWrtSh
.StartAction();
318 const SwNumRule
* pOutlineRule
= rWrtSh
.GetOutlineNumRule();
320 sal_uInt16 i
, nCount
= rWrtSh
.GetTextFormatCollCount();
321 for( i
= 0; i
< nCount
; ++i
)
323 SwTextFormatColl
&rTextColl
= 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
= rWrtSh
.FindTextFormatCollByName( sHeadline
);
361 if( !pColl
&& aCollNames
[i
] != sHeadline
)
363 SwTextFormatColl
* pTextColl
= rWrtSh
.GetTextCollFromPool(
364 static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
) );
365 pTextColl
->DeleteAssignmentToListLevelOfOutlineStyle();
366 pTextColl
->ResetFormatAttr(RES_PARATR_NUMRULE
);
368 if( !aCollNames
[i
].isEmpty() )
370 pTextColl
= rWrtSh
.GetParaStyle(
371 aCollNames
[i
], SwWrtShell::GETSTYLE_CREATESOME
);
374 pTextColl
->AssignToListLevelOfOutlineStyle(i
);
375 SwNumRuleItem
aItem(pOutlineRule
->GetName());
376 pTextColl
->SetFormatAttr(aItem
);
382 rWrtSh
.SetOutlineNumRule(*xNumRule
);
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 , aNoFormatName(SwResId(SW_STR_NONE
))
396 , 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(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
->connect_changed(LINK(this, SwOutlineSettingsTabPage
, CharFormatHdl
));
424 void SwOutlineSettingsTabPage::Update()
426 // if a template was already selected for this level, select it in the ListBox
427 m_xCollBox
->set_sensitive(USHRT_MAX
!= nActLevel
);
428 if(USHRT_MAX
== nActLevel
)
430 bool bSamePrefix
= true;
431 bool bSameSuffix
= true;
432 bool bSameType
= true;
433 bool bSameComplete
= true;
434 bool bSameStart
= true;
435 bool bSameCharFormat
= true;
437 const SwNumFormat
* aNumFormatArr
[MAXLEVEL
];
438 const SwCharFormat
* pFirstFormat
= nullptr;
440 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
443 aNumFormatArr
[ i
] = &pNumRule
->Get(i
);
445 pFirstFormat
= aNumFormatArr
[i
]->GetCharFormat();
448 bSameType
&= aNumFormatArr
[i
]->GetNumberingType() == aNumFormatArr
[0]->GetNumberingType();
449 bSameStart
&= aNumFormatArr
[i
]->GetStart() == aNumFormatArr
[0]->GetStart();
450 bSamePrefix
&= aNumFormatArr
[i
]->GetPrefix() == aNumFormatArr
[0]->GetPrefix();
451 bSameSuffix
&= aNumFormatArr
[i
]->GetSuffix() == aNumFormatArr
[0]->GetSuffix();
452 bSameComplete
&= aNumFormatArr
[i
]->GetIncludeUpperLevels() == aNumFormatArr
[0]->GetIncludeUpperLevels();
453 const SwCharFormat
* pFormat
= aNumFormatArr
[i
]->GetCharFormat();
454 bSameCharFormat
&= (!pFirstFormat
&& !pFormat
)
455 || (pFirstFormat
&& pFormat
&& pFormat
->GetName() == pFirstFormat
->GetName());
458 CheckForStartValue_Impl(aNumFormatArr
[0]->GetNumberingType());
460 m_xNumberBox
->SelectNumberingType( aNumFormatArr
[0]->GetNumberingType() );
462 m_xNumberBox
->SetNoSelection();
464 m_xStartEdit
->set_value(aNumFormatArr
[0]->GetStart());
466 m_xStartEdit
->set_text(OUString());
468 m_xPrefixED
->set_text(aNumFormatArr
[0]->GetPrefix());
470 m_xPrefixED
->set_text(OUString());
472 m_xSuffixED
->set_text(aNumFormatArr
[0]->GetSuffix());
474 m_xSuffixED
->set_text(OUString());
479 m_xCharFormatLB
->set_active_text(pFirstFormat
->GetName());
481 m_xCharFormatLB
->set_active_text(SwViewShell::GetShellRes()->aStrNone
);
484 m_xCharFormatLB
->set_active(-1);
486 m_xAllLevelFT
->set_sensitive(true);
487 m_xAllLevelNF
->set_sensitive(true);
488 m_xAllLevelNF
->set_max(MAXLEVEL
);
491 m_xAllLevelNF
->set_value(aNumFormatArr
[0]->GetIncludeUpperLevels());
495 m_xAllLevelNF
->set_text(OUString());
500 sal_uInt16 nTmpLevel
= lcl_BitToLevel(nActLevel
);
501 OUString
aColl(pCollNames
[nTmpLevel
]);
503 m_xCollBox
->set_active_text(aColl
);
505 m_xCollBox
->set_active_text(aNoFormatName
);
506 const SwNumFormat
&rFormat
= pNumRule
->Get(nTmpLevel
);
508 m_xNumberBox
->SelectNumberingType( rFormat
.GetNumberingType() );
509 m_xPrefixED
->set_text(rFormat
.GetPrefix());
510 m_xSuffixED
->set_text(rFormat
.GetSuffix());
511 const SwCharFormat
* pFormat
= rFormat
.GetCharFormat();
513 m_xCharFormatLB
->set_active_text(pFormat
->GetName());
515 m_xCharFormatLB
->set_active_text(SwViewShell::GetShellRes()->aStrNone
);
519 m_xAllLevelFT
->set_sensitive(true);
520 m_xAllLevelNF
->set_sensitive(true);
521 m_xAllLevelNF
->set_max(nTmpLevel
+ 1);
522 m_xAllLevelNF
->set_value(rFormat
.GetIncludeUpperLevels());
526 m_xAllLevelNF
->set_text(OUString());
527 m_xAllLevelNF
->set_sensitive(false);
528 m_xAllLevelFT
->set_sensitive(false);
530 CheckForStartValue_Impl(rFormat
.GetNumberingType());
531 m_xStartEdit
->set_value( rFormat
.GetStart() );
536 IMPL_LINK( SwOutlineSettingsTabPage
, LevelHdl
, weld::TreeView
&, rBox
, void )
539 auto aRows
= rBox
.get_selected_rows();
540 if (std::find(aRows
.begin(), aRows
.end(), MAXLEVEL
) != aRows
.end())
546 sal_uInt16 nMask
= 1;
547 for( sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++ )
549 if (std::find(aRows
.begin(), aRows
.end(), i
) != aRows
.end())
557 IMPL_LINK(SwOutlineSettingsTabPage
, ToggleComplete
, weld::SpinButton
&, rEdit
, void)
559 sal_uInt16 nMask
= 1;
560 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
562 if(nActLevel
& nMask
)
564 SwNumFormat
aNumFormat(pNumRule
->Get(i
));
565 aNumFormat
.SetIncludeUpperLevels( std::min( static_cast<sal_uInt8
>(rEdit
.get_value()),
566 static_cast<sal_uInt8
>(i
+ 1)) );
567 pNumRule
->Set(i
, aNumFormat
);
574 IMPL_LINK( SwOutlineSettingsTabPage
, CollSelect
, weld::ComboBox
&, rBox
, void )
578 const OUString
aCollName(rBox
.get_active_text());
579 //0xFFFF not allowed here (disable)
580 sal_uInt16 nTmpLevel
= lcl_BitToLevel(nActLevel
);
581 OUString
sOldName( pCollNames
[nTmpLevel
] );
583 for( i
= 0; i
< MAXLEVEL
; ++i
)
584 pCollNames
[i
] = aSaveCollNames
[i
];
586 if(aCollName
== aNoFormatName
)
587 pCollNames
[nTmpLevel
].clear();
590 pCollNames
[nTmpLevel
] = aCollName
;
591 // template already in use?
592 for( i
= 0; i
< MAXLEVEL
; ++i
)
593 if(i
!= nTmpLevel
&& pCollNames
[i
] == aCollName
)
594 pCollNames
[i
].clear();
597 // search the oldname and put it into the current entries
598 if( !sOldName
.isEmpty() )
599 for( i
= 0; i
< MAXLEVEL
; ++i
)
600 if( aSaveCollNames
[ i
] == sOldName
&& i
!= nTmpLevel
&&
601 pCollNames
[ i
].isEmpty() )
604 for( n
= 0; n
< MAXLEVEL
; ++n
)
605 if( pCollNames
[ n
] == sOldName
)
609 // it was an outline level name and the current entries is zero.
610 pCollNames
[ i
] = sOldName
;
617 void SwOutlineSettingsTabPage::CollSave()
619 for (sal_uInt8 i
= 0; i
< MAXLEVEL
; ++i
)
620 aSaveCollNames
[i
] = pCollNames
[i
];
623 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, NumberSelect
, weld::ComboBox
&, void)
625 sal_uInt16 nMask
= 1;
626 SvxNumType nNumberType
= m_xNumberBox
->GetSelectedNumberingType();
627 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
629 if(nActLevel
& nMask
)
631 SwNumFormat
aNumFormat(pNumRule
->Get(i
));
632 aNumFormat
.SetNumberingType(nNumberType
);
633 pNumRule
->Set(i
, aNumFormat
);
634 CheckForStartValue_Impl(nNumberType
);
641 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, DelimModify
, weld::Entry
&, void)
643 sal_uInt16 nMask
= 1;
644 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
646 if(nActLevel
& nMask
)
648 SwNumFormat
aNumFormat(pNumRule
->Get(i
));
649 aNumFormat
.SetPrefix( m_xPrefixED
->get_text() );
650 aNumFormat
.SetSuffix( m_xSuffixED
->get_text() );
651 pNumRule
->Set(i
, aNumFormat
);
658 IMPL_LINK( SwOutlineSettingsTabPage
, StartModified
, weld::SpinButton
&, rEdit
, void )
660 sal_uInt16 nMask
= 1;
661 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
663 if(nActLevel
& nMask
)
665 SwNumFormat
aNumFormat(pNumRule
->Get(i
));
666 aNumFormat
.SetStart(static_cast<sal_uInt16
>(rEdit
.get_value()));
667 pNumRule
->Set(i
, aNumFormat
);
674 IMPL_LINK_NOARG(SwOutlineSettingsTabPage
, CharFormatHdl
, weld::ComboBox
&, void)
676 OUString sEntry
= m_xCharFormatLB
->get_active_text();
677 sal_uInt16 nMask
= 1;
678 bool bFormatNone
= sEntry
== SwViewShell::GetShellRes()->aStrNone
;
679 SwCharFormat
* pFormat
= nullptr;
682 sal_uInt16 nChCount
= pSh
->GetCharFormatCount();
683 for(sal_uInt16 i
= 0; i
< nChCount
; i
++)
685 SwCharFormat
& rChFormat
= pSh
->GetCharFormat(i
);
686 if(rChFormat
.GetName() == sEntry
)
688 pFormat
= &rChFormat
;
694 SfxStyleSheetBasePool
* pPool
= pSh
->GetView().GetDocShell()->GetStyleSheetPool();
695 SfxStyleSheetBase
* pBase
;
696 pBase
= pPool
->Find(sEntry
, SfxStyleFamily::Char
);
698 pBase
= &pPool
->Make(sEntry
, SfxStyleFamily::Page
);
699 pFormat
= static_cast<SwDocStyleSheet
*>(pBase
)->GetCharFormat();
704 for(sal_uInt16 i
= 0; i
< MAXLEVEL
; i
++)
706 if(nActLevel
& nMask
)
708 SwNumFormat
aNumFormat(pNumRule
->Get(i
));
710 aNumFormat
.SetCharFormat(nullptr);
712 aNumFormat
.SetCharFormat(pFormat
);
713 pNumRule
->Set(i
, aNumFormat
);
719 SwOutlineSettingsTabPage::~SwOutlineSettingsTabPage()
723 void SwOutlineSettingsTabPage::SetWrtShell(SwWrtShell
* pShell
)
726 // query this document's NumRules
727 pNumRule
= static_cast<SwOutlineTabDialog
*>(GetDialogController())->GetNumRule();
728 pCollNames
= static_cast<SwOutlineTabDialog
*>(GetDialogController())->GetCollNames();
732 m_aPreviewWIN
.SetNumRule(pNumRule
);
733 m_aPreviewWIN
.SetOutlineNames(pCollNames
);
734 // set start value - nActLevel must be 1 here
735 sal_uInt16 nTmpLevel
= lcl_BitToLevel(nActLevel
);
736 const SwNumFormat
& rNumFormat
= pNumRule
->Get( nTmpLevel
);
737 m_xStartEdit
->set_value( rNumFormat
.GetStart() );
739 // create pool formats for headlines
740 for (sal_uInt16 i
= 0; i
< MAXLEVEL
; ++i
)
742 m_xCollBox
->append_text( SwStyleNameMapper::GetUIName(
743 static_cast< sal_uInt16
>(RES_POOLCOLL_HEADLINE1
+ i
), OUString()));
744 m_xLevelLB
->append_text( OUString::number(i
+ 1) );
746 OUString sStr
= "1 - " + OUString::number(MAXLEVEL
);
747 m_xLevelLB
->append_text(sStr
);
749 // query the texttemplates' outlining levels
750 const sal_uInt16 nCount
= pSh
->GetTextFormatCollCount();
751 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
753 SwTextFormatColl
&rTextColl
= pSh
->GetTextFormatColl(i
);
754 if(!rTextColl
.IsDefault())
756 sStr
= rTextColl
.GetName();
757 if (m_xCollBox
->find_text(sStr
) == -1)
758 m_xCollBox
->append_text(sStr
);
762 m_xNumberBox
->SelectNumberingType(rNumFormat
.GetNumberingType());
763 SwOutlineNodes::size_type nOutlinePos
= pSh
->GetOutlinePos(MAXLEVEL
);
765 if(nOutlinePos
!= SwOutlineNodes::npos
)
767 nTmp
= static_cast<sal_uInt16
>(pSh
->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos
));
769 m_xLevelLB
->select(nTmp
-1);
771 // collect char styles
772 m_xCharFormatLB
->clear();
773 m_xCharFormatLB
->append_text(SwViewShell::GetShellRes()->aStrNone
);
776 ::FillCharStyleListBox(*m_xCharFormatLB
,
777 pSh
->GetView().GetDocShell());
781 void SwOutlineSettingsTabPage::ActivatePage(const SfxItemSet
& )
783 nActLevel
= SwOutlineTabDialog::GetActNumLevel();
784 if(nActLevel
!= USHRT_MAX
)
785 m_xLevelLB
->select(lcl_BitToLevel(nActLevel
));
787 m_xLevelLB
->select(MAXLEVEL
);
788 LevelHdl(*m_xLevelLB
);
791 DeactivateRC
SwOutlineSettingsTabPage::DeactivatePage(SfxItemSet
*)
793 SwOutlineTabDialog::SetActNumLevel(nActLevel
);
794 return DeactivateRC::LeavePage
;
797 bool SwOutlineSettingsTabPage::FillItemSet( SfxItemSet
* )
802 void SwOutlineSettingsTabPage::Reset( const SfxItemSet
* rSet
)
807 std::unique_ptr
<SfxTabPage
> SwOutlineSettingsTabPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
,
808 const SfxItemSet
* rAttrSet
)
810 return std::make_unique
<SwOutlineSettingsTabPage
>(pPage
, pController
, *rAttrSet
);
813 void SwOutlineSettingsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType
)
815 bool bIsNull
= m_xStartEdit
->get_value() == 0;
816 bool bNoZeroAllowed
= nNumberingType
< SVX_NUM_ARABIC
||
817 SVX_NUM_CHARS_UPPER_LETTER_N
== nNumberingType
||
818 SVX_NUM_CHARS_LOWER_LETTER_N
== nNumberingType
;
819 m_xStartEdit
->set_min(bNoZeroAllowed
? 1 : 0);
820 if (bIsNull
&& bNoZeroAllowed
)
821 StartModified(*m_xStartEdit
);
824 static long lcl_DrawBullet(vcl::RenderContext
* pVDev
, const SwNumFormat
& rFormat
, long nXStart
, long nYStart
, const Size
& rSize
)
826 vcl::Font
aTmpFont(pVDev
->GetFont());
828 // via Uno it's possible that no font has been set!
829 vcl::Font
aFont(rFormat
.GetBulletFont() ? *rFormat
.GetBulletFont() : aTmpFont
);
830 Size
aTmpSize(rSize
);
831 aTmpSize
.setWidth( aTmpSize
.Width() * ( rFormat
.GetBulletRelSize()) );
832 aTmpSize
.setWidth( aTmpSize
.Width() / 100 ) ;
833 aTmpSize
.setHeight( aTmpSize
.Height() * ( rFormat
.GetBulletRelSize()) );
834 aTmpSize
.setHeight( aTmpSize
.Height() / 100 ) ;
835 // in case of a height of zero it is drawn in original height
836 if(!aTmpSize
.Height())
837 aTmpSize
.setHeight( 1 );
838 aFont
.SetFontSize(aTmpSize
);
839 aFont
.SetTransparent(true);
840 Color aBulletColor
= rFormat
.GetBulletColor();
841 if(aBulletColor
== COL_AUTO
)
842 aBulletColor
= pVDev
->GetFillColor().IsDark() ? COL_WHITE
: COL_BLACK
;
843 else if(aBulletColor
== pVDev
->GetFillColor())
844 aBulletColor
.Invert();
845 aFont
.SetColor(aBulletColor
);
846 pVDev
->SetFont( aFont
);
847 OUString
aText(rFormat
.GetBulletChar());
849 nY
-= ((aTmpSize
.Height() - rSize
.Height())/ 2);
850 pVDev
->DrawText( Point(nXStart
, nY
), aText
);
851 long nRet
= pVDev
->GetTextWidth(aText
);
853 pVDev
->SetFont(aTmpFont
);
857 static long lcl_DrawGraphic(vcl::RenderContext
* pVDev
, const SwNumFormat
&rFormat
, long nXStart
, long nYStart
, long nDivision
)
859 const SvxBrushItem
* pBrushItem
= rFormat
.GetBrush();
863 const Graphic
* pGraphic
= pBrushItem
->GetGraphic();
866 Size
aGSize( rFormat
.GetGraphicSize());
867 aGSize
.setWidth( aGSize
.Width() / nDivision
);
868 nRet
= aGSize
.Width();
869 aGSize
.setHeight( aGSize
.Height() / nDivision
);
870 pGraphic
->Draw(pVDev
, Point(nXStart
, nYStart
), pVDev
->PixelToLogic(aGSize
));
876 void NumberingPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
878 const Size
aSize(rRenderContext
.PixelToLogic(GetOutputSizePixel()));
880 ScopedVclPtrInstance
<VirtualDevice
> pVDev(rRenderContext
);
881 pVDev
->SetMapMode(rRenderContext
.GetMapMode());
882 pVDev
->SetOutputSize(aSize
);
885 pVDev
->SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetWindowColor());
886 pVDev
->SetLineColor(rRenderContext
.GetSettings().GetStyleSettings().GetButtonTextColor());
887 pVDev
->DrawRect(tools::Rectangle(Point(0,0), aSize
));
891 long nWidthRelation
= 30; // chapter dialog
894 nWidthRelation
= nPageWidth
/ aSize
.Width();
896 nWidthRelation
= nWidthRelation
* 2 / 3;
898 nWidthRelation
= nWidthRelation
/ 4;
902 const long nXStep
= aSize
.Width() / (3 * MAXLEVEL
* ((MAXLEVEL
< 10) ? 2 : 1));
903 const long nYStep
= (aSize
.Height() - 6)/ MAXLEVEL
;
905 aStdFont
= OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS
, GetAppLanguage(),
906 GetDefaultFontFlags::OnlyOne
, &rRenderContext
);
908 aStdFont
.SetColor(SwViewOption::GetFontColor());
910 const long nFontHeight
= nYStep
* ( bPosition
? 15 : 6 ) / 10;
911 aStdFont
.SetFontSize(Size( 0, nFontHeight
));
913 long nPreNum
= pActNum
->Get(0).GetStart();
917 const long nLineHeight
= nFontHeight
* 8 / 7;
918 sal_uInt8 nStart
= 0;
919 while (!(nActLevel
& (1 << nStart
)))
923 if(nStart
) // so that possible predecessors and successors are showed
926 SwNumberTree::tNumberVector aNumVector
;
927 sal_uInt8 nEnd
= std::min(sal_uInt8(nStart
+ 3), MAXLEVEL
);
928 for (sal_uInt8 nLevel
= nStart
; nLevel
< nEnd
; ++nLevel
)
930 const SwNumFormat
&rFormat
= pActNum
->Get(nLevel
);
931 aNumVector
.push_back(rFormat
.GetStart());
934 long nTextOffset( 0 );
935 long nNumberXPos( 0 );
936 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
938 nXStart
= rFormat
.GetAbsLSpace() / nWidthRelation
;
939 nTextOffset
= rFormat
.GetCharTextDistance() / nWidthRelation
;
940 nNumberXPos
= nXStart
;
941 const long nFirstLineOffset
= (-rFormat
.GetFirstLineOffset()) / nWidthRelation
;
943 if(nFirstLineOffset
<= nNumberXPos
)
944 nNumberXPos
-= nFirstLineOffset
;
948 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
950 const long nTmpNumberXPos((rFormat
.GetIndentAt() + rFormat
.GetFirstLineIndent()) / nWidthRelation
);
951 nNumberXPos
= (nTmpNumberXPos
< 0) ? 0 : nTmpNumberXPos
;
954 long nBulletWidth
= 0;
955 if (SVX_NUM_BITMAP
== rFormat
.GetNumberingType())
957 nBulletWidth
= lcl_DrawGraphic(pVDev
.get(), rFormat
, nNumberXPos
,
958 nYStart
, nWidthRelation
);
960 else if (SVX_NUM_CHAR_SPECIAL
== rFormat
.GetNumberingType())
962 nBulletWidth
= lcl_DrawBullet(pVDev
.get(), rFormat
, nNumberXPos
,
963 nYStart
, aStdFont
.GetFontSize());
967 pVDev
->SetFont(aStdFont
);
968 if(pActNum
->IsContinusNum())
969 aNumVector
[nLevel
] = nPreNum
;
970 OUString
aText(pActNum
->MakeNumString( aNumVector
));
971 pVDev
->DrawText( Point(nNumberXPos
, nYStart
), aText
);
972 nBulletWidth
= pVDev
->GetTextWidth(aText
);
975 if ( rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
&&
976 rFormat
.GetLabelFollowedBy() == SvxNumberFormat::SPACE
)
978 pVDev
->SetFont(aStdFont
);
980 pVDev
->DrawText( Point(nNumberXPos
, nYStart
), aText
);
981 nBulletWidth
+= pVDev
->GetTextWidth(aText
);
985 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
989 nTextXPos
= nTextXPos
+ nTextOffset
;
990 if (nNumberXPos
+ nBulletWidth
+ nTextOffset
> nTextXPos
)
991 nTextXPos
= nNumberXPos
+ nBulletWidth
+ nTextOffset
;
993 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
995 switch (rFormat
.GetLabelFollowedBy())
997 case SvxNumberFormat::LISTTAB
:
999 nTextXPos
= rFormat
.GetListtabPos() / nWidthRelation
;
1000 if (nTextXPos
< nNumberXPos
+ nBulletWidth
)
1002 nTextXPos
= nNumberXPos
+ nBulletWidth
;
1006 case SvxNumberFormat::SPACE
:
1007 case SvxNumberFormat::NOTHING
:
1008 case SvxNumberFormat::NEWLINE
:
1010 nTextXPos
= nNumberXPos
+ nBulletWidth
;
1015 nXStart
= rFormat
.GetIndentAt() / nWidthRelation
;
1018 tools::Rectangle
aRect1(Point(nTextXPos
, nYStart
+ nFontHeight
/ 2), Size(aSize
.Width() / 2, 2));
1019 pVDev
->SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetWindowColor()); // COL_BLACK );
1020 pVDev
->DrawRect(aRect1
);
1022 tools::Rectangle
aRect2(Point(nXStart
, nYStart
+ nLineHeight
+ nFontHeight
/ 2), Size(aSize
.Width() / 2, 2));
1023 pVDev
->DrawRect(aRect2
);
1024 nYStart
+= 2 * nLineHeight
;
1029 SwNumberTree::tNumberVector aNumVector
;
1030 const long nLineHeight
= nFontHeight
* 3 / 2;
1031 for (sal_uInt8 nLevel
= 0; nLevel
< MAXLEVEL
; ++nLevel
, nYStart
= nYStart
+ nYStep
)
1033 const SwNumFormat
&rFormat
= pActNum
->Get(nLevel
);
1034 aNumVector
.push_back(rFormat
.GetStart());
1036 if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1038 nXStart
= rFormat
.GetAbsLSpace() / nWidthRelation
;
1040 else if (rFormat
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
1042 const long nTmpXStart((rFormat
.GetIndentAt() + rFormat
.GetFirstLineIndent() ) / nWidthRelation
);
1043 nXStart
= (nTmpXStart
< 0) ? 0 : nTmpXStart
;
1048 if (SVX_NUM_BITMAP
== rFormat
.GetNumberingType())
1050 lcl_DrawGraphic(pVDev
.get(), rFormat
, nXStart
, nYStart
, nWidthRelation
);
1051 nTextOffset
= nLineHeight
+ nXStep
;
1053 else if (SVX_NUM_CHAR_SPECIAL
== rFormat
.GetNumberingType())
1055 nTextOffset
= lcl_DrawBullet(pVDev
.get(), rFormat
, nXStart
, nYStart
, aStdFont
.GetFontSize());
1056 nTextOffset
+= nXStep
;
1060 pVDev
->SetFont(aStdFont
);
1061 if (pActNum
->IsContinusNum())
1062 aNumVector
[nLevel
] = nPreNum
;
1063 OUString
aText(pActNum
->MakeNumString( aNumVector
));
1064 pVDev
->DrawText( Point(nXStart
, nYStart
), aText
);
1065 nTextOffset
= pVDev
->GetTextWidth(aText
) + nXStep
;
1068 pVDev
->SetFont(aStdFont
);
1070 Point(nXStart
+ nTextOffset
, nYStart
),
1071 (pOutlineNames
== nullptr
1072 ? utl::ConfigManager::getProductName()
1073 : pOutlineNames
[nLevel
]));
1077 rRenderContext
.DrawOutDev(Point(0,0), aSize
, Point(0,0), aSize
, *pVDev
);
1080 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */