tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / cui / source / dialogs / linkdlg.cxx
blobd78dd2bbc6d64e9c6a4a447c3e7de508ef56f452
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 <linkdlg.hxx>
21 #include <o3tl/safeint.hxx>
22 #include <vcl/svapp.hxx>
24 #include <comphelper/diagnose_ex.hxx>
25 #include <tools/debug.hxx>
26 #include <tools/urlobj.hxx>
27 #include <vcl/idle.hxx>
28 #include <vcl/timer.hxx>
29 #include <vcl/weld.hxx>
30 #include <vcl/weldutils.hxx>
32 #include <strings.hrc>
33 #include <sfx2/filedlghelper.hxx>
34 #include <sfx2/linkmgr.hxx>
35 #include <sfx2/linksrc.hxx>
36 #include <sfx2/lnkbase.hxx>
37 #include <sfx2/objsh.hxx>
39 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
40 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
41 #include <comphelper/processfactory.hxx>
43 #include <dialmgr.hxx>
46 using namespace sfx2;
47 using namespace ::com::sun::star;
49 namespace {
51 class SvBaseLinkMemberList {
52 private:
53 std::vector<SvBaseLink*> mLinks;
55 public:
56 ~SvBaseLinkMemberList()
58 for (auto const& link : mLinks)
60 if( link )
61 link->ReleaseRef();
65 size_t size() const { return mLinks.size(); }
67 SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
69 void push_back(SvBaseLink* p)
71 mLinks.push_back(p);
72 p->AddFirstRef();
78 SvBaseLinksDlg::SvBaseLinksDlg(weld::Window * pParent, LinkManager* pMgr, bool bHtmlMode)
79 : GenericDialogController(pParent, u"cui/ui/baselinksdialog.ui"_ustr, u"BaseLinksDialog"_ustr)
80 , aStrAutolink( CuiResId( STR_AUTOLINK ) )
81 , aStrManuallink( CuiResId( STR_MANUALLINK ) )
82 , aStrBrokenlink( CuiResId( STR_BROKENLINK ) )
83 , aStrCloselinkmsg( CuiResId( STR_CLOSELINKMSG ) )
84 , aStrCloselinkmsgMulti( CuiResId( STR_CLOSELINKMSG_MULTI ) )
85 , aStrWaitinglink( CuiResId( STR_WAITINGLINK ) )
86 , pLinkMgr( nullptr )
87 , aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
88 , m_xTbLinks(m_xBuilder->weld_tree_view(u"TB_LINKS"_ustr))
89 , m_xFtFullFileName(m_xBuilder->weld_link_button(u"FULL_FILE_NAME"_ustr))
90 , m_xFtFullSourceName(m_xBuilder->weld_label(u"FULL_SOURCE_NAME"_ustr))
91 , m_xFtFullTypeName(m_xBuilder->weld_label(u"FULL_TYPE_NAME"_ustr))
92 , m_xRbAutomatic(m_xBuilder->weld_radio_button(u"AUTOMATIC"_ustr))
93 , m_xRbManual(m_xBuilder->weld_radio_button(u"MANUAL"_ustr))
94 , m_xPbUpdateNow(m_xBuilder->weld_button(u"UPDATE_NOW"_ustr))
95 , m_xPbChangeSource(m_xBuilder->weld_button(u"CHANGE_SOURCE"_ustr))
96 , m_xPbBreakLink(m_xBuilder->weld_button(u"BREAK_LINK"_ustr))
97 , m_xVirDev(VclPtr<VirtualDevice>::Create())
99 // expand the point size of the desired font to the equivalent pixel size
100 weld::SetPointFont(*m_xVirDev, m_xTbLinks->get_font());
101 m_xTbLinks->set_size_request(m_xTbLinks->get_approximate_digit_width() * 90,
102 m_xTbLinks->get_height_rows(12));
104 m_xTbLinks->set_selection_mode(SelectionMode::Multiple);
106 std::vector<int> aWidths
108 o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 30),
109 o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 20),
110 o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 20)
112 m_xTbLinks->set_column_fixed_widths(aWidths);
114 // UpdateTimer for DDE-/Grf-links, which are waited for
115 aUpdateIdle.SetInvokeHandler( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
116 aUpdateIdle.SetPriority( TaskPriority::LOWEST );
118 m_xTbLinks->connect_selection_changed(LINK(this, SvBaseLinksDlg, LinksSelectHdl));
119 m_xTbLinks->connect_row_activated( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
120 m_xRbAutomatic->connect_toggled( LINK( this, SvBaseLinksDlg, ToggleHdl ) );
121 m_xRbManual->connect_toggled( LINK( this, SvBaseLinksDlg, ToggleHdl ) );
122 m_xPbUpdateNow->connect_clicked( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
123 m_xPbChangeSource->connect_clicked( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
124 if(!bHtmlMode)
125 m_xPbBreakLink->connect_clicked( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
126 else
127 m_xPbBreakLink->hide();
129 SetManager( pMgr );
132 SvBaseLinksDlg::~SvBaseLinksDlg()
136 /*************************************************************************
137 |* SvBaseLinksDlg::Handler()
138 *************************************************************************/
139 IMPL_LINK(SvBaseLinksDlg, LinksSelectHdl, weld::TreeView&, rTreeView, void)
141 LinksSelectHdl(&rTreeView);
144 void SvBaseLinksDlg::LinksSelectHdl(weld::TreeView* pSvTabListBox)
146 const int nSelectionCount = pSvTabListBox ?
147 pSvTabListBox->count_selected_rows() : 0;
148 if (nSelectionCount > 1)
150 // possibly deselect old entries in case of multi-selection
151 int nSelEntry = pSvTabListBox->get_selected_index();
152 SvBaseLink* pLink = weld::fromId<SvBaseLink*>(pSvTabListBox->get_id(nSelEntry));
153 SvBaseLinkObjectType nObjectType = pLink->GetObjType();
154 if(!isClientFileType(nObjectType))
156 pSvTabListBox->unselect_all();
157 pSvTabListBox->select(nSelEntry);
159 else
161 std::vector<int> aRows = pSvTabListBox->get_selected_rows();
162 for (auto nEntry : aRows)
164 pLink = weld::fromId<SvBaseLink*>(pSvTabListBox->get_id(nEntry));
165 DBG_ASSERT(pLink, "Where is the Link?");
166 if (!pLink)
167 continue;
168 if( !isClientFileType(pLink->GetObjType()) )
169 pSvTabListBox->unselect(nEntry);
173 m_xPbUpdateNow->set_sensitive(true);
174 m_xRbAutomatic->set_sensitive(false);
175 m_xRbManual->set_active(true);
176 m_xRbManual->set_sensitive(false);
178 else
180 int nPos;
181 SvBaseLink* pLink = GetSelEntry( &nPos );
182 if( !pLink )
183 return;
185 m_xPbUpdateNow->set_sensitive(true);
187 OUString sType, sLink;
188 OUString *pLinkNm = &sLink, *pFilter = nullptr;
190 if( isClientFileType(pLink->GetObjType()) )
192 m_xRbAutomatic->set_sensitive(false);
193 m_xRbManual->set_active(true);
194 m_xRbManual->set_sensitive(false);
195 if( SvBaseLinkObjectType::ClientGraphic == pLink->GetObjType() )
197 pLinkNm = nullptr;
198 pFilter = &sLink;
201 else
203 m_xRbAutomatic->set_sensitive(true);
204 m_xRbManual->set_sensitive(true);
206 if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
207 m_xRbAutomatic->set_active(true);
208 else
209 m_xRbManual->set_active(true);
212 OUString aFileName;
213 sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
214 aFileName = INetURLObject::decode(aFileName, INetURLObject::DecodeMechanism::Unambiguous);
215 m_xFtFullFileName->set_label( aFileName );
216 m_xFtFullFileName->set_uri( aFileName );
217 m_xFtFullSourceName->set_label( sLink );
218 m_xFtFullTypeName->set_label( sType );
222 IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, weld::TreeView&, bool )
224 ChangeSourceClickHdl(*m_xPbChangeSource);
225 return true;
228 IMPL_LINK(SvBaseLinksDlg, ToggleHdl, weld::Toggleable&, rButton, void)
230 if (!rButton.get_active())
231 return;
233 int nPos;
234 SvBaseLink* pLink = GetSelEntry( &nPos );
236 if (m_xRbAutomatic->get_active())
238 if( pLink && !isClientFileType( pLink->GetObjType() ) &&
239 SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
240 SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
242 else
244 if( pLink && !isClientFileType( pLink->GetObjType() ) &&
245 SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
246 SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
250 IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, weld::Button&, void)
252 std::vector< SvBaseLink* > aLnkArr;
253 std::vector< sal_Int16 > aPosArr;
255 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
256 for (int nFndPos : aRows)
258 aLnkArr.push_back( weld::fromId<SvBaseLink*>( m_xTbLinks->get_id(nFndPos) ) );
259 aPosArr.push_back( nFndPos );
262 if( aLnkArr.empty() )
263 return;
265 for( size_t n = 0; n < aLnkArr.size(); ++n )
267 tools::SvRef<SvBaseLink> xLink = aLnkArr[ n ];
269 // first look for the entry in the array
270 for(const auto & i : pLinkMgr->GetLinks())
271 if( xLink == i )
273 SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
274 break;
278 // if somebody is of the opinion to swap his links (SD)
279 LinkManager* pNewMgr = pLinkMgr;
280 pLinkMgr = nullptr;
281 SetManager( pNewMgr );
284 OUString sId = weld::toId(aLnkArr[0]);
285 int nE = m_xTbLinks->find_id(sId);
286 if (nE == -1)
287 nE = m_xTbLinks->get_selected_index();
288 int nSelEntry = m_xTbLinks->get_selected_index();
289 if (nE != nSelEntry)
290 m_xTbLinks->unselect(nSelEntry);
291 m_xTbLinks->select(nE);
292 m_xTbLinks->scroll_to_row(nE);
294 pNewMgr->CloseCachedComps();
297 IMPL_LINK_NOARG(SvBaseLinksDlg, ChangeSourceClickHdl, weld::Button&, void)
299 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
300 if (aRows.size() > 1)
304 uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
305 comphelper::getProcessComponentContext(), m_xDialog.get());
307 OUString sType, sFile, sLinkName;
308 OUString sFilter;
309 SvBaseLink* pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(aRows[0]));
310 sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile );
311 INetURLObject aUrl(sFile);
312 if(aUrl.GetProtocol() == INetProtocol::File)
314 OUString sOldPath(aUrl.PathToFileName());
315 sal_Int32 nLen = aUrl.GetLastName().getLength();
316 sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
317 xFolderPicker->setDisplayDirectory(sOldPath);
319 if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
321 OUString aPath = xFolderPicker->getDirectory();
323 for (auto nRow : aRows)
325 pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nRow));
326 DBG_ASSERT(pLink,"Where is the link?");
327 if (!pLink)
328 continue;
329 sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
330 INetURLObject aUrl_(sFile);
331 INetURLObject aUrl2(aPath, INetProtocol::File);
332 aUrl2.insertName( aUrl_.getName() );
333 OUString sNewLinkName;
334 MakeLnkName( sNewLinkName, nullptr ,
335 aUrl2.GetMainURL(INetURLObject::DecodeMechanism::ToIUri), sLinkName, &sFilter);
336 pLink->SetLinkSourceName( sNewLinkName );
337 pLink->Update();
339 if( pLinkMgr->GetPersist() )
340 pLinkMgr->GetPersist()->SetModified();
341 LinkManager* pNewMgr = pLinkMgr;
342 pLinkMgr = nullptr;
343 SetManager( pNewMgr );
346 catch (const uno::Exception &)
348 TOOLS_WARN_EXCEPTION("cui.dialogs", "SvBaseLinksDlg");
351 else
353 int nPos;
354 SvBaseLink* pLink = GetSelEntry( &nPos );
355 if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
356 pLink->Edit(m_xDialog.get(), LINK(this, SvBaseLinksDlg, EndEditHdl));
360 IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, weld::Button&, void )
362 bool bModified = false;
363 if (m_xTbLinks->count_selected_rows() <= 1)
365 int nPos;
366 tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
367 if( !xLink.is() )
368 return;
370 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
371 VclMessageType::Question, VclButtonsType::YesNo,
372 aStrCloselinkmsg));
373 xQueryBox->set_default_response(RET_YES);
375 if (RET_YES == xQueryBox->run())
377 m_xTbLinks->remove(nPos);
379 // close object, if it's still existing
380 bool bNewLnkMgr = SvBaseLinkObjectType::ClientFile == xLink->GetObjType();
382 // tell the link that it will be resolved!
383 xLink->Closed();
385 // if somebody has forgotten to deregister himself
386 if( xLink.is() )
387 pLinkMgr->Remove( xLink.get() );
389 if( bNewLnkMgr )
391 LinkManager* pNewMgr = pLinkMgr;
392 pLinkMgr = nullptr;
393 SetManager( pNewMgr );
394 m_xTbLinks->set_cursor(nPos ? --nPos : 0);
396 bModified = true;
399 else
401 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
402 VclMessageType::Question, VclButtonsType::YesNo,
403 aStrCloselinkmsgMulti));
404 xQueryBox->set_default_response(RET_YES);
406 if (RET_YES == xQueryBox->run())
408 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
409 SvBaseLinkMemberList aLinkList;
410 for (auto nRow : aRows)
412 SvBaseLink* pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nRow));
413 if (pLink)
414 aLinkList.push_back(pLink);
416 std::sort(aRows.begin(), aRows.end());
417 for (auto it = aRows.rbegin(); it != aRows.rend(); ++it)
418 m_xTbLinks->remove(*it);
419 for (size_t i = 0; i < aLinkList.size(); ++i)
421 tools::SvRef<SvBaseLink> xLink = aLinkList[i];
422 // tell the link that it will be resolved!
423 xLink->Closed();
425 // if somebody has forgotten to deregister himself
426 pLinkMgr->Remove( xLink.get() );
427 bModified = true;
429 // then remove all selected entries
432 if(!bModified)
433 return;
435 if (!m_xTbLinks->n_children())
437 m_xRbAutomatic->set_sensitive(false);
438 m_xRbManual->set_sensitive(false);
439 m_xPbUpdateNow->set_sensitive(false);
440 m_xPbChangeSource->set_sensitive(false);
441 m_xPbBreakLink->set_sensitive(false);
443 m_xFtFullSourceName->set_label( u""_ustr );
444 m_xFtFullTypeName->set_label( u""_ustr );
446 if( pLinkMgr && pLinkMgr->GetPersist() )
447 pLinkMgr->GetPersist()->SetModified();
450 IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, void )
452 m_xTbLinks->freeze();
453 for (int nPos = m_xTbLinks->n_children(); nPos; --nPos)
455 tools::SvRef<SvBaseLink> xLink( weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos)) );
456 if( xLink.is() )
458 OUString sCur( ImplGetStateStr( *xLink ) ),
459 sOld( m_xTbLinks->get_text(nPos, 3) );
460 if( sCur != sOld )
461 m_xTbLinks->set_text(nPos, sCur, 3);
464 m_xTbLinks->thaw();
467 IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
469 int nPos;
470 GetSelEntry( &nPos );
472 if( !_rLink.WasLastEditOK() )
473 return;
475 // StarImpress/Draw swap the LinkObjects themselves!
476 // So search for the link in the manager; if it does not exist
477 // anymore, fill the list completely new. Otherwise only the
478 // edited link needs to be refreshed.
479 bool bLinkFnd = false;
480 for( size_t n = pLinkMgr->GetLinks().size(); n; )
481 if( &_rLink == &(*pLinkMgr->GetLinks()[ --n ]) )
483 bLinkFnd = true;
484 break;
487 if( bLinkFnd )
489 m_xTbLinks->remove(nPos);
490 int nToUnselect = m_xTbLinks->get_selected_index();
491 InsertEntry(_rLink, nPos, true);
492 if (nToUnselect != -1)
493 m_xTbLinks->unselect(nToUnselect);
495 else
497 LinkManager* pNewMgr = pLinkMgr;
498 pLinkMgr = nullptr;
499 SetManager( pNewMgr );
501 if (pLinkMgr && pLinkMgr->GetPersist())
502 pLinkMgr->GetPersist()->SetModified();
505 OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
507 OUString sRet;
508 if( !rLnk.GetObj() )
509 sRet = aStrBrokenlink;
510 else if( rLnk.GetObj()->IsPending() )
512 sRet = aStrWaitinglink;
513 aUpdateIdle.Start();
515 else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
516 sRet = aStrAutolink;
517 else
518 sRet = aStrManuallink;
520 return sRet;
523 void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
525 if( pLinkMgr == pNewMgr )
526 return;
528 if (pNewMgr)
530 // update has to be stopped before clear
531 m_xTbLinks->freeze();
534 m_xTbLinks->clear();
535 pLinkMgr = pNewMgr;
537 if( !pLinkMgr )
538 return;
540 SvBaseLinks& rLnks = const_cast<SvBaseLinks&>(pLinkMgr->GetLinks());
541 for( size_t n = 0; n < rLnks.size(); ++n )
543 tools::SvRef<SvBaseLink>& rLinkRef = rLnks[ n ];
544 if( !rLinkRef.is() )
546 rLnks.erase( rLnks.begin() + n );
547 --n;
548 continue;
550 if( rLinkRef->IsVisible() )
551 InsertEntry( *rLinkRef );
554 m_xTbLinks->thaw();
556 if( !rLnks.empty() )
558 m_xTbLinks->set_cursor(0);
559 m_xTbLinks->select(0);
560 LinksSelectHdl( nullptr );
564 void SvBaseLinksDlg::InsertEntry(const SvBaseLink& rLink, int nPos, bool bSelect)
566 OUString sFileNm, sLinkNm, sTypeNm, sFilter;
568 sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
570 auto nWidthPixel = m_xTbLinks->get_column_width(0);
571 OUString aTxt = m_xVirDev->GetEllipsisString(sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis);
572 INetURLObject aPath( sFileNm, INetProtocol::File );
573 OUString aFileName = aPath.getName(
574 INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::Unambiguous);
576 if( aFileName.getLength() > aTxt.getLength() )
577 aTxt = aFileName;
578 else if (!aFileName.isEmpty() && aTxt.indexOf(aFileName, aTxt.getLength() - aFileName.getLength()) == -1)
579 // filename not in string
580 aTxt = aFileName;
582 if (nPos == -1)
583 nPos = m_xTbLinks->n_children();
584 m_xTbLinks->insert(nPos);
585 m_xTbLinks->set_text(nPos, aTxt, 0);
586 m_xTbLinks->set_id(nPos, weld::toId(&rLink));
587 if( SvBaseLinkObjectType::ClientGraphic == rLink.GetObjType() )
588 m_xTbLinks->set_text(nPos, sFilter, 1);
589 else
590 m_xTbLinks->set_text(nPos, sLinkNm, 1);
591 m_xTbLinks->set_text(nPos, sTypeNm, 2);
592 m_xTbLinks->set_text(nPos, ImplGetStateStr(rLink), 3);
593 if (bSelect)
594 m_xTbLinks->select(nPos);
597 SvBaseLink* SvBaseLinksDlg::GetSelEntry(int* pPos)
599 int nPos = m_xTbLinks->get_selected_index();
600 if (nPos != -1)
602 if (pPos)
603 *pPos = nPos;
604 return weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos));
606 return nullptr;
609 void SvBaseLinksDlg::SetType(SvBaseLink& rLink,
610 int nSelPos,
611 SfxLinkUpdateMode nType)
613 rLink.SetUpdateMode( nType );
614 rLink.Update();
615 m_xTbLinks->set_text(nSelPos, ImplGetStateStr(rLink), 3);
616 if (pLinkMgr->GetPersist())
617 pLinkMgr->GetPersist()->SetModified();
620 void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
622 if( !pLinkMgr )
623 return;
625 const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
626 int nSelect = 0;
627 for(const auto & rLinkRef : rLnks)
629 // #109573# only visible links have been inserted into the TreeListBox,
630 // invisible ones have to be skipped here
631 if( rLinkRef->IsVisible() )
633 if( pLink == rLinkRef.get() )
635 m_xTbLinks->select(nSelect);
636 LinksSelectHdl( nullptr );
637 return ;
639 ++nSelect;
644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */