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/propertyvalue.hxx>
29 #include <comphelper/string.hxx>
30 #include <tools/debug.hxx>
31 #include <comphelper/diagnose_ex.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/weld.hxx>
36 #include <vcl/weldutils.hxx>
42 using ::com::sun::star::uno::Reference
;
43 using ::com::sun::star::uno::XComponentContext
;
44 using ::com::sun::star::inspection::XPropertyControl
;
45 using ::com::sun::star::inspection::XPropertyControlContext
;
46 using ::com::sun::star::uno::Exception
;
47 using ::com::sun::star::graphic::GraphicProvider
;
48 using ::com::sun::star::graphic::XGraphicProvider
;
49 using ::com::sun::star::uno::Sequence
;
50 using ::com::sun::star::graphic::XGraphic
;
52 namespace PropertyLineElement
= ::com::sun::star::inspection::PropertyLineElement
;
54 OBrowserLine::OBrowserLine(OUString aEntryName
, weld::Container
* pParent
, weld::SizeGroup
* pLabelGroup
,
55 weld::Container
* pInitialControlParent
)
56 : m_sEntryName(std::move(aEntryName
))
57 , m_xBuilder(Application::CreateBuilder(pParent
, "modules/spropctrlr/ui/browserline.ui"))
58 , m_xContainer(m_xBuilder
->weld_container("BrowserLine"))
59 , m_xFtTitle(m_xBuilder
->weld_label("label"))
60 , m_xBrowseButton(m_xBuilder
->weld_button("browse"))
61 , m_xAdditionalBrowseButton(m_xBuilder
->weld_button("morebrowse"))
62 , m_pInitialControlParent(pInitialControlParent
) // controls start with this as their parent and need to be moved into m_xContainer
64 , m_pControlWindow( nullptr )
65 , m_pBrowseButton(nullptr)
66 , m_pAdditionalBrowseButton( nullptr )
67 , m_pClickListener( nullptr )
69 , m_nEnableFlags( 0xFFFF )
70 , m_bIndentTitle( false )
71 , m_bReadOnly( false )
73 pLabelGroup
->add_widget(m_xFtTitle
.get());
76 OBrowserLine::~OBrowserLine()
78 implHideBrowseButton(true);
79 implHideBrowseButton(false);
80 m_pParent
->move(m_xContainer
.get(), nullptr);
83 void OBrowserLine::IndentTitle( bool _bIndent
)
85 if ( m_bIndentTitle
!= _bIndent
)
87 m_bIndentTitle
= _bIndent
;
91 void OBrowserLine::SetComponentHelpIds(const OUString
& rHelpId
)
94 m_pControlWindow
->set_help_id(rHelpId
);
96 if ( m_pBrowseButton
)
98 m_pBrowseButton
->set_help_id(rHelpId
);
100 if ( m_pAdditionalBrowseButton
)
102 m_pAdditionalBrowseButton
->set_help_id(rHelpId
);
107 void OBrowserLine::setControl( const Reference
< XPropertyControl
>& rxControl
)
109 m_xControl
= rxControl
;
110 auto xWindow
= m_xControl
->getControlWindow();
111 if (weld::TransportAsXWindow
* pTunnel
= dynamic_cast<weld::TransportAsXWindow
*>(xWindow
.get()))
112 m_pControlWindow
= pTunnel
->getWidget();
114 m_pControlWindow
= nullptr;
115 DBG_ASSERT( m_pControlWindow
, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" );
117 if ( m_pControlWindow
)
119 m_pInitialControlParent
->move(m_pControlWindow
, m_xContainer
.get());
120 m_pControlWindow
->set_grid_left_attach(1);
121 m_xFtTitle
->set_mnemonic_widget(m_pControlWindow
);
122 m_pControlWindow
->show();
126 bool OBrowserLine::GrabFocus()
130 if (m_pControlWindow
&& m_pControlWindow
->get_sensitive())
132 m_pControlWindow
->grab_focus();
135 else if ( m_pAdditionalBrowseButton
&& m_pAdditionalBrowseButton
->get_sensitive() )
137 m_pAdditionalBrowseButton
->grab_focus();
140 else if ( m_pBrowseButton
&& m_pBrowseButton
->get_sensitive() )
142 m_pBrowseButton
->grab_focus();
148 void OBrowserLine::Show(bool bFlag
)
150 m_xFtTitle
->set_visible(bFlag
);
151 if (m_pControlWindow
)
152 m_pControlWindow
->set_visible( bFlag
);
153 if ( m_pBrowseButton
)
154 m_pBrowseButton
->set_visible( bFlag
);
155 if ( m_pAdditionalBrowseButton
)
156 m_pAdditionalBrowseButton
->set_visible( bFlag
);
159 void OBrowserLine::Hide()
164 void OBrowserLine::SetTitle(const OUString
& rNewTitle
)
166 if ( GetTitle() == rNewTitle
)
168 m_xFtTitle
->set_label( rNewTitle
);
169 if (m_pControlWindow
)
170 m_pControlWindow
->set_accessible_name(rNewTitle
);
171 if ( m_pBrowseButton
)
172 m_pBrowseButton
->set_accessible_name( rNewTitle
);
173 FullFillTitleString();
176 void OBrowserLine::FullFillTitleString()
178 OUStringBuffer
aText(m_xFtTitle
->get_label());
180 int n10DotsWidth
= m_xFtTitle
->get_pixel_size("..........").Width();
181 int nTextWidth
= m_xFtTitle
->get_pixel_size(OUString::unacquired(aText
)).Width();
182 int nDiff
= m_nNameWidth
- nTextWidth
;
183 int nExtraChars
= (nDiff
* 10) / n10DotsWidth
;
184 for (int i
= 0; i
< nExtraChars
; ++i
)
188 if (AllSettings::GetLayoutRTL())
190 sal_Unicode
const cRTL_mark
= 0x200F;
191 aText
.append( cRTL_mark
);
194 m_xFtTitle
->set_label(aText
.makeStringAndClear());
197 OUString
OBrowserLine::GetTitle() const
199 OUString sDisplayName
= m_xFtTitle
->get_label();
202 if (AllSettings::GetLayoutRTL())
204 sal_Unicode
const cRTL_mark
= 0x200F;
205 sDisplayName
= comphelper::string::stripEnd(sDisplayName
, cRTL_mark
);
208 sDisplayName
= comphelper::string::stripEnd(sDisplayName
, '.');
213 void OBrowserLine::SetReadOnly( bool _bReadOnly
)
215 if ( m_bReadOnly
!= _bReadOnly
)
217 m_bReadOnly
= _bReadOnly
;
218 implUpdateEnabledDisabled();
224 void implSetBitIfAffected(sal_uInt16
& nEnabledBits
, sal_Int16 _nAffectedMask
, sal_Int16 _nTestBit
, bool _bSet
)
226 if ( _nAffectedMask
& _nTestBit
)
229 nEnabledBits
|= _nTestBit
;
231 nEnabledBits
&= ~_nTestBit
;
235 void implEnable(weld::Widget
* pWindow
, bool bEnable
)
237 // tdf#138131 get_sensitive comparison as bodge for
238 // vcl's recursive Enable behavior
239 if (pWindow
&& pWindow
->get_sensitive() != bEnable
)
240 pWindow
->set_sensitive(bEnable
);
243 void implEnable(weld::Widget
* pWindow
, sal_uInt16 nEnabledBits
, sal_uInt16 nMatchBits
)
245 bool bEnable
= ((nEnabledBits
& nMatchBits
) == nMatchBits
);
246 implEnable(pWindow
, bEnable
);
250 void OBrowserLine::implUpdateEnabledDisabled()
252 implEnable( m_xFtTitle
.get(), m_nEnableFlags
, PropertyLineElement::CompleteLine
);
253 if ( m_pControlWindow
)
254 implEnable( m_pControlWindow
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::InputControl
);
258 implEnable( m_pBrowseButton
, false );
259 implEnable( m_pAdditionalBrowseButton
, false );
263 implEnable( m_pBrowseButton
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::PrimaryButton
);
264 implEnable( m_pAdditionalBrowseButton
, m_nEnableFlags
, PropertyLineElement::CompleteLine
| PropertyLineElement::SecondaryButton
);
268 void OBrowserLine::EnablePropertyLine( bool _bEnable
)
270 implSetBitIfAffected( m_nEnableFlags
, PropertyLineElement::CompleteLine
, PropertyLineElement::CompleteLine
, _bEnable
);
271 implUpdateEnabledDisabled();
275 void OBrowserLine::EnablePropertyControls( sal_Int16 _nControls
, bool _bEnable
)
277 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::InputControl
, _bEnable
);
278 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::PrimaryButton
, _bEnable
);
279 implSetBitIfAffected( m_nEnableFlags
, _nControls
, PropertyLineElement::SecondaryButton
, _bEnable
);
280 implUpdateEnabledDisabled();
283 weld::Button
& OBrowserLine::impl_ensureButton(bool bPrimary
)
285 weld::Button
* pButton
;
287 pButton
= m_pBrowseButton
;
289 pButton
= m_pAdditionalBrowseButton
;
294 pButton
= m_pBrowseButton
= m_xBrowseButton
.get();
296 pButton
= m_pAdditionalBrowseButton
= m_xAdditionalBrowseButton
.get();
297 pButton
->connect_focus_in(LINK(this, OBrowserLine
, OnButtonFocus
));
298 pButton
->connect_clicked(LINK(this, OBrowserLine
, OnButtonClicked
));
306 void OBrowserLine::ShowBrowseButton( const OUString
& rImageURL
, bool bPrimary
)
308 weld::Button
& rButton( impl_ensureButton( bPrimary
) );
310 OSL_PRECOND( !rImageURL
.isEmpty(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
311 Reference
<XGraphic
> xGraphic
;
314 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
315 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create(xContext
) );
317 Sequence aMediaProperties
{ comphelper::makePropertyValue("URL", rImageURL
) };
319 xGraphic
= Reference
<XGraphic
>(xGraphicProvider
->queryGraphic(aMediaProperties
), css::uno::UNO_SET_THROW
);
321 catch( const Exception
& )
323 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
326 rButton
.set_image(xGraphic
);
329 void OBrowserLine::ShowBrowseButton(const css::uno::Reference
<css::graphic::XGraphic
>& rGraphic
, bool bPrimary
)
331 weld::Button
& rButton( impl_ensureButton( bPrimary
) );
332 rButton
.set_image(rGraphic
);
335 void OBrowserLine::ShowBrowseButton( bool bPrimary
)
337 impl_ensureButton(bPrimary
);
340 void OBrowserLine::implHideBrowseButton(bool bPrimary
)
346 m_pBrowseButton
->hide();
347 m_pBrowseButton
->connect_focus_in(Link
<weld::Widget
&, void>());
348 m_pBrowseButton
= nullptr;
353 if (m_pAdditionalBrowseButton
)
355 m_pAdditionalBrowseButton
->hide();
356 m_pAdditionalBrowseButton
->connect_focus_in(Link
<weld::Widget
&, void>());
357 m_pAdditionalBrowseButton
= nullptr;
362 void OBrowserLine::HideBrowseButton(bool bPrimary
)
364 implHideBrowseButton(bPrimary
);
367 void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth
)
369 int nMinDotsWidth
= m_xFtTitle
->get_pixel_size("...").Width();
370 if (m_nNameWidth
!= nWidth
+ nMinDotsWidth
)
371 m_nNameWidth
= nWidth
+ nMinDotsWidth
;
372 FullFillTitleString();
375 void OBrowserLine::SetClickListener( IButtonClickListener
* _pListener
)
377 m_pClickListener
= _pListener
;
380 IMPL_LINK(OBrowserLine
, OnButtonClicked
, weld::Button
&, rButton
, void)
382 if ( m_pClickListener
)
383 m_pClickListener
->buttonClicked(this, &rButton
== m_pBrowseButton
);
386 IMPL_LINK_NOARG( OBrowserLine
, OnButtonFocus
, weld::Widget
&, void )
388 if ( m_xControl
.is() )
392 Reference
< XPropertyControlContext
> xContext( m_xControl
->getControlContext(), css::uno::UNO_SET_THROW
);
393 xContext
->focusGained( m_xControl
);
395 catch( const Exception
& )
397 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */