1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <linkdlg.hxx>
21 #include <o3tl/safeint.hxx>
22 #include <vcl/svapp.hxx>
23
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>
31
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>
38
39 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
40 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
41 #include <comphelper/processfactory.hxx>
42
43 #include <dialmgr.hxx>
44
45
46 using namespace sfx2;
47 using namespace ::com::sun::star;
48
49 namespace {
50
51 class SvBaseLinkMemberList {
52 private:
53 std::vector<SvBaseLink*> mLinks;
54
55 public:
~SvBaseLinkMemberList()56 ~SvBaseLinkMemberList()
57 {
58 for (auto const& link : mLinks)
59 {
60 if( link )
61 link->ReleaseRef();
62 }
63 }
64
size() const65 size_t size() const { return mLinks.size(); }
66
operator [](size_t i) const67 SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
68
push_back(SvBaseLink * p)69 void push_back(SvBaseLink* p)
70 {
71 mLinks.push_back(p);
72 p->AddFirstRef();
73 }
74 };
75
76 }
77
SvBaseLinksDlg(weld::Window * pParent,LinkManager * pMgr,bool bHtmlMode)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())
98 {
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));
103
104 m_xTbLinks->set_selection_mode(SelectionMode::Multiple);
105
106 std::vector<int> aWidths
107 {
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)
111 };
112 m_xTbLinks->set_column_fixed_widths(aWidths);
113
114 // UpdateTimer for DDE-/Grf-links, which are waited for
115 aUpdateIdle.SetInvokeHandler( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
116 aUpdateIdle.SetPriority( TaskPriority::LOWEST );
117
118 m_xTbLinks->connect_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();
128
129 SetManager( pMgr );
130 }
131
~SvBaseLinksDlg()132 SvBaseLinksDlg::~SvBaseLinksDlg()
133 {
134 }
135
136 /*************************************************************************
137 |* SvBaseLinksDlg::Handler()
138 *************************************************************************/
IMPL_LINK(SvBaseLinksDlg,LinksSelectHdl,weld::TreeView &,rTreeView,void)139 IMPL_LINK(SvBaseLinksDlg, LinksSelectHdl, weld::TreeView&, rTreeView, void)
140 {
141 LinksSelectHdl(&rTreeView);
142 }
143
LinksSelectHdl(weld::TreeView * pSvTabListBox)144 void SvBaseLinksDlg::LinksSelectHdl(weld::TreeView* pSvTabListBox)
145 {
146 const int nSelectionCount = pSvTabListBox ?
147 pSvTabListBox->count_selected_rows() : 0;
148 if (nSelectionCount > 1)
149 {
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))
155 {
156 pSvTabListBox->unselect_all();
157 pSvTabListBox->select(nSelEntry);
158 }
159 else
160 {
161 std::vector<int> aRows = pSvTabListBox->get_selected_rows();
162 for (auto nEntry : aRows)
163 {
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);
170 }
171 }
172
173 m_xPbUpdateNow->set_sensitive(true);
174 m_xRbAutomatic->set_sensitive(false);
175 m_xRbManual->set_active(true);
176 m_xRbManual->set_sensitive(false);
177 }
178 else
179 {
180 int nPos;
181 SvBaseLink* pLink = GetSelEntry( &nPos );
182 if( !pLink )
183 return;
184
185 m_xPbUpdateNow->set_sensitive(true);
186
187 OUString sType, sLink;
188 OUString *pLinkNm = &sLink, *pFilter = nullptr;
189
190 if( isClientFileType(pLink->GetObjType()) )
191 {
192 m_xRbAutomatic->set_sensitive(false);
193 m_xRbManual->set_active(true);
194 m_xRbManual->set_sensitive(false);
195 if( SvBaseLinkObjectType::ClientGraphic == pLink->GetObjType() )
196 {
197 pLinkNm = nullptr;
198 pFilter = &sLink;
199 }
200 }
201 else
202 {
203 m_xRbAutomatic->set_sensitive(true);
204 m_xRbManual->set_sensitive(true);
205
206 if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
207 m_xRbAutomatic->set_active(true);
208 else
209 m_xRbManual->set_active(true);
210 }
211
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 );
219 }
220 }
221
IMPL_LINK_NOARG(SvBaseLinksDlg,LinksDoubleClickHdl,weld::TreeView &,bool)222 IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, weld::TreeView&, bool )
223 {
224 ChangeSourceClickHdl(*m_xPbChangeSource);
225 return true;
226 }
227
IMPL_LINK(SvBaseLinksDlg,ToggleHdl,weld::Toggleable &,rButton,void)228 IMPL_LINK(SvBaseLinksDlg, ToggleHdl, weld::Toggleable&, rButton, void)
229 {
230 if (!rButton.get_active())
231 return;
232
233 int nPos;
234 SvBaseLink* pLink = GetSelEntry( &nPos );
235
236 if (m_xRbAutomatic->get_active())
237 {
238 if( pLink && !isClientFileType( pLink->GetObjType() ) &&
239 SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
240 SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
241 }
242 else
243 {
244 if( pLink && !isClientFileType( pLink->GetObjType() ) &&
245 SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
246 SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
247 }
248 }
249
IMPL_LINK_NOARG(SvBaseLinksDlg,UpdateNowClickHdl,weld::Button &,void)250 IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, weld::Button&, void)
251 {
252 std::vector< SvBaseLink* > aLnkArr;
253 std::vector< sal_Int16 > aPosArr;
254
255 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
256 for (int nFndPos : aRows)
257 {
258 aLnkArr.push_back( weld::fromId<SvBaseLink*>( m_xTbLinks->get_id(nFndPos) ) );
259 aPosArr.push_back( nFndPos );
260 }
261
262 if( aLnkArr.empty() )
263 return;
264
265 for( size_t n = 0; n < aLnkArr.size(); ++n )
266 {
267 tools::SvRef<SvBaseLink> xLink = aLnkArr[ n ];
268
269 // first look for the entry in the array
270 for(const auto & i : pLinkMgr->GetLinks())
271 if( xLink == i )
272 {
273 SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
274 break;
275 }
276 }
277
278 // if somebody is of the opinion to swap his links (SD)
279 LinkManager* pNewMgr = pLinkMgr;
280 pLinkMgr = nullptr;
281 SetManager( pNewMgr );
282
283
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);
293
294 pNewMgr->CloseCachedComps();
295 }
296
IMPL_LINK_NOARG(SvBaseLinksDlg,ChangeSourceClickHdl,weld::Button &,void)297 IMPL_LINK_NOARG(SvBaseLinksDlg, ChangeSourceClickHdl, weld::Button&, void)
298 {
299 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
300 if (aRows.size() > 1)
301 {
302 try
303 {
304 uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
305 comphelper::getProcessComponentContext(), m_xDialog.get());
306
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)
313 {
314 OUString sOldPath(aUrl.PathToFileName());
315 sal_Int32 nLen = aUrl.GetLastName().getLength();
316 sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
317 xFolderPicker->setDisplayDirectory(sOldPath);
318 }
319 if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
320 {
321 OUString aPath = xFolderPicker->getDirectory();
322
323 for (auto nRow : aRows)
324 {
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();
338 }
339 if( pLinkMgr->GetPersist() )
340 pLinkMgr->GetPersist()->SetModified();
341 LinkManager* pNewMgr = pLinkMgr;
342 pLinkMgr = nullptr;
343 SetManager( pNewMgr );
344 }
345 }
346 catch (const uno::Exception &)
347 {
348 TOOLS_WARN_EXCEPTION("cui.dialogs", "SvBaseLinksDlg");
349 }
350 }
351 else
352 {
353 int nPos;
354 SvBaseLink* pLink = GetSelEntry( &nPos );
355 if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
356 pLink->Edit(m_xDialog.get(), LINK(this, SvBaseLinksDlg, EndEditHdl));
357 }
358 }
359
IMPL_LINK_NOARG(SvBaseLinksDlg,BreakLinkClickHdl,weld::Button &,void)360 IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, weld::Button&, void )
361 {
362 bool bModified = false;
363 if (m_xTbLinks->count_selected_rows() <= 1)
364 {
365 int nPos;
366 tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
367 if( !xLink.is() )
368 return;
369
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);
374
375 if (RET_YES == xQueryBox->run())
376 {
377 m_xTbLinks->remove(nPos);
378
379 // close object, if it's still existing
380 bool bNewLnkMgr = SvBaseLinkObjectType::ClientFile == xLink->GetObjType();
381
382 // tell the link that it will be resolved!
383 xLink->Closed();
384
385 // if somebody has forgotten to deregister himself
386 if( xLink.is() )
387 pLinkMgr->Remove( xLink.get() );
388
389 if( bNewLnkMgr )
390 {
391 LinkManager* pNewMgr = pLinkMgr;
392 pLinkMgr = nullptr;
393 SetManager( pNewMgr );
394 m_xTbLinks->set_cursor(nPos ? --nPos : 0);
395 }
396 bModified = true;
397 }
398 }
399 else
400 {
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);
405
406 if (RET_YES == xQueryBox->run())
407 {
408 std::vector<int> aRows = m_xTbLinks->get_selected_rows();
409 SvBaseLinkMemberList aLinkList;
410 for (auto nRow : aRows)
411 {
412 SvBaseLink* pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nRow));
413 if (pLink)
414 aLinkList.push_back(pLink);
415 }
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)
420 {
421 tools::SvRef<SvBaseLink> xLink = aLinkList[i];
422 // tell the link that it will be resolved!
423 xLink->Closed();
424
425 // if somebody has forgotten to deregister himself
426 pLinkMgr->Remove( xLink.get() );
427 bModified = true;
428 }
429 // then remove all selected entries
430 }
431 }
432 if(!bModified)
433 return;
434
435 if (!m_xTbLinks->n_children())
436 {
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);
442
443 m_xFtFullSourceName->set_label( u""_ustr );
444 m_xFtFullTypeName->set_label( u""_ustr );
445 }
446 if( pLinkMgr && pLinkMgr->GetPersist() )
447 pLinkMgr->GetPersist()->SetModified();
448 }
449
IMPL_LINK_NOARG(SvBaseLinksDlg,UpdateWaitingHdl,Timer *,void)450 IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, void )
451 {
452 m_xTbLinks->freeze();
453 for (int nPos = m_xTbLinks->n_children(); nPos; --nPos)
454 {
455 tools::SvRef<SvBaseLink> xLink( weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos)) );
456 if( xLink.is() )
457 {
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);
462 }
463 }
464 m_xTbLinks->thaw();
465 }
466
IMPL_LINK(SvBaseLinksDlg,EndEditHdl,sfx2::SvBaseLink &,_rLink,void)467 IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
468 {
469 int nPos;
470 GetSelEntry( &nPos );
471
472 if( !_rLink.WasLastEditOK() )
473 return;
474
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 ]) )
482 {
483 bLinkFnd = true;
484 break;
485 }
486
487 if( bLinkFnd )
488 {
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);
494 }
495 else
496 {
497 LinkManager* pNewMgr = pLinkMgr;
498 pLinkMgr = nullptr;
499 SetManager( pNewMgr );
500 }
501 if (pLinkMgr && pLinkMgr->GetPersist())
502 pLinkMgr->GetPersist()->SetModified();
503 }
504
ImplGetStateStr(const SvBaseLink & rLnk)505 OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
506 {
507 OUString sRet;
508 if( !rLnk.GetObj() )
509 sRet = aStrBrokenlink;
510 else if( rLnk.GetObj()->IsPending() )
511 {
512 sRet = aStrWaitinglink;
513 aUpdateIdle.Start();
514 }
515 else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
516 sRet = aStrAutolink;
517 else
518 sRet = aStrManuallink;
519
520 return sRet;
521 }
522
SetManager(LinkManager * pNewMgr)523 void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
524 {
525 if( pLinkMgr == pNewMgr )
526 return;
527
528 if (pNewMgr)
529 {
530 // update has to be stopped before clear
531 m_xTbLinks->freeze();
532 }
533
534 m_xTbLinks->clear();
535 pLinkMgr = pNewMgr;
536
537 if( !pLinkMgr )
538 return;
539
540 SvBaseLinks& rLnks = const_cast<SvBaseLinks&>(pLinkMgr->GetLinks());
541 for( size_t n = 0; n < rLnks.size(); ++n )
542 {
543 tools::SvRef<SvBaseLink>& rLinkRef = rLnks[ n ];
544 if( !rLinkRef.is() )
545 {
546 rLnks.erase( rLnks.begin() + n );
547 --n;
548 continue;
549 }
550 if( rLinkRef->IsVisible() )
551 InsertEntry( *rLinkRef );
552 }
553
554 m_xTbLinks->thaw();
555
556 if( !rLnks.empty() )
557 {
558 m_xTbLinks->set_cursor(0);
559 m_xTbLinks->select(0);
560 LinksSelectHdl( nullptr );
561 }
562 }
563
InsertEntry(const SvBaseLink & rLink,int nPos,bool bSelect)564 void SvBaseLinksDlg::InsertEntry(const SvBaseLink& rLink, int nPos, bool bSelect)
565 {
566 OUString sFileNm, sLinkNm, sTypeNm, sFilter;
567
568 sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
569
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);
575
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;
581
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);
595 }
596
GetSelEntry(int * pPos)597 SvBaseLink* SvBaseLinksDlg::GetSelEntry(int* pPos)
598 {
599 int nPos = m_xTbLinks->get_selected_index();
600 if (nPos != -1)
601 {
602 if (pPos)
603 *pPos = nPos;
604 return weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos));
605 }
606 return nullptr;
607 }
608
SetType(SvBaseLink & rLink,int nSelPos,SfxLinkUpdateMode nType)609 void SvBaseLinksDlg::SetType(SvBaseLink& rLink,
610 int nSelPos,
611 SfxLinkUpdateMode nType)
612 {
613 rLink.SetUpdateMode( nType );
614 rLink.Update();
615 m_xTbLinks->set_text(nSelPos, ImplGetStateStr(rLink), 3);
616 if (pLinkMgr->GetPersist())
617 pLinkMgr->GetPersist()->SetModified();
618 }
619
SetActLink(SvBaseLink const * pLink)620 void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
621 {
622 if( !pLinkMgr )
623 return;
624
625 const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
626 int nSelect = 0;
627 for(const auto & rLinkRef : rLnks)
628 {
629 // #109573# only visible links have been inserted into the TreeListBox,
630 // invisible ones have to be skipped here
631 if( rLinkRef->IsVisible() )
632 {
633 if( pLink == rLinkRef.get() )
634 {
635 m_xTbLinks->select(nSelect);
636 LinksSelectHdl( nullptr );
637 return ;
638 }
639 ++nSelect;
640 }
641 }
642 }
643
644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
645