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