xref: /aoo41x/main/svtools/source/control/taskbox.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #define _TASKBAR_CXX
32 
33 #include <tools/list.hxx>
34 #include <tools/debug.hxx>
35 #include <vcl/image.hxx>
36 #include <vcl/help.hxx>
37 #include <svtools/taskbar.hxx>
38 
39 // =======================================================================
40 
41 #define TASKBOX_TASKOFF             3
42 
43 // =======================================================================
44 
45 struct ImplTaskItem
46 {
47     Image               maImage;
48     XubString           maText;
49 };
50 
51 DECLARE_LIST( ImplTaskItemList, ImplTaskItem* )
52 
53 // =======================================================================
54 
55 TaskToolBox::TaskToolBox( Window* pParent, WinBits nWinStyle ) :
56     ToolBox( pParent, nWinStyle | WB_SCROLL | WB_3DLOOK )
57 {
58     mpItemList      = new ImplTaskItemList;
59     mnMaxTextWidth  = 0;
60     mnActiveItemId  = 0;
61     mnTaskItem      = 0;
62     mnSmallItem     = TOOLBOX_ITEM_NOTFOUND;
63     mbMinActivate   = sal_False;
64 
65     SetAlign( WINDOWALIGN_BOTTOM );
66     SetButtonType( BUTTON_SYMBOLTEXT );
67 }
68 
69 // -----------------------------------------------------------------------
70 
71 TaskToolBox::~TaskToolBox()
72 {
73     ImplTaskItem* pItem = mpItemList->First();
74     while ( pItem )
75     {
76         delete pItem;
77         pItem = mpItemList->Next();
78     }
79 
80     delete mpItemList;
81 }
82 
83 // -----------------------------------------------------------------------
84 
85 void TaskToolBox::ActivateTaskItem( sal_uInt16 nItemId, sal_Bool bMinActivate )
86 {
87     if ( nItemId )
88     {
89         if ( nItemId != mnActiveItemId )
90         {
91             if ( mnActiveItemId )
92                 CheckItem( mnActiveItemId, sal_False );
93             CheckItem( nItemId );
94             mnActiveItemId = nItemId;
95         }
96         else
97         {
98             if ( !bMinActivate )
99                 return;
100 
101             mbMinActivate = sal_True;
102         }
103 
104         mnTaskItem = nItemId-1;
105         ActivateTask();
106         mnTaskItem = 0;
107         mbMinActivate = sal_False;
108     }
109 }
110 
111 // -----------------------------------------------------------------------
112 
113 void TaskToolBox::ActivateTask()
114 {
115     maActivateTaskHdl.Call( this );
116 }
117 
118 // -----------------------------------------------------------------------
119 
120 void TaskToolBox::ContextMenu()
121 {
122     maContextMenuHdl.Call( this );
123 }
124 
125 // -----------------------------------------------------------------------
126 
127 void TaskToolBox::MouseButtonDown( const MouseEvent& rMEvt )
128 {
129     if ( !rMEvt.IsRight() )
130         ToolBox::MouseButtonDown( rMEvt );
131 }
132 
133 // -----------------------------------------------------------------------
134 
135 void TaskToolBox::Resize()
136 {
137     mnOldItemCount  = mpItemList->Count();
138     mnUpdatePos     = (sal_uInt16)mnOldItemCount;
139     mnUpdateNewPos  = TOOLBOX_ITEM_NOTFOUND;
140     ImplFormatTaskToolBox();
141     ToolBox::Resize();
142 }
143 
144 // -----------------------------------------------------------------------
145 
146 void TaskToolBox::Command( const CommandEvent& rCEvt )
147 {
148     if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
149     {
150         sal_uInt16 nItemId = GetItemId( rCEvt.GetMousePosPixel() );
151 // Dies machen wir nicht mehr, da es von zu vielen als stoerend empfunden wurde
152 //        ActivateTaskItem( nItemId );
153         mnTaskItem = nItemId-1;
154 
155         maContextMenuPos = rCEvt.GetMousePosPixel();
156         ContextMenu();
157         maContextMenuPos = Point();
158         mnTaskItem = 0;
159     }
160     else
161         ToolBox::Command( rCEvt );
162 }
163 
164 // -----------------------------------------------------------------------
165 
166 void TaskToolBox::RequestHelp( const HelpEvent& rHEvt )
167 {
168     if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
169     {
170         sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
171 
172         if ( nItemId )
173         {
174             ImplTaskItem* pItem = mpItemList->GetObject( nItemId-1 );
175             if ( pItem )
176             {
177                 if ( pItem->maText != GetItemText( nItemId ) )
178                 {
179                     Rectangle aItemRect = GetItemRect( nItemId );
180                     if ( rHEvt.GetMode() & HELPMODE_QUICK )
181                         Help::ShowQuickHelp( this, aItemRect, pItem->maText );
182                     else
183                         Help::ShowBalloon( this, aItemRect.Center(), aItemRect, pItem->maText );
184                 }
185                 else
186                     Help::ShowQuickHelp( this, Rectangle(), String() );
187                 return;
188             }
189         }
190     }
191 
192     ToolBox::RequestHelp( rHEvt );
193 }
194 
195 // -----------------------------------------------------------------------
196 
197 void TaskToolBox::Select()
198 {
199     sal_uInt16 nItemId = GetCurItemId();
200     ActivateTaskItem( nItemId, sal_True );
201 }
202 
203 // -----------------------------------------------------------------------
204 
205 void TaskToolBox::ImplFormatTaskToolBox()
206 {
207     if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
208     {
209         // Eintraege aus der Liste entfernen
210         while ( mpItemList->Count() > mnUpdatePos )
211             delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
212         mnUpdateNewPos = mnUpdatePos;
213     }
214 
215     // Maximale Itemgroesse berechnen
216     long nOldMaxTextWidth = mnMaxTextWidth;
217     mnMaxTextWidth = 70;
218     if ( mpItemList->Count() )
219     {
220         long nWinSize = GetOutputSizePixel().Width()-8;
221         long nItemSize = mpItemList->GetObject(0)->maImage.GetSizePixel().Width()+7+TASKBOX_TASKOFF+2;
222         nWinSize -= mpItemList->Count()*nItemSize;
223         if ( nWinSize > 0 )
224             nWinSize /= mpItemList->Count();
225         else
226             nWinSize = 0;
227         if ( nWinSize < mnMaxTextWidth )
228             mnMaxTextWidth = nWinSize;
229         if ( (mnMaxTextWidth < nOldMaxTextWidth) ||
230              ((mnMaxTextWidth-nOldMaxTextWidth > 3) &&
231               (mnSmallItem != TOOLBOX_ITEM_NOTFOUND)) )
232         {
233             mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
234             mnUpdateNewPos = 0;
235         }
236     }
237 
238     // Eintraege aus der ToolBox entfernen, die ersetzt werden
239     sal_uInt16 nBtnPos = (mnUpdateNewPos*2);
240     while ( nBtnPos < GetItemCount() )
241         RemoveItem( nBtnPos );
242     if ( mnUpdateNewPos <= (mnActiveItemId-1) )
243         mnActiveItemId = 0;
244 
245     // Neue Eintrage einfuegen
246     sal_uInt16 i = mnUpdateNewPos;
247     while ( i < mpItemList->Count() )
248     {
249         ImplTaskItem* pItem = mpItemList->GetObject( i );
250 
251         // Textlaenge berechnen
252         XubString aText = pItem->maText;
253         if ( !aText.Len() )
254             aText = ' ';
255         long nTxtWidth = GetTextWidth( aText );
256         if ( nTxtWidth > mnMaxTextWidth )
257         {
258             if ( mnSmallItem == TOOLBOX_ITEM_NOTFOUND )
259                 mnSmallItem = i;
260             // 3 == Len of "..."
261             aText.AppendAscii( "..." );
262             do
263             {
264                 aText.Erase( aText.Len()-3-1, 1 );
265                 nTxtWidth = GetTextWidth( aText );
266             }
267             while ( (nTxtWidth > mnMaxTextWidth) && (aText.Len() > 3) );
268         }
269 
270         sal_uInt16 nItemId = i+1;
271         if ( aText.EqualsAscii( "..." ) )
272             InsertItem( nItemId, pItem->maImage, TIB_LEFT );
273         else
274             InsertItem( nItemId, pItem->maImage, aText, TIB_LEFT );
275         InsertSeparator( TOOLBOX_APPEND, TASKBOX_TASKOFF );
276         i++;
277     }
278 
279     if ( mnUpdateNewPos != 0 )
280         mnMaxTextWidth = nOldMaxTextWidth;
281 
282     if ( mnNewActivePos+1 != mnActiveItemId )
283     {
284         if ( mnActiveItemId )
285             CheckItem( mnActiveItemId, sal_False );
286         mnActiveItemId = mnNewActivePos+1;
287         CheckItem( mnActiveItemId );
288     }
289 }
290 
291 // -----------------------------------------------------------------------
292 
293 void TaskToolBox::StartUpdateTask()
294 {
295     mnOldItemCount  = mpItemList->Count();
296     mnUpdatePos     = 0;
297     mnUpdateNewPos  = TOOLBOX_ITEM_NOTFOUND;
298     mnNewActivePos  = 0xFFFE;
299 }
300 
301 // -----------------------------------------------------------------------
302 
303 void TaskToolBox::UpdateTask( const Image& rImage, const String& rText,
304                               sal_Bool bActive )
305 {
306     ImplTaskItem* pItem = mpItemList->GetObject( mnUpdatePos );
307     if ( pItem )
308     {
309         if ( (pItem->maText != rText) || (pItem->maImage != rImage) )
310         {
311             // Eintraege aus der Liste entfernen
312             while ( mpItemList->Count() > mnUpdatePos )
313                 delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
314             pItem = NULL;
315         }
316     }
317 
318     if ( !pItem )
319     {
320         if ( mnUpdatePos < mnUpdateNewPos )
321             mnUpdateNewPos = mnUpdatePos;
322 
323         pItem           = new ImplTaskItem;
324         pItem->maImage  = rImage;
325         pItem->maText   = rText;
326         mpItemList->Insert( pItem, LIST_APPEND );
327     }
328 
329     if ( bActive )
330         mnNewActivePos = mnUpdatePos;
331 
332     mnUpdatePos++;
333 }
334 
335 // -----------------------------------------------------------------------
336 
337 void TaskToolBox::EndUpdateTask()
338 {
339     if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
340     {
341         // Eintraege aus der Liste entfernen
342         while ( mpItemList->Count() > mnUpdatePos )
343             delete mpItemList->Remove( (sal_uLong)mnUpdatePos );
344         mnUpdateNewPos = mnUpdatePos;
345     }
346 
347     ImplFormatTaskToolBox();
348 }
349 
350