Line data Source code
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 <vcl/svapp.hxx>
22 : #include "helpid.hrc"
23 :
24 : #include <tools/urlobj.hxx>
25 : #include <svtools/svmedit.hxx>
26 : #include <vcl/dialog.hxx>
27 : #include <vcl/button.hxx>
28 : #include <vcl/fixed.hxx>
29 : #include <vcl/group.hxx>
30 : #include <vcl/lstbox.hxx>
31 : #include <vcl/msgbox.hxx>
32 : #include <vcl/timer.hxx>
33 : #include <vcl/idle.hxx>
34 : #include <svtools/svtabbx.hxx>
35 : #include "svtools/treelistentry.hxx"
36 :
37 : #include <svuidlg.hrc>
38 : #include <sfx2/linkmgr.hxx>
39 : #include <sfx2/linksrc.hxx>
40 : #include <svtools/soerr.hxx>
41 : #include <sfx2/lnkbase.hxx>
42 : #include <sfx2/objsh.hxx>
43 :
44 : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
45 : #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
46 : #include <comphelper/processfactory.hxx>
47 :
48 : #include <dialmgr.hxx>
49 :
50 :
51 : #define FILEOBJECT ( OBJECT_CLIENT_FILE & ~OBJECT_CLIENT_SO )
52 :
53 : using namespace sfx2;
54 : using namespace ::com::sun::star;
55 :
56 0 : class SvBaseLinkMemberList {
57 : private:
58 : std::vector<SvBaseLink*> mLinks;
59 :
60 : public:
61 0 : ~SvBaseLinkMemberList()
62 0 : {
63 0 : for( std::vector<SvBaseLink*>::const_iterator it = mLinks.begin(); it != mLinks.end(); ++it )
64 : {
65 0 : SvBaseLink* p = *it;
66 0 : if( p )
67 0 : p->ReleaseRef();
68 : }
69 0 : }
70 :
71 0 : size_t size() const { return mLinks.size(); }
72 :
73 0 : SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
74 :
75 0 : void push_back(SvBaseLink* p)
76 : {
77 0 : mLinks.push_back(p);
78 0 : p->AddFirstRef();
79 0 : }
80 : };
81 :
82 : // attention, this array is indexed directly (0, 1, ...) in the code
83 : static long nTabs[] =
84 : { 4, // Number of Tabs
85 : 0, 77, 144, 209
86 : };
87 :
88 :
89 0 : SvBaseLinksDlg::SvBaseLinksDlg( vcl::Window * pParent, LinkManager* pMgr, bool bHtml )
90 : : ModalDialog( pParent, "BaseLinksDialog", "cui/ui/baselinksdialog.ui"),
91 0 : aStrAutolink( CUI_RES( STR_AUTOLINK ) ),
92 0 : aStrManuallink( CUI_RES( STR_MANUALLINK ) ),
93 0 : aStrBrokenlink( CUI_RES( STR_BROKENLINK ) ),
94 0 : aStrGraphiclink( CUI_RES( STR_GRAPHICLINK ) ),
95 0 : aStrButtonclose( CUI_RES( STR_BUTTONCLOSE ) ),
96 0 : aStrCloselinkmsg( CUI_RES( STR_CLOSELINKMSG ) ),
97 0 : aStrCloselinkmsgMulti( CUI_RES( STR_CLOSELINKMSG_MULTI ) ),
98 0 : aStrWaitinglink( CUI_RES( STR_WAITINGLINK ) ),
99 : pLinkMgr( NULL ),
100 0 : bHtmlMode(bHtml)
101 : {
102 0 : get(m_pTbLinks, "TB_LINKS");
103 0 : Size aSize(LogicToPixel(Size(257, 87), MAP_APPFONT));
104 0 : m_pTbLinks->set_width_request(aSize.Width());
105 0 : m_pTbLinks->set_height_request(aSize.Height());
106 0 : get(m_pFtFullFileName, "FULL_FILE_NAME");
107 0 : get(m_pFtFullSourceName, "FULL_SOURCE_NAME");
108 0 : get(m_pFtFullTypeName, "FULL_TYPE_NAME");
109 0 : get(m_pRbAutomatic, "AUTOMATIC");
110 0 : get(m_pRbManual, "MANUAL");
111 0 : get(m_pPbUpdateNow, "UPDATE_NOW");
112 0 : get(m_pPbOpenSource, "OPEN");
113 0 : get(m_pPbChangeSource, "CHANGE_SOURCE");
114 0 : get(m_pPbBreakLink, "BREAK_LINK");
115 :
116 0 : m_pTbLinks->SetSelectionMode( MULTIPLE_SELECTION );
117 0 : m_pTbLinks->SetTabs( &nTabs[0], MAP_APPFONT );
118 0 : FixedText *pFtFiles = get<FixedText>("FILES");
119 0 : pFtFiles->set_width_request(LogicToPixel(Size(nTabs[2] - nTabs[1] - 2, 0), MAP_APPFONT).Width());
120 0 : FixedText *pFtLinks = get<FixedText>("LINKS");
121 0 : pFtLinks->set_width_request(LogicToPixel(Size(nTabs[3] - nTabs[2] - 2, 0), MAP_APPFONT).Width());
122 0 : FixedText *pFtTypes = get<FixedText>("TYPE");
123 0 : pFtTypes->set_width_request(LogicToPixel(Size(nTabs[4] - nTabs[3] - 2, 0), MAP_APPFONT).Width());
124 0 : m_pTbLinks->Resize(); // OS: hack for correct selection
125 :
126 : // UpdateTimer for DDE-/Grf-links, which are waited for
127 0 : aUpdateIdle.SetIdleHdl( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
128 0 : aUpdateIdle.SetPriority( SchedulerPriority::LOWEST );
129 :
130 0 : m_pPbOpenSource->Hide();
131 :
132 0 : m_pTbLinks->SetSelectHdl( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
133 0 : m_pTbLinks->SetDoubleClickHdl( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
134 0 : m_pRbAutomatic->SetClickHdl( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
135 0 : m_pRbManual->SetClickHdl( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
136 0 : m_pPbUpdateNow->SetClickHdl( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
137 0 : m_pPbChangeSource->SetClickHdl( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
138 0 : if(!bHtmlMode)
139 0 : m_pPbBreakLink->SetClickHdl( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
140 : else
141 0 : m_pPbBreakLink->Hide();
142 :
143 0 : SetManager( pMgr );
144 0 : }
145 :
146 0 : SvBaseLinksDlg::~SvBaseLinksDlg()
147 : {
148 0 : disposeOnce();
149 0 : }
150 :
151 0 : void SvBaseLinksDlg::dispose()
152 : {
153 0 : m_pTbLinks.clear();
154 0 : m_pFtFullFileName.clear();
155 0 : m_pFtFullSourceName.clear();
156 0 : m_pFtFullTypeName.clear();
157 0 : m_pRbAutomatic.clear();
158 0 : m_pRbManual.clear();
159 0 : m_pPbUpdateNow.clear();
160 0 : m_pPbOpenSource.clear();
161 0 : m_pPbChangeSource.clear();
162 0 : m_pPbBreakLink.clear();
163 0 : ModalDialog::dispose();
164 0 : }
165 :
166 : /*************************************************************************
167 : |* SvBaseLinksDlg::Handler()
168 : *************************************************************************/
169 0 : IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTabListBox *, pSvTabListBox )
170 : {
171 : sal_uLong nSelectionCount = pSvTabListBox ?
172 0 : pSvTabListBox->GetSelectionCount() : 0;
173 0 : if(nSelectionCount > 1)
174 : {
175 : // possibly deselect old entries in case of multi-selection
176 0 : SvTreeListEntry* pEntry = 0;
177 0 : SvBaseLink* pLink = 0;
178 0 : pEntry = pSvTabListBox->GetHdlEntry();
179 0 : pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
180 0 : sal_uInt16 nObjectType = pLink->GetObjType();
181 0 : if((OBJECT_CLIENT_FILE & nObjectType) != OBJECT_CLIENT_FILE)
182 : {
183 0 : pSvTabListBox->SelectAll(false);
184 0 : pSvTabListBox->Select(pEntry);
185 0 : nSelectionCount = 1;
186 : }
187 : else
188 : {
189 0 : for( sal_uLong i = 0; i < nSelectionCount; i++)
190 : {
191 0 : pEntry = i == 0 ? pSvTabListBox->FirstSelected() :
192 0 : pSvTabListBox->NextSelected(pEntry);
193 : DBG_ASSERT(pEntry, "Wo ist der Entry?");
194 0 : if (!pEntry)
195 0 : continue;
196 0 : pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
197 : DBG_ASSERT(pLink, "Wo ist der Link?");
198 0 : if (!pLink)
199 0 : continue;
200 0 : if( (OBJECT_CLIENT_FILE & pLink->GetObjType()) != OBJECT_CLIENT_FILE )
201 0 : pSvTabListBox->Select( pEntry, false );
202 :
203 : }
204 : }
205 :
206 0 : m_pPbUpdateNow->Enable();
207 :
208 0 : m_pRbAutomatic->Disable();
209 0 : m_pRbManual->Check();
210 0 : m_pRbManual->Disable();
211 : }
212 : else
213 : {
214 : sal_uLong nPos;
215 0 : SvBaseLink* pLink = GetSelEntry( &nPos );
216 0 : if( !pLink )
217 0 : return 0;
218 :
219 0 : m_pPbUpdateNow->Enable();
220 :
221 0 : OUString sType, sLink;
222 0 : OUString *pLinkNm = &sLink, *pFilter = 0;
223 :
224 0 : if( FILEOBJECT & pLink->GetObjType() )
225 : {
226 0 : m_pRbAutomatic->Disable();
227 0 : m_pRbManual->Check();
228 0 : m_pRbManual->Disable();
229 0 : if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
230 0 : pLinkNm = 0, pFilter = &sLink;
231 : }
232 : else
233 : {
234 0 : m_pRbAutomatic->Enable();
235 0 : m_pRbManual->Enable();
236 :
237 0 : if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
238 0 : m_pRbAutomatic->Check();
239 : else
240 0 : m_pRbManual->Check();
241 : }
242 :
243 0 : OUString aFileName;
244 0 : sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
245 0 : aFileName = INetURLObject::decode(aFileName, INetURLObject::DECODE_UNAMBIGUOUS);
246 0 : m_pFtFullFileName->SetText( aFileName );
247 0 : m_pFtFullSourceName->SetText( sLink );
248 0 : m_pFtFullTypeName->SetText( sType );
249 : }
250 0 : return 0;
251 : }
252 :
253 0 : IMPL_LINK( SvBaseLinksDlg, LinksDoubleClickHdl, SvTabListBox *, pSvTabListBox )
254 : {
255 : (void)pSvTabListBox;
256 :
257 0 : ChangeSourceClickHdl( 0 );
258 0 : return 0;
259 : }
260 :
261 0 : IMPL_LINK( SvBaseLinksDlg, AutomaticClickHdl, RadioButton *, pRadioButton )
262 : {
263 : (void)pRadioButton;
264 :
265 : sal_uLong nPos;
266 0 : SvBaseLink* pLink = GetSelEntry( &nPos );
267 0 : if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
268 0 : SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
269 0 : SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
270 0 : return 0;
271 : }
272 :
273 0 : IMPL_LINK( SvBaseLinksDlg, ManualClickHdl, RadioButton *, pRadioButton )
274 : {
275 : (void)pRadioButton;
276 :
277 : sal_uLong nPos;
278 0 : SvBaseLink* pLink = GetSelEntry( &nPos );
279 0 : if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
280 0 : SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
281 0 : SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
282 0 : return 0;
283 : }
284 :
285 0 : IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl)
286 : {
287 0 : SvTabListBox& rListBox = *m_pTbLinks;
288 0 : sal_uLong nSelCnt = rListBox.GetSelectionCount();
289 0 : if( 255 < nSelCnt )
290 0 : nSelCnt = 255;
291 :
292 0 : std::vector< SvBaseLink* > aLnkArr;
293 0 : std::vector< sal_Int16 > aPosArr;
294 :
295 0 : SvTreeListEntry* pE = rListBox.FirstSelected();
296 0 : while( pE )
297 : {
298 0 : sal_uLong nFndPos = rListBox.GetModel()->GetAbsPos( pE );
299 0 : if( TREELIST_ENTRY_NOTFOUND != nFndPos )
300 : {
301 0 : aLnkArr.push_back( static_cast< SvBaseLink* >( pE->GetUserData() ) );
302 0 : aPosArr.push_back( nFndPos );
303 : }
304 0 : pE = rListBox.NextSelected( pE );
305 : }
306 :
307 0 : if( !aLnkArr.empty() )
308 : {
309 0 : for( size_t n = 0; n < aLnkArr.size(); ++n )
310 : {
311 0 : SvBaseLinkRef xLink = aLnkArr[ n ];
312 :
313 : // first look for the entry in the array
314 0 : for( size_t i = 0; i < pLinkMgr->GetLinks().size(); ++i )
315 0 : if( &xLink == *pLinkMgr->GetLinks()[ i ] )
316 : {
317 0 : xLink->SetUseCache( false );
318 0 : SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
319 0 : xLink->SetUseCache( true );
320 0 : break;
321 : }
322 0 : }
323 :
324 : // if somebody is of the opinion to swap his links (SD)
325 0 : LinkManager* pNewMgr = pLinkMgr;
326 0 : pLinkMgr = 0;
327 0 : SetManager( pNewMgr );
328 :
329 :
330 0 : if( 0 == (pE = rListBox.GetEntry( aPosArr[ 0 ] )) ||
331 0 : pE->GetUserData() != aLnkArr[ 0 ] )
332 : {
333 : // search the link
334 0 : pE = rListBox.First();
335 0 : while( pE )
336 : {
337 0 : if( pE->GetUserData() == aLnkArr[ 0 ] )
338 0 : break;
339 0 : pE = rListBox.Next( pE );
340 : }
341 :
342 0 : if( !pE )
343 0 : pE = rListBox.FirstSelected();
344 : }
345 :
346 0 : if( pE )
347 : {
348 0 : SvTreeListEntry* pSelEntry = rListBox.FirstSelected();
349 0 : if( pE != pSelEntry )
350 0 : rListBox.Select( pSelEntry, false );
351 0 : rListBox.Select( pE );
352 0 : rListBox.MakeVisible( pE );
353 : }
354 :
355 0 : pNewMgr->CloseCachedComps();
356 : }
357 0 : return 0;
358 : }
359 :
360 0 : IMPL_LINK( SvBaseLinksDlg, ChangeSourceClickHdl, PushButton *, pPushButton )
361 : {
362 : (void)pPushButton;
363 :
364 0 : sal_uLong nSelectionCount = m_pTbLinks->GetSelectionCount();
365 0 : if(nSelectionCount > 1)
366 : {
367 : try
368 : {
369 0 : uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = ui::dialogs::FolderPicker::create(comphelper::getProcessComponentContext());
370 :
371 0 : OUString sType, sFile, sLinkName;
372 0 : OUString sFilter;
373 0 : SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
374 0 : SvBaseLink* pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
375 0 : sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, 0, 0 );
376 0 : INetURLObject aUrl(sFile);
377 0 : if(aUrl.GetProtocol() == INetProtocol::File)
378 : {
379 0 : OUString sOldPath(aUrl.PathToFileName());
380 0 : sal_Int32 nLen = aUrl.GetName().getLength();
381 0 : sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
382 0 : xFolderPicker->setDisplayDirectory(sOldPath);
383 : }
384 0 : if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
385 : {
386 0 : OUString aPath = xFolderPicker->getDirectory();
387 :
388 0 : for( sal_uLong i = 0; i < nSelectionCount; i++)
389 : {
390 : pEntry = i==0 ?
391 0 : m_pTbLinks->FirstSelected() :
392 0 : m_pTbLinks->NextSelected( pEntry );
393 : DBG_ASSERT(pEntry,"Where is the entry?");
394 0 : if (!pEntry)
395 0 : continue;
396 0 : pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
397 : DBG_ASSERT(pLink,"Where is the link?");
398 0 : if (!pLink)
399 0 : continue;
400 0 : sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
401 0 : INetURLObject aUrl_(sFile);
402 0 : INetURLObject aUrl2(aPath, INetProtocol::File);
403 0 : aUrl2.insertName( aUrl_.getName() );
404 0 : OUString sNewLinkName;
405 : MakeLnkName( sNewLinkName, 0 ,
406 0 : aUrl2.GetMainURL(INetURLObject::DECODE_TO_IURI), sLinkName, &sFilter);
407 0 : pLink->SetLinkSourceName( sNewLinkName );
408 0 : pLink->Update();
409 0 : }
410 0 : if( pLinkMgr->GetPersist() )
411 0 : pLinkMgr->GetPersist()->SetModified();
412 0 : LinkManager* pNewMgr = pLinkMgr;
413 0 : pLinkMgr = 0;
414 0 : SetManager( pNewMgr );
415 0 : }
416 : }
417 0 : catch (uno::Exception & e)
418 : {
419 : SAL_WARN("cui.dialogs", "SvBaseLinksDlg: caught UNO exception: " << e.Message);
420 : }
421 : }
422 : else
423 : {
424 : sal_uLong nPos;
425 0 : SvBaseLink* pLink = GetSelEntry( &nPos );
426 0 : if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
427 0 : pLink->Edit( this, LINK( this, SvBaseLinksDlg, EndEditHdl ) );
428 : }
429 0 : return 0;
430 : }
431 :
432 0 : IMPL_LINK( SvBaseLinksDlg, BreakLinkClickHdl, PushButton *, pPushButton )
433 : {
434 : (void)pPushButton;
435 :
436 0 : bool bModified = false;
437 0 : if(m_pTbLinks->GetSelectionCount() <= 1)
438 : {
439 : sal_uLong nPos;
440 0 : SvBaseLinkRef xLink = GetSelEntry( &nPos );
441 0 : if( !xLink.Is() )
442 0 : return 0;
443 :
444 0 : ScopedVclPtrInstance< QueryBox > aBox( this, WB_YES_NO | WB_DEF_YES, Closelinkmsg() );
445 :
446 0 : if( RET_YES == aBox->Execute() )
447 : {
448 0 : m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
449 :
450 : // close object, if it's still existing
451 0 : bool bNewLnkMgr = OBJECT_CLIENT_FILE == xLink->GetObjType();
452 :
453 : // tell the link that it will be resolved!
454 0 : xLink->Closed();
455 :
456 : // if somebody has forgotten to deregister himself
457 0 : if( xLink.Is() )
458 0 : pLinkMgr->Remove( &xLink );
459 :
460 0 : if( bNewLnkMgr )
461 : {
462 0 : LinkManager* pNewMgr = pLinkMgr;
463 0 : pLinkMgr = 0;
464 0 : SetManager( pNewMgr );
465 :
466 0 : SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( nPos ? --nPos : 0 );
467 0 : if( pEntry )
468 0 : m_pTbLinks->SetCurEntry( pEntry );
469 : }
470 0 : bModified = true;
471 0 : }
472 : }
473 : else
474 : {
475 0 : ScopedVclPtrInstance< QueryBox > aBox( this, WB_YES_NO | WB_DEF_YES, CloselinkmsgMulti() );
476 :
477 0 : if( RET_YES == aBox->Execute() )
478 : {
479 :
480 0 : SvBaseLinkMemberList aLinkList;
481 0 : SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
482 0 : while ( pEntry )
483 : {
484 0 : void * pUD = pEntry->GetUserData();
485 0 : if( pUD )
486 0 : aLinkList.push_back( static_cast<SvBaseLink*>(pUD) );
487 0 : pEntry = m_pTbLinks->NextSelected(pEntry);
488 : }
489 0 : m_pTbLinks->RemoveSelection();
490 0 : for( sal_uLong i = 0; i < aLinkList.size(); i++ )
491 : {
492 0 : SvBaseLinkRef xLink = aLinkList[i];
493 : // tell the link that it will be resolved!
494 0 : xLink->Closed();
495 :
496 : // if somebody has forgotten to deregister himself
497 0 : pLinkMgr->Remove( &xLink );
498 0 : bModified = true;
499 0 : }
500 : // then remove all selected entries
501 0 : }
502 : }
503 0 : if(bModified)
504 : {
505 0 : if( !m_pTbLinks->GetEntryCount() )
506 : {
507 0 : m_pRbAutomatic->Disable();
508 0 : m_pRbManual->Disable();
509 0 : m_pPbUpdateNow->Disable();
510 0 : m_pPbChangeSource->Disable();
511 0 : m_pPbBreakLink->Disable();
512 :
513 0 : OUString aEmpty;
514 0 : m_pFtFullSourceName->SetText( aEmpty );
515 0 : m_pFtFullTypeName->SetText( aEmpty );
516 : }
517 0 : if( pLinkMgr && pLinkMgr->GetPersist() )
518 0 : pLinkMgr->GetPersist()->SetModified();
519 : }
520 0 : return 0;
521 : }
522 :
523 0 : IMPL_LINK_NOARG_TYPED( SvBaseLinksDlg, UpdateWaitingHdl, Idle*, void )
524 : {
525 0 : m_pTbLinks->SetUpdateMode(false);
526 0 : for( sal_uLong nPos = m_pTbLinks->GetEntryCount(); nPos; )
527 : {
528 0 : SvTreeListEntry* pBox = m_pTbLinks->GetEntry( --nPos );
529 0 : SvBaseLinkRef xLink( static_cast<SvBaseLink*>(pBox->GetUserData()) );
530 0 : if( xLink.Is() )
531 : {
532 0 : OUString sCur( ImplGetStateStr( *xLink ) ),
533 0 : sOld( SvTabListBox::GetEntryText( pBox, 3 ) );
534 0 : if( sCur != sOld )
535 0 : m_pTbLinks->SetEntryText( sCur, pBox, 3 );
536 : }
537 0 : }
538 0 : m_pTbLinks->SetUpdateMode(true);
539 0 : }
540 :
541 0 : IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink*, _pLink )
542 : {
543 : sal_uLong nPos;
544 0 : GetSelEntry( &nPos );
545 :
546 0 : if( _pLink && _pLink->WasLastEditOK() )
547 : {
548 : // StarImpress/Draw swap the LinkObjects themselves!
549 : // So search for the link in the manager; if it does not exist
550 : // anymore, fill the list completely new. Otherwise only the
551 : // edited link needs to be refreshed.
552 0 : bool bLinkFnd = false;
553 0 : for( size_t n = pLinkMgr->GetLinks().size(); n; )
554 0 : if( _pLink == &(*pLinkMgr->GetLinks()[ --n ]) )
555 : {
556 0 : bLinkFnd = true;
557 0 : break;
558 : }
559 :
560 0 : if( bLinkFnd )
561 : {
562 0 : m_pTbLinks->SetUpdateMode(false);
563 0 : m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
564 0 : SvTreeListEntry* pToUnselect = m_pTbLinks->FirstSelected();
565 0 : InsertEntry( *_pLink, nPos, true );
566 0 : if(pToUnselect)
567 0 : m_pTbLinks->Select(pToUnselect, false);
568 0 : m_pTbLinks->SetUpdateMode(true);
569 : }
570 : else
571 : {
572 0 : LinkManager* pNewMgr = pLinkMgr;
573 0 : pLinkMgr = 0;
574 0 : SetManager( pNewMgr );
575 : }
576 0 : if (pLinkMgr && pLinkMgr->GetPersist())
577 0 : pLinkMgr->GetPersist()->SetModified();
578 : }
579 0 : return 0;
580 : }
581 :
582 0 : OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
583 : {
584 0 : OUString sRet;
585 0 : if( !rLnk.GetObj() )
586 0 : sRet = Brokenlink();
587 0 : else if( rLnk.GetObj()->IsPending() )
588 : {
589 0 : sRet = Waitinglink();
590 0 : StartUpdateTimer();
591 : }
592 0 : else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
593 0 : sRet = Autolink();
594 : else
595 0 : sRet = Manuallink();
596 :
597 0 : return sRet;
598 : }
599 :
600 0 : void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
601 : {
602 0 : if( pLinkMgr == pNewMgr )
603 0 : return;
604 :
605 0 : if( pNewMgr )
606 : // update has to be stopped before clear
607 0 : m_pTbLinks->SetUpdateMode( false );
608 :
609 0 : m_pTbLinks->Clear();
610 0 : pLinkMgr = pNewMgr;
611 :
612 0 : if( pLinkMgr )
613 : {
614 0 : SvBaseLinks& rLnks = (SvBaseLinks&)pLinkMgr->GetLinks();
615 0 : for( size_t n = 0; n < rLnks.size(); ++n )
616 : {
617 0 : SvBaseLinkRef* pLinkRef = rLnks[ n ];
618 0 : if( !pLinkRef->Is() )
619 : {
620 0 : rLnks.erase( rLnks.begin() + n );
621 0 : --n;
622 0 : continue;
623 : }
624 0 : if( (*pLinkRef)->IsVisible() )
625 0 : InsertEntry( **pLinkRef );
626 : }
627 :
628 0 : if( !rLnks.empty() )
629 : {
630 0 : SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( 0 );
631 0 : m_pTbLinks->SetCurEntry( pEntry );
632 0 : m_pTbLinks->Select( pEntry );
633 0 : LinksSelectHdl( 0 );
634 : }
635 0 : m_pTbLinks->SetUpdateMode( true );
636 0 : m_pTbLinks->Invalidate();
637 : }
638 : }
639 :
640 :
641 0 : void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uLong nPos, bool bSelect )
642 : {
643 0 : OUString aEntry, sFileNm, sLinkNm, sTypeNm, sFilter;
644 :
645 0 : sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
646 :
647 : // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
648 : // So the first text column's width is Tab(2)-Tab(1).
649 0 : long nWidthPixel = m_pTbLinks->GetLogicTab( 2 ) - m_pTbLinks->GetLogicTab( 1 );
650 0 : nWidthPixel -= SV_TAB_BORDER;
651 0 : OUString aTxt = m_pTbLinks->GetEllipsisString( sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis );
652 0 : INetURLObject aPath( sFileNm, INetProtocol::File );
653 0 : OUString aFileName = aPath.getName();
654 0 : aFileName = INetURLObject::decode(aFileName, INetURLObject::DECODE_UNAMBIGUOUS);
655 :
656 0 : if( aFileName.getLength() > aTxt.getLength() )
657 0 : aTxt = aFileName;
658 0 : else if( aTxt.indexOf( aFileName, aTxt.getLength() - aFileName.getLength() ) == -1 )
659 : // filename not in string
660 0 : aTxt = aFileName;
661 :
662 0 : aEntry = aTxt;
663 0 : aEntry += "\t";
664 0 : if( OBJECT_CLIENT_GRF == rLink.GetObjType() )
665 0 : aEntry += sFilter;
666 : else
667 0 : aEntry += sLinkNm;
668 0 : aEntry += "\t";
669 0 : aEntry += sTypeNm;
670 0 : aEntry += "\t";
671 0 : aEntry += ImplGetStateStr( rLink );
672 :
673 0 : SvTreeListEntry * pE = m_pTbLinks->InsertEntryToColumn( aEntry, nPos );
674 0 : pE->SetUserData( const_cast<SvBaseLink *>(&rLink) );
675 0 : if(bSelect)
676 0 : m_pTbLinks->Select(pE);
677 0 : }
678 :
679 0 : SvBaseLink* SvBaseLinksDlg::GetSelEntry( sal_uLong* pPos )
680 : {
681 0 : SvTreeListEntry* pE = m_pTbLinks->FirstSelected();
682 : sal_uLong nPos;
683 0 : if( pE && TREELIST_ENTRY_NOTFOUND !=
684 0 : ( nPos = m_pTbLinks->GetModel()->GetAbsPos( pE ) ) )
685 : {
686 : DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
687 :
688 0 : if( pPos )
689 0 : *pPos = nPos;
690 0 : return static_cast<SvBaseLink*>(pE->GetUserData());
691 : }
692 0 : return 0;
693 : }
694 :
695 0 : void SvBaseLinksDlg::SetType( SvBaseLink& rLink,
696 : sal_uLong nSelPos,
697 : SfxLinkUpdateMode nType )
698 : {
699 0 : rLink.SetUpdateMode( nType );
700 0 : rLink.Update();
701 0 : SvTreeListEntry* pBox = m_pTbLinks->GetEntry( nSelPos );
702 0 : m_pTbLinks->SetEntryText( ImplGetStateStr( rLink ), pBox, 3 );
703 0 : if( pLinkMgr->GetPersist() )
704 0 : pLinkMgr->GetPersist()->SetModified();
705 0 : }
706 :
707 0 : void SvBaseLinksDlg::SetActLink( SvBaseLink * pLink )
708 : {
709 0 : if( pLinkMgr )
710 : {
711 0 : const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
712 0 : sal_uLong nSelect = 0;
713 0 : for( size_t n = 0; n < rLnks.size(); ++n )
714 : {
715 0 : SvBaseLinkRef* pLinkRef = rLnks[ n ];
716 : // #109573# only visible links have been inserted into the TreeListBox,
717 : // invisible ones have to be skipped here
718 0 : if( (*pLinkRef)->IsVisible() )
719 : {
720 0 : if( pLink == *pLinkRef )
721 : {
722 0 : m_pTbLinks->Select( m_pTbLinks->GetEntry( nSelect ) );
723 0 : LinksSelectHdl( 0 );
724 0 : return ;
725 : }
726 0 : nSelect++;
727 : }
728 : }
729 : }
730 0 : }
731 :
732 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|