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>
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)
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
54 OUString sTmp
= m_xEditBox
->get_text();
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
);
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
);
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
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())
102 int nSelectedRows(0);
104 m_xBookmarksBox
->selected_foreach([this, &nSelectedRows
](weld::TreeIter
& rEntry
) {
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
));
114 std::erase(m_aTableBookmarks
, std::make_pair(pBookmark
, sRemoved
));
124 // remove from BookmarkTable
125 m_xBookmarksBox
->remove_selection();
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();
145 IMPL_LINK_NOARG(SwInsertBookmarkDlg
, SelectionChangedHdl
, weld::TreeView
&, void)
147 if (!ValidateBookmarks())
149 // this event should fired only if we change selection by clicking on BookmarkTable entry
150 if (!m_xBookmarksBox
->has_focus())
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
);
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());
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())
194 auto pSelected
= m_xBookmarksBox
->get_selected();
198 m_xBookmarksBox
->start_editing(*pSelected
);
201 IMPL_LINK_NOARG(SwInsertBookmarkDlg
, RenameHdl
, weld::Button
&, void)
203 if (!ValidateBookmarks())
205 auto xSelected
= m_xBookmarksBox
->get_selected();
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
;
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
)
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);
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
)));
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
)));
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
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
);
293 void SwInsertBookmarkDlg::GotoSelectedBookmark()
295 if (!ValidateBookmarks())
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();
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())
315 m_xEditBox
->set_text(u
""_ustr
);
321 bool SwInsertBookmarkDlg::HaveBookmarksChanged()
323 IDocumentMarkAccess
* const pMarkAccess
= m_rSh
.getIDocumentMarkAccess();
324 if (pMarkAccess
->getBookmarksCount() != m_nLastBookmarksCount
)
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())
337 if (aListIter
->first
!= *ppBookmark
|| aListIter
->second
!= (*ppBookmark
)->GetName())
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
)
369 , m_nLastBookmarksCount(0)
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 });
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());
433 if (m_xBookmarksBox
->SelectByName(*pSelected
))
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)
456 m_xBookmarksBox
->make_sorted();
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
);
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
);
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()))
499 void BookmarkTable::InsertBookmark(SwWrtShell
& rSh
, sw::mark::MarkBase
* const pMark
)
501 sw::mark::Bookmark
* pBookmark
= dynamic_cast<sw::mark::Bookmark
*>(pMark
);
504 OUString sBookmarkNodeText
;
505 static const sal_Int32 nMaxTextLen
= 50;
507 if (pBookmark
->IsExpanded())
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();
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
);
559 sw::mark::MarkBase
* BookmarkTable::GetBookmarkByName(const OUString
& sName
)
561 auto xEntry
= GetRowByBookmarkName(sName
);
565 return weld::fromId
<sw::mark::MarkBase
*>(m_xControl
->get_id(*xEntry
));
568 bool BookmarkTable::SelectByName(const OUString
& sName
)
570 auto xEntry
= GetRowByBookmarkName(sName
);
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: */