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