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