xref: /trunk/main/cui/source/dialogs/hlmarkwn.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 <vcl/wrkwin.hxx>
32 #include <dialmgr.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/settings.hxx>
36 
37 // UNO-Stuff
38 #include <comphelper/processfactory.hxx>
39 #include <com/sun/star/awt/XBitmap.hpp>
40 #include <com/sun/star/frame/XDesktop.hpp>
41 #include <com/sun/star/frame/XDesktop.hpp>
42 #include <com/sun/star/frame/XComponentLoader.hpp>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/document/XLinkTargetSupplier.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 
47 #include <toolkit/unohlp.hxx>
48 
49 #include <cuires.hrc>
50 #include "hlmarkwn.hrc"
51 #include "hlmarkwn.hxx"
52 #include "hltpbase.hxx"
53 
54 using namespace ::com::sun::star;
55 using namespace ::rtl;
56 
57 /*************************************************************************
58 |*
59 |* Userdata-struct for tree-entries
60 |*
61 |************************************************************************/
62 
63 struct TargetData
64 {
65     OUString        aUStrLinkname;
66     sal_Bool        bIsTarget;
67 
68     TargetData ( OUString aUStrLName, sal_Bool bTarget )
69         :   bIsTarget ( bTarget )
70     {
71         if ( bIsTarget )
72             aUStrLinkname = aUStrLName;
73     }
74 };
75 
76 
77 //########################################################################
78 //#                                                                      #
79 //# Tree-Window                                                          #
80 //#                                                                      #
81 //########################################################################
82 
83 SvxHlmarkTreeLBox::SvxHlmarkTreeLBox( Window* pParent, const ResId& rResId )
84 : SvTreeListBox ( pParent, rResId ),
85   mpParentWnd   ( (SvxHlinkDlgMarkWnd*) pParent )
86 {
87     SetNodeDefaultImages();
88 }
89 
90 void SvxHlmarkTreeLBox::Paint( const Rectangle& rRect )
91 {
92     if( mpParentWnd->mnError == LERR_NOERROR )
93     {
94         SvTreeListBox::Paint(rRect);
95     }
96     else
97     {
98         Erase();
99 
100         Rectangle aDrawRect( Point( 0, 0 ), GetSizePixel() );
101 
102         String aStrMessage;
103 
104         switch( mpParentWnd->mnError )
105         {
106         case LERR_NOENTRIES :
107             aStrMessage = CUI_RESSTR( RID_SVXSTR_HYPDLG_ERR_LERR_NOENTRIES );
108             break;
109         case LERR_DOCNOTOPEN :
110             aStrMessage = CUI_RESSTR( RID_SVXSTR_HYPDLG_ERR_LERR_DOCNOTOPEN );
111             break;
112         }
113 
114         DrawText( aDrawRect, aStrMessage, TEXT_DRAW_LEFT | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
115     }
116 
117 }
118 
119 //########################################################################
120 //#                                                                      #
121 //# Window-Class                                                         #
122 //#                                                                      #
123 //########################################################################
124 
125 /*************************************************************************
126 |*
127 |* Contructor / Destructor
128 |*
129 |************************************************************************/
130 
131 SvxHlinkDlgMarkWnd::SvxHlinkDlgMarkWnd( SvxHyperlinkTabPageBase *pParent )
132 :   ModalDialog( (Window*)pParent, CUI_RES ( RID_SVXFLOAT_HYPERLINK_MARKWND ) ),
133     maBtApply( this, CUI_RES (BT_APPLY) ),
134     maBtClose( this, CUI_RES (BT_CLOSE) ),
135     maLbTree ( this, CUI_RES (TLB_MARK) ),
136     mbUserMoved ( sal_False ),
137     mbFirst     ( sal_True ),
138     mpParent    ( pParent ),
139     mnError     ( LERR_NOERROR )
140 {
141     FreeResource();
142 
143     maBtApply.SetClickHdl       ( LINK ( this, SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl ) );
144     maBtClose.SetClickHdl       ( LINK ( this, SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl ) );
145     maLbTree.SetDoubleClickHdl  ( LINK ( this, SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl ) );
146 
147     // Tree-ListBox mit Linien versehen
148     maLbTree.SetStyle( maLbTree.GetStyle() | WB_TABSTOP | WB_BORDER | WB_HASLINES |
149                             WB_HASBUTTONS |  //WB_HASLINESATROOT |
150                             WB_HSCROLL | WB_HASBUTTONSATROOT );
151 
152     maLbTree.SetAccessibleName(String(CUI_RES(STR_MARK_TREE)));
153 
154 }
155 
156 SvxHlinkDlgMarkWnd::~SvxHlinkDlgMarkWnd()
157 {
158     ClearTree();
159 }
160 
161 /*************************************************************************
162 |*
163 |* Set an errorstatus
164 |*
165 |************************************************************************/
166 
167 sal_uInt16 SvxHlinkDlgMarkWnd::SetError( sal_uInt16 nError)
168 {
169     sal_uInt16 nOldError = mnError;
170     mnError = nError;
171 
172     if( mnError != LERR_NOERROR )
173         ClearTree();
174 
175     maLbTree.Invalidate();
176 
177     return nOldError;
178 }
179 
180 /*************************************************************************
181 |*
182 |* Move window
183 |*
184 |************************************************************************/
185 
186 sal_Bool SvxHlinkDlgMarkWnd::MoveTo ( Point aNewPos )
187 {
188     if ( !mbUserMoved )
189     {
190         sal_Bool bOldStatus = mbUserMoved;
191         SetPosPixel ( aNewPos );
192         mbUserMoved = bOldStatus;
193     }
194 
195     return mbUserMoved;
196 }
197 
198 void SvxHlinkDlgMarkWnd::Move ()
199 {
200     Window::Move();
201 
202     if ( IsReallyVisible() )
203         mbUserMoved = sal_True;
204 }
205 
206 sal_Bool SvxHlinkDlgMarkWnd::ConnectToDialog( sal_Bool bDoit )
207 {
208     sal_Bool bOldStatus = mbUserMoved;
209 
210     mbUserMoved = !bDoit;
211 
212     return bOldStatus;
213 }
214 
215 /*************************************************************************
216 |*
217 |* Interface to refresh tree
218 |*
219 |************************************************************************/
220 
221 void SvxHlinkDlgMarkWnd::RefreshTree ( String aStrURL )
222 {
223     String aEmptyStr;
224     OUString aUStrURL;
225 
226     EnterWait();
227 
228     ClearTree();
229 
230     xub_StrLen nPos = aStrURL.Search ( sal_Unicode('#') );
231 
232     if( nPos != 0 )
233         aUStrURL = ::rtl::OUString( aStrURL );
234 
235     if( !RefreshFromDoc ( aUStrURL ) )
236         maLbTree.Invalidate();
237 
238     if ( nPos != STRING_NOTFOUND )
239     {
240         String aStrMark = aStrURL.Copy ( nPos+1 );
241         SelectEntry ( aStrMark );
242     }
243 
244     LeaveWait();
245 
246     maStrLastURL = aStrURL;
247 }
248 
249 /*************************************************************************
250 |*
251 |* get links from document
252 |*
253 |************************************************************************/
254 
255 sal_Bool SvxHlinkDlgMarkWnd::RefreshFromDoc( OUString aURL )
256 {
257     mnError = LERR_NOERROR;
258 
259     uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
260     if( xFactory.is() )
261     {
262         uno::Reference< frame::XDesktop > xDesktop( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ),
263                     uno::UNO_QUERY );
264         if( xDesktop.is() )
265         {
266             uno::Reference< lang::XComponent > xComp;
267 
268             if( aURL.getLength() )
269             {
270                 // load from url
271                 uno::Reference< frame::XComponentLoader > xLoader( xDesktop, uno::UNO_QUERY );
272                 if( xLoader.is() )
273                 {
274                     try
275                     {
276                         uno::Sequence< beans::PropertyValue > aArg(1);
277                         aArg.getArray()[0].Name = OUString::createFromAscii( "Hidden" );
278                         aArg.getArray()[0].Value <<= (sal_Bool) sal_True;
279                         xComp = xLoader->loadComponentFromURL( aURL, OUString::createFromAscii( "_blank" ), 0, aArg );
280                     }
281                     catch( const io::IOException& )
282                     {
283 
284                     }
285                     catch( const lang::IllegalArgumentException& )
286                     {
287 
288                     }
289                 }
290             }
291             else
292             {
293                 // the component with user focus ( current document )
294                 xComp = xDesktop->getCurrentComponent();
295             }
296 
297             if( xComp.is() )
298             {
299                 uno::Reference< document::XLinkTargetSupplier > xLTS( xComp, uno::UNO_QUERY );
300 
301                 if( xLTS.is() )
302                 {
303                     if( FillTree( xLTS->getLinks() ) == 0 )
304                         mnError = LERR_NOENTRIES;
305                 }
306                 else
307                     mnError = LERR_DOCNOTOPEN;
308 
309                 if ( aURL.getLength() )
310                     xComp->dispose();
311             }
312             else
313             {
314                 if( aURL.getLength() )
315                     mnError=LERR_DOCNOTOPEN;
316             }
317         }
318     }
319     return (mnError==0);
320 }
321 /*
322 void SvxHlinkDlgMarkWnd::Error(int nNr)
323 {
324     switch(nNr)
325     {
326         case 0:
327         {
328             Rectangle aDrawRect( Point( 0, 0 ), maLbTree.GetSizePixel() );
329             //maLbTree.SetTextColor( Color(COL_BLACK) );
330             //maLbTree.DrawText( aDrawRect, "Keine Ziele im Dokument vorhanden.", TEXT_DRAW_LEFT);// | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
331             maLbTree.DrawText( Point(0,0), "Keine Ziele im Dokument vorhanden.");
332             maLbTree.DrawLine(aDrawRect.TopLeft(), aDrawRect.BottomRight() );
333         }
334         break;
335         case 1:
336             Rectangle aDrawRect( Point( 0, 0 ), maLbTree.GetSizePixel() );
337             maLbTree.DrawText( aDrawRect, "Das Dokument konnte nicht ge�ffnet werden.", TEXT_DRAW_LEFT | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
338             break;
339     }
340 }
341 */
342 /*************************************************************************
343 |*
344 |* Fill Tree-Control
345 |*
346 |************************************************************************/
347 
348 int SvxHlinkDlgMarkWnd::FillTree( uno::Reference< container::XNameAccess > xLinks, SvLBoxEntry* pParentEntry )
349 {
350     int nEntries=0;
351     const uno::Sequence< OUString > aNames( xLinks->getElementNames() );
352     const sal_uLong nLinks = aNames.getLength();
353     const OUString* pNames = aNames.getConstArray();
354 
355     Color aMaskColor( COL_LIGHTMAGENTA );
356     const OUString aProp_LinkDisplayName( RTL_CONSTASCII_USTRINGPARAM( "LinkDisplayName" ) );
357     const OUString aProp_LinkTarget( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.LinkTarget" ) );
358     const OUString aProp_LinkDisplayBitmap( RTL_CONSTASCII_USTRINGPARAM( "LinkDisplayBitmap" ) );
359     for( sal_uLong i = 0; i < nLinks; i++ )
360     {
361         uno::Any aAny;
362         OUString aLink( *pNames++ );
363 
364         sal_Bool bError = sal_False;
365         try
366         {
367             aAny = xLinks->getByName( aLink );
368         }
369         catch(const uno::Exception&)
370         {
371             // if the name of the target was invalid (like empty headings)
372             // no object can be provided
373             bError = sal_True;
374         }
375         if(bError)
376             continue;
377 
378         uno::Reference< beans::XPropertySet > xTarget;
379 
380         if( aAny >>= xTarget )
381         {
382             try
383             {
384                 // get name to display
385                 aAny = xTarget->getPropertyValue( aProp_LinkDisplayName );
386                 OUString aDisplayName;
387                 aAny >>= aDisplayName;
388                 String aStrDisplayname ( aDisplayName );
389 
390                 // is it a target ?
391                 uno::Reference< lang::XServiceInfo > xSI( xTarget, uno::UNO_QUERY );
392                 sal_Bool bIsTarget = xSI->supportsService( aProp_LinkTarget );
393 
394                 // create userdata
395                 TargetData *pData = new TargetData ( aLink, bIsTarget );
396 
397                 SvLBoxEntry* pEntry;
398 
399                 try
400                 {
401                     // get bitmap for the tree-entry
402                     uno::Reference< awt::XBitmap > aXBitmap( xTarget->getPropertyValue( aProp_LinkDisplayBitmap ), uno::UNO_QUERY );
403                     if( aXBitmap.is() )
404                     {
405                         Image aBmp( VCLUnoHelper::GetBitmap( aXBitmap ).GetBitmap(), aMaskColor );
406                         // insert Displayname into treelist with bitmaps
407                         pEntry = maLbTree.InsertEntry ( aStrDisplayname,
408                                                         aBmp, aBmp,
409                                                         pParentEntry,
410                                                         sal_False, LIST_APPEND,
411                                                         (void*)pData );
412                         maLbTree.SetExpandedEntryBmp( pEntry, aBmp, BMP_COLOR_HIGHCONTRAST );
413                         maLbTree.SetCollapsedEntryBmp( pEntry, aBmp, BMP_COLOR_HIGHCONTRAST );
414                         nEntries++;
415                     }
416                     else
417                     {
418                         // insert Displayname into treelist without bitmaps
419                         pEntry = maLbTree.InsertEntry ( aStrDisplayname,
420                                                         pParentEntry,
421                                                         sal_False, LIST_APPEND,
422                                                         (void*)pData );
423                         nEntries++;
424                     }
425                 }
426                 catch(const com::sun::star::uno::Exception&)
427                 {
428                     // insert Displayname into treelist without bitmaps
429                     pEntry = maLbTree.InsertEntry ( aStrDisplayname,
430                                                     pParentEntry,
431                                                     sal_False, LIST_APPEND,
432                                                     (void*)pData );
433                     nEntries++;
434                 }
435 
436                 uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY );
437                 if( xLTS.is() )
438                     nEntries += FillTree( xLTS->getLinks(), pEntry );
439             }
440             catch(const com::sun::star::uno::Exception&)
441             {
442             }
443         }
444     }
445 
446     return nEntries;
447 }
448 
449 /*************************************************************************
450 |*
451 |* Clear Tree
452 |*
453 |************************************************************************/
454 
455 void SvxHlinkDlgMarkWnd::ClearTree()
456 {
457     SvLBoxEntry* pEntry = maLbTree.First();
458 
459     while ( pEntry )
460     {
461         TargetData* pUserData = ( TargetData * ) pEntry->GetUserData();
462         delete pUserData;
463 
464         pEntry = maLbTree.Next( pEntry );
465     }
466 
467     maLbTree.Clear();
468 }
469 
470 /*************************************************************************
471 |*
472 |* Find Entry for Strng
473 |*
474 |************************************************************************/
475 
476 SvLBoxEntry* SvxHlinkDlgMarkWnd::FindEntry ( String aStrName )
477 {
478     sal_Bool bFound=sal_False;
479     SvLBoxEntry* pEntry = maLbTree.First();
480 
481     while ( pEntry && !bFound )
482     {
483         TargetData* pUserData = ( TargetData * ) pEntry->GetUserData ();
484         if ( aStrName == String( pUserData->aUStrLinkname ) )
485             bFound = sal_True;
486         else
487             pEntry = maLbTree.Next( pEntry );
488     }
489 
490     return pEntry;
491 }
492 
493 /*************************************************************************
494 |*
495 |* Select Entry
496 |*
497 |************************************************************************/
498 
499 void SvxHlinkDlgMarkWnd::SelectEntry ( String aStrMark )
500 {
501     SvLBoxEntry* pEntry = FindEntry ( aStrMark );
502     if ( pEntry )
503     {
504         maLbTree.Select ( pEntry );
505         maLbTree.MakeVisible ( pEntry );
506     }
507 }
508 
509 /*************************************************************************
510 |*
511 |* Click on Apply-Button / Doubleclick on item in tree
512 |*
513 |************************************************************************/
514 
515 IMPL_LINK ( SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl, void *, EMPTYARG )
516 {
517     SvLBoxEntry* pEntry = maLbTree.GetCurEntry();
518 
519     if ( pEntry )
520     {
521         TargetData *pData = ( TargetData * )pEntry->GetUserData();
522 
523         if ( pData->bIsTarget )
524         {
525             String aStrMark ( pData->aUStrLinkname );
526             mpParent->SetMarkStr ( aStrMark );
527         }
528     }
529 
530     return( 0L );
531 }
532 
533 /*************************************************************************
534 |*
535 |* Click on Close-Button
536 |*
537 |************************************************************************/
538 
539 IMPL_LINK ( SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl, void *, EMPTYARG )
540 {
541     Close();
542 
543     return( 0L );
544 }
545 
546 
547