1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_extensions.hxx" 30 #include "browserline.hxx" 31 32 /** === begin UNO includes === **/ 33 #include <com/sun/star/inspection/PropertyLineElement.hpp> 34 #include <com/sun/star/graphic/XGraphicProvider.hpp> 35 /** === end UNO includes === **/ 36 37 #include <vcl/svapp.hxx> 38 #include <tools/debug.hxx> 39 #include <tools/diagnose_ex.h> 40 #include <tools/urlobj.hxx> 41 #include <toolkit/helper/vclunohelper.hxx> 42 43 #include <comphelper/processfactory.hxx> 44 #include <comphelper/componentcontext.hxx> 45 46 //............................................................................ 47 namespace pcr 48 { 49 //............................................................................ 50 51 /** === begin UNO using === **/ 52 using ::com::sun::star::uno::Reference; 53 using ::com::sun::star::inspection::XPropertyControl; 54 using ::com::sun::star::inspection::XPropertyControlContext; 55 using ::com::sun::star::uno::UNO_QUERY_THROW; 56 using ::com::sun::star::uno::Exception; 57 using ::com::sun::star::graphic::XGraphicProvider; 58 using ::com::sun::star::uno::Sequence; 59 using ::com::sun::star::beans::PropertyValue; 60 using ::com::sun::star::graphic::XGraphic; 61 /** === end UNO using === **/ 62 63 namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement; 64 65 //================================================================== 66 //= OBrowserLine 67 //================================================================== 68 DBG_NAME(OBrowserLine) 69 //------------------------------------------------------------------ 70 71 OBrowserLine::OBrowserLine( const ::rtl::OUString& _rEntryName, Window* pParent ) 72 :m_sEntryName( _rEntryName ) 73 ,m_aFtTitle(pParent) 74 ,m_pControlWindow( NULL ) 75 ,m_pBrowseButton(NULL) 76 ,m_pAdditionalBrowseButton( NULL ) 77 ,m_pClickListener( NULL ) 78 ,m_pTheParent(pParent) 79 ,m_nNameWidth(0) 80 ,m_nEnableFlags( 0xFFFF ) 81 ,m_bIndentTitle( false ) 82 ,m_bReadOnly( false ) 83 { 84 DBG_CTOR(OBrowserLine,NULL); 85 m_aFtTitle.Show(); 86 } 87 88 //------------------------------------------------------------------ 89 OBrowserLine::~OBrowserLine() 90 { 91 implHideBrowseButton( true, false ); 92 implHideBrowseButton( false, false ); 93 94 DBG_DTOR(OBrowserLine,NULL); 95 } 96 97 //------------------------------------------------------------------ 98 void OBrowserLine::IndentTitle( bool _bIndent ) 99 { 100 if ( m_bIndentTitle != _bIndent ) 101 { 102 m_bIndentTitle = _bIndent; 103 impl_layoutComponents(); 104 } 105 } 106 107 //------------------------------------------------------------------ 108 void OBrowserLine::SetComponentHelpIds( const rtl::OString& _rHelpId, const rtl::OString& _sPrimaryButtonId, const rtl::OString& _sSecondaryButtonId ) 109 { 110 if ( m_pControlWindow ) 111 m_pControlWindow->SetHelpId( _rHelpId ); 112 113 if ( m_pBrowseButton ) 114 { 115 m_pBrowseButton->SetHelpId( _rHelpId ); 116 m_pBrowseButton->SetUniqueId( _sPrimaryButtonId ); 117 118 if ( m_pAdditionalBrowseButton ) 119 { 120 m_pAdditionalBrowseButton->SetHelpId( _rHelpId ); 121 m_pAdditionalBrowseButton->SetUniqueId( _sSecondaryButtonId ); 122 } 123 } 124 } 125 126 //------------------------------------------------------------------ 127 void OBrowserLine::setControl( const Reference< XPropertyControl >& _rxControl ) 128 { 129 m_xControl = _rxControl; 130 m_pControlWindow = m_xControl.is() ? VCLUnoHelper::GetWindow( _rxControl->getControlWindow() ) : NULL; 131 DBG_ASSERT( m_pControlWindow, "OBrowserLine::setControl: setting NULL controls/windows is not allowed!" ); 132 133 if ( m_pControlWindow ) 134 { 135 m_pControlWindow->SetParent( m_pTheParent ); 136 m_pControlWindow->Show(); 137 } 138 impl_layoutComponents(); 139 } 140 141 //------------------------------------------------------------------ 142 Window* OBrowserLine::GetRefWindow() 143 { 144 Window* pRefWindow=&m_aFtTitle; 145 146 if(m_pBrowseButton) 147 { 148 pRefWindow=(Window*)m_pBrowseButton; 149 } 150 else if ( m_pControlWindow ) 151 { 152 pRefWindow = m_pControlWindow; 153 } 154 return pRefWindow; 155 } 156 157 //------------------------------------------------------------------ 158 void OBrowserLine::SetTabOrder(Window* pRefWindow, sal_uInt16 nFlags ) 159 { 160 m_aFtTitle.SetZOrder(pRefWindow,nFlags); 161 if ( m_pControlWindow ) 162 m_pControlWindow->SetZOrder( (Window*)&m_aFtTitle, WINDOW_ZORDER_BEHIND ); 163 164 if ( m_pBrowseButton ) 165 m_pBrowseButton->SetZOrder( m_pControlWindow, WINDOW_ZORDER_BEHIND ); 166 167 if ( m_pAdditionalBrowseButton ) 168 m_pAdditionalBrowseButton->SetZOrder( m_pBrowseButton, WINDOW_ZORDER_BEHIND ); 169 } 170 171 //------------------------------------------------------------------ 172 sal_Bool OBrowserLine::GrabFocus() 173 { 174 sal_Bool bRes=sal_False; 175 176 if ( m_pControlWindow && m_pControlWindow->IsEnabled() ) 177 { 178 m_pControlWindow->GrabFocus(); 179 bRes = sal_True; 180 } 181 else if ( m_pAdditionalBrowseButton && m_pAdditionalBrowseButton->IsEnabled() ) 182 { 183 m_pAdditionalBrowseButton->GrabFocus(); 184 bRes = sal_True; 185 } 186 else if ( m_pBrowseButton && m_pBrowseButton->IsEnabled() ) 187 { 188 m_pBrowseButton->GrabFocus(); 189 bRes = sal_True; 190 } 191 return bRes; 192 } 193 194 //------------------------------------------------------------------ 195 void OBrowserLine::SetPosSizePixel( Point _rPos, Size _rSize ) 196 { 197 m_aLinePos = _rPos; 198 m_aOutputSize = _rSize; 199 200 impl_layoutComponents(); 201 } 202 203 //------------------------------------------------------------------ 204 void OBrowserLine::Show(sal_Bool bFlag) 205 { 206 m_aFtTitle.Show(bFlag); 207 if ( m_pControlWindow ) 208 m_pControlWindow->Show( bFlag ); 209 if ( m_pBrowseButton ) 210 m_pBrowseButton->Show( bFlag ); 211 if ( m_pAdditionalBrowseButton ) 212 m_pAdditionalBrowseButton->Show( bFlag ); 213 } 214 215 //------------------------------------------------------------------ 216 void OBrowserLine::Hide() 217 { 218 Show(sal_False); 219 } 220 221 //------------------------------------------------------------------ 222 sal_Bool OBrowserLine::IsVisible() 223 { 224 return m_aFtTitle.IsVisible(); 225 } 226 227 //------------------------------------------------------------------ 228 void OBrowserLine::impl_layoutComponents() 229 { 230 { 231 Point aTitlePos( m_aLinePos.X(), m_aLinePos.Y() + 8 ); 232 Size aTitleSize( m_nNameWidth - 3, m_aOutputSize.Height() ); 233 234 if ( m_bIndentTitle ) 235 { 236 Size aIndent( m_pTheParent->LogicToPixel( Size( 8, 0 ), MAP_APPFONT ) ); 237 aTitlePos.X() += aIndent.Width(); 238 aTitleSize.Width() -= aIndent.Width(); 239 } 240 m_aFtTitle.SetPosSizePixel( aTitlePos, aTitleSize ); 241 } 242 243 sal_Int32 nBrowseButtonSize = m_aOutputSize.Height() - 4; 244 245 if ( m_pControlWindow ) 246 { 247 Point aControlPos( m_aLinePos.X() + m_nNameWidth, m_aLinePos.Y() + 2 ); 248 m_pControlWindow->SetPosPixel( aControlPos ); 249 250 Size aControlSize( m_aOutputSize.Width() - 4 - m_nNameWidth - nBrowseButtonSize - 4, m_pControlWindow->GetSizePixel().Height() ); 251 if ( m_pAdditionalBrowseButton ) 252 aControlSize.Width() -= nBrowseButtonSize + 4; 253 m_pControlWindow->SetSizePixel( aControlSize ); 254 } 255 256 if ( m_pBrowseButton ) 257 { 258 Point aButtonPos( m_aOutputSize.Width() - 4 - nBrowseButtonSize, m_aLinePos.Y() + 2 ); 259 Size aButtonSize( nBrowseButtonSize, nBrowseButtonSize ); 260 m_pBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize ); 261 262 if ( m_pAdditionalBrowseButton ) 263 { 264 aButtonPos.X() -= nBrowseButtonSize + 4; 265 m_pAdditionalBrowseButton->SetPosSizePixel( aButtonPos, aButtonSize ); 266 } 267 } 268 } 269 270 //------------------------------------------------------------------ 271 void OBrowserLine::SetTitle(const XubString& _rNewTtile ) 272 { 273 if ( GetTitle() == _rNewTtile ) 274 return; 275 // #99102# -------------- 276 m_aFtTitle.SetText( _rNewTtile ); 277 if ( m_pControlWindow ) 278 m_pControlWindow->SetAccessibleName( _rNewTtile ); 279 if ( m_pBrowseButton ) 280 m_pBrowseButton->SetAccessibleName( _rNewTtile ); 281 FullFillTitleString(); 282 } 283 284 // #99102# --------------------------------------------------------- 285 void OBrowserLine::FullFillTitleString() 286 { 287 if( m_pTheParent ) 288 { 289 String aText = m_aFtTitle.GetText(); 290 291 while( m_pTheParent->GetTextWidth( aText ) < m_nNameWidth ) 292 aText.AppendAscii("..........."); 293 294 // for Issue 69452 295 if (Application::GetSettings().GetLayoutRTL()) 296 { 297 sal_Unicode cRTL_mark = 0x200F; 298 aText.Append(cRTL_mark); 299 } 300 301 m_aFtTitle.SetText(aText); 302 } 303 } 304 305 //------------------------------------------------------------------ 306 XubString OBrowserLine::GetTitle() const 307 { 308 String sDisplayName = m_aFtTitle.GetText(); 309 310 // for Issue 69452 311 if (Application::GetSettings().GetLayoutRTL()) 312 { 313 sal_Unicode cRTL_mark = 0x200F; 314 sDisplayName.EraseTrailingChars(cRTL_mark); 315 } 316 317 sDisplayName.EraseTrailingChars( '.' ); 318 319 return sDisplayName; 320 } 321 322 //------------------------------------------------------------------ 323 void OBrowserLine::SetReadOnly( bool _bReadOnly ) 324 { 325 if ( m_bReadOnly != _bReadOnly ) 326 { 327 m_bReadOnly = _bReadOnly; 328 implUpdateEnabledDisabled(); 329 } 330 } 331 332 //------------------------------------------------------------------ 333 namespace 334 { 335 void implSetBitIfAffected( sal_uInt16& _nEnabledBits, sal_Int16 _nAffectedMask, sal_Int16 _nTestBit, bool _bSet ) 336 { 337 if ( _nAffectedMask & _nTestBit ) 338 { 339 if ( _bSet ) 340 _nEnabledBits |= _nTestBit; 341 else 342 _nEnabledBits &= ~_nTestBit; 343 } 344 } 345 346 void implEnable( Window* _pWindow, sal_uInt16 _nEnabledBits, sal_uInt16 _nMatchBits ) 347 { 348 if ( _pWindow ) 349 _pWindow->Enable( ( _nEnabledBits & _nMatchBits ) == _nMatchBits ); 350 } 351 352 void implEnable( Window* _pWindow, bool _bEnable ) 353 { 354 if ( _pWindow ) 355 _pWindow->Enable( _bEnable ); 356 } 357 } 358 359 //------------------------------------------------------------------ 360 void OBrowserLine::implUpdateEnabledDisabled() 361 { 362 implEnable( &m_aFtTitle, m_nEnableFlags, PropertyLineElement::CompleteLine ); 363 if ( m_pControlWindow ) 364 implEnable( m_pControlWindow, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::InputControl ); 365 366 if ( m_bReadOnly ) 367 { 368 implEnable( m_pBrowseButton, false ); 369 implEnable( m_pAdditionalBrowseButton, false ); 370 } 371 else 372 { 373 implEnable( m_pBrowseButton, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::PrimaryButton ); 374 implEnable( m_pAdditionalBrowseButton, m_nEnableFlags, PropertyLineElement::CompleteLine | PropertyLineElement::SecondaryButton ); 375 } 376 } 377 378 //------------------------------------------------------------------ 379 void OBrowserLine::EnablePropertyLine( bool _bEnable ) 380 { 381 implSetBitIfAffected( m_nEnableFlags, PropertyLineElement::CompleteLine, PropertyLineElement::CompleteLine, _bEnable ); 382 implUpdateEnabledDisabled(); 383 } 384 385 //------------------------------------------------------------------ 386 void OBrowserLine::EnablePropertyControls( sal_Int16 _nControls, bool _bEnable ) 387 { 388 implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::InputControl, _bEnable ); 389 implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::PrimaryButton, _bEnable ); 390 implSetBitIfAffected( m_nEnableFlags, _nControls, PropertyLineElement::SecondaryButton, _bEnable ); 391 implUpdateEnabledDisabled(); 392 } 393 394 //------------------------------------------------------------------ 395 PushButton& OBrowserLine::impl_ensureButton( bool _bPrimary ) 396 { 397 PushButton*& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton; 398 399 if ( !rpButton ) 400 { 401 rpButton = new PushButton( m_pTheParent, WB_NOPOINTERFOCUS ); 402 rpButton->SetGetFocusHdl( LINK( this, OBrowserLine, OnButtonFocus ) ); 403 rpButton->SetClickHdl( LINK( this, OBrowserLine, OnButtonClicked ) ); 404 rpButton->SetText( String::CreateFromAscii( "..." ) ); 405 } 406 407 rpButton->Show(); 408 409 impl_layoutComponents(); 410 411 return *rpButton; 412 } 413 414 //------------------------------------------------------------------ 415 void OBrowserLine::impl_getImagesFromURL_nothrow( const ::rtl::OUString& _rImageURL, Image& _out_rImage, Image& _out_rHCImage ) 416 { 417 try 418 { 419 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 420 Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW ); 421 422 Sequence< PropertyValue > aMediaProperties(1); 423 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 424 aMediaProperties[0].Value <<= _rImageURL; 425 426 Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ), UNO_QUERY_THROW ); 427 _out_rImage = _out_rHCImage = Image( xGraphic ); 428 429 // see if we find an HC version beside the normal graphic 430 INetURLObject aURL( _rImageURL ); 431 ::rtl::OUString sBaseName( aURL.getBase() ); 432 aURL.setBase( sBaseName + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_hc" ) ) ); 433 ::rtl::OUString sHCImageURL( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 434 435 Reference< XGraphic > xHCGraphic; 436 try 437 { 438 aMediaProperties[0].Value <<= sHCImageURL; 439 xHCGraphic = xGraphicProvider->queryGraphic( aMediaProperties ); 440 } 441 catch( const Exception& ) { } 442 443 if ( xHCGraphic.is() ) 444 _out_rHCImage = Image( xHCGraphic ); 445 } 446 catch( const Exception& ) 447 { 448 DBG_UNHANDLED_EXCEPTION(); 449 } 450 } 451 452 //------------------------------------------------------------------ 453 void OBrowserLine::ShowBrowseButton( const ::rtl::OUString& _rImageURL, sal_Bool _bPrimary ) 454 { 455 PushButton& rButton( impl_ensureButton( _bPrimary ) ); 456 457 OSL_PRECOND( _rImageURL.getLength(), "OBrowserLine::ShowBrowseButton: use the other version if you don't have an image!" ); 458 Image aImage, aHCImage; 459 impl_getImagesFromURL_nothrow( _rImageURL, aImage, aHCImage ); 460 461 rButton.SetModeImage( aImage, BMP_COLOR_NORMAL ); 462 rButton.SetModeImage( aHCImage, BMP_COLOR_HIGHCONTRAST ); 463 } 464 465 //------------------------------------------------------------------ 466 void OBrowserLine::ShowBrowseButton( const Image& _rImage, sal_Bool _bPrimary ) 467 { 468 PushButton& rButton( impl_ensureButton( _bPrimary ) ); 469 if ( !!_rImage ) 470 rButton.SetModeImage( _rImage ); 471 } 472 473 //------------------------------------------------------------------ 474 void OBrowserLine::ShowBrowseButton( sal_Bool _bPrimary ) 475 { 476 impl_ensureButton( _bPrimary ); 477 } 478 479 //------------------------------------------------------------------ 480 void OBrowserLine::implHideBrowseButton( sal_Bool _bPrimary, bool _bReLayout ) 481 { 482 PushButton*& rpButton = _bPrimary ? m_pBrowseButton : m_pAdditionalBrowseButton; 483 484 if ( rpButton ) 485 { 486 rpButton->Hide(); 487 delete rpButton; 488 rpButton = NULL; 489 } 490 491 if ( _bReLayout ) 492 impl_layoutComponents(); 493 } 494 495 //------------------------------------------------------------------ 496 void OBrowserLine::HideBrowseButton( sal_Bool _bPrimary ) 497 { 498 implHideBrowseButton( _bPrimary, true ); 499 } 500 501 //------------------------------------------------------------------ 502 void OBrowserLine::SetTitleWidth(sal_uInt16 nWidth) 503 { 504 if (m_nNameWidth != nWidth+10) 505 { 506 m_nNameWidth = nWidth+10; 507 impl_layoutComponents(); 508 } 509 // #99102# --------- 510 FullFillTitleString(); 511 } 512 513 //------------------------------------------------------------------ 514 void OBrowserLine::SetClickListener( IButtonClickListener* _pListener ) 515 { 516 m_pClickListener = _pListener; 517 } 518 519 //------------------------------------------------------------------ 520 IMPL_LINK( OBrowserLine, OnButtonClicked, PushButton*, _pButton ) 521 { 522 if ( m_pClickListener ) 523 m_pClickListener->buttonClicked( this, _pButton == m_pBrowseButton ); 524 525 return 0L; 526 } 527 528 //------------------------------------------------------------------ 529 IMPL_LINK( OBrowserLine, OnButtonFocus, PushButton*, /*pPB*/ ) 530 { 531 if ( m_xControl.is() ) 532 { 533 try 534 { 535 Reference< XPropertyControlContext > xContext( m_xControl->getControlContext(), UNO_QUERY_THROW ); 536 xContext->focusGained( m_xControl ); 537 } 538 catch( const Exception& ) 539 { 540 DBG_UNHANDLED_EXCEPTION(); 541 } 542 } 543 return 0; 544 } 545 //............................................................................ 546 } // namespace pcr 547 //............................................................................ 548 549