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 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 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 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 109 void TaskToolBox::ActivateTask() 110 { 111 maActivateTaskHdl.Call( this ); 112 } 113 114 // ----------------------------------------------------------------------- 115 116 void TaskToolBox::ContextMenu() 117 { 118 maContextMenuHdl.Call( this ); 119 } 120 121 // ----------------------------------------------------------------------- 122 123 void TaskToolBox::MouseButtonDown( const MouseEvent& rMEvt ) 124 { 125 if ( !rMEvt.IsRight() ) 126 ToolBox::MouseButtonDown( rMEvt ); 127 } 128 129 // ----------------------------------------------------------------------- 130 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 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 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 193 void TaskToolBox::Select() 194 { 195 sal_uInt16 nItemId = GetCurItemId(); 196 ActivateTaskItem( nItemId, sal_True ); 197 } 198 199 // ----------------------------------------------------------------------- 200 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 289 void TaskToolBox::StartUpdateTask() 290 { 291 mnOldItemCount = mpItemList->Count(); 292 mnUpdatePos = 0; 293 mnUpdateNewPos = TOOLBOX_ITEM_NOTFOUND; 294 mnNewActivePos = 0xFFFE; 295 } 296 297 // ----------------------------------------------------------------------- 298 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 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