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