remove assert looking for new compatibilityMode DOCX
[LibreOffice.git] / sw / source / ui / misc / bookmark.cxx
blobdecf3ea803248a23890bd5304a5f4645fda62593
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 <rtl/ustrbuf.hxx>
21 #include <sfx2/request.hxx>
22 #include <svl/stritem.hxx>
23 #include <unotools/viewoptions.hxx>
24 #include <vcl/weld.hxx>
25 #include <o3tl/string_view.hxx>
26 #include <com/sun/star/frame/XModel.hpp>
27 #include <com/sun/star/text/XBookmarksSupplier.hpp>
28 #include <officecfg/Office/Common.hxx>
30 #include <swabstdlg.hxx>
31 #include <swuiexp.hxx>
32 #include <view.hxx>
33 #include <wrtsh.hxx>
34 #include <cmdid.h>
35 #include <bookmark.hxx>
36 #include <docsh.hxx>
37 #include <ndtxt.hxx>
38 #include <strings.hrc>
39 #include <IDocumentSettingAccess.hxx>
40 #include <unotxdoc.hxx>
42 using namespace ::com::sun::star;
44 const char BookmarkTable::s_cSeparator(';');
46 // callback to modify EditBox
47 IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, weld::Entry&, void)
49 ValidateBookmarks();
50 m_xBookmarksBox->unselect_all();
51 // if a string has been pasted from the clipboard then
52 // there may be illegal characters in the box
53 // sanitization
54 OUString sTmp = m_xEditBox->get_text();
55 OUString sMsg;
56 const sal_Int32 nLen = sTmp.getLength();
57 for (sal_Int32 i = 0; i < BookmarkTable::aForbiddenChars.getLength(); i++)
59 const sal_Int32 nTmpLen = sTmp.getLength();
60 sTmp = sTmp.replaceAll(OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]), "");
61 if (sTmp.getLength() != nTmpLen)
62 sMsg += OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]);
64 const bool bHasForbiddenChars = sTmp.getLength() != nLen;
65 m_xForbiddenChars->set_visible(bHasForbiddenChars);
66 if (bHasForbiddenChars)
67 m_xEditBox->set_message_type(weld::EntryMessageType::Error);
68 else
69 m_xEditBox->set_message_type(weld::EntryMessageType::Normal);
71 sal_Int32 nSelectedEntries = 0;
72 sal_Int32 nEntries = 0;
73 sal_Int32 nTokenIndex = 0;
74 while (!sTmp.isEmpty() && nTokenIndex >= 0)
76 OUString aToken = sTmp.getToken(0, BookmarkTable::s_cSeparator, nTokenIndex);
77 if (m_xBookmarksBox->GetBookmarkByName(aToken))
79 m_xBookmarksBox->SelectByName(aToken);
80 nSelectedEntries++;
82 nEntries++;
85 // allow to add new bookmark only if one name provided and it's not taken
86 m_xInsertBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 0 && !bHasForbiddenChars
87 && !m_bAreProtected);
89 // allow to delete only if all bookmarks are recognized
90 m_xDeleteBtn->set_sensitive(nEntries > 0 && nSelectedEntries == nEntries && !m_bAreProtected);
91 m_xGotoBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
92 m_xEditTextBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
93 m_xRenameBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1 && !m_bAreProtected);
96 // callback to delete a text mark
97 IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, weld::Button&, void)
99 if (!ValidateBookmarks())
100 return;
102 int nSelectedRows(0);
104 m_xBookmarksBox->selected_foreach([this, &nSelectedRows](weld::TreeIter& rEntry) {
105 // remove from model
106 sw::mark::MarkBase* pBookmark
107 = weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(rEntry));
108 OUString sRemoved = pBookmark->GetName();
109 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
110 pMarkAccess->deleteMark(pMarkAccess->findMark(sRemoved), false);
111 SfxRequest aReq(m_rSh.GetView().GetViewFrame(), FN_DELETE_BOOKMARK);
112 aReq.AppendItem(SfxStringItem(FN_DELETE_BOOKMARK, sRemoved));
113 aReq.Done();
114 std::erase(m_aTableBookmarks, std::make_pair(pBookmark, sRemoved));
116 ++nSelectedRows;
118 return false;
121 if (!nSelectedRows)
122 return;
124 // remove from BookmarkTable
125 m_xBookmarksBox->remove_selection();
127 ValidateBookmarks();
129 m_xDeleteBtn->set_sensitive(false);
130 m_xGotoBtn->set_sensitive(false);
131 m_xEditTextBtn->set_sensitive(false);
132 m_xRenameBtn->set_sensitive(false);
133 m_xInsertBtn->set_sensitive(false);
136 // callback to a goto button
137 IMPL_LINK_NOARG(SwInsertBookmarkDlg, GotoHdl, weld::Button&, void) { GotoSelectedBookmark(); }
139 IMPL_LINK_NOARG(SwInsertBookmarkDlg, DoubleClickHdl, weld::TreeView&, bool)
141 GotoSelectedBookmark();
142 return true;
145 IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, weld::TreeView&, void)
147 if (!ValidateBookmarks())
148 return;
149 // this event should fired only if we change selection by clicking on BookmarkTable entry
150 if (!m_xBookmarksBox->has_focus())
151 return;
153 SelectionChanged();
156 void SwInsertBookmarkDlg::SelectionChanged()
158 OUStringBuffer sEditBoxText;
159 int nSelectedRows = 0;
160 m_xBookmarksBox->selected_foreach(
161 [this, &sEditBoxText, &nSelectedRows](weld::TreeIter& rEntry) {
162 sw::mark::MarkBase* pBookmark
163 = weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(rEntry));
164 const OUString& sEntryName = pBookmark->GetName();
165 if (!sEditBoxText.isEmpty())
166 sEditBoxText.append(";");
167 sEditBoxText.append(sEntryName);
168 ++nSelectedRows;
169 return false;
171 if (nSelectedRows)
173 m_xInsertBtn->set_sensitive(false);
174 m_xGotoBtn->set_sensitive(nSelectedRows == 1);
175 m_xEditTextBtn->set_sensitive(nSelectedRows == 1);
176 m_xRenameBtn->set_sensitive(nSelectedRows == 1 && !m_bAreProtected);
177 m_xDeleteBtn->set_sensitive(!m_bAreProtected);
178 m_xEditBox->set_text(sEditBoxText.makeStringAndClear());
180 else
182 m_xInsertBtn->set_sensitive(!m_bAreProtected);
183 m_xGotoBtn->set_sensitive(false);
184 m_xEditTextBtn->set_sensitive(false);
185 m_xRenameBtn->set_sensitive(false);
186 m_xDeleteBtn->set_sensitive(false);
190 IMPL_LINK_NOARG(SwInsertBookmarkDlg, EditTextHdl, weld::Button&, void)
192 if (!ValidateBookmarks())
193 return;
194 auto pSelected = m_xBookmarksBox->get_selected();
195 if (!pSelected)
196 return;
198 m_xBookmarksBox->start_editing(*pSelected);
201 IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, weld::Button&, void)
203 if (!ValidateBookmarks())
204 return;
205 auto xSelected = m_xBookmarksBox->get_selected();
206 if (!xSelected)
207 return;
209 sw::mark::MarkBase* pBookmark
210 = weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(*xSelected));
211 rtl::Reference<SwXTextDocument> xModel = m_rSh.GetView().GetDocShell()->GetBaseModel();
212 uno::Reference<container::XNameAccess> xNameAccess = xModel->getBookmarks();
213 uno::Any aObj = xNameAccess->getByName(pBookmark->GetName());
214 uno::Reference<uno::XInterface> xTmp;
215 aObj >>= xTmp;
216 uno::Reference<container::XNamed> xNamed(xTmp, uno::UNO_QUERY);
217 SwAbstractDialogFactory& rFact = swui::GetFactory();
218 VclPtr<AbstractSwRenameXNamedDlg> pDlg(
219 rFact.CreateSwRenameXNamedDlg(m_xDialog.get(), xNamed, xNameAccess));
220 pDlg->SetForbiddenChars(BookmarkTable::aForbiddenChars
221 + OUStringChar(BookmarkTable::s_cSeparator));
223 pDlg->StartExecuteAsync([pDlg, this](sal_Int32 nResult) {
224 if (nResult == RET_OK)
226 ValidateBookmarks();
227 m_xDeleteBtn->set_sensitive(false);
228 m_xGotoBtn->set_sensitive(false);
229 m_xEditTextBtn->set_sensitive(false);
230 m_xRenameBtn->set_sensitive(false);
231 m_xInsertBtn->set_sensitive(false);
233 pDlg->disposeOnce();
237 // callback to an insert button. Inserts a new text mark to the current position.
238 IMPL_LINK_NOARG(SwInsertBookmarkDlg, InsertHdl, weld::Button&, void)
240 OUString sBookmark = m_xEditBox->get_text();
241 m_rSh.SetBookmark2(vcl::KeyCode(), sBookmark, m_xHideCB->get_active(),
242 m_xConditionED->get_text());
244 m_xDialog->response(RET_OK);
247 IMPL_LINK(SwInsertBookmarkDlg, ChangeHideHdl, weld::Toggleable&, rBox, void)
249 bool bHide = rBox.get_active();
250 m_xConditionED->set_sensitive(bHide);
251 m_xConditionFT->set_sensitive(bHide);
254 IMPL_LINK(SwInsertBookmarkDlg, EditingHdl, weld::TreeIter const&, rIter, bool)
256 sw::mark::MarkBase const* const pBookmark(
257 weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(rIter)));
258 assert(pBookmark);
259 return pBookmark->IsExpanded()
260 && pBookmark->GetMarkPos().GetNode() == pBookmark->GetOtherMarkPos().GetNode()
261 && !m_xBookmarksBox->get_text(rIter).endsWith(u"…");
264 IMPL_LINK(SwInsertBookmarkDlg, EditedHdl, weld::TreeView::iter_string const&, rIterString, bool)
266 sw::mark::MarkBase const* const pBookmark(
267 weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(rIterString.first)));
268 assert(pBookmark);
269 bool bRet(false);
270 if (pBookmark->GetMarkPos() != pBookmark->GetOtherMarkPos())
272 if (pBookmark->GetMarkPos().GetNode() != pBookmark->GetOtherMarkPos().GetNode())
274 return false; // don't allow editing if it spans multiple nodes
276 m_rSh.Push();
277 m_rSh.GotoMark(pBookmark);
278 // GetSelText only works for 1 paragraph, but it's checked above
279 if (m_rSh.GetSelText() != rIterString.second)
281 bRet = m_rSh.Replace(rIterString.second, false);
283 m_rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
285 else if (pBookmark->IsExpanded() && !rIterString.second.isEmpty())
286 { // SwEditShell::Replace does nothing for empty selection
287 m_rSh.Insert(rIterString.second);
288 bRet = true;
290 return bRet;
293 void SwInsertBookmarkDlg::GotoSelectedBookmark()
295 if (!ValidateBookmarks())
296 return;
297 // if no entries selected we can't jump anywhere
298 // shouldn't be needed as we disable GoTo button when jump is not possible
299 auto xSelected = m_xBookmarksBox->get_selected();
300 if (!xSelected)
301 return;
303 sw::mark::MarkBase* pBookmark
304 = weld::fromId<sw::mark::MarkBase*>(m_xBookmarksBox->get_id(*xSelected));
306 m_rSh.EnterStdMode();
307 m_rSh.GotoMark(pBookmark);
310 bool SwInsertBookmarkDlg::ValidateBookmarks()
312 if (HaveBookmarksChanged())
314 PopulateTable();
315 m_xEditBox->set_text(u""_ustr);
316 return false;
318 return true;
321 bool SwInsertBookmarkDlg::HaveBookmarksChanged()
323 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
324 if (pMarkAccess->getBookmarksCount() != m_nLastBookmarksCount)
325 return true;
327 std::vector<std::pair<sw::mark::MarkBase*, OUString>>::const_iterator aListIter
328 = m_aTableBookmarks.begin();
329 for (auto ppBookmark = pMarkAccess->getBookmarksBegin();
330 ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
332 if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
334 // more bookmarks then expected
335 if (aListIter == m_aTableBookmarks.end())
336 return true;
337 if (aListIter->first != *ppBookmark || aListIter->second != (*ppBookmark)->GetName())
338 return true;
339 ++aListIter;
342 // less bookmarks then expected
343 return aListIter != m_aTableBookmarks.end();
346 void SwInsertBookmarkDlg::PopulateTable()
348 m_aTableBookmarks.clear();
349 m_xBookmarksBox->clear();
351 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
352 for (auto ppBookmark = pMarkAccess->getBookmarksBegin();
353 ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
355 if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
357 m_xBookmarksBox->InsertBookmark(m_rSh, *ppBookmark);
358 m_aTableBookmarks.emplace_back(*ppBookmark, (*ppBookmark)->GetName());
361 m_nLastBookmarksCount = pMarkAccess->getBookmarksCount();
364 SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* pParent, SwWrtShell& rS,
365 OUString const* const pSelected)
366 : SfxDialogController(pParent, u"modules/swriter/ui/insertbookmark.ui"_ustr,
367 u"InsertBookmarkDialog"_ustr)
368 , m_rSh(rS)
369 , m_nLastBookmarksCount(0)
370 , m_bSorted(false)
371 , m_xEditBox(m_xBuilder->weld_entry(u"name"_ustr))
372 , m_xInsertBtn(m_xBuilder->weld_button(u"insert"_ustr))
373 , m_xDeleteBtn(m_xBuilder->weld_button(u"delete"_ustr))
374 , m_xGotoBtn(m_xBuilder->weld_button(u"goto"_ustr))
375 , m_xEditTextBtn(m_xBuilder->weld_button(u"edittext"_ustr))
376 , m_xRenameBtn(m_xBuilder->weld_button(u"rename"_ustr))
377 , m_xHideCB(m_xBuilder->weld_check_button(u"hide"_ustr))
378 , m_xConditionFT(m_xBuilder->weld_label(u"condlabel"_ustr))
379 , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry(u"withcond"_ustr)))
380 , m_xBookmarksBox(new BookmarkTable(m_xBuilder->weld_tree_view(u"bookmarks"_ustr)))
381 , m_xForbiddenChars(m_xBuilder->weld_label(u"lbForbiddenChars"_ustr))
383 m_xBookmarksBox->connect_changed(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl));
384 m_xBookmarksBox->connect_row_activated(LINK(this, SwInsertBookmarkDlg, DoubleClickHdl));
385 m_xBookmarksBox->connect_column_clicked(LINK(this, SwInsertBookmarkDlg, HeaderBarClick));
386 m_xBookmarksBox->connect_editing(LINK(this, SwInsertBookmarkDlg, EditingHdl),
387 LINK(this, SwInsertBookmarkDlg, EditedHdl));
388 m_xEditBox->connect_changed(LINK(this, SwInsertBookmarkDlg, ModifyHdl));
389 m_xInsertBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, InsertHdl));
390 m_xDeleteBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, DeleteHdl));
391 m_xGotoBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, GotoHdl));
392 m_xEditTextBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, EditTextHdl));
393 m_xRenameBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, RenameHdl));
394 m_xHideCB->connect_toggled(LINK(this, SwInsertBookmarkDlg, ChangeHideHdl));
396 m_xDeleteBtn->set_sensitive(false);
397 m_xGotoBtn->set_sensitive(false);
398 m_xEditTextBtn->set_sensitive(false);
399 m_xRenameBtn->set_sensitive(false);
401 // select 3rd column, otherwise it'll pick 1st one
402 m_xBookmarksBox->set_column_editables({ false, false, true, false, false });
404 PopulateTable();
406 m_xEditBox->set_text(m_xBookmarksBox->GetNameProposal());
407 m_xEditBox->set_position(-1);
409 m_xForbiddenChars->set_label(SwResId(STR_BOOKMARK_FORBIDDENCHARS) + " "
410 + BookmarkTable::aForbiddenChars);
411 m_xForbiddenChars->set_visible(false);
413 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
415 m_xHideCB->set_visible(false);
416 m_xConditionFT->set_visible(false);
417 m_xConditionED->set_visible(false);
420 m_bAreProtected = m_rSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS);
422 // disabled until "Hide" flag is not checked
423 m_xConditionED->set_sensitive(false);
424 m_xConditionFT->set_sensitive(false);
426 // restore dialog size
427 SvtViewOptions aDlgOpt(EViewType::Dialog, u"BookmarkDialog"_ustr);
428 if (aDlgOpt.Exists())
429 m_xDialog->set_window_state(aDlgOpt.GetWindowState());
431 if (pSelected)
433 if (m_xBookmarksBox->SelectByName(*pSelected))
435 SelectionChanged();
436 // which is better, focus on a button or focus on the table row?
437 // as long as editing doesn't work via the TreeView with VCL
438 // widgets, better on button.
439 m_xEditTextBtn->grab_focus();
444 SwInsertBookmarkDlg::~SwInsertBookmarkDlg()
446 // tdf#146261 - Remember size of bookmark dialog
447 SvtViewOptions aDlgOpt(EViewType::Dialog, u"BookmarkDialog"_ustr);
448 OUString sWindowState = m_xDialog->get_window_state(vcl::WindowDataMask::PosSize);
449 aDlgOpt.SetWindowState(sWindowState);
452 IMPL_LINK(SwInsertBookmarkDlg, HeaderBarClick, int, nColumn, void)
454 if (!m_bSorted)
456 m_xBookmarksBox->make_sorted();
457 m_bSorted = true;
460 bool bSortAtoZ = m_xBookmarksBox->get_sort_order();
462 //set new arrow positions in headerbar
463 if (nColumn == m_xBookmarksBox->get_sort_column())
465 bSortAtoZ = !bSortAtoZ;
466 m_xBookmarksBox->set_sort_order(bSortAtoZ);
468 else
470 int nOldSortColumn = m_xBookmarksBox->get_sort_column();
471 if (nOldSortColumn != -1)
472 m_xBookmarksBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
473 m_xBookmarksBox->set_sort_column(nColumn);
476 if (nColumn != -1)
478 //sort lists
479 m_xBookmarksBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
483 BookmarkTable::BookmarkTable(std::unique_ptr<weld::TreeView> xControl)
484 : m_xControl(std::move(xControl))
486 m_xControl->set_size_request(-1, m_xControl->get_height_rows(8));
487 m_xControl->set_column_fixed_widths({ 40, 110, 150, 160 });
488 m_xControl->set_selection_mode(SelectionMode::Multiple);
491 std::unique_ptr<weld::TreeIter> BookmarkTable::get_selected() const
493 std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator());
494 if (!m_xControl->get_selected(xIter.get()))
495 xIter.reset();
496 return xIter;
499 void BookmarkTable::InsertBookmark(SwWrtShell& rSh, sw::mark::MarkBase* const pMark)
501 sw::mark::Bookmark* pBookmark = dynamic_cast<sw::mark::Bookmark*>(pMark);
502 assert(pBookmark);
504 OUString sBookmarkNodeText;
505 static const sal_Int32 nMaxTextLen = 50;
507 if (pBookmark->IsExpanded())
509 rSh.Push();
510 rSh.GotoMark(pBookmark);
511 rSh.GetSelectedText(sBookmarkNodeText, ParaBreakType::ToBlank);
512 rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
514 if (nMaxTextLen < sBookmarkNodeText.getLength())
516 sBookmarkNodeText = sBookmarkNodeText.subView(0, nMaxTextLen);
518 sBookmarkNodeText += u"…";
521 const OUString& sHideCondition = pBookmark->GetHideCondition();
522 const OUString& sName = pBookmark->GetName();
523 OUString sHidden
524 = (pBookmark->IsHidden() || !sHideCondition.isEmpty() ||
525 // tdf#150955 add "hidden" status to the imported OOXML _Toc and _Ref bookmarks
526 // to allow separating custom bookmarks by sorting based on their Hidden status.
527 // Note: this "hidden" means here only that these bookmarks haven't got
528 // visible bookmark formatting aids (gray I-shape or brackets), otherwise
529 // their anchor are still visible.
530 sName.startsWith("_Toc") || sName.startsWith("_Ref"))
531 ? SwResId(STR_BOOKMARK_YES)
532 : SwResId(STR_BOOKMARK_NO);
534 OUString sPageNum = OUString::number(SwPaM(pMark->GetMarkStart()).GetPageNum());
535 int nRow = m_xControl->n_children();
536 m_xControl->append(weld::toId(pMark), sPageNum);
537 m_xControl->set_text(nRow, sName, 1);
538 m_xControl->set_text(nRow, sBookmarkNodeText, 2);
539 m_xControl->set_text(nRow, sHidden, 3);
540 m_xControl->set_text(nRow, sHideCondition, 4);
543 std::unique_ptr<weld::TreeIter> BookmarkTable::GetRowByBookmarkName(const OUString& sName)
545 std::unique_ptr<weld::TreeIter> xRet;
546 m_xControl->all_foreach([this, &sName, &xRet](weld::TreeIter& rEntry) {
547 sw::mark::MarkBase* pBookmark
548 = weld::fromId<sw::mark::MarkBase*>(m_xControl->get_id(rEntry));
549 if (pBookmark->GetName() == sName)
551 xRet = m_xControl->make_iterator(&rEntry);
552 return true;
554 return false;
556 return xRet;
559 sw::mark::MarkBase* BookmarkTable::GetBookmarkByName(const OUString& sName)
561 auto xEntry = GetRowByBookmarkName(sName);
562 if (!xEntry)
563 return nullptr;
565 return weld::fromId<sw::mark::MarkBase*>(m_xControl->get_id(*xEntry));
568 bool BookmarkTable::SelectByName(const OUString& sName)
570 auto xEntry = GetRowByBookmarkName(sName);
571 if (!xEntry)
572 return false;
573 select(*xEntry);
574 return true;
577 OUString BookmarkTable::GetNameProposal() const
579 OUString sDefaultBookmarkName = SwResId(STR_BOOKMARK_DEF_NAME);
580 sal_Int32 nHighestBookmarkId = 0;
581 for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
583 sw::mark::MarkBase* pBookmark = weld::fromId<sw::mark::MarkBase*>(m_xControl->get_id(i));
584 const OUString& sName = pBookmark->GetName();
585 sal_Int32 nIndex = 0;
586 if (o3tl::getToken(sName, 0, ' ', nIndex) == sDefaultBookmarkName)
588 sal_Int32 nCurrBookmarkId = o3tl::toInt32(o3tl::getToken(sName, 0, ' ', nIndex));
589 nHighestBookmarkId = std::max<sal_Int32>(nHighestBookmarkId, nCurrBookmarkId);
592 return sDefaultBookmarkName + " " + OUString::number(nHighestBookmarkId + 1);
595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */