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 <vcl/image.hxx>
32 #include <vcl/help.hxx>
33 #include <svtools/taskbar.hxx>
34 
35 // =======================================================================
36 
37 #define TASKBOX_TASKOFF             3
38 
39 // =======================================================================
40 
41 struct ImplTaskItem
42 {
43     Image               maImage;
44     XubString           maText;
45 };
46 
DECLARE_LIST(ImplTaskItemList,ImplTaskItem *)47 DECLARE_LIST( ImplTaskItemList, ImplTaskItem* )
48 
49 // =======================================================================
50 
51 TaskToolBox::TaskToolBox( Window* pParent, WinBits nWinStyle ) :
52     ToolBox( pParent, nWinStyle | WB_SCROLL | WB_3DLOOK )
53 {
54     mpItemList      = new ImplTaskItemList;
55     mnMaxTextWidth  = 0;
56     mnActiveItemId  = 0;
57     mnTaskItem      = 0;
58     mnSmallItem     = TOOLBOX_ITEM_NOTFOUND;
59     mbMinActivate   = sal_False;
60 
61     SetAlign( WINDOWALIGN_BOTTOM );
62     SetButtonType( BUTTON_SYMBOLTEXT );
63 }
64 
65 // -----------------------------------------------------------------------
66 
~TaskToolBox()67 TaskToolBox::~TaskToolBox()
68 {
69     ImplTaskItem* pItem = mpItemList->First();
70     while ( pItem )
71     {
72         delete pItem;
73         pItem = mpItemList->Next();
74     }
75 
76     delete mpItemList;
77 }
78 
79 // -----------------------------------------------------------------------
80 
ActivateTaskItem(sal_uInt16 nItemId,sal_Bool bMinActivate)81 void TaskToolBox::ActivateTaskItem( sal_uInt16 nItemId, sal_Bool bMinActivate )
82 {
83     if ( nItemId )
84     {
85         if ( nItemId != mnActiveItemId )
86         {
87             if ( mnActiveItemId )
88                 CheckItem( mnActiveItemId, sal_False );
89             CheckItem( nItemId );
90             mnActiveItemId = nItemId;
91         }
92         else
93         {
94             if ( !bMinActivate )
95                 return;
96 
97             mbMinActivate = sal_True;
98         }
99 
100         mnTaskItem = nItemId-1;
101         ActivateTask();
102         mnTaskItem = 0;
103         mbMinActivate = sal_False;
104     }
105 }
106 
107 // -----------------------------------------------------------------------
108 
ActivateTask()109 void TaskToolBox::ActivateTask()
110 {
111     maActivateTaskHdl.Call( this );
112 }
113 
114 // -----------------------------------------------------------------------
115 
ContextMenu()116 void TaskToolBox::ContextMenu()
117 {
118     maContextMenuHdl.Call( this );
119 }
120 
121 // -----------------------------------------------------------------------
122 
MouseButtonDown(const MouseEvent & rMEvt)123 void TaskToolBox::MouseButtonDown( const MouseEvent& rMEvt )
124 {
125     if ( !rMEvt.IsRight() )
126         ToolBox::MouseButtonDown( rMEvt );
127 }
128 
129 // -----------------------------------------------------------------------
130 
Resize()131 void TaskToolBox::Resize()
132 {
133     mnOldItemCount  = mpItemList->Count();
134     mnUpdatePos     = (sal_uInt16)mnOldItemCount;
135     mnUpdateNewPos  = TOOLBOX_ITEM_NOTFOUND;
136     ImplFormatTaskToolBox();
137     ToolBox::Resize();
138 }
139 
140 // -----------------------------------------------------------------------
141 
Command(const CommandEvent & rCEvt)142 void TaskToolBox::Command( const CommandEvent& rCEvt )
143 {
144     if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
145     {
146         sal_uInt16 nItemId = GetItemId( rCEvt.GetMousePosPixel() );
147 // Dies machen wir nicht mehr, da es von zu vielen als stoerend empfunden wurde
148 //        ActivateTaskItem( nItemId );
149         mnTaskItem = nItemId-1;
150 
151         maContextMenuPos = rCEvt.GetMousePosPixel();
152         ContextMenu();
153         maContextMenuPos = Point();
154         mnTaskItem = 0;
155     }
156     else
157         ToolBox::Command( rCEvt );
158 }
159 
160 // -----------------------------------------------------------------------
161 
RequestHelp(const HelpEvent & rHEvt)162 void TaskToolBox::RequestHelp( const HelpEvent& rHEvt )
163 {
164     if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
165     {
166         sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
167 
168         if ( nItemId )
169         {
170             ImplTaskItem* pItem = mpItemList->GetObject( nItemId-1 );
171             if ( pItem )
172             {
173                 if ( pItem->maText != GetItemText( nItemId ) )
174                 {
175                     Rectangle aItemRect = GetItemRect( nItemId );
176                     if ( rHEvt.GetMode() & HELPMODE_QUICK )
177                         Help::ShowQuickHelp( this, aItemRect, pItem->maText );
178                     else
179                         Help::ShowBalloon( this, aItemRect.Center(), aItemRect, pItem->maText );
180                 }
181                 else
182                     Help::ShowQuickHelp( this, Rectangle(), String() );
183                 return;
184             }
185         }
186     }
187 
188     ToolBox::RequestHelp( rHEvt );
189 }
190 
191 // -----------------------------------------------------------------------
192 
Select()193 void TaskToolBox::Select()
194 {
195     sal_uInt16 nItemId = GetCurItemId();
196     ActivateTaskItem( nItemId, sal_True );
197 }
198 
199 // -----------------------------------------------------------------------
200 
ImplFormatTaskToolBox()201 void TaskToolBox::ImplFormatTaskToolBox()
202 {
203     if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
204     {
205         // Eintraege aus der Liste entfernen
206         while ( mpItemList->Count() > mnUpdatePos )
207             delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
208         mnUpdateNewPos = mnUpdatePos;
209     }
210 
211     // Maximale Itemgroesse berechnen
212     long nOldMaxTextWidth = mnMaxTextWidth;
213     mnMaxTextWidth = 70;
214     if ( mpItemList->Count() )
215     {
216         long nWinSize = GetOutputSizePixel().Width()-8;
217         long nItemSize = mpItemList->GetObject(0)->maImage.GetSizePixel().Width()+7+TASKBOX_TASKOFF+2;
218         nWinSize -= mpItemList->Count()*nItemSize;
219         if ( nWinSize > 0 )
220             nWinSize /= mpItemList->Count();
221         else
222             nWinSize = 0;
223         if ( nWinSize < mnMaxTextWidth )
224             mnMaxTextWidth = nWinSize;
225         if ( (mnMaxTextWidth < nOldMaxTextWidth) ||
226              ((mnMaxTextWidth-nOldMaxTextWidth > 3) &&
227               (mnSmallItem != TOOLBOX_ITEM_NOTFOUND)) )
228         {
229             mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
230             mnUpdateNewPos = 0;
231         }
232     }
233 
234     // Eintraege aus der ToolBox entfernen, die ersetzt werden
235     sal_uInt16 nBtnPos = (mnUpdateNewPos*2);
236     while ( nBtnPos < GetItemCount() )
237         RemoveItem( nBtnPos );
238     if ( mnUpdateNewPos <= (mnActiveItemId-1) )
239         mnActiveItemId = 0;
240 
241     // Neue Eintrage einfuegen
242     sal_uInt16 i = mnUpdateNewPos;
243     while ( i < mpItemList->Count() )
244     {
245         ImplTaskItem* pItem = mpItemList->GetObject( i );
246 
247         // Textlaenge berechnen
248         XubString aText = pItem->maText;
249         if ( !aText.Len() )
250             aText = ' ';
251         long nTxtWidth = GetTextWidth( aText );
252         if ( nTxtWidth > mnMaxTextWidth )
253         {
254             if ( mnSmallItem == TOOLBOX_ITEM_NOTFOUND )
255                 mnSmallItem = i;
256             // 3 == Len of "..."
257             aText.AppendAscii( "..." );
258             do
259             {
260                 aText.Erase( aText.Len()-3-1, 1 );
261                 nTxtWidth = GetTextWidth( aText );
262             }
263             while ( (nTxtWidth > mnMaxTextWidth) && (aText.Len() > 3) );
264         }
265 
266         sal_uInt16 nItemId = i+1;
267         if ( aText.EqualsAscii( "..." ) )
268             InsertItem( nItemId, pItem->maImage, TIB_LEFT );
269         else
270             InsertItem( nItemId, pItem->maImage, aText, TIB_LEFT );
271         InsertSeparator( TOOLBOX_APPEND, TASKBOX_TASKOFF );
272         i++;
273     }
274 
275     if ( mnUpdateNewPos != 0 )
276         mnMaxTextWidth = nOldMaxTextWidth;
277 
278     if ( mnNewActivePos+1 != mnActiveItemId )
279     {
280         if ( mnActiveItemId )
281             CheckItem( mnActiveItemId, sal_False );
282         mnActiveItemId = mnNewActivePos+1;
283         CheckItem( mnActiveItemId );
284     }
285 }
286 
287 // -----------------------------------------------------------------------
288 
StartUpdateTask()289 void TaskToolBox::StartUpdateTask()
290 {
291     mnOldItemCount  = mpItemList->Count();
292     mnUpdatePos     = 0;
293     mnUpdateNewPos  = TOOLBOX_ITEM_NOTFOUND;
294     mnNewActivePos  = 0xFFFE;
295 }
296 
297 // -----------------------------------------------------------------------
298 
UpdateTask(const Image & rImage,const String & rText,sal_Bool bActive)299 void TaskToolBox::UpdateTask( const Image& rImage, const String& rText,
300                               sal_Bool bActive )
301 {
302     ImplTaskItem* pItem = mpItemList->GetObject( mnUpdatePos );
303     if ( pItem )
304     {
305         if ( (pItem->maText != rText) || (pItem->maImage != rImage) )
306         {
307             // Eintraege aus der Liste entfernen
308             while ( mpItemList->Count() > mnUpdatePos )
309                 delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
310             pItem = NULL;
311         }
312     }
313 
314     if ( !pItem )
315     {
316         if ( mnUpdatePos < mnUpdateNewPos )
317             mnUpdateNewPos = mnUpdatePos;
318 
319         pItem           = new ImplTaskItem;
320         pItem->maImage  = rImage;
321         pItem->maText   = rText;
322         mpItemList->Insert( pItem, LIST_APPEND );
323     }
324 
325     if ( bActive )
326         mnNewActivePos = mnUpdatePos;
327 
328     mnUpdatePos++;
329 }
330 
331 // -----------------------------------------------------------------------
332 
EndUpdateTask()333 void TaskToolBox::EndUpdateTask()
334 {
335     if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
336     {
337         // Eintraege aus der Liste entfernen
338         while ( mpItemList->Count() > mnUpdatePos )
339             delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
340         mnUpdateNewPos = mnUpdatePos;
341     }
342 
343     ImplFormatTaskToolBox();
344 }
345 
346