xref: /aoo41x/main/cui/source/dialogs/linkdlg.cxx (revision 2ee96f1c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cui.hxx"
26 
27 #include <linkdlg.hxx>
28 #include <vcl/svapp.hxx>
29 #include "helpid.hrc"
30 
31 #include <tools/urlobj.hxx>
32 #include <svtools/svmedit.hxx>
33 #include <svtools/filedlg.hxx>
34 #include <vcl/dialog.hxx>
35 #include <vcl/button.hxx>
36 #include <vcl/fixed.hxx>
37 #include <vcl/group.hxx>
38 #include <vcl/lstbox.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <vcl/timer.hxx>
41 #include <svtools/svtabbx.hxx>
42 
43 #include <svuidlg.hrc>
44 #include <sfx2/linkmgr.hxx>
45 #include <sfx2/linksrc.hxx>
46 #include <svtools/soerr.hxx>
47 #include <sfx2/lnkbase.hxx>
48 #include <sfx2/objsh.hxx>
49 
50 #include <dialmgr.hxx>
51 
52 #define _SVSTDARR_USHORTS
53 #include <svl/svstdarr.hxx>
54 
55 #define MAX_FILENAME	18
56 #define MAX_LINKNAME	18
57 #define MAX_TYPENAME	15
58 #define MAX_UPDATENAME	10
59 
60 #define FILEOBJECT ( OBJECT_CLIENT_FILE & ~OBJECT_CLIENT_SO )
61 
62 using namespace sfx2;
63 
64 SV_DECL_IMPL_REF_LIST(SvBaseLink,SvBaseLink*)
65 
66 // Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert
67 static long nTabs[] =
68 	{	4, // Number of Tabs
69 		0, 77, 144, 209
70 	};
71 
72 
73 SvBaseLinksDlg::SvBaseLinksDlg( Window * pParent, LinkManager* pMgr, sal_Bool bHtml )
74     : ModalDialog( pParent, CUI_RES( MD_UPDATE_BASELINKS ) ),
75     aFtFiles( this, CUI_RES( FT_FILES ) ),
76     aFtLinks( this, CUI_RES( FT_LINKS ) ),
77     aFtType( this, CUI_RES( FT_TYPE ) ),
78     aFtStatus( this, CUI_RES( FT_STATUS ) ),
79     aTbLinks( this, CUI_RES(TB_LINKS ) ),
80     aFtFiles2( this, CUI_RES( FT_FILES2 ) ),
81     aFtFullFileName( this, CUI_RES( FT_FULL_FILE_NAME ) ),
82     aFtSource2( this, CUI_RES( FT_SOURCE2 ) ),
83     aFtFullSourceName( this, CUI_RES( FT_FULL_SOURCE_NAME ) ),
84     aFtType2( this, CUI_RES( FT_TYPE2 ) ),
85     aFtFullTypeName( this, CUI_RES( FT_FULL_TYPE_NAME ) ),
86     aFtUpdate( this, CUI_RES( FT_UPDATE ) ),
87     aRbAutomatic( this, CUI_RES( RB_AUTOMATIC ) ),
88     aRbManual( this, CUI_RES( RB_MANUAL ) ),
89     aCancelButton1( this, CUI_RES( 1 ) ),
90     aHelpButton1( this, CUI_RES( 1 ) ),
91     aPbUpdateNow( this, CUI_RES( PB_UPDATE_NOW ) ),
92     aPbOpenSource( this, CUI_RES( PB_OPEN_SOURCE ) ),
93     aPbChangeSource( this, CUI_RES( PB_CHANGE_SOURCE ) ),
94     aPbBreakLink( this, CUI_RES( PB_BREAK_LINK ) ),
95     aStrAutolink( CUI_RES( STR_AUTOLINK ) ),
96     aStrManuallink( CUI_RES( STR_MANUALLINK ) ),
97     aStrBrokenlink( CUI_RES( STR_BROKENLINK ) ),
98     aStrGraphiclink( CUI_RES( STR_GRAPHICLINK ) ),
99     aStrButtonclose( CUI_RES( STR_BUTTONCLOSE ) ),
100     aStrCloselinkmsg( CUI_RES( STR_CLOSELINKMSG ) ),
101     aStrCloselinkmsgMulti( CUI_RES( STR_CLOSELINKMSG_MULTI ) ),
102     aStrWaitinglink( CUI_RES( STR_WAITINGLINK ) ),
103     pLinkMgr( NULL ),
104 	bHtmlMode(bHtml)
105 {
106     FreeResource();
107 
108     aTbLinks.SetHelpId(HID_LINKDLG_TABLB);
109     aTbLinks.SetSelectionMode( MULTIPLE_SELECTION );
110     aTbLinks.SetTabs( &nTabs[0], MAP_APPFONT );
111     aTbLinks.Resize();  // OS: Hack fuer richtige Selektion
112 
113     //JP 24.02.99: UpdateTimer fuer DDE-/Grf-Links, auf die gewarted wird
114     aUpdateTimer.SetTimeoutHdl( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
115     aUpdateTimer.SetTimeout( 1000 );
116 	//IAccessibility2 Implementation 2009-----
117 	// Set the ZOrder, and accessible name to the dialog's title
118 	aTbLinks.SetZOrder(0, WINDOW_ZORDER_FIRST);
119 	aTbLinks.SetAccessibleName(this->GetText());
120 	aTbLinks.SetAccessibleRelationLabeledBy(&aFtFiles);
121 	//-----IAccessibility2 Implementation 2009
122 
123     OpenSource().Hide();
124 
125     Links().SetSelectHdl( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
126     Links().SetDoubleClickHdl( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
127     Automatic().SetClickHdl( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
128     Manual().SetClickHdl( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
129     UpdateNow().SetClickHdl( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
130 //  OpenSource().SetClickHdl( LINK( this, SvBaseLinksDlg, OpenSourceClickHdl ) );
131     ChangeSource().SetClickHdl( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
132 	if(!bHtmlMode)
133         BreakLink().SetClickHdl( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
134 	else
135         BreakLink().Hide();
136 
137 	SetManager( pMgr );
138 }
139 
140 SvBaseLinksDlg::~SvBaseLinksDlg()
141 {
142 }
143 
144 /*************************************************************************
145 |*    SvBaseLinksDlg::Handler()
146 |*
147 |*	  Beschreibung
148 |*	  Ersterstellung	MM 14.06.94
149 |*	  Letzte Aenderung	JP 30.05.95
150 *************************************************************************/
151 IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTabListBox *, pSvTabListBox )
152 {
153 	sal_uInt16 nSelectionCount = pSvTabListBox ?
154 		(sal_uInt16)pSvTabListBox->GetSelectionCount() : 0;
155 	if(nSelectionCount > 1)
156 	{
157 		//bei Mehrfachselektion ggf. alte Eintraege deselektieren
158 		SvLBoxEntry* pEntry = 0;
159 		SvBaseLink* pLink = 0;
160 		pEntry = pSvTabListBox->GetHdlEntry();
161 		pLink = (SvBaseLink*)pEntry->GetUserData();
162 		sal_uInt16 nObjectType = pLink->GetObjType();
163 		if((OBJECT_CLIENT_FILE & nObjectType) != OBJECT_CLIENT_FILE)
164 		{
165 			pSvTabListBox->SelectAll(sal_False);
166 			pSvTabListBox->Select(pEntry);
167 			nSelectionCount = 1;
168 		}
169 		else
170 		{
171 			for( sal_uInt16 i = 0; i < nSelectionCount; i++)
172 			{
173 				pEntry = i == 0 ? pSvTabListBox->FirstSelected() :
174 									pSvTabListBox->NextSelected(pEntry);
175 				DBG_ASSERT(pEntry, "Wo ist der Entry?");
176 				pLink = (SvBaseLink*)pEntry->GetUserData();
177 				DBG_ASSERT(pLink, "Wo ist der Link?");
178 				if( (OBJECT_CLIENT_FILE & pLink->GetObjType()) != OBJECT_CLIENT_FILE )
179 					pSvTabListBox->Select( pEntry, sal_False );
180 
181 			}
182 		}
183 
184         UpdateNow().Enable();
185 
186         Automatic().Disable();
187         Manual().Check();
188         Manual().Disable();
189 	}
190 	else
191 	{
192 		sal_uInt16 nPos;
193 		SvBaseLink* pLink = GetSelEntry( &nPos );
194 		if( !pLink )
195 			return 0;
196 
197         UpdateNow().Enable();
198 
199 		String sType, sLink;
200 		String *pLinkNm = &sLink, *pFilter = 0;
201 
202 		if( FILEOBJECT & pLink->GetObjType() )
203 		{
204             Automatic().Disable();
205             Manual().Check();
206             Manual().Disable();
207 			if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
208 				pLinkNm = 0, pFilter = &sLink;
209 		}
210 		else
211 		{
212             Automatic().Enable();
213             Manual().Enable();
214 
215 			if( LINKUPDATE_ALWAYS == pLink->GetUpdateMode() )
216                 Automatic().Check();
217 			else
218                 Manual().Check();
219 		}
220 
221 		String aFileName;
222 		pLinkMgr->GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
223         aFileName = INetURLObject::decode(aFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
224         FileName().SetText( aFileName );
225         SourceName().SetText( sLink );
226         TypeName().SetText( sType );
227 	}
228 	return 0;
229 }
230 
231 IMPL_LINK_INLINE_START( SvBaseLinksDlg, LinksDoubleClickHdl, SvTabListBox *, pSvTabListBox )
232 {
233 	(void)pSvTabListBox;
234 
235 	ChangeSourceClickHdl( 0 );
236 	return 0;
237 }
238 IMPL_LINK_INLINE_END( SvBaseLinksDlg, LinksDoubleClickHdl, SvTabListBox *, pSvTabListBox )
239 
240 IMPL_LINK_INLINE_START( SvBaseLinksDlg, AutomaticClickHdl, RadioButton *, pRadioButton )
241 {
242 	(void)pRadioButton;
243 
244 	sal_uInt16 nPos;
245 	SvBaseLink* pLink = GetSelEntry( &nPos );
246 	if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
247 		LINKUPDATE_ALWAYS != pLink->GetUpdateMode() )
248 		SetType( *pLink, nPos, LINKUPDATE_ALWAYS );
249 	return 0;
250 }
251 IMPL_LINK_INLINE_END( SvBaseLinksDlg, AutomaticClickHdl, RadioButton *, pRadioButton )
252 
253 IMPL_LINK_INLINE_START( SvBaseLinksDlg, ManualClickHdl, RadioButton *, pRadioButton )
254 {
255 	(void)pRadioButton;
256 
257 	sal_uInt16 nPos;
258 	SvBaseLink* pLink = GetSelEntry( &nPos );
259 	if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
260 		LINKUPDATE_ONCALL != pLink->GetUpdateMode())
261 		SetType( *pLink, nPos, LINKUPDATE_ONCALL );
262 	return 0;
263 }
264 IMPL_LINK_INLINE_END( SvBaseLinksDlg, ManualClickHdl, RadioButton *, pRadioButton )
265 
266 IMPL_LINK( SvBaseLinksDlg, UpdateNowClickHdl, PushButton *, EMPTYARG )
267 {
268     SvTabListBox& rListBox = Links();
269 	sal_uInt16 nSelCnt = (sal_uInt16)rListBox.GetSelectionCount();
270 	if( 255 < nSelCnt )
271 		nSelCnt = 255;
272 
273 	std::vector< SvBaseLink* > aLnkArr;
274 	std::vector< sal_uInt16 > aPosArr;
275 
276 	SvLBoxEntry* pE = rListBox.FirstSelected();
277 	while( pE )
278 	{
279 		sal_uInt16 nFndPos = (sal_uInt16)rListBox.GetModel()->GetAbsPos( pE );
280 		if( LISTBOX_ENTRY_NOTFOUND != nFndPos )
281 		{
282 			aLnkArr.push_back( static_cast< SvBaseLink* >( pE->GetUserData() ) );
283 			aPosArr.push_back( nFndPos );
284 		}
285 		pE = rListBox.NextSelected( pE );
286 	}
287 
288 	if( !aLnkArr.empty() )
289 	{
290 		for( sal_uInt16 n = 0; n < aLnkArr.size(); ++n )
291 		{
292 			SvBaseLinkRef xLink = aLnkArr[ n ];
293 
294 			// suche erstmal im Array nach dem Eintrag
295 			for( sal_uInt16 i = 0; i < pLinkMgr->GetLinks().Count(); ++i )
296 				if( &xLink == *pLinkMgr->GetLinks()[ i ] )
297 				{
298 					xLink->SetUseCache( sal_False );
299 					SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
300 					xLink->SetUseCache( sal_True );
301 					break;
302 				}
303 		}
304 
305 		// falls jemand der Meinung ist, seine Links auszutauschen (SD)
306 		LinkManager* pNewMgr = pLinkMgr;
307 		pLinkMgr = 0;
308 		SetManager( pNewMgr );
309 
310 
311 		if( 0 == (pE = rListBox.GetEntry( aPosArr[ 0 ] )) ||
312 			pE->GetUserData() != aLnkArr[ 0 ] )
313 		{
314 			// suche mal den Link
315 			pE = rListBox.First();
316 			while( pE )
317 			{
318 				if( pE->GetUserData() == aLnkArr[ 0 ] )
319 					break;
320 				pE = rListBox.Next( pE );
321 			}
322 
323 			if( !pE )
324 				pE = rListBox.FirstSelected();
325 		}
326 
327 		if( pE )
328 		{
329 			SvLBoxEntry* pSelEntry = rListBox.FirstSelected();
330 			if( pE != pSelEntry )
331 				rListBox.Select( pSelEntry, sal_False );
332 			rListBox.Select( pE );
333 			rListBox.MakeVisible( pE );
334 		}
335 	}
336 	return 0;
337 }
338 
339 /*
340 IMPL_LINK_INLINE_START( SvBaseLinksDlg, OpenSourceClickHdl, PushButton *, pPushButton )
341 {
342 	DBG_ASSERT( !this, "Open noch nicht impl." );
343 	return 0;
344 }
345 IMPL_LINK_INLINE_END( SvBaseLinksDlg, OpenSourceClickHdl, PushButton *, pPushButton )
346 */
347 
348 IMPL_LINK( SvBaseLinksDlg, ChangeSourceClickHdl, PushButton *, pPushButton )
349 {
350 	(void)pPushButton;
351 
352     sal_uInt16 nSelectionCount = (sal_uInt16)Links().GetSelectionCount();
353 	if(nSelectionCount > 1)
354 	{
355         PathDialog aPathDlg( this );
356 		String sType, sFile, sLinkName;
357 		String  sFilter;
358         SvLBoxEntry* pEntry = Links().FirstSelected();
359 		SvBaseLink* pLink = (SvBaseLink*)pEntry->GetUserData();
360 		pLinkMgr->GetDisplayNames( pLink, &sType, &sFile, 0, 0 );
361 		INetURLObject aUrl(sFile);
362 		if(aUrl.GetProtocol() == INET_PROT_FILE)
363 		{
364 			rtl::OUString sOldPath(aUrl.PathToFileName());
365 			sal_Int32 nLen = aUrl.GetName().getLength();
366 			sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
367 			aPathDlg.SetPath(sOldPath);
368 		}
369 		if(aPathDlg.Execute() == RET_OK)
370 		{
371 			String aPath = aPathDlg.GetPath();
372 
373 			for( sal_uInt16 i = 0; i < nSelectionCount; i++)
374 			{
375 				pEntry = i==0 ?
376                         Links().FirstSelected() :
377                             Links().NextSelected( pEntry );
378 				DBG_ASSERT(pEntry,"Wo ist der Entry");
379 				pLink = (SvBaseLink*)pEntry->GetUserData();
380 				DBG_ASSERT(pLink,"Wo ist der Link");
381 				pLinkMgr->GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
382 				INetURLObject aUrl_(sFile);
383 				INetURLObject aUrl2(aPath, INET_PROT_FILE);
384 				aUrl2.insertName( aUrl_.getName() );
385 				String sNewLinkName;
386                 MakeLnkName( sNewLinkName, 0 ,
387 						aUrl2.GetMainURL(INetURLObject::DECODE_TO_IURI), sLinkName, &sFilter);
388 				pLink->SetLinkSourceName( sNewLinkName );
389 				pLink->Update();
390 			}
391 			if( pLinkMgr->GetPersist() )
392 				pLinkMgr->GetPersist()->SetModified();
393 			LinkManager* pNewMgr = pLinkMgr;
394 			pLinkMgr = 0;
395 			SetManager( pNewMgr );
396 		}
397 	}
398 	else
399 	{
400 		sal_uInt16 nPos;
401 		SvBaseLink* pLink = GetSelEntry( &nPos );
402         if ( pLink && (pLink->GetLinkSourceName().Len() != 0) )
403             pLink->Edit( this, LINK( this, SvBaseLinksDlg, EndEditHdl ) );
404 	}
405 	return 0;
406 }
407 
408 IMPL_LINK( SvBaseLinksDlg, BreakLinkClickHdl, PushButton *, pPushButton )
409 {
410 	(void)pPushButton;
411 
412 	sal_Bool bModified = sal_False;
413     if(Links().GetSelectionCount() <= 1)
414 	{
415 		sal_uInt16 nPos;
416 		SvBaseLinkRef xLink = GetSelEntry( &nPos );
417 		if( !xLink.Is() )
418 			return 0;
419 
420         QueryBox aBox( this, WB_YES_NO | WB_DEF_YES, Closelinkmsg() );
421 
422 		if( RET_YES == aBox.Execute() )
423 		{
424             Links().GetModel()->Remove( Links().GetEntry( nPos ) );
425 
426 			// falls Object noch vorhanden, dann das schliessen
427 			sal_Bool bNewLnkMgr = OBJECT_CLIENT_FILE == xLink->GetObjType();
428 
429 			// dem Link sagen, das er aufgeloest wird!
430 			xLink->Closed();
431 
432 			// falls einer vergessen hat sich auszutragen
433 			if( xLink.Is() )
434 				pLinkMgr->Remove( &xLink );
435 
436 			if( bNewLnkMgr )
437 			{
438 				LinkManager* pNewMgr = pLinkMgr;
439 				pLinkMgr = 0;
440 				SetManager( pNewMgr );
441 
442                 SvLBoxEntry* pEntry = Links().GetEntry( nPos ? --nPos : 0 );
443 				if( pEntry )
444                     Links().SetCurEntry( pEntry );
445 			}
446 			bModified = sal_True;
447 		}
448 	}
449 	else
450 	{
451         QueryBox aBox( this, WB_YES_NO | WB_DEF_YES, CloselinkmsgMulti() );
452 
453 		if( RET_YES == aBox.Execute() )
454 		{
455 
456 			SvBaseLinkMemberList aLinkList;
457             SvLBoxEntry* pEntry = Links().FirstSelected();
458 			while ( pEntry )
459 			{
460 				void * pUD = pEntry->GetUserData();
461 				if( pUD )
462 					aLinkList.Append( (SvBaseLink*)pUD );
463                 pEntry = Links().NextSelected(pEntry);
464 			}
465             Links().RemoveSelection();
466 			for( sal_uLong i = 0; i < aLinkList.Count(); i++ )
467 			{
468 				SvBaseLinkRef xLink = aLinkList.GetObject( i );
469 				// dem Link sagen, das er aufgeloest wird!
470 				xLink->Closed();
471 
472 				// falls einer vergessen hat sich auszutragen
473 				pLinkMgr->Remove( &xLink );
474 				bModified = sal_True;
475 			}
476 			//Danach alle selektierten Eintraege entfernen
477 		}
478 	}
479 	if(bModified)
480 	{
481         if( !Links().GetEntryCount() )
482 		{
483 			// Der letzte macht das Licht aus
484             Automatic().Disable();
485             Manual().Disable();
486             UpdateNow().Disable();
487 //            OpenSource().Disable();
488             ChangeSource().Disable();
489             BreakLink().Disable();
490 
491 			String aEmpty;
492             SourceName().SetText( aEmpty );
493             TypeName().SetText( aEmpty );
494 		}
495 		if( pLinkMgr->GetPersist() )
496 			pLinkMgr->GetPersist()->SetModified();
497 	}
498 	return 0;
499 }
500 
501 IMPL_LINK( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, pTimer )
502 {
503 	(void)pTimer;
504 //    for( SvLBoxEntry* pBox = Links().First(); pBox;
505 //          pBox = Links().Next( pBox ))
506 
507     Links().SetUpdateMode(sal_False);
508     for( sal_uLong nPos = Links().GetEntryCount(); nPos; )
509 	{
510         SvLBoxEntry* pBox = Links().GetEntry( --nPos );
511 		SvBaseLinkRef xLink( (SvBaseLink*)pBox->GetUserData() );
512 		if( xLink.Is() )
513 		{
514 			String sCur( ImplGetStateStr( *xLink ) ),
515                     sOld( Links().GetEntryText( pBox, 3 ) );
516 			if( sCur != sOld )
517                 Links().SetEntryText( sCur, pBox, 3 );
518 		}
519 	}
520     Links().SetUpdateMode(sal_True);
521 	return 0;
522 }
523 
524 IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink*, _pLink )
525 {
526     sal_uInt16 nPos;
527     GetSelEntry( &nPos );
528 
529     if( _pLink && _pLink->WasLastEditOK() )
530     {
531         // JP 09.01.98:
532         // StarImpress/Draw tauschen die LinkObjecte selbst aus!
533         // also suche den Link im Manager, wenn der nicht mehr existiert,
534         // dann setze fuelle die Liste komplett neu. Ansonsten braucht
535         // nur der editierte Linkt aktualisiert werden.
536         sal_Bool bLinkFnd = sal_False;
537         for( sal_uInt16 n = pLinkMgr->GetLinks().Count(); n;  )
538             if( _pLink == &(*pLinkMgr->GetLinks()[ --n ]) )
539             {
540                 bLinkFnd = sal_True;
541                 break;
542             }
543 
544         if( bLinkFnd )
545         {
546             Links().SetUpdateMode(sal_False);
547             Links().GetModel()->Remove( Links().GetEntry( nPos ) );
548             SvLBoxEntry* pToUnselect = Links().FirstSelected();
549             InsertEntry( *_pLink, nPos, sal_True );
550             if(pToUnselect)
551                 Links().Select(pToUnselect, sal_False);
552             Links().SetUpdateMode(sal_True);
553         }
554         else
555         {
556             LinkManager* pNewMgr = pLinkMgr;
557             pLinkMgr = 0;
558             SetManager( pNewMgr );
559         }
560         if( pLinkMgr->GetPersist() )
561             pLinkMgr->GetPersist()->SetModified();
562     }
563     return 0;
564 }
565 
566 String SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
567 {
568 	String sRet;
569 	if( !rLnk.GetObj() )
570         sRet = Brokenlink();
571 	else if( rLnk.GetObj()->IsPending() )
572 	{
573         sRet = Waitinglink();
574         StartUpdateTimer();
575 	}
576 	else if( LINKUPDATE_ALWAYS == rLnk.GetUpdateMode() )
577         sRet = Autolink();
578 	else
579         sRet = Manuallink();
580 
581 	return sRet;
582 }
583 
584 void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
585 {
586 	if( pLinkMgr == pNewMgr )
587 		return;
588 
589 	if( pNewMgr )
590 		// Update muss vor Clear gestoppt werden
591         Links().SetUpdateMode( sal_False );
592 
593     Links().Clear();
594 	pLinkMgr = pNewMgr;
595 
596 	if( pLinkMgr )
597 	{
598 		SvBaseLinks& rLnks = (SvBaseLinks&)pLinkMgr->GetLinks();
599 		for( sal_uInt16 n = 0; n < rLnks.Count(); ++n )
600 		{
601 			SvBaseLinkRef* pLinkRef = rLnks[ n ];
602 			if( !pLinkRef->Is() )
603 			{
604 				rLnks.Remove( n, 1 );
605 				--n;
606 				continue;
607 			}
608 			if( (*pLinkRef)->IsVisible() )
609 				InsertEntry( **pLinkRef );
610 		}
611 
612 		if( rLnks.Count() )
613 		{
614             SvLBoxEntry* pEntry = Links().GetEntry( 0 );
615             Links().SetCurEntry( pEntry );
616             Links().Select( pEntry );
617 			LinksSelectHdl( 0 );
618 		}
619         Links().SetUpdateMode( sal_True );
620         Links().Invalidate();
621 	}
622 }
623 
624 
625 void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uInt16 nPos, sal_Bool bSelect )
626 {
627 	String aEntry, sFileNm, sLinkNm, sTypeNm, sFilter;
628 
629 	pLinkMgr->GetDisplayNames( (SvBaseLink*)&rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
630 
631 	// GetTab(0) gibt die Position der von der TabListBox automatisch eingefuegten
632 	// Bitmap. Die Breite der ersten Textspalte ergibt sich deshalb aus Tab(2)-Tab(1)
633     long nWidthPixel = Links().GetLogicTab( 2 ) - Links().GetLogicTab( 1 );
634 	nWidthPixel -= SV_TAB_BORDER;
635     XubString aTxt = Links().GetEllipsisString( sFileNm, nWidthPixel, TEXT_DRAW_PATHELLIPSIS );
636 	INetURLObject aPath( sFileNm, INET_PROT_FILE );
637 	String aFileName = aPath.getName();
638     aFileName = INetURLObject::decode(aFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
639 
640     if( aFileName.Len() > aTxt.Len() )
641 		aTxt = aFileName;
642 	else if( aTxt.Search( aFileName, aTxt.Len() - aFileName.Len() ) == STRING_NOTFOUND )
643 		// filename not in string
644 		aTxt = aFileName;
645 
646 	aEntry = aTxt;
647 	aEntry += '\t';
648 	if( OBJECT_CLIENT_GRF == rLink.GetObjType() )
649 		aEntry += sFilter;
650 	else
651 		aEntry += sLinkNm;
652 	aEntry += '\t';
653 	aEntry += sTypeNm;
654 	aEntry += '\t';
655 	aEntry += ImplGetStateStr( rLink );
656 
657     SvLBoxEntry * pE = Links().InsertEntryToColumn( aEntry, nPos );
658 	pE->SetUserData( (void*)&rLink );
659     if(bSelect)
660         Links().Select(pE);
661 }
662 
663 SvBaseLink* SvBaseLinksDlg::GetSelEntry( sal_uInt16* pPos )
664 {
665     SvLBoxEntry* pE = Links().FirstSelected();
666 	sal_uInt16 nPos;
667 	if( pE && LISTBOX_ENTRY_NOTFOUND !=
668         ( nPos = (sal_uInt16)Links().GetModel()->GetAbsPos( pE ) ) )
669 	{
670 		DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
671 
672 		if( pPos )
673 			*pPos = nPos;
674 		return (SvBaseLink*)pE->GetUserData();
675 	}
676 	return 0;
677 }
678 
679 void SvBaseLinksDlg::SetType( SvBaseLink& rLink,
680 									sal_uInt16 nSelPos,
681 									sal_uInt16 nType )
682 {
683 	rLink.SetUpdateMode( nType );
684 	rLink.Update();
685     SvLBoxEntry* pBox = Links().GetEntry( nSelPos );
686     Links().SetEntryText( ImplGetStateStr( rLink ), pBox, 3 );
687 	if( pLinkMgr->GetPersist() )
688 		pLinkMgr->GetPersist()->SetModified();
689 }
690 
691 void SvBaseLinksDlg::SetActLink( SvBaseLink * pLink )
692 {
693 	if( pLinkMgr )
694 	{
695 		const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
696         sal_uInt16 nSelect = 0;
697         for( sal_uInt16 n = 0; n < rLnks.Count(); ++n )
698         {
699             SvBaseLinkRef* pLinkRef = rLnks[ n ];
700             // #109573# only visible links have been inserted into the TreeListBox,
701             // invisible ones have to be skipped here
702             if( (*pLinkRef)->IsVisible() )
703             {
704                 if( pLink == *pLinkRef )
705                 {
706                     Links().Select( Links().GetEntry( nSelect ) );
707                     LinksSelectHdl( 0 );
708                     return ;
709                 }
710                 nSelect++;
711             }
712         }
713 	}
714 }
715 
716