xref: /AOO41X/main/cui/source/dialogs/linkdlg.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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