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