1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "browserline.hxx"
22 #include <com/sun/star/uno/XComponentContext.hpp>
23 #include <com/sun/star/inspection/PropertyLineElement.hpp>
24 #include <com/sun/star/graphic/GraphicProvider.hpp>
25 #include <com/sun/star/graphic/XGraphicProvider.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <comphelper/string.hxx>
29 #include <tools/debug.hxx>
30 #include <tools/diagnose_ex.h>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/settings.hxx>
40 using ::com::sun::star::uno::Reference
;
41 using ::com::sun::star::uno::XComponentContext
;
42 using ::com::sun::star::inspection::XPropertyControl
;
43 using ::com::sun::star::inspection::XPropertyControlContext
;
44 using ::com::sun::star::uno::UNO_QUERY_THROW
;
45 using ::com::sun::star::uno::Exception
;
46 using ::com::sun::star::graphic::GraphicProvider
;
47 using ::com::sun::star::graphic::XGraphicProvider
;
48 using ::com::sun::star::uno::Sequence
;
49 using ::com::sun::star::beans::PropertyValue
;
50 using ::com::sun::star::graphic::XGraphic
;
52 namespace PropertyLineElement
= ::com::sun::star::inspection::PropertyLineElement
;
54 OBrowserLine::OBrowserLine( const OUString
& _rEntryName
, vcl::Window
* pParent
)
55 :m_sEntryName( _rEntryName
)
56 ,m_aFtTitle(VclPtr
<FixedText
>::Create(pParent
))
57 ,m_pControlWindow( nullptr )
58 ,m_pBrowseButton(nullptr)
59 ,m_pAdditionalBrowseButton( nullptr )
60 ,m_pClickListener( nullptr )
61 ,m_pTheParent(pParent
)
63 ,m_nEnableFlags( 0xFFFF )
64 ,m_bIndentTitle( false )
70 OBrowserLine::~OBrowserLine()
72 implHideBrowseButton(true);
73 implHideBrowseButton(false);
74 m_aFtTitle
.disposeAndClear();
78 void OBrowserLine::IndentTitle( bool _bIndent
)
80 if ( m_bIndentTitle
!= _bIndent
)
82 m_bIndentTitle
= _bIndent
;
83 impl_layoutComponents();
87 void OBrowserLine::SetComponentHelpIds(const OString
& _rHelpId
)
89 if ( m_pControlWindow
)
90 m_pControlWindow
->SetHelpId( _rHelpId
);
92 if ( m_pBrowseButton
)
94 m_pBrowseButton
->SetHelpId( _rHelpId
);
96 if ( m_pAdditionalBrowseButton
)
98 m_pAdditionalBrowseButton
->SetHelpId( _rHelpId
);
103 void OBrowserLine::setControl( const Reference
< XPropertyControl
>& _rxControl
)
105 m_xControl
= _rxControl
;
106 m_pControlWindow
= m_xControl
.is() ? VCLUnoHelper::GetWindow( _rxControl
->getControlWindow() ) : VclPtr
<vcl::Window
>();
107 DBG_ASSERT( m_pControlWindow
, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" );
109 if ( m_pControlWindow
)
111 m_pControlWindow
->SetParent( m_pTheParent
);
112 m_pControlWindow
->Show();
114 impl_layoutComponents();
118 vcl::Window
* OBrowserLine::GetRefWindow()
120 vcl::Window
* pRefWindow
= m_aFtTitle
.get();
124 pRefWindow
= m_pBrowseButton
;
126 else if ( m_pControlWindow
)
128 pRefWindow
= m_pControlWindow
;
134 void OBrowserLine::SetTabOrder(vcl::Window
* pRefWindow
, ZOrderFlags nFlags
)
136 m_aFtTitle
->SetZOrder(pRefWindow
,nFlags
);
137 if ( m_pControlWindow
)
138 m_pControlWindow
->SetZOrder( m_aFtTitle
.get(), ZOrderFlags::Behind
);
140 if ( m_pBrowseButton
&& m_pControlWindow
)
141 m_pBrowseButton
->SetZOrder( m_pControlWindow
, ZOrderFlags::Behind
);
143 if ( m_pAdditionalBrowseButton
&& m_pBrowseButton
)
144 m_pAdditionalBrowseButton
->SetZOrder( m_pBrowseButton
, ZOrderFlags::Behind
);
148 bool OBrowserLine::GrabFocus()
152 if ( m_pControlWindow
&& m_pControlWindow
->IsEnabled() )
154 m_pControlWindow
->GrabFocus();
157 else if ( m_pAdditionalBrowseButton
&& m_pAdditionalBrowseButton
->IsEnabled() )
159 m_pAdditionalBrowseButton
->GrabFocus();
162 else if ( m_pBrowseButton
&& m_pBrowseButton
->IsEnabled() )
164 m_pBrowseButton
->GrabFocus();
171 void OBrowserLine::SetPosSizePixel( Point _rPos
, Size _rSize
)
174 m_aOutputSize
= _rSize
;
176 impl_layoutComponents();
180 void OBrowserLine::Show(bool bFlag
)
182 m_aFtTitle
->Show(bFlag
);
183 if ( m_pControlWindow
)
184 m_pControlWindow
->Show( bFlag
);
185 if ( m_pBrowseButton
)
186 m_pBrowseButton
->Show( bFlag
);
187 if ( m_pAdditionalBrowseButton
)
188 m_pAdditionalBrowseButton
->Show( bFlag
);
192 void OBrowserLine::Hide()
198 bool OBrowserLine::IsVisible() const
200 return m_aFtTitle
->IsVisible();
204 void OBrowserLine::impl_layoutComponents()
207 Point
aTitlePos( m_aLinePos
.X(), m_aLinePos
.Y() + 8 );
208 Size
aTitleSize( m_nNameWidth
- 3, m_aOutputSize
.Height() );
210 if ( m_bIndentTitle
)
212 Size
aIndent( m_pTheParent
->LogicToPixel(Size(8, 0), MapMode(MapUnit::MapAppFont
)) );
213 aTitlePos
.AdjustX(aIndent
.Width() );
214 aTitleSize
.AdjustWidth( -(aIndent
.Width()) );
216 m_aFtTitle
->SetPosSizePixel( aTitlePos
, aTitleSize
);
219 sal_Int32 nBrowseButtonSize
= m_aOutputSize
.Height() - 4;
221 if ( m_pControlWindow
)
223 Point
aControlPos( m_aLinePos
.X() + m_nNameWidth
, m_aLinePos
.Y() + 2 );
224 m_pControlWindow
->SetPosPixel( aControlPos
);
226 Size
aControlSize( m_aOutputSize
.Width() - 4 - m_nNameWidth
- nBrowseButtonSize
- 4, m_pControlWindow
->GetSizePixel().Height() );
227 if ( m_pAdditionalBrowseButton
)
228 aControlSize
.AdjustWidth( -(nBrowseButtonSize
+ 4) );
229 m_pControlWindow
->SetSizePixel( aControlSize
);
232 if ( m_pBrowseButton
)
234 Point
aButtonPos( m_aOutputSize
.Width() - 4 - nBrowseButtonSize
, m_aLinePos
.Y() + 2 );
235 Size
aButtonSize( nBrowseButtonSize
, nBrowseButtonSize
);
236 m_pBrowseButton
->SetPosSizePixel( aButtonPos
, aButtonSize
);
238 if ( m_pAdditionalBrowseButton
)
240 aButtonPos
.AdjustX( -(nBrowseButtonSize
+ 4) );
241 m_pAdditionalBrowseButton
->SetPosSizePixel( aButtonPos
, aButtonSize
);
247 void OBrowserLine::SetTitle(const OUString
& _rNewTitle
)
249 if ( GetTitle() == _rNewTitle
)
251 m_aFtTitle
->SetText( _rNewTitle
);
252 if ( m_pControlWindow
)
253 m_pControlWindow
->SetAccessibleName( _rNewTitle
);
254 if ( m_pBrowseButton
)
255 m_pBrowseButton
->SetAccessibleName( _rNewTitle
);
256 FullFillTitleString();
259 void OBrowserLine::FullFillTitleString()
263 OUStringBuffer
aText( m_aFtTitle
->GetText() );
265 while( m_pTheParent
->GetTextWidth( aText
.toString() ) < m_nNameWidth
)
266 aText
.append("...........");
269 if (AllSettings::GetLayoutRTL())
271 sal_Unicode
const cRTL_mark
= 0x200F;
272 aText
.append( OUString(cRTL_mark
) );
275 m_aFtTitle
->SetText( aText
.makeStringAndClear() );
280 OUString
OBrowserLine::GetTitle() const
282 OUString sDisplayName
= m_aFtTitle
->GetText();
285 if (AllSettings::GetLayoutRTL())
287 sal_Unicode
const cRTL_mark
= 0x200F;
288 sDisplayName
= comphelper::string::stripEnd(sDisplayName
, cRTL_mark
);
291 sDisplayName
= comphelper::string::stripEnd(sDisplayName
, '.');
297 void OBrowserLine::SetReadOnly( bool _bReadOnly
)
299 if ( m_bReadOnly
!= _bReadOnly
)
301 m_bReadOnly
= _bReadOnly
;
302 implUpdateEnabledDisabled();
309 void implSetBitIfAffected( sal_uInt16
& _nEnabledBits
, sal_Int16 _nAffectedMask
, sal_Int16 _nTestBit
, bool _bSet
)
311 if ( _nAffectedMask
& _nTestBit
)
314 _nEnabledBits
|= _nTestBit
;
316 _nEnabledBits
&= ~_nTestBit
;
320 void implEnable( vcl::Window
* _pWindow
, sal_uInt16 _nEnabledBits
, sal_uInt16 _nMatchBits
)
323 _pWindow
->Enable( ( _nEnabledBits
& _nMatchBits
) == _nMatchBits
);
326 void implEnable( vcl::Window
* _pWindow
, bool _bEnable
)
329 _pWindow
->Enable( _bEnable
);
334 void OBrowserLine::implUpdateEnabledDisabled()
336 implEnable( m_aFtTitle
.get(), m_nEnableFlags
, PropertyLineElement::CompleteLine
);
337 if ( m_pControlWindow
)
338 implEnable( m_pControlWindow
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::InputControl
);
342 implEnable( m_pBrowseButton
, false );
343 implEnable( m_pAdditionalBrowseButton
, false );
347 implEnable( m_pBrowseButton
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::PrimaryButton
);
348 implEnable( m_pAdditionalBrowseButton
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::SecondaryButton
);
353 void OBrowserLine::EnablePropertyLine( bool _bEnable
)
355 implSetBitIfAffected( m_nEnableFlags
, PropertyLineElement::CompleteLine
, PropertyLineElement::CompleteLine
, _bEnable
);
356 implUpdateEnabledDisabled();
360 void OBrowserLine::EnablePropertyControls( sal_Int16 _nControls
, bool _bEnable
)
362 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::InputControl
, _bEnable
);
363 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::PrimaryButton
, _bEnable
);
364 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::SecondaryButton
, _bEnable
);
365 implUpdateEnabledDisabled();
369 PushButton
& OBrowserLine::impl_ensureButton( bool _bPrimary
)
371 VclPtr
<PushButton
>& rpButton
= _bPrimary
? m_pBrowseButton
: m_pAdditionalBrowseButton
;
375 rpButton
= VclPtr
<PushButton
>::Create( m_pTheParent
, WB_NOPOINTERFOCUS
);
376 rpButton
->SetGetFocusHdl( LINK( this, OBrowserLine
, OnButtonFocus
) );
377 rpButton
->SetClickHdl( LINK( this, OBrowserLine
, OnButtonClicked
) );
378 rpButton
->SetText("...");
383 impl_layoutComponents();
389 void OBrowserLine::ShowBrowseButton( const OUString
& _rImageURL
, bool _bPrimary
)
391 PushButton
& rButton( impl_ensureButton( _bPrimary
) );
393 OSL_PRECOND( !_rImageURL
.isEmpty(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
397 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
398 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create(xContext
) );
400 Sequence
< PropertyValue
> aMediaProperties(1);
401 aMediaProperties
[0].Name
= "URL";
402 aMediaProperties
[0].Value
<<= _rImageURL
;
404 Reference
< XGraphic
> xGraphic( xGraphicProvider
->queryGraphic( aMediaProperties
), css::uno::UNO_SET_THROW
);
405 aImage
= Image( xGraphic
);
407 catch( const Exception
& )
409 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
412 rButton
.SetModeImage( aImage
);
415 void OBrowserLine::ShowBrowseButton( const Image
& _rImage
, bool _bPrimary
)
417 PushButton
& rButton( impl_ensureButton( _bPrimary
) );
419 rButton
.SetModeImage( _rImage
);
422 void OBrowserLine::ShowBrowseButton( bool _bPrimary
)
424 impl_ensureButton( _bPrimary
);
427 void OBrowserLine::implHideBrowseButton(bool _bPrimary
)
429 VclPtr
<PushButton
>& rpButton
= _bPrimary
? m_pBrowseButton
: m_pAdditionalBrowseButton
;
434 rpButton
.disposeAndClear();
438 void OBrowserLine::HideBrowseButton(bool _bPrimary
)
440 implHideBrowseButton(_bPrimary
);
441 impl_layoutComponents();
444 void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth
)
446 if (m_nNameWidth
!= nWidth
+10)
448 m_nNameWidth
= nWidth
+10;
449 impl_layoutComponents();
451 FullFillTitleString();
455 void OBrowserLine::SetClickListener( IButtonClickListener
* _pListener
)
457 m_pClickListener
= _pListener
;
461 IMPL_LINK( OBrowserLine
, OnButtonClicked
, Button
*, _pButton
, void )
463 if ( m_pClickListener
)
464 m_pClickListener
->buttonClicked( this, _pButton
== m_pBrowseButton
);
468 IMPL_LINK_NOARG( OBrowserLine
, OnButtonFocus
, Control
&, void )
470 if ( m_xControl
.is() )
474 Reference
< XPropertyControlContext
> xContext( m_xControl
->getControlContext(), css::uno::UNO_SET_THROW
);
475 xContext
->focusGained( m_xControl
);
477 catch( const Exception
& )
479 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */