xref: /trunk/main/cui/source/dialogs/linkdlg.cxx (revision 870262e3)
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 
SvBaseLinksDlg(Window * pParent,LinkManager * pMgr,sal_Bool bHtml)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 	// Set the ZOrder, and accessible name to the dialog's title
117 	aTbLinks.SetZOrder(0, WINDOW_ZORDER_FIRST);
118 	aTbLinks.SetAccessibleName(this->GetText());
119 	aTbLinks.SetAccessibleRelationLabeledBy(&aFtFiles);
120 
121     OpenSource().Hide();
122 
123     Links().SetSelectHdl( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
124     Links().SetDoubleClickHdl( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
125     Automatic().SetClickHdl( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
126     Manual().SetClickHdl( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
127     UpdateNow().SetClickHdl( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
128 //  OpenSource().SetClickHdl( LINK( this, SvBaseLinksDlg, OpenSourceClickHdl ) );
129     ChangeSource().SetClickHdl( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
130 	if(!bHtmlMode)
131         BreakLink().SetClickHdl( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
132 	else
133         BreakLink().Hide();
134 
135 	SetManager( pMgr );
136 }
137 
~SvBaseLinksDlg()138 SvBaseLinksDlg::~SvBaseLinksDlg()
139 {
140 }
141 
142 /*************************************************************************
143 |*    SvBaseLinksDlg::Handler()
144 |*
145 |*	  Beschreibung
146 |*	  Ersterstellung	MM 14.06.94
147 |*	  Letzte Aenderung	JP 30.05.95
148 *************************************************************************/
IMPL_LINK(SvBaseLinksDlg,LinksSelectHdl,SvTabListBox *,pSvTabListBox)149 IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTabListBox *, pSvTabListBox )
150 {
151 	sal_uInt16 nSelectionCount = pSvTabListBox ?
152 		(sal_uInt16)pSvTabListBox->GetSelectionCount() : 0;
153 	if(nSelectionCount > 1)
154 	{
155 		//bei Mehrfachselektion ggf. alte Eintraege deselektieren
156 		SvLBoxEntry* pEntry = 0;
157 		SvBaseLink* pLink = 0;
158 		pEntry = pSvTabListBox->GetHdlEntry();
159 		pLink = (SvBaseLink*)pEntry->GetUserData();
160 		sal_uInt16 nObjectType = pLink->GetObjType();
161 		if((OBJECT_CLIENT_FILE & nObjectType) != OBJECT_CLIENT_FILE)
162 		{
163 			pSvTabListBox->SelectAll(sal_False);
164 			pSvTabListBox->Select(pEntry);
165 			nSelectionCount = 1;
166 		}
167 		else
168 		{
169 			for( sal_uInt16 i = 0; i < nSelectionCount; i++)
170 			{
171 				pEntry = i == 0 ? pSvTabListBox->FirstSelected() :
172 									pSvTabListBox->NextSelected(pEntry);
173 				DBG_ASSERT(pEntry, "Wo ist der Entry?");
174 				pLink = (SvBaseLink*)pEntry->GetUserData();
175 				DBG_ASSERT(pLink, "Wo ist der Link?");
176 				if( (OBJECT_CLIENT_FILE & pLink->GetObjType()) != OBJECT_CLIENT_FILE )
177 					pSvTabListBox->Select( pEntry, sal_False );
178 
179 			}
180 		}
181 
182         UpdateNow().Enable();
183 
184         Automatic().Disable();
185         Manual().Check();
186         Manual().Disable();
187 	}
188 	else
189 	{
190 		sal_uInt16 nPos;
191 		SvBaseLink* pLink = GetSelEntry( &nPos );
192 		if( !pLink )
193 			return 0;
194 
195         UpdateNow().Enable();
196 
197 		String sType, sLink;
198 		String *pLinkNm = &sLink, *pFilter = 0;
199 
200 		if( FILEOBJECT & pLink->GetObjType() )
201 		{
202             Automatic().Disable();
203             Manual().Check();
204             Manual().Disable();
205 			if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
206 				pLinkNm = 0, pFilter = &sLink;
207 		}
208 		else
209 		{
210             Automatic().Enable();
211             Manual().Enable();
212 
213 			if( LINKUPDATE_ALWAYS == pLink->GetUpdateMode() )
214                 Automatic().Check();
215 			else
216                 Manual().Check();
217 		}
218 
219 		String aFileName;
220 		pLinkMgr->GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
221         aFileName = INetURLObject::decode(aFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
222         FileName().SetText( aFileName );
223         SourceName().SetText( sLink );
224         TypeName().SetText( sType );
225 	}
226 	return 0;
227 }
228 
IMPL_LINK_INLINE_START(SvBaseLinksDlg,LinksDoubleClickHdl,SvTabListBox *,pSvTabListBox)229 IMPL_LINK_INLINE_START( SvBaseLinksDlg, LinksDoubleClickHdl, SvTabListBox *, pSvTabListBox )
230 {
231 	(void)pSvTabListBox;
232 
233 	ChangeSourceClickHdl( 0 );
234 	return 0;
235 }
IMPL_LINK_INLINE_END(SvBaseLinksDlg,LinksDoubleClickHdl,SvTabListBox *,pSvTabListBox)236 IMPL_LINK_INLINE_END( SvBaseLinksDlg, LinksDoubleClickHdl, SvTabListBox *, pSvTabListBox )
237 
238 IMPL_LINK_INLINE_START( SvBaseLinksDlg, AutomaticClickHdl, RadioButton *, pRadioButton )
239 {
240 	(void)pRadioButton;
241 
242 	sal_uInt16 nPos;
243 	SvBaseLink* pLink = GetSelEntry( &nPos );
244 	if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
245 		LINKUPDATE_ALWAYS != pLink->GetUpdateMode() )
246 		SetType( *pLink, nPos, LINKUPDATE_ALWAYS );
247 	return 0;
248 }
IMPL_LINK_INLINE_END(SvBaseLinksDlg,AutomaticClickHdl,RadioButton *,pRadioButton)249 IMPL_LINK_INLINE_END( SvBaseLinksDlg, AutomaticClickHdl, RadioButton *, pRadioButton )
250 
251 IMPL_LINK_INLINE_START( SvBaseLinksDlg, ManualClickHdl, RadioButton *, pRadioButton )
252 {
253 	(void)pRadioButton;
254 
255 	sal_uInt16 nPos;
256 	SvBaseLink* pLink = GetSelEntry( &nPos );
257 	if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
258 		LINKUPDATE_ONCALL != pLink->GetUpdateMode())
259 		SetType( *pLink, nPos, LINKUPDATE_ONCALL );
260 	return 0;
261 }
IMPL_LINK_INLINE_END(SvBaseLinksDlg,ManualClickHdl,RadioButton *,pRadioButton)262 IMPL_LINK_INLINE_END( SvBaseLinksDlg, ManualClickHdl, RadioButton *, pRadioButton )
263 
264 IMPL_LINK( SvBaseLinksDlg, UpdateNowClickHdl, PushButton *, EMPTYARG )
265 {
266     SvTabListBox& rListBox = Links();
267 	sal_uInt16 nSelCnt = (sal_uInt16)rListBox.GetSelectionCount();
268 	if( 255 < nSelCnt )
269 		nSelCnt = 255;
270 
271 	std::vector< SvBaseLink* > aLnkArr;
272 	std::vector< sal_uInt16 > aPosArr;
273 
274 	SvLBoxEntry* pE = rListBox.FirstSelected();
275 	while( pE )
276 	{
277 		sal_uInt16 nFndPos = (sal_uInt16)rListBox.GetModel()->GetAbsPos( pE );
278 		if( LISTBOX_ENTRY_NOTFOUND != nFndPos )
279 		{
280 			aLnkArr.push_back( static_cast< SvBaseLink* >( pE->GetUserData() ) );
281 			aPosArr.push_back( nFndPos );
282 		}
283 		pE = rListBox.NextSelected( pE );
284 	}
285 
286 	if( !aLnkArr.empty() )
287 	{
288 		for( sal_uInt16 n = 0; n < aLnkArr.size(); ++n )
289 		{
290 			SvBaseLinkRef xLink = aLnkArr[ n ];
291 
292 			// suche erstmal im Array nach dem Eintrag
293 			for( sal_uInt16 i = 0; i < pLinkMgr->GetLinks().Count(); ++i )
294 				if( &xLink == *pLinkMgr->GetLinks()[ i ] )
295 				{
296 					xLink->SetUseCache( sal_False );
297 					SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
298 					xLink->SetUseCache( sal_True );
299 					break;
300 				}
301 		}
302 
303 		// falls jemand der Meinung ist, seine Links auszutauschen (SD)
304 		LinkManager* pNewMgr = pLinkMgr;
305 		pLinkMgr = 0;
306 		SetManager( pNewMgr );
307 
308 
309 		if( 0 == (pE = rListBox.GetEntry( aPosArr[ 0 ] )) ||
310 			pE->GetUserData() != aLnkArr[ 0 ] )
311 		{
312 			// suche mal den Link
313 			pE = rListBox.First();
314 			while( pE )
315 			{
316 				if( pE->GetUserData() == aLnkArr[ 0 ] )
317 					break;
318 				pE = rListBox.Next( pE );
319 			}
320 
321 			if( !pE )
322 				pE = rListBox.FirstSelected();
323 		}
324 
325 		if( pE )
326 		{
327 			SvLBoxEntry* pSelEntry = rListBox.FirstSelected();
328 			if( pE != pSelEntry )
329 				rListBox.Select( pSelEntry, sal_False );
330 			rListBox.Select( pE );
331 			rListBox.MakeVisible( pE );
332 		}
333 	}
334 	return 0;
335 }
336 
337 /*
338 IMPL_LINK_INLINE_START( SvBaseLinksDlg, OpenSourceClickHdl, PushButton *, pPushButton )
339 {
340 	DBG_ASSERT( sal_False, "Open not yet implemented" );
341 	return 0;
342 }
343 IMPL_LINK_INLINE_END( SvBaseLinksDlg, OpenSourceClickHdl, PushButton *, pPushButton )
344 */
345 
IMPL_LINK(SvBaseLinksDlg,ChangeSourceClickHdl,PushButton *,pPushButton)346 IMPL_LINK( SvBaseLinksDlg, ChangeSourceClickHdl, PushButton *, pPushButton )
347 {
348 	(void)pPushButton;
349 
350     sal_uInt16 nSelectionCount = (sal_uInt16)Links().GetSelectionCount();
351 	if(nSelectionCount > 1)
352 	{
353         PathDialog aPathDlg( this );
354 		String sType, sFile, sLinkName;
355 		String  sFilter;
356         SvLBoxEntry* pEntry = Links().FirstSelected();
357 		SvBaseLink* pLink = (SvBaseLink*)pEntry->GetUserData();
358 		pLinkMgr->GetDisplayNames( pLink, &sType, &sFile, 0, 0 );
359 		INetURLObject aUrl(sFile);
360 		if(aUrl.GetProtocol() == INET_PROT_FILE)
361 		{
362 			rtl::OUString sOldPath(aUrl.PathToFileName());
363 			sal_Int32 nLen = aUrl.GetName().getLength();
364 			sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
365 			aPathDlg.SetPath(sOldPath);
366 		}
367 		if(aPathDlg.Execute() == RET_OK)
368 		{
369 			String aPath = aPathDlg.GetPath();
370 
371 			for( sal_uInt16 i = 0; i < nSelectionCount; i++)
372 			{
373 				pEntry = i==0 ?
374                         Links().FirstSelected() :
375                             Links().NextSelected( pEntry );
376 				DBG_ASSERT(pEntry,"Wo ist der Entry");
377 				pLink = (SvBaseLink*)pEntry->GetUserData();
378 				DBG_ASSERT(pLink,"Wo ist der Link");
379 				pLinkMgr->GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
380 				INetURLObject aUrl_(sFile);
381 				INetURLObject aUrl2(aPath, INET_PROT_FILE);
382 				aUrl2.insertName( aUrl_.getName() );
383 				String sNewLinkName;
384                 MakeLnkName( sNewLinkName, 0 ,
385 						aUrl2.GetMainURL(INetURLObject::DECODE_TO_IURI), sLinkName, &sFilter);
386 				pLink->SetLinkSourceName( sNewLinkName );
387 				pLink->Update();
388 			}
389 			if( pLinkMgr->GetPersist() )
390 				pLinkMgr->GetPersist()->SetModified();
391 			LinkManager* pNewMgr = pLinkMgr;
392 			pLinkMgr = 0;
393 			SetManager( pNewMgr );
394 		}
395 	}
396 	else
397 	{
398 		sal_uInt16 nPos;
399 		SvBaseLink* pLink = GetSelEntry( &nPos );
400         if ( pLink && (pLink->GetLinkSourceName().Len() != 0) )
401             pLink->Edit( this, LINK( this, SvBaseLinksDlg, EndEditHdl ) );
402 	}
403 	return 0;
404 }
405 
IMPL_LINK(SvBaseLinksDlg,BreakLinkClickHdl,PushButton *,pPushButton)406 IMPL_LINK( SvBaseLinksDlg, BreakLinkClickHdl, PushButton *, pPushButton )
407 {
408 	(void)pPushButton;
409 
410 	sal_Bool bModified = sal_False;
411     if(Links().GetSelectionCount() <= 1)
412 	{
413 		sal_uInt16 nPos;
414 		SvBaseLinkRef xLink = GetSelEntry( &nPos );
415 		if( !xLink.Is() )
416 			return 0;
417 
418         QueryBox aBox( this, WB_YES_NO | WB_DEF_YES, Closelinkmsg() );
419 
420 		if( RET_YES == aBox.Execute() )
421 		{
422             Links().GetModel()->Remove( Links().GetEntry( nPos ) );
423 
424 			// falls Object noch vorhanden, dann das schliessen
425 			sal_Bool bNewLnkMgr = OBJECT_CLIENT_FILE == xLink->GetObjType();
426 
427 			// dem Link sagen, das er aufgeloest wird!
428 			xLink->Closed();
429 
430 			// falls einer vergessen hat sich auszutragen
431 			if( xLink.Is() )
432 				pLinkMgr->Remove( &xLink );
433 
434 			if( bNewLnkMgr )
435 			{
436 				LinkManager* pNewMgr = pLinkMgr;
437 				pLinkMgr = 0;
438 				SetManager( pNewMgr );
439 
440                 SvLBoxEntry* pEntry = Links().GetEntry( nPos ? --nPos : 0 );
441 				if( pEntry )
442                     Links().SetCurEntry( pEntry );
443 			}
444 			bModified = sal_True;
445 		}
446 	}
447 	else
448 	{
449         QueryBox aBox( this, WB_YES_NO | WB_DEF_YES, CloselinkmsgMulti() );
450 
451 		if( RET_YES == aBox.Execute() )
452 		{
453 
454 			SvBaseLinkMemberList aLinkList;
455             SvLBoxEntry* pEntry = Links().FirstSelected();
456 			while ( pEntry )
457 			{
458 				void * pUD = pEntry->GetUserData();
459 				if( pUD )
460 					aLinkList.Append( (SvBaseLink*)pUD );
461                 pEntry = Links().NextSelected(pEntry);
462 			}
463             Links().RemoveSelection();
464 			for( sal_uLong i = 0; i < aLinkList.Count(); i++ )
465 			{
466 				SvBaseLinkRef xLink = aLinkList.GetObject( i );
467 				// dem Link sagen, das er aufgeloest wird!
468 				xLink->Closed();
469 
470 				// falls einer vergessen hat sich auszutragen
471 				pLinkMgr->Remove( &xLink );
472 				bModified = sal_True;
473 			}
474 			//Danach alle selektierten Eintraege entfernen
475 		}
476 	}
477 	if(bModified)
478 	{
479         if( !Links().GetEntryCount() )
480 		{
481 			// Der letzte macht das Licht aus
482             Automatic().Disable();
483             Manual().Disable();
484             UpdateNow().Disable();
485 //            OpenSource().Disable();
486             ChangeSource().Disable();
487             BreakLink().Disable();
488 
489 			String aEmpty;
490             SourceName().SetText( aEmpty );
491             TypeName().SetText( aEmpty );
492 		}
493 		if( pLinkMgr->GetPersist() )
494 			pLinkMgr->GetPersist()->SetModified();
495 	}
496 	return 0;
497 }
498 
IMPL_LINK(SvBaseLinksDlg,UpdateWaitingHdl,Timer *,pTimer)499 IMPL_LINK( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, pTimer )
500 {
501 	(void)pTimer;
502 //    for( SvLBoxEntry* pBox = Links().First(); pBox;
503 //          pBox = Links().Next( pBox ))
504 
505     Links().SetUpdateMode(sal_False);
506     for( sal_uLong nPos = Links().GetEntryCount(); nPos; )
507 	{
508         SvLBoxEntry* pBox = Links().GetEntry( --nPos );
509 		SvBaseLinkRef xLink( (SvBaseLink*)pBox->GetUserData() );
510 		if( xLink.Is() )
511 		{
512 			String sCur( ImplGetStateStr( *xLink ) ),
513                     sOld( Links().GetEntryText( pBox, 3 ) );
514 			if( sCur != sOld )
515                 Links().SetEntryText( sCur, pBox, 3 );
516 		}
517 	}
518     Links().SetUpdateMode(sal_True);
519 	return 0;
520 }
521 
IMPL_LINK(SvBaseLinksDlg,EndEditHdl,sfx2::SvBaseLink *,_pLink)522 IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink*, _pLink )
523 {
524     sal_uInt16 nPos;
525     GetSelEntry( &nPos );
526 
527     if( _pLink && _pLink->WasLastEditOK() )
528     {
529         // JP 09.01.98:
530         // StarImpress/Draw tauschen die LinkObjecte selbst aus!
531         // also suche den Link im Manager, wenn der nicht mehr existiert,
532         // dann setze fuelle die Liste komplett neu. Ansonsten braucht
533         // nur der editierte Linkt aktualisiert werden.
534         sal_Bool bLinkFnd = sal_False;
535         for( sal_uInt16 n = pLinkMgr->GetLinks().Count(); n;  )
536             if( _pLink == &(*pLinkMgr->GetLinks()[ --n ]) )
537             {
538                 bLinkFnd = sal_True;
539                 break;
540             }
541 
542         if( bLinkFnd )
543         {
544             Links().SetUpdateMode(sal_False);
545             Links().GetModel()->Remove( Links().GetEntry( nPos ) );
546             SvLBoxEntry* pToUnselect = Links().FirstSelected();
547             InsertEntry( *_pLink, nPos, sal_True );
548             if(pToUnselect)
549                 Links().Select(pToUnselect, sal_False);
550             Links().SetUpdateMode(sal_True);
551         }
552         else
553         {
554             LinkManager* pNewMgr = pLinkMgr;
555             pLinkMgr = 0;
556             SetManager( pNewMgr );
557         }
558         if( pLinkMgr->GetPersist() )
559             pLinkMgr->GetPersist()->SetModified();
560     }
561     return 0;
562 }
563 
ImplGetStateStr(const SvBaseLink & rLnk)564 String SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
565 {
566 	String sRet;
567 	if( !rLnk.GetObj() )
568         sRet = Brokenlink();
569 	else if( rLnk.GetObj()->IsPending() )
570 	{
571         sRet = Waitinglink();
572         StartUpdateTimer();
573 	}
574 	else if( LINKUPDATE_ALWAYS == rLnk.GetUpdateMode() )
575         sRet = Autolink();
576 	else
577         sRet = Manuallink();
578 
579 	return sRet;
580 }
581 
SetManager(LinkManager * pNewMgr)582 void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
583 {
584 	if( pLinkMgr == pNewMgr )
585 		return;
586 
587 	if( pNewMgr )
588 		// Update muss vor Clear gestoppt werden
589         Links().SetUpdateMode( sal_False );
590 
591     Links().Clear();
592 	pLinkMgr = pNewMgr;
593 
594 	if( pLinkMgr )
595 	{
596 		SvBaseLinks& rLnks = (SvBaseLinks&)pLinkMgr->GetLinks();
597 		for( sal_uInt16 n = 0; n < rLnks.Count(); ++n )
598 		{
599 			SvBaseLinkRef* pLinkRef = rLnks[ n ];
600 			if( !pLinkRef->Is() )
601 			{
602 				rLnks.Remove( n, 1 );
603 				--n;
604 				continue;
605 			}
606 			if( (*pLinkRef)->IsVisible() )
607 				InsertEntry( **pLinkRef );
608 		}
609 
610 		if( rLnks.Count() )
611 		{
612             SvLBoxEntry* pEntry = Links().GetEntry( 0 );
613             Links().SetCurEntry( pEntry );
614             Links().Select( pEntry );
615 			LinksSelectHdl( 0 );
616 		}
617         Links().SetUpdateMode( sal_True );
618         Links().Invalidate();
619 	}
620 }
621 
622 
InsertEntry(const SvBaseLink & rLink,sal_uInt16 nPos,sal_Bool bSelect)623 void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uInt16 nPos, sal_Bool bSelect )
624 {
625 	String aEntry, sFileNm, sLinkNm, sTypeNm, sFilter;
626 
627 	pLinkMgr->GetDisplayNames( (SvBaseLink*)&rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
628 
629 	// GetTab(0) gibt die Position der von der TabListBox automatisch eingefuegten
630 	// Bitmap. Die Breite der ersten Textspalte ergibt sich deshalb aus Tab(2)-Tab(1)
631     long nWidthPixel = Links().GetLogicTab( 2 ) - Links().GetLogicTab( 1 );
632 	nWidthPixel -= SV_TAB_BORDER;
633     XubString aTxt = Links().GetEllipsisString( sFileNm, nWidthPixel, TEXT_DRAW_PATHELLIPSIS );
634 	INetURLObject aPath( sFileNm, INET_PROT_FILE );
635 	String aFileName = aPath.getName();
636     aFileName = INetURLObject::decode(aFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
637 
638     if( aFileName.Len() > aTxt.Len() )
639 		aTxt = aFileName;
640 	else if( aTxt.Search( aFileName, aTxt.Len() - aFileName.Len() ) == STRING_NOTFOUND )
641 		// filename not in string
642 		aTxt = aFileName;
643 
644 	aEntry = aTxt;
645 	aEntry += '\t';
646 	if( OBJECT_CLIENT_GRF == rLink.GetObjType() )
647 		aEntry += sFilter;
648 	else
649 		aEntry += sLinkNm;
650 	aEntry += '\t';
651 	aEntry += sTypeNm;
652 	aEntry += '\t';
653 	aEntry += ImplGetStateStr( rLink );
654 
655     SvLBoxEntry * pE = Links().InsertEntryToColumn( aEntry, nPos );
656 	pE->SetUserData( (void*)&rLink );
657     if(bSelect)
658         Links().Select(pE);
659 }
660 
GetSelEntry(sal_uInt16 * pPos)661 SvBaseLink* SvBaseLinksDlg::GetSelEntry( sal_uInt16* pPos )
662 {
663     SvLBoxEntry* pE = Links().FirstSelected();
664 	sal_uInt16 nPos;
665 	if( pE && LISTBOX_ENTRY_NOTFOUND !=
666         ( nPos = (sal_uInt16)Links().GetModel()->GetAbsPos( pE ) ) )
667 	{
668 		DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
669 
670 		if( pPos )
671 			*pPos = nPos;
672 		return (SvBaseLink*)pE->GetUserData();
673 	}
674 	return 0;
675 }
676 
SetType(SvBaseLink & rLink,sal_uInt16 nSelPos,sal_uInt16 nType)677 void SvBaseLinksDlg::SetType( SvBaseLink& rLink,
678 									sal_uInt16 nSelPos,
679 									sal_uInt16 nType )
680 {
681 	rLink.SetUpdateMode( nType );
682 	rLink.Update();
683     SvLBoxEntry* pBox = Links().GetEntry( nSelPos );
684     Links().SetEntryText( ImplGetStateStr( rLink ), pBox, 3 );
685 	if( pLinkMgr->GetPersist() )
686 		pLinkMgr->GetPersist()->SetModified();
687 }
688 
SetActLink(SvBaseLink * pLink)689 void SvBaseLinksDlg::SetActLink( SvBaseLink * pLink )
690 {
691 	if( pLinkMgr )
692 	{
693 		const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
694         sal_uInt16 nSelect = 0;
695         for( sal_uInt16 n = 0; n < rLnks.Count(); ++n )
696         {
697             SvBaseLinkRef* pLinkRef = rLnks[ n ];
698             // #109573# only visible links have been inserted into the TreeListBox,
699             // invisible ones have to be skipped here
700             if( (*pLinkRef)->IsVisible() )
701             {
702                 if( pLink == *pLinkRef )
703                 {
704                     Links().Select( Links().GetEntry( nSelect ) );
705                     LinksSelectHdl( 0 );
706                     return ;
707                 }
708                 nSelect++;
709             }
710         }
711 	}
712 }
713 
714