bump product version to 7.6.3.2-android
[LibreOffice.git] / sw / source / ui / misc / bookmark.cxx
blob4eafb8c1264a2958177001d9437a2d89e6f63cdc
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>
41 using namespace ::com::sun::star;
43 const char BookmarkTable::s_cSeparator(';');
45 // callback to modify EditBox
46 IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, weld::Entry&, void)
48 ValidateBookmarks();
49 m_xBookmarksBox->unselect_all();
50 // if a string has been pasted from the clipboard then
51 // there may be illegal characters in the box
52 // sanitization
53 OUString sTmp = m_xEditBox->get_text();
54 OUString sMsg;
55 const sal_Int32 nLen = sTmp.getLength();
56 for (sal_Int32 i = 0; i < BookmarkTable::aForbiddenChars.getLength(); i++)
58 const sal_Int32 nTmpLen = sTmp.getLength();
59 sTmp = sTmp.replaceAll(OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]), "");
60 if (sTmp.getLength() != nTmpLen)
61 sMsg += OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]);
63 const bool bHasForbiddenChars = sTmp.getLength() != nLen;
64 m_xForbiddenChars->set_visible(bHasForbiddenChars);
65 if (bHasForbiddenChars)
66 m_xEditBox->set_message_type(weld::EntryMessageType::Error);
67 else
68 m_xEditBox->set_message_type(weld::EntryMessageType::Normal);
70 sal_Int32 nSelectedEntries = 0;
71 sal_Int32 nEntries = 0;
72 sal_Int32 nTokenIndex = 0;
73 while (!sTmp.isEmpty() && nTokenIndex >= 0)
75 OUString aToken = sTmp.getToken(0, BookmarkTable::s_cSeparator, nTokenIndex);
76 if (m_xBookmarksBox->GetBookmarkByName(aToken))
78 m_xBookmarksBox->SelectByName(aToken);
79 nSelectedEntries++;
81 nEntries++;
84 // allow to add new bookmark only if one name provided and it's not taken
85 m_xInsertBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 0 && !bHasForbiddenChars
86 && !m_bAreProtected);
88 // allow to delete only if all bookmarks are recognized
89 m_xDeleteBtn->set_sensitive(nEntries > 0 && nSelectedEntries == nEntries && !m_bAreProtected);
90 m_xGotoBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
91 m_xEditTextBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
92 m_xRenameBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1 && !m_bAreProtected);
95 // callback to delete a text mark
96 IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, weld::Button&, void)
98 if (!ValidateBookmarks())
99 return;
101 int nSelectedRows(0);
103 m_xBookmarksBox->selected_foreach([this, &nSelectedRows](weld::TreeIter& rEntry) {
104 // remove from model
105 sw::mark::IMark* pBookmark
106 = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry));
107 OUString sRemoved = pBookmark->GetName();
108 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
109 pMarkAccess->deleteMark(pMarkAccess->findMark(sRemoved), false);
110 SfxRequest aReq(m_rSh.GetView().GetViewFrame(), FN_DELETE_BOOKMARK);
111 aReq.AppendItem(SfxStringItem(FN_DELETE_BOOKMARK, sRemoved));
112 aReq.Done();
113 m_aTableBookmarks.erase(std::remove(m_aTableBookmarks.begin(), m_aTableBookmarks.end(),
114 std::make_pair(pBookmark, sRemoved)),
115 m_aTableBookmarks.end());
117 ++nSelectedRows;
119 return false;
122 if (!nSelectedRows)
123 return;
125 // remove from BookmarkTable
126 m_xBookmarksBox->remove_selection();
128 ValidateBookmarks();
130 m_xDeleteBtn->set_sensitive(false);
131 m_xGotoBtn->set_sensitive(false);
132 m_xEditTextBtn->set_sensitive(false);
133 m_xRenameBtn->set_sensitive(false);
134 m_xInsertBtn->set_sensitive(false);
137 // callback to a goto button
138 IMPL_LINK_NOARG(SwInsertBookmarkDlg, GotoHdl, weld::Button&, void) { GotoSelectedBookmark(); }
140 IMPL_LINK_NOARG(SwInsertBookmarkDlg, DoubleClickHdl, weld::TreeView&, bool)
142 GotoSelectedBookmark();
143 return true;
146 IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, weld::TreeView&, void)
148 if (!ValidateBookmarks())
149 return;
150 // this event should fired only if we change selection by clicking on BookmarkTable entry
151 if (!m_xBookmarksBox->has_focus())
152 return;
154 SelectionChanged();
157 void SwInsertBookmarkDlg::SelectionChanged()
159 OUStringBuffer sEditBoxText;
160 int nSelectedRows = 0;
161 m_xBookmarksBox->selected_foreach(
162 [this, &sEditBoxText, &nSelectedRows](weld::TreeIter& rEntry) {
163 sw::mark::IMark* pBookmark
164 = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry));
165 const OUString& sEntryName = pBookmark->GetName();
166 if (!sEditBoxText.isEmpty())
167 sEditBoxText.append(";");
168 sEditBoxText.append(sEntryName);
169 ++nSelectedRows;
170 return false;
172 if (nSelectedRows)
174 m_xInsertBtn->set_sensitive(false);
175 m_xGotoBtn->set_sensitive(nSelectedRows == 1);
176 m_xEditTextBtn->set_sensitive(nSelectedRows == 1);
177 m_xRenameBtn->set_sensitive(nSelectedRows == 1 && !m_bAreProtected);
178 m_xDeleteBtn->set_sensitive(!m_bAreProtected);
179 m_xEditBox->set_text(sEditBoxText.makeStringAndClear());
181 else
183 m_xInsertBtn->set_sensitive(!m_bAreProtected);
184 m_xGotoBtn->set_sensitive(false);
185 m_xEditTextBtn->set_sensitive(false);
186 m_xRenameBtn->set_sensitive(false);
187 m_xDeleteBtn->set_sensitive(false);
191 IMPL_LINK_NOARG(SwInsertBookmarkDlg, EditTextHdl, weld::Button&, void)
193 if (!ValidateBookmarks())
194 return;
195 auto pSelected = m_xBookmarksBox->get_selected();
196 if (!pSelected)
197 return;
199 m_xBookmarksBox->start_editing(*pSelected);
202 IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, weld::Button&, void)
204 if (!ValidateBookmarks())
205 return;
206 auto xSelected = m_xBookmarksBox->get_selected();
207 if (!xSelected)
208 return;
210 sw::mark::IMark* pBookmark
211 = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected));
212 uno::Reference<frame::XModel> xModel = m_rSh.GetView().GetDocShell()->GetBaseModel();
213 uno::Reference<text::XBookmarksSupplier> xBkms(xModel, uno::UNO_QUERY);
214 uno::Reference<container::XNameAccess> xNameAccess = xBkms->getBookmarks();
215 uno::Any aObj = xNameAccess->getByName(pBookmark->GetName());
216 uno::Reference<uno::XInterface> xTmp;
217 aObj >>= xTmp;
218 uno::Reference<container::XNamed> xNamed(xTmp, uno::UNO_QUERY);
219 SwAbstractDialogFactory& rFact = swui::GetFactory();
220 ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(
221 rFact.CreateSwRenameXNamedDlg(m_xDialog.get(), xNamed, xNameAccess));
222 pDlg->SetForbiddenChars(BookmarkTable::aForbiddenChars
223 + OUStringChar(BookmarkTable::s_cSeparator));
225 if (pDlg->Execute())
227 ValidateBookmarks();
228 m_xDeleteBtn->set_sensitive(false);
229 m_xGotoBtn->set_sensitive(false);
230 m_xEditTextBtn->set_sensitive(false);
231 m_xRenameBtn->set_sensitive(false);
232 m_xInsertBtn->set_sensitive(false);
236 // callback to an insert button. Inserts a new text mark to the current position.
237 IMPL_LINK_NOARG(SwInsertBookmarkDlg, InsertHdl, weld::Button&, void)
239 OUString sBookmark = m_xEditBox->get_text();
240 m_rSh.SetBookmark2(vcl::KeyCode(), sBookmark, m_xHideCB->get_active(),
241 m_xConditionED->get_text());
243 m_xDialog->response(RET_OK);
246 IMPL_LINK(SwInsertBookmarkDlg, ChangeHideHdl, weld::Toggleable&, rBox, void)
248 bool bHide = rBox.get_active();
249 m_xConditionED->set_sensitive(bHide);
250 m_xConditionFT->set_sensitive(bHide);
253 IMPL_LINK(SwInsertBookmarkDlg, EditingHdl, weld::TreeIter const&, rIter, bool)
255 sw::mark::IMark const* const pBookmark(
256 weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rIter)));
257 assert(pBookmark);
258 return pBookmark->IsExpanded()
259 && pBookmark->GetMarkPos().GetNode() == pBookmark->GetOtherMarkPos().GetNode()
260 && !m_xBookmarksBox->get_text(rIter).endsWith(u"…");
263 IMPL_LINK(SwInsertBookmarkDlg, EditedHdl, weld::TreeView::iter_string const&, rIterString, bool)
265 sw::mark::IMark const* const pBookmark(
266 weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rIterString.first)));
267 assert(pBookmark);
268 bool bRet(false);
269 if (pBookmark->GetMarkPos() != pBookmark->GetOtherMarkPos())
271 if (pBookmark->GetMarkPos().GetNode() != pBookmark->GetOtherMarkPos().GetNode())
273 return false; // don't allow editing if it spans multiple nodes
275 m_rSh.Push();
276 m_rSh.GotoMark(pBookmark);
277 // GetSelText only works for 1 paragraph, but it's checked above
278 if (m_rSh.GetSelText() != rIterString.second)
280 bRet = m_rSh.Replace(rIterString.second, false);
282 m_rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
284 else if (pBookmark->IsExpanded() && !rIterString.second.isEmpty())
285 { // SwEditShell::Replace does nothing for empty selection
286 m_rSh.Insert(rIterString.second);
287 bRet = true;
289 return bRet;
292 void SwInsertBookmarkDlg::GotoSelectedBookmark()
294 if (!ValidateBookmarks())
295 return;
296 // if no entries selected we can't jump anywhere
297 // shouldn't be needed as we disable GoTo button when jump is not possible
298 auto xSelected = m_xBookmarksBox->get_selected();
299 if (!xSelected)
300 return;
302 sw::mark::IMark* pBookmark
303 = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected));
305 m_rSh.EnterStdMode();
306 m_rSh.GotoMark(pBookmark);
309 bool SwInsertBookmarkDlg::ValidateBookmarks()
311 if (HaveBookmarksChanged())
313 PopulateTable();
314 m_xEditBox->set_text("");
315 return false;
317 return true;
320 bool SwInsertBookmarkDlg::HaveBookmarksChanged()
322 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
323 if (pMarkAccess->getBookmarksCount() != m_nLastBookmarksCount)
324 return true;
326 std::vector<std::pair<sw::mark::IMark*, OUString>>::const_iterator aListIter
327 = m_aTableBookmarks.begin();
328 for (IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
329 ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
331 if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
333 // more bookmarks then expected
334 if (aListIter == m_aTableBookmarks.end())
335 return true;
336 if (aListIter->first != *ppBookmark || aListIter->second != (*ppBookmark)->GetName())
337 return true;
338 ++aListIter;
341 // less bookmarks then expected
342 return aListIter != m_aTableBookmarks.end();
345 void SwInsertBookmarkDlg::PopulateTable()
347 m_aTableBookmarks.clear();
348 m_xBookmarksBox->clear();
350 IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
351 for (IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
352 ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
354 if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
356 m_xBookmarksBox->InsertBookmark(m_rSh, *ppBookmark);
357 m_aTableBookmarks.emplace_back(*ppBookmark, (*ppBookmark)->GetName());
360 m_nLastBookmarksCount = pMarkAccess->getBookmarksCount();
363 SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* pParent, SwWrtShell& rS,
364 OUString const* const pSelected)
365 : SfxDialogController(pParent, "modules/swriter/ui/insertbookmark.ui", "InsertBookmarkDialog")
366 , m_rSh(rS)
367 , m_nLastBookmarksCount(0)
368 , m_bSorted(false)
369 , m_xEditBox(m_xBuilder->weld_entry("name"))
370 , m_xInsertBtn(m_xBuilder->weld_button("insert"))
371 , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
372 , m_xGotoBtn(m_xBuilder->weld_button("goto"))
373 , m_xEditTextBtn(m_xBuilder->weld_button("edittext"))
374 , m_xRenameBtn(m_xBuilder->weld_button("rename"))
375 , m_xHideCB(m_xBuilder->weld_check_button("hide"))
376 , m_xConditionFT(m_xBuilder->weld_label("condlabel"))
377 , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("withcond")))
378 , m_xBookmarksBox(new BookmarkTable(m_xBuilder->weld_tree_view("bookmarks")))
379 , m_xForbiddenChars(m_xBuilder->weld_label("lbForbiddenChars"))
381 m_xBookmarksBox->connect_changed(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl));
382 m_xBookmarksBox->connect_row_activated(LINK(this, SwInsertBookmarkDlg, DoubleClickHdl));
383 m_xBookmarksBox->connect_column_clicked(LINK(this, SwInsertBookmarkDlg, HeaderBarClick));
384 m_xBookmarksBox->connect_editing(LINK(this, SwInsertBookmarkDlg, EditingHdl),
385 LINK(this, SwInsertBookmarkDlg, EditedHdl));
386 m_xEditBox->connect_changed(LINK(this, SwInsertBookmarkDlg, ModifyHdl));
387 m_xInsertBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, InsertHdl));
388 m_xDeleteBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, DeleteHdl));
389 m_xGotoBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, GotoHdl));
390 m_xEditTextBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, EditTextHdl));
391 m_xRenameBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, RenameHdl));
392 m_xHideCB->connect_toggled(LINK(this, SwInsertBookmarkDlg, ChangeHideHdl));
394 m_xDeleteBtn->set_sensitive(false);
395 m_xGotoBtn->set_sensitive(false);
396 m_xEditTextBtn->set_sensitive(false);
397 m_xRenameBtn->set_sensitive(false);
399 // select 3rd column, otherwise it'll pick 1st one
400 m_xBookmarksBox->set_column_editables({ false, false, true, false, false });
402 PopulateTable();
404 m_xEditBox->set_text(m_xBookmarksBox->GetNameProposal());
405 m_xEditBox->set_position(-1);
407 m_xForbiddenChars->set_label(SwResId(STR_BOOKMARK_FORBIDDENCHARS) + " "
408 + BookmarkTable::aForbiddenChars);
409 m_xForbiddenChars->set_visible(false);
411 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
413 m_xHideCB->set_visible(false);
414 m_xConditionFT->set_visible(false);
415 m_xConditionED->set_visible(false);
418 m_bAreProtected = m_rSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS);
420 // disabled until "Hide" flag is not checked
421 m_xConditionED->set_sensitive(false);
422 m_xConditionFT->set_sensitive(false);
424 // restore dialog size
425 SvtViewOptions aDlgOpt(EViewType::Dialog, "BookmarkDialog");
426 if (aDlgOpt.Exists())
427 m_xDialog->set_window_state(aDlgOpt.GetWindowState());
429 if (pSelected)
431 if (m_xBookmarksBox->SelectByName(*pSelected))
433 SelectionChanged();
434 // which is better, focus on a button or focus on the table row?
435 // as long as editing doesn't work via the TreeView with VCL
436 // widgets, better on button.
437 m_xEditTextBtn->grab_focus();
442 SwInsertBookmarkDlg::~SwInsertBookmarkDlg()
444 // tdf#146261 - Remember size of bookmark dialog
445 SvtViewOptions aDlgOpt(EViewType::Dialog, "BookmarkDialog");
446 OUString sWindowState = m_xDialog->get_window_state(vcl::WindowDataMask::PosSize);
447 aDlgOpt.SetWindowState(sWindowState);
450 IMPL_LINK(SwInsertBookmarkDlg, HeaderBarClick, int, nColumn, void)
452 if (!m_bSorted)
454 m_xBookmarksBox->make_sorted();
455 m_bSorted = true;
458 bool bSortAtoZ = m_xBookmarksBox->get_sort_order();
460 //set new arrow positions in headerbar
461 if (nColumn == m_xBookmarksBox->get_sort_column())
463 bSortAtoZ = !bSortAtoZ;
464 m_xBookmarksBox->set_sort_order(bSortAtoZ);
466 else
468 int nOldSortColumn = m_xBookmarksBox->get_sort_column();
469 if (nOldSortColumn != -1)
470 m_xBookmarksBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
471 m_xBookmarksBox->set_sort_column(nColumn);
474 if (nColumn != -1)
476 //sort lists
477 m_xBookmarksBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
481 BookmarkTable::BookmarkTable(std::unique_ptr<weld::TreeView> xControl)
482 : m_xControl(std::move(xControl))
484 m_xControl->set_size_request(-1, m_xControl->get_height_rows(8));
485 m_xControl->set_column_fixed_widths({ 40, 110, 150, 160 });
486 m_xControl->set_selection_mode(SelectionMode::Multiple);
489 std::unique_ptr<weld::TreeIter> BookmarkTable::get_selected() const
491 std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator());
492 if (!m_xControl->get_selected(xIter.get()))
493 xIter.reset();
494 return xIter;
497 void BookmarkTable::InsertBookmark(SwWrtShell& rSh, sw::mark::IMark* const pMark)
499 sw::mark::IBookmark* pBookmark = dynamic_cast<sw::mark::IBookmark*>(pMark);
500 assert(pBookmark);
502 OUString sBookmarkNodeText;
503 static const sal_Int32 nMaxTextLen = 50;
505 if (pBookmark->IsExpanded())
507 rSh.Push();
508 rSh.GotoMark(pBookmark);
509 rSh.GetSelectedText(sBookmarkNodeText, ParaBreakType::ToBlank);
510 rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
512 if (nMaxTextLen < sBookmarkNodeText.getLength())
514 sBookmarkNodeText = sBookmarkNodeText.subView(0, nMaxTextLen);
516 sBookmarkNodeText += u"…";
519 const OUString& sHideCondition = pBookmark->GetHideCondition();
520 const OUString& sName = pBookmark->GetName();
521 OUString sHidden
522 = (pBookmark->IsHidden() || !sHideCondition.isEmpty() ||
523 // tdf#150955 add "hidden" status to the imported OOXML _Toc and _Ref bookmarks
524 // to allow separating custom bookmarks by sorting based on their Hidden status.
525 // Note: this "hidden" means here only that these bookmarks haven't got
526 // visible bookmark formatting aids (gray I-shape or brackets), otherwise
527 // their anchor are still visible.
528 sName.startsWith("_Toc") || sName.startsWith("_Ref"))
529 ? SwResId(STR_BOOKMARK_YES)
530 : SwResId(STR_BOOKMARK_NO);
532 OUString sPageNum = OUString::number(SwPaM(pMark->GetMarkStart()).GetPageNum());
533 int nRow = m_xControl->n_children();
534 m_xControl->append(weld::toId(pMark), sPageNum);
535 m_xControl->set_text(nRow, sName, 1);
536 m_xControl->set_text(nRow, sBookmarkNodeText, 2);
537 m_xControl->set_text(nRow, sHidden, 3);
538 m_xControl->set_text(nRow, sHideCondition, 4);
541 std::unique_ptr<weld::TreeIter> BookmarkTable::GetRowByBookmarkName(const OUString& sName)
543 std::unique_ptr<weld::TreeIter> xRet;
544 m_xControl->all_foreach([this, &sName, &xRet](weld::TreeIter& rEntry) {
545 sw::mark::IMark* pBookmark = weld::fromId<sw::mark::IMark*>(m_xControl->get_id(rEntry));
546 if (pBookmark->GetName() == sName)
548 xRet = m_xControl->make_iterator(&rEntry);
549 return true;
551 return false;
553 return xRet;
556 sw::mark::IMark* BookmarkTable::GetBookmarkByName(const OUString& sName)
558 auto xEntry = GetRowByBookmarkName(sName);
559 if (!xEntry)
560 return nullptr;
562 return weld::fromId<sw::mark::IMark*>(m_xControl->get_id(*xEntry));
565 bool BookmarkTable::SelectByName(const OUString& sName)
567 auto xEntry = GetRowByBookmarkName(sName);
568 if (!xEntry)
569 return false;
570 select(*xEntry);
571 return true;
574 OUString BookmarkTable::GetNameProposal() const
576 OUString sDefaultBookmarkName = SwResId(STR_BOOKMARK_DEF_NAME);
577 sal_Int32 nHighestBookmarkId = 0;
578 for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
580 sw::mark::IMark* pBookmark = weld::fromId<sw::mark::IMark*>(m_xControl->get_id(i));
581 const OUString& sName = pBookmark->GetName();
582 sal_Int32 nIndex = 0;
583 if (o3tl::getToken(sName, 0, ' ', nIndex) == sDefaultBookmarkName)
585 sal_Int32 nCurrBookmarkId = o3tl::toInt32(o3tl::getToken(sName, 0, ' ', nIndex));
586 nHighestBookmarkId = std::max<sal_Int32>(nHighestBookmarkId, nCurrBookmarkId);
589 return sDefaultBookmarkName + " " + OUString::number(nHighestBookmarkId + 1);
592 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */