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_svtools.hxx" 30 #include <svtools/roadmap.hxx> 31 32 #ifndef _STRING_HXX 33 #define _STRING_HXX 34 #endif 35 36 #include <vector> 37 #include <algorithm> 38 #include <vcl/bitmap.hxx> 39 #include <tools/color.hxx> 40 #include <memory> 41 42 #define ROADMAP_INDENT_X 4 43 #define ROADMAP_INDENT_Y 27 44 #define ROADMAP_ITEM_DISTANCE_Y 6 45 #define RMINCOMPLETE -1 46 #define NADDITEM 1 47 #define INCOMPLETELABEL ::String::CreateFromAscii("...") // TODO: Cast to String 48 49 //......................................................................... 50 namespace svt 51 { 52 //......................................................................... 53 54 typedef std::vector< ::rtl::OUString > S_Vector; 55 typedef std::vector< RoadmapItem* > HL_Vector; 56 57 //===================================================================== 58 //= ColorChanger 59 //===================================================================== 60 class IDLabel : public FixedText 61 { 62 public: 63 IDLabel( Window* _pParent, WinBits _nWinStyle = 0 ); 64 ~IDLabel( ); 65 virtual void DataChanged( const DataChangedEvent& rDCEvt ); 66 }; 67 68 //===================================================================== 69 //= ColorChanger 70 //===================================================================== 71 class ColorChanger 72 { 73 protected: 74 OutputDevice* m_pDev; 75 76 public: 77 ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor ) 78 :m_pDev( _pDev ) 79 { 80 m_pDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 81 m_pDev->SetLineColor( _rNewLineColor ); 82 m_pDev->SetFillColor( _rNewFillColor ); 83 } 84 85 ~ColorChanger() 86 { 87 m_pDev->Pop(); 88 } 89 }; 90 91 //===================================================================== 92 //= RoadmapItem 93 //===================================================================== 94 class RoadmapItem : public RoadmapTypes 95 { 96 private: 97 IDLabel* mpID; 98 HyperLabel* mpDescription; 99 const Size m_aItemPlayground; 100 101 public: 102 RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground ); 103 ~RoadmapItem( ); 104 105 void SetID( sal_Int16 _ID ); 106 sal_Int16 GetID() const; 107 108 void SetIndex( ItemIndex _Index ); 109 ItemIndex GetIndex() const; 110 111 void SetLabel( const ::rtl::OUString& _rText ); 112 ::rtl::OUString GetLabel( ); 113 114 void Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText ); 115 116 void SetPosition( RoadmapItem* OldHyperLabel ); 117 118 void ToggleBackgroundColor( const Color& _rGBColor ); 119 void SetInteractive( sal_Bool _bInteractive ); 120 121 void SetClickHdl( const Link& rLink ); 122 const Link& GetClickHdl() const; 123 void SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, sal_uInt16 nFlags ); 124 void Enable( sal_Bool bEnable = sal_True); 125 sal_Bool IsEnabled() const; 126 void GrabFocus(); 127 128 bool Contains( const Window* _pWindow ) const; 129 130 HyperLabel* GetDescriptionHyperLabel() const { return mpDescription; } 131 132 private: 133 void ImplUpdateIndex( const ItemIndex _nIndex ); 134 void ImplUpdatePosSize(); 135 }; 136 137 //===================================================================== 138 //= RoadmapImpl 139 //===================================================================== 140 class RoadmapImpl : public RoadmapTypes 141 { 142 protected: 143 const ORoadmap& m_rAntiImpl; 144 Link m_aSelectHdl; 145 BitmapEx m_aPicture; 146 HL_Vector m_aRoadmapSteps; 147 ItemId m_iCurItemID; 148 sal_Bool m_bInteractive; 149 sal_Bool m_bComplete; 150 Size m_aItemSizePixel; 151 152 public: 153 RoadmapImpl( const ORoadmap& _rAntiImpl ) 154 :m_rAntiImpl( _rAntiImpl ) 155 ,m_iCurItemID( -1 ) 156 ,m_bInteractive( sal_True ) 157 ,m_bComplete( sal_True ) 158 { 159 } 160 161 RoadmapItem* InCompleteHyperLabel; 162 163 void addHyperLabel( RoadmapItem* _rRoadmapStep ) { m_aRoadmapSteps.push_back(_rRoadmapStep); } 164 165 HL_Vector& getHyperLabels() { return m_aRoadmapSteps; } 166 const HL_Vector& getHyperLabels() const { return m_aRoadmapSteps; } 167 168 void insertHyperLabel( ItemIndex _Index, RoadmapItem* _rRoadmapStep ) { m_aRoadmapSteps.insert( m_aRoadmapSteps.begin() + _Index, _rRoadmapStep ); } 169 170 ItemIndex getItemCount() const { return m_aRoadmapSteps.size();} 171 172 void setCurItemID( ItemId i ) {m_iCurItemID = i; } 173 ItemId getCurItemID() const { return m_iCurItemID; } 174 175 void setInteractive(const sal_Bool _bInteractive) {m_bInteractive = _bInteractive; } 176 sal_Bool isInteractive() const { return m_bInteractive; }; 177 178 void setComplete(const sal_Bool _bComplete) {m_bComplete = _bComplete; } 179 sal_Bool isComplete() const { return m_bComplete; }; 180 181 void setPicture( const BitmapEx& _rPic ) { m_aPicture = _rPic; } 182 const BitmapEx& getPicture( ) const { return m_aPicture; } 183 184 void setSelectHdl( const Link& _rHdl ) { m_aSelectHdl = _rHdl; } 185 const Link& getSelectHdl( ) const { return m_aSelectHdl; } 186 187 void initItemSize(); 188 const Size& getItemSize() const { return m_aItemSizePixel; } 189 190 void removeHyperLabel( ItemIndex _Index ) 191 { 192 if ( ( _Index > -1 ) && ( _Index < getItemCount() ) ) 193 { 194 delete m_aRoadmapSteps[_Index]; 195 m_aRoadmapSteps.erase( m_aRoadmapSteps.begin() + _Index); 196 } 197 } 198 }; 199 200 201 //===================================================================== 202 //= Roadmap 203 //===================================================================== 204 //--------------------------------------------------------------------- 205 void RoadmapImpl::initItemSize() 206 { 207 Size aLabelSize( m_rAntiImpl.GetOutputSizePixel() ); 208 aLabelSize.Height() = m_rAntiImpl.LogicToPixel( Size( 0, LABELBASEMAPHEIGHT ), MAP_APPFONT ).Height(); 209 aLabelSize.Width() -= m_rAntiImpl.LogicToPixel( Size( 2 * ROADMAP_INDENT_X, 0 ), MAP_APPFONT ).Width(); 210 m_aItemSizePixel = aLabelSize; 211 } 212 213 //===================================================================== 214 //= Roadmap 215 //===================================================================== 216 //--------------------------------------------------------------------- 217 ORoadmap::ORoadmap( Window* _pParent, const ResId& _rId ) 218 :Control( _pParent, _rId ) 219 ,m_pImpl( new RoadmapImpl( *this ) ) 220 { 221 implInit(); 222 } 223 224 //--------------------------------------------------------------------- 225 ORoadmap::ORoadmap( Window* _pParent, WinBits _nWinStyle ) 226 :Control( _pParent, _nWinStyle ) 227 ,m_pImpl( new RoadmapImpl( *this ) ) 228 229 { 230 implInit(); 231 } 232 233 //--------------------------------------------------------------------- 234 void ORoadmap::implInit() 235 { 236 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 237 Color aTextColor = rStyleSettings.GetFieldTextColor(); 238 Font aFont = GetFont( ); 239 aFont.SetColor( aTextColor ); 240 aFont.SetWeight( WEIGHT_BOLD ); 241 aFont.SetUnderline( UNDERLINE_SINGLE ); 242 SetFont( aFont ); 243 SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) ); 244 m_pImpl->InCompleteHyperLabel = NULL; 245 m_pImpl->setCurItemID(-1 ); 246 m_pImpl->setComplete( sal_True ); 247 248 // Roadmap control should be reachable as one unit with a Tab key 249 // the next Tab key should spring out of the control. 250 // To reach it the control itself should get focus and set it 251 // on entries. The entries themself should not be reachable with 252 // the Tab key directly. So each entry should have WB_NOTABSTOP. 253 // 254 // In other words the creator should create the control with the following 255 // flags: 256 // SetStyle( ( GetStyle() | WB_TABSTOP ) & ~WB_DIALOGCONTROL ); 257 258 // TODO: if somebody sets a new font from outside (OutputDevice::SetFont), we would have to react 259 // on this with calculating a new bold font. 260 // Unfortunately, the OutputDevice does not offer a notify mechanism for a changed font. 261 // So settings the font from outside is simply a forbidded scenario at the moment 262 EnableMapMode( sal_False ); 263 } 264 265 //--------------------------------------------------------------------- 266 ORoadmap::~ORoadmap( ) 267 { 268 HL_Vector aItemsCopy = m_pImpl->getHyperLabels(); 269 m_pImpl->getHyperLabels().clear(); 270 for ( HL_Vector::iterator i = aItemsCopy.begin(); i< aItemsCopy.end(); ++i ) 271 { 272 delete *i; 273 } 274 if ( ! m_pImpl->isComplete() ) 275 delete m_pImpl->InCompleteHyperLabel; 276 delete m_pImpl; 277 m_pImpl = NULL; 278 } 279 280 281 RoadmapTypes::ItemId ORoadmap::GetCurrentRoadmapItemID() const 282 { 283 return m_pImpl->getCurItemID(); 284 } 285 286 287 RoadmapItem* ORoadmap::GetPreviousHyperLabel( ItemIndex _Index) 288 { 289 RoadmapItem* pOldItem = NULL; 290 if ( _Index > 0 ) 291 pOldItem = m_pImpl->getHyperLabels().at( _Index - 1 ); 292 return pOldItem; 293 } 294 295 296 //--------------------------------------------------------------------- 297 298 RoadmapItem* ORoadmap::InsertHyperLabel( ItemIndex _Index, const ::rtl::OUString& _sLabel, ItemId _RMID, sal_Bool _bEnabled) 299 { 300 if ( m_pImpl->getItemCount() == 0 ) 301 m_pImpl->initItemSize(); 302 303 RoadmapItem* pItem = NULL; 304 RoadmapItem* pOldItem = GetPreviousHyperLabel( _Index ); 305 306 pItem = new RoadmapItem( *this, m_pImpl->getItemSize() ); 307 if ( _RMID != RMINCOMPLETE ) 308 { 309 pItem->SetInteractive( m_pImpl->isInteractive() ); 310 m_pImpl->insertHyperLabel( _Index, pItem ); 311 } 312 else 313 { 314 pItem->SetInteractive( sal_False ); 315 } 316 pItem->SetPosition( pOldItem ); 317 pItem->Update( _Index, _sLabel ); 318 pItem->SetClickHdl(LINK( this, ORoadmap, ImplClickHdl ) ); 319 pItem->SetID( _RMID ); 320 pItem->SetIndex( _Index ); 321 if (!_bEnabled) 322 pItem->Enable( _bEnabled ); 323 return pItem; 324 } 325 326 //--------------------------------------------------------------------- 327 void ORoadmap::SetRoadmapBitmap( const BitmapEx& _rBmp, sal_Bool _bInvalidate ) 328 { 329 m_pImpl->setPicture( _rBmp ); 330 if ( _bInvalidate ) 331 Invalidate( ); 332 } 333 334 //--------------------------------------------------------------------- 335 const BitmapEx& ORoadmap::GetRoadmapBitmap( ) const 336 { 337 return m_pImpl->getPicture( ); 338 } 339 340 //--------------------------------------------------------------------- 341 void ORoadmap::SetRoadmapInteractive( sal_Bool _bInteractive ) 342 { 343 m_pImpl->setInteractive( _bInteractive ); 344 345 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 346 for ( HL_Vector::const_iterator i = rItems.begin(); 347 i < rItems.end(); 348 ++i 349 ) 350 { 351 (*i)->SetInteractive( _bInteractive ); 352 } 353 } 354 355 //--------------------------------------------------------------------- 356 sal_Bool ORoadmap::IsRoadmapInteractive() 357 { 358 return m_pImpl->isInteractive(); 359 } 360 361 //--------------------------------------------------------------------- 362 void ORoadmap::SetRoadmapComplete( sal_Bool _bComplete ) 363 { 364 sal_Bool bWasComplete = m_pImpl->isComplete(); 365 m_pImpl->setComplete( _bComplete ); 366 if ( _bComplete ) 367 { 368 if ( m_pImpl->InCompleteHyperLabel != NULL) 369 { 370 delete m_pImpl->InCompleteHyperLabel; 371 m_pImpl->InCompleteHyperLabel = NULL; 372 } 373 } 374 else if ( bWasComplete ) 375 m_pImpl->InCompleteHyperLabel = InsertHyperLabel( m_pImpl->getItemCount(), ::String::CreateFromAscii( "..." ), RMINCOMPLETE ); 376 } 377 378 //--------------------------------------------------------------------- 379 void ORoadmap::UpdatefollowingHyperLabels( ItemIndex _nIndex ) 380 { 381 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 382 if ( _nIndex < (ItemIndex)rItems.size() ) 383 { 384 RoadmapItem* pItem = NULL; 385 for ( HL_Vector::const_iterator i = rItems.begin() + _nIndex; 386 i< rItems.end(); 387 ++i, ++_nIndex 388 ) 389 { 390 pItem = *i; 391 392 pItem->SetIndex( _nIndex ); 393 pItem->SetPosition( GetPreviousHyperLabel( _nIndex ) ); 394 } 395 } 396 if ( ! m_pImpl->isComplete() ) 397 { 398 RoadmapItem* pOldItem = GetPreviousHyperLabel( m_pImpl->getItemCount() ); 399 m_pImpl->InCompleteHyperLabel->SetPosition( pOldItem ); 400 m_pImpl->InCompleteHyperLabel->Update( m_pImpl->getItemCount(), ::String::CreateFromAscii("...") ); 401 } 402 } 403 404 //--------------------------------------------------------------------- 405 void ORoadmap::ReplaceRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _RMID, sal_Bool _bEnabled ) 406 { 407 RoadmapItem* pItem = GetByIndex( _Index); 408 if ( pItem != NULL ) 409 { 410 pItem->Update( _Index, _RoadmapItem ); 411 pItem->SetID( _RMID ); 412 pItem->Enable( _bEnabled ); 413 } 414 } 415 416 //--------------------------------------------------------------------- 417 RoadmapTypes::ItemIndex ORoadmap::GetItemCount() const 418 { 419 return m_pImpl->getItemCount(); 420 } 421 422 //--------------------------------------------------------------------- 423 RoadmapTypes::ItemId ORoadmap::GetItemID( ItemIndex _nIndex ) const 424 { 425 const RoadmapItem* pHyperLabel = GetByIndex( _nIndex ); 426 if ( pHyperLabel ) 427 return pHyperLabel->GetID(); 428 return -1; 429 } 430 431 //--------------------------------------------------------------------- 432 RoadmapTypes::ItemIndex ORoadmap::GetItemIndex( ItemId _nID ) const 433 { 434 ItemId nLocID = 0; 435 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 436 for ( HL_Vector::const_iterator i = rItems.begin(); 437 i < rItems.end(); 438 ++i 439 ) 440 { 441 nLocID = (*i)->GetID(); 442 if ( nLocID == _nID ) 443 return ItemIndex( i - rItems.begin() ); 444 } 445 return -1; 446 } 447 448 //--------------------------------------------------------------------- 449 void ORoadmap::InsertRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _nUniqueId, sal_Bool _bEnabled ) 450 { 451 InsertHyperLabel( _Index, _RoadmapItem, _nUniqueId, _bEnabled ); 452 // Todo: YPos is superfluous, if items are always appended 453 UpdatefollowingHyperLabels( _Index + 1 ); 454 } 455 456 //--------------------------------------------------------------------- 457 void ORoadmap::DeleteRoadmapItem( ItemIndex _Index ) 458 { 459 if ( m_pImpl->getItemCount() > 0 && ( _Index > -1) && ( _Index < m_pImpl->getItemCount() ) ) 460 { 461 m_pImpl->removeHyperLabel( _Index ); 462 UpdatefollowingHyperLabels( _Index ); 463 } 464 } 465 466 //--------------------------------------------------------------------- 467 sal_Bool ORoadmap::IsRoadmapComplete( ) const 468 { 469 return m_pImpl->isComplete(); 470 } 471 472 //--------------------------------------------------------------------- 473 sal_Bool ORoadmap::IsRoadmapItemEnabled( ItemId _nItemId, ItemIndex _nStartIndex ) const 474 { 475 const RoadmapItem* _pLabelItem = GetByID( _nItemId, _nStartIndex ); 476 return _pLabelItem ? _pLabelItem->IsEnabled() : sal_False; 477 } 478 479 //--------------------------------------------------------------------- 480 void ORoadmap::EnableRoadmapItem( ItemId _nItemId, sal_Bool _bEnable, ItemIndex _nStartIndex ) 481 { 482 RoadmapItem* pItem = GetByID( _nItemId, _nStartIndex ); 483 if ( pItem != NULL ) 484 pItem->Enable( _bEnable ); 485 } 486 487 //--------------------------------------------------------------------- 488 void ORoadmap::ChangeRoadmapItemLabel( ItemId _nID, const ::rtl::OUString& _sLabel, ItemIndex _nStartIndex ) 489 { 490 RoadmapItem* pItem = GetByID( _nID, _nStartIndex ); 491 if ( pItem != NULL ) 492 { 493 pItem->Update( pItem->GetIndex(), _sLabel ); 494 495 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 496 for ( HL_Vector::const_iterator i = rItems.begin() + _nStartIndex; 497 i < rItems.end(); 498 ++i 499 ) 500 { 501 (*i)->SetPosition( GetPreviousHyperLabel( i - rItems.begin() ) ); 502 } 503 } 504 } 505 506 //--------------------------------------------------------------------- 507 508 ::rtl::OUString ORoadmap::GetRoadmapItemLabel( ItemId _nID, ItemIndex _nStartIndex ) 509 { 510 RoadmapItem* pItem = GetByID( _nID, _nStartIndex ); 511 if ( pItem != NULL ) 512 return pItem->GetLabel(); 513 else 514 return ::rtl::OUString(); 515 } 516 517 //--------------------------------------------------------------------- 518 void ORoadmap::ChangeRoadmapItemID( ItemId _nID, ItemId _NewID, ItemIndex _nStartIndex ) 519 { 520 RoadmapItem* pItem = GetByID( _nID, _nStartIndex ); 521 if ( pItem != NULL ) 522 pItem->SetID( _NewID ); 523 } 524 525 //--------------------------------------------------------------------- 526 RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex) 527 { 528 ItemId nLocID = 0; 529 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 530 for ( HL_Vector::const_iterator i = rItems.begin() + _nStartIndex; 531 i < rItems.end(); 532 ++i 533 ) 534 { 535 nLocID = (*i)->GetID(); 536 if ( nLocID == _nID ) 537 return *i; 538 } 539 return NULL; 540 } 541 542 //--------------------------------------------------------------------- 543 const RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex ) const 544 { 545 return const_cast< ORoadmap* >( this )->GetByID( _nID, _nStartIndex ); 546 } 547 548 //--------------------------------------------------------------------- 549 RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex) 550 { 551 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 552 if ( ( _nItemIndex > -1 ) && ( _nItemIndex < (ItemIndex)rItems.size() ) ) 553 { 554 return rItems.at( _nItemIndex ); 555 } 556 return NULL; 557 } 558 559 //--------------------------------------------------------------------- 560 const RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex ) const 561 { 562 return const_cast< ORoadmap* >( this )->GetByIndex( _nItemIndex ); 563 } 564 565 //--------------------------------------------------------------------- 566 RoadmapTypes::ItemId ORoadmap::GetNextAvailableItemId( ItemIndex _nNewIndex ) 567 { 568 RoadmapItem* pItem = NULL; 569 570 ItemIndex searchIndex = ++_nNewIndex; 571 while ( searchIndex < m_pImpl->getItemCount() ) 572 { 573 pItem = GetByIndex( searchIndex ); 574 if ( pItem->IsEnabled() ) 575 return pItem->GetID( ); 576 577 ++searchIndex; 578 } 579 return -1; 580 } 581 582 //--------------------------------------------------------------------- 583 RoadmapTypes::ItemId ORoadmap::GetPreviousAvailableItemId( ItemIndex _nNewIndex ) 584 { 585 RoadmapItem* pItem = NULL; 586 ItemIndex searchIndex = --_nNewIndex; 587 while ( searchIndex > -1 ) 588 { 589 pItem = GetByIndex( searchIndex ); 590 if ( pItem->IsEnabled() ) 591 return pItem->GetID( ); 592 593 searchIndex--; 594 } 595 return -1; 596 } 597 598 //--------------------------------------------------------------------- 599 void ORoadmap::DeselectOldRoadmapItems() 600 { 601 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 602 for ( HL_Vector::const_iterator i = rItems.begin(); 603 i < rItems.end(); 604 ++i 605 ) 606 { 607 (*i)->ToggleBackgroundColor( COL_TRANSPARENT ); 608 } 609 } 610 611 //--------------------------------------------------------------------- 612 void ORoadmap::SetItemSelectHdl( const Link& _rHdl ) 613 { 614 m_pImpl->setSelectHdl( _rHdl ); 615 } 616 617 //--------------------------------------------------------------------- 618 Link ORoadmap::GetItemSelectHdl( ) const 619 { 620 return m_pImpl->getSelectHdl(); 621 } 622 623 //--------------------------------------------------------------------- 624 void ORoadmap::Select() 625 { 626 GetItemSelectHdl().Call( this ); 627 CallEventListeners( VCLEVENT_ROADMAP_ITEMSELECTED ); 628 } 629 630 //--------------------------------------------------------------------- 631 void ORoadmap::GetFocus() 632 { 633 RoadmapItem* pCurHyperLabel = GetByID( GetCurrentRoadmapItemID() ); 634 if ( pCurHyperLabel != NULL ) 635 pCurHyperLabel->GrabFocus(); 636 } 637 638 //--------------------------------------------------------------------- 639 sal_Bool ORoadmap::SelectRoadmapItemByID( ItemId _nNewID ) 640 { 641 DeselectOldRoadmapItems(); 642 RoadmapItem* pItem = GetByID( _nNewID ); 643 if ( pItem != NULL ) 644 { 645 if ( pItem->IsEnabled() ) 646 { 647 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 648 pItem->ToggleBackgroundColor( rStyleSettings.GetHighlightColor() ); //HighlightColor 649 650 pItem->GrabFocus(); 651 m_pImpl->setCurItemID(_nNewID); 652 653 Select(); 654 return sal_True; 655 } 656 } 657 return sal_False; 658 } 659 660 //--------------------------------------------------------------------- 661 void ORoadmap::Paint( const Rectangle& _rRect ) 662 { 663 Control::Paint( _rRect ); 664 665 666 // draw the bitmap 667 if ( !!m_pImpl->getPicture() ) 668 { 669 Size aBitmapSize = m_pImpl->getPicture().GetSizePixel(); 670 Size aMySize = GetOutputSizePixel(); 671 672 Point aBitmapPos( aMySize.Width() - aBitmapSize.Width(), aMySize.Height() - aBitmapSize.Height() ); 673 674 // draw it 675 DrawBitmapEx( aBitmapPos, m_pImpl->getPicture() ); 676 } 677 678 //................................................................. 679 // draw the headline 680 DrawHeadline(); 681 } 682 683 //--------------------------------------------------------------------- 684 void ORoadmap::DrawHeadline() 685 { 686 Point aTextPos = LogicToPixel( Point( ROADMAP_INDENT_X, 8 ), MAP_APPFONT ); 687 688 Size aOutputSize( GetOutputSizePixel() ); 689 690 // draw it 691 DrawText( Rectangle( aTextPos, aOutputSize ), GetText(), TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); 692 DrawTextLine( aTextPos, aOutputSize.Width(), STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, sal_False ); 693 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 694 SetLineColor( rStyleSettings.GetFieldTextColor()); 695 SetTextColor(rStyleSettings.GetFieldTextColor()); 696 } 697 698 //--------------------------------------------------------------------- 699 RoadmapItem* ORoadmap::GetByPointer(Window* pWindow) 700 { 701 const HL_Vector& rItems = m_pImpl->getHyperLabels(); 702 for ( HL_Vector::const_iterator i = rItems.begin(); 703 i < rItems.end(); 704 ++i 705 ) 706 { 707 if ( (*i)->Contains( pWindow ) ) 708 return *i; 709 } 710 return NULL; 711 } 712 713 //--------------------------------------------------------------------- 714 long ORoadmap::PreNotify( NotifyEvent& _rNEvt ) 715 { 716 // capture KeyEvents for taskpane cycling 717 if ( _rNEvt.GetType() == EVENT_KEYINPUT ) 718 { 719 Window* pWindow = _rNEvt.GetWindow(); 720 RoadmapItem* pItem = GetByPointer( pWindow ); 721 if ( pItem != NULL ) 722 { 723 sal_Int16 nKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode().GetCode(); 724 switch( nKeyCode ) 725 { 726 case KEY_UP: 727 { // Note: Performancewise this is not optimal, because we search for an ID in the labels 728 // and afterwards we search again for a label with the appropriate ID -> 729 // unnecessarily we search twice!!! 730 ItemId nPrevItemID = GetPreviousAvailableItemId( pItem->GetIndex() ); 731 if ( nPrevItemID != -1 ) 732 return SelectRoadmapItemByID( nPrevItemID ); 733 } 734 break; 735 case KEY_DOWN: 736 { 737 ItemId nNextItemID = GetNextAvailableItemId( pItem->GetIndex() ); 738 if ( nNextItemID != -1 ) 739 return SelectRoadmapItemByID( nNextItemID ); 740 } 741 break; 742 case KEY_SPACE: 743 return SelectRoadmapItemByID( pItem->GetID() ); 744 } 745 } 746 } 747 return Window::PreNotify( _rNEvt ); 748 } 749 750 //--------------------------------------------------------------------- 751 IMPL_LINK(ORoadmap, ImplClickHdl, HyperLabel*, _CurHyperLabel) 752 { 753 return SelectRoadmapItemByID( _CurHyperLabel->GetID() ); 754 } 755 756 757 758 //--------------------------------------------------------------------- 759 void ORoadmap::DataChanged( const DataChangedEvent& rDCEvt ) 760 { 761 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || 762 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) && 763 ( rDCEvt.GetFlags() & SETTINGS_STYLE )) 764 { 765 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 766 SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) ); 767 Color aTextColor = rStyleSettings.GetFieldTextColor(); 768 Font aFont = GetFont(); 769 aFont.SetColor( aTextColor ); 770 SetFont( aFont ); 771 RoadmapTypes::ItemId curItemID = GetCurrentRoadmapItemID(); 772 RoadmapItem* pLabelItem = GetByID( curItemID ); 773 pLabelItem->ToggleBackgroundColor(rStyleSettings.GetHighlightColor()); 774 Invalidate(); 775 } 776 } 777 778 779 //--------------------------------------------------------------------- 780 RoadmapItem::RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground ) 781 :m_aItemPlayground( _rItemPlayground ) 782 { 783 mpID = new IDLabel( &_rParent, WB_WORDBREAK ); 784 mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) ); 785 mpID->Show(); 786 mpDescription = new HyperLabel( &_rParent, WB_NOTABSTOP | WB_WORDBREAK ); 787 mpDescription->Show(); 788 } 789 790 //--------------------------------------------------------------------- 791 bool RoadmapItem::Contains( const Window* _pWindow ) const 792 { 793 return ( mpID == _pWindow ) || ( mpDescription == _pWindow ); 794 } 795 796 //--------------------------------------------------------------------- 797 void RoadmapItem::GrabFocus() 798 { 799 if ( mpDescription ) 800 mpDescription->GrabFocus(); 801 } 802 803 //--------------------------------------------------------------------- 804 void RoadmapItem::SetInteractive( sal_Bool _bInteractive ) 805 { 806 if ( mpDescription ) 807 mpDescription->SetInteractive(_bInteractive); 808 } 809 810 //--------------------------------------------------------------------- 811 void RoadmapItem::SetID( sal_Int16 _ID ) 812 { 813 if ( mpDescription ) 814 mpDescription->SetID(_ID); 815 } 816 817 //--------------------------------------------------------------------- 818 sal_Int16 RoadmapItem::GetID() const 819 { 820 return mpDescription ? mpDescription->GetID() : sal_Int16(-1); 821 } 822 823 //--------------------------------------------------------------------- 824 void RoadmapItem::ImplUpdateIndex( const ItemIndex _nIndex ) 825 { 826 if ( mpDescription ) 827 mpDescription->SetIndex( _nIndex ); 828 829 if ( mpID ) 830 { 831 ::rtl::OUString aIDText = ::rtl::OUString::valueOf( (sal_Int32)( _nIndex + 1 ) ) + ::rtl::OUString::createFromAscii( "." ); 832 mpID->SetText( aIDText ); 833 } 834 835 // update the geometry of both controls 836 ImplUpdatePosSize(); 837 } 838 839 //--------------------------------------------------------------------- 840 void RoadmapItem::SetIndex( ItemIndex _Index ) 841 { 842 ImplUpdateIndex( _Index ); 843 } 844 845 //--------------------------------------------------------------------- 846 RoadmapTypes::ItemIndex RoadmapItem::GetIndex() const 847 { 848 return mpDescription ? mpDescription->GetIndex() : ItemIndex(-1); 849 } 850 851 //--------------------------------------------------------------------- 852 void RoadmapItem::SetLabel( const ::rtl::OUString& _rText ) 853 { 854 if ( mpDescription ) 855 mpDescription->SetText(_rText); 856 } 857 858 //--------------------------------------------------------------------- 859 ::rtl::OUString RoadmapItem::GetLabel( ) 860 { 861 return mpDescription ? mpDescription->GetText() : String(); 862 } 863 864 //--------------------------------------------------------------------- 865 void RoadmapItem::SetPosition( RoadmapItem* _pOldItem ) 866 { 867 Point aIDPos; 868 if ( _pOldItem == NULL ) 869 { 870 aIDPos = mpID->LogicToPixel( Point( ROADMAP_INDENT_X, ROADMAP_INDENT_Y ), MAP_APPFONT ); 871 } 872 else 873 { 874 Size aOldSize = _pOldItem->GetDescriptionHyperLabel()->GetSizePixel(); 875 876 aIDPos = _pOldItem->mpID->GetPosPixel(); 877 aIDPos.Y() += aOldSize.Height(); 878 aIDPos.Y() += mpID->GetParent()->LogicToPixel( Size( 0, ROADMAP_ITEM_DISTANCE_Y ) ).Height(); 879 } 880 mpID->SetPosPixel( aIDPos ); 881 882 sal_Int32 nDescPos = aIDPos.X() + mpID->GetSizePixel().Width(); 883 mpDescription->SetPosPixel( Point( nDescPos, aIDPos.Y() ) ); 884 } 885 886 //--------------------------------------------------------------------- 887 void RoadmapItem::SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, sal_uInt16 nFlags ) 888 { 889 if (pRefRoadmapHyperLabel == NULL) 890 mpDescription->SetZOrder( NULL, nFlags); //WINDOW_ZORDER_FIRST ); 891 else 892 mpDescription->SetZOrder( pRefRoadmapHyperLabel->mpDescription, nFlags); //, WINDOW_ZORDER_BEHIND ); 893 } 894 895 //--------------------------------------------------------------------- 896 void RoadmapItem::Enable( sal_Bool _bEnable) 897 { 898 mpID->Enable(_bEnable); 899 mpDescription->Enable(_bEnable); 900 } 901 902 //--------------------------------------------------------------------- 903 sal_Bool RoadmapItem::IsEnabled() const 904 { 905 return mpID->IsEnabled(); 906 } 907 908 //--------------------------------------------------------------------- 909 void RoadmapItem::ToggleBackgroundColor( const Color& _rGBColor ) 910 { 911 if (_rGBColor == COL_TRANSPARENT) 912 { 913 mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) ); 914 mpID->SetControlBackground( COL_TRANSPARENT ); 915 } 916 else 917 { 918 mpID->SetControlBackground( mpID->GetSettings().GetStyleSettings().GetHighlightColor() ); 919 mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetHighlightTextColor( ) ); 920 } 921 mpDescription->ToggleBackgroundColor(_rGBColor); 922 } 923 924 //--------------------------------------------------------------------- 925 void RoadmapItem::ImplUpdatePosSize() 926 { 927 // calculate widths 928 long nIDWidth = mpID->GetTextWidth( mpID->GetText() ); 929 long nMaxIDWidth = mpID->GetTextWidth( ::rtl::OUString::createFromAscii( "100." ) ); 930 nIDWidth = ::std::min( nIDWidth, nMaxIDWidth ); 931 932 // check how many space the description would need 933 Size aDescriptionSize = mpDescription->CalcMinimumSize( m_aItemPlayground.Width() - nIDWidth ); 934 935 // position and size both controls 936 Size aIDSize( nIDWidth, aDescriptionSize.Height() ); 937 mpID->SetSizePixel( aIDSize ); 938 939 Point aIDPos = mpID->GetPosPixel(); 940 mpDescription->SetPosPixel( Point( aIDPos.X() + nIDWidth, aIDPos.Y() ) ); 941 mpDescription->SetSizePixel( aDescriptionSize ); 942 } 943 944 //--------------------------------------------------------------------- 945 void RoadmapItem::Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText ) 946 { 947 // update description label 948 mpDescription->SetLabel( _rText ); 949 950 // update the index in both controls, which triggers updating the geometry of both 951 ImplUpdateIndex( _RMIndex ); 952 } 953 954 //--------------------------------------------------------------------- 955 RoadmapItem::~RoadmapItem( ) 956 { 957 { 958 ::std::auto_ptr<Control> aTemp(mpID); 959 mpID = NULL; 960 } 961 { 962 ::std::auto_ptr<Control> aTemp(mpDescription); 963 mpDescription = NULL; 964 } 965 } 966 967 //--------------------------------------------------------------------- 968 void RoadmapItem::SetClickHdl( const Link& rLink ) 969 { 970 if ( mpDescription ) 971 mpDescription->SetClickHdl( rLink); 972 } 973 974 //--------------------------------------------------------------------- 975 const Link& RoadmapItem::GetClickHdl( ) const 976 { 977 return mpDescription->GetClickHdl(); 978 } 979 980 //--------------------------------------------------------------------- 981 IDLabel::IDLabel( Window* _pParent, WinBits _nWinStyle ) 982 :FixedText( _pParent, _nWinStyle ) 983 { 984 985 } 986 987 //--------------------------------------------------------------------- 988 IDLabel::~IDLabel( ) 989 { 990 } 991 992 //--------------------------------------------------------------------- 993 void IDLabel::DataChanged( const DataChangedEvent& rDCEvt ) 994 { 995 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 996 FixedText::DataChanged( rDCEvt ); 997 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || 998 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) && 999 ( rDCEvt.GetFlags() & SETTINGS_STYLE )) 1000 { 1001 const Color& rGBColor = GetControlBackground(); 1002 if (rGBColor == COL_TRANSPARENT) 1003 SetTextColor( rStyleSettings.GetFieldTextColor( ) ); 1004 else 1005 { 1006 SetControlBackground(rStyleSettings.GetHighlightColor()); 1007 SetTextColor( rStyleSettings.GetHighlightTextColor( ) ); 1008 } 1009 Invalidate(); 1010 } 1011 } 1012 1013 1014 1015 1016 //......................................................................... 1017 } // namespace svt 1018 //......................................................................... 1019