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 "propertyeditor.hxx" 31 #include "browserpage.hxx" 32 #include "linedescriptor.hxx" 33 34 /** === begin UNO includes === **/ 35 /** === end UNO includes === **/ 36 #include <tools/debug.hxx> 37 38 //............................................................................ 39 namespace pcr 40 { 41 //............................................................................ 42 43 #define LAYOUT_BORDER_LEFT 3 44 #define LAYOUT_BORDER_TOP 3 45 #define LAYOUT_BORDER_RIGHT 3 46 #define LAYOUT_BORDER_BOTTOM 3 47 48 /** === begin UNO using === **/ 49 using ::com::sun::star::uno::Any; 50 using ::com::sun::star::inspection::XPropertyControl; 51 using ::com::sun::star::uno::Reference; 52 /** === end UNO using === **/ 53 54 //================================================================== 55 // class OPropertyEditor 56 //================================================================== 57 DBG_NAME(OPropertyEditor) 58 //------------------------------------------------------------------ 59 OPropertyEditor::OPropertyEditor( Window* pParent, WinBits nWinStyle) 60 :Control(pParent, nWinStyle) 61 ,m_aTabControl( this ) 62 ,m_nNextId(1) 63 ,m_bHasHelpSection( false ) 64 ,m_nMinHelpLines( 0 ) 65 ,m_nMaxHelpLines( 0 ) 66 { 67 DBG_CTOR(OPropertyEditor,NULL); 68 69 m_aTabControl.Show(); 70 m_aTabControl.SetDeactivatePageHdl(LINK(this, OPropertyEditor, OnPageDeactivate)); 71 m_aTabControl.SetActivatePageHdl(LINK(this, OPropertyEditor, OnPageActivate)); 72 m_aTabControl.SetBackground(GetBackground()); 73 m_aTabControl.SetPaintTransparent(sal_True); 74 } 75 76 //------------------------------------------------------------------ 77 OPropertyEditor::~OPropertyEditor() 78 { 79 Hide(); 80 ClearAll(); 81 DBG_DTOR(OPropertyEditor,NULL); 82 } 83 84 //------------------------------------------------------------------ 85 void OPropertyEditor::ClearAll() 86 { 87 m_nNextId=1; 88 sal_uInt16 nCount = m_aTabControl.GetPageCount(); 89 for(long i = nCount-1; i >= 0; --i) 90 { 91 sal_uInt16 nID = m_aTabControl.GetPageId((sal_uInt16)i); 92 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID)); 93 if (pPage) 94 { 95 pPage->EnableInput(sal_False); 96 m_aTabControl.RemovePage(nID); 97 delete pPage; 98 } 99 } 100 m_aTabControl.Clear(); 101 102 { 103 MapStringToPageId aEmpty; 104 m_aPropertyPageIds.swap( aEmpty ); 105 } 106 107 while ( !m_aHiddenPages.empty() ) 108 { 109 delete m_aHiddenPages.begin()->second.pPage; 110 m_aHiddenPages.erase( m_aHiddenPages.begin() ); 111 } 112 } 113 114 //------------------------------------------------------------------ 115 sal_Int32 OPropertyEditor::getMinimumHeight() 116 { 117 sal_Int32 nMinHeight( LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM ); 118 119 if ( m_aTabControl.GetPageCount() > 0 ) 120 { 121 sal_uInt16 nFirstID = m_aTabControl.GetPageId( 0 ); 122 123 // reserve space for the tabs themself 124 Rectangle aTabArea( m_aTabControl.GetTabBounds( nFirstID ) ); 125 nMinHeight += aTabArea.GetHeight(); 126 127 // ask the page how much it requires 128 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nFirstID ) ); 129 if ( pPage ) 130 nMinHeight += pPage->getMinimumHeight(); 131 } 132 else 133 nMinHeight += 250; // arbitrary ... 134 135 return nMinHeight; 136 } 137 138 //------------------------------------------------------------------ 139 sal_Int32 OPropertyEditor::getMinimumWidth() 140 { 141 sal_uInt16 nCount = m_aTabControl.GetPageCount(); 142 sal_Int32 nPageMinWidth = 0; 143 for(long i = nCount-1; i >= 0; --i) 144 { 145 sal_uInt16 nID = m_aTabControl.GetPageId((sal_uInt16)i); 146 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID)); 147 if (pPage) 148 { 149 sal_Int32 nCurPageMinWidth = pPage->getMinimumWidth(); 150 if( nCurPageMinWidth > nPageMinWidth ) 151 nPageMinWidth = nCurPageMinWidth; 152 } 153 } 154 return nPageMinWidth+6; 155 } 156 157 //------------------------------------------------------------------ 158 void OPropertyEditor::CommitModified() 159 { 160 // commit all of my pages, if necessary 161 162 sal_uInt16 nCount = m_aTabControl.GetPageCount(); 163 for ( sal_uInt16 i=0; i<nCount; ++i ) 164 { 165 sal_uInt16 nID = m_aTabControl.GetPageId( i ); 166 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nID ) ); 167 168 if ( pPage && pPage->getListBox().IsModified() ) 169 pPage->getListBox().CommitModified(); 170 } 171 } 172 173 //------------------------------------------------------------------ 174 void OPropertyEditor::GetFocus() 175 { 176 m_aTabControl.GrabFocus(); 177 } 178 179 //------------------------------------------------------------------ 180 OBrowserPage* OPropertyEditor::getPage( const ::rtl::OUString& _rPropertyName ) 181 { 182 OBrowserPage* pPage = NULL; 183 MapStringToPageId::const_iterator aPropertyPageIdPos = m_aPropertyPageIds.find( _rPropertyName ); 184 if ( aPropertyPageIdPos != m_aPropertyPageIds.end() ) 185 pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( aPropertyPageIdPos->second ) ); 186 return pPage; 187 } 188 189 //------------------------------------------------------------------ 190 const OBrowserPage* OPropertyEditor::getPage( const ::rtl::OUString& _rPropertyName ) const 191 { 192 return const_cast< OPropertyEditor* >( this )->getPage( _rPropertyName ); 193 } 194 195 //------------------------------------------------------------------ 196 OBrowserPage* OPropertyEditor::getPage( sal_uInt16& _rPageId ) 197 { 198 return static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( _rPageId ) ); 199 } 200 201 //------------------------------------------------------------------ 202 const OBrowserPage* OPropertyEditor::getPage( sal_uInt16& _rPageId ) const 203 { 204 return const_cast< OPropertyEditor* >( this )->getPage( _rPageId ); 205 } 206 207 //------------------------------------------------------------------ 208 void OPropertyEditor::Resize() 209 { 210 Rectangle aPlayground( 211 Point( LAYOUT_BORDER_LEFT, LAYOUT_BORDER_TOP ), 212 Size( 213 GetOutputSizePixel().Width() - LAYOUT_BORDER_LEFT - LAYOUT_BORDER_RIGHT, 214 GetOutputSizePixel().Height() - LAYOUT_BORDER_TOP - LAYOUT_BORDER_BOTTOM 215 ) 216 ); 217 218 Rectangle aTabArea( aPlayground ); 219 m_aTabControl.SetPosSizePixel( aTabArea.TopLeft(), aTabArea.GetSize() ); 220 } 221 222 //------------------------------------------------------------------ 223 sal_uInt16 OPropertyEditor::AppendPage( const String & _rText, const rtl::OString& _rHelpId ) 224 { 225 // obtain a new id 226 sal_uInt16 nId = m_nNextId++; 227 // insert the id 228 m_aTabControl.InsertPage(nId, _rText); 229 230 // create a new page 231 OBrowserPage* pPage = new OBrowserPage(&m_aTabControl); 232 pPage->SetText( _rText ); 233 // some knittings 234 pPage->SetSizePixel(m_aTabControl.GetTabPageSizePixel()); 235 pPage->getListBox().SetListener(m_pListener); 236 pPage->getListBox().SetObserver(m_pObserver); 237 pPage->getListBox().EnableHelpSection( m_bHasHelpSection ); 238 pPage->getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines ); 239 pPage->SetHelpId( _rHelpId ); 240 241 // immediately activate the page 242 m_aTabControl.SetTabPage(nId, pPage); 243 m_aTabControl.SetCurPageId(nId); 244 245 return nId; 246 } 247 248 //------------------------------------------------------------------ 249 void OPropertyEditor::SetHelpId( const rtl::OString& rHelpId ) 250 { 251 Control::SetHelpId(""); 252 m_aTabControl.SetHelpId(rHelpId); 253 } 254 255 //------------------------------------------------------------------ 256 void OPropertyEditor::RemovePage(sal_uInt16 nID) 257 { 258 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID)); 259 260 if (pPage) 261 pPage->EnableInput(sal_False); 262 m_aTabControl.RemovePage(nID); 263 if (pPage) 264 delete pPage; 265 } 266 267 //------------------------------------------------------------------ 268 void OPropertyEditor::SetPage(sal_uInt16 nId) 269 { 270 m_aTabControl.SetCurPageId(nId); 271 } 272 273 //------------------------------------------------------------------ 274 sal_uInt16 OPropertyEditor::GetCurPage() 275 { 276 if(m_aTabControl.GetPageCount()>0) 277 return m_aTabControl.GetCurPageId(); 278 else 279 return 0; 280 } 281 282 //------------------------------------------------------------------ 283 void OPropertyEditor::Update(const ::std::mem_fun_t<void,OBrowserListBox>& _aUpdateFunction) 284 { 285 // forward this to all our pages 286 sal_uInt16 nCount = m_aTabControl.GetPageCount(); 287 for (sal_uInt16 i=0;i<nCount;++i) 288 { 289 sal_uInt16 nID = m_aTabControl.GetPageId(i); 290 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID)); 291 if (pPage) 292 _aUpdateFunction(&pPage->getListBox()); 293 } 294 } 295 //------------------------------------------------------------------ 296 void OPropertyEditor::EnableUpdate() 297 { 298 Update(::std::mem_fun(&OBrowserListBox::EnableUpdate)); 299 } 300 //------------------------------------------------------------------ 301 void OPropertyEditor::DisableUpdate() 302 { 303 Update(::std::mem_fun(&OBrowserListBox::DisableUpdate)); 304 } 305 306 //------------------------------------------------------------------ 307 void OPropertyEditor::forEachPage( PageOperation _pOperation, const void* _pArgument ) 308 { 309 sal_uInt16 nCount = m_aTabControl.GetPageCount(); 310 for ( sal_uInt16 i=0; i<nCount; ++i ) 311 { 312 sal_uInt16 nID = m_aTabControl.GetPageId(i); 313 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nID ) ); 314 if ( !pPage ) 315 continue; 316 (this->*_pOperation)( *pPage, _pArgument ); 317 } 318 } 319 320 //------------------------------------------------------------------ 321 void OPropertyEditor::setPageLineListener( OBrowserPage& _rPage, const void* ) 322 { 323 _rPage.getListBox().SetListener( m_pListener ); 324 } 325 326 //------------------------------------------------------------------ 327 void OPropertyEditor::SetLineListener(IPropertyLineListener* _pListener) 328 { 329 m_pListener = _pListener; 330 forEachPage( &OPropertyEditor::setPageLineListener ); 331 } 332 333 //------------------------------------------------------------------ 334 void OPropertyEditor::setPageControlObserver( OBrowserPage& _rPage, const void* ) 335 { 336 _rPage.getListBox().SetObserver( m_pObserver ); 337 } 338 339 //------------------------------------------------------------------ 340 void OPropertyEditor::SetControlObserver( IPropertyControlObserver* _pObserver ) 341 { 342 m_pObserver = _pObserver; 343 forEachPage( &OPropertyEditor::setPageControlObserver ); 344 } 345 346 //------------------------------------------------------------------ 347 void OPropertyEditor::EnableHelpSection( bool _bEnable ) 348 { 349 m_bHasHelpSection = _bEnable; 350 forEachPage( &OPropertyEditor::enableHelpSection ); 351 } 352 353 //------------------------------------------------------------------ 354 bool OPropertyEditor::HasHelpSection() const 355 { 356 return m_bHasHelpSection; 357 } 358 359 //------------------------------------------------------------------ 360 void OPropertyEditor::SetHelpText( const ::rtl::OUString& _rHelpText ) 361 { 362 forEachPage( &OPropertyEditor::setHelpSectionText, &_rHelpText ); 363 } 364 365 //------------------------------------------------------------------ 366 void OPropertyEditor::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines ) 367 { 368 m_nMinHelpLines = _nMinLines; 369 m_nMaxHelpLines = _nMaxLines; 370 forEachPage( &OPropertyEditor::setHelpLineLimits ); 371 } 372 373 //------------------------------------------------------------------ 374 void OPropertyEditor::enableHelpSection( OBrowserPage& _rPage, const void* ) 375 { 376 _rPage.getListBox().EnableHelpSection( m_bHasHelpSection ); 377 } 378 379 //------------------------------------------------------------------ 380 void OPropertyEditor::setHelpSectionText( OBrowserPage& _rPage, const void* _pPointerToOUString ) 381 { 382 OSL_ENSURE( _pPointerToOUString, "OPropertyEditor::setHelpSectionText: invalid argument!" ); 383 if ( !_pPointerToOUString ) 384 return; 385 386 const ::rtl::OUString& rText( *(const ::rtl::OUString*)_pPointerToOUString ); 387 _rPage.getListBox().SetHelpText( rText ); 388 } 389 390 //------------------------------------------------------------------ 391 void OPropertyEditor::setHelpLineLimits( OBrowserPage& _rPage, const void* ) 392 { 393 _rPage.getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines ); 394 } 395 396 //------------------------------------------------------------------ 397 sal_uInt16 OPropertyEditor::InsertEntry( const OLineDescriptor& rData, sal_uInt16 _nPageId, sal_uInt16 nPos ) 398 { 399 // let the current page handle this 400 OBrowserPage* pPage = getPage( _nPageId ); 401 DBG_ASSERT( pPage, "OPropertyEditor::InsertEntry: don't have such a page!" ); 402 if ( !pPage ) 403 return LISTBOX_ENTRY_NOTFOUND; 404 405 sal_uInt16 nEntry = pPage->getListBox().InsertEntry( rData, nPos ); 406 407 OSL_ENSURE( m_aPropertyPageIds.find( rData.sName ) == m_aPropertyPageIds.end(), 408 "OPropertyEditor::InsertEntry: property already present in the map!" ); 409 m_aPropertyPageIds.insert( MapStringToPageId::value_type( rData.sName, _nPageId ) ); 410 411 return nEntry; 412 } 413 414 //------------------------------------------------------------------ 415 void OPropertyEditor::RemoveEntry( const ::rtl::OUString& _rName ) 416 { 417 OBrowserPage* pPage = getPage( _rName ); 418 if ( pPage ) 419 { 420 OSL_VERIFY( pPage->getListBox().RemoveEntry( _rName ) ); 421 422 OSL_ENSURE( m_aPropertyPageIds.find( _rName ) != m_aPropertyPageIds.end(), 423 "OPropertyEditor::RemoveEntry: property not present in the map!" ); 424 m_aPropertyPageIds.erase( _rName ); 425 } 426 } 427 428 //------------------------------------------------------------------ 429 void OPropertyEditor::ChangeEntry( const OLineDescriptor& rData ) 430 { 431 OBrowserPage* pPage = getPage( rData.sName ); 432 if ( pPage ) 433 pPage->getListBox().ChangeEntry( rData, EDITOR_LIST_REPLACE_EXISTING ); 434 } 435 436 //------------------------------------------------------------------ 437 void OPropertyEditor::SetPropertyValue( const ::rtl::OUString& rEntryName, const Any& _rValue, bool _bUnknownValue ) 438 { 439 OBrowserPage* pPage = getPage( rEntryName ); 440 if ( pPage ) 441 pPage->getListBox().SetPropertyValue( rEntryName, _rValue, _bUnknownValue ); 442 } 443 444 //------------------------------------------------------------------ 445 sal_uInt16 OPropertyEditor::GetPropertyPos( const ::rtl::OUString& rEntryName ) const 446 { 447 sal_uInt16 nVal=LISTBOX_ENTRY_NOTFOUND; 448 const OBrowserPage* pPage = getPage( rEntryName ); 449 if ( pPage ) 450 nVal = pPage->getListBox().GetPropertyPos( rEntryName ); 451 return nVal; 452 } 453 454 //------------------------------------------------------------------ 455 void OPropertyEditor::ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow ) 456 { 457 if ( !_bShow ) 458 { 459 sal_uInt16 nPagePos = m_aTabControl.GetPagePos( _nPageId ); 460 if ( TAB_PAGE_NOTFOUND == nPagePos ) 461 return; 462 DBG_ASSERT( m_aHiddenPages.find( _nPageId ) == m_aHiddenPages.end(), "OPropertyEditor::ShowPropertyPage: page already hidden!" ); 463 464 m_aHiddenPages[ _nPageId ] = HiddenPage( nPagePos, m_aTabControl.GetTabPage( _nPageId ) ); 465 m_aTabControl.RemovePage( _nPageId ); 466 } 467 else 468 { 469 ::std::map< sal_uInt16, HiddenPage >::iterator aPagePos = m_aHiddenPages.find( _nPageId ); 470 if ( aPagePos == m_aHiddenPages.end() ) 471 return; 472 473 aPagePos->second.pPage->SetSizePixel( m_aTabControl.GetTabPageSizePixel() ); 474 m_aTabControl.InsertPage( aPagePos->first, aPagePos->second.pPage->GetText(), aPagePos->second.nPos ); 475 m_aTabControl.SetTabPage( aPagePos->first, aPagePos->second.pPage ); 476 477 m_aHiddenPages.erase( aPagePos ); 478 } 479 } 480 481 //------------------------------------------------------------------ 482 void OPropertyEditor::EnablePropertyControls( const ::rtl::OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable ) 483 { 484 for ( sal_uInt16 i = 0; i < m_aTabControl.GetPageCount(); ++i ) 485 { 486 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( m_aTabControl.GetPageId( i ) ) ); 487 if ( pPage ) 488 pPage->getListBox().EnablePropertyControls( _rEntryName, _nControls, _bEnable ); 489 } 490 } 491 492 //------------------------------------------------------------------ 493 void OPropertyEditor::EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable ) 494 { 495 for ( sal_uInt16 i = 0; i < m_aTabControl.GetPageCount(); ++i ) 496 { 497 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( m_aTabControl.GetPageId( i ) ) ); 498 if ( pPage ) 499 pPage->getListBox().EnablePropertyLine( _rEntryName, _bEnable ); 500 } 501 } 502 503 //------------------------------------------------------------------ 504 Reference< XPropertyControl > OPropertyEditor::GetPropertyControl(const ::rtl::OUString& rEntryName) 505 { 506 Reference< XPropertyControl > xControl; 507 // let the current page handle this 508 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(m_aTabControl.GetCurPageId())); 509 if (pPage) 510 xControl = pPage->getListBox().GetPropertyControl(rEntryName); 511 return xControl; 512 } 513 514 //------------------------------------------------------------------ 515 IMPL_LINK(OPropertyEditor, OnPageActivate, TabControl*, EMPTYARG) 516 { 517 if (m_aPageActivationHandler.IsSet()) 518 m_aPageActivationHandler.Call(NULL); 519 return 0L; 520 } 521 522 //------------------------------------------------------------------ 523 IMPL_LINK(OPropertyEditor, OnPageDeactivate, TabControl*, EMPTYARG) 524 { 525 // commit the data on the current (to-be-decativated) tab page 526 // (79404) 527 sal_Int32 nCurrentId = m_aTabControl.GetCurPageId(); 528 OBrowserPage* pCurrentPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage((sal_uInt16)nCurrentId)); 529 if ( !pCurrentPage ) 530 return 1L; 531 532 if ( pCurrentPage->getListBox().IsModified() ) 533 pCurrentPage->getListBox().CommitModified(); 534 535 return 1L; 536 } 537 538 //............................................................................ 539 } // namespace pcr 540 //............................................................................ 541 542 543