1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <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>
35 #include <bookmark.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)
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
53 OUString sTmp
= m_xEditBox
->get_text();
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
);
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
);
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
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())
101 int nSelectedRows(0);
103 m_xBookmarksBox
->selected_foreach([this, &nSelectedRows
](weld::TreeIter
& rEntry
) {
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
));
113 m_aTableBookmarks
.erase(std::remove(m_aTableBookmarks
.begin(), m_aTableBookmarks
.end(),
114 std::make_pair(pBookmark
, sRemoved
)),
115 m_aTableBookmarks
.end());
125 // remove from BookmarkTable
126 m_xBookmarksBox
->remove_selection();
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();
146 IMPL_LINK_NOARG(SwInsertBookmarkDlg
, SelectionChangedHdl
, weld::TreeView
&, void)
148 if (!ValidateBookmarks())
150 // this event should fired only if we change selection by clicking on BookmarkTable entry
151 if (!m_xBookmarksBox
->has_focus())
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
);
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());
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())
195 auto pSelected
= m_xBookmarksBox
->get_selected();
199 m_xBookmarksBox
->start_editing(*pSelected
);
202 IMPL_LINK_NOARG(SwInsertBookmarkDlg
, RenameHdl
, weld::Button
&, void)
204 if (!ValidateBookmarks())
206 auto xSelected
= m_xBookmarksBox
->get_selected();
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
;
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
));
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
)));
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
)));
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
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
);
292 void SwInsertBookmarkDlg::GotoSelectedBookmark()
294 if (!ValidateBookmarks())
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();
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())
314 m_xEditBox
->set_text("");
320 bool SwInsertBookmarkDlg::HaveBookmarksChanged()
322 IDocumentMarkAccess
* const pMarkAccess
= m_rSh
.getIDocumentMarkAccess();
323 if (pMarkAccess
->getBookmarksCount() != m_nLastBookmarksCount
)
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())
336 if (aListIter
->first
!= *ppBookmark
|| aListIter
->second
!= (*ppBookmark
)->GetName())
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")
367 , m_nLastBookmarksCount(0)
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 });
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());
431 if (m_xBookmarksBox
->SelectByName(*pSelected
))
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)
454 m_xBookmarksBox
->make_sorted();
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
);
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
);
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()))
497 void BookmarkTable::InsertBookmark(SwWrtShell
& rSh
, sw::mark::IMark
* const pMark
)
499 sw::mark::IBookmark
* pBookmark
= dynamic_cast<sw::mark::IBookmark
*>(pMark
);
502 OUString sBookmarkNodeText
;
503 static const sal_Int32 nMaxTextLen
= 50;
505 if (pBookmark
->IsExpanded())
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();
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
);
556 sw::mark::IMark
* BookmarkTable::GetBookmarkByName(const OUString
& sName
)
558 auto xEntry
= GetRowByBookmarkName(sName
);
562 return weld::fromId
<sw::mark::IMark
*>(m_xControl
->get_id(*xEntry
));
565 bool BookmarkTable::SelectByName(const OUString
& sName
)
567 auto xEntry
= GetRowByBookmarkName(sName
);
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: */