Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / index / cnttab.cxx
blobf68aa514d27206de414b209343be0862adb0bc0e
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 <sal/config.h>
22 #include <osl/diagnose.h>
23 #include <o3tl/safeint.hxx>
24 #include <sal/log.hxx>
25 #include <svl/style.hxx>
26 #include <utility>
27 #include <vcl/weld.hxx>
28 #include <svl/stritem.hxx>
29 #include <unotools/pathoptions.hxx>
30 #include <sfx2/viewfrm.hxx>
31 #include <sfx2/dispatch.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <sfx2/sfxdlg.hxx>
34 #include <svx/dialogs.hrc>
35 #include <svx/flagsdef.hxx>
36 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
38 #include <svtools/indexentryres.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <column.hxx>
41 #include <fmtfsize.hxx>
42 #include <authfld.hxx>
43 #include <swtypes.hxx>
44 #include <wrtsh.hxx>
45 #include <view.hxx>
46 #include <cnttab.hxx>
47 #include <swuicnttab.hxx>
48 #include <poolfmt.hxx>
49 #include <strings.hrc>
50 #include <uitool.hxx>
51 #include <fmtcol.hxx>
52 #include <fldbas.hxx>
53 #include <expfld.hxx>
54 #include <unotools.hxx>
55 #include <docsh.hxx>
56 #include <swmodule.hxx>
57 #include <modcfg.hxx>
58 #include <iodetect.hxx>
60 #include <cmdid.h>
61 #include <cnttab.hrc>
62 #include <SwStyleNameMapper.hxx>
63 #include <sfx2/filedlghelper.hxx>
64 #include <toxwrap.hxx>
65 #include <chpfld.hxx>
67 #include <cmath>
68 #include <memory>
69 #include <string_view>
70 #include <vector>
71 #include <numeric>
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::uno;
77 using namespace com::sun::star::ui::dialogs;
78 using namespace ::sfx2;
79 #include <svtools/editbrowsebox.hxx>
81 const sal_Unicode aDeliStart = '['; // for the form
82 const sal_Unicode aDeliEnd = ']'; // for the form
84 static OUString lcl_CreateAutoMarkFileDlg(weld::Window* pParent, const OUString& rURL,
85 const OUString& rFileString, bool bOpen)
87 OUString sRet;
89 FileDialogHelper aDlgHelper( bOpen ?
90 TemplateDescription::FILEOPEN_SIMPLE : TemplateDescription::FILESAVE_AUTOEXTENSION,
91 FileDialogFlags::NONE, pParent);
92 uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
94 xFP->appendFilter( rFileString, "*.sdi" );
95 xFP->setCurrentFilter( rFileString ) ;
97 if( !rURL.isEmpty() )
98 xFP->setDisplayDirectory( rURL );
99 else
101 SvtPathOptions aPathOpt;
102 xFP->setDisplayDirectory( aPathOpt.GetUserConfigPath() );
105 const ErrCode aErrCode = aDlgHelper.Execute();
106 if (aErrCode == ERRCODE_NONE)
108 sRet = xFP->getSelectedFiles().getConstArray()[0];
110 // tdf#120405 - use previously selected file, if selection is aborted
111 else if (aErrCode == ERRCODE_ABORT && !rURL.isEmpty())
113 sRet = rURL;
116 return sRet;
119 namespace {
121 struct AutoMarkEntry
123 OUString sSearch;
124 OUString sAlternative;
125 OUString sPrimKey;
126 OUString sSecKey;
127 OUString sComment;
128 bool bCase;
129 bool bWord;
131 AutoMarkEntry() :
132 bCase(false),
133 bWord(false){}
138 typedef ::svt::EditBrowseBox SwEntryBrowseBox_Base;
140 namespace {
142 class SwEntryBrowseBox : public SwEntryBrowseBox_Base
144 VclPtr<svt::EditControl> m_aCellEdit;
145 VclPtr<svt::CheckBoxControl> m_aCellCheckBox;
147 OUString m_sYes;
148 OUString m_sNo;
150 std::vector<std::unique_ptr<AutoMarkEntry>> m_Entries;
152 ::svt::CellControllerRef m_xController;
153 ::svt::CellControllerRef m_xCheckController;
155 sal_Int32 m_nCurrentRow;
156 bool m_bModified;
158 protected:
159 virtual bool SeekRow( sal_Int32 nRow ) override;
160 virtual void PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId) const override;
161 virtual void InitController(::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol) override;
162 virtual ::svt::CellController* GetController(sal_Int32 nRow, sal_uInt16 nCol) override;
163 virtual bool SaveModified() override;
165 std::vector<tools::Long> GetOptimalColWidths() const;
167 public:
168 SwEntryBrowseBox(const css::uno::Reference<css::awt::XWindow> &rParent);
169 virtual ~SwEntryBrowseBox() override;
170 virtual void dispose() override;
171 void ReadEntries(SvStream& rInStr);
172 void WriteEntries(SvStream& rOutStr);
174 bool IsModified()const override;
176 virtual OUString GetCellText( sal_Int32 nRow, sal_uInt16 nColumn ) const override;
177 virtual void Resize() override;
178 virtual Size GetOptimalSize() const override;
181 class SwAutoMarkDlg_Impl : public weld::GenericDialogController
183 OUString m_sAutoMarkURL;
184 bool m_bCreateMode;
186 std::unique_ptr<weld::Button> m_xOKPB;
187 std::unique_ptr<weld::Container> m_xTable;
188 css::uno::Reference<css::awt::XWindow> m_xTableCtrlParent;
189 VclPtr<SwEntryBrowseBox> m_xEntriesBB;
191 DECL_LINK(OkHdl, weld::Button&, void);
192 public:
193 SwAutoMarkDlg_Impl(weld::Window* pParent, OUString aAutoMarkURL,
194 bool bCreate);
195 virtual ~SwAutoMarkDlg_Impl() override;
200 sal_uInt16 CurTOXType::GetFlatIndex() const
202 return static_cast< sal_uInt16 >( (eType == TOX_USER && nIndex)
203 ? TOX_AUTHORITIES + nIndex : eType );
206 SwMultiTOXTabDialog::SwMultiTOXTabDialog(weld::Widget* pParent, const SfxItemSet& rSet,
207 SwWrtShell &rShell, SwTOXBase* pCurTOX,
208 sal_uInt16 nToxType, bool bGlobal)
209 : SfxTabDialogController(pParent, "modules/swriter/ui/tocdialog.ui", "TocDialog", &rSet)
210 , m_pMgr( new SwTOXMgr( &rShell ) )
211 , m_rWrtShell(rShell)
212 , m_pParamTOXBase(pCurTOX)
213 , m_sUserDefinedIndex(SwResId(STR_USER_DEFINED_INDEX))
214 , m_nInitialTOXType(nToxType)
215 , m_bEditTOX(false)
216 , m_bExampleCreated(false)
217 , m_bGlobalFlag(bGlobal)
218 , m_xShowExampleCB(m_xBuilder->weld_check_button("showexample"))
220 m_eCurrentTOXType.eType = TOX_CONTENT;
221 m_eCurrentTOXType.nIndex = 0;
223 const sal_uInt16 nUserTypeCount = m_rWrtShell.GetTOXTypeCount(TOX_USER);
224 m_vTypeData.resize(nUserTypeCount + 6);
225 //the standard user index is on position TOX_USER
226 //all user indexes follow after position TOX_AUTHORITIES
227 if(pCurTOX)
229 m_bEditTOX = true;
231 for(int i = m_vTypeData.size() - 1; i > -1; i--)
233 m_vTypeData[i].m_oIndexSections.emplace();
234 if(pCurTOX)
236 m_eCurrentTOXType.eType = pCurTOX->GetType();
237 sal_uInt16 nArrayIndex = static_cast< sal_uInt16 >(m_eCurrentTOXType.eType);
238 if(m_eCurrentTOXType.eType == TOX_USER)
240 //which user type is it?
241 for(sal_uInt16 nUser = 0; nUser < nUserTypeCount; nUser++)
243 const SwTOXType* pTemp = m_rWrtShell.GetTOXType(TOX_USER, nUser);
244 if(pCurTOX->GetTOXType() == pTemp)
246 m_eCurrentTOXType.nIndex = nUser;
247 nArrayIndex = static_cast< sal_uInt16 >(nUser > 0 ? TOX_AUTHORITIES + nUser : TOX_USER);
248 break;
252 m_vTypeData[nArrayIndex].m_pForm.reset(new SwForm(pCurTOX->GetTOXForm()));
253 m_vTypeData[nArrayIndex].m_pDescription = CreateTOXDescFromTOXBase(pCurTOX);
254 if(TOX_AUTHORITIES == m_eCurrentTOXType.eType)
256 const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
257 m_rWrtShell.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
258 if(pFType)
260 OUString sBrackets;
261 if(pFType->GetPrefix())
262 sBrackets += OUStringChar(pFType->GetPrefix());
263 if(pFType->GetSuffix())
264 sBrackets += OUStringChar(pFType->GetSuffix());
265 m_vTypeData[nArrayIndex].m_pDescription->SetAuthBrackets(sBrackets);
266 m_vTypeData[nArrayIndex].m_pDescription->SetAuthSequence(pFType->IsSequence());
268 else
270 m_vTypeData[nArrayIndex].m_pDescription->SetAuthBrackets("[]");
275 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
276 AddTabPage("index", SwTOXSelectTabPage::Create, nullptr);
277 AddTabPage("styles", SwTOXStylesTabPage::Create, nullptr);
278 AddTabPage("columns", SwColumnPage::Create, nullptr);
279 AddTabPage("background", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr);
280 AddTabPage("entries", SwTOXEntryTabPage::Create, nullptr);
281 if (!pCurTOX)
282 SetCurPageId("index");
284 m_xShowExampleCB->connect_toggled(LINK(this, SwMultiTOXTabDialog, ShowPreviewHdl));
285 m_xShowExampleCB->set_active(SW_MOD()->GetModuleConfig()->IsShowIndexPreview());
287 ShowPreview();
290 SwMultiTOXTabDialog::~SwMultiTOXTabDialog()
292 SW_MOD()->GetModuleConfig()->SetShowIndexPreview(m_xShowExampleCB->get_active());
295 void SwMultiTOXTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
297 if (rId == "background")
299 SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
300 aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
301 rPage.PageCreated(aSet);
303 else if (rId == "columns")
305 const SwFormatFrameSize& rSize = GetInputSetImpl()->Get(RES_FRM_SIZE);
307 static_cast<SwColumnPage&>(rPage).SetPageWidth(rSize.GetWidth());
309 else if (rId == "entries")
310 static_cast<SwTOXEntryTabPage&>(rPage).SetWrtShell(m_rWrtShell);
311 else if (rId == "index")
313 static_cast<SwTOXSelectTabPage&>(rPage).SetWrtShell(m_rWrtShell);
314 if(USHRT_MAX != m_nInitialTOXType)
315 static_cast<SwTOXSelectTabPage&>(rPage).SelectType(static_cast<TOXTypes>(m_nInitialTOXType));
319 short SwMultiTOXTabDialog::Ok()
321 short nRet = SfxTabDialogController::Ok();
322 SwTOXDescription& rDesc = GetTOXDescription(m_eCurrentTOXType);
323 SwTOXBase aNewDef(*m_rWrtShell.GetDefaultTOXBase( m_eCurrentTOXType.eType, true ));
325 const sal_uInt16 nIndex = m_eCurrentTOXType.GetFlatIndex();
326 if(m_vTypeData[nIndex].m_pForm)
328 rDesc.SetForm(*m_vTypeData[nIndex].m_pForm);
329 aNewDef.SetTOXForm(*m_vTypeData[nIndex].m_pForm);
331 rDesc.ApplyTo(aNewDef);
332 if(!m_bGlobalFlag)
333 m_pMgr->UpdateOrInsertTOX(
334 rDesc, nullptr, GetOutputItemSet());
335 else if(m_bEditTOX)
336 m_pMgr->UpdateOrInsertTOX(
337 rDesc, &m_pParamTOXBase, GetOutputItemSet());
339 if(!m_eCurrentTOXType.nIndex)
340 m_rWrtShell.SetDefaultTOXBase(aNewDef);
342 return nRet;
345 SwForm* SwMultiTOXTabDialog::GetForm(CurTOXType eType)
347 const sal_uInt16 nIndex = eType.GetFlatIndex();
348 if(!m_vTypeData[nIndex].m_pForm)
349 m_vTypeData[nIndex].m_pForm.reset(new SwForm(eType.eType));
350 return m_vTypeData[nIndex].m_pForm.get();
353 SwTOXDescription& SwMultiTOXTabDialog::GetTOXDescription(CurTOXType eType)
355 const sal_uInt16 nIndex = eType.GetFlatIndex();
356 if(!m_vTypeData[nIndex].m_pDescription)
358 const SwTOXBase* pDef = m_rWrtShell.GetDefaultTOXBase( eType.eType );
359 if(pDef)
360 m_vTypeData[nIndex].m_pDescription = CreateTOXDescFromTOXBase(pDef);
361 else
363 m_vTypeData[nIndex].m_pDescription.reset(new SwTOXDescription(eType.eType));
364 if(eType.eType == TOX_USER)
365 m_vTypeData[nIndex].m_pDescription->SetTitle(m_sUserDefinedIndex);
366 else
367 m_vTypeData[nIndex].m_pDescription->SetTitle(
368 m_rWrtShell.GetTOXType(eType.eType, 0)->GetTypeName());
370 if(TOX_AUTHORITIES == eType.eType)
372 const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
373 m_rWrtShell.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
374 if(pFType)
376 m_vTypeData[nIndex].m_pDescription->SetAuthBrackets(OUStringChar(pFType->GetPrefix()) +
377 OUStringChar(pFType->GetSuffix()));
378 m_vTypeData[nIndex].m_pDescription->SetAuthSequence(pFType->IsSequence());
380 else
382 m_vTypeData[nIndex].m_pDescription->SetAuthBrackets("[]");
385 else if(TOX_INDEX == eType.eType)
386 m_vTypeData[nIndex].m_pDescription->SetMainEntryCharStyle(SwResId(STR_POOLCHR_IDX_MAIN_ENTRY));
389 return *m_vTypeData[nIndex].m_pDescription;
392 std::unique_ptr<SwTOXDescription> SwMultiTOXTabDialog::CreateTOXDescFromTOXBase(
393 const SwTOXBase*pCurTOX)
395 std::unique_ptr<SwTOXDescription> pDesc(new SwTOXDescription(pCurTOX->GetType()));
396 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
397 pDesc->SetStyleNames(pCurTOX->GetStyleNames(i), i);
398 pDesc->SetAutoMarkURL(m_rWrtShell.GetTOIAutoMarkURL());
399 pDesc->SetTitle(pCurTOX->GetTitle());
401 pDesc->SetContentOptions(pCurTOX->GetCreateType());
402 if(pDesc->GetTOXType() == TOX_INDEX)
403 pDesc->SetIndexOptions(pCurTOX->GetOptions());
404 pDesc->SetMainEntryCharStyle(pCurTOX->GetMainEntryCharStyle());
405 if(pDesc->GetTOXType() != TOX_INDEX)
406 pDesc->SetLevel(static_cast<sal_uInt8>(pCurTOX->GetLevel()));
407 pDesc->SetCreateFromObjectNames(pCurTOX->IsFromObjectNames());
408 pDesc->SetSequenceName(pCurTOX->GetSequenceName());
409 pDesc->SetCaptionDisplay(pCurTOX->GetCaptionDisplay());
410 pDesc->SetFromChapter(pCurTOX->IsFromChapter());
411 pDesc->SetReadonly(pCurTOX->IsProtected());
412 pDesc->SetOLEOptions(pCurTOX->GetOLEOptions());
413 pDesc->SetLevelFromChapter(pCurTOX->IsLevelFromChapter());
414 pDesc->SetLanguage(pCurTOX->GetLanguage());
415 pDesc->SetSortAlgorithm(pCurTOX->GetSortAlgorithm());
416 return pDesc;
419 void SwMultiTOXTabDialog::ShowPreview()
421 if (m_xShowExampleCB->get_active())
423 if(!m_xExampleFrame && !m_bExampleCreated)
425 m_bExampleCreated = true;
426 OUString sTemplate("internal/idxexample.odt");
428 SvtPathOptions aOpt;
429 bool bExist = aOpt.SearchFile( sTemplate, SvtPathOptions::Paths::Template );
431 if(!bExist)
433 OUString sInfo(SwResId(STR_FILE_NOT_FOUND));
434 sInfo = sInfo.replaceFirst( "%1", sTemplate );
435 sInfo = sInfo.replaceFirst( "%2", aOpt.GetTemplatePath() );
436 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
437 VclMessageType::Info, VclButtonsType::Ok,
438 sInfo));
439 xInfoBox->run();
441 else
443 Link<SwOneExampleFrame&,void> aLink(LINK(this, SwMultiTOXTabDialog, CreateExample_Hdl));
444 m_xExampleFrame.reset(new SwOneExampleFrame(EX_SHOW_ONLINE_LAYOUT | EX_LOCALIZE_TOC_STRINGS, &aLink, &sTemplate));
445 m_xExampleFrameWin.reset(new weld::CustomWeld(*m_xBuilder, "example", *m_xExampleFrame));
447 m_xShowExampleCB->set_visible(m_xExampleFrame != nullptr);
451 if (m_xExampleFrame)
453 const bool bSetViewWindow = m_xShowExampleCB->get_active();
454 if (bSetViewWindow)
455 m_xExampleFrame->Show();
456 else
457 m_xExampleFrame->Hide();
461 IMPL_LINK_NOARG(SwMultiTOXTabDialog, ShowPreviewHdl, weld::Toggleable&, void)
463 ShowPreview();
464 m_xDialog->resize_to_request();
467 bool SwMultiTOXTabDialog::IsNoNum(SwWrtShell& rSh, const OUString& rName)
469 SwTextFormatColl* pColl = rSh.GetParaStyle(rName);
470 if(pColl && ! pColl->IsAssignedToListLevelOfOutlineStyle())
471 return true;
473 const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
474 rName, SwGetPoolIdFromName::TxtColl);
475 return nId != USHRT_MAX &&
476 ! rSh.GetTextCollFromPool(nId)->IsAssignedToListLevelOfOutlineStyle();
479 namespace {
481 class SwAddStylesDlg_Impl : public SfxDialogController
483 OUString* m_pStyleArr;
485 std::unique_ptr<weld::Button> m_xOk;
486 std::unique_ptr<weld::Button> m_xLeftPB;
487 std::unique_ptr<weld::Button> m_xRightPB;
488 std::unique_ptr<weld::TreeView> m_xHeaderTree;
490 void ToggleOn(int nEntry, int nToggleColumn);
492 DECL_LINK(OkHdl, weld::Button&, void);
493 DECL_LINK(LeftRightHdl, weld::Button&, void);
494 DECL_LINK(KeyInput, const KeyEvent&, bool);
495 DECL_LINK(TreeSizeAllocHdl, const Size&, void);
496 DECL_LINK(RadioToggleOnHdl, const weld::TreeView::iter_col&, void);
497 DECL_LINK(HeaderBarClick, int, void);
499 public:
500 SwAddStylesDlg_Impl(weld::Window* pParent, SwWrtShell const & rWrtSh, OUString rStringArr[]);
505 SwAddStylesDlg_Impl::SwAddStylesDlg_Impl(weld::Window* pParent,
506 SwWrtShell const & rWrtSh, OUString rStringArr[])
507 : SfxDialogController(pParent, "modules/swriter/ui/assignstylesdialog.ui", "AssignStylesDialog")
508 , m_pStyleArr(rStringArr)
509 , m_xOk(m_xBuilder->weld_button("ok"))
510 , m_xLeftPB(m_xBuilder->weld_button("left"))
511 , m_xRightPB(m_xBuilder->weld_button("right"))
512 , m_xHeaderTree(m_xBuilder->weld_tree_view("styles"))
514 m_xOk->connect_clicked(LINK(this, SwAddStylesDlg_Impl, OkHdl));
515 m_xLeftPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
516 m_xRightPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
518 m_xHeaderTree->connect_size_allocate(LINK(this, SwAddStylesDlg_Impl, TreeSizeAllocHdl));
519 m_xHeaderTree->enable_toggle_buttons(weld::ColumnToggleType::Radio);
520 m_xHeaderTree->connect_toggled(LINK(this, SwAddStylesDlg_Impl, RadioToggleOnHdl));
521 m_xHeaderTree->connect_column_clicked(LINK(this, SwAddStylesDlg_Impl, HeaderBarClick));
523 std::vector<int> aWidths
525 o3tl::narrowing<int>(m_xHeaderTree->get_approximate_digit_width() * 30)
527 int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
528 OUString sTitle(m_xHeaderTree->get_column_title(1));
529 for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
531 sTitle = OUString::number(i);
532 m_xHeaderTree->set_column_title(i + 1, sTitle);
533 aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
535 m_xHeaderTree->set_column_fixed_widths(aWidths);
536 auto nWidth = std::accumulate(aWidths.begin(), aWidths.end(),
537 Application::GetSettings().GetStyleSettings().GetScrollBarSize());
538 m_xHeaderTree->set_size_request(nWidth, m_xHeaderTree->get_height_rows(15));
540 int nRow(0);
541 for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
543 const OUString &rStyles{rStringArr[i]};
544 if (rStyles.isEmpty())
545 continue;
546 sal_Int32 nPos(0);
549 OUString sEntry = rStyles.getToken(0, TOX_STYLE_DELIMITER, nPos);
550 m_xHeaderTree->append_text(sEntry);
551 for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
553 TriState eState = i == j - 1 ? TRISTATE_TRUE : TRISTATE_FALSE;
554 m_xHeaderTree->set_toggle(nRow, eState, j + 1);
556 ++nRow;
557 } while (nPos>=0);
559 // now the other styles
561 const sal_uInt16 nSz = rWrtSh.GetTextFormatCollCount();
562 for (sal_uInt16 j = 0; j < nSz; ++j)
564 const SwTextFormatColl& rColl = rWrtSh.GetTextFormatColl(j);
565 if (rColl.IsDefault())
566 continue;
568 const OUString aName = rColl.GetName();
569 if (!aName.isEmpty())
571 bool bEntry = false;
572 int nChildren = m_xHeaderTree->n_children();
573 for (int i = 0; i < nChildren; ++i)
575 if (m_xHeaderTree->get_text(i, 0) == aName)
577 bEntry = true;
578 break;
581 if (!bEntry)
583 m_xHeaderTree->append_text(aName);
584 for (sal_uInt16 k = 0; k <= MAXLEVEL; ++k)
586 TriState eState = k == 0 ? TRISTATE_TRUE : TRISTATE_FALSE;
587 m_xHeaderTree->set_toggle(nRow, eState, k + 1);
589 ++nRow;
594 m_xHeaderTree->make_sorted();
595 m_xHeaderTree->set_sort_column(0);
596 m_xHeaderTree->set_sort_order(true);
597 m_xHeaderTree->set_sort_indicator(TRISTATE_TRUE, 0);
599 m_xHeaderTree->select(0);
600 m_xHeaderTree->connect_key_release(LINK(this, SwAddStylesDlg_Impl, KeyInput));
603 IMPL_LINK(SwAddStylesDlg_Impl, HeaderBarClick, int, nColumn, void)
605 bool bSortAtoZ = m_xHeaderTree->get_sort_order();
607 //set new arrow positions in headerbar
608 if (nColumn == m_xHeaderTree->get_sort_column())
610 bSortAtoZ = !bSortAtoZ;
611 m_xHeaderTree->set_sort_order(bSortAtoZ);
614 if (nColumn != -1)
616 //sort lists
617 m_xHeaderTree->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
621 IMPL_LINK(SwAddStylesDlg_Impl, TreeSizeAllocHdl, const Size&, rSize, void)
623 auto nWidth = rSize.Width() - Application::GetSettings().GetStyleSettings().GetScrollBarSize();
625 std::vector<int> aWidths { 0 };
626 int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
627 for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
629 OUString sTitle(m_xHeaderTree->get_column_title(i + 1));
630 aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
632 auto nOtherWidth = std::accumulate(aWidths.begin(), aWidths.end(), 0);
633 aWidths[0] = nWidth - nOtherWidth;
634 m_xHeaderTree->set_column_fixed_widths(aWidths);
637 IMPL_LINK(SwAddStylesDlg_Impl, RadioToggleOnHdl, const weld::TreeView::iter_col&, rRowCol, void)
639 for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
641 TriState eState = rRowCol.second == i + 1 ? TRISTATE_TRUE : TRISTATE_FALSE;
642 m_xHeaderTree->set_toggle(rRowCol.first, eState, i + 1);
646 IMPL_LINK(SwAddStylesDlg_Impl, KeyInput, const KeyEvent&, rKEvt, bool)
648 vcl::KeyCode aCode = rKEvt.GetKeyCode();
649 bool bHandled = false;
651 sal_uInt16 nCode = aCode.GetCode();
652 switch (nCode)
654 case KEY_ADD:
655 LeftRightHdl(*m_xRightPB);
656 bHandled = true;
657 break;
658 case KEY_SUBTRACT:
659 LeftRightHdl(*m_xLeftPB);
660 bHandled = true;
661 break;
662 case KEY_0:
663 case KEY_1:
664 case KEY_2:
665 case KEY_3:
666 case KEY_4:
667 case KEY_5:
668 case KEY_6:
669 case KEY_7:
670 case KEY_8:
671 case KEY_9:
672 case KEY_A:
674 int nEntry = m_xHeaderTree->get_selected_index();
675 if (nEntry != -1)
677 ToggleOn(nEntry, nCode != KEY_A ? nCode - KEY_0 : 10);
678 bHandled = true;
680 break;
684 return bHandled;
687 IMPL_LINK_NOARG(SwAddStylesDlg_Impl, OkHdl, weld::Button&, void)
689 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
690 m_pStyleArr[i].clear();
692 int nChildren = m_xHeaderTree->n_children();
693 for (int i = 0; i < nChildren; ++i)
695 int nToggleColumn = 0;
696 for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
698 if (m_xHeaderTree->get_toggle(i, j + 1) == TRISTATE_TRUE)
700 nToggleColumn = j;
701 break;
704 if (nToggleColumn)
706 int nLevel = nToggleColumn - 1;
707 if(!m_pStyleArr[nLevel].isEmpty())
708 m_pStyleArr[nLevel] += OUStringChar(TOX_STYLE_DELIMITER);
709 m_pStyleArr[nLevel] += m_xHeaderTree->get_text(i, 0);
713 //TODO write back style names
714 m_xDialog->response(RET_OK);
717 IMPL_LINK(SwAddStylesDlg_Impl, LeftRightHdl, weld::Button&, rBtn, void)
719 bool bLeft = &rBtn == m_xLeftPB.get();
720 int nEntry = m_xHeaderTree->get_selected_index();
721 if (nEntry == -1)
722 return;
724 int nToggleColumn = 0;
725 for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
727 if (m_xHeaderTree->get_toggle(nEntry, j + 1) == TRISTATE_TRUE)
729 nToggleColumn = j;
730 break;
734 if (bLeft)
736 if (nToggleColumn)
737 --nToggleColumn;
739 else
741 if (nToggleColumn < MAXLEVEL)
742 ++nToggleColumn;
745 ToggleOn(nEntry, nToggleColumn);
748 void SwAddStylesDlg_Impl::ToggleOn(int nEntry, int nToggleColumn)
750 for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
752 m_xHeaderTree->set_toggle(nEntry, j == nToggleColumn ? TRISTATE_TRUE : TRISTATE_FALSE, j + 1);
756 SwTOXSelectTabPage::SwTOXSelectTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
757 : SfxTabPage(pPage, pController, "modules/swriter/ui/tocindexpage.ui", "TocIndexPage", &rAttrSet)
758 , m_sAutoMarkType(SwResId(STR_AUTOMARK_TYPE))
759 , m_bWaitingInitialSettings(true)
760 , m_xTitleED(m_xBuilder->weld_entry("title"))
761 , m_xTypeFT(m_xBuilder->weld_label("typeft"))
762 , m_xTypeLB(m_xBuilder->weld_combo_box("type"))
763 , m_xReadOnlyCB(m_xBuilder->weld_check_button("readonly"))
764 , m_xAreaFrame(m_xBuilder->weld_widget("areaframe"))
765 , m_xAreaLB(m_xBuilder->weld_combo_box("scope"))
766 , m_xLevelFT(m_xBuilder->weld_label("levelft"))
767 , m_xLevelNF(m_xBuilder->weld_spin_button("level"))
768 , m_xCreateFrame(m_xBuilder->weld_widget("createframe"))
769 , m_xFromHeadingsCB(m_xBuilder->weld_check_button("fromheadings"))
770 , m_xStylesCB(m_xBuilder->weld_check_button("stylescb"))
771 , m_xAddStylesCB(m_xBuilder->weld_check_button("addstylescb"))
772 , m_xAddStylesPB(m_xBuilder->weld_button("styles"))
773 , m_xFromTablesCB(m_xBuilder->weld_check_button("fromtables"))
774 , m_xFromFramesCB(m_xBuilder->weld_check_button("fromframes"))
775 , m_xFromGraphicsCB(m_xBuilder->weld_check_button("fromgraphics"))
776 , m_xFromOLECB(m_xBuilder->weld_check_button("fromoles"))
777 , m_xLevelFromChapterCB(m_xBuilder->weld_check_button("uselevel"))
778 , m_xFromCaptionsRB(m_xBuilder->weld_radio_button("captions"))
779 , m_xFromObjectNamesRB(m_xBuilder->weld_radio_button("objnames"))
780 , m_xCaptionSequenceFT(m_xBuilder->weld_label("categoryft"))
781 , m_xCaptionSequenceLB(m_xBuilder->weld_combo_box("category"))
782 , m_xDisplayTypeFT(m_xBuilder->weld_label("displayft"))
783 , m_xDisplayTypeLB(m_xBuilder->weld_combo_box("display"))
784 , m_xParaStyleCB(m_xBuilder->weld_check_button("useparastyle"))
785 , m_xParaStyleLB(m_xBuilder->weld_combo_box("parastyle"))
786 , m_xTOXMarksCB(m_xBuilder->weld_check_button("indexmarks"))
787 , m_xIdxOptionsFrame(m_xBuilder->weld_widget("optionsframe"))
788 , m_xCollectSameCB(m_xBuilder->weld_check_button("combinesame"))
789 , m_xUseFFCB(m_xBuilder->weld_check_button("useff"))
790 , m_xUseDashCB(m_xBuilder->weld_check_button("usedash"))
791 , m_xCaseSensitiveCB(m_xBuilder->weld_check_button("casesens"))
792 , m_xInitialCapsCB(m_xBuilder->weld_check_button("initcaps"))
793 , m_xKeyAsEntryCB(m_xBuilder->weld_check_button("keyasentry"))
794 , m_xFromFileCB(m_xBuilder->weld_check_button("fromfile"))
795 , m_xAutoMarkPB(m_xBuilder->weld_menu_button("file"))
796 , m_xFromObjCLB(m_xBuilder->weld_tree_view("objects"))
797 , m_xFromObjFrame(m_xBuilder->weld_widget("objectframe"))
798 , m_xSequenceCB(m_xBuilder->weld_check_button("numberentries"))
799 , m_xBracketLB(m_xBuilder->weld_combo_box("brackets"))
800 , m_xAuthorityFrame(m_xBuilder->weld_widget("authframe"))
801 , m_xSortFrame(m_xBuilder->weld_widget("sortframe"))
802 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
803 , m_xSortAlgorithmLB(m_xBuilder->weld_combo_box("keytype"))
805 m_sAddStyleUser = m_xStylesCB->get_label();
806 m_pIndexEntryWrapper.reset(new IndexEntrySupplierWrapper());
808 m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
809 false );
811 //Default mode is arranged to be the tallest mode
812 //of alphabetical index, lock that size in now
813 LanguageHdl(nullptr); //fill sort algorithm list
814 Size aPrefSize(m_xContainer->get_preferred_size());
815 m_xContainer->set_size_request(aPrefSize.Width(), aPrefSize.Height());
817 m_sAddStyleContent = m_xAddStylesCB->get_label();
819 m_xFromObjCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
821 for (size_t i = 0; i < SAL_N_ELEMENTS(RES_SRCTYPES); ++i)
823 OUString sId(OUString::number(static_cast<sal_uInt32>(RES_SRCTYPES[i].second)));
824 m_xFromObjCLB->append();
825 m_xFromObjCLB->set_toggle(i, TRISTATE_FALSE);
826 m_xFromObjCLB->set_text(i, SwResId(RES_SRCTYPES[i].first), 0);
827 m_xFromObjCLB->set_id(i, sId);
829 m_xFromObjCLB->set_size_request(-1, std::max<int>(m_xFromObjCLB->get_preferred_size().Height(),
830 m_xFromObjCLB->get_height_rows(SAL_N_ELEMENTS(RES_SRCTYPES))) + 2);
832 SetExchangeSupport();
833 m_xTypeLB->connect_changed(LINK(this, SwTOXSelectTabPage, TOXTypeHdl));
835 m_xAddStylesPB->connect_clicked(LINK(this, SwTOXSelectTabPage, AddStylesHdl));
837 m_xAutoMarkPB->connect_toggled(LINK(this, SwTOXSelectTabPage, MenuEnableHdl));
838 m_xAutoMarkPB->connect_selected(LINK(this, SwTOXSelectTabPage, MenuExecuteHdl));
840 Link<weld::Toggleable&,void> aLk = LINK(this, SwTOXSelectTabPage, CheckBoxHdl);
841 m_xAddStylesCB->connect_toggled(aLk);
842 m_xFromHeadingsCB->connect_toggled(aLk);
843 m_xTOXMarksCB->connect_toggled(aLk);
844 m_xFromFileCB->connect_toggled(aLk);
845 m_xCollectSameCB->connect_toggled(aLk);
846 m_xUseFFCB->connect_toggled(aLk);
847 m_xUseDashCB->connect_toggled(aLk);
848 m_xInitialCapsCB->connect_toggled(aLk);
849 m_xKeyAsEntryCB->connect_toggled(aLk);
850 m_xParaStyleCB->connect_toggled(aLk);
852 m_xTitleED->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyEntryHdl));
853 m_xLevelNF->connect_value_changed(LINK(this, SwTOXSelectTabPage, ModifySpinHdl));
854 m_xSortAlgorithmLB->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyListBoxHdl));
855 m_xParaStyleLB->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyListBoxHdl));
857 aLk = LINK(this, SwTOXSelectTabPage, RadioButtonHdl);
858 m_xFromCaptionsRB->connect_toggled(aLk);
859 m_xFromObjectNamesRB->connect_toggled(aLk);
860 RadioButtonHdl(*m_xFromCaptionsRB);
862 m_xLanguageLB->connect_changed(LINK(this, SwTOXSelectTabPage, LanguageListBoxHdl));
863 m_xTypeLB->set_active(0);
864 m_xTitleED->save_value();
867 SwTOXSelectTabPage::~SwTOXSelectTabPage()
869 m_pIndexRes.reset();
870 m_pIndexEntryWrapper.reset();
871 m_xLanguageLB.reset();
874 void SwTOXSelectTabPage::SetWrtShell(SwWrtShell const & rSh)
876 const sal_uInt16 nUserTypeCount = rSh.GetTOXTypeCount(TOX_USER);
877 if(nUserTypeCount <= 1)
878 return;
880 //insert all new user indexes names after the standard user index
881 sal_Int32 nPos = m_xTypeLB->find_id(OUString::number(sal_uInt32(TO_USER))) + 1;
882 for (sal_uInt16 nUser = 1; nUser < nUserTypeCount; nUser++)
884 sal_uInt32 nEntryData = nUser << 8;
885 nEntryData |= TO_USER;
886 OUString sId(OUString::number(nEntryData));
887 m_xTypeLB->insert(nPos++, rSh.GetTOXType(TOX_USER, nUser)->GetTypeName(),
888 &sId, nullptr, nullptr);
892 bool SwTOXSelectTabPage::FillItemSet( SfxItemSet* )
894 return true;
897 static tools::Long lcl_TOXTypesToUserData(CurTOXType eType)
899 sal_uInt16 nRet = TOX_INDEX;
900 switch(eType.eType)
902 case TOX_INDEX : nRet = TO_INDEX; break;
903 case TOX_USER :
905 nRet = eType.nIndex << 8;
906 nRet |= TO_USER;
908 break;
909 case TOX_CONTENT : nRet = TO_CONTENT; break;
910 case TOX_ILLUSTRATIONS:nRet = TO_ILLUSTRATION; break;
911 case TOX_OBJECTS : nRet = TO_OBJECT; break;
912 case TOX_TABLES : nRet = TO_TABLE; break;
913 case TOX_AUTHORITIES : nRet = TO_AUTHORITIES; break;
914 case TOX_BIBLIOGRAPHY : nRet = TO_BIBLIOGRAPHY; break;
915 case TOX_CITATION :break;
917 return nRet;
920 void SwTOXSelectTabPage::SelectType(TOXTypes eSet)
922 CurTOXType eCurType (eSet);
924 sal_uInt32 nData = lcl_TOXTypesToUserData(eCurType);
925 m_xTypeLB->set_active_id(OUString::number(nData));
926 m_xTypeFT->set_sensitive(false);
927 m_xTypeLB->set_sensitive(false);
928 TOXTypeHdl(*m_xTypeLB);
931 static CurTOXType lcl_UserData2TOXTypes(sal_uInt16 nData)
933 CurTOXType eRet;
935 switch(nData&0xff)
937 case TO_INDEX : eRet.eType = TOX_INDEX; break;
938 case TO_USER :
940 eRet.eType = TOX_USER;
941 eRet.nIndex = (nData&0xff00) >> 8;
943 break;
944 case TO_CONTENT : eRet.eType = TOX_CONTENT; break;
945 case TO_ILLUSTRATION: eRet.eType = TOX_ILLUSTRATIONS; break;
946 case TO_OBJECT : eRet.eType = TOX_OBJECTS; break;
947 case TO_TABLE : eRet.eType = TOX_TABLES; break;
948 case TO_AUTHORITIES : eRet.eType = TOX_AUTHORITIES; break;
949 case TO_BIBLIOGRAPHY : eRet.eType = TOX_BIBLIOGRAPHY; break;
950 default: OSL_FAIL("what a type?");
952 return eRet;
955 void SwTOXSelectTabPage::ApplyTOXDescription()
957 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
958 const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
959 SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
961 m_xReadOnlyCB->set_active(rDesc.IsReadonly());
962 if (!m_xTitleED->get_value_changed_from_saved())
964 if (rDesc.GetTitle())
965 m_xTitleED->set_text(*rDesc.GetTitle());
966 else
967 m_xTitleED->set_text(OUString());
968 m_xTitleED->save_value();
971 m_xAreaLB->set_active(rDesc.IsFromChapter() ? 1 : 0);
973 if (aCurType.eType != TOX_INDEX)
974 m_xLevelNF->set_value(rDesc.GetLevel()); //content, user
976 SwTOXElement nCreateType = rDesc.GetContentOptions();
978 //user + content
979 bool bHasStyleNames = false;
981 for( sal_uInt16 i = 0; i < MAXLEVEL; i++)
982 if(!rDesc.GetStyleNames(i).isEmpty())
984 bHasStyleNames = true;
985 break;
987 m_xAddStylesCB->set_active(bHasStyleNames && (nCreateType & SwTOXElement::Template));
989 m_xFromOLECB->set_active( bool(nCreateType & SwTOXElement::Ole) );
990 m_xFromTablesCB->set_active( bool(nCreateType & SwTOXElement::Table) );
991 m_xFromGraphicsCB->set_active( bool(nCreateType & SwTOXElement::Graphic) );
992 m_xFromFramesCB->set_active( bool(nCreateType & SwTOXElement::Frame) );
994 m_xLevelFromChapterCB->set_active(rDesc.IsLevelFromChapter());
996 //all but illustration and table
997 m_xTOXMarksCB->set_active( bool(nCreateType & SwTOXElement::Mark) );
999 if (TOX_ILLUSTRATIONS == aCurType.eType || TOX_TABLES == aCurType.eType
1000 || TOX_OBJECTS== aCurType.eType)
1002 // load all para styles...
1003 m_xParaStyleLB->clear();
1004 SwWrtShell const& rWrtSh(static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell());
1005 const sal_uInt16 nSz = rWrtSh.GetTextFormatCollCount();
1006 for (sal_uInt16 j = 0; j < nSz; ++j)
1008 SwTextFormatColl const& rColl = rWrtSh.GetTextFormatColl(j);
1009 if (rColl.IsDefault())
1010 continue;
1012 OUString const name(rColl.GetName());
1013 if (!name.isEmpty())
1015 m_xParaStyleLB->append_text(name);
1018 // first, init ParaStyle - because any later init (e.g. m_xFromCaptionsRB)
1019 // ends up calling FillTOXDescription() resetting rDesc!
1020 OUString const& rStyle(rDesc.GetStyleNames(0));
1021 assert(rStyle.indexOf(TOX_STYLE_DELIMITER) == -1);
1022 if (rStyle.isEmpty())
1024 m_xParaStyleCB->set_active(false);
1025 m_xParaStyleLB->set_sensitive(false);
1027 else
1029 m_xParaStyleCB->set_active(true);
1030 m_xParaStyleLB->set_sensitive(true);
1031 m_xParaStyleLB->set_active_text(rStyle);
1035 //content
1036 if(TOX_CONTENT == aCurType.eType)
1038 m_xFromHeadingsCB->set_active( bool(nCreateType & SwTOXElement::OutlineLevel) );
1039 m_xAddStylesCB->set_label(m_sAddStyleContent);
1040 m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
1042 //index only
1043 else if(TOX_INDEX == aCurType.eType)
1045 const SwTOIOptions nIndexOptions = rDesc.GetIndexOptions();
1046 m_xCollectSameCB->set_active( bool(nIndexOptions & SwTOIOptions::SameEntry) );
1047 m_xUseFFCB->set_active( bool(nIndexOptions & SwTOIOptions::FF) );
1048 m_xUseDashCB->set_active( bool(nIndexOptions & SwTOIOptions::Dash) );
1049 if (m_xUseFFCB->get_active())
1050 m_xUseDashCB->set_sensitive(false);
1051 else if (m_xUseDashCB->get_active())
1052 m_xUseFFCB->set_sensitive(false);
1054 m_xCaseSensitiveCB->set_active( bool(nIndexOptions & SwTOIOptions::CaseSensitive) );
1055 m_xInitialCapsCB->set_active( bool(nIndexOptions & SwTOIOptions::InitialCaps) );
1056 m_xKeyAsEntryCB->set_active( bool(nIndexOptions & SwTOIOptions::KeyAsEntry) );
1058 else if (TOX_ILLUSTRATIONS == aCurType.eType || TOX_TABLES == aCurType.eType)
1060 OUString sName(rDesc.GetSequenceName());
1061 int nIndex = m_xCaptionSequenceLB->find_text(sName);
1062 if (nIndex != -1)
1063 m_xCaptionSequenceLB->set_active(nIndex);
1064 m_xDisplayTypeLB->set_active(static_cast<sal_Int32>(rDesc.GetCaptionDisplay()));
1065 if (m_xDisplayTypeLB->get_active() == -1)
1066 m_xDisplayTypeLB->set_active(0);
1067 m_xFromObjectNamesRB->set_active(rDesc.IsCreateFromObjectNames());
1068 m_xFromCaptionsRB->set_active(!rDesc.IsCreateFromObjectNames());
1069 RadioButtonHdl(*m_xFromCaptionsRB);
1071 else if(TOX_OBJECTS == aCurType.eType)
1073 SwTOOElements nOLEData = rDesc.GetOLEOptions();
1074 for (int nFromObj = 0, nCount = m_xFromObjCLB->n_children(); nFromObj < nCount; ++nFromObj)
1076 SwTOOElements nData = static_cast<SwTOOElements>(m_xFromObjCLB->get_id(nFromObj).toInt32());
1077 m_xFromObjCLB->set_toggle(nFromObj, bool(nData & nOLEData) ? TRISTATE_TRUE : TRISTATE_FALSE);
1080 else if(TOX_AUTHORITIES == aCurType.eType)
1082 const OUString& sBrackets(rDesc.GetAuthBrackets());
1083 if(sBrackets.isEmpty() || sBrackets == " ")
1084 m_xBracketLB->set_active(0);
1085 else
1086 m_xBracketLB->set_active_text(sBrackets);
1087 m_xSequenceCB->set_active(rDesc.IsAuthSequence());
1089 m_xAutoMarkPB->set_sensitive(m_xFromFileCB->get_active());
1091 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
1092 m_aStyleArr[i] = rDesc.GetStyleNames(i);
1094 m_xLanguageLB->set_active_id(rDesc.GetLanguage());
1095 LanguageHdl(nullptr);
1096 for (int nCnt = 0, nEntryCount = m_xSortAlgorithmLB->get_count(); nCnt < nEntryCount; ++nCnt)
1098 const OUString& rEntryData = m_xSortAlgorithmLB->get_id(nCnt);
1099 if (rEntryData == rDesc.GetSortAlgorithm())
1101 m_xSortAlgorithmLB->set_active(nCnt);
1102 break;
1107 void SwTOXSelectTabPage::FillTOXDescription()
1109 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
1110 CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
1111 SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
1112 rDesc.SetTitle(m_xTitleED->get_text());
1113 rDesc.SetFromChapter(1 == m_xAreaLB->get_active());
1114 SwTOXElement nContentOptions = SwTOXElement::NONE;
1115 if (m_xTOXMarksCB->get_visible() && m_xTOXMarksCB->get_active())
1116 nContentOptions |= SwTOXElement::Mark;
1118 SwTOIOptions nIndexOptions = rDesc.GetIndexOptions()&SwTOIOptions::AlphaDelimiter;
1119 switch(rDesc.GetTOXType())
1121 case TOX_CONTENT:
1122 if(m_xFromHeadingsCB->get_active())
1123 nContentOptions |= SwTOXElement::OutlineLevel;
1124 break;
1125 case TOX_USER:
1127 rDesc.SetTOUName(m_xTypeLB->get_active_text());
1129 if(m_xFromOLECB->get_active())
1130 nContentOptions |= SwTOXElement::Ole;
1131 if(m_xFromTablesCB->get_active())
1132 nContentOptions |= SwTOXElement::Table;
1133 if(m_xFromFramesCB->get_active())
1134 nContentOptions |= SwTOXElement::Frame;
1135 if(m_xFromGraphicsCB->get_active())
1136 nContentOptions |= SwTOXElement::Graphic;
1138 break;
1139 case TOX_INDEX:
1141 nContentOptions = SwTOXElement::Mark;
1143 if(m_xCollectSameCB->get_active())
1144 nIndexOptions |= SwTOIOptions::SameEntry;
1145 if(m_xUseFFCB->get_active())
1146 nIndexOptions |= SwTOIOptions::FF;
1147 if(m_xUseDashCB->get_active())
1148 nIndexOptions |= SwTOIOptions::Dash;
1149 if(m_xCaseSensitiveCB->get_active())
1150 nIndexOptions |= SwTOIOptions::CaseSensitive;
1151 if(m_xInitialCapsCB->get_active())
1152 nIndexOptions |= SwTOIOptions::InitialCaps;
1153 if(m_xKeyAsEntryCB->get_active())
1154 nIndexOptions |= SwTOIOptions::KeyAsEntry;
1155 if(m_xFromFileCB->get_active())
1156 rDesc.SetAutoMarkURL(m_sAutoMarkURL);
1157 else
1158 rDesc.SetAutoMarkURL(OUString());
1160 break;
1161 case TOX_ILLUSTRATIONS:
1162 case TOX_TABLES :
1163 rDesc.SetCreateFromObjectNames(m_xFromObjectNamesRB->get_active());
1164 rDesc.SetSequenceName(m_xCaptionSequenceLB->get_active_text());
1165 rDesc.SetCaptionDisplay(static_cast<SwCaptionDisplay>(m_xDisplayTypeLB->get_active()));
1166 if (m_xParaStyleCB->get_active())
1168 m_aStyleArr[0] = m_xParaStyleLB->get_active_text();
1170 else
1172 m_aStyleArr[0] = OUString();
1174 break;
1175 case TOX_OBJECTS:
1177 SwTOOElements nOLEData = SwTOOElements::NONE;
1178 for (int i = 0, nCount = m_xFromObjCLB->n_children(); i < nCount; ++i)
1180 if (m_xFromObjCLB->get_toggle(i) == TRISTATE_TRUE)
1182 SwTOOElements nData = static_cast<SwTOOElements>(m_xFromObjCLB->get_id(i).toInt32());
1183 nOLEData |= nData;
1186 rDesc.SetOLEOptions(nOLEData);
1187 if (m_xParaStyleCB->get_active())
1189 m_aStyleArr[0] = m_xParaStyleLB->get_active_text();
1191 else
1193 m_aStyleArr[0] = OUString();
1196 break;
1197 case TOX_AUTHORITIES:
1198 case TOX_BIBLIOGRAPHY :
1200 if (m_xBracketLB->get_active())
1201 rDesc.SetAuthBrackets(m_xBracketLB->get_active_text());
1202 else
1203 rDesc.SetAuthBrackets(OUString());
1204 rDesc.SetAuthSequence(m_xSequenceCB->get_active());
1206 break;
1207 case TOX_CITATION :
1208 break;
1211 rDesc.SetLevelFromChapter( m_xLevelFromChapterCB->get_visible() &&
1212 m_xLevelFromChapterCB->get_active());
1213 if (m_xTOXMarksCB->get_active() && m_xTOXMarksCB->get_visible())
1214 nContentOptions |= SwTOXElement::Mark;
1215 if (m_xFromHeadingsCB->get_active() && m_xFromHeadingsCB->get_visible())
1216 nContentOptions |= SwTOXElement::OutlineLevel;
1217 if ((m_xAddStylesCB->get_active() && m_xAddStylesCB->get_visible())
1218 || (m_xParaStyleCB->get_active() && m_xParaStyleCB->get_visible()))
1220 nContentOptions |= SwTOXElement::Template;
1223 rDesc.SetContentOptions(nContentOptions);
1224 rDesc.SetIndexOptions(nIndexOptions);
1225 rDesc.SetLevel(m_xLevelNF->get_value());
1227 rDesc.SetReadonly(m_xReadOnlyCB->get_active());
1229 for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
1230 rDesc.SetStyleNames(m_aStyleArr[i], i);
1232 rDesc.SetLanguage(m_xLanguageLB->get_active_id());
1233 const OUString& rEntryData = m_xSortAlgorithmLB->get_active_id();
1234 rDesc.SetSortAlgorithm(rEntryData);
1237 void SwTOXSelectTabPage::Reset( const SfxItemSet* )
1239 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
1240 SwWrtShell& rSh = pTOXDlg->GetWrtShell();
1241 const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
1242 sal_uInt32 nData = lcl_TOXTypesToUserData(aCurType);
1243 m_xTypeLB->set_active_id(OUString::number(nData));
1245 m_sAutoMarkURL = INetURLObject::decode( rSh.GetTOIAutoMarkURL(),
1246 INetURLObject::DecodeMechanism::Unambiguous );
1247 m_xFromFileCB->set_active(!m_sAutoMarkURL.isEmpty());
1249 m_xCaptionSequenceLB->clear();
1250 const size_t nCount = rSh.GetFieldTypeCount(SwFieldIds::SetExp);
1251 for (size_t i = 0; i < nCount; ++i)
1253 SwFieldType *pType = rSh.GetFieldType( i, SwFieldIds::SetExp );
1254 if( pType->Which() == SwFieldIds::SetExp &&
1255 static_cast<SwSetExpFieldType *>( pType)->GetType() & nsSwGetSetExpType::GSE_SEQ )
1256 m_xCaptionSequenceLB->append_text(pType->GetName());
1259 if(pTOXDlg->IsTOXEditMode())
1261 m_xTypeFT->set_sensitive(false);
1262 m_xTypeLB->set_sensitive(false);
1265 if(!m_bWaitingInitialSettings)
1267 // save current values into the proper TOXDescription
1268 FillTOXDescription();
1270 m_bWaitingInitialSettings = false;
1272 TOXTypeHdl(*m_xTypeLB);
1273 CheckBoxHdl(*m_xAddStylesCB);
1276 void SwTOXSelectTabPage::ActivatePage( const SfxItemSet& )
1278 //nothing to do
1281 DeactivateRC SwTOXSelectTabPage::DeactivatePage(SfxItemSet* _pSet)
1283 if (_pSet)
1284 _pSet->Put(SfxUInt16Item(FN_PARAM_TOX_TYPE, m_xTypeLB->get_active_id().toUInt32()));
1285 FillTOXDescription();
1286 return DeactivateRC::LeavePage;
1289 std::unique_ptr<SfxTabPage> SwTOXSelectTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
1291 return std::make_unique<SwTOXSelectTabPage>(pPage, pController, *rAttrSet);
1294 IMPL_LINK(SwTOXSelectTabPage, TOXTypeHdl, weld::ComboBox&, rBox, void)
1296 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
1297 const sal_uInt16 nType = rBox.get_active_id().toUInt32();
1298 CurTOXType eCurType = lcl_UserData2TOXTypes(nType);
1299 pTOXDlg->SetCurrentTOXType(eCurType);
1301 m_xAreaLB->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_INDEX|TO_TABLE|TO_OBJECT)) );
1302 m_xLevelFT->set_visible( 0 != (nType & (TO_CONTENT)) );
1303 m_xLevelNF->set_visible( 0 != (nType & (TO_CONTENT)) );
1304 m_xLevelFromChapterCB->set_visible( 0 != (nType & (TO_USER)) );
1305 m_xAreaFrame->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_INDEX|TO_TABLE|TO_OBJECT)) );
1307 m_xFromHeadingsCB->set_visible( 0 != (nType & (TO_CONTENT)) );
1308 m_xAddStylesCB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
1309 m_xAddStylesPB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
1311 m_xFromTablesCB->set_visible( 0 != (nType & (TO_USER)) );
1312 m_xFromFramesCB->set_visible( 0 != (nType & (TO_USER)) );
1313 m_xFromGraphicsCB->set_visible( 0 != (nType & (TO_USER)) );
1314 m_xFromOLECB->set_visible( 0 != (nType & (TO_USER)) );
1316 m_xFromCaptionsRB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1317 m_xFromObjectNamesRB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1319 m_xTOXMarksCB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
1321 m_xCreateFrame->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_TABLE)) );
1322 m_xCaptionSequenceFT->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1323 m_xCaptionSequenceLB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1324 m_xDisplayTypeFT->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1325 m_xDisplayTypeLB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
1326 m_xParaStyleCB->set_visible(0 != (nType & (TO_ILLUSTRATION|TO_TABLE|TO_OBJECT)));
1327 m_xParaStyleLB->set_visible(0 != (nType & (TO_ILLUSTRATION|TO_TABLE|TO_OBJECT)));
1329 m_xAuthorityFrame->set_visible( 0 != (nType & TO_AUTHORITIES) );
1331 bool bEnableSortLanguage = 0 != (nType & (TO_INDEX|TO_AUTHORITIES));
1332 m_xSortFrame->set_visible(bEnableSortLanguage);
1334 if( nType & TO_ILLUSTRATION )
1336 OUString sName(SwStyleNameMapper::GetUIName(RES_POOLCOLL_LABEL_FIGURE, OUString()));
1337 m_xCaptionSequenceLB->set_active_text(sName);
1339 else if( nType & TO_TABLE )
1341 OUString sName(SwStyleNameMapper::GetUIName(RES_POOLCOLL_LABEL_TABLE, OUString()));
1342 m_xCaptionSequenceLB->set_active_text(sName);
1344 else if( nType & TO_USER )
1346 m_xAddStylesCB->set_label(m_sAddStyleUser);
1349 m_xIdxOptionsFrame->set_visible( 0 != (nType & TO_INDEX) );
1351 //object index
1352 m_xFromObjFrame->set_visible( 0 != (nType & TO_OBJECT) );
1354 //set control values from the proper TOXDescription
1356 ApplyTOXDescription();
1358 ModifyHdl();
1361 void SwTOXSelectTabPage::ModifyHdl()
1363 if(!m_bWaitingInitialSettings)
1365 FillTOXDescription();
1366 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
1367 pTOXDlg->CreateOrUpdateExample(pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_SELECT);
1371 IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifyListBoxHdl, weld::ComboBox&, void)
1373 ModifyHdl();
1376 IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifyEntryHdl, weld::Entry&, void)
1378 ModifyHdl();
1381 IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifySpinHdl, weld::SpinButton&, void)
1383 ModifyHdl();
1386 IMPL_LINK(SwTOXSelectTabPage, CheckBoxHdl, weld::Toggleable&, rButton, void)
1388 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
1389 const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
1390 if(TOX_CONTENT == aCurType.eType)
1392 //at least one of the three CheckBoxes must be checked
1393 if (!m_xAddStylesCB->get_active() && !m_xFromHeadingsCB->get_active() && !m_xTOXMarksCB->get_active())
1395 //TODO: InfoBox?
1396 rButton.set_active(true);
1398 m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
1400 if (TOX_USER == aCurType.eType)
1402 m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
1404 else if (TOX_INDEX == aCurType.eType)
1406 m_xAutoMarkPB->set_sensitive(m_xFromFileCB->get_active());
1407 m_xUseFFCB->set_sensitive(m_xCollectSameCB->get_active() && !m_xUseDashCB->get_active());
1408 m_xUseDashCB->set_sensitive(m_xCollectSameCB->get_active() && !m_xUseFFCB->get_active());
1409 m_xCaseSensitiveCB->set_sensitive(m_xCollectSameCB->get_active());
1411 else if (TOX_ILLUSTRATIONS == aCurType.eType
1412 || TOX_TABLES == aCurType.eType
1413 || TOX_OBJECTS == aCurType.eType)
1415 bool const bEnable(m_xParaStyleCB->get_active());
1416 m_xParaStyleLB->set_sensitive(bEnable);
1418 ModifyHdl();
1421 IMPL_LINK_NOARG(SwTOXSelectTabPage, RadioButtonHdl, weld::Toggleable&, void)
1423 bool bEnable = m_xFromCaptionsRB->get_active();
1424 m_xCaptionSequenceFT->set_sensitive(bEnable);
1425 m_xCaptionSequenceLB->set_sensitive(bEnable);
1426 m_xDisplayTypeFT->set_sensitive(bEnable);
1427 m_xDisplayTypeLB->set_sensitive(bEnable);
1428 ModifyHdl();
1431 IMPL_LINK(SwTOXSelectTabPage, LanguageListBoxHdl, weld::ComboBox&, rBox, void)
1433 LanguageHdl(&rBox);
1436 void SwTOXSelectTabPage::LanguageHdl(const weld::ComboBox* pBox)
1438 lang::Locale aLcl( LanguageTag( m_xLanguageLB->get_active_id() ).getLocale() );
1439 Sequence< OUString > aSeq = m_pIndexEntryWrapper->GetAlgorithmList( aLcl );
1441 if( !m_pIndexRes )
1442 m_pIndexRes.reset(new IndexEntryResource());
1444 OUString sOldString = m_xSortAlgorithmLB->get_active_id();
1445 m_xSortAlgorithmLB->clear();
1447 sal_Int32 nEnd = aSeq.getLength();
1448 for( sal_Int32 nCnt = 0; nCnt < nEnd; ++nCnt )
1450 const OUString sAlg(aSeq[ nCnt ]);
1451 const OUString sUINm = m_pIndexRes->GetTranslation( sAlg );
1452 m_xSortAlgorithmLB->append(sAlg, sUINm);
1453 if( sAlg == sOldString )
1454 m_xSortAlgorithmLB->set_active(nCnt);
1457 if (m_xSortAlgorithmLB->get_active() == -1)
1458 m_xSortAlgorithmLB->set_active(0);
1460 if (pBox)
1461 ModifyHdl();
1464 IMPL_LINK_NOARG(SwTOXSelectTabPage, AddStylesHdl, weld::Button&, void)
1466 SwAddStylesDlg_Impl aDlg(GetFrameWeld(), static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell(),
1467 m_aStyleArr);
1468 aDlg.run();
1469 ModifyHdl();
1472 IMPL_LINK_NOARG(SwTOXSelectTabPage, MenuEnableHdl, weld::Toggleable&, void)
1474 m_xAutoMarkPB->set_item_sensitive("edit", !m_sAutoMarkURL.isEmpty());
1477 IMPL_LINK(SwTOXSelectTabPage, MenuExecuteHdl, const OUString&, rIdent, void)
1479 const OUString sSaveAutoMarkURL = m_sAutoMarkURL;
1481 if (rIdent == "open")
1483 m_sAutoMarkURL = lcl_CreateAutoMarkFileDlg(GetFrameWeld(),
1484 m_sAutoMarkURL, m_sAutoMarkType, true);
1486 else if (rIdent == "new" || rIdent == "edit")
1488 bool bNew = (rIdent == "new");
1489 if (bNew)
1491 m_sAutoMarkURL = lcl_CreateAutoMarkFileDlg(GetFrameWeld(),
1492 m_sAutoMarkURL, m_sAutoMarkType, false);
1493 if (m_sAutoMarkURL.isEmpty())
1494 return;
1497 SwAutoMarkDlg_Impl aAutoMarkDlg(GetFrameWeld(), m_sAutoMarkURL, bNew);
1498 if (RET_OK != aAutoMarkDlg.run() && bNew)
1499 m_sAutoMarkURL = sSaveAutoMarkURL;
1503 class SwTOXWidget
1505 protected:
1506 Link<SwTOXWidget&,void> m_aGetFocusLink;
1507 public:
1508 virtual WindowType GetType() const = 0;
1509 virtual void GrabFocus() = 0;
1510 virtual void Hide() = 0;
1511 virtual void set_grid_left_attach(int nPos) = 0;
1512 virtual void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) = 0;
1513 void SetGetFocusHdl(const Link<SwTOXWidget&,void>& rLink) { m_aGetFocusLink = rLink; }
1514 virtual ~SwTOXWidget() {}
1517 class SwTOXEdit : public SwTOXWidget
1519 std::unique_ptr<weld::Builder> m_xBuilder;
1520 SwFormToken m_aFormToken;
1521 Link<SwTOXEdit&,void> m_aModifiedLink;
1522 Link<SwTOXEdit&,void> m_aPrevNextControlLink;
1523 bool m_bNextControl;
1524 SwTokenWindow* m_pParent;
1525 std::unique_ptr<weld::Entry> m_xEntry;
1527 DECL_LINK(ModifyHdl, weld::Entry&, void);
1528 public:
1529 SwTOXEdit(SwTokenWindow* pTokenWin, const SwFormToken& rToken)
1530 : m_xBuilder(Application::CreateBuilder(pTokenWin->get_child_container(), "modules/swriter/ui/toxentrywidget.ui"))
1531 , m_aFormToken(rToken)
1532 , m_bNextControl(false)
1533 , m_pParent(pTokenWin)
1534 , m_xEntry(m_xBuilder->weld_entry("entry"))
1536 m_xEntry->connect_changed(LINK(this, SwTOXEdit, ModifyHdl));
1537 m_xEntry->connect_key_press(LINK(this, SwTOXEdit, KeyInputHdl));
1538 m_xEntry->connect_focus_in(LINK(this, SwTOXEdit, FocusInHdl));
1539 m_xEntry->set_tooltip_text(m_pParent->CreateQuickHelp(rToken));
1542 virtual ~SwTOXEdit() override
1544 m_pParent->get_child_container()->move(m_xEntry.get(), nullptr);
1547 virtual WindowType GetType() const override
1549 return WindowType::EDIT;
1552 virtual void GrabFocus() override
1554 m_xEntry->grab_focus();
1557 virtual void Hide() override
1559 m_xEntry->hide();
1562 void Show()
1564 m_xEntry->show();
1567 void SetAccessibleName(const OUString& rName)
1569 m_xEntry->set_accessible_name(rName);
1572 virtual void set_grid_left_attach(int nPos) override
1574 m_xEntry->set_grid_left_attach(nPos);
1577 virtual void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) override
1579 m_xEntry->get_extents_relative_to(rRelative, x, y, width, height);
1582 OUString GetText() const
1584 return m_xEntry->get_text();
1587 void SetText(const OUString& rText)
1589 m_xEntry->set_text(rText);
1592 void get_selection_bounds(int& rStartPos, int& rEndPos)
1594 m_xEntry->get_selection_bounds(rStartPos, rEndPos);
1597 void select_region(int nStartPos, int nEndPos)
1599 m_xEntry->select_region(nStartPos, nEndPos);
1602 void SetModifyHdl(const Link<SwTOXEdit&,void>& rLink)
1604 m_aModifiedLink = rLink;
1607 DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
1608 DECL_LINK(FocusInHdl, weld::Widget&, void);
1610 bool IsNextControl() const { return m_bNextControl; }
1611 void SetPrevNextLink(const Link<SwTOXEdit&,void>& rLink) { m_aPrevNextControlLink = rLink; }
1613 const SwFormToken& GetFormToken()
1615 m_aFormToken.sText = m_xEntry->get_text();
1616 return m_aFormToken;
1619 void SetCharStyleName(const OUString& rSet, sal_uInt16 nPoolId)
1621 m_aFormToken.sCharStyleName = rSet;
1622 m_aFormToken.nPoolId = nPoolId;
1625 void AdjustSize();
1628 IMPL_LINK_NOARG(SwTOXEdit, ModifyHdl, weld::Entry&, void)
1630 m_aModifiedLink.Call(*this);
1633 IMPL_LINK(SwTOXEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1635 bool bCall = false;
1636 int nStartPos, nEndPos;
1637 bool bStartIsEnd = !m_xEntry->get_selection_bounds(nStartPos, nEndPos);
1638 int nMin = std::min(nStartPos, nEndPos);
1639 const sal_Int32 nTextLen = GetText().getLength();
1640 if ((bStartIsEnd && !nMin) || nMin == nTextLen)
1642 vcl::KeyCode aCode = rKEvt.GetKeyCode();
1643 if (aCode.GetCode() == KEY_RIGHT && nMin == nTextLen)
1645 m_bNextControl = true;
1646 bCall = true;
1648 else if (aCode.GetCode() == KEY_LEFT && !nMin)
1650 m_bNextControl = false;
1651 bCall = true;
1653 else if ( (aCode.GetCode() == KEY_F3) && aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
1655 if (m_pParent)
1657 m_pParent->SetFocus2theAllBtn();
1660 if (bCall && m_aPrevNextControlLink.IsSet())
1661 m_aPrevNextControlLink.Call(*this);
1662 else
1663 bCall = false;
1666 return bCall;
1669 IMPL_LINK_NOARG(SwTOXEdit, FocusInHdl, weld::Widget&, void)
1671 m_aGetFocusLink.Call(*this);
1674 void SwTOXEdit::AdjustSize()
1676 auto nWidth = m_xEntry->get_pixel_size(GetText()).Width();
1677 float fChars = nWidth / m_xEntry->get_approximate_digit_width();
1678 m_xEntry->set_width_chars(std::max(1.0f, std::ceil(fChars)));
1681 class SwTOXButton : public SwTOXWidget
1683 std::unique_ptr<weld::Builder> m_xBuilder;
1684 SwFormToken m_aFormToken;
1685 Link<SwTOXButton&,void> m_aPrevNextControlLink;
1686 bool m_bNextControl;
1687 SwTokenWindow* m_pParent;
1688 std::unique_ptr<weld::ToggleButton> m_xButton;
1689 public:
1690 SwTOXButton(SwTokenWindow* pTokenWin, const SwFormToken& rToken)
1691 : m_xBuilder(Application::CreateBuilder(pTokenWin->get_child_container(), "modules/swriter/ui/toxbuttonwidget.ui"))
1692 , m_aFormToken(rToken)
1693 , m_bNextControl(false)
1694 , m_pParent(pTokenWin)
1695 , m_xButton(m_xBuilder->weld_toggle_button("button"))
1697 m_xButton->connect_key_press(LINK(this, SwTOXButton, KeyInputHdl));
1698 m_xButton->connect_focus_in(LINK(this, SwTOXButton, FocusInHdl));
1699 m_xButton->set_tooltip_text(m_pParent->CreateQuickHelp(rToken));
1702 virtual ~SwTOXButton() override
1704 m_pParent->get_child_container()->move(m_xButton.get(), nullptr);
1707 virtual WindowType GetType() const override
1709 return WindowType::PUSHBUTTON;
1712 virtual void GrabFocus() override
1714 m_xButton->grab_focus();
1717 virtual void Hide() override
1719 m_xButton->hide();
1722 void Show()
1724 m_xButton->show();
1727 void SetAccessibleName(const OUString& rName)
1729 m_xButton->set_accessible_name(rName);
1732 virtual void set_grid_left_attach(int nPos) override
1734 m_xButton->set_grid_left_attach(nPos);
1737 void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) override
1739 m_xButton->get_extents_relative_to(rRelative, x, y, width, height);
1742 void Check(bool bCheck = true)
1744 m_xButton->set_active(bCheck);
1747 DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
1748 DECL_LINK(FocusInHdl, weld::Widget&, void);
1750 bool IsNextControl() const {return m_bNextControl;}
1751 void SetPrevNextLink(const Link<SwTOXButton&,void>& rLink) {m_aPrevNextControlLink = rLink;}
1752 const SwFormToken& GetFormToken() const {return m_aFormToken;}
1754 void SetCharStyleName(const OUString& rSet, sal_uInt16 nPoolId)
1756 m_aFormToken.sCharStyleName = rSet;
1757 m_aFormToken.nPoolId = nPoolId;
1760 void SetTabPosition(SwTwips nSet)
1761 { m_aFormToken.nTabStopPosition = nSet; }
1763 void SetFillChar( sal_Unicode cSet )
1764 { m_aFormToken.cTabFillChar = cSet; }
1766 void SetTabAlign(SvxTabAdjust eAlign)
1767 { m_aFormToken.eTabAlign = eAlign;}
1769 //---> i89791
1770 //used for entry number format, in TOC only
1771 //needed for different UI dialog position
1772 void SetEntryNumberFormat(sal_uInt16 nSet) {
1773 switch(nSet)
1775 default:
1776 case 0:
1777 m_aFormToken.nChapterFormat = CF_NUMBER;
1778 break;
1779 case 1:
1780 m_aFormToken.nChapterFormat = CF_NUM_NOPREPST_TITLE;
1781 break;
1785 void SetChapterInfo(sal_uInt16 nSet) {
1786 switch(nSet)
1788 default:
1789 case 0:
1790 m_aFormToken.nChapterFormat = CF_NUM_NOPREPST_TITLE;
1791 break;
1792 case 1:
1793 m_aFormToken.nChapterFormat = CF_TITLE;
1794 break;
1795 case 2:
1796 m_aFormToken.nChapterFormat = CF_NUMBER_NOPREPST;
1797 break;
1801 void SetOutlineLevel( sal_uInt16 nSet ) { m_aFormToken.nOutlineLevel = nSet;}//i53420
1803 void SetText(const OUString& rText)
1805 m_xButton->set_label(rText);
1808 void SetLinkEnd()
1810 OSL_ENSURE(TOKEN_LINK_START == m_aFormToken.eTokenType,
1811 "call SetLinkEnd for link start only!");
1812 m_aFormToken.eTokenType = TOKEN_LINK_END;
1813 m_aFormToken.sText = SwForm::GetFormLinkEnd();
1814 SetText(m_aFormToken.sText);
1817 void SetLinkStart()
1819 OSL_ENSURE(TOKEN_LINK_END == m_aFormToken.eTokenType,
1820 "call SetLinkStart for link start only!");
1821 m_aFormToken.eTokenType = TOKEN_LINK_START;
1822 m_aFormToken.sText = SwForm::GetFormLinkStt();
1823 SetText(m_aFormToken.sText);
1827 IMPL_LINK(SwTOXButton, KeyInputHdl, const KeyEvent&, rKEvt, bool)
1829 bool bCall = false;
1830 vcl::KeyCode aCode = rKEvt.GetKeyCode();
1831 if (aCode.GetCode() == KEY_RIGHT)
1833 m_bNextControl = true;
1834 bCall = true;
1836 else if (aCode.GetCode() == KEY_LEFT)
1838 m_bNextControl = false;
1839 bCall = true;
1841 else if (aCode.GetCode() == KEY_DELETE)
1843 m_pParent->RemoveControl(this, true);
1844 //this is invalid here
1845 return true;
1847 else if ( (aCode.GetCode() == KEY_F3) && aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
1849 if (m_pParent)
1851 m_pParent->SetFocus2theAllBtn();
1854 if (bCall && m_aPrevNextControlLink.IsSet())
1855 m_aPrevNextControlLink.Call(*this);
1856 else
1857 bCall = false;
1858 return bCall;
1861 IMPL_LINK_NOARG(SwTOXButton, FocusInHdl, weld::Widget&, void)
1863 m_aGetFocusLink.Call(*this);
1866 namespace
1868 const TranslateId STR_AUTH_FIELD_ARY[] =
1870 STR_AUTH_FIELD_IDENTIFIER,
1871 STR_AUTH_FIELD_AUTHORITY_TYPE,
1872 STR_AUTH_FIELD_ADDRESS,
1873 STR_AUTH_FIELD_ANNOTE,
1874 STR_AUTH_FIELD_AUTHOR,
1875 STR_AUTH_FIELD_BOOKTITLE,
1876 STR_AUTH_FIELD_CHAPTER,
1877 STR_AUTH_FIELD_EDITION,
1878 STR_AUTH_FIELD_EDITOR,
1879 STR_AUTH_FIELD_HOWPUBLISHED,
1880 STR_AUTH_FIELD_INSTITUTION,
1881 STR_AUTH_FIELD_JOURNAL,
1882 STR_AUTH_FIELD_MONTH,
1883 STR_AUTH_FIELD_NOTE,
1884 STR_AUTH_FIELD_NUMBER,
1885 STR_AUTH_FIELD_ORGANIZATIONS,
1886 STR_AUTH_FIELD_PAGES,
1887 STR_AUTH_FIELD_PUBLISHER,
1888 STR_AUTH_FIELD_SCHOOL,
1889 STR_AUTH_FIELD_SERIES,
1890 STR_AUTH_FIELD_TITLE,
1891 STR_AUTH_FIELD_TYPE,
1892 STR_AUTH_FIELD_VOLUME,
1893 STR_AUTH_FIELD_YEAR,
1894 STR_AUTH_FIELD_URL,
1895 STR_AUTH_FIELD_CUSTOM1,
1896 STR_AUTH_FIELD_CUSTOM2,
1897 STR_AUTH_FIELD_CUSTOM3,
1898 STR_AUTH_FIELD_CUSTOM4,
1899 STR_AUTH_FIELD_CUSTOM5,
1900 STR_AUTH_FIELD_ISBN,
1901 STR_AUTH_FIELD_LOCAL_URL,
1902 STR_AUTH_FIELD_TARGET_TYPE,
1903 STR_AUTH_FIELD_TARGET_URL,
1907 SwTOXEntryTabPage::SwTOXEntryTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
1908 : SfxTabPage(pPage, pController, "modules/swriter/ui/tocentriespage.ui", "TocEntriesPage", &rAttrSet)
1909 , m_sDelimStr(SwResId(STR_DELIM))
1910 , m_sNoCharStyle(SwResId(STR_NO_CHAR_STYLE))
1911 , m_pCurrentForm(nullptr)
1912 , m_bInLevelHdl(false)
1913 , m_xTypeFT(m_xBuilder->weld_label("typeft"))
1914 , m_xLevelFT(m_xBuilder->weld_label("levelft"))
1915 , m_xLevelLB(m_xBuilder->weld_tree_view("level"))
1916 , m_xAllLevelsPB(m_xBuilder->weld_button("all"))
1917 , m_xEntryNoPB(m_xBuilder->weld_button("chapterno"))
1918 , m_xEntryPB(m_xBuilder->weld_button("entrytext"))
1919 , m_xTabPB(m_xBuilder->weld_button("tabstop"))
1920 , m_xChapterInfoPB(m_xBuilder->weld_button("chapterinfo"))
1921 , m_xPageNoPB(m_xBuilder->weld_button("pageno"))
1922 , m_xHyperLinkPB(m_xBuilder->weld_button("hyperlink"))
1923 , m_xFieldBox(m_xBuilder->weld_widget("fieldbox"))
1924 , m_xAuthFieldsLB(m_xBuilder->weld_combo_box("authfield"))
1925 , m_xAuthInsertPB(m_xBuilder->weld_button("insert"))
1926 , m_xAuthRemovePB(m_xBuilder->weld_button("remove"))
1927 , m_xCharStyleLB(m_xBuilder->weld_combo_box("charstyle"))
1928 , m_xEditStylePB(m_xBuilder->weld_button("edit"))
1929 , m_xChapterEntryFT(m_xBuilder->weld_label("chapterentryft"))
1930 , m_xChapterEntryLB(m_xBuilder->weld_combo_box("chapterentry"))
1931 , m_xNumberFormatFT(m_xBuilder->weld_label("numberformatft"))
1932 , m_xNumberFormatLB(m_xBuilder->weld_combo_box("numberformat"))
1933 , m_xEntryOutlineLevelFT(m_xBuilder->weld_label("entryoutlinelevelft"))
1934 , m_xEntryOutlineLevelNF(m_xBuilder->weld_spin_button("entryoutlinelevel"))
1935 , m_xFillCharFT(m_xBuilder->weld_label("fillcharft"))
1936 , m_xFillCharCB(m_xBuilder->weld_combo_box("fillchar"))
1937 , m_xTabPosFT(m_xBuilder->weld_label("tabstopposft"))
1938 , m_xTabPosMF(m_xBuilder->weld_metric_spin_button("tabstoppos", FieldUnit::CM))
1939 , m_xAutoRightCB(m_xBuilder->weld_check_button("alignright"))
1940 , m_xFormatFrame(m_xBuilder->weld_widget("formatframe"))
1941 , m_xMainEntryStyleFT(m_xBuilder->weld_label("mainstyleft"))
1942 , m_xMainEntryStyleLB(m_xBuilder->weld_combo_box("mainstyle"))
1943 , m_xAlphaDelimCB(m_xBuilder->weld_check_button("alphadelim"))
1944 , m_xCommaSeparatedCB(m_xBuilder->weld_check_button("commasep"))
1945 , m_xRelToStyleCB(m_xBuilder->weld_check_button("reltostyle"))
1946 , m_xSortingFrame(m_xBuilder->weld_widget("sortingframe"))
1947 , m_xSortDocPosRB(m_xBuilder->weld_radio_button("sortpos"))
1948 , m_xSortContentRB(m_xBuilder->weld_radio_button("sortcontents"))
1949 , m_xSortKeyFrame(m_xBuilder->weld_widget("sortkeyframe"))
1950 , m_xFirstKeyLB(m_xBuilder->weld_combo_box("key1lb"))
1951 , m_xFirstSortUpRB(m_xBuilder->weld_toggle_button("up1cb"))
1952 , m_xFirstSortDownRB(m_xBuilder->weld_toggle_button("down1cb"))
1953 , m_xSecondKeyLB(m_xBuilder->weld_combo_box("key2lb"))
1954 , m_xSecondSortUpRB(m_xBuilder->weld_toggle_button("up2cb"))
1955 , m_xSecondSortDownRB(m_xBuilder->weld_toggle_button("down2cb"))
1956 , m_xThirdKeyLB(m_xBuilder->weld_combo_box("key3lb"))
1957 , m_xThirdSortUpRB(m_xBuilder->weld_toggle_button("up3cb"))
1958 , m_xThirdSortDownRB(m_xBuilder->weld_toggle_button("down3cb"))
1959 , m_xTokenWIN(new SwTokenWindow(m_xBuilder->weld_container("token")))
1961 const OUString sNoCharSortKey(SwResId(STR_NOSORTKEY));
1963 m_sAuthTypeStr = m_xTypeFT->get_label();
1964 m_sLevelStr = m_xLevelFT->get_label();
1965 m_xAuthFieldsLB->make_sorted();
1966 m_xTokenWIN->SetTabPage(this);
1968 m_aLastTOXType.eType = TOXTypes(USHRT_MAX);
1969 m_aLastTOXType.nIndex = 0;
1971 SetExchangeSupport();
1972 m_xEntryNoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1973 m_xEntryPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1974 m_xChapterInfoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1975 m_xPageNoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1976 m_xTabPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1977 m_xHyperLinkPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
1978 m_xEditStylePB->connect_clicked(LINK(this, SwTOXEntryTabPage, EditStyleHdl));
1979 m_xLevelLB->connect_changed(LINK(this, SwTOXEntryTabPage, LevelHdl));
1980 m_xTokenWIN->SetButtonSelectedHdl(LINK(this, SwTOXEntryTabPage, TokenSelectedHdl));
1981 m_xTokenWIN->SetModifyHdl(LINK(this, SwTOXEntryTabPage, ModifyHdl));
1982 m_xCharStyleLB->connect_changed(LINK(this, SwTOXEntryTabPage, StyleSelectHdl));
1983 m_xCharStyleLB->append_text(m_sNoCharStyle);
1984 m_xChapterEntryLB->connect_changed(LINK(this, SwTOXEntryTabPage, ChapterInfoHdl));
1985 m_xEntryOutlineLevelNF->connect_value_changed(LINK(this, SwTOXEntryTabPage, ChapterInfoOutlineHdl));
1986 m_xNumberFormatLB->connect_changed(LINK(this, SwTOXEntryTabPage, NumberFormatHdl));
1988 m_xTabPosMF->connect_value_changed(LINK(this, SwTOXEntryTabPage, TabPosHdl));
1989 m_xFillCharCB->connect_changed(LINK(this, SwTOXEntryTabPage, FillCharHdl));
1990 m_xAutoRightCB->connect_toggled(LINK(this, SwTOXEntryTabPage, AutoRightHdl));
1991 m_xAuthInsertPB->connect_clicked(LINK(this, SwTOXEntryTabPage, RemoveInsertAuthHdl));
1992 m_xAuthRemovePB->connect_clicked(LINK(this, SwTOXEntryTabPage, RemoveInsertAuthHdl));
1993 m_xSortDocPosRB->connect_toggled(LINK(this, SwTOXEntryTabPage, SortKeyHdl));
1994 m_xSortContentRB->connect_toggled(LINK(this, SwTOXEntryTabPage, SortKeyHdl));
1995 m_xAllLevelsPB->connect_clicked(LINK(this, SwTOXEntryTabPage, AllLevelsHdl));
1997 m_xAlphaDelimCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
1998 m_xCommaSeparatedCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
1999 m_xRelToStyleCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
2001 m_xFirstSortUpRB->set_active(true);
2002 m_xSecondSortUpRB->set_active(true);
2003 m_xThirdSortUpRB->set_active(true);
2005 m_xFirstSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2006 m_xFirstSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2007 m_xSecondSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2008 m_xSecondSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2009 m_xThirdSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2010 m_xThirdSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
2012 FieldUnit aMetric = ::GetDfltMetric(false);
2013 ::SetFieldUnit(*m_xTabPosMF, aMetric);
2015 m_xSortDocPosRB->set_active(true);
2017 m_xFillCharCB->set_entry_max_length(1);
2018 m_xFillCharCB->append_text(OUString(' '));
2019 m_xFillCharCB->append_text(OUString('.'));
2020 m_xFillCharCB->append_text(OUString('-'));
2021 m_xFillCharCB->append_text(OUString('_'));
2022 m_xFillCharCB->append_text(OUString(u'\x2024')); // ONE DOT LEADER
2023 m_xFillCharCB->append_text(OUString(u'\x2025')); // TWO DOT LEADER
2024 m_xFillCharCB->append_text(OUString(u'\x2026')); // HORIZONTAL ELLIPSIS
2026 m_xEditStylePB->set_sensitive(false);
2028 //fill the types in
2029 for (sal_uInt16 i = 0; i < AUTH_FIELD_END; ++i)
2031 OUString sId(OUString::number(i));
2032 m_xAuthFieldsLB->append(sId, SwResId(STR_AUTH_FIELD_ARY[i]));
2035 m_xFirstKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
2036 m_xSecondKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
2037 m_xThirdKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
2039 for (sal_uInt16 i = 0; i < AUTH_FIELD_END; ++i)
2041 const OUString sTmp(m_xAuthFieldsLB->get_text(i));
2042 const OUString sEntryData(m_xAuthFieldsLB->get_id(i));
2043 m_xFirstKeyLB->append(sEntryData, sTmp);
2044 m_xSecondKeyLB->append(sEntryData, sTmp);
2045 m_xThirdKeyLB->append(sEntryData, sTmp);
2047 m_xFirstKeyLB->set_active(0);
2048 m_xSecondKeyLB->set_active(0);
2049 m_xThirdKeyLB->set_active(0);
2051 // lock size of dialog. Determine the field box's widest possible
2052 // configuration (tdf#149186) before doing so.
2053 int nFieldBoxWidth = 0;
2054 for (int eType = TOX_CITATION; eType >= TOX_INDEX; --eType)
2056 ShowHideControls(eType);
2057 nFieldBoxWidth = std::max<int>(m_xFieldBox->get_preferred_size().Width(), nFieldBoxWidth);
2059 m_xFieldBox->set_size_request(nFieldBoxWidth, -1);
2060 Size aPrefSize(m_xContainer->get_preferred_size());
2061 m_xFieldBox->set_size_request(-1, -1);
2062 m_xContainer->set_size_request(aPrefSize.Width(), aPrefSize.Height());
2065 SwTOXEntryTabPage::~SwTOXEntryTabPage()
2067 m_xTokenWIN.reset();
2070 IMPL_LINK_NOARG(SwTOXEntryTabPage, ModifyClickHdl, weld::Toggleable&, void)
2072 OnModify(true);
2075 IMPL_LINK_NOARG(SwTOXEntryTabPage, ModifyHdl, LinkParamNone*, void)
2077 OnModify(false);
2080 IMPL_LINK(SwTOXEntryTabPage, ToggleHdl, weld::Toggleable&, rToggle, void)
2082 if (&rToggle == m_xFirstSortUpRB.get())
2083 m_xFirstSortDownRB->set_active(!m_xFirstSortUpRB->get_active());
2084 else if (&rToggle == m_xFirstSortDownRB.get())
2085 m_xFirstSortUpRB->set_active(!m_xFirstSortDownRB->get_active());
2086 else if (&rToggle == m_xSecondSortUpRB.get())
2087 m_xSecondSortDownRB->set_active(!m_xSecondSortUpRB->get_active());
2088 else if (&rToggle == m_xSecondSortDownRB.get())
2089 m_xSecondSortUpRB->set_active(!m_xSecondSortDownRB->get_active());
2090 else if (&rToggle == m_xThirdSortUpRB.get())
2091 m_xThirdSortDownRB->set_active(!m_xThirdSortUpRB->get_active());
2092 else if (&rToggle == m_xThirdSortDownRB.get())
2093 m_xThirdSortUpRB->set_active(!m_xThirdSortDownRB->get_active());
2096 // bAllLevels is used as signal to change all levels of the example
2097 void SwTOXEntryTabPage::OnModify(bool bAllLevels)
2099 UpdateDescriptor();
2101 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
2102 if (pTOXDlg)
2104 sal_uInt16 nCurLevel = m_xLevelLB->get_selected_index() + 1;
2105 if (m_aLastTOXType.eType == TOX_CONTENT && bAllLevels)
2106 nCurLevel = USHRT_MAX;
2107 pTOXDlg->CreateOrUpdateExample(
2108 pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_ENTRY, nCurLevel);
2112 bool SwTOXEntryTabPage::FillItemSet( SfxItemSet* )
2114 // nothing to do
2115 return true;
2118 void SwTOXEntryTabPage::Reset( const SfxItemSet* )
2120 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
2121 const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
2122 m_pCurrentForm = pTOXDlg->GetForm(aCurType);
2123 if(TOX_INDEX == aCurType.eType)
2125 SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
2126 const OUString& sMainEntryCharStyle = rDesc.GetMainEntryCharStyle();
2127 if(!sMainEntryCharStyle.isEmpty())
2129 if (m_xMainEntryStyleLB->find_text(sMainEntryCharStyle) == -1)
2130 m_xMainEntryStyleLB->append_text(sMainEntryCharStyle);
2131 m_xMainEntryStyleLB->set_active_text(sMainEntryCharStyle);
2133 else
2134 m_xMainEntryStyleLB->set_active_text(m_sNoCharStyle);
2135 m_xAlphaDelimCB->set_active( bool(rDesc.GetIndexOptions() & SwTOIOptions::AlphaDelimiter) );
2137 m_xRelToStyleCB->set_active(m_pCurrentForm->IsRelTabPos());
2138 m_xCommaSeparatedCB->set_active(m_pCurrentForm->IsCommaSeparated());
2141 void SwTOXEntryTabPage::ShowHideControls(int eType)
2143 bool bToxIsAuthorities = TOX_AUTHORITIES == eType;
2144 bool bToxIsIndex = TOX_INDEX == eType;
2145 bool bToxIsContent = TOX_CONTENT == eType;
2146 bool bToxSupportsLinks = TOX_CONTENT == eType ||
2147 TOX_ILLUSTRATIONS == eType ||
2148 TOX_TABLES == eType ||
2149 TOX_OBJECTS == eType ||
2150 TOX_USER == eType;
2152 //show or hide controls
2153 m_xEntryNoPB->set_visible(bToxIsContent);
2154 m_xHyperLinkPB->set_visible(bToxSupportsLinks);
2155 m_xRelToStyleCB->set_visible(!bToxIsAuthorities);
2156 m_xChapterInfoPB->set_visible(!bToxIsContent && !bToxIsAuthorities);
2157 m_xEntryPB->set_visible(!bToxIsAuthorities);
2158 m_xPageNoPB->set_visible(!bToxIsAuthorities);
2159 m_xAuthFieldsLB->set_visible(bToxIsAuthorities);
2160 m_xAuthInsertPB->set_visible(bToxIsAuthorities);
2161 m_xAuthRemovePB->set_visible(bToxIsAuthorities);
2163 m_xFormatFrame->set_visible(!bToxIsAuthorities);
2165 m_xSortingFrame->set_visible(bToxIsAuthorities);
2166 m_xSortKeyFrame->set_visible(bToxIsAuthorities);
2168 m_xMainEntryStyleFT->set_visible(bToxIsIndex);
2169 m_xMainEntryStyleLB->set_visible(bToxIsIndex);
2170 m_xAlphaDelimCB->set_visible(bToxIsIndex);
2171 m_xCommaSeparatedCB->set_visible(bToxIsIndex);
2174 void SwTOXEntryTabPage::ActivatePage( const SfxItemSet& /*rSet*/)
2176 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
2177 const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
2179 m_pCurrentForm = pTOXDlg->GetForm(aCurType);
2180 if( !( m_aLastTOXType == aCurType ))
2182 bool bToxIsAuthorities = TOX_AUTHORITIES == aCurType.eType;
2183 bool bToxIsIndex = TOX_INDEX == aCurType.eType;
2185 m_xLevelLB->clear();
2186 for(sal_uInt16 i = 1; i < m_pCurrentForm->GetFormMax(); i++)
2188 if(bToxIsAuthorities)
2189 m_xLevelLB->append_text( SwAuthorityFieldType::GetAuthTypeName(
2190 static_cast<ToxAuthorityType>(i - 1)) );
2191 else if( bToxIsIndex )
2193 if(i == 1)
2194 m_xLevelLB->append_text( m_sDelimStr );
2195 else
2196 m_xLevelLB->append_text( OUString::number(i - 1) );
2198 else
2199 m_xLevelLB->append_text(OUString::number(i));
2201 if(bToxIsAuthorities)
2203 SwWrtShell& rSh = pTOXDlg->GetWrtShell();
2204 const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
2205 rSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
2206 if(pFType)
2208 if(pFType->IsSortByDocument())
2209 m_xSortDocPosRB->set_active(true);
2210 else
2212 m_xSortContentRB->set_active(true);
2213 const sal_uInt16 nKeyCount = pFType->GetSortKeyCount();
2214 if(0 < nKeyCount)
2216 const SwTOXSortKey* pKey = pFType->GetSortKey(0);
2217 m_xFirstKeyLB->set_active_id(OUString::number(pKey->eField));
2218 m_xFirstSortUpRB->set_active(pKey->bSortAscending);
2219 m_xFirstSortDownRB->set_active(!pKey->bSortAscending);
2221 if(1 < nKeyCount)
2223 const SwTOXSortKey* pKey = pFType->GetSortKey(1);
2224 m_xSecondKeyLB->set_active_id(OUString::number(pKey->eField));
2225 m_xSecondSortUpRB->set_active(pKey->bSortAscending);
2226 m_xSecondSortDownRB->set_active(!pKey->bSortAscending);
2228 if(2 < nKeyCount)
2230 const SwTOXSortKey* pKey = pFType->GetSortKey(2);
2231 m_xThirdKeyLB->set_active_id(OUString::number(pKey->eField));
2232 m_xThirdSortUpRB->set_active(pKey->bSortAscending);
2233 m_xThirdSortDownRB->set_active(!pKey->bSortAscending);
2237 SortKeyHdl(m_xSortDocPosRB->get_active() ? *m_xSortDocPosRB : *m_xSortContentRB);
2238 m_xLevelFT->set_label(m_sAuthTypeStr);
2240 else
2241 m_xLevelFT->set_label(m_sLevelStr);
2243 m_xLevelLB->select(bToxIsIndex ? 1 : 0);
2245 //show or hide controls
2246 ShowHideControls(aCurType.eType);
2248 m_aLastTOXType = aCurType;
2250 //invalidate PatternWindow
2251 m_xTokenWIN->SetInvalid();
2252 LevelHdl(*m_xLevelLB);
2255 void SwTOXEntryTabPage::UpdateDescriptor()
2257 WriteBackLevel();
2258 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
2259 SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(m_aLastTOXType);
2260 if(TOX_INDEX == m_aLastTOXType.eType)
2262 const OUString sTemp(m_xMainEntryStyleLB->get_active_text());
2263 rDesc.SetMainEntryCharStyle(m_sNoCharStyle == sTemp ? OUString(): sTemp);
2264 SwTOIOptions nIdxOptions = rDesc.GetIndexOptions() & ~SwTOIOptions::AlphaDelimiter;
2265 if (m_xAlphaDelimCB->get_active())
2266 nIdxOptions |= SwTOIOptions::AlphaDelimiter;
2267 rDesc.SetIndexOptions(nIdxOptions);
2269 else if (TOX_AUTHORITIES == m_aLastTOXType.eType)
2271 rDesc.SetSortByDocument(m_xSortDocPosRB->get_active());
2272 SwTOXSortKey aKey1, aKey2, aKey3;
2273 aKey1.eField = static_cast<ToxAuthorityField>(m_xFirstKeyLB->get_active_id().toInt32());
2274 aKey1.bSortAscending = m_xFirstSortUpRB->get_active();
2275 aKey2.eField = static_cast<ToxAuthorityField>(m_xSecondKeyLB->get_active_id().toInt32());
2276 aKey2.bSortAscending = m_xSecondSortUpRB->get_active();
2277 aKey3.eField = static_cast<ToxAuthorityField>(m_xThirdKeyLB->get_active_id().toInt32());
2278 aKey3.bSortAscending = m_xThirdSortUpRB->get_active();
2280 rDesc.SetSortKeys(aKey1, aKey2, aKey3);
2282 SwForm* pCurrentForm = pTOXDlg->GetForm(m_aLastTOXType);
2283 if (m_xRelToStyleCB->get_visible())
2284 pCurrentForm->SetRelTabPos(m_xRelToStyleCB->get_active());
2285 if (m_xCommaSeparatedCB->get_visible())
2286 pCurrentForm->SetCommaSeparated(m_xCommaSeparatedCB->get_active());
2289 DeactivateRC SwTOXEntryTabPage::DeactivatePage( SfxItemSet* /*pSet*/)
2291 UpdateDescriptor();
2292 return DeactivateRC::LeavePage;
2295 std::unique_ptr<SfxTabPage> SwTOXEntryTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
2297 return std::make_unique<SwTOXEntryTabPage>(pPage, pController, *rAttrSet);
2300 IMPL_LINK_NOARG(SwTOXEntryTabPage, EditStyleHdl, weld::Button&, void)
2302 if (m_xCharStyleLB->get_active() != -1)
2304 SfxStringItem aStyle(SID_STYLE_EDIT, m_xCharStyleLB->get_active_text());
2305 SfxUInt16Item aFamily(SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Char));
2306 static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell().
2307 GetView().GetViewFrame().GetDispatcher()->ExecuteList(SID_STYLE_EDIT,
2308 SfxCallMode::SYNCHRON,
2309 { &aStyle, &aFamily });
2313 IMPL_LINK(SwTOXEntryTabPage, RemoveInsertAuthHdl, weld::Button&, rButton, void)
2315 bool bInsert = &rButton == m_xAuthInsertPB.get();
2316 if(bInsert)
2318 sal_Int32 nSelPos = m_xAuthFieldsLB->get_active();
2319 const OUString sToInsert(m_xAuthFieldsLB->get_active_text());
2320 SwFormToken aInsert(TOKEN_AUTHORITY);
2321 aInsert.nAuthorityField = m_xAuthFieldsLB->get_id(nSelPos).toUInt32();
2322 m_xTokenWIN->InsertAtSelection(aInsert);
2323 m_xAuthFieldsLB->remove_text(sToInsert);
2324 m_xAuthFieldsLB->set_active(nSelPos ? nSelPos - 1 : 0);
2326 else
2328 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2329 OSL_ENSURE(WindowType::EDIT != pCtrl->GetType(), "Remove should be disabled");
2330 if (WindowType::EDIT != pCtrl->GetType())
2332 //fill it into the ListBox
2333 const SwFormToken& rToken = static_cast<SwTOXButton*>(pCtrl)->GetFormToken();
2334 PreTokenButtonRemoved(rToken);
2335 m_xTokenWIN->RemoveControl(static_cast<SwTOXButton*>(pCtrl));
2338 ModifyHdl(nullptr);
2341 void SwTOXEntryTabPage::PreTokenButtonRemoved(const SwFormToken& rToken)
2343 //fill it into the ListBox
2344 sal_uInt32 nData = rToken.nAuthorityField;
2345 m_xAuthFieldsLB->append(OUString::number(nData), SwResId(STR_AUTH_FIELD_ARY[nData]));
2348 void SwTOXEntryTabPage::SetFocus2theAllBtn()
2350 m_xAllLevelsPB->grab_focus();
2353 // This function initializes the default value in the Token
2354 // put here the UI dependent initializations
2355 IMPL_LINK(SwTOXEntryTabPage, InsertTokenHdl, weld::Button&, rBtn, void)
2357 FormTokenType eTokenType = TOKEN_ENTRY_NO;
2358 OUString sCharStyle;
2359 sal_uInt16 nChapterFormat = CF_NUMBER; // i89791
2360 if (&rBtn == m_xEntryNoPB.get())
2362 eTokenType = TOKEN_ENTRY_NO;
2364 else if (&rBtn == m_xEntryPB.get())
2366 if( TOX_CONTENT == m_pCurrentForm->GetTOXType() )
2368 eTokenType = TOKEN_ENTRY_TEXT;
2370 else
2372 eTokenType = TOKEN_ENTRY;
2375 else if (&rBtn == m_xChapterInfoPB.get())
2377 eTokenType = TOKEN_CHAPTER_INFO;
2378 nChapterFormat = CF_NUM_NOPREPST_TITLE; // i89791
2380 else if (&rBtn == m_xPageNoPB.get())
2382 eTokenType = TOKEN_PAGE_NUMS;
2384 else if (&rBtn == m_xHyperLinkPB.get())
2386 eTokenType = TOKEN_LINK_START;
2387 sCharStyle = SwResId(STR_POOLCHR_TOXJUMP);
2389 else if (&rBtn == m_xTabPB.get())
2391 eTokenType = TOKEN_TAB_STOP;
2393 SwFormToken aInsert(eTokenType);
2394 aInsert.sCharStyleName = sCharStyle;
2395 aInsert.nTabStopPosition = 0;
2396 aInsert.nChapterFormat = nChapterFormat; // i89791
2397 m_xTokenWIN->InsertAtSelection(aInsert);
2398 ModifyHdl(nullptr);
2401 IMPL_LINK_NOARG(SwTOXEntryTabPage, AllLevelsHdl, weld::Button&, void)
2403 //get current level
2404 //write it into all levels
2405 if(m_xTokenWIN->IsValid())
2407 const OUString sNewToken = m_xTokenWIN->GetPattern();
2408 for(sal_uInt16 i = 1; i < m_pCurrentForm->GetFormMax(); i++)
2409 m_pCurrentForm->SetPattern(i, sNewToken);
2411 OnModify(true);
2415 void SwTOXEntryTabPage::WriteBackLevel()
2417 if(m_xTokenWIN->IsValid())
2419 const OUString sNewToken = m_xTokenWIN->GetPattern();
2420 const sal_uInt16 nLastLevel = m_xTokenWIN->GetLastLevel();
2421 if(nLastLevel != USHRT_MAX)
2422 m_pCurrentForm->SetPattern(nLastLevel + 1, sNewToken);
2426 IMPL_LINK(SwTOXEntryTabPage, LevelHdl, weld::TreeView&, rBox, void)
2428 if(m_bInLevelHdl)
2429 return;
2430 m_bInLevelHdl = true;
2431 WriteBackLevel();
2433 const sal_uInt16 nLevel = rBox.get_selected_index();
2434 m_xTokenWIN->SetForm(*m_pCurrentForm, nLevel);
2435 if(TOX_AUTHORITIES == m_pCurrentForm->GetTOXType())
2437 //fill the types in
2438 m_xAuthFieldsLB->clear();
2439 for( sal_uInt32 i = 0; i < AUTH_FIELD_END; i++)
2441 m_xAuthFieldsLB->append(OUString::number(i), SwResId(STR_AUTH_FIELD_ARY[i]));
2444 // #i21237#
2445 SwFormTokens aPattern = m_pCurrentForm->GetPattern(nLevel + 1);
2447 for(const auto& aToken : aPattern)
2449 if(TOKEN_AUTHORITY == aToken.eTokenType)
2451 sal_uInt32 nSearch = aToken.nAuthorityField;
2452 int nLstBoxPos = m_xAuthFieldsLB->find_id(OUString::number(nSearch));
2453 OSL_ENSURE(nLstBoxPos != -1, "Entry not found?");
2454 m_xAuthFieldsLB->remove(nLstBoxPos);
2457 m_xAuthFieldsLB->set_active(0);
2459 m_bInLevelHdl = false;
2460 rBox.grab_focus();
2463 IMPL_LINK_NOARG(SwTOXEntryTabPage, SortKeyHdl, weld::Toggleable&, void)
2465 bool bEnable = m_xSortContentRB->get_active();
2466 m_xSortKeyFrame->set_sensitive(bEnable);
2469 IMPL_LINK(SwTOXEntryTabPage, TokenSelectedHdl, SwFormToken&, rToken, void)
2471 if (!rToken.sCharStyleName.isEmpty())
2472 m_xCharStyleLB->set_active_text(rToken.sCharStyleName);
2473 else
2474 m_xCharStyleLB->set_active_text(m_sNoCharStyle);
2476 const OUString sEntry = m_xCharStyleLB->get_active_text();
2477 m_xEditStylePB->set_sensitive(sEntry != m_sNoCharStyle);
2479 if(rToken.eTokenType == TOKEN_CHAPTER_INFO)
2481 //---> i89791
2482 switch(rToken.nChapterFormat)
2484 default:
2485 m_xChapterEntryLB->set_active(-1);//to alert the user
2486 break;
2487 case CF_NUM_NOPREPST_TITLE:
2488 m_xChapterEntryLB->set_active(0);
2489 break;
2490 case CF_TITLE:
2491 m_xChapterEntryLB->set_active(1);
2492 break;
2493 case CF_NUMBER_NOPREPST:
2494 m_xChapterEntryLB->set_active(2);
2495 break;
2497 //i53420
2499 m_xEntryOutlineLevelNF->set_value(rToken.nOutlineLevel);
2502 //i53420
2503 if(rToken.eTokenType == TOKEN_ENTRY_NO)
2505 m_xEntryOutlineLevelNF->set_value(rToken.nOutlineLevel);
2506 const sal_uInt16 nFormat =
2507 rToken.nChapterFormat == CF_NUM_NOPREPST_TITLE ? 1 : 0;
2508 m_xNumberFormatLB->set_active(nFormat);
2511 bool bTabStop = TOKEN_TAB_STOP == rToken.eTokenType;
2512 m_xFillCharFT->set_visible(bTabStop);
2513 m_xFillCharCB->set_visible(bTabStop);
2514 m_xTabPosFT->set_visible(bTabStop);
2515 m_xTabPosMF->set_visible(bTabStop);
2516 m_xAutoRightCB->set_visible(bTabStop);
2517 m_xAutoRightCB->set_sensitive(bTabStop);
2518 if(bTabStop)
2520 m_xTabPosMF->set_value(m_xTabPosMF->normalize(rToken.nTabStopPosition), FieldUnit::TWIP);
2521 m_xAutoRightCB->set_active(SvxTabAdjust::End == rToken.eTabAlign);
2522 m_xFillCharCB->set_entry_text(OUString(rToken.cTabFillChar));
2523 m_xTabPosFT->set_sensitive(!m_xAutoRightCB->get_active());
2524 m_xTabPosMF->set_sensitive(!m_xAutoRightCB->get_active());
2526 else
2528 m_xTabPosMF->set_sensitive(false);
2531 bool bIsChapterInfo = rToken.eTokenType == TOKEN_CHAPTER_INFO;
2532 bool bIsEntryNumber = rToken.eTokenType == TOKEN_ENTRY_NO;
2533 m_xChapterEntryFT->set_visible( bIsChapterInfo );
2534 m_xChapterEntryLB->set_visible( bIsChapterInfo );
2535 m_xEntryOutlineLevelFT->set_visible( bIsChapterInfo || bIsEntryNumber );
2536 m_xEntryOutlineLevelNF->set_visible( bIsChapterInfo || bIsEntryNumber );
2537 m_xNumberFormatFT->set_visible( bIsEntryNumber );
2538 m_xNumberFormatLB->set_visible( bIsEntryNumber );
2540 //now enable the visible buttons
2541 //- inserting the same type of control is not allowed
2542 //- some types of controls can only appear once (EntryText EntryNumber)
2544 if (m_xEntryNoPB->get_visible())
2546 m_xEntryNoPB->set_sensitive(TOKEN_ENTRY_NO != rToken.eTokenType );
2548 if (m_xEntryPB->get_visible())
2550 m_xEntryPB->set_sensitive(TOKEN_ENTRY_TEXT != rToken.eTokenType &&
2551 !m_xTokenWIN->Contains(TOKEN_ENTRY_TEXT)
2552 && !m_xTokenWIN->Contains(TOKEN_ENTRY));
2555 if (m_xChapterInfoPB->get_visible())
2557 m_xChapterInfoPB->set_sensitive(TOKEN_CHAPTER_INFO != rToken.eTokenType);
2559 if (m_xPageNoPB->get_visible())
2561 m_xPageNoPB->set_sensitive(TOKEN_PAGE_NUMS != rToken.eTokenType &&
2562 !m_xTokenWIN->Contains(TOKEN_PAGE_NUMS));
2564 if (m_xTabPB->get_visible())
2566 m_xTabPB->set_sensitive(!bTabStop);
2568 if (m_xHyperLinkPB->get_visible())
2570 m_xHyperLinkPB->set_sensitive(TOKEN_LINK_START != rToken.eTokenType &&
2571 TOKEN_LINK_END != rToken.eTokenType);
2573 //table of authorities
2574 if (m_xAuthInsertPB->get_visible())
2576 bool bText = TOKEN_TEXT == rToken.eTokenType;
2577 m_xAuthInsertPB->set_sensitive(bText && !m_xAuthFieldsLB->get_active_text().isEmpty());
2578 m_xAuthRemovePB->set_sensitive(!bText);
2582 IMPL_LINK(SwTOXEntryTabPage, StyleSelectHdl, weld::ComboBox&, rBox, void)
2584 OUString sEntry = rBox.get_active_text();
2585 const sal_uInt16 nId = rBox.get_active_id().toUInt32();
2586 const bool bEqualsNoCharStyle = sEntry == m_sNoCharStyle;
2587 m_xEditStylePB->set_sensitive(!bEqualsNoCharStyle);
2588 if (bEqualsNoCharStyle)
2589 sEntry.clear();
2590 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2591 OSL_ENSURE(pCtrl, "no active control?");
2592 if(pCtrl)
2594 if(WindowType::EDIT == pCtrl->GetType())
2595 static_cast<SwTOXEdit*>(pCtrl)->SetCharStyleName(sEntry, nId);
2596 else
2597 static_cast<SwTOXButton*>(pCtrl)->SetCharStyleName(sEntry, nId);
2600 ModifyHdl(nullptr);
2603 IMPL_LINK(SwTOXEntryTabPage, ChapterInfoHdl, weld::ComboBox&, rBox, void)
2605 int nPos = rBox.get_active();
2606 if (nPos != -1)
2608 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2609 OSL_ENSURE(pCtrl, "no active control?");
2610 if(pCtrl && WindowType::EDIT != pCtrl->GetType())
2611 static_cast<SwTOXButton*>(pCtrl)->SetChapterInfo(nPos);
2612 ModifyHdl(nullptr);
2616 IMPL_LINK(SwTOXEntryTabPage, ChapterInfoOutlineHdl, weld::SpinButton&, rEdit, void)
2618 const sal_uInt16 nLevel = rEdit.get_value();
2620 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2621 OSL_ENSURE(pCtrl, "no active control?");
2622 if(pCtrl && WindowType::EDIT != pCtrl->GetType())
2623 static_cast<SwTOXButton*>(pCtrl)->SetOutlineLevel(nLevel);
2625 ModifyHdl(nullptr);
2628 IMPL_LINK(SwTOXEntryTabPage, NumberFormatHdl, weld::ComboBox&, rBox, void)
2630 const sal_Int32 nPos = rBox.get_active();
2631 if (nPos != -1)
2633 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2634 OSL_ENSURE(pCtrl, "no active control?");
2635 if(pCtrl && WindowType::EDIT != pCtrl->GetType())
2637 static_cast<SwTOXButton*>(pCtrl)->SetEntryNumberFormat(nPos);//i89791
2639 ModifyHdl(nullptr);
2643 IMPL_LINK(SwTOXEntryTabPage, TabPosHdl, weld::MetricSpinButton&, rEdit, void)
2645 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2646 OSL_ENSURE(pCtrl && WindowType::EDIT != pCtrl->GetType() &&
2647 TOKEN_TAB_STOP == static_cast<SwTOXButton*>(pCtrl)->GetFormToken().eTokenType,
2648 "no active style::TabStop control?");
2649 if( pCtrl && WindowType::EDIT != pCtrl->GetType() )
2651 static_cast<SwTOXButton*>(pCtrl)->SetTabPosition( static_cast< SwTwips >(
2652 rEdit.denormalize(rEdit.get_value(FieldUnit::TWIP))));
2654 ModifyHdl(nullptr);
2657 IMPL_LINK(SwTOXEntryTabPage, FillCharHdl, weld::ComboBox&, rBox, void)
2659 SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
2660 OSL_ENSURE(pCtrl && WindowType::EDIT != pCtrl->GetType() &&
2661 TOKEN_TAB_STOP == static_cast<SwTOXButton*>(pCtrl)->GetFormToken().eTokenType,
2662 "no active style::TabStop control?");
2663 if (pCtrl && WindowType::EDIT != pCtrl->GetType())
2665 sal_Unicode cSet;
2666 if (!rBox.get_active_text().isEmpty())
2667 cSet = rBox.get_active_text()[0];
2668 else
2669 cSet = ' ';
2670 static_cast<SwTOXButton*>(pCtrl)->SetFillChar( cSet );
2672 ModifyHdl(nullptr);
2675 IMPL_LINK(SwTOXEntryTabPage, AutoRightHdl, weld::Toggleable&, rBox, void)
2677 //the most right style::TabStop is usually right aligned
2678 SwTOXWidget* pCurCtrl = m_xTokenWIN->GetActiveControl();
2679 OSL_ENSURE(WindowType::EDIT != pCurCtrl->GetType() &&
2680 static_cast<SwTOXButton*>(pCurCtrl)->GetFormToken().eTokenType == TOKEN_TAB_STOP,
2681 "no style::TabStop selected!");
2683 const SwFormToken& rToken = static_cast<SwTOXButton*>(pCurCtrl)->GetFormToken();
2684 bool bChecked = rBox.get_active();
2685 if(rToken.eTokenType == TOKEN_TAB_STOP)
2686 static_cast<SwTOXButton*>(pCurCtrl)->SetTabAlign(
2687 bChecked ? SvxTabAdjust::End : SvxTabAdjust::Left);
2688 m_xTabPosFT->set_sensitive(!bChecked);
2689 m_xTabPosMF->set_sensitive(!bChecked);
2690 ModifyHdl(nullptr);
2693 void SwTOXEntryTabPage::SetWrtShell(SwWrtShell& rSh)
2695 SwDocShell* pDocSh = rSh.GetView().GetDocShell();
2696 ::FillCharStyleListBox(*m_xCharStyleLB, pDocSh, true, true);
2697 const OUString sDefault(SwResId(STR_POOLCHR_STANDARD));
2698 for (int i = 0, nCount = m_xCharStyleLB->get_count(); i < nCount; ++i)
2700 const OUString sEntry = m_xCharStyleLB->get_text(i);
2701 if(sDefault != sEntry)
2703 m_xMainEntryStyleLB->append(m_xCharStyleLB->get_id(i), sEntry);
2706 m_xMainEntryStyleLB->set_active_text(SwStyleNameMapper::GetUIName(
2707 RES_POOLCHR_IDX_MAIN_ENTRY, OUString()));
2710 const TranslateId STR_TOKEN_ARY[] =
2712 STR_TOKEN_ENTRY_NO,
2713 STR_TOKEN_ENTRY, //mapped from original STR_TOKEN_ENTRY_TEXT,
2714 STR_TOKEN_ENTRY,
2715 STR_TOKEN_TAB_STOP,
2717 STR_TOKEN_PAGE_NUMS,
2718 STR_TOKEN_CHAPTER_INFO,
2719 STR_TOKEN_LINK_START,
2720 STR_TOKEN_LINK_END,
2721 STR_TOKEN_AUTHORITY
2724 const TranslateId STR_TOKEN_HELP_ARY[] =
2726 STR_TOKEN_HELP_ENTRY_NO,
2727 STR_TOKEN_HELP_ENTRY, // mapped from original STR_TOKEN_HELP_ENTRY_TEXT,
2728 STR_TOKEN_HELP_ENTRY,
2729 STR_TOKEN_HELP_TAB_STOP,
2730 STR_TOKEN_HELP_TEXT,
2731 STR_TOKEN_HELP_PAGE_NUMS,
2732 STR_TOKEN_HELP_CHAPTER_INFO,
2733 STR_TOKEN_HELP_LINK_START,
2734 STR_TOKEN_HELP_LINK_END,
2735 STR_TOKEN_HELP_AUTHORITY
2738 SwTokenWindow::SwTokenWindow(std::unique_ptr<weld::Container> xParent)
2739 : m_pForm(nullptr)
2740 , m_nLevel(0)
2741 , m_bValid(false)
2742 , m_sCharStyle(SwResId(STR_CHARSTYLE))
2743 , m_pActiveCtrl(nullptr)
2744 , m_aAdjustPositionsIdle("SwTokenWindow m_aAdjustPositionsIdle")
2745 , m_pParent(nullptr)
2746 , m_xParentWidget(std::move(xParent))
2747 , m_xBuilder(Application::CreateBuilder(m_xParentWidget.get(), "modules/swriter/ui/tokenwidget.ui"))
2748 , m_xContainer(m_xBuilder->weld_container("TokenWidget"))
2749 , m_xLeftScrollWin(m_xBuilder->weld_button("left"))
2750 , m_xCtrlParentWin(m_xBuilder->weld_container("ctrl"))
2751 , m_xScrollWin(m_xBuilder->weld_scrolled_window("scrollwin"))
2752 , m_xRightScrollWin(m_xBuilder->weld_button("right"))
2754 m_xScrollWin->connect_hadjustment_changed(LINK(this, SwTokenWindow, ScrollHdl));
2755 m_xCtrlParentWin->connect_size_allocate(LINK(this, SwTokenWindow, AdjustPositionsHdl));
2757 for (sal_uInt32 i = 0; i < TOKEN_END; ++i)
2759 TranslateId pTextId = STR_TOKEN_ARY[i];
2760 if (pTextId)
2761 m_aButtonTexts[i] = SwResId(pTextId);
2763 TranslateId pHelpId = STR_TOKEN_HELP_ARY[i];
2764 m_aButtonHelpTexts[i] = SwResId(pHelpId);
2767 m_sAccessibleName = SwResId(STR_STRUCTURE);
2768 m_sAdditionalAccnameString1 = SwResId(STR_ADDITIONAL_ACCNAME_STRING1);
2769 m_sAdditionalAccnameString2 = SwResId(STR_ADDITIONAL_ACCNAME_STRING2);
2770 m_sAdditionalAccnameString3 = SwResId(STR_ADDITIONAL_ACCNAME_STRING3);
2772 Link<weld::Button&,void> aLink(LINK(this, SwTokenWindow, ScrollBtnHdl));
2773 m_xLeftScrollWin->connect_clicked(aLink);
2774 m_xRightScrollWin->connect_clicked(aLink);
2777 SwTokenWindow::~SwTokenWindow()
2781 void SwTokenWindow::SetForm(SwForm& rForm, sal_uInt16 nL)
2783 SetActiveControl(nullptr);
2784 m_bValid = true;
2786 if (m_pForm)
2788 //apply current level settings to the form
2789 m_aControlList.clear();
2792 m_nLevel = nL;
2793 m_pForm = &rForm;
2794 //now the display
2795 if(m_nLevel < MAXLEVEL || rForm.GetTOXType() == TOX_AUTHORITIES)
2797 // #i21237#
2798 SwFormTokens aPattern = m_pForm->GetPattern(m_nLevel + 1);
2799 bool bLastWasText = false; //assure alternating text - code - text
2801 SwTOXWidget* pSetActiveControl = nullptr;
2802 for (const auto& aToken : aPattern) // #i21237#
2804 if(TOKEN_TEXT == aToken.eTokenType)
2806 SAL_WARN_IF(bLastWasText, "sw", "text following text is invalid");
2807 SwTOXWidget* pCtrl = InsertItem(aToken.sText, aToken);
2808 bLastWasText = true;
2809 if (!GetActiveControl())
2810 SetActiveControl(pCtrl);
2812 else
2814 if( !bLastWasText )
2816 SwFormToken aTemp(TOKEN_TEXT);
2817 SwTOXWidget* pCtrl = InsertItem(OUString(), aTemp);
2818 if(!pSetActiveControl)
2819 pSetActiveControl = pCtrl;
2822 OUString sForm;
2823 switch( aToken.eTokenType )
2825 case TOKEN_ENTRY_NO: sForm = SwForm::GetFormEntryNum(); break;
2826 case TOKEN_ENTRY_TEXT: sForm = SwForm::GetFormEntryText(); break;
2827 case TOKEN_ENTRY: sForm = SwForm::GetFormEntry(); break;
2828 case TOKEN_TAB_STOP: sForm = SwForm::GetFormTab(); break;
2829 case TOKEN_PAGE_NUMS: sForm = SwForm::GetFormPageNums(); break;
2830 case TOKEN_CHAPTER_INFO: sForm = SwForm::GetFormChapterMark(); break;
2831 case TOKEN_LINK_START: sForm = SwForm::GetFormLinkStt(); break;
2832 case TOKEN_LINK_END: sForm = SwForm::GetFormLinkEnd(); break;
2833 case TOKEN_AUTHORITY: sForm = SwForm::GetFormAuth(); break;
2834 default:; //prevent warning
2837 InsertItem( sForm, aToken );
2838 bLastWasText = false;
2841 if(!bLastWasText)
2843 SwFormToken aTemp(TOKEN_TEXT);
2844 SwTOXWidget* pCtrl = InsertItem(OUString(), aTemp);
2845 if(!pSetActiveControl)
2846 pSetActiveControl = pCtrl;
2848 SetActiveControl(pSetActiveControl);
2850 AdjustScrolling();
2853 void SwTokenWindow::SetActiveControl(SwTOXWidget* pSet)
2855 if (pSet == m_pActiveCtrl)
2856 return;
2858 m_pActiveCtrl = pSet;
2859 if( !m_pActiveCtrl )
2860 return;
2862 m_pActiveCtrl->GrabFocus();
2863 //it must be a SwTOXEdit
2864 const SwFormToken* pFToken;
2865 if( WindowType::EDIT == m_pActiveCtrl->GetType() )
2866 pFToken = &static_cast<SwTOXEdit*>(m_pActiveCtrl)->GetFormToken();
2867 else
2868 pFToken = &static_cast<SwTOXButton*>(m_pActiveCtrl)->GetFormToken();
2870 SwFormToken aTemp( *pFToken );
2871 m_aButtonSelectedHdl.Call( aTemp );
2874 SwTOXWidget* SwTokenWindow::InsertItem(const OUString& rText, const SwFormToken& rToken)
2876 SwTOXWidget* pRet = nullptr;
2878 if (TOKEN_TEXT == rToken.eTokenType)
2880 SwTOXEdit* pEdit = new SwTOXEdit(this, rToken);
2881 pEdit->set_grid_left_attach(m_aControlList.size());
2883 m_aControlList.emplace_back(pEdit);
2885 pEdit->SetText(rText);
2886 sal_uInt32 nIndex = GetControlIndex( TOKEN_TEXT );
2887 OUString strName(m_sAccessibleName + OUString::number(nIndex));
2888 if ( nIndex == 1 )
2890 /*Press left or right arrow to choose the structure controls*/
2891 strName += " (" + m_sAdditionalAccnameString2 + ", "
2892 /*Press Ctrl+Alt+A to move focus for more operations*/
2893 + m_sAdditionalAccnameString1 + ", "
2894 /*Press Ctrl+Alt+B to move focus back to the current structure control*/
2895 + m_sAdditionalAccnameString3 + ")";
2897 pEdit->SetAccessibleName(strName);
2898 pEdit->AdjustSize();
2899 pEdit->SetModifyHdl(LINK(this, SwTokenWindow, EditResize ));
2900 pEdit->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemHdl));
2901 pEdit->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusHdl));
2902 pEdit->Show();
2903 pRet = pEdit;
2905 else
2907 SwTOXButton* pButton = new SwTOXButton(this, rToken);
2908 pButton->set_grid_left_attach(m_aControlList.size());
2910 m_aControlList.emplace_back(pButton);
2912 pButton->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemBtnHdl));
2913 pButton->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusBtnHdl));
2915 if(TOKEN_AUTHORITY != rToken.eTokenType)
2916 pButton->SetText(m_aButtonTexts[rToken.eTokenType]);
2917 else
2919 //use the first two chars as symbol
2920 OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
2921 static_cast<ToxAuthorityField>(rToken.nAuthorityField)));
2922 pButton->SetText(sTmp.copy(0, 2));
2925 sal_uInt32 nIndex = GetControlIndex( rToken.eTokenType );
2926 OUString sAccName = m_aButtonHelpTexts[rToken.eTokenType];
2927 if ( nIndex )
2929 sAccName += " " + OUString::number(nIndex);
2931 pButton->SetAccessibleName( sAccName );
2933 pButton->Show();
2934 pRet = pButton;
2937 return pRet;
2940 void SwTokenWindow::InsertAtSelection(const SwFormToken& rToken)
2942 OSL_ENSURE(m_pActiveCtrl, "no active control!");
2944 if(!m_pActiveCtrl)
2945 return;
2947 SwFormToken aToInsertToken(rToken);
2949 if(TOKEN_LINK_START == aToInsertToken.eTokenType)
2951 //determine if start or end of hyperlink is appropriate
2952 //eventually change a following link start into a link end
2953 // groups of LS LE should be ignored
2954 // <insert>
2955 //LS <insert>
2956 //LE <insert>
2957 //<insert> LS
2958 //<insert> LE
2959 //<insert>
2960 bool bPreStartLinkFound = false;
2961 bool bPreEndLinkFound = false;
2963 const SwTOXWidget* pControl = nullptr;
2964 const SwTOXWidget* pExchange = nullptr;
2966 auto it = m_aControlList.cbegin();
2967 for( ; it != m_aControlList.cend() && m_pActiveCtrl != it->get(); ++it )
2969 pControl = it->get();
2971 if( WindowType::EDIT != pControl->GetType())
2973 const SwFormToken& rNewToken =
2974 static_cast<const SwTOXButton*>(pControl)->GetFormToken();
2976 if( TOKEN_LINK_START == rNewToken.eTokenType )
2978 bPreStartLinkFound = true;
2979 pExchange = nullptr;
2981 else if(TOKEN_LINK_END == rNewToken.eTokenType)
2983 if( bPreStartLinkFound )
2984 bPreStartLinkFound = false;
2985 else
2987 bPreEndLinkFound = false;
2988 pExchange = pControl;
2994 bool bPostLinkStartFound = false;
2996 if(!bPreStartLinkFound && !bPreEndLinkFound)
2998 for( ; it != m_aControlList.cend(); ++it )
3000 pControl = it->get();
3002 if( pControl != m_pActiveCtrl &&
3003 WindowType::EDIT != pControl->GetType())
3005 const SwFormToken& rNewToken =
3006 static_cast<const SwTOXButton*>(pControl)->GetFormToken();
3008 if( TOKEN_LINK_START == rNewToken.eTokenType )
3010 if(bPostLinkStartFound)
3011 break;
3012 bPostLinkStartFound = true;
3013 pExchange = pControl;
3015 else if(TOKEN_LINK_END == rNewToken.eTokenType )
3017 if(bPostLinkStartFound)
3019 bPostLinkStartFound = false;
3020 pExchange = nullptr;
3022 break;
3028 if(bPreStartLinkFound)
3030 aToInsertToken.eTokenType = TOKEN_LINK_END;
3031 aToInsertToken.sText = m_aButtonTexts[TOKEN_LINK_END];
3034 if(bPostLinkStartFound)
3036 OSL_ENSURE(pExchange, "no control to exchange?");
3037 if(pExchange)
3039 const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetLinkEnd();
3040 const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetText(m_aButtonTexts[TOKEN_LINK_END]);
3044 if(bPreEndLinkFound)
3046 OSL_ENSURE(pExchange, "no control to exchange?");
3048 if(pExchange)
3050 const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetLinkStart();
3051 const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetText(m_aButtonTexts[TOKEN_LINK_START]);
3056 //if the active control is text then insert a new button at the selection
3057 //else replace the button
3058 auto iterActive = std::find_if(m_aControlList.begin(), m_aControlList.end(),
3059 [this](const auto& rControl)
3061 SwTOXWidget* pCtrl = rControl.get();
3062 return pCtrl == m_pActiveCtrl;
3065 assert(iterActive != m_aControlList.end());
3066 if (iterActive == m_aControlList.end())
3067 return;
3069 if (WindowType::EDIT == m_pActiveCtrl->GetType())
3071 ++iterActive;
3073 int nStartPos, nEndPos;
3074 static_cast<SwTOXEdit*>(m_pActiveCtrl)->get_selection_bounds(nStartPos, nEndPos);
3076 const OUString sEditText = static_cast<SwTOXEdit*>(m_pActiveCtrl)->GetText();
3077 const OUString sLeft = sEditText.copy( 0, std::min(nStartPos, nEndPos) );
3078 const OUString sRight = sEditText.copy( std::max(nStartPos, nEndPos) );
3080 static_cast<SwTOXEdit*>(m_pActiveCtrl)->SetText(sLeft);
3081 static_cast<SwTOXEdit*>(m_pActiveCtrl)->AdjustSize();
3083 SwFormToken aTmpToken(TOKEN_TEXT);
3084 SwTOXEdit* pEdit = new SwTOXEdit(this, aTmpToken);
3085 iterActive = m_aControlList.emplace(iterActive, pEdit);
3087 pEdit->SetText(sRight);
3088 sal_uInt32 nIndex = GetControlIndex( TOKEN_TEXT );
3089 OUString strName(m_sAccessibleName + OUString::number(nIndex));
3090 if ( nIndex == 1)
3092 /*Press left or right arrow to choose the structure controls*/
3093 strName += " (" + m_sAdditionalAccnameString2 + ", "
3094 /*Press Ctrl+Alt+A to move focus for more operations*/
3095 + m_sAdditionalAccnameString1 + ", "
3096 /*Press Ctrl+Alt+B to move focus back to the current structure control*/
3097 + m_sAdditionalAccnameString3 + ")";
3099 pEdit->SetAccessibleName(strName);
3100 pEdit->AdjustSize();
3101 pEdit->SetModifyHdl(LINK(this, SwTokenWindow, EditResize ));
3102 pEdit->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemHdl));
3103 pEdit->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusHdl));
3104 pEdit->Show();
3106 else
3108 m_pActiveCtrl->Hide();
3109 m_pActiveCtrl = nullptr;
3110 iterActive = m_aControlList.erase(iterActive);
3113 //now the new button
3114 SwTOXButton* pButton = new SwTOXButton(this, aToInsertToken);
3115 m_aControlList.emplace(iterActive, pButton);
3117 pButton->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemBtnHdl));
3118 pButton->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusBtnHdl));
3120 if (TOKEN_AUTHORITY != aToInsertToken.eTokenType)
3122 pButton->SetText(m_aButtonTexts[aToInsertToken.eTokenType]);
3124 else
3126 //use the first two chars as symbol
3127 OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
3128 static_cast<ToxAuthorityField>(aToInsertToken.nAuthorityField)));
3129 pButton->SetText(sTmp.copy(0, 2));
3132 pButton->Check();
3133 pButton->Show();
3134 SetActiveControl(pButton);
3136 AdjustPositions();
3139 void SwTokenWindow::RemoveControl(const SwTOXButton* pDel, bool bInternalCall)
3141 if (bInternalCall && TOX_AUTHORITIES == m_pForm->GetTOXType())
3142 m_pParent->PreTokenButtonRemoved(pDel->GetFormToken());
3144 auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
3145 [pDel](const auto& rControl)
3147 SwTOXWidget* pCtrl = rControl.get();
3148 return pCtrl == pDel;
3150 assert(it != m_aControlList.end()); //Control does not exist!
3151 if (it == m_aControlList.end())
3152 return;
3154 // the two neighbours of the box must be merged
3155 // the properties of the right one will be lost
3156 assert(it != m_aControlList.begin() && it != m_aControlList.end() - 1); //Button at first or last position?
3157 if (it == m_aControlList.begin() || it == m_aControlList.end() - 1)
3158 return;
3160 auto itLeft = it, itRight = it;
3161 --itLeft;
3162 ++itRight;
3163 SwTOXWidget* pLeftEdit = itLeft->get();
3164 SwTOXWidget* pRightEdit = itRight->get();
3166 static_cast<SwTOXEdit*>(pLeftEdit)->SetText(static_cast<SwTOXEdit*>(pLeftEdit)->GetText() +
3167 static_cast<SwTOXEdit*>(pRightEdit)->GetText());
3168 static_cast<SwTOXEdit*>(pLeftEdit)->AdjustSize();
3170 m_pActiveCtrl->Hide();
3171 m_pActiveCtrl = nullptr;
3173 m_aControlList.erase(itRight);
3174 m_aControlList.erase(it);
3176 SetActiveControl(pLeftEdit);
3177 AdjustPositions();
3178 m_aModifyHdl.Call(nullptr);
3181 IMPL_LINK_NOARG(SwTokenWindow, AdjustPositionsHdl, const Size&, void)
3183 AdjustScrolling();
3186 void SwTokenWindow::AdjustPositions()
3188 for (size_t i = 0; i < m_aControlList.size(); ++i)
3189 m_aControlList[i]->set_grid_left_attach(i);
3190 AdjustScrolling();
3193 void SwTokenWindow::MoveControls(tools::Long nOffset)
3195 m_xScrollWin->hadjustment_set_value(nOffset);
3198 IMPL_LINK_NOARG(SwTokenWindow, ScrollHdl, weld::ScrolledWindow&, void)
3200 AdjustScrolling();
3203 void SwTokenWindow::AdjustScrolling()
3205 if (m_aControlList.size() <= 1)
3206 return;
3208 //validate scroll buttons
3210 auto nLeft = m_xScrollWin->hadjustment_get_value();
3211 auto nSpace = m_xScrollWin->hadjustment_get_page_size();
3212 auto nWidth = m_xScrollWin->hadjustment_get_upper();
3214 bool bEnable = nWidth > nSpace;
3216 //the active control must be visible
3217 if (bEnable && m_pActiveCtrl)
3219 int x, y, width, height;
3220 m_pActiveCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
3222 if (x < nLeft || x + width > nLeft + nSpace)
3224 MoveControls(x);
3225 nLeft = x;
3228 m_xLeftScrollWin->set_sensitive(nLeft > 0);
3229 m_xRightScrollWin->set_sensitive(nLeft + nSpace < nWidth);
3231 else
3233 //if the control fits into the space then the first control must be at position 0
3234 m_xRightScrollWin->set_sensitive(false);
3235 m_xLeftScrollWin->set_sensitive(false);
3239 IMPL_LINK(SwTokenWindow, ScrollBtnHdl, weld::Button&, rBtn, void)
3241 if (m_aControlList.empty())
3242 return;
3244 const auto nSpace = m_xScrollWin->hadjustment_get_page_size();
3245 const auto nWidth = m_xScrollWin->hadjustment_get_upper();
3246 const auto nLeft = m_xScrollWin->hadjustment_get_value();
3248 tools::Long nMove = nLeft;
3249 if (&rBtn == m_xLeftScrollWin.get())
3251 //find the first completely visible control (left edge visible)
3252 auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
3253 [this, nLeft](const auto& rControl)
3255 SwTOXWidget* pCtrl = rControl.get();
3257 int x, y, width, height;
3258 pCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
3260 return x >= nLeft;
3262 if (it != m_aControlList.end())
3264 if (it == m_aControlList.begin())
3266 nMove = 0;
3268 else
3270 //move the left neighbor to the start position
3271 auto itLeft = it;
3272 --itLeft;
3273 SwTOXWidget* pLeft = itLeft->get();
3275 int x, y, width, height;
3276 pLeft->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
3278 nMove = x;
3282 else
3284 //find the first completely visible control (right edge visible)
3285 auto it = std::find_if(m_aControlList.rbegin(), m_aControlList.rend(),
3286 [this, nLeft, nSpace](const auto& rControl) {
3287 SwTOXWidget* pCtrl = rControl.get();
3289 int x, y, width, height;
3290 pCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
3292 auto nXPos = x + width;
3293 return nXPos <= nLeft + nSpace;
3295 if (it != m_aControlList.rend() && it != m_aControlList.rbegin())
3297 //move the right neighbor to the right edge right aligned
3298 auto itRight = it;
3299 --itRight;
3300 SwTOXWidget* pRight = itRight->get();
3302 int x, y, width, height;
3303 pRight->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
3305 nMove = x + width - nSpace;
3308 //move it left until it's completely visible
3311 if (nMove != nLeft)
3313 // move the complete list
3314 MoveControls(nMove);
3315 m_xLeftScrollWin->set_sensitive(nMove > 0);
3316 m_xRightScrollWin->set_sensitive(nMove + nSpace < nWidth);
3320 OUString SwTokenWindow::GetPattern() const
3322 OUStringBuffer sRet;
3324 for (const auto& elem : m_aControlList)
3326 const SwTOXWidget* pCtrl = elem.get();
3328 const SwFormToken &rNewToken = pCtrl->GetType() == WindowType::EDIT
3329 ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pCtrl))->GetFormToken()
3330 : static_cast<const SwTOXButton*>(pCtrl)->GetFormToken();
3332 //TODO: prevent input of TOX_STYLE_DELIMITER in KeyInput
3333 sRet.append(rNewToken.GetString());
3336 return sRet.makeStringAndClear();
3339 // Check if a control of the specified TokenType is already contained in the list
3340 bool SwTokenWindow::Contains(FormTokenType eSearchFor) const
3342 bool bRet = false;
3344 for (const auto& elem : m_aControlList)
3346 const SwTOXWidget* pCtrl = elem.get();
3347 const SwFormToken &rNewToken = pCtrl->GetType() == WindowType::EDIT
3348 ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pCtrl))->GetFormToken()
3349 : static_cast<const SwTOXButton*>(pCtrl)->GetFormToken();
3351 if (eSearchFor == rNewToken.eTokenType)
3353 bRet = true;
3354 break;
3358 return bRet;
3361 OUString SwTokenWindow::CreateQuickHelp(const SwFormToken& rToken)
3363 OUString sEntry;
3364 if (rToken.eTokenType != TOKEN_AUTHORITY)
3365 sEntry = m_aButtonHelpTexts[rToken.eTokenType];
3366 else
3368 sEntry += SwAuthorityFieldType::GetAuthFieldName(
3369 static_cast<ToxAuthorityField>(rToken.nAuthorityField));
3372 if (rToken.eTokenType != TOKEN_TAB_STOP)
3374 if (!rToken.sCharStyleName.isEmpty())
3376 sEntry += " " + m_sCharStyle + rToken.sCharStyleName;
3380 return sEntry;
3383 IMPL_LINK(SwTokenWindow, EditResize, SwTOXEdit&, rEdit, void)
3385 rEdit.AdjustSize();
3386 AdjustPositions();
3387 m_aModifyHdl.Call(nullptr);
3390 IMPL_LINK(SwTokenWindow, NextItemHdl, SwTOXEdit&, rEdit, void)
3392 auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
3393 [&rEdit](const auto& rControl)
3395 SwTOXWidget* pCtrl = rControl.get();
3396 return pCtrl == &rEdit;
3399 if (it == m_aControlList.end())
3400 return;
3402 auto itTest = it;
3403 ++itTest;
3405 if ((it != m_aControlList.begin() && !rEdit.IsNextControl()) ||
3406 (itTest != m_aControlList.end() && rEdit.IsNextControl()))
3408 auto iterFocus = it;
3409 rEdit.IsNextControl() ? ++iterFocus : --iterFocus;
3411 SwTOXWidget *pCtrlFocus = iterFocus->get();
3412 pCtrlFocus->GrabFocus();
3413 static_cast<SwTOXButton*>(pCtrlFocus)->Check();
3415 AdjustScrolling();
3419 IMPL_LINK(SwTokenWindow, TbxFocusHdl, SwTOXWidget&, rControl, void)
3421 SwTOXEdit* pEdit = static_cast<SwTOXEdit*>(&rControl);
3422 for (const auto& aControl : m_aControlList)
3424 SwTOXWidget* pCtrl = aControl.get();
3425 if (pCtrl && pCtrl->GetType() != WindowType::EDIT)
3426 static_cast<SwTOXButton*>(pCtrl)->Check(false);
3429 SetActiveControl(pEdit);
3432 IMPL_LINK(SwTokenWindow, NextItemBtnHdl, SwTOXButton&, rBtn, void )
3434 auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
3435 [&rBtn](const auto& rControl)
3437 SwTOXWidget* pCtrl = rControl.get();
3438 return pCtrl == &rBtn;
3441 if (it == m_aControlList.end())
3442 return;
3444 auto itTest = it;
3445 ++itTest;
3447 if (rBtn.IsNextControl() && (itTest == m_aControlList.end() || !rBtn.IsNextControl()))
3448 return;
3450 bool isNext = rBtn.IsNextControl();
3452 auto iterFocus = it;
3453 isNext ? ++iterFocus : --iterFocus;
3455 SwTOXWidget* pCtrlFocus = iterFocus->get();
3456 pCtrlFocus->GrabFocus();
3457 int nStartPos(0), nEndPos(0);
3459 if (!isNext)
3461 const sal_Int32 nLen = static_cast<SwTOXEdit*>(pCtrlFocus)->GetText().getLength();
3463 nStartPos = nLen;
3464 nEndPos = nLen;
3467 static_cast<SwTOXEdit*>(pCtrlFocus)->select_region(nStartPos, nEndPos);
3469 rBtn.Check(false);
3471 AdjustScrolling();
3474 IMPL_LINK(SwTokenWindow, TbxFocusBtnHdl, SwTOXWidget&, rControl, void)
3476 SwTOXButton* pBtn = static_cast<SwTOXButton*>(&rControl);
3477 for (const auto& aControl : m_aControlList)
3479 SwTOXWidget* pControl = aControl.get();
3481 if (pControl && WindowType::EDIT != pControl->GetType())
3482 static_cast<SwTOXButton*>(pControl)->Check(pBtn == pControl);
3485 SetActiveControl(pBtn);
3488 void SwTokenWindow::SetFocus2theAllBtn()
3490 if (m_pParent)
3492 m_pParent->SetFocus2theAllBtn();
3496 sal_uInt32 SwTokenWindow::GetControlIndex(FormTokenType eType) const
3498 //there are only one entry-text button and only one page-number button,
3499 //so we need not add index for these two buttons.
3500 if ( eType == TOKEN_ENTRY_TEXT || eType == TOKEN_PAGE_NUMS )
3502 return 0;
3505 sal_uInt32 nIndex = 0;
3506 for (const auto& elem : m_aControlList)
3508 const SwTOXWidget* pControl = elem.get();
3510 const SwFormToken& rNewToken = WindowType::EDIT == pControl->GetType()
3511 ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pControl))->GetFormToken()
3512 : static_cast<const SwTOXButton*>(pControl)->GetFormToken();
3514 if(eType == rNewToken.eTokenType)
3516 ++nIndex;
3520 return nIndex;
3523 SwTOXStylesTabPage::SwTOXStylesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
3524 : SfxTabPage(pPage, pController, "modules/swriter/ui/tocstylespage.ui", "TocStylesPage", &rAttrSet)
3525 , m_xLevelLB(m_xBuilder->weld_tree_view("levels"))
3526 , m_xAssignBT(m_xBuilder->weld_button("assign"))
3527 , m_xParaLayLB(m_xBuilder->weld_tree_view("styles"))
3528 , m_xStdBT(m_xBuilder->weld_button("default"))
3529 , m_xEditStyleBT(m_xBuilder->weld_button("edit"))
3531 m_xParaLayLB->make_sorted();
3532 auto nHeight = m_xLevelLB->get_height_rows(16);
3533 m_xLevelLB->set_size_request(-1, nHeight);
3534 m_xParaLayLB->set_size_request(-1, nHeight);
3536 SetExchangeSupport();
3538 m_xEditStyleBT->connect_clicked(LINK(this, SwTOXStylesTabPage, EditStyleHdl));
3539 m_xAssignBT->connect_clicked(LINK(this, SwTOXStylesTabPage, AssignHdl));
3540 m_xStdBT->connect_clicked(LINK(this, SwTOXStylesTabPage, StdHdl));
3541 m_xParaLayLB->connect_changed(LINK(this, SwTOXStylesTabPage, EnableSelectHdl));
3542 m_xLevelLB->connect_changed(LINK(this, SwTOXStylesTabPage, EnableSelectHdl));
3543 m_xParaLayLB->connect_row_activated(LINK(this, SwTOXStylesTabPage, DoubleClickHdl));
3546 SwTOXStylesTabPage::~SwTOXStylesTabPage()
3550 bool SwTOXStylesTabPage::FillItemSet( SfxItemSet* )
3552 return true;
3555 void SwTOXStylesTabPage::Reset( const SfxItemSet* rSet )
3557 ActivatePage(*rSet);
3560 void SwTOXStylesTabPage::ActivatePage( const SfxItemSet& )
3562 m_pCurrentForm.reset(new SwForm(GetForm()));
3564 // not hyperlink for user directories
3565 const sal_uInt16 nSize = m_pCurrentForm->GetFormMax();
3567 // display form pattern without title
3569 m_xLevelLB->freeze();
3570 m_xLevelLB->clear();
3571 // display 1st TemplateEntry
3572 OUString aStr( SwResId( STR_TITLE ));
3573 if( !m_pCurrentForm->GetTemplate( 0 ).isEmpty() )
3575 aStr += " " + OUStringChar(aDeliStart)
3576 + m_pCurrentForm->GetTemplate( 0 )
3577 + OUStringChar(aDeliEnd);
3579 m_xLevelLB->append_text(aStr);
3581 for( sal_uInt16 i=1; i < nSize; ++i )
3583 if( TOX_INDEX == m_pCurrentForm->GetTOXType() &&
3584 FORM_ALPHA_DELIMITER == i )
3586 aStr = SwResId(STR_ALPHA);
3588 else
3590 aStr = SwResId(STR_LEVEL) + OUString::number(
3591 TOX_INDEX == m_pCurrentForm->GetTOXType() ? i - 1 : i );
3593 if( !m_pCurrentForm->GetTemplate( i ).isEmpty() )
3595 aStr += " " + OUStringChar(aDeliStart)
3596 + m_pCurrentForm->GetTemplate( i )
3597 + OUStringChar(aDeliEnd);
3599 m_xLevelLB->append_text(aStr);
3601 m_xLevelLB->thaw();
3603 // initialise templates
3604 SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
3605 const sal_uInt16 nSz = rSh.GetTextFormatCollCount();
3607 m_xParaLayLB->freeze();
3608 m_xParaLayLB->clear();
3609 for( sal_uInt16 i = 0; i < nSz; ++i )
3611 const SwTextFormatColl *pColl = &rSh.GetTextFormatColl( i );
3612 if( !pColl->IsDefault() )
3613 m_xParaLayLB->append_text( pColl->GetName() );
3616 // query pool collections and set them for the directory
3617 for( sal_uInt16 i = 0; i < m_pCurrentForm->GetFormMax(); ++i )
3619 aStr = m_pCurrentForm->GetTemplate( i );
3620 if (!aStr.isEmpty() && m_xParaLayLB->find_text(aStr) == -1)
3621 m_xParaLayLB->append_text(aStr);
3623 m_xParaLayLB->thaw();
3625 EnableSelectHdl(*m_xParaLayLB);
3628 DeactivateRC SwTOXStylesTabPage::DeactivatePage( SfxItemSet* /*pSet*/ )
3630 GetForm() = *m_pCurrentForm;
3631 return DeactivateRC::LeavePage;
3634 std::unique_ptr<SfxTabPage> SwTOXStylesTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
3635 const SfxItemSet* rAttrSet)
3637 return std::make_unique<SwTOXStylesTabPage>(pPage, pController, *rAttrSet);
3640 IMPL_LINK_NOARG(SwTOXStylesTabPage, EditStyleHdl, weld::Button&, void)
3642 if (m_xParaLayLB->get_selected_index() != -1)
3644 SfxStringItem aStyle(SID_STYLE_EDIT, m_xParaLayLB->get_selected_text());
3645 SfxUInt16Item aFamily(SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Para));
3646 SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
3647 rSh.GetView().GetViewFrame().GetDispatcher()->ExecuteList(SID_STYLE_EDIT,
3648 SfxCallMode::SYNCHRON,
3649 { &aStyle, &aFamily });
3653 // allocate templates
3654 IMPL_LINK_NOARG(SwTOXStylesTabPage, AssignHdl, weld::Button&, void)
3656 auto nLevPos = m_xLevelLB->get_selected_index();
3657 auto nTemplPos = m_xParaLayLB->get_selected_index();
3658 if (nLevPos == -1 || nTemplPos == -1)
3659 return;
3661 const OUString aStr(o3tl::getToken(m_xLevelLB->get_text(nLevPos), 0, aDeliStart)
3662 + OUStringChar(aDeliStart)
3663 + m_xParaLayLB->get_selected_text()
3664 + OUStringChar(aDeliEnd));
3666 m_pCurrentForm->SetTemplate(nLevPos, m_xParaLayLB->get_selected_text());
3668 m_xLevelLB->remove(nLevPos);
3669 m_xLevelLB->insert_text(nLevPos, aStr);
3670 m_xLevelLB->select_text(aStr);
3671 Modify();
3674 IMPL_LINK_NOARG(SwTOXStylesTabPage, StdHdl, weld::Button&, void)
3676 const auto nPos = m_xLevelLB->get_selected_index();
3677 if (nPos != -1)
3679 const OUString aStr(m_xLevelLB->get_text(nPos).getToken(0, aDeliStart));
3680 m_xLevelLB->remove(nPos);
3681 m_xLevelLB->insert_text(nPos, aStr);
3682 m_xLevelLB->select_text(aStr);
3683 m_pCurrentForm->SetTemplate(nPos, OUString());
3684 Modify();
3688 IMPL_LINK_NOARG(SwTOXStylesTabPage, DoubleClickHdl, weld::TreeView&, bool)
3690 const OUString aTmpName(m_xParaLayLB->get_selected_text());
3691 SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
3693 if(m_xParaLayLB->get_selected_index() != -1 &&
3694 (m_xLevelLB->get_selected_index() == 0 || SwMultiTOXTabDialog::IsNoNum(rSh, aTmpName)))
3695 AssignHdl(*m_xAssignBT);
3697 return true;
3700 // enable only when selected
3701 IMPL_LINK_NOARG(SwTOXStylesTabPage, EnableSelectHdl, weld::TreeView&, void)
3703 m_xStdBT->set_sensitive(m_xLevelLB->get_selected_index() != -1);
3705 SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
3706 const OUString aTmpName(m_xParaLayLB->get_selected_text());
3707 m_xAssignBT->set_sensitive(m_xParaLayLB->get_selected_index() != -1 &&
3708 m_xLevelLB->get_selected_index() != -1 &&
3709 (m_xLevelLB->get_selected_index() == 0 || SwMultiTOXTabDialog::IsNoNum(rSh, aTmpName)));
3710 m_xEditStyleBT->set_sensitive(m_xParaLayLB->get_selected_index() != -1);
3713 void SwTOXStylesTabPage::Modify()
3715 SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
3716 if (pTOXDlg)
3718 GetForm() = *m_pCurrentForm;
3719 pTOXDlg->CreateOrUpdateExample(pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_STYLES);
3723 #define ITEM_SEARCH 1
3724 #define ITEM_ALTERNATIVE 2
3725 #define ITEM_PRIM_KEY 3
3726 #define ITEM_SEC_KEY 4
3727 #define ITEM_COMMENT 5
3728 #define ITEM_CASE 6
3729 #define ITEM_WORDONLY 7
3731 SwEntryBrowseBox::SwEntryBrowseBox(const css::uno::Reference<css::awt::XWindow> &rParent)
3732 : SwEntryBrowseBox_Base(VCLUnoHelper::GetWindow(rParent), EditBrowseBoxFlags::NONE, WB_TABSTOP | WB_BORDER,
3733 BrowserMode::KEEPHIGHLIGHT |
3734 BrowserMode::COLUMNSELECTION |
3735 BrowserMode::MULTISELECTION |
3736 BrowserMode::TRACKING_TIPS |
3737 BrowserMode::HLINES |
3738 BrowserMode::VLINES |
3739 BrowserMode::AUTO_VSCROLL|
3740 BrowserMode::HIDECURSOR )
3741 , m_aCellEdit(VclPtr<svt::EditControl>::Create(&GetDataWindow()))
3742 , m_aCellCheckBox(VclPtr<svt::CheckBoxControl>::Create(&GetDataWindow()))
3743 , m_nCurrentRow(0)
3744 , m_bModified(false)
3746 OUString sSearch = SwResId(STR_AUTOMARK_SEARCHTERM);
3747 OUString sAlternative = SwResId(STR_AUTOMARK_ALTERNATIVE);
3748 OUString sPrimKey = SwResId(STR_AUTOMARK_KEY1);
3749 OUString sSecKey = SwResId(STR_AUTOMARK_KEY2);
3750 OUString sComment = SwResId(STR_AUTOMARK_COMMENT);
3751 OUString sCaseSensitive = SwResId(STR_AUTOMARK_CASESENSITIVE);
3752 OUString sWordOnly = SwResId(STR_AUTOMARK_WORDONLY);
3753 m_sYes = SwResId(STR_AUTOMARK_YES);
3754 m_sNo = SwResId(STR_AUTOMARK_NO);
3756 m_aCellCheckBox->EnableTriState(false);
3757 m_xController = new ::svt::EditCellController(m_aCellEdit.get());
3758 m_xCheckController = new ::svt::CheckBoxCellController(m_aCellCheckBox.get());
3760 // HACK: BrowseBox doesn't invalidate its children, how it should be.
3761 // That's why WB_CLIPCHILDREN is reset in order to enforce the
3762 // children' invalidation
3763 WinBits aStyle = GetStyle();
3764 if( aStyle & WB_CLIPCHILDREN )
3766 aStyle &= ~WB_CLIPCHILDREN;
3767 SetStyle( aStyle );
3770 const OUString* aTitles[7] =
3772 &sSearch,
3773 &sAlternative,
3774 &sPrimKey,
3775 &sSecKey,
3776 &sComment,
3777 &sCaseSensitive,
3778 &sWordOnly
3781 tools::Long nWidth = GetSizePixel().Width();
3782 nWidth /=7;
3783 --nWidth;
3784 for(sal_uInt16 i = 1; i < 8; i++)
3785 InsertDataColumn( i, *aTitles[i - 1], nWidth );
3788 SwEntryBrowseBox::~SwEntryBrowseBox()
3790 disposeOnce();
3793 void SwEntryBrowseBox::dispose()
3795 m_aCellEdit.disposeAndClear();
3796 m_aCellCheckBox.disposeAndClear();
3797 SwEntryBrowseBox_Base::dispose();
3800 void SwEntryBrowseBox::Resize()
3802 SwEntryBrowseBox_Base::Resize();
3804 tools::Long nWidth = GetSizePixel().Width();
3805 std::vector<tools::Long> aWidths = GetOptimalColWidths();
3806 tools::Long nNaturalWidth(std::accumulate(aWidths.begin(), aWidths.end(), 0));
3807 tools::Long nExcess = ((nWidth - nNaturalWidth) / aWidths.size()) - 1;
3809 for (size_t i = 0; i < aWidths.size(); ++i)
3810 SetColumnWidth(i+1, aWidths[i] + nExcess);
3813 std::vector<tools::Long> SwEntryBrowseBox::GetOptimalColWidths() const
3815 std::vector<tools::Long> aWidths;
3817 tools::Long nStandardColMinWidth = approximate_digit_width() * 15;
3818 tools::Long nYesNoWidth = approximate_digit_width() * 5;
3819 nYesNoWidth = std::max(nYesNoWidth, GetTextWidth(m_sYes));
3820 nYesNoWidth = std::max(nYesNoWidth, GetTextWidth(m_sNo));
3821 for (sal_uInt16 i = 1; i < 6; i++)
3823 tools::Long nColWidth = std::max(nStandardColMinWidth,
3824 GetTextWidth(GetColumnTitle(i)));
3825 nColWidth += 12;
3826 aWidths.push_back(nColWidth);
3829 for (sal_uInt16 i = 6; i < 8; i++)
3831 tools::Long nColWidth = std::max(nYesNoWidth,
3832 GetTextWidth(GetColumnTitle(i)));
3833 nColWidth += 12;
3834 aWidths.push_back(nColWidth);
3837 return aWidths;
3840 Size SwEntryBrowseBox::GetOptimalSize() const
3842 Size aSize = LogicToPixel(Size(276 , 175), MapMode(MapUnit::MapAppFont));
3844 std::vector<tools::Long> aWidths = GetOptimalColWidths();
3846 tools::Long nWidth(std::accumulate(aWidths.begin(), aWidths.end(), 0));
3848 aSize.setWidth( std::max(aSize.Width(), nWidth) );
3850 return aSize;
3853 bool SwEntryBrowseBox::SeekRow( sal_Int32 nRow )
3855 m_nCurrentRow = nRow;
3856 return true;
3859 OUString SwEntryBrowseBox::GetCellText(sal_Int32 nRow, sal_uInt16 nColumn) const
3861 OUString pRet;
3862 if (o3tl::make_unsigned(nRow) < m_Entries.size())
3864 const AutoMarkEntry* pEntry = m_Entries[ nRow ].get();
3865 switch(nColumn)
3867 case ITEM_SEARCH : pRet = pEntry->sSearch; break;
3868 case ITEM_ALTERNATIVE : pRet = pEntry->sAlternative; break;
3869 case ITEM_PRIM_KEY : pRet = pEntry->sPrimKey; break;
3870 case ITEM_SEC_KEY : pRet = pEntry->sSecKey; break;
3871 case ITEM_COMMENT : pRet = pEntry->sComment; break;
3872 case ITEM_CASE : pRet = pEntry->bCase ? m_sYes : m_sNo; break;
3873 case ITEM_WORDONLY : pRet = pEntry->bWord ? m_sYes : m_sNo; break;
3876 return pRet;
3879 void SwEntryBrowseBox::PaintCell(OutputDevice& rDev,
3880 const tools::Rectangle& rRect, sal_uInt16 nColumnId) const
3882 const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
3883 rDev.DrawText( rRect, GetCellText( m_nCurrentRow, nColumnId ), nStyle );
3886 ::svt::CellController* SwEntryBrowseBox::GetController(sal_Int32 /*nRow*/, sal_uInt16 nCol)
3888 return nCol < ITEM_CASE ? m_xController.get() : m_xCheckController.get();
3891 bool SwEntryBrowseBox::SaveModified()
3893 m_bModified = true;
3894 const size_t nRow = GetCurRow();
3895 const sal_uInt16 nCol = GetCurColumnId();
3897 OUString sNew;
3898 bool bVal = false;
3899 ::svt::CellController* pController = nullptr;
3900 if(nCol < ITEM_CASE)
3902 pController = m_xController.get();
3903 sNew = static_cast< ::svt::EditCellController*>(pController)->GetEditImplementation()->GetText( LINEEND_LF );
3905 else
3907 pController = m_xCheckController.get();
3908 bVal = static_cast< ::svt::CheckBoxCellController*>(pController)->GetCheckBox().get_active();
3910 const bool bAddEntry = nRow >= m_Entries.size();
3911 std::unique_ptr<AutoMarkEntry> xNewEntry(bAddEntry ? new AutoMarkEntry : nullptr);
3912 AutoMarkEntry* pEntry = bAddEntry ? xNewEntry.get() : m_Entries[nRow].get();
3913 switch(nCol)
3915 case ITEM_SEARCH : pEntry->sSearch = sNew; break;
3916 case ITEM_ALTERNATIVE : pEntry->sAlternative = sNew; break;
3917 case ITEM_PRIM_KEY : pEntry->sPrimKey = sNew; break;
3918 case ITEM_SEC_KEY : pEntry->sSecKey = sNew; break;
3919 case ITEM_COMMENT : pEntry->sComment = sNew; break;
3920 case ITEM_CASE : pEntry->bCase = bVal; break;
3921 case ITEM_WORDONLY : pEntry->bWord = bVal; break;
3923 if (bAddEntry)
3925 m_Entries.push_back(std::move(xNewEntry));
3926 RowInserted(nRow, 1, true, true);
3927 if(nCol < ITEM_WORDONLY)
3929 pController->SaveValue();
3930 GoToRow( nRow );
3933 return true;
3936 void SwEntryBrowseBox::InitController(
3937 ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol)
3939 const OUString rText = GetCellText( nRow, nCol );
3940 if(nCol < ITEM_CASE)
3942 rController = m_xController;
3943 ::svt::CellController* pController = m_xController.get();
3944 static_cast< ::svt::EditCellController*>(pController)->GetEditImplementation()->SetText( rText );
3946 else
3948 rController = m_xCheckController;
3949 ::svt::CellController* pController = m_xCheckController.get();
3950 static_cast< ::svt::CheckBoxCellController*>(pController)->GetCheckBox().set_active(
3951 rText == m_sYes );
3955 void SwEntryBrowseBox::ReadEntries(SvStream& rInStr)
3957 AutoMarkEntry* pToInsert = nullptr;
3958 // tdf#108910, tdf#125496 - read index entries using the appropriate character set
3959 rtl_TextEncoding eTEnc = SwIoSystem::GetTextEncoding(rInStr);
3960 if (eTEnc == RTL_TEXTENCODING_DONTKNOW)
3961 eTEnc = osl_getThreadTextEncoding();
3962 while (rInStr.good())
3964 OUString sLine;
3965 rInStr.ReadByteStringLine( sLine, eTEnc );
3967 // # -> comment
3968 // ; -> delimiter between entries ->
3969 // Format: TextToSearchFor;AlternativeString;PrimaryKey;SecondaryKey
3970 // Leading and trailing blanks are ignored
3971 if( !sLine.isEmpty() )
3973 //comments are contained in separate lines but are put into the struct of the following data
3974 //line (if available)
3975 if( '#' != sLine[0] )
3977 if( !pToInsert )
3978 pToInsert = new AutoMarkEntry;
3980 sal_Int32 nSttPos = 0;
3981 pToInsert->sSearch = sLine.getToken(0, ';', nSttPos );
3982 pToInsert->sAlternative = sLine.getToken(0, ';', nSttPos );
3983 pToInsert->sPrimKey = sLine.getToken(0, ';', nSttPos );
3984 pToInsert->sSecKey = sLine.getToken(0, ';', nSttPos );
3986 std::u16string_view sStr = o3tl::getToken(sLine, 0, ';', nSttPos );
3987 pToInsert->bCase = !sStr.empty() && sStr != u"0";
3989 sStr = o3tl::getToken(sLine, 0, ';', nSttPos );
3990 pToInsert->bWord = !sStr.empty() && sStr != u"0";
3992 m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
3993 pToInsert = nullptr;
3995 else
3997 if(pToInsert)
3998 m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
3999 pToInsert = new AutoMarkEntry;
4000 pToInsert->sComment = sLine.copy(1);
4004 if( pToInsert )
4005 m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
4006 RowInserted(0, m_Entries.size() + 1);
4009 void SwEntryBrowseBox::WriteEntries(SvStream& rOutStr)
4011 //check if the current controller is modified
4012 const sal_uInt16 nCol = GetCurColumnId();
4013 ::svt::CellController* pController;
4014 if(nCol < ITEM_CASE)
4015 pController = m_xController.get();
4016 else
4017 pController = m_xCheckController.get();
4018 if (pController->IsValueChangedFromSaved())
4019 GoToColumnId(nCol + (nCol < ITEM_CASE ? 1 : -1 ));
4021 for(const std::unique_ptr<AutoMarkEntry> & rpEntry : m_Entries)
4023 AutoMarkEntry* pEntry = rpEntry.get();
4024 if(!pEntry->sComment.isEmpty())
4026 // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
4027 rOutStr.WriteByteStringLine( Concat2View("#" + pEntry->sComment), RTL_TEXTENCODING_UTF8 );
4030 OUString sWrite( pEntry->sSearch + ";" +
4031 pEntry->sAlternative + ";" +
4032 pEntry->sPrimKey + ";" +
4033 pEntry->sSecKey + ";" +
4034 (pEntry->bCase ? std::u16string_view(u"1") : std::u16string_view(u"0")) +
4035 ";" +
4036 (pEntry->bWord ? std::u16string_view(u"1") : std::u16string_view(u"0")) );
4038 if( sWrite.getLength() > 5 )
4039 // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
4040 rOutStr.WriteByteStringLine( sWrite, RTL_TEXTENCODING_UTF8 );
4044 bool SwEntryBrowseBox::IsModified()const
4046 if(m_bModified)
4047 return true;
4049 //check if the current controller is modified
4050 const sal_uInt16 nCol = GetCurColumnId();
4051 ::svt::CellController* pController;
4052 if(nCol < ITEM_CASE)
4053 pController = m_xController.get();
4054 else
4055 pController = m_xCheckController.get();
4056 return pController->IsValueChangedFromSaved();
4059 SwAutoMarkDlg_Impl::SwAutoMarkDlg_Impl(weld::Window* pParent, OUString aAutoMarkURL,
4060 bool bCreate)
4061 : GenericDialogController(pParent, "modules/swriter/ui/createautomarkdialog.ui", "CreateAutomarkDialog")
4062 , m_sAutoMarkURL(std::move(aAutoMarkURL))
4063 , m_bCreateMode(bCreate)
4064 , m_xOKPB(m_xBuilder->weld_button("ok"))
4065 , m_xTable(m_xBuilder->weld_container("area"))
4066 , m_xTableCtrlParent(m_xTable->CreateChildFrame())
4067 , m_xEntriesBB(VclPtr<SwEntryBrowseBox>::Create(m_xTableCtrlParent))
4069 m_xEntriesBB->Show();
4070 m_xOKPB->connect_clicked(LINK(this, SwAutoMarkDlg_Impl, OkHdl));
4072 m_xDialog->set_title(m_xDialog->get_title() + ": " + m_sAutoMarkURL);
4073 bool bError = false;
4074 if( m_bCreateMode )
4075 m_xEntriesBB->RowInserted(0);
4076 else
4078 SfxMedium aMed( m_sAutoMarkURL, StreamMode::STD_READ );
4079 if( aMed.GetInStream() && !aMed.GetInStream()->GetError() )
4080 m_xEntriesBB->ReadEntries( *aMed.GetInStream() );
4081 else
4082 bError = true;
4085 Size aPrefSize = m_xEntriesBB->GetOptimalSize();
4086 m_xTable->set_size_request(aPrefSize.Width(), aPrefSize.Height());
4088 if (bError)
4089 m_xDialog->response(RET_CANCEL);
4092 SwAutoMarkDlg_Impl::~SwAutoMarkDlg_Impl()
4094 m_xEntriesBB.disposeAndClear();
4095 m_xTableCtrlParent->dispose();
4096 m_xTableCtrlParent.clear();
4099 IMPL_LINK_NOARG(SwAutoMarkDlg_Impl, OkHdl, weld::Button&, void)
4101 bool bError = false;
4102 if (m_xEntriesBB->IsModified() || m_bCreateMode)
4104 SfxMedium aMed( m_sAutoMarkURL,
4105 m_bCreateMode ? StreamMode::WRITE
4106 : StreamMode::WRITE| StreamMode::TRUNC );
4107 SvStream* pStrm = aMed.GetOutStream();
4108 // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
4109 pStrm->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
4110 if( !pStrm->GetError() )
4112 m_xEntriesBB->WriteEntries( *pStrm );
4113 aMed.Commit();
4115 else
4116 bError = true;
4118 if (!bError)
4119 m_xDialog->response(RET_OK);
4122 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */