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