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