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