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/help.hxx> 36 #include <svtools/taskbar.hxx> 37 38 // ======================================================================= 39 40 TaskButtonBar::TaskButtonBar( Window* pParent, WinBits nWinStyle ) : 41 ToolBox( pParent, nWinStyle | WB_3DLOOK ) 42 { 43 SetAlign( WINDOWALIGN_BOTTOM ); 44 SetButtonType( BUTTON_SYMBOLTEXT ); 45 } 46 47 // ----------------------------------------------------------------------- 48 49 TaskButtonBar::~TaskButtonBar() 50 { 51 } 52 53 // ----------------------------------------------------------------------- 54 55 void TaskButtonBar::RequestHelp( const HelpEvent& rHEvt ) 56 { 57 ToolBox::RequestHelp( rHEvt ); 58 } 59 60 // ======================================================================= 61 62 WindowArrange::WindowArrange() 63 { 64 mpWinList = new List; 65 } 66 67 // ----------------------------------------------------------------------- 68 69 WindowArrange::~WindowArrange() 70 { 71 delete mpWinList; 72 } 73 74 // ----------------------------------------------------------------------- 75 76 static sal_uInt16 ImplCeilSqareRoot( sal_uInt16 nVal ) 77 { 78 sal_uInt16 i; 79 80 // Ueberlauf verhindern 81 if ( nVal > 0xFE * 0xFE ) 82 return 0xFE; 83 84 for ( i=0; i*i < nVal; i++ ) 85 {} 86 87 return i; 88 } 89 90 // ----------------------------------------------------------------------- 91 92 static void ImplPosSizeWindow( Window* pWindow, 93 long nX, long nY, long nWidth, long nHeight ) 94 { 95 if ( nWidth < 32 ) 96 nWidth = 32; 97 if ( nHeight < 24 ) 98 nHeight = 24; 99 pWindow->SetPosSizePixel( nX, nY, nWidth, nHeight ); 100 } 101 102 // ----------------------------------------------------------------------- 103 104 void WindowArrange::ImplTile( const Rectangle& rRect ) 105 { 106 sal_uInt16 nCount = (sal_uInt16)mpWinList->Count(); 107 if ( nCount < 3 ) 108 { 109 ImplVert( rRect ); 110 return; 111 } 112 113 sal_uInt16 i; 114 sal_uInt16 j; 115 sal_uInt16 nCols; 116 sal_uInt16 nRows; 117 sal_uInt16 nActRows; 118 sal_uInt16 nOffset; 119 long nOverWidth; 120 long nOverHeight; 121 Window* pWindow; 122 long nX = rRect.Left(); 123 long nY = rRect.Top(); 124 long nWidth = rRect.GetWidth(); 125 long nHeight = rRect.GetHeight(); 126 long nRectY = nY; 127 long nRectWidth = nWidth; 128 long nRectHeight = nHeight; 129 long nTempWidth; 130 long nTempHeight; 131 132 nCols = ImplCeilSqareRoot( nCount ); 133 nOffset = (nCols*nCols) - nCount; 134 if ( nOffset >= nCols ) 135 { 136 nRows = nCols -1; 137 nOffset = nOffset - nCols; 138 } 139 else 140 nRows = nCols; 141 142 nWidth /= nCols; 143 if ( nWidth < 1 ) 144 nWidth = 1; 145 nOverWidth = nRectWidth-(nWidth*nCols); 146 147 pWindow = (Window*)mpWinList->First(); 148 for ( i = 0; i < nCols; i++ ) 149 { 150 if ( i < nOffset ) 151 nActRows = nRows - 1; 152 else 153 nActRows = nRows; 154 155 nTempWidth = nWidth; 156 if ( nOverWidth > 0 ) 157 { 158 nTempWidth++; 159 nOverWidth--; 160 } 161 162 nHeight = nRectHeight / nActRows; 163 if ( nHeight < 1 ) 164 nHeight = 1; 165 nOverHeight = nRectHeight-(nHeight*nActRows); 166 for ( j = 0; j < nActRows; j++ ) 167 { 168 // Ueberhang verteilen 169 nTempHeight = nHeight; 170 if ( nOverHeight > 0 ) 171 { 172 nTempHeight++; 173 nOverHeight--; 174 } 175 ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nTempHeight ); 176 nY += nTempHeight; 177 178 pWindow = (Window*)mpWinList->Next(); 179 if ( !pWindow ) 180 break; 181 } 182 183 nX += nWidth; 184 nY = nRectY; 185 186 if ( !pWindow ) 187 break; 188 } 189 } 190 191 // ----------------------------------------------------------------------- 192 193 void WindowArrange::ImplHorz( const Rectangle& rRect ) 194 { 195 long nCount = (long)mpWinList->Count(); 196 long nX = rRect.Left(); 197 long nY = rRect.Top(); 198 long nWidth = rRect.GetWidth(); 199 long nHeight = rRect.GetHeight(); 200 long nRectHeight = nHeight; 201 long nOver; 202 long nTempHeight; 203 Window* pWindow; 204 205 nHeight /= nCount; 206 if ( nHeight < 1 ) 207 nHeight = 1; 208 nOver = nRectHeight - (nCount*nHeight); 209 pWindow = (Window*)mpWinList->First(); 210 while ( pWindow ) 211 { 212 nTempHeight = nHeight; 213 if ( nOver > 0 ) 214 { 215 nTempHeight++; 216 nOver--; 217 } 218 ImplPosSizeWindow( pWindow, nX, nY, nWidth, nTempHeight ); 219 nY += nTempHeight; 220 221 pWindow = (Window*)mpWinList->Next(); 222 } 223 } 224 225 // ----------------------------------------------------------------------- 226 227 void WindowArrange::ImplVert( const Rectangle& rRect ) 228 { 229 long nCount = (long)mpWinList->Count(); 230 long nX = rRect.Left(); 231 long nY = rRect.Top(); 232 long nWidth = rRect.GetWidth(); 233 long nHeight = rRect.GetHeight(); 234 long nRectWidth = nWidth; 235 long nOver; 236 long nTempWidth; 237 Window* pWindow; 238 239 nWidth /= nCount; 240 if ( nWidth < 1 ) 241 nWidth = 1; 242 nOver = nRectWidth - (nCount*nWidth); 243 pWindow = (Window*)mpWinList->First(); 244 while ( pWindow ) 245 { 246 nTempWidth = nWidth; 247 if ( nOver > 0 ) 248 { 249 nTempWidth++; 250 nOver--; 251 } 252 ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nHeight ); 253 nX += nTempWidth; 254 255 pWindow = (Window*)mpWinList->Next(); 256 } 257 } 258 259 // ----------------------------------------------------------------------- 260 261 void WindowArrange::ImplCascade( const Rectangle& rRect ) 262 { 263 long nX = rRect.Left(); 264 long nY = rRect.Top(); 265 long nWidth = rRect.GetWidth(); 266 long nHeight = rRect.GetHeight(); 267 long nRectWidth = nWidth; 268 long nRectHeight = nHeight; 269 long nOff; 270 long nCascadeWins; 271 sal_Int32 nLeftBorder; 272 sal_Int32 nTopBorder; 273 sal_Int32 nRightBorder; 274 sal_Int32 nBottomBorder; 275 long nStartOverWidth; 276 long nStartOverHeight; 277 long nOverWidth = 0; 278 long nOverHeight = 0; 279 long nTempX; 280 long nTempY; 281 long nTempWidth; 282 long nTempHeight; 283 long i; 284 Window* pWindow; 285 Window* pTempWindow; 286 287 // Border-Fenster suchen um den Versatz zu ermitteln 288 pTempWindow = (Window*)mpWinList->First(); 289 pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder ); 290 while ( !nTopBorder ) 291 { 292 Window* pBrdWin = pTempWindow->GetWindow( WINDOW_REALPARENT ); 293 if ( !pBrdWin || (pBrdWin->GetWindow( WINDOW_CLIENT ) != pTempWindow) ) 294 break; 295 pTempWindow = pBrdWin; 296 pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder ); 297 } 298 if ( !nTopBorder ) 299 nTopBorder = 22; 300 nOff = nTopBorder; 301 302 nCascadeWins = nRectHeight / 3 / nOff; 303 if ( !nCascadeWins ) 304 nCascadeWins = 1; 305 nWidth -= nCascadeWins*nOff; 306 nHeight -= nCascadeWins*nOff; 307 if ( nWidth < 1 ) 308 nWidth = 1; 309 if ( nHeight < 1 ) 310 nHeight = 1; 311 312 nStartOverWidth = nRectWidth-(nWidth+(nCascadeWins*nOff)); 313 nStartOverHeight = nRectHeight-(nHeight+(nCascadeWins*nOff)); 314 315 i = 0; 316 pWindow = (Window*)mpWinList->First(); 317 while ( pWindow ) 318 { 319 if ( !i ) 320 { 321 nOverWidth = nStartOverWidth; 322 nOverHeight = nStartOverHeight; 323 } 324 325 // Position 326 nTempX = nX + (i*nOff); 327 nTempY = nY + (i*nOff); 328 329 // Ueberhang verteilen 330 nTempWidth = nWidth; 331 if ( nOverWidth > 0 ) 332 { 333 nTempWidth++; 334 nOverWidth--; 335 } 336 nTempHeight = nHeight; 337 if ( nOverHeight > 0 ) 338 { 339 nTempHeight++; 340 nOverHeight--; 341 } 342 343 ImplPosSizeWindow( pWindow, nTempX, nTempY, nTempWidth, nTempHeight ); 344 345 if ( i < nCascadeWins ) 346 i++; 347 else 348 i = 0; 349 350 pWindow = (Window*)mpWinList->Next(); 351 } 352 } 353 354 // ----------------------------------------------------------------------- 355 356 void WindowArrange::Arrange( sal_uInt16 nType, const Rectangle& rRect ) 357 { 358 if ( !mpWinList->Count() ) 359 return; 360 361 switch ( nType ) 362 { 363 case WINDOWARRANGE_TILE: 364 ImplTile( rRect ); 365 break; 366 case WINDOWARRANGE_HORZ: 367 ImplHorz( rRect ); 368 break; 369 case WINDOWARRANGE_VERT: 370 ImplVert( rRect ); 371 break; 372 case WINDOWARRANGE_CASCADE: 373 ImplCascade( rRect ); 374 break; 375 } 376 } 377 378