xref: /trunk/main/extensions/source/propctrlr/browserline.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_extensions.hxx"
30 #include "browserline.hxx"
31 
32 /** === begin UNO includes === **/
33 #include <com/sun/star/inspection/PropertyLineElement.hpp>
34 #include <com/sun/star/graphic/XGraphicProvider.hpp>
35 /** === end UNO includes === **/
36 
37 #include <vcl/svapp.hxx>
38 #include <tools/debug.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <tools/urlobj.hxx>
41 #include <toolkit/helper/vclunohelper.hxx>
42 
43 #include <comphelper/processfactory.hxx>
44 #include <comphelper/componentcontext.hxx>
45 
46 //............................................................................
47 namespace pcr
48 {
49 //............................................................................
50 
51     /** === begin UNO using === **/
52     using ::com::sun::star::uno::Reference;
53     using ::com::sun::star::inspection::XPropertyControl;
54     using ::com::sun::star::inspection::XPropertyControlContext;
55     using ::com::sun::star::uno::UNO_QUERY_THROW;
56     using ::com::sun::star::uno::Exception;
57     using ::com::sun::star::graphic::XGraphicProvider;
58     using ::com::sun::star::uno::Sequence;
59     using ::com::sun::star::beans::PropertyValue;
60     using ::com::sun::star::graphic::XGraphic;
61     /** === end UNO using === **/
62 
63     namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;
64 
65     //==================================================================
66     //= OBrowserLine
67     //==================================================================
68     DBG_NAME(OBrowserLine)
69     //------------------------------------------------------------------
70 
71     OBrowserLine::OBrowserLine( const ::rtl::OUString& _rEntryName, Window* pParent )
72             :m_sEntryName( _rEntryName )
73             ,m_aFtTitle(pParent)
74             ,m_pControlWindow( NULL )
75             ,m_pBrowseButton(NULL)
76             ,m_pAdditionalBrowseButton( NULL )
77             ,m_pClickListener( NULL )
78             ,m_pTheParent(pParent)
79             ,m_nNameWidth(0)
80             ,m_nEnableFlags( 0xFFFF )
81             ,m_bIndentTitle( false )
82             ,m_bReadOnly( false )
83     {
84         DBG_CTOR(OBrowserLine,NULL);
85         m_aFtTitle.Show();
86     }
87 
88     //------------------------------------------------------------------
89     OBrowserLine::~OBrowserLine()
90     {
91         implHideBrowseButton( true, false );
92         implHideBrowseButton( false, false );
93 
94         DBG_DTOR(OBrowserLine,NULL);
95     }
96 
97     //------------------------------------------------------------------
98     void OBrowserLine::IndentTitle( bool _bIndent )
99     {
100         if ( m_bIndentTitle != _bIndent )
101         {
102             m_bIndentTitle = _bIndent;
103             impl_layoutComponents();
104         }
105     }
106 
107     //------------------------------------------------------------------
108     void OBrowserLine::SetComponentHelpIds( const rtl::OString& _rHelpId, const rtl::OString& _sPrimaryButtonId, const rtl::OString& _sSecondaryButtonId )
109     {
110         if ( m_pControlWindow )
111             m_pControlWindow->SetHelpId( _rHelpId );
112 
113         if ( m_pBrowseButton )
114         {
115             m_pBrowseButton->SetHelpId( _rHelpId );
116             m_pBrowseButton->SetUniqueId( _sPrimaryButtonId );
117 
118             if ( m_pAdditionalBrowseButton )
119             {
120                 m_pAdditionalBrowseButton->SetHelpId( _rHelpId );
121                 m_pAdditionalBrowseButton->SetUniqueId( _sSecondaryButtonId );
122             }
123         }
124     }
125 
126     //------------------------------------------------------------------
127     void OBrowserLine::setControl( const Reference< XPropertyControl >& _rxControl )
128     {
129         m_xControl = _rxControl;
130         m_pControlWindow = m_xControl.is() ? VCLUnoHelper::GetWindow( _rxControl->getControlWindow() ) : NULL;
131         DBG_ASSERT( m_pControlWindow, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" );
132 
133         if ( m_pControlWindow )
134         {
135             m_pControlWindow->SetParent( m_pTheParent );
136             m_pControlWindow->Show();
137         }
138         impl_layoutComponents();
139     }
140 
141     //------------------------------------------------------------------
142     Window* OBrowserLine::GetRefWindow()
143     {
144         Window* pRefWindow=&m_aFtTitle;
145 
146         if(m_pBrowseButton)
147         {
148             pRefWindow=(Window*)m_pBrowseButton;
149         }
150         else if ( m_pControlWindow )
151         {
152             pRefWindow = m_pControlWindow;
153         }
154         return pRefWindow;
155     }
156 
157     //------------------------------------------------------------------
158     void OBrowserLine::SetTabOrder(Window* pRefWindow, sal_uInt16 nFlags )
159     {
160         m_aFtTitle.SetZOrder(pRefWindow,nFlags);
161         if ( m_pControlWindow )
162             m_pControlWindow->SetZOrder( (Window*)&m_aFtTitle, WINDOW_ZORDER_BEHIND );
163 
164         if ( m_pBrowseButton )
165             m_pBrowseButton->SetZOrder( m_pControlWindow, WINDOW_ZORDER_BEHIND );
166 
167         if ( m_pAdditionalBrowseButton )
168             m_pAdditionalBrowseButton->SetZOrder( m_pBrowseButton, WINDOW_ZORDER_BEHIND );
169     }
170 
171     //------------------------------------------------------------------
172     sal_Bool OBrowserLine::GrabFocus()
173     {
174         sal_Bool bRes=sal_False;
175 
176         if ( m_pControlWindow && m_pControlWindow->IsEnabled() )
177         {
178             m_pControlWindow->GrabFocus();
179             bRes = sal_True;
180         }
181         else if ( m_pAdditionalBrowseButton && m_pAdditionalBrowseButton->IsEnabled() )
182         {
183             m_pAdditionalBrowseButton->GrabFocus();
184             bRes = sal_True;
185         }
186         else if ( m_pBrowseButton && m_pBrowseButton->IsEnabled() )
187         {
188             m_pBrowseButton->GrabFocus();
189             bRes = sal_True;
190         }
191         return bRes;
192     }
193 
194     //------------------------------------------------------------------
195     void OBrowserLine::SetPosSizePixel( Point _rPos, Size _rSize )
196     {
197         m_aLinePos = _rPos;
198         m_aOutputSize = _rSize;
199 
200         impl_layoutComponents();
201     }
202 
203     //------------------------------------------------------------------
204     void OBrowserLine::Show(sal_Bool bFlag)
205     {
206         m_aFtTitle.Show(bFlag);
207         if ( m_pControlWindow )
208             m_pControlWindow->Show( bFlag );
209         if ( m_pBrowseButton )
210             m_pBrowseButton->Show( bFlag );
211         if ( m_pAdditionalBrowseButton )
212             m_pAdditionalBrowseButton->Show( bFlag );
213     }
214 
215     //------------------------------------------------------------------
216     void OBrowserLine::Hide()
217     {
218         Show(sal_False);
219     }
220 
221     //------------------------------------------------------------------
222     sal_Bool OBrowserLine::IsVisible()
223     {
224         return m_aFtTitle.IsVisible();
225     }
226 
227     //------------------------------------------------------------------
228     void OBrowserLine::impl_layoutComponents()
229     {
230         {
231             Point aTitlePos( m_aLinePos.X(), m_aLinePos.Y() + 8 );
232             Size aTitleSize( m_nNameWidth - 3, m_aOutputSize.Height() );
233 
234             if ( m_bIndentTitle )
235             {
236                 Size aIndent( m_pTheParent->LogicToPixel( Size( 8, 0 ), MAP_APPFONT ) );
237                 aTitlePos.X() += aIndent.Width();
238                 aTitleSize.Width() -= aIndent.Width();
239             }
240             m_aFtTitle.SetPosSizePixel( aTitlePos, aTitleSize );
241         }
242 
243         sal_Int32 nBrowseButtonSize = m_aOutputSize.Height() - 4;
244 
245         if ( m_pControlWindow )
246         {
247             Point aControlPos( m_aLinePos.X() + m_nNameWidth, m_aLinePos.Y() + 2 );
248             m_pControlWindow->SetPosPixel( aControlPos );
249 
250             Size aControlSize( m_aOutputSize.Width() - 4 - m_nNameWidth - nBrowseButtonSize - 4, m_pControlWindow->GetSizePixel().Height() );
251             if ( m_pAdditionalBrowseButton )
252                 aControlSize.Width() -= nBrowseButtonSize + 4;
253             m_pControlWindow->SetSizePixel( aControlSize );
254         }
255 
256         if ( m_pBrowseButton )
257         {
258             Point aButtonPos( m_aOutputSize.Width() - 4 - nBrowseButtonSize, m_aLinePos.Y() + 2 );
259             Size aButtonSize( nBrowseButtonSize, nBrowseButtonSize );
260             m_pBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );
261 
262             if ( m_pAdditionalBrowseButton )
263             {
264                 aButtonPos.X() -= nBrowseButtonSize + 4;
265                 m_pAdditionalBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );
266             }
267         }
268     }
269 
270     //------------------------------------------------------------------
271     void OBrowserLine::SetTitle(const XubString& _rNewTtile )
272     {
273         if ( GetTitle() == _rNewTtile )
274             return;
275         // #99102# --------------
276         m_aFtTitle.SetText( _rNewTtile );
277         if ( m_pControlWindow )
278             m_pControlWindow->SetAccessibleName( _rNewTtile );
279         if ( m_pBrowseButton )
280             m_pBrowseButton->SetAccessibleName( _rNewTtile );
281         FullFillTitleString();
282     }
283 
284     // #99102# ---------------------------------------------------------
285     void OBrowserLine::FullFillTitleString()
286     {
287         if( m_pTheParent )
288         {
289             String aText = m_aFtTitle.GetText();
290 
291             while( m_pTheParent->GetTextWidth( aText ) < m_nNameWidth )
292                         aText.AppendAscii("...........");
293 
294             // for Issue 69452
295             if (Application::GetSettings().GetLayoutRTL())
296             {
297                 sal_Unicode cRTL_mark = 0x200F;
298                 aText.Append(cRTL_mark);
299             }
300 
301             m_aFtTitle.SetText(aText);
302         }
303     }
304 
305     //------------------------------------------------------------------
306     XubString OBrowserLine::GetTitle() const
307     {
308         String sDisplayName = m_aFtTitle.GetText();
309 
310     // for Issue 69452
311     if (Application::GetSettings().GetLayoutRTL())
312     {
313         sal_Unicode cRTL_mark = 0x200F;
314         sDisplayName.EraseTrailingChars(cRTL_mark);
315     }
316 
317         sDisplayName.EraseTrailingChars( '.' );
318 
319         return sDisplayName;
320     }
321 
322     //------------------------------------------------------------------
323     void OBrowserLine::SetReadOnly( bool _bReadOnly )
324     {
325         if ( m_bReadOnly != _bReadOnly )
326         {
327             m_bReadOnly = _bReadOnly;
328             implUpdateEnabledDisabled();
329         }
330     }
331 
332     //------------------------------------------------------------------
333     namespace
334     {
335         void implSetBitIfAffected( sal_uInt16& _nEnabledBits, sal_Int16 _nAffectedMask, sal_Int16 _nTestBit, bool _bSet )
336         {
337             if ( _nAffectedMask & _nTestBit )
338             {
339                 if ( _bSet )
340                     _nEnabledBits |= _nTestBit;
341                 else
342                     _nEnabledBits &= ~_nTestBit;
343             }
344         }
345 
346         void implEnable( Window* _pWindow, sal_uInt16 _nEnabledBits, sal_uInt16 _nMatchBits  )
347         {
348             if ( _pWindow )
349                 _pWindow->Enable( ( _nEnabledBits & _nMatchBits ) == _nMatchBits );
350         }
351 
352         void implEnable( Window* _pWindow, bool _bEnable )
353         {
354             if ( _pWindow )
355                 _pWindow->Enable( _bEnable );
356         }
357     }
358 
359     //------------------------------------------------------------------
360     void OBrowserLine::implUpdateEnabledDisabled()
361     {
362         implEnable( &m_aFtTitle,                m_nEnableFlags, PropertyLineElement::CompleteLine );
363         if ( m_pControlWindow )
364             implEnable( m_pControlWindow,       m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::InputControl );
365 
366         if ( m_bReadOnly )
367         {
368             implEnable( m_pBrowseButton,            false );
369             implEnable( m_pAdditionalBrowseButton,  false );
370         }
371         else
372         {
373             implEnable( m_pBrowseButton,            m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::PrimaryButton );
374             implEnable( m_pAdditionalBrowseButton,  m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::SecondaryButton );
375         }
376     }
377 
378     //------------------------------------------------------------------
379     void OBrowserLine::EnablePropertyLine( bool _bEnable )
380     {
381         implSetBitIfAffected( m_nEnableFlags, PropertyLineElement::CompleteLine, PropertyLineElement::CompleteLine, _bEnable );
382         implUpdateEnabledDisabled();
383     }
384 
385     //------------------------------------------------------------------
386     void OBrowserLine::EnablePropertyControls( sal_Int16 _nControls, bool _bEnable )
387     {
388         implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::InputControl, _bEnable );
389         implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::PrimaryButton, _bEnable );
390         implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::SecondaryButton, _bEnable );
391         implUpdateEnabledDisabled();
392     }
393 
394     //------------------------------------------------------------------
395     PushButton& OBrowserLine::impl_ensureButton( bool _bPrimary )
396     {
397         PushButton*& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;
398 
399         if ( !rpButton )
400         {
401             rpButton = new PushButton( m_pTheParent, WB_NOPOINTERFOCUS );
402             rpButton->SetGetFocusHdl( LINK( this, OBrowserLine, OnButtonFocus ) );
403             rpButton->SetClickHdl( LINK( this, OBrowserLine, OnButtonClicked ) );
404             rpButton->SetText( String::CreateFromAscii( "..." ) );
405         }
406 
407         rpButton->Show();
408 
409         impl_layoutComponents();
410 
411         return *rpButton;
412     }
413 
414     //------------------------------------------------------------------
415     void OBrowserLine::impl_getImagesFromURL_nothrow( const ::rtl::OUString& _rImageURL, Image& _out_rImage, Image& _out_rHCImage )
416     {
417         try
418         {
419             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
420             Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW );
421 
422             Sequence< PropertyValue > aMediaProperties(1);
423             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
424             aMediaProperties[0].Value <<= _rImageURL;
425 
426             Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ), UNO_QUERY_THROW );
427             _out_rImage = _out_rHCImage = Image( xGraphic );
428 
429             // see if we find an HC version beside the normal graphic
430             INetURLObject aURL( _rImageURL );
431             ::rtl::OUString sBaseName( aURL.getBase() );
432             aURL.setBase( sBaseName + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_hc" ) ) );
433             ::rtl::OUString sHCImageURL( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
434 
435             Reference< XGraphic > xHCGraphic;
436             try
437             {
438                 aMediaProperties[0].Value <<= sHCImageURL;
439                 xHCGraphic = xGraphicProvider->queryGraphic( aMediaProperties );
440             }
441             catch( const Exception& ) { }
442 
443             if ( xHCGraphic.is() )
444                 _out_rHCImage = Image( xHCGraphic );
445         }
446         catch( const Exception& )
447         {
448             DBG_UNHANDLED_EXCEPTION();
449         }
450     }
451 
452     //------------------------------------------------------------------
453     void OBrowserLine::ShowBrowseButton( const ::rtl::OUString& _rImageURL, sal_Bool _bPrimary )
454     {
455         PushButton& rButton( impl_ensureButton( _bPrimary ) );
456 
457         OSL_PRECOND( _rImageURL.getLength(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
458         Image aImage, aHCImage;
459         impl_getImagesFromURL_nothrow( _rImageURL, aImage, aHCImage );
460 
461         rButton.SetModeImage( aImage, BMP_COLOR_NORMAL );
462         rButton.SetModeImage( aHCImage, BMP_COLOR_HIGHCONTRAST );
463     }
464 
465     //------------------------------------------------------------------
466     void OBrowserLine::ShowBrowseButton( const Image& _rImage, sal_Bool _bPrimary )
467     {
468         PushButton& rButton( impl_ensureButton( _bPrimary ) );
469         if ( !!_rImage )
470             rButton.SetModeImage( _rImage );
471     }
472 
473     //------------------------------------------------------------------
474     void OBrowserLine::ShowBrowseButton( sal_Bool _bPrimary )
475     {
476         impl_ensureButton( _bPrimary );
477     }
478 
479     //------------------------------------------------------------------
480     void OBrowserLine::implHideBrowseButton( sal_Bool _bPrimary, bool _bReLayout )
481     {
482         PushButton*& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;
483 
484         if ( rpButton )
485         {
486             rpButton->Hide();
487             delete rpButton;
488             rpButton = NULL;
489         }
490 
491         if ( _bReLayout )
492             impl_layoutComponents();
493     }
494 
495     //------------------------------------------------------------------
496     void OBrowserLine::HideBrowseButton( sal_Bool _bPrimary )
497     {
498         implHideBrowseButton( _bPrimary, true );
499     }
500 
501     //------------------------------------------------------------------
502     void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth)
503     {
504         if (m_nNameWidth != nWidth+10)
505         {
506             m_nNameWidth = nWidth+10;
507             impl_layoutComponents();
508         }
509         // #99102# ---------
510         FullFillTitleString();
511     }
512 
513     //------------------------------------------------------------------
514     void OBrowserLine::SetClickListener( IButtonClickListener* _pListener )
515     {
516         m_pClickListener = _pListener;
517     }
518 
519     //------------------------------------------------------------------
520     IMPL_LINK( OBrowserLine, OnButtonClicked, PushButton*, _pButton )
521     {
522         if ( m_pClickListener )
523             m_pClickListener->buttonClicked( this, _pButton == m_pBrowseButton );
524 
525         return 0L;
526     }
527 
528     //------------------------------------------------------------------
529     IMPL_LINK( OBrowserLine, OnButtonFocus, PushButton*, /*pPB*/ )
530     {
531         if ( m_xControl.is() )
532         {
533             try
534             {
535                 Reference< XPropertyControlContext > xContext( m_xControl->getControlContext(), UNO_QUERY_THROW );
536                 xContext->focusGained( m_xControl );
537             }
538             catch( const Exception& )
539             {
540                 DBG_UNHANDLED_EXCEPTION();
541             }
542         }
543         return 0;
544     }
545 //............................................................................
546 } // namespace pcr
547 //............................................................................
548 
549