Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "browserline.hxx"
21 :
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>
26 :
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>
34 :
35 :
36 : namespace pcr
37 : {
38 :
39 :
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;
51 :
52 : namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;
53 :
54 0 : OBrowserLine::OBrowserLine( const OUString& _rEntryName, vcl::Window* pParent )
55 : :m_sEntryName( _rEntryName )
56 : ,m_aFtTitle(VclPtr<FixedText>::Create(pParent))
57 : ,m_pControlWindow( NULL )
58 : ,m_pBrowseButton(NULL)
59 : ,m_pAdditionalBrowseButton( NULL )
60 : ,m_pClickListener( NULL )
61 : ,m_pTheParent(pParent)
62 : ,m_nNameWidth(0)
63 : ,m_nEnableFlags( 0xFFFF )
64 : ,m_bIndentTitle( false )
65 0 : ,m_bReadOnly( false )
66 : {
67 0 : m_aFtTitle->Show();
68 0 : }
69 :
70 0 : OBrowserLine::~OBrowserLine()
71 : {
72 0 : implHideBrowseButton( true, false );
73 0 : implHideBrowseButton( false, false );
74 0 : m_aFtTitle.disposeAndClear();
75 0 : }
76 :
77 :
78 0 : void OBrowserLine::IndentTitle( bool _bIndent )
79 : {
80 0 : if ( m_bIndentTitle != _bIndent )
81 : {
82 0 : m_bIndentTitle = _bIndent;
83 0 : impl_layoutComponents();
84 : }
85 0 : }
86 :
87 :
88 0 : void OBrowserLine::SetComponentHelpIds( const OString& _rHelpId, const OString& _sPrimaryButtonId, const OString& _sSecondaryButtonId )
89 : {
90 0 : if ( m_pControlWindow )
91 0 : m_pControlWindow->SetHelpId( _rHelpId );
92 :
93 0 : if ( m_pBrowseButton )
94 : {
95 0 : m_pBrowseButton->SetHelpId( _rHelpId );
96 0 : m_pBrowseButton->SetUniqueId( _sPrimaryButtonId );
97 :
98 0 : if ( m_pAdditionalBrowseButton )
99 : {
100 0 : m_pAdditionalBrowseButton->SetHelpId( _rHelpId );
101 0 : m_pAdditionalBrowseButton->SetUniqueId( _sSecondaryButtonId );
102 : }
103 : }
104 0 : }
105 :
106 :
107 0 : void OBrowserLine::setControl( const Reference< XPropertyControl >& _rxControl )
108 : {
109 0 : m_xControl = _rxControl;
110 0 : m_pControlWindow = m_xControl.is() ? VCLUnoHelper::GetWindow( _rxControl->getControlWindow() ) : VclPtr<vcl::Window>();
111 : DBG_ASSERT( m_pControlWindow, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" );
112 :
113 0 : if ( m_pControlWindow )
114 : {
115 0 : m_pControlWindow->SetParent( m_pTheParent );
116 0 : m_pControlWindow->Show();
117 : }
118 0 : impl_layoutComponents();
119 0 : }
120 :
121 :
122 0 : vcl::Window* OBrowserLine::GetRefWindow()
123 : {
124 0 : vcl::Window* pRefWindow = m_aFtTitle.get();
125 :
126 0 : if(m_pBrowseButton)
127 : {
128 0 : pRefWindow=static_cast<vcl::Window*>(m_pBrowseButton);
129 : }
130 0 : else if ( m_pControlWindow )
131 : {
132 0 : pRefWindow = m_pControlWindow;
133 : }
134 0 : return pRefWindow;
135 : }
136 :
137 :
138 0 : void OBrowserLine::SetTabOrder(vcl::Window* pRefWindow, ZOrderFlags nFlags )
139 : {
140 0 : m_aFtTitle->SetZOrder(pRefWindow,nFlags);
141 0 : if ( m_pControlWindow )
142 0 : m_pControlWindow->SetZOrder( m_aFtTitle.get(), ZOrderFlags::Behind );
143 :
144 0 : if ( m_pBrowseButton && m_pControlWindow )
145 0 : m_pBrowseButton->SetZOrder( m_pControlWindow, ZOrderFlags::Behind );
146 :
147 0 : if ( m_pAdditionalBrowseButton && m_pBrowseButton )
148 0 : m_pAdditionalBrowseButton->SetZOrder( m_pBrowseButton, ZOrderFlags::Behind );
149 0 : }
150 :
151 :
152 0 : bool OBrowserLine::GrabFocus()
153 : {
154 0 : bool bRes=false;
155 :
156 0 : if ( m_pControlWindow && m_pControlWindow->IsEnabled() )
157 : {
158 0 : m_pControlWindow->GrabFocus();
159 0 : bRes = true;
160 : }
161 0 : else if ( m_pAdditionalBrowseButton && m_pAdditionalBrowseButton->IsEnabled() )
162 : {
163 0 : m_pAdditionalBrowseButton->GrabFocus();
164 0 : bRes = true;
165 : }
166 0 : else if ( m_pBrowseButton && m_pBrowseButton->IsEnabled() )
167 : {
168 0 : m_pBrowseButton->GrabFocus();
169 0 : bRes = true;
170 : }
171 0 : return bRes;
172 : }
173 :
174 :
175 0 : void OBrowserLine::SetPosSizePixel( Point _rPos, Size _rSize )
176 : {
177 0 : m_aLinePos = _rPos;
178 0 : m_aOutputSize = _rSize;
179 :
180 0 : impl_layoutComponents();
181 0 : }
182 :
183 :
184 0 : void OBrowserLine::Show(bool bFlag)
185 : {
186 0 : m_aFtTitle->Show(bFlag);
187 0 : if ( m_pControlWindow )
188 0 : m_pControlWindow->Show( bFlag );
189 0 : if ( m_pBrowseButton )
190 0 : m_pBrowseButton->Show( bFlag );
191 0 : if ( m_pAdditionalBrowseButton )
192 0 : m_pAdditionalBrowseButton->Show( bFlag );
193 0 : }
194 :
195 :
196 0 : void OBrowserLine::Hide()
197 : {
198 0 : Show(false);
199 0 : }
200 :
201 :
202 0 : bool OBrowserLine::IsVisible()
203 : {
204 0 : return m_aFtTitle->IsVisible();
205 : }
206 :
207 :
208 0 : void OBrowserLine::impl_layoutComponents()
209 : {
210 : {
211 0 : Point aTitlePos( m_aLinePos.X(), m_aLinePos.Y() + 8 );
212 0 : Size aTitleSize( m_nNameWidth - 3, m_aOutputSize.Height() );
213 :
214 0 : if ( m_bIndentTitle )
215 : {
216 0 : Size aIndent( m_pTheParent->LogicToPixel( Size( 8, 0 ), MAP_APPFONT ) );
217 0 : aTitlePos.X() += aIndent.Width();
218 0 : aTitleSize.Width() -= aIndent.Width();
219 : }
220 0 : m_aFtTitle->SetPosSizePixel( aTitlePos, aTitleSize );
221 : }
222 :
223 0 : sal_Int32 nBrowseButtonSize = m_aOutputSize.Height() - 4;
224 :
225 0 : if ( m_pControlWindow )
226 : {
227 0 : Point aControlPos( m_aLinePos.X() + m_nNameWidth, m_aLinePos.Y() + 2 );
228 0 : m_pControlWindow->SetPosPixel( aControlPos );
229 :
230 0 : Size aControlSize( m_aOutputSize.Width() - 4 - m_nNameWidth - nBrowseButtonSize - 4, m_pControlWindow->GetSizePixel().Height() );
231 0 : if ( m_pAdditionalBrowseButton )
232 0 : aControlSize.Width() -= nBrowseButtonSize + 4;
233 0 : m_pControlWindow->SetSizePixel( aControlSize );
234 : }
235 :
236 0 : if ( m_pBrowseButton )
237 : {
238 0 : Point aButtonPos( m_aOutputSize.Width() - 4 - nBrowseButtonSize, m_aLinePos.Y() + 2 );
239 0 : Size aButtonSize( nBrowseButtonSize, nBrowseButtonSize );
240 0 : m_pBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );
241 :
242 0 : if ( m_pAdditionalBrowseButton )
243 : {
244 0 : aButtonPos.X() -= nBrowseButtonSize + 4;
245 0 : m_pAdditionalBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize );
246 : }
247 : }
248 0 : }
249 :
250 :
251 0 : void OBrowserLine::SetTitle(const OUString& _rNewTtile )
252 : {
253 0 : if ( GetTitle() == _rNewTtile )
254 0 : return;
255 : // #99102# --------------
256 0 : m_aFtTitle->SetText( _rNewTtile );
257 0 : if ( m_pControlWindow )
258 0 : m_pControlWindow->SetAccessibleName( _rNewTtile );
259 0 : if ( m_pBrowseButton )
260 0 : m_pBrowseButton->SetAccessibleName( _rNewTtile );
261 0 : FullFillTitleString();
262 : }
263 :
264 : // #99102# ---------------------------------------------------------
265 0 : void OBrowserLine::FullFillTitleString()
266 : {
267 0 : if( m_pTheParent )
268 : {
269 0 : OUStringBuffer aText( m_aFtTitle->GetText() );
270 :
271 0 : while( m_pTheParent->GetTextWidth( aText.toString() ) < m_nNameWidth )
272 0 : aText.append("...........");
273 :
274 : // for Issue 69452
275 0 : if (AllSettings::GetLayoutRTL())
276 : {
277 0 : sal_Unicode cRTL_mark = 0x200F;
278 0 : aText.append( OUString(cRTL_mark) );
279 : }
280 :
281 0 : m_aFtTitle->SetText( aText.makeStringAndClear() );
282 : }
283 0 : }
284 :
285 :
286 0 : OUString OBrowserLine::GetTitle() const
287 : {
288 0 : OUString sDisplayName = m_aFtTitle->GetText();
289 :
290 : // for Issue 69452
291 0 : if (AllSettings::GetLayoutRTL())
292 : {
293 0 : sal_Unicode cRTL_mark = 0x200F;
294 0 : sDisplayName = comphelper::string::stripEnd(sDisplayName, cRTL_mark);
295 : }
296 :
297 0 : sDisplayName = comphelper::string::stripEnd(sDisplayName, '.');
298 :
299 0 : return sDisplayName;
300 : }
301 :
302 :
303 0 : void OBrowserLine::SetReadOnly( bool _bReadOnly )
304 : {
305 0 : if ( m_bReadOnly != _bReadOnly )
306 : {
307 0 : m_bReadOnly = _bReadOnly;
308 0 : implUpdateEnabledDisabled();
309 : }
310 0 : }
311 :
312 :
313 : namespace
314 : {
315 0 : void implSetBitIfAffected( sal_uInt16& _nEnabledBits, sal_Int16 _nAffectedMask, sal_Int16 _nTestBit, bool _bSet )
316 : {
317 0 : if ( _nAffectedMask & _nTestBit )
318 : {
319 0 : if ( _bSet )
320 0 : _nEnabledBits |= _nTestBit;
321 : else
322 0 : _nEnabledBits &= ~_nTestBit;
323 : }
324 0 : }
325 :
326 0 : void implEnable( vcl::Window* _pWindow, sal_uInt16 _nEnabledBits, sal_uInt16 _nMatchBits )
327 : {
328 0 : if ( _pWindow )
329 0 : _pWindow->Enable( ( _nEnabledBits & _nMatchBits ) == _nMatchBits );
330 0 : }
331 :
332 0 : void implEnable( vcl::Window* _pWindow, bool _bEnable )
333 : {
334 0 : if ( _pWindow )
335 0 : _pWindow->Enable( _bEnable );
336 0 : }
337 : }
338 :
339 :
340 0 : void OBrowserLine::implUpdateEnabledDisabled()
341 : {
342 0 : implEnable( m_aFtTitle.get(), m_nEnableFlags, PropertyLineElement::CompleteLine );
343 0 : if ( m_pControlWindow )
344 0 : implEnable( m_pControlWindow, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::InputControl );
345 :
346 0 : if ( m_bReadOnly )
347 : {
348 0 : implEnable( m_pBrowseButton, false );
349 0 : implEnable( m_pAdditionalBrowseButton, false );
350 : }
351 : else
352 : {
353 0 : implEnable( m_pBrowseButton, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::PrimaryButton );
354 0 : implEnable( m_pAdditionalBrowseButton, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::SecondaryButton );
355 : }
356 0 : }
357 :
358 :
359 0 : void OBrowserLine::EnablePropertyLine( bool _bEnable )
360 : {
361 0 : implSetBitIfAffected( m_nEnableFlags, PropertyLineElement::CompleteLine, PropertyLineElement::CompleteLine, _bEnable );
362 0 : implUpdateEnabledDisabled();
363 0 : }
364 :
365 :
366 0 : void OBrowserLine::EnablePropertyControls( sal_Int16 _nControls, bool _bEnable )
367 : {
368 0 : implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::InputControl, _bEnable );
369 0 : implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::PrimaryButton, _bEnable );
370 0 : implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::SecondaryButton, _bEnable );
371 0 : implUpdateEnabledDisabled();
372 0 : }
373 :
374 :
375 0 : PushButton& OBrowserLine::impl_ensureButton( bool _bPrimary )
376 : {
377 0 : VclPtr<PushButton>& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;
378 :
379 0 : if ( !rpButton )
380 : {
381 0 : rpButton = VclPtr<PushButton>::Create( m_pTheParent, WB_NOPOINTERFOCUS );
382 0 : rpButton->SetGetFocusHdl( LINK( this, OBrowserLine, OnButtonFocus ) );
383 0 : rpButton->SetClickHdl( LINK( this, OBrowserLine, OnButtonClicked ) );
384 0 : rpButton->SetText(OUString("..."));
385 : }
386 :
387 0 : rpButton->Show();
388 :
389 0 : impl_layoutComponents();
390 :
391 0 : return *rpButton;
392 : }
393 :
394 :
395 0 : void OBrowserLine::impl_getImagesFromURL_nothrow( const OUString& _rImageURL, Image& _out_rImage )
396 : {
397 : try
398 : {
399 0 : Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
400 0 : Reference< XGraphicProvider > xGraphicProvider( GraphicProvider::create(xContext) );
401 :
402 0 : Sequence< PropertyValue > aMediaProperties(1);
403 0 : aMediaProperties[0].Name = "URL";
404 0 : aMediaProperties[0].Value <<= _rImageURL;
405 :
406 0 : Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ), UNO_QUERY_THROW );
407 0 : _out_rImage = Image( xGraphic );
408 : }
409 0 : catch( const Exception& )
410 : {
411 : DBG_UNHANDLED_EXCEPTION();
412 : }
413 0 : }
414 :
415 :
416 0 : void OBrowserLine::ShowBrowseButton( const OUString& _rImageURL, bool _bPrimary )
417 : {
418 0 : PushButton& rButton( impl_ensureButton( _bPrimary ) );
419 :
420 : OSL_PRECOND( !_rImageURL.isEmpty(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" );
421 0 : Image aImage;
422 0 : impl_getImagesFromURL_nothrow( _rImageURL, aImage );
423 :
424 0 : rButton.SetModeImage( aImage );
425 0 : }
426 :
427 :
428 0 : void OBrowserLine::ShowBrowseButton( const Image& _rImage, bool _bPrimary )
429 : {
430 0 : PushButton& rButton( impl_ensureButton( _bPrimary ) );
431 0 : if ( !!_rImage )
432 0 : rButton.SetModeImage( _rImage );
433 0 : }
434 :
435 :
436 0 : void OBrowserLine::ShowBrowseButton( bool _bPrimary )
437 : {
438 0 : impl_ensureButton( _bPrimary );
439 0 : }
440 :
441 :
442 0 : void OBrowserLine::implHideBrowseButton( bool _bPrimary, bool _bReLayout )
443 : {
444 0 : VclPtr<PushButton>& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton;
445 :
446 0 : if ( rpButton )
447 : {
448 0 : rpButton->Hide();
449 0 : rpButton.disposeAndClear();
450 : }
451 :
452 0 : if ( _bReLayout )
453 0 : impl_layoutComponents();
454 0 : }
455 :
456 :
457 0 : void OBrowserLine::HideBrowseButton( bool _bPrimary )
458 : {
459 0 : implHideBrowseButton( _bPrimary, true );
460 0 : }
461 :
462 :
463 0 : void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth)
464 : {
465 0 : if (m_nNameWidth != nWidth+10)
466 : {
467 0 : m_nNameWidth = nWidth+10;
468 0 : impl_layoutComponents();
469 : }
470 : // #99102# ---------
471 0 : FullFillTitleString();
472 0 : }
473 :
474 :
475 0 : void OBrowserLine::SetClickListener( IButtonClickListener* _pListener )
476 : {
477 0 : m_pClickListener = _pListener;
478 0 : }
479 :
480 :
481 0 : IMPL_LINK( OBrowserLine, OnButtonClicked, PushButton*, _pButton )
482 : {
483 0 : if ( m_pClickListener )
484 0 : m_pClickListener->buttonClicked( this, _pButton == m_pBrowseButton );
485 :
486 0 : return 0L;
487 : }
488 :
489 :
490 0 : IMPL_LINK( OBrowserLine, OnButtonFocus, PushButton*, /*pPB*/ )
491 : {
492 0 : if ( m_xControl.is() )
493 : {
494 : try
495 : {
496 0 : Reference< XPropertyControlContext > xContext( m_xControl->getControlContext(), UNO_QUERY_THROW );
497 0 : xContext->focusGained( m_xControl );
498 : }
499 0 : catch( const Exception& )
500 : {
501 : DBG_UNHANDLED_EXCEPTION();
502 : }
503 : }
504 0 : return 0;
505 : }
506 :
507 6 : } // namespace pcr
508 :
509 :
510 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|