bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / misc / outline.cxx
blobf80d0b99721c55b861a5e4fe7430ee89148f4b34
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <tools/shl.hxx>
22 #include <vcl/menu.hxx>
23 #include <vcl/msgbox.hxx>
24 #include <sfx2/tabdlg.hxx>
25 #include <editeng/brushitem.hxx>
26 #include <unotools/configmgr.hxx>
27 #include <SwStyleNameMapper.hxx>
28 #include <num.hxx>
29 #include <view.hxx>
30 #include <docsh.hxx>
31 #include <uitool.hxx>
32 #include <wrtsh.hxx>
33 #include <swmodule.hxx>
34 #include <fmtcol.hxx>
35 #include <outline.hxx>
36 #include <uinums.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 <helpid.h>
45 #include <globals.hrc> // for template name 'none'
46 #include <misc.hrc>
47 #include <paratr.hxx>
49 #include <unomid.h>
51 #include <IDocumentOutlineNodes.hxx>
52 #include <app.hrc>
54 #include <com/sun/star/accessibility/AccessibleRole.hpp>
56 using namespace ::com::sun::star;
58 DBG_NAME(outlinehdl)
60 class SwNumNamesDlg : public ModalDialog
62 Edit* m_pFormEdit;
63 ListBox* m_pFormBox;
64 OKButton* m_pOKBtn;
66 DECL_LINK( ModifyHdl, Edit * );
67 DECL_LINK( SelectHdl, ListBox * );
68 DECL_LINK(DoubleClickHdl, void *);
70 public:
71 SwNumNamesDlg(Window *pParent);
72 void SetUserNames(const String *pList[]);
73 String GetName() const { return m_pFormEdit->GetText(); }
74 sal_uInt16 GetCurEntryPos() const { return m_pFormBox->GetSelectEntryPos(); }
77 /*------------------------------------------------------------------------
78 Description: remember selected entry
79 ------------------------------------------------------------------------*/
80 IMPL_LINK_INLINE_START( SwNumNamesDlg, SelectHdl, ListBox *, pBox )
82 m_pFormEdit->SetText(pBox->GetSelectEntry());
83 m_pFormEdit->SetSelection(Selection(0, SELECTION_MAX));
84 return 0;
86 IMPL_LINK_INLINE_END( SwNumNamesDlg, SelectHdl, ListBox *, pBox )
88 /*------------------------------------------------------------------------
89 Description: set user defined names
90 Parameter: list of user defined names;
91 unknown positions for the user are 0.
92 ------------------------------------------------------------------------*/
93 void SwNumNamesDlg::SetUserNames(const String *pList[])
95 sal_uInt16 nSelect = 0;
96 for(sal_uInt16 i = 0; i < SwBaseNumRules::nMaxRules; ++i)
98 if(pList[i])
100 m_pFormBox->RemoveEntry(i);
101 m_pFormBox->InsertEntry(*pList[i], i);
102 if(i == nSelect && nSelect < SwBaseNumRules::nMaxRules)
103 nSelect++;
106 m_pFormBox->SelectEntryPos(nSelect);
107 SelectHdl(m_pFormBox);
110 /*------------------------------------------------------------------------
111 Description: unlock OK-Button when text is in Edit
112 ------------------------------------------------------------------------*/
113 IMPL_LINK_INLINE_START( SwNumNamesDlg, ModifyHdl, Edit *, pBox )
115 m_pOKBtn->Enable(!pBox->GetText().isEmpty());
116 return 0;
118 IMPL_LINK_INLINE_END( SwNumNamesDlg, ModifyHdl, Edit *, pBox )
120 /*------------------------------------------------------------------------
121 Description: DoubleClickHdl
122 ------------------------------------------------------------------------*/
123 IMPL_LINK_NOARG_INLINE_START(SwNumNamesDlg, DoubleClickHdl)
125 EndDialog(RET_OK);
126 return 0;
128 IMPL_LINK_NOARG_INLINE_END(SwNumNamesDlg, DoubleClickHdl)
130 SwNumNamesDlg::SwNumNamesDlg(Window *pParent)
131 : ModalDialog(pParent, "NumberingNameDialog",
132 "modules/swriter/ui/numberingnamedialog.ui")
134 get(m_pFormEdit, "entry");
135 get(m_pFormBox, "form");
136 m_pFormBox->SetDropDownLineCount(5);
137 get(m_pOKBtn, "ok");
138 m_pFormEdit->SetModifyHdl(LINK(this, SwNumNamesDlg, ModifyHdl));
139 m_pFormBox->SetSelectHdl(LINK(this, SwNumNamesDlg, SelectHdl));
140 m_pFormBox->SetDoubleClickHdl(LINK(this, SwNumNamesDlg, DoubleClickHdl));
141 SelectHdl(m_pFormBox);
144 static sal_uInt16 lcl_BitToLevel(sal_uInt16 nActLevel)
146 sal_uInt16 nTmp = nActLevel;
147 sal_uInt16 nTmpLevel = 0;
148 while( 0 != (nTmp >>= 1) )
149 nTmpLevel++;
150 return nTmpLevel;
153 sal_uInt16 SwOutlineTabDialog::nNumLevel = 1;
154 SwOutlineTabDialog::SwOutlineTabDialog(Window* pParent, const SfxItemSet* pSwItemSet,
155 SwWrtShell &rSh)
156 : SfxTabDialog(pParent, "OutlineNumberingDialog",
157 "modules/swriter/ui/outlinenumbering.ui", pSwItemSet)
158 , rWrtSh(rSh)
159 , pChapterNumRules(SW_MOD()->GetChapterNumRules())
160 , bModified(rWrtSh.IsModified())
162 PushButton* pUserButton = GetUserButton();
163 pUserButton->SetClickHdl(LINK(this, SwOutlineTabDialog, FormHdl));
164 pUserButton->SetAccessibleRole( com::sun::star::accessibility::AccessibleRole::BUTTON_MENU );
166 pNumRule = new SwNumRule( *rSh.GetOutlineNumRule() );
167 GetCancelButton().SetClickHdl(LINK(this, SwOutlineTabDialog, CancelHdl));
169 m_nNumPosId = AddTabPage("position", &SwNumPositionTabPage::Create, 0);
170 m_nOutlineId = AddTabPage("numbering", &SwOutlineSettingsTabPage::Create, 0);
172 String sHeadline;
173 sal_uInt16 i;
175 for( i = 0; i < MAXLEVEL; ++i )
177 // if the style wasn't created yet, it's still at this position
178 if( !rWrtSh.GetParaStyle( sHeadline =
179 SwStyleNameMapper::GetUIName( static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i),
180 sHeadline )) )
181 aCollNames[i] = sHeadline;
184 // query the text templates' outlining levels
185 const sal_uInt16 nCount = rWrtSh.GetTxtFmtCollCount();
186 for(i = 0; i < nCount; ++i )
188 SwTxtFmtColl &rTxtColl = rWrtSh.GetTxtFmtColl(i);
189 if(!rTxtColl.IsDefault())
191 //->added by zhaojianwei
192 if(rTxtColl.IsAssignedToListLevelOfOutlineStyle())
194 int nOutLevel = rTxtColl.GetAssignedOutlineStyleLevel();
195 aCollNames[ nOutLevel ] = rTxtColl.GetName();
197 //<-end
202 SwOutlineTabDialog::~SwOutlineTabDialog()
204 delete pNumRule;
207 void SwOutlineTabDialog::PageCreated(sal_uInt16 nPageId, SfxTabPage& rPage)
209 if (nPageId == m_nNumPosId)
211 ((SwNumPositionTabPage&)rPage).SetWrtShell(&rWrtSh);
212 ((SwNumPositionTabPage&)rPage).SetOutlineTabDialog(this);
214 else if (nPageId == m_nOutlineId)
216 ((SwOutlineSettingsTabPage&)rPage).SetWrtShell(&rWrtSh);
220 IMPL_LINK_NOARG(SwOutlineTabDialog, CancelHdl)
222 if (!bModified)
223 rWrtSh.ResetModified();
224 EndDialog(RET_CANCEL);
225 return 0;
228 IMPL_LINK( SwOutlineTabDialog, FormHdl, Button *, pBtn )
230 PopupMenu *pFormMenu = get_menu("form");
231 // fill PopupMenu
232 for( sal_uInt16 i = 0; i < SwChapterNumRules::nMaxRules; ++i )
234 const SwNumRulesWithName *pRules = pChapterNumRules->GetRules(i);
235 if( pRules )
236 pFormMenu->SetItemText(pFormMenu->GetItemId(i), pRules->GetName());
239 OString sHelpId(pFormMenu->GetHelpId(pFormMenu->GetItemId("form1")));
240 for (sal_Int32 i = 2; i <= 9; ++i)
242 OString sForm("form");
243 pFormMenu->SetHelpId(pFormMenu->GetItemId(sForm + OString::valueOf(i)), sHelpId);
246 pFormMenu->SetSelectHdl(LINK(this, SwOutlineTabDialog, MenuSelectHdl));
247 pFormMenu->Execute(pBtn, Rectangle(Point(0,0), pBtn->GetSizePixel()), POPUPMENU_EXECUTE_DOWN);
248 return 0;
251 IMPL_LINK( SwOutlineTabDialog, MenuSelectHdl, Menu *, pMenu )
253 sal_uInt8 nLevelNo = 0;
254 OString sIdent = pMenu->GetCurItemIdent();
256 if (sIdent == "form1")
257 nLevelNo = 1;
258 else if (sIdent == "form2")
259 nLevelNo = 2;
260 else if (sIdent == "form3")
261 nLevelNo = 3;
262 else if (sIdent == "form4")
263 nLevelNo = 4;
264 else if (sIdent == "form5")
265 nLevelNo = 5;
266 else if (sIdent == "form6")
267 nLevelNo = 6;
268 else if (sIdent == "form7")
269 nLevelNo = 7;
270 else if (sIdent == "form8")
271 nLevelNo = 8;
272 else if (sIdent == "form9")
273 nLevelNo = 9;
274 else if (sIdent == "saveas")
276 SwNumNamesDlg *pDlg = new SwNumNamesDlg(this);
277 const String *aStrArr[SwChapterNumRules::nMaxRules];
278 for(sal_uInt16 i = 0; i < SwChapterNumRules::nMaxRules; ++i)
280 const SwNumRulesWithName *pRules = pChapterNumRules->GetRules(i);
281 if(pRules)
282 aStrArr[i] = &pRules->GetName();
283 else
284 aStrArr[i] = 0;
286 pDlg->SetUserNames(aStrArr);
287 if(RET_OK == pDlg->Execute())
289 const String aName(pDlg->GetName());
290 pChapterNumRules->ApplyNumRules( SwNumRulesWithName(
291 *pNumRule, aName ), pDlg->GetCurEntryPos() );
292 pMenu->SetItemText(pMenu->GetItemId(pDlg->GetCurEntryPos()), aName);
294 delete pDlg;
295 return 0;
299 if( nLevelNo-- )
301 const SwNumRulesWithName *pRules = pChapterNumRules->GetRules( nLevelNo );
302 if( pRules )
304 pRules->MakeNumRule( rWrtSh, *pNumRule );
305 pNumRule->SetRuleType( OUTLINE_RULE );
307 else
308 *pNumRule = *rWrtSh.GetOutlineNumRule();
311 sal_uInt16 nPageId = GetCurPageId();
312 SfxTabPage* pPage = GetTabPage( nPageId );
313 pPage->Reset(*GetOutputItemSet());
315 return 0;
318 sal_uInt16 SwOutlineTabDialog::GetLevel(const String &rFmtName) const
320 for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
322 if(aCollNames[i] == rFmtName)
323 return i;
325 return MAXLEVEL;//NO_NUMBERING; //#outline level,zhaojianwei
329 short SwOutlineTabDialog::Ok()
331 SfxTabDialog::Ok();
332 // set levels for all created templates; has to be done in order to
333 // delete possibly cancelled assignments again.
335 // #130443#
336 // encapsulate changes into a action to avoid effects on the current cursor
337 // position during the changes.
338 rWrtSh.StartAction();
340 const SwNumRule * pOutlineRule = rWrtSh.GetOutlineNumRule();
342 sal_uInt16 i, nCount = rWrtSh.GetTxtFmtCollCount();
343 for( i = 0; i < nCount; ++i )
345 SwTxtFmtColl &rTxtColl = rWrtSh.GetTxtFmtColl(i);
346 if( !rTxtColl.IsDefault() )
349 const SfxPoolItem & rItem =
350 rTxtColl.GetFmtAttr(RES_PARATR_NUMRULE, sal_False);
352 if ((sal_uInt8)GetLevel(rTxtColl.GetName()) == MAXLEVEL) //add by zhaojianwei
354 if(rTxtColl.IsAssignedToListLevelOfOutlineStyle())
356 rTxtColl.DeleteAssignmentToListLevelOfOutlineStyle();
358 if (static_cast<const SwNumRuleItem &>(rItem).GetValue() ==
359 pOutlineRule->GetName())
361 rTxtColl.ResetFmtAttr(RES_PARATR_NUMRULE);
364 else
366 rTxtColl.AssignToListLevelOfOutlineStyle(GetLevel(rTxtColl.GetName()));
368 if (static_cast<const SwNumRuleItem &>(rItem).GetValue() !=
369 pOutlineRule->GetName())
371 SwNumRuleItem aItem(pOutlineRule->GetName());
372 rTxtColl.SetFmtAttr(aItem);
374 } //<-end,zhaojianwei
378 for(i = 0; i < MAXLEVEL; ++i )
380 String sHeadline;
381 ::SwStyleNameMapper::FillUIName( static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i),
382 sHeadline );
383 SwTxtFmtColl* pColl = rWrtSh.FindTxtFmtCollByName( sHeadline );
384 if( !pColl )
386 if(aCollNames[i] != sHeadline)
388 SwTxtFmtColl* pTxtColl = rWrtSh.GetTxtCollFromPool(
389 static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i) );
390 pTxtColl->DeleteAssignmentToListLevelOfOutlineStyle();
391 pTxtColl->ResetFmtAttr(RES_PARATR_NUMRULE);
393 if( aCollNames[i].Len() )
395 pTxtColl = rWrtSh.GetParaStyle(
396 aCollNames[i], SwWrtShell::GETSTYLE_CREATESOME);
397 if(pTxtColl)
399 pTxtColl->AssignToListLevelOfOutlineStyle(i);
400 SwNumRuleItem aItem(pOutlineRule->GetName());
401 pTxtColl->SetFmtAttr(aItem);
408 rWrtSh.SetOutlineNumRule( *pNumRule);
410 // #i30443#
411 rWrtSh.EndAction();
413 return RET_OK;
416 SwOutlineSettingsTabPage::SwOutlineSettingsTabPage(Window* pParent,
417 const SfxItemSet& rSet)
418 : SfxTabPage(pParent, "OutlineNumberingPage",
419 "modules/swriter/ui/outlinenumberingpage.ui", rSet)
420 , aNoFmtName(SW_RESSTR(SW_STR_NONE))
421 , pSh(0)
422 , pCollNames(0)
423 , nActLevel(1)
425 get(m_pLevelLB, "level");
426 get(m_pCollBox, "style");
427 m_pCollBox->SetStyle(m_pCollBox->GetStyle()|WB_SORT);
428 get(m_pNumberBox, "numbering");
429 get(m_pCharFmtLB, "charstyle");
430 get(m_pAllLevelFT, "sublevelsft");
431 get(m_pAllLevelNF, "sublevelsnf");
432 get(m_pPrefixED, "prefix");
433 get(m_pSuffixED, "suffix");
434 get(m_pStartEdit, "startat");
435 get(m_pPreviewWIN, "preview");
437 SetExchangeSupport();
439 m_pCollBox->InsertEntry(aNoFmtName);
440 m_pLevelLB->SetSelectHdl(LINK(this, SwOutlineSettingsTabPage, LevelHdl));
441 m_pAllLevelNF->SetModifyHdl(LINK(this, SwOutlineSettingsTabPage, ToggleComplete));
442 m_pCollBox->SetSelectHdl(LINK(this, SwOutlineSettingsTabPage, CollSelect));
443 m_pCollBox->SetGetFocusHdl(LINK(this, SwOutlineSettingsTabPage, CollSelectGetFocus));
444 m_pNumberBox->SetSelectHdl(LINK(this, SwOutlineSettingsTabPage, NumberSelect));
445 m_pPrefixED->SetModifyHdl(LINK(this, SwOutlineSettingsTabPage, DelimModify));
446 m_pSuffixED->SetModifyHdl(LINK(this, SwOutlineSettingsTabPage, DelimModify));
447 m_pStartEdit->SetModifyHdl(LINK(this, SwOutlineSettingsTabPage, StartModified));
448 m_pCharFmtLB->SetSelectHdl(LINK(this, SwOutlineSettingsTabPage, CharFmtHdl));
451 void SwOutlineSettingsTabPage::Update()
453 // if a template was already selected for this level, select it in the ListBox
454 m_pCollBox->Enable(USHRT_MAX != nActLevel);
455 if(USHRT_MAX == nActLevel)
457 sal_Bool bSamePrefix = sal_True;
458 sal_Bool bSameSuffix = sal_True;
459 sal_Bool bSameType = sal_True;
460 sal_Bool bSameComplete = sal_True;
461 sal_Bool bSameStart = sal_True;
462 sal_Bool bSameCharFmt = sal_True;
464 const SwNumFmt* aNumFmtArr[MAXLEVEL];
465 const SwCharFmt* pFirstFmt = 0;
467 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
470 aNumFmtArr[ i ] = &pNumRule->Get(i);
471 if(i == 0)
472 pFirstFmt = aNumFmtArr[i]->GetCharFmt();
473 else
475 bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[0]->GetNumberingType();
476 bSameStart &= aNumFmtArr[i]->GetStart() == aNumFmtArr[0]->GetStart();
477 bSamePrefix &= aNumFmtArr[i]->GetPrefix() == aNumFmtArr[0]->GetPrefix();
478 bSameSuffix &= aNumFmtArr[i]->GetSuffix() == aNumFmtArr[0]->GetSuffix();
479 bSameComplete &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[0]->GetIncludeUpperLevels();
480 const SwCharFmt* pFmt = aNumFmtArr[i]->GetCharFmt();
481 bSameCharFmt &= (!pFirstFmt && !pFmt)
482 || (pFirstFmt && pFmt && pFmt->GetName() == pFirstFmt->GetName());
485 CheckForStartValue_Impl(aNumFmtArr[0]->GetNumberingType());
486 if(bSameType)
487 m_pNumberBox->SelectNumberingType( aNumFmtArr[0]->GetNumberingType() );
488 else
489 m_pNumberBox->SetNoSelection();
490 if(bSameStart)
491 m_pStartEdit->SetValue(aNumFmtArr[0]->GetStart());
492 else
493 m_pStartEdit->SetText(aEmptyStr);
494 if(bSamePrefix)
495 m_pPrefixED->SetText(aNumFmtArr[0]->GetPrefix());
496 else
497 m_pPrefixED->SetText(aEmptyStr);
498 if(bSameSuffix)
499 m_pSuffixED->SetText(aNumFmtArr[0]->GetSuffix());
500 else
501 m_pSuffixED->SetText(aEmptyStr);
503 if(bSameCharFmt)
505 if(pFirstFmt)
506 m_pCharFmtLB->SelectEntry(pFirstFmt->GetName());
507 else
508 m_pCharFmtLB->SelectEntry( ViewShell::GetShellRes()->aStrNone );
510 else
511 m_pCharFmtLB->SetNoSelection();
513 m_pAllLevelFT->Enable(sal_True);
514 m_pAllLevelNF->Enable(sal_True);
515 m_pAllLevelNF->SetMax(MAXLEVEL);
516 if(bSameComplete)
518 m_pAllLevelNF->SetValue(aNumFmtArr[0]->GetIncludeUpperLevels());
520 else
522 m_pAllLevelNF->SetText(aEmptyStr);
525 else
527 sal_uInt16 nTmpLevel = lcl_BitToLevel(nActLevel);
528 String aColl(pCollNames[nTmpLevel]);
529 if(aColl.Len())
530 m_pCollBox->SelectEntry(aColl);
531 else
532 m_pCollBox->SelectEntry(aNoFmtName);
533 const SwNumFmt &rFmt = pNumRule->Get(nTmpLevel);
535 m_pNumberBox->SelectNumberingType( rFmt.GetNumberingType() );
536 m_pPrefixED->SetText(rFmt.GetPrefix());
537 m_pSuffixED->SetText(rFmt.GetSuffix());
538 const SwCharFmt* pFmt = rFmt.GetCharFmt();
539 if(pFmt)
540 m_pCharFmtLB->SelectEntry(pFmt->GetName());
541 else
542 m_pCharFmtLB->SelectEntry( ViewShell::GetShellRes()->aStrNone );
544 if(nTmpLevel)
546 m_pAllLevelFT->Enable(sal_True);
547 m_pAllLevelNF->Enable(sal_True);
548 m_pAllLevelNF->SetMax(nTmpLevel + 1);
549 m_pAllLevelNF->SetValue(rFmt.GetIncludeUpperLevels());
551 else
553 m_pAllLevelNF->SetText(aEmptyStr);
554 m_pAllLevelNF->Enable(sal_False);
555 m_pAllLevelFT->Enable(sal_False);
557 CheckForStartValue_Impl(rFmt.GetNumberingType());
558 m_pStartEdit->SetValue( rFmt.GetStart() );
560 SetModified();
563 IMPL_LINK( SwOutlineSettingsTabPage, LevelHdl, ListBox *, pBox )
565 nActLevel = 0;
566 if(pBox->IsEntryPosSelected( MAXLEVEL ))
568 nActLevel = 0xFFFF;
570 else
572 sal_uInt16 nMask = 1;
573 for( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
575 if(pBox->IsEntryPosSelected( i ))
576 nActLevel |= nMask;
577 nMask <<= 1;
580 Update();
581 return 0;
584 IMPL_LINK( SwOutlineSettingsTabPage, ToggleComplete, NumericField *, pFld )
586 sal_uInt16 nMask = 1;
587 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
589 if(nActLevel & nMask)
591 SwNumFmt aNumFmt(pNumRule->Get(i));
592 aNumFmt.SetIncludeUpperLevels( std::min( (sal_uInt8)pFld->GetValue(),
593 (sal_uInt8)(i + 1)) );
594 pNumRule->Set(i, aNumFmt);
596 nMask <<= 1;
598 SetModified();
599 return 0;
602 IMPL_LINK( SwOutlineSettingsTabPage, CollSelect, ListBox *, pBox )
604 sal_uInt8 i;
606 const String aCollName(pBox->GetSelectEntry());
607 //0xFFFF not allowed here (disable)
608 sal_uInt16 nTmpLevel = lcl_BitToLevel(nActLevel);
609 String sOldName( pCollNames[nTmpLevel] );
611 for( i = 0; i < MAXLEVEL; ++i)
612 pCollNames[i] = aSaveCollNames[i];
614 if(aCollName == aNoFmtName)
615 pCollNames[nTmpLevel] = aEmptyStr;
616 else
618 pCollNames[nTmpLevel] = aCollName;
619 // template already in use?
620 for( i = 0; i < MAXLEVEL; ++i)
621 if(i != nTmpLevel && pCollNames[i] == aCollName )
622 pCollNames[i] = aEmptyStr;
625 // search the oldname and put it into the current entries
626 if( sOldName.Len() )
627 for( i = 0; i < MAXLEVEL; ++i)
628 if( aSaveCollNames[ i ] == sOldName && i != nTmpLevel &&
629 !pCollNames[ i ].Len() )
631 sal_uInt8 n;
632 for( n = 0; n < MAXLEVEL; ++n )
633 if( pCollNames[ n ] == sOldName )
634 break;
636 if( MAXLEVEL == n )
637 // it was a outline leveld name and the current entries is zero.
638 pCollNames[ i ] = sOldName;
641 SetModified();
642 return 0;
645 IMPL_LINK_NOARG(SwOutlineSettingsTabPage, CollSelectGetFocus)
647 for( sal_uInt8 i = 0; i < MAXLEVEL; ++i)
648 aSaveCollNames[i] = pCollNames[i];
649 return 0;
652 IMPL_LINK( SwOutlineSettingsTabPage, NumberSelect, SwNumberingTypeListBox *, pBox )
654 sal_uInt16 nMask = 1;
655 sal_Int16 nNumberType = pBox->GetSelectedNumberingType();
656 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
658 if(nActLevel & nMask)
660 SwNumFmt aNumFmt(pNumRule->Get(i));
661 aNumFmt.SetNumberingType(nNumberType);
662 pNumRule->Set(i, aNumFmt);
663 CheckForStartValue_Impl(nNumberType);
665 nMask <<= 1;
667 SetModified();
668 return 0;
671 IMPL_LINK_NOARG(SwOutlineSettingsTabPage, DelimModify)
673 sal_uInt16 nMask = 1;
674 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
676 if(nActLevel & nMask)
678 SwNumFmt aNumFmt(pNumRule->Get(i));
679 aNumFmt.SetPrefix( m_pPrefixED->GetText() );
680 aNumFmt.SetSuffix( m_pSuffixED->GetText() );
681 pNumRule->Set(i, aNumFmt);
683 nMask <<= 1;
685 SetModified();
686 return 0;
689 IMPL_LINK( SwOutlineSettingsTabPage, StartModified, NumericField *, pFld )
691 sal_uInt16 nMask = 1;
692 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
694 if(nActLevel & nMask)
696 SwNumFmt aNumFmt(pNumRule->Get(i));
697 aNumFmt.SetStart( (sal_uInt16)pFld->GetValue() );
698 pNumRule->Set(i, aNumFmt);
700 nMask <<= 1;
702 SetModified();
703 return 0;
706 IMPL_LINK_NOARG(SwOutlineSettingsTabPage, CharFmtHdl)
708 String sEntry = m_pCharFmtLB->GetSelectEntry();
709 sal_uInt16 nMask = 1;
710 bool bFormatNone = sEntry == ViewShell::GetShellRes()->aStrNone;
711 SwCharFmt* pFmt = 0;
712 if(!bFormatNone)
714 sal_uInt16 nChCount = pSh->GetCharFmtCount();
715 for(sal_uInt16 i = 0; i < nChCount; i++)
717 SwCharFmt& rChFmt = pSh->GetCharFmt(i);
718 if(rChFmt.GetName() == sEntry)
720 pFmt = &rChFmt;
721 break;
724 if(!pFmt)
726 SfxStyleSheetBasePool* pPool = pSh->GetView().GetDocShell()->GetStyleSheetPool();
727 SfxStyleSheetBase* pBase;
728 pBase = pPool->Find(sEntry, SFX_STYLE_FAMILY_CHAR);
729 if(!pBase)
730 pBase = &pPool->Make(sEntry, SFX_STYLE_FAMILY_PAGE);
731 pFmt = ((SwDocStyleSheet*)pBase)->GetCharFmt();
736 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
738 if(nActLevel & nMask)
740 SwNumFmt aNumFmt(pNumRule->Get(i));
741 if(bFormatNone)
742 aNumFmt.SetCharFmt(0);
743 else
744 aNumFmt.SetCharFmt(pFmt);
745 pNumRule->Set(i, aNumFmt);
747 nMask <<= 1;
749 return RET_OK;
752 SwOutlineSettingsTabPage::~SwOutlineSettingsTabPage()
756 void SwOutlineSettingsTabPage::SetWrtShell(SwWrtShell* pShell)
758 pSh = pShell;
759 // query this document's NumRules
760 pNumRule = ((SwOutlineTabDialog*)GetTabDialog())->GetNumRule();
761 pCollNames = ((SwOutlineTabDialog*)GetTabDialog())->GetCollNames();
763 m_pPreviewWIN->SetNumRule(pNumRule);
764 m_pPreviewWIN->SetOutlineNames(pCollNames);
765 // set start value - nActLevel must be 1 here
766 sal_uInt16 nTmpLevel = lcl_BitToLevel(nActLevel);
767 const SwNumFmt& rNumFmt = pNumRule->Get( nTmpLevel );
768 m_pStartEdit->SetValue( rNumFmt.GetStart() );
770 // create pool formats for headlines
771 String sStr;
772 sal_uInt16 i;
773 for( i = 0; i < MAXLEVEL; ++i )
775 m_pCollBox->InsertEntry( SwStyleNameMapper::GetUIName(
776 static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i), aEmptyStr ));
777 m_pLevelLB->InsertEntry( OUString::number(i + 1) );
779 sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "1 - " ));
780 sStr += OUString::number(MAXLEVEL);
781 m_pLevelLB->InsertEntry( sStr );
783 // query the texttemplates' outlining levels
784 const sal_uInt16 nCount = pSh->GetTxtFmtCollCount();
785 for( i = 0; i < nCount; ++i )
787 SwTxtFmtColl &rTxtColl = pSh->GetTxtFmtColl(i);
788 if(!rTxtColl.IsDefault())
790 sStr = rTxtColl.GetName();
791 if(LISTBOX_ENTRY_NOTFOUND == m_pCollBox->GetEntryPos( sStr ))
792 m_pCollBox->InsertEntry( sStr );
796 m_pNumberBox->SelectNumberingType(rNumFmt.GetNumberingType());
797 sal_uInt16 nOutlinePos = pSh->GetOutlinePos(MAXLEVEL);
798 sal_uInt16 nTmp = 0;
799 if(nOutlinePos != USHRT_MAX)
801 nTmp = static_cast<sal_uInt16>(pSh->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos));
803 m_pLevelLB->SelectEntryPos(nTmp-1);//nTmp);//#outline level,zhaojianwei
805 // collect char styles
806 m_pCharFmtLB->Clear();
807 m_pCharFmtLB->InsertEntry( ViewShell::GetShellRes()->aStrNone );
809 // char styles
810 ::FillCharStyleListBox(*m_pCharFmtLB,
811 pSh->GetView().GetDocShell());
812 Update();
815 void SwOutlineSettingsTabPage::ActivatePage(const SfxItemSet& )
817 nActLevel = SwOutlineTabDialog::GetActNumLevel();
818 if(nActLevel != USHRT_MAX)
819 m_pLevelLB->SelectEntryPos(lcl_BitToLevel(nActLevel));
820 else
821 m_pLevelLB->SelectEntryPos(MAXLEVEL);
822 LevelHdl(m_pLevelLB);
825 int SwOutlineSettingsTabPage::DeactivatePage(SfxItemSet*)
827 SwOutlineTabDialog::SetActNumLevel(nActLevel);
828 return LEAVE_PAGE;
831 sal_Bool SwOutlineSettingsTabPage::FillItemSet( SfxItemSet& )
833 return sal_True;
836 void SwOutlineSettingsTabPage::Reset( const SfxItemSet& rSet )
838 ActivatePage(rSet);
841 SfxTabPage* SwOutlineSettingsTabPage::Create( Window* pParent,
842 const SfxItemSet& rAttrSet)
844 return new SwOutlineSettingsTabPage(pParent, rAttrSet);
847 void SwOutlineSettingsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
849 bool bIsNull = m_pStartEdit->GetValue() == 0;
850 bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
851 SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
852 SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
853 m_pStartEdit->SetMin(bNoZeroAllowed ? 1 : 0);
854 if(bIsNull && bNoZeroAllowed)
855 m_pStartEdit->GetModifyHdl().Call(m_pStartEdit);
858 static sal_uInt16 lcl_DrawBullet(VirtualDevice* pVDev,
859 const SwNumFmt& rFmt, sal_uInt16 nXStart,
860 sal_uInt16 nYStart, const Size& rSize)
862 Font aTmpFont(pVDev->GetFont());
864 Font aFont(*rFmt.GetBulletFont());
865 aFont.SetSize(rSize);
866 aFont.SetTransparent(sal_True);
867 pVDev->SetFont( aFont );
868 OUString aText(rFmt.GetBulletChar());
869 pVDev->DrawText( Point(nXStart, nYStart), aText );
870 sal_uInt16 nRet = (sal_uInt16)pVDev->GetTextWidth(aText);
872 pVDev->SetFont(aTmpFont);
873 return nRet;
876 static sal_uInt16 lcl_DrawGraphic(VirtualDevice* pVDev, const SwNumFmt &rFmt, sal_uInt16 nXStart,
877 sal_uInt16 nYStart, sal_uInt16 nDivision)
879 const SvxBrushItem* pBrushItem = rFmt.GetBrush();
880 sal_uInt16 nRet = 0;
881 if(pBrushItem)
883 const Graphic* pGrf = pBrushItem->GetGraphic();
884 if(pGrf)
886 Size aGSize( rFmt.GetGraphicSize());
887 aGSize.Width() /= nDivision;
888 nRet = (sal_uInt16)aGSize.Width();
889 aGSize.Height() /= nDivision;
890 pGrf->Draw( pVDev, Point(nXStart,nYStart),
891 pVDev->PixelToLogic( aGSize ) );
894 return nRet;
898 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeNumberingPreview(Window *pParent, VclBuilder::stringmap &)
900 return new NumberingPreview(pParent);
903 /*--------------------------------------------------
904 paint numbering's preview
905 --------------------------------------------------*/
906 void NumberingPreview::Paint( const Rectangle& /*rRect*/ )
908 Size aSize(PixelToLogic(GetOutputSizePixel()));
909 Rectangle aRect(Point(0,0), aSize);
911 VirtualDevice* pVDev = new VirtualDevice(*this);
912 pVDev->SetMapMode(GetMapMode());
913 pVDev->SetOutputSize( aSize );
915 // #101524# OJ
916 pVDev->SetFillColor( GetSettings().GetStyleSettings().GetWindowColor() );
917 pVDev->SetLineColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
918 pVDev->DrawRect(aRect);
920 if(pActNum)
922 sal_uInt16 nWidthRelation;
923 if(nPageWidth)
925 nWidthRelation = sal_uInt16 (nPageWidth / aSize.Width());
926 if(bPosition)
927 nWidthRelation = nWidthRelation * 2 / 3;
928 else
929 nWidthRelation = nWidthRelation / 4;
931 else
932 nWidthRelation = 30; // chapter dialog
934 // height per level
935 sal_uInt16 nXStep = sal_uInt16(aSize.Width() / (3 * MAXLEVEL));
936 if(MAXLEVEL < 10)
937 nXStep /= 2;
938 sal_uInt16 nYStart = 4;
939 sal_uInt16 nYStep = sal_uInt16((aSize.Height() - 6)/ MAXLEVEL);
940 aStdFont = OutputDevice::GetDefaultFont(
941 DEFAULTFONT_UI_SANS, GetAppLanguage(),
942 DEFAULTFONT_FLAGS_ONLYONE, this );
943 // #101524# OJ
944 aStdFont.SetColor( SwViewOption::GetFontColor() );
946 sal_uInt16 nFontHeight = nYStep * 6 / 10;
947 if(bPosition)
948 nFontHeight = nYStep * 15 / 10;
949 aStdFont.SetSize(Size( 0, nFontHeight ));
951 sal_uInt16 nPreNum = pActNum->Get(0).GetStart();
953 if(bPosition)
955 sal_uInt16 nLineHeight = nFontHeight * 8 / 7;
956 sal_uInt8 nStart = 0;
957 while( !(nActLevel & (1<<nStart)) )
959 nStart++;
961 if(nStart) // so that possible predecessors and successors are showed
962 nStart--;
964 SwNumberTree::tNumberVector aNumVector;
965 sal_uInt8 nEnd = std::min( (sal_uInt8)(nStart + 3), MAXLEVEL );
966 for( sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel )
968 const SwNumFmt &rFmt = pActNum->Get(nLevel);
969 aNumVector.push_back(rFmt.GetStart());
971 sal_uInt16 nXStart( 0 );
972 short nTextOffset( 0 );
973 sal_uInt16 nNumberXPos( 0 );
974 if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
976 nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
977 nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
978 nNumberXPos = nXStart;
979 sal_uInt16 nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation;
981 if(nFirstLineOffset <= nNumberXPos)
982 nNumberXPos = nNumberXPos - nFirstLineOffset;
983 else
984 nNumberXPos = 0;
986 else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
988 const long nTmpNumberXPos( ( rFmt.GetIndentAt() +
989 rFmt.GetFirstLineIndent() ) /
990 nWidthRelation );
991 if ( nTmpNumberXPos < 0 )
993 nNumberXPos = 0;
995 else
997 nNumberXPos = static_cast<sal_uInt16>(nTmpNumberXPos);
1001 sal_uInt16 nBulletWidth = 0;
1002 if( SVX_NUM_BITMAP == rFmt.GetNumberingType() )
1004 nBulletWidth = lcl_DrawGraphic(pVDev, rFmt,
1005 nNumberXPos,
1006 nYStart, nWidthRelation);
1008 else if( SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType() )
1010 nBulletWidth = lcl_DrawBullet(pVDev, rFmt, nNumberXPos, nYStart, aStdFont.GetSize());
1012 else
1014 pVDev->SetFont(aStdFont);
1015 if(pActNum->IsContinusNum())
1016 aNumVector[nLevel] = nPreNum;
1017 // #128041#
1018 String aText(pActNum->MakeNumString( aNumVector ));
1019 pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
1020 nBulletWidth = (sal_uInt16)pVDev->GetTextWidth(aText);
1021 nPreNum++;
1023 if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
1024 rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
1026 pVDev->SetFont(aStdFont);
1027 OUString aText(' ');
1028 pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
1029 nBulletWidth = nBulletWidth + (sal_uInt16)pVDev->GetTextWidth(aText);
1032 sal_uInt16 nTextXPos( 0 );
1033 if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1035 nTextXPos = nXStart;
1036 if(nTextOffset < 0)
1037 nTextXPos = nTextXPos + nTextOffset;
1038 if(nNumberXPos + nBulletWidth + nTextOffset > nTextXPos )
1039 nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
1041 else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
1043 switch ( rFmt.GetLabelFollowedBy() )
1045 case SvxNumberFormat::LISTTAB:
1047 nTextXPos = static_cast<sal_uInt16>(
1048 rFmt.GetListtabPos() / nWidthRelation );
1049 if ( nTextXPos < nNumberXPos + nBulletWidth )
1051 nTextXPos = nNumberXPos + nBulletWidth;
1054 break;
1055 case SvxNumberFormat::SPACE:
1056 case SvxNumberFormat::NOTHING:
1058 nTextXPos = nNumberXPos + nBulletWidth;
1060 break;
1063 nXStart = static_cast<sal_uInt16>( rFmt.GetIndentAt() / nWidthRelation );
1067 Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
1068 pVDev->SetFillColor( GetSettings().GetStyleSettings().GetWindowColor() ); // Color( COL_BLACK ) );
1069 pVDev->DrawRect( aRect1 );
1071 Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
1072 pVDev->DrawRect( aRect2 );
1073 nYStart += 2 * nLineHeight;
1076 else
1078 SwNumberTree::tNumberVector aNumVector;
1079 sal_uInt16 nLineHeight = nFontHeight * 3 / 2;
1080 for( sal_uInt8 nLevel = 0; nLevel < MAXLEVEL;
1081 ++nLevel, nYStart = nYStart + nYStep )
1083 const SwNumFmt &rFmt = pActNum->Get(nLevel);
1084 aNumVector.push_back(rFmt.GetStart());
1085 sal_uInt16 nXStart( 0 );
1086 if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1088 nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
1090 else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
1092 const long nTmpXStart( ( rFmt.GetIndentAt() +
1093 rFmt.GetFirstLineIndent() ) /
1094 nWidthRelation );
1095 if ( nTmpXStart < 0 )
1097 nXStart = 0;
1099 else
1101 nXStart = static_cast<sal_uInt16>(nTmpXStart);
1104 nXStart /= 2;
1105 nXStart += 2;
1106 sal_uInt16 nTextOffset = 2 * nXStep;
1107 if( SVX_NUM_BITMAP == rFmt.GetNumberingType() )
1109 lcl_DrawGraphic(pVDev, rFmt, nXStart, nYStart, nWidthRelation);
1110 nTextOffset = nLineHeight + nXStep;
1112 else if( SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType() )
1114 nTextOffset = lcl_DrawBullet(pVDev, rFmt, nXStart, nYStart, aStdFont.GetSize());
1115 nTextOffset = nTextOffset + nXStep;
1117 else
1119 pVDev->SetFont(aStdFont);
1120 if(pActNum->IsContinusNum())
1121 aNumVector[nLevel] = nPreNum;
1122 // #128041#
1123 String aText(pActNum->MakeNumString( aNumVector ));
1124 pVDev->DrawText( Point(nXStart, nYStart), aText );
1125 nTextOffset = (sal_uInt16)pVDev->GetTextWidth(aText);
1126 nTextOffset = nTextOffset + nXStep;
1127 nPreNum++;
1129 pVDev->SetFont(aStdFont);
1130 pVDev->DrawText(
1131 Point(nXStart + nTextOffset, nYStart),
1132 (pOutlineNames == 0
1133 ? utl::ConfigManager::getProductName()
1134 : OUString(pOutlineNames[nLevel])));
1138 DrawOutDev( Point(0,0), aSize,
1139 Point(0,0), aSize,
1140 *pVDev );
1141 delete pVDev;
1145 NumberingPreview::~NumberingPreview()
1149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */