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
27 #define _TASKBAR_CXX
28
29 #include <tools/list.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/date.hxx>
32 #include <vcl/image.hxx>
33 #include <vcl/help.hxx>
34 #include <vcl/svapp.hxx>
35 #include <unotools/calendarwrapper.hxx>
36 #include <unotools/syslocale.hxx>
37 #include <svtools/taskbar.hxx>
38
39 // =======================================================================
40
41 #define TASKSTATUSBAR_CLOCXOFFX 3
42 #define TASKSTATUSBAR_IMAGEOFFX 1
43
44 // =======================================================================
45
46 struct ImplTaskSBFldItem
47 {
48 TaskStatusFieldItem maItem;
49 sal_uInt16 mnId;
50 long mnOffX;
51 };
52
DECLARE_LIST(ImplTaskSBItemList,ImplTaskSBFldItem *)53 DECLARE_LIST( ImplTaskSBItemList, ImplTaskSBFldItem* )
54
55 // =======================================================================
56
57 sal_Bool ITaskStatusNotify::MouseButtonDown( sal_uInt16, const MouseEvent& )
58 {
59 return sal_False;
60 }
61
62 // -----------------------------------------------------------------------
63
MouseButtonUp(sal_uInt16,const MouseEvent &)64 sal_Bool ITaskStatusNotify::MouseButtonUp( sal_uInt16, const MouseEvent& )
65 {
66 return sal_False;
67 }
68
69 // -----------------------------------------------------------------------
70
MouseMove(sal_uInt16,const MouseEvent &)71 sal_Bool ITaskStatusNotify::MouseMove( sal_uInt16, const MouseEvent& )
72 {
73 return sal_False;
74 }
75
76 // -----------------------------------------------------------------------
77
Command(sal_uInt16,const CommandEvent &)78 sal_Bool ITaskStatusNotify::Command( sal_uInt16, const CommandEvent& )
79 {
80 return sal_False;
81 }
82
83 // -----------------------------------------------------------------------
84
UpdateHelp(sal_uInt16)85 sal_Bool ITaskStatusNotify::UpdateHelp( sal_uInt16 )
86 {
87 return sal_False;
88 }
89
90 // =======================================================================
91
TaskStatusFieldItem()92 TaskStatusFieldItem::TaskStatusFieldItem()
93 {
94 mpNotify = NULL;
95 mnFlags = 0;
96 }
97
98 // -----------------------------------------------------------------------
99
TaskStatusFieldItem(const TaskStatusFieldItem & rItem)100 TaskStatusFieldItem::TaskStatusFieldItem( const TaskStatusFieldItem& rItem ) :
101 mpNotify( rItem.mpNotify ),
102 maImage( rItem.maImage ),
103 maQuickHelpText( rItem.maQuickHelpText ),
104 maHelpText( rItem.maHelpText ),
105 mnFlags( rItem.mnFlags )
106 {
107 }
108
109 // -----------------------------------------------------------------------
110
TaskStatusFieldItem(ITaskStatusNotify * pNotify,const Image & rImage,const XubString & rQuickHelpText,const XubString & rHelpText,sal_uInt16 nFlags)111 TaskStatusFieldItem::TaskStatusFieldItem( ITaskStatusNotify* pNotify,
112 const Image& rImage,
113 const XubString& rQuickHelpText,
114 const XubString& rHelpText,
115 sal_uInt16 nFlags ) :
116 mpNotify( pNotify ),
117 maImage( rImage ),
118 maQuickHelpText( rQuickHelpText ),
119 maHelpText( rHelpText ),
120 mnFlags( nFlags )
121 {
122 }
123
124 // -----------------------------------------------------------------------
125
~TaskStatusFieldItem()126 TaskStatusFieldItem::~TaskStatusFieldItem()
127 {
128 }
129
130 // -----------------------------------------------------------------------
131
operator =(const TaskStatusFieldItem & rItem)132 const TaskStatusFieldItem& TaskStatusFieldItem::operator=( const TaskStatusFieldItem& rItem )
133 {
134 mpNotify = rItem.mpNotify;
135 maImage = rItem.maImage;
136 maQuickHelpText = rItem.maQuickHelpText;
137 maHelpText = rItem.maHelpText;
138 mnFlags = rItem.mnFlags;
139 return *this;
140 }
141
142 // =======================================================================
143
TaskStatusBar(Window * pParent,WinBits nWinStyle)144 TaskStatusBar::TaskStatusBar( Window* pParent, WinBits nWinStyle ) :
145 StatusBar( pParent, nWinStyle | WB_3DLOOK ),
146 maTime( 0, 0, 0 )
147 {
148 mpFieldItemList = NULL;
149 mpNotifyTaskBar = NULL;
150 mpNotify = NULL;
151 mnClockWidth = 0;
152 mnItemWidth = 0;
153 mnFieldWidth = 0;
154 mnFieldFlags = 0;
155 mbFlashItems = sal_False;
156 mbOutInterval = sal_False;
157
158 maTimer.SetTimeoutHdl( LINK( this, TaskStatusBar, ImplTimerHdl ) );
159 }
160
161 // -----------------------------------------------------------------------
162
~TaskStatusBar()163 TaskStatusBar::~TaskStatusBar()
164 {
165 if ( mpFieldItemList )
166 {
167 ImplTaskSBFldItem* pItem = mpFieldItemList->First();
168 while ( pItem )
169 {
170 delete pItem;
171 pItem = mpFieldItemList->Next();
172 }
173
174 delete mpFieldItemList;
175 }
176 }
177
178 // -----------------------------------------------------------------------
179
IMPL_LINK(TaskStatusBar,ImplTimerHdl,Timer *,EMPTYARG)180 IMPL_LINK( TaskStatusBar, ImplTimerHdl, Timer*, EMPTYARG )
181 {
182 sal_Bool bUpdate = ImplUpdateClock();
183 if ( ImplUpdateFlashItems() )
184 bUpdate = sal_True;
185 if ( bUpdate )
186 SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
187
188 return 0;
189 }
190
191 // -----------------------------------------------------------------------
192
ImplGetFieldItem(sal_uInt16 nItemId) const193 ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( sal_uInt16 nItemId ) const
194 {
195 if ( !mpFieldItemList )
196 return NULL;
197
198 ImplTaskSBFldItem* pItem = mpFieldItemList->First();
199 while ( pItem )
200 {
201 if ( pItem->mnId == nItemId )
202 return pItem;
203
204 pItem = mpFieldItemList->Next();
205 }
206
207 return NULL;
208 }
209
210 // -----------------------------------------------------------------------
211
ImplGetFieldItem(const Point & rPos,sal_Bool & rFieldRect) const212 ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( const Point& rPos, sal_Bool& rFieldRect ) const
213 {
214 if ( GetItemId( rPos ) == TASKSTATUSBAR_STATUSFIELDID )
215 {
216 rFieldRect = sal_True;
217
218 if ( mpFieldItemList )
219 {
220 long nX = rPos.X()-GetItemRect( TASKSTATUSBAR_STATUSFIELDID ).Left();
221 ImplTaskSBFldItem* pItem = mpFieldItemList->First();
222 while ( pItem )
223 {
224 if ( nX < pItem->mnOffX+pItem->maItem.GetImage().GetSizePixel().Width() )
225 return pItem;
226
227 pItem = mpFieldItemList->Next();
228 }
229 }
230 }
231 else
232 rFieldRect = sal_False;
233
234 return NULL;
235 }
236
237 // -----------------------------------------------------------------------
238
ImplUpdateClock()239 sal_Bool TaskStatusBar::ImplUpdateClock()
240 {
241 if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
242 {
243 Time aTime;
244 maTimer.SetTimeout( ((long)60000)-((aTime.GetSec()*1000)+(aTime.Get100Sec()*10)) );
245 if ( (aTime.GetMin() != maTime.GetMin()) ||
246 (aTime.GetHour() != maTime.GetHour()) )
247 {
248 maTime = aTime;
249 maTimeText = SvtSysLocale().GetLocaleData().getTime( aTime, sal_False, sal_False );
250 return sal_True;
251 }
252 }
253
254 return sal_False;
255 }
256
257 // -----------------------------------------------------------------------
258
ImplUpdateFlashItems()259 sal_Bool TaskStatusBar::ImplUpdateFlashItems()
260 {
261 if ( mbFlashItems )
262 {
263 if ( mbOutInterval )
264 {
265 maTimer.SetTimeout( 900 );
266 mbOutInterval = sal_False;
267 }
268 else
269 {
270 maTimer.SetTimeout( 700 );
271 mbOutInterval = sal_True;
272 }
273
274 return sal_True;
275 }
276
277 return sal_False;
278 }
279
280 // -----------------------------------------------------------------------
281
ImplUpdateField(sal_Bool bItems)282 void TaskStatusBar::ImplUpdateField( sal_Bool bItems )
283 {
284 maTimer.Stop();
285
286 if ( bItems )
287 {
288 ImplTaskSBFldItem* pItem = mpFieldItemList->First();
289 mnItemWidth = 0;
290 mbFlashItems = sal_False;
291 mbOutInterval = sal_False;
292 while ( pItem )
293 {
294 mnItemWidth += TASKSTATUSBAR_IMAGEOFFX;
295 pItem->mnOffX = mnItemWidth;
296 mnItemWidth += pItem->maItem.GetImage().GetSizePixel().Width();
297 if ( pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH )
298 mbFlashItems = sal_True;
299
300 pItem = mpFieldItemList->Next();
301 }
302 }
303 else
304 {
305 if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
306 {
307 XubString aStr = SvtSysLocale().GetLocaleData().getTime( Time( 23, 59, 59 ), sal_False, sal_False );
308 mnClockWidth = GetTextWidth( aStr )+(TASKSTATUSBAR_CLOCXOFFX*2);
309 }
310 else
311 mnClockWidth = 0;
312 }
313
314 long nNewWidth = mnItemWidth+mnClockWidth;
315 if ( mnItemWidth && !mnClockWidth )
316 nNewWidth += TASKSTATUSBAR_IMAGEOFFX;
317 if ( nNewWidth != mnFieldWidth )
318 {
319 RemoveItem( TASKSTATUSBAR_STATUSFIELDID );
320
321 if ( mnItemWidth || mnClockWidth )
322 {
323 mnFieldWidth = nNewWidth;
324 long nOffset = GetItemOffset( TASKSTATUSBAR_STATUSFIELDID );
325 sal_uInt16 nItemPos = GetItemPos( TASKSTATUSBAR_STATUSFIELDID );
326 InsertItem( TASKSTATUSBAR_STATUSFIELDID, nNewWidth, SIB_RIGHT | SIB_IN | SIB_USERDRAW, nOffset, nItemPos );
327 }
328 else
329 mnFieldWidth = 0;
330
331 if ( mpNotifyTaskBar )
332 mpNotifyTaskBar->Resize();
333 }
334 else
335 SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
336
337 if ( mbFlashItems || (mnFieldFlags & TASKSTATUSFIELD_CLOCK) )
338 {
339 ImplUpdateClock();
340 mbOutInterval = sal_True;
341 ImplUpdateFlashItems();
342 maTimer.Start();
343 }
344 }
345
346 // -----------------------------------------------------------------------
347
MouseButtonDown(const MouseEvent & rMEvt)348 void TaskStatusBar::MouseButtonDown( const MouseEvent& rMEvt )
349 {
350 sal_Bool bFieldRect;
351 sal_Bool bBaseClass = sal_False;
352 ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
353
354 ITaskStatusNotify* pNotify = mpNotify;
355 sal_uInt16 nItemId = 0;
356
357 if ( bFieldRect )
358 nItemId = TASKSTATUSBAR_CLOCKID;
359
360 if ( pItem )
361 {
362 pNotify = pItem->maItem.GetNotifyObject();
363 nItemId = pItem->mnId;
364 }
365
366 if ( pNotify )
367 bBaseClass = pNotify->MouseButtonDown( nItemId, rMEvt );
368
369 if ( bBaseClass )
370 StatusBar::MouseButtonDown( rMEvt );
371 }
372
373 // -----------------------------------------------------------------------
374
MouseButtonUp(const MouseEvent & rMEvt)375 void TaskStatusBar::MouseButtonUp( const MouseEvent& rMEvt )
376 {
377 sal_Bool bFieldRect;
378 sal_Bool bBaseClass = sal_False;
379 ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
380
381 ITaskStatusNotify* pNotify = mpNotify;
382 sal_uInt16 nItemId = 0;
383
384 if ( bFieldRect )
385 nItemId = TASKSTATUSBAR_CLOCKID;
386
387 if ( pItem )
388 {
389 pNotify = pItem->maItem.GetNotifyObject();
390 nItemId = pItem->mnId;
391 }
392
393 if ( pNotify )
394 bBaseClass = pNotify->MouseButtonUp( nItemId, rMEvt );
395
396 if ( bBaseClass )
397 StatusBar::MouseButtonUp( rMEvt );
398 }
399
400 // -----------------------------------------------------------------------
401
MouseMove(const MouseEvent & rMEvt)402 void TaskStatusBar::MouseMove( const MouseEvent& rMEvt )
403 {
404 sal_Bool bFieldRect;
405 sal_Bool bBaseClass = sal_False;
406 ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
407
408 ITaskStatusNotify* pNotify = mpNotify;
409 sal_uInt16 nItemId = 0;
410
411 if ( bFieldRect )
412 nItemId = TASKSTATUSBAR_CLOCKID;
413
414 if ( pItem )
415 {
416 pNotify = pItem->maItem.GetNotifyObject();
417 nItemId = pItem->mnId;
418 }
419
420 if ( pNotify )
421 bBaseClass = pNotify->MouseMove( nItemId, rMEvt );
422
423 if ( bBaseClass )
424 StatusBar::MouseMove( rMEvt );
425 }
426
427 // -----------------------------------------------------------------------
428
Command(const CommandEvent & rCEvt)429 void TaskStatusBar::Command( const CommandEvent& rCEvt )
430 {
431 sal_Bool bFieldRect;
432 sal_Bool bBaseClass = sal_False;
433 ImplTaskSBFldItem* pItem = ImplGetFieldItem( rCEvt.GetMousePosPixel(), bFieldRect );
434
435 ITaskStatusNotify* pNotify = mpNotify;
436 sal_uInt16 nItemId = 0;
437
438 if ( bFieldRect )
439 nItemId = TASKSTATUSBAR_CLOCKID;
440
441 if ( pItem )
442 {
443 pNotify = pItem->maItem.GetNotifyObject();
444 nItemId = pItem->mnId;
445 }
446
447 if ( pNotify )
448 bBaseClass = pNotify->Command( nItemId, rCEvt );
449
450 if ( bBaseClass )
451 StatusBar::Command( rCEvt );
452 }
453
454 // -----------------------------------------------------------------------
455
RequestHelp(const HelpEvent & rHEvt)456 void TaskStatusBar::RequestHelp( const HelpEvent& rHEvt )
457 {
458 sal_Bool bFieldRect;
459 ImplTaskSBFldItem* pItem = ImplGetFieldItem( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), bFieldRect );
460 if ( bFieldRect )
461 {
462 ITaskStatusNotify* pNotify = mpNotify;
463 sal_uInt16 nItemId = 0;
464
465 if ( pItem )
466 {
467 pNotify = pItem->maItem.GetNotifyObject();
468 nItemId = pItem->mnId;
469 }
470
471 if ( pNotify )
472 pNotify->UpdateHelp( nItemId );
473
474 if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
475 {
476 Rectangle aItemRect = GetItemRect( TASKSTATUSBAR_STATUSFIELDID );
477 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
478 aItemRect.Left() = aPt.X();
479 aItemRect.Top() = aPt.Y();
480 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
481 aItemRect.Right() = aPt.X();
482 aItemRect.Bottom() = aPt.Y();
483 if ( pItem )
484 {
485 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
486 {
487 XubString aStr = pItem->maItem.GetHelpText();
488 if ( !aStr.Len() )
489 aStr = pItem->maItem.GetQuickHelpText();
490 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
491 }
492 else
493 Help::ShowQuickHelp( this, aItemRect, pItem->maItem.GetQuickHelpText() );
494 }
495 else
496 {
497 SvtSysLocale aSL;
498 const LocaleDataWrapper& rLDW = aSL.GetLocaleData();
499 CalendarWrapper aCal( rLDW.getServiceFactory());
500 aCal.loadDefaultCalendar( rLDW.getLoadedLocale());
501 XubString aStr = rLDW.getLongDate( Date(), aCal );
502 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
503 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
504 else
505 Help::ShowQuickHelp( this, aItemRect, aStr );
506 }
507 return;
508 }
509 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
510 {
511 if ( pItem )
512 {
513 rtl::OUString aHelpId( rtl::OStringToOUString( pItem->maItem.GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
514 if ( aHelpId.getLength() )
515 {
516 // Wenn eine Hilfe existiert, dann ausloesen
517 Help* pHelp = Application::GetHelp();
518 if ( pHelp )
519 pHelp->Start( aHelpId, this );
520 return;
521 }
522 }
523 }
524 }
525
526 StatusBar::RequestHelp( rHEvt );
527 }
528
529 // -----------------------------------------------------------------------
530
UserDraw(const UserDrawEvent & rUDEvt)531 void TaskStatusBar::UserDraw( const UserDrawEvent& rUDEvt )
532 {
533 if ( rUDEvt.GetItemId() == TASKSTATUSBAR_STATUSFIELDID )
534 {
535 OutputDevice* pDev = rUDEvt.GetDevice();
536 Rectangle aRect = rUDEvt.GetRect();
537
538 if ( mpFieldItemList )
539 {
540 ImplTaskSBFldItem* pItem = mpFieldItemList->First();
541 while ( pItem )
542 {
543 if ( !mbOutInterval || !(pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH) )
544 {
545 const Image& rImage = pItem->maItem.GetImage();
546 Size aImgSize = rImage.GetSizePixel();
547 pDev->DrawImage( Point( aRect.Left()+pItem->mnOffX,
548 aRect.Top()+((aRect.GetHeight()-aImgSize.Width())/2) ),
549 rImage );
550 }
551
552 pItem = mpFieldItemList->Next();
553 }
554 }
555
556 if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
557 {
558 long nX = mnItemWidth+TASKSTATUSBAR_CLOCXOFFX;
559 Point aPos = GetItemTextPos( TASKSTATUSBAR_STATUSFIELDID );
560 aPos.X() = aRect.Left()+nX;
561 pDev->DrawText( aPos, maTimeText );
562 }
563 }
564 else
565 StatusBar::UserDraw( rUDEvt );
566 }
567
568 // -----------------------------------------------------------------------
569
InsertStatusField(long,sal_uInt16,sal_uInt16 nFlags)570 void TaskStatusBar::InsertStatusField( long, sal_uInt16,
571 sal_uInt16 nFlags )
572 {
573 mnFieldFlags = nFlags;
574 ImplUpdateField( sal_False );
575 }
576
577 // -----------------------------------------------------------------------
578
SetFieldFlags(sal_uInt16 nFlags)579 void TaskStatusBar::SetFieldFlags( sal_uInt16 nFlags )
580 {
581 if ( mnFieldFlags != nFlags )
582 {
583 mnFieldFlags = nFlags;
584 ImplUpdateField( sal_False );
585 }
586 }
587
588 // -----------------------------------------------------------------------
589
AddStatusFieldItem(sal_uInt16 nItemId,const TaskStatusFieldItem & rItem,sal_uInt16 nPos)590 void TaskStatusBar::AddStatusFieldItem( sal_uInt16 nItemId, const TaskStatusFieldItem& rItem,
591 sal_uInt16 nPos )
592 {
593 DBG_ASSERT( nItemId, "TaskStatusBar::AddStatusFieldItem() - Item is 0" );
594 DBG_ASSERT( !ImplGetFieldItem( nItemId ), "TaskStatusBar::AddStatusFieldItem() - Item-Id already exist" );
595
596 if ( !mpFieldItemList )
597 mpFieldItemList = new ImplTaskSBItemList;
598
599 ImplTaskSBFldItem* pItem = new ImplTaskSBFldItem;
600 pItem->maItem = rItem;
601 pItem->mnId = nItemId;
602 pItem->mnOffX = 0;
603 mpFieldItemList->Insert( pItem, (sal_uLong)nPos );
604
605 ImplUpdateField( sal_True );
606 }
607
608 // -----------------------------------------------------------------------
609
ModifyStatusFieldItem(sal_uInt16 nItemId,const TaskStatusFieldItem & rItem)610 void TaskStatusBar::ModifyStatusFieldItem( sal_uInt16 nItemId, const TaskStatusFieldItem& rItem )
611 {
612 ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
613 if ( pItem )
614 {
615 sal_Bool bUpdate = (pItem->maItem.GetImage() != rItem.GetImage()) ||
616 (pItem->maItem.GetFlags() != rItem.GetFlags());
617 pItem->maItem = rItem;
618 if ( bUpdate )
619 ImplUpdateField( sal_True );
620 }
621 }
622
623 // -----------------------------------------------------------------------
624
RemoveStatusFieldItem(sal_uInt16 nItemId)625 void TaskStatusBar::RemoveStatusFieldItem( sal_uInt16 nItemId )
626 {
627 ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
628 if ( pItem )
629 {
630 mpFieldItemList->Remove( pItem );
631 delete pItem;
632 ImplUpdateField( sal_True );
633 }
634 }
635
636 // -----------------------------------------------------------------------
637
GetStatusFieldItem(sal_uInt16 nItemId,TaskStatusFieldItem & rItem) const638 sal_Bool TaskStatusBar::GetStatusFieldItem( sal_uInt16 nItemId, TaskStatusFieldItem& rItem ) const
639 {
640 ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
641 if ( pItem )
642 {
643 rItem = pItem->maItem;
644 return sal_True;
645 }
646
647 return sal_False;
648 }
649
650