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