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