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 #include <limits.h> 28 #include <tools/debug.hxx> 29 #include <vcl/wall.hxx> 30 #include <vcl/help.hxx> 31 #include <vcl/decoview.hxx> 32 #include <vcl/svapp.hxx> 33 #include <tools/poly.hxx> 34 #include <vcl/lineinfo.hxx> 35 #include <vcl/i18nhelp.hxx> 36 #include <vcl/mnemonic.hxx> 37 #include <vcl/controllayout.hxx> 38 39 #include <svtools/ivctrl.hxx> 40 #include "imivctl.hxx" 41 #include <svtools/svmedit.hxx> 42 43 #include <algorithm> 44 #include <memory> 45 46 #define DD_SCROLL_PIXEL 24 47 #define IMPICNVIEW_ACC_RETURN 1 48 #define IMPICNVIEW_ACC_ESCAPE 2 49 50 #define DRAWTEXT_FLAGS_ICON \ 51 ( TEXT_DRAW_CENTER | TEXT_DRAW_TOP | TEXT_DRAW_ENDELLIPSIS | \ 52 TEXT_DRAW_CLIP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MNEMONIC ) 53 54 #define DRAWTEXT_FLAGS_SMALLICON (TEXT_DRAW_LEFT|TEXT_DRAW_ENDELLIPSIS|TEXT_DRAW_CLIP) 55 56 #define EVENTID_SHOW_CURSOR ((void*)1) 57 #define EVENTID_ADJUST_SCROLLBARS ((void*)2) 58 59 struct SvxIconChoiceCtrlEntry_Impl 60 { 61 SvxIconChoiceCtrlEntry* _pEntry; 62 Point _aPos; 63 SvxIconChoiceCtrlEntry_Impl( SvxIconChoiceCtrlEntry* pEntry, const Rectangle& rBoundRect ) 64 : _pEntry( pEntry), _aPos( rBoundRect.TopLeft()) {} 65 }; 66 67 static sal_Bool bEndScrollInvalidate = sal_True; 68 69 // ---------------------------------------------------------------------------------------------- 70 71 class IcnViewEdit_Impl : public MultiLineEdit 72 { 73 Link aCallBackHdl; 74 Accelerator aAccReturn; 75 Accelerator aAccEscape; 76 Timer aTimer; 77 sal_Bool bCanceled; 78 sal_Bool bAlreadyInCallback; 79 sal_Bool bGrabFocus; 80 81 void CallCallBackHdl_Impl(); 82 DECL_LINK( Timeout_Impl, Timer * ); 83 DECL_LINK( ReturnHdl_Impl, Accelerator * ); 84 DECL_LINK( EscapeHdl_Impl, Accelerator * ); 85 86 public: 87 88 IcnViewEdit_Impl( 89 SvtIconChoiceCtrl* pParent, 90 const Point& rPos, 91 const Size& rSize, 92 const XubString& rData, 93 const Link& rNotifyEditEnd ); 94 95 ~IcnViewEdit_Impl(); 96 virtual void KeyInput( const KeyEvent& rKEvt ); 97 virtual long PreNotify( NotifyEvent& rNEvt ); 98 sal_Bool EditingCanceled() const { return bCanceled; } 99 void StopEditing( sal_Bool bCancel = sal_False ); 100 sal_Bool IsGrabFocus() const { return bGrabFocus; } 101 }; 102 103 // ---------------------------------------------------------------------------------------------- 104 105 // ---------------------------------------------------------------------------------------------- 106 107 SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl( SvtIconChoiceCtrl* pCurView, 108 WinBits nWinStyle ) : 109 aEntries( this ), 110 aVerSBar( pCurView, WB_DRAG | WB_VSCROLL ), 111 aHorSBar( pCurView, WB_DRAG | WB_HSCROLL ), 112 aScrBarBox( pCurView ), 113 aImageSize( 32, 32 ), 114 pColumns( 0 ) 115 { 116 bChooseWithCursor=sal_False; 117 pEntryPaintDev = 0; 118 pCurEditedEntry = 0; 119 pCurHighlightFrame = 0; 120 pEdit = 0; 121 pAnchor = 0; 122 pDraggedSelection = 0; 123 pPrevDropTarget = 0; 124 pHdlEntry = 0; 125 pHead = NULL; 126 pCursor = NULL; 127 bUpdateMode = sal_True; 128 bEntryEditingEnabled = sal_False; 129 bInDragDrop = sal_False; 130 bHighlightFramePressed = sal_False; 131 eSelectionMode = MULTIPLE_SELECTION; 132 pView = pCurView; 133 pZOrderList = new List; //SvPtrarr; 134 ePositionMode = IcnViewPositionModeFree; 135 SetStyle( nWinStyle ); 136 nFlags = 0; 137 nUserEventAdjustScrBars = 0; 138 nUserEventShowCursor = 0; 139 nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH; 140 nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT; 141 pDDRefEntry = 0; 142 pDDDev = 0; 143 pDDBufDev = 0; 144 pDDTempDev = 0; 145 eTextMode = IcnShowTextShort; 146 pImpCursor = new IcnCursor_Impl( this ); 147 pGridMap = new IcnGridMap_Impl( this ); 148 149 aVerSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollUpDownHdl ) ); 150 aHorSBar.SetScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl ) ); 151 Link aEndScrollHdl( LINK( this, SvxIconChoiceCtrl_Impl, EndScrollHdl ) ); 152 aVerSBar.SetEndScrollHdl( aEndScrollHdl ); 153 aHorSBar.SetEndScrollHdl( aEndScrollHdl ); 154 155 nHorSBarHeight = aHorSBar.GetSizePixel().Height(); 156 nVerSBarWidth = aVerSBar.GetSizePixel().Width(); 157 158 aEditTimer.SetTimeout( 800 ); 159 aEditTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,EditTimeoutHdl)); 160 aAutoArrangeTimer.SetTimeout( 100 ); 161 aAutoArrangeTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,AutoArrangeHdl)); 162 aCallSelectHdlTimer.SetTimeout( 500 ); 163 aCallSelectHdlTimer.SetTimeoutHdl( LINK(this,SvxIconChoiceCtrl_Impl,CallSelectHdlHdl)); 164 165 aDocRectChangedTimer.SetTimeout( 50 ); 166 aDocRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,DocRectChangedHdl)); 167 aVisRectChangedTimer.SetTimeout( 50 ); 168 aVisRectChangedTimer.SetTimeoutHdl(LINK(this,SvxIconChoiceCtrl_Impl,VisRectChangedHdl)); 169 170 Clear( sal_True ); 171 172 SetGrid( Size(100, 70) ); 173 } 174 175 SvxIconChoiceCtrl_Impl::~SvxIconChoiceCtrl_Impl() 176 { 177 pCurEditedEntry = 0; 178 DELETEZ(pEdit); 179 Clear(); 180 StopEditTimer(); 181 CancelUserEvents(); 182 delete pZOrderList; 183 delete pImpCursor; 184 delete pGridMap; 185 delete pDDDev; 186 delete pDDBufDev; 187 delete pDDTempDev; 188 delete pDraggedSelection; 189 delete pEntryPaintDev; 190 ClearSelectedRectList(); 191 ClearColumnList(); 192 } 193 194 void SvxIconChoiceCtrl_Impl::Clear( sal_Bool bInCtor ) 195 { 196 StopEntryEditing( sal_True ); 197 nSelectionCount = 0; 198 DELETEZ(pDraggedSelection); 199 bInDragDrop = sal_False; 200 pCurHighlightFrame = 0; 201 StopEditTimer(); 202 CancelUserEvents(); 203 ShowCursor( sal_False ); 204 bBoundRectsDirty = sal_False; 205 nMaxBoundHeight = 0; 206 207 nFlags &= ~(F_PAINTED | F_MOVED_ENTRIES); 208 pCursor = 0; 209 if( !bInCtor ) 210 { 211 pImpCursor->Clear(); 212 pGridMap->Clear(); 213 aVirtOutputSize.Width() = 0; 214 aVirtOutputSize.Height() = 0; 215 Size aSize( pView->GetOutputSizePixel() ); 216 nMaxVirtWidth = aSize.Width() - nVerSBarWidth; 217 if( nMaxVirtWidth <= 0 ) 218 nMaxVirtWidth = DEFAULT_MAX_VIRT_WIDTH; 219 nMaxVirtHeight = aSize.Height() - nHorSBarHeight; 220 if( nMaxVirtHeight <= 0 ) 221 nMaxVirtHeight = DEFAULT_MAX_VIRT_HEIGHT; 222 pZOrderList->Clear(); //Remove(0,pZOrderList->Count()); 223 SetOrigin( Point() ); 224 if( bUpdateMode ) 225 pView->Invalidate(INVALIDATE_NOCHILDREN); 226 } 227 AdjustScrollBars(); 228 sal_uLong nCount = aEntries.Count(); 229 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 230 { 231 SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 232 delete pCur; 233 } 234 aEntries.Clear(); 235 DocRectChanged(); 236 VisRectChanged(); 237 } 238 239 void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle ) 240 { 241 nWinBits = nWinStyle; 242 nCurTextDrawFlags = DRAWTEXT_FLAGS_ICON; 243 if( nWinBits & (WB_SMALLICON | WB_DETAILS) ) 244 nCurTextDrawFlags = DRAWTEXT_FLAGS_SMALLICON; 245 if( nWinBits & WB_NOSELECTION ) 246 eSelectionMode = NO_SELECTION; 247 if( !(nWinStyle & (WB_ALIGN_TOP | WB_ALIGN_LEFT))) 248 nWinBits |= WB_ALIGN_LEFT; 249 if( (nWinStyle & WB_DETAILS)) 250 { 251 if( !pColumns ) 252 SetColumn( 0, SvxIconChoiceCtrlColumnInfo( 0, 100, IcnViewAlignLeft )); 253 } 254 } 255 256 IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollUpDownHdl, ScrollBar*, pScrollBar ) 257 { 258 StopEntryEditing( sal_True ); 259 // Pfeil hoch: delta=-1; Pfeil runter: delta=+1 260 Scroll( 0, pScrollBar->GetDelta(), sal_True ); 261 bEndScrollInvalidate = sal_True; 262 return 0; 263 } 264 265 IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollLeftRightHdl, ScrollBar*, pScrollBar ) 266 { 267 StopEntryEditing( sal_True ); 268 // Pfeil links: delta=-1; Pfeil rechts: delta=+1 269 Scroll( pScrollBar->GetDelta(), 0, sal_True ); 270 bEndScrollInvalidate = sal_True; 271 return 0; 272 } 273 274 IMPL_LINK( SvxIconChoiceCtrl_Impl, EndScrollHdl, void*, EMPTYARG ) 275 { 276 if( pView->HasBackground() && !pView->GetBackground().IsScrollable() && 277 bEndScrollInvalidate ) 278 { 279 pView->Invalidate(INVALIDATE_NOCHILDREN); 280 } 281 return 0; 282 } 283 284 void SvxIconChoiceCtrl_Impl::FontModified() 285 { 286 StopEditTimer(); 287 DELETEZ(pDDDev); 288 DELETEZ(pDDBufDev); 289 DELETEZ(pDDTempDev); 290 DELETEZ(pEntryPaintDev); 291 SetDefaultTextSize(); 292 ShowCursor( sal_False ); 293 ShowCursor( sal_True ); 294 } 295 296 void SvxIconChoiceCtrl_Impl::InsertEntry( SvxIconChoiceCtrlEntry* pEntry, sal_uLong nPos, 297 const Point* pPos ) 298 { 299 StopEditTimer(); 300 aEntries.Insert( pEntry, nPos ); 301 if( (nFlags & F_ENTRYLISTPOS_VALID) && nPos >= aEntries.Count() - 1 ) 302 pEntry->nPos = aEntries.Count() - 1; 303 else 304 nFlags &= ~F_ENTRYLISTPOS_VALID; 305 306 pZOrderList->Insert( (void*)pEntry, LIST_APPEND ); //pZOrderList->Count() ); 307 pImpCursor->Clear(); 308 // pGridMap->Clear(); 309 if( pPos ) 310 { 311 Size aSize( CalcBoundingSize( pEntry ) ); 312 SetBoundingRect_Impl( pEntry, *pPos, aSize ); 313 SetEntryPos( pEntry, *pPos, sal_False, sal_True, sal_True /*keep grid map*/ ); 314 pEntry->nFlags |= ICNVIEW_FLAG_POS_MOVED; 315 SetEntriesMoved( sal_True ); 316 } 317 else 318 { 319 // wenn der UpdateMode sal_True ist, wollen wir nicht pauschal alle 320 // BoundRects auf 'zu ueberpruefen' setzen, sondern nur das des 321 // neuen Eintrags. Deshalb kein InvalidateBoundingRect aufrufen! 322 pEntry->aRect.Right() = LONG_MAX; 323 if( bUpdateMode ) 324 { 325 FindBoundingRect( pEntry ); 326 Rectangle aOutputArea( GetOutputRect() ); 327 pGridMap->OccupyGrids( pEntry ); 328 if( !aOutputArea.IsOver( pEntry->aRect ) ) 329 return; // ist nicht sichtbar 330 pView->Invalidate( pEntry->aRect ); 331 } 332 else 333 InvalidateBoundingRect( pEntry->aRect ); 334 } 335 } 336 337 void SvxIconChoiceCtrl_Impl::CreateAutoMnemonics( MnemonicGenerator* _pGenerator ) 338 { 339 ::std::auto_ptr< MnemonicGenerator > pAutoDeleteOwnGenerator; 340 if ( !_pGenerator ) 341 { 342 _pGenerator = new MnemonicGenerator; 343 pAutoDeleteOwnGenerator.reset( _pGenerator ); 344 } 345 346 sal_uLong nEntryCount = GetEntryCount(); 347 sal_uLong i; 348 349 // insert texts in generator 350 for( i = 0; i < nEntryCount; ++i ) 351 { 352 DBG_ASSERT( GetEntry( i ), "-SvxIconChoiceCtrl_Impl::CreateAutoMnemonics(): more expected than provided!" ); 353 354 _pGenerator->RegisterMnemonic( GetEntry( i )->GetText() ); 355 } 356 357 // exchange texts with generated mnemonics 358 for( i = 0; i < nEntryCount; ++i ) 359 { 360 SvxIconChoiceCtrlEntry* pEntry = GetEntry( i ); 361 String aTxt = pEntry->GetText(); 362 363 if( _pGenerator->CreateMnemonic( aTxt ) ) 364 pEntry->SetText( aTxt ); 365 } 366 } 367 368 Rectangle SvxIconChoiceCtrl_Impl::GetOutputRect() const 369 { 370 Point aOrigin( pView->GetMapMode().GetOrigin() ); 371 aOrigin *= -1; 372 return Rectangle( aOrigin, aOutputSize ); 373 } 374 375 void SvxIconChoiceCtrl_Impl::SetListPositions() 376 { 377 if( nFlags & F_ENTRYLISTPOS_VALID ) 378 return; 379 380 sal_uLong nCount = aEntries.Count(); 381 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 382 { 383 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 384 pEntry->nPos = nCur; 385 } 386 nFlags |= F_ENTRYLISTPOS_VALID; 387 } 388 389 void SvxIconChoiceCtrl_Impl::RemoveEntry( SvxIconChoiceCtrlEntry* pEntry ) 390 { 391 sal_Bool bSyncSingleSelection; 392 // bei Single-Selection wird die Selektion beim Umsetzen des Cursors 393 // mitgefuehrt. Das soll aber nur erfolgen, wenn ueberhaupt ein 394 // Eintrag selektiert ist. 395 if( GetSelectionCount() ) 396 bSyncSingleSelection = sal_True; 397 else 398 bSyncSingleSelection = sal_False; 399 400 if( pEntry == pCurHighlightFrame ) 401 pCurHighlightFrame = 0; 402 403 if( bInDragDrop ) 404 { 405 DELETEZ(pDraggedSelection); 406 bInDragDrop = sal_False; 407 } 408 409 if( pEntry->IsSelected() ) 410 CallSelectHandler( 0 ); 411 412 if( aEntries.Count() == 1 && aEntries.GetObject(0) == pEntry ) 413 { 414 Clear(); 415 return; 416 } 417 418 StopEditTimer(); 419 if( pEntry == pAnchor ) 420 pAnchor = 0; 421 if( pEntry->IsSelected() ) 422 nSelectionCount--; 423 sal_Bool bEntryBoundValid = IsBoundingRectValid( pEntry->aRect ); 424 if( bEntryBoundValid ) 425 pView->Invalidate( pEntry->aRect ); 426 427 sal_Bool bSetNewCursor = sal_False; 428 SvxIconChoiceCtrlEntry* pNewCursor = NULL; 429 430 if( pEntry == pCursor ) 431 { 432 bSetNewCursor = sal_True; 433 pNewCursor = FindNewCursor(); 434 ShowCursor( sal_False ); 435 pCursor = 0; 436 } 437 438 sal_Bool bCurEntryPosValid = (nFlags & F_ENTRYLISTPOS_VALID) ? sal_True : sal_False; 439 if( bCurEntryPosValid && aEntries.GetObject(aEntries.Count()-1) != pEntry ) 440 nFlags &= ~F_ENTRYLISTPOS_VALID; 441 sal_uLong nPos = pZOrderList->GetPos( (void*)pEntry ); 442 pZOrderList->Remove( nPos ); 443 if( bCurEntryPosValid ) 444 { 445 DBG_ASSERT(aEntries.GetObject(pEntry->nPos)==pEntry,"RemoveEntry: Wrong nPos in entry"); 446 aEntries.Remove( pEntry->nPos ); 447 } 448 else 449 aEntries.Remove( pEntry ); 450 pImpCursor->Clear(); 451 pGridMap->Clear(); 452 delete pEntry; 453 if( IsAutoArrange() && aEntries.Count() ) 454 aAutoArrangeTimer.Start(); 455 if( bSetNewCursor ) 456 { 457 // Fokusrechteck asynchron einblenden, um das Loeschen einer 458 // Multiselektion zu beschleunigen. 459 SetCursor( pNewCursor, bSyncSingleSelection, sal_True ); 460 } 461 } 462 463 void SvxIconChoiceCtrl_Impl::SelectEntry( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bSelect, 464 sal_Bool bCallHdl, sal_Bool bAdd, sal_Bool bSyncPaint ) 465 { 466 if( eSelectionMode == NO_SELECTION ) 467 return; 468 469 if( !bAdd ) 470 { 471 if ( 0 == ( nFlags & F_CLEARING_SELECTION ) ) 472 { 473 nFlags |= F_CLEARING_SELECTION; 474 DeselectAllBut( pEntry, sal_True ); 475 nFlags &= ~F_CLEARING_SELECTION; 476 } 477 } 478 if( pEntry->IsSelected() != bSelect ) 479 { 480 pHdlEntry = pEntry; 481 sal_uInt16 nEntryFlags = pEntry->GetFlags(); 482 if( bSelect ) 483 { 484 nEntryFlags |= ICNVIEW_FLAG_SELECTED; 485 pEntry->AssignFlags( nEntryFlags ); 486 nSelectionCount++; 487 if( bCallHdl ) 488 CallSelectHandler( pEntry ); 489 } 490 else 491 { 492 nEntryFlags &= ~( ICNVIEW_FLAG_SELECTED); 493 pEntry->AssignFlags( nEntryFlags ); 494 nSelectionCount--; 495 if( bCallHdl ) 496 CallSelectHandler( 0 ); 497 } 498 EntrySelected( pEntry, bSelect, bSyncPaint ); 499 } 500 } 501 502 void SvxIconChoiceCtrl_Impl::EntrySelected( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bSelect, 503 sal_Bool bSyncPaint ) 504 { 505 // bei SingleSelection dafuer sorgen, dass der Cursor immer 506 // auf dem (einzigen) selektierten Eintrag steht. Aber nur, 507 // wenn es bereits einen Cursor gibt 508 if( bSelect && pCursor && 509 eSelectionMode == SINGLE_SELECTION && 510 pEntry != pCursor ) 511 { 512 SetCursor( pEntry ); 513 //DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?") 514 } 515 516 // beim Aufziehen nicht, da sonst die Schleife in SelectRect 517 // nicht richtig funktioniert! 518 if( !(nFlags & F_SELECTING_RECT) ) 519 ToTop( pEntry ); 520 if( bUpdateMode ) 521 { 522 if( pEntry == pCursor ) 523 ShowCursor( sal_False ); 524 if( pView->IsTracking() && (bSelect || !pView->HasBackground()) ) // beim Tracken immer synchron 525 PaintEntry( pEntry ); 526 else if( bSyncPaint ) // synchron & mit virtuellem OutDev! 527 PaintEntryVirtOutDev( pEntry ); 528 else 529 { 530 pView->Invalidate( CalcFocusRect( pEntry ) ); 531 } 532 if( pEntry == pCursor ) 533 ShowCursor( sal_True ); 534 } // if( bUpdateMode ) 535 536 // --> OD 2009-05-27 #i101012# 537 // emit vcl event LISTBOX_SELECT only in case that the given entry is selected. 538 if ( bSelect ) 539 { 540 CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry ); 541 } 542 // <-- 543 } 544 545 void SvxIconChoiceCtrl_Impl::ResetVirtSize() 546 { 547 StopEditTimer(); 548 aVirtOutputSize.Width() = 0; 549 aVirtOutputSize.Height() = 0; 550 sal_Bool bLockedEntryFound = sal_False; 551 const sal_uLong nCount = aEntries.Count(); 552 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 553 { 554 SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 555 pCur->ClearFlags( ICNVIEW_FLAG_POS_MOVED ); 556 if( pCur->IsPosLocked() ) 557 { 558 // VirtSize u.a. anpassen 559 if( !IsBoundingRectValid( pCur->aRect ) ) 560 FindBoundingRect( pCur ); 561 else 562 AdjustVirtSize( pCur->aRect ); 563 bLockedEntryFound = sal_True; 564 } 565 else 566 InvalidateBoundingRect( pCur->aRect ); 567 } 568 569 if( !(nWinBits & (WB_NOVSCROLL | WB_NOHSCROLL)) ) 570 { 571 Size aRealOutputSize( pView->GetOutputSizePixel() ); 572 if( aVirtOutputSize.Width() < aRealOutputSize.Width() || 573 aVirtOutputSize.Height() < aRealOutputSize.Height() ) 574 { 575 sal_uLong nGridCount = IcnGridMap_Impl::GetGridCount( 576 aRealOutputSize, (sal_uInt16)nGridDX, (sal_uInt16)nGridDY ); 577 if( nGridCount < nCount ) 578 { 579 if( nWinBits & WB_ALIGN_TOP ) 580 nMaxVirtWidth = aRealOutputSize.Width() - nVerSBarWidth; 581 else // WB_ALIGN_LEFT 582 nMaxVirtHeight = aRealOutputSize.Height() - nHorSBarHeight; 583 } 584 } 585 } 586 587 pImpCursor->Clear(); 588 pGridMap->Clear(); 589 VisRectChanged(); 590 } 591 592 void SvxIconChoiceCtrl_Impl::AdjustVirtSize( const Rectangle& rRect ) 593 { 594 long nHeightOffs = 0; 595 long nWidthOffs = 0; 596 597 if( aVirtOutputSize.Width() < (rRect.Right()+LROFFS_WINBORDER) ) 598 nWidthOffs = (rRect.Right()+LROFFS_WINBORDER) - aVirtOutputSize.Width(); 599 600 if( aVirtOutputSize.Height() < (rRect.Bottom()+TBOFFS_WINBORDER) ) 601 nHeightOffs = (rRect.Bottom()+TBOFFS_WINBORDER) - aVirtOutputSize.Height(); 602 603 if( nWidthOffs || nHeightOffs ) 604 { 605 Range aRange; 606 aVirtOutputSize.Width() += nWidthOffs; 607 aRange.Max() = aVirtOutputSize.Width(); 608 aHorSBar.SetRange( aRange ); 609 610 aVirtOutputSize.Height() += nHeightOffs; 611 aRange.Max() = aVirtOutputSize.Height(); 612 aVerSBar.SetRange( aRange ); 613 614 pImpCursor->Clear(); 615 pGridMap->OutputSizeChanged(); 616 AdjustScrollBars(); 617 DocRectChanged(); 618 } 619 } 620 621 void SvxIconChoiceCtrl_Impl::InitPredecessors() 622 { 623 DBG_ASSERT(!pHead,"SvxIconChoiceCtrl_Impl::InitPredecessors() >> Already initialized"); 624 sal_uLong nCount = aEntries.Count(); 625 if( nCount ) 626 { 627 SvxIconChoiceCtrlEntry* pPrev = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 ); 628 for( sal_uLong nCur = 1; nCur <= nCount; nCur++ ) 629 { 630 pPrev->ClearFlags( ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED | 631 ICNVIEW_FLAG_PRED_SET); 632 633 SvxIconChoiceCtrlEntry* pNext; 634 if( nCur == nCount ) 635 pNext = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 ); 636 else 637 pNext = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 638 pPrev->pflink = pNext; 639 pNext->pblink = pPrev; 640 pPrev = pNext; 641 } 642 pHead = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 ); 643 } 644 else 645 pHead = 0; 646 nFlags &= ~F_MOVED_ENTRIES; 647 } 648 649 void SvxIconChoiceCtrl_Impl::ClearPredecessors() 650 { 651 if( pHead ) 652 { 653 sal_uLong nCount = aEntries.Count(); 654 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 655 { 656 SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 657 pCur->pflink = 0; 658 pCur->pblink = 0; 659 pCur->ClearFlags( ICNVIEW_FLAG_PRED_SET ); 660 } 661 pHead = 0; 662 } 663 } 664 665 void SvxIconChoiceCtrl_Impl::Arrange( sal_Bool bKeepPredecessors, long nSetMaxVirtWidth, long nSetMaxVirtHeight ) 666 { 667 if ( nSetMaxVirtWidth != 0 ) 668 nMaxVirtWidth = nSetMaxVirtWidth; 669 else 670 nMaxVirtWidth = aOutputSize.Width(); 671 672 if ( nSetMaxVirtHeight != 0 ) 673 nMaxVirtHeight = nSetMaxVirtHeight; 674 else 675 nMaxVirtHeight = aOutputSize.Height(); 676 677 ImpArrange( bKeepPredecessors ); 678 } 679 680 void SvxIconChoiceCtrl_Impl::ImpArrange( sal_Bool bKeepPredecessors ) 681 { 682 static Point aEmptyPoint; 683 684 sal_Bool bOldUpdate = bUpdateMode; 685 Rectangle aCurOutputArea( GetOutputRect() ); 686 if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint ) 687 bUpdateMode = sal_False; 688 aAutoArrangeTimer.Stop(); 689 nFlags &= ~F_MOVED_ENTRIES; 690 nFlags |= F_ARRANGING; 691 StopEditTimer(); 692 ShowCursor( sal_False ); 693 ResetVirtSize(); 694 if( !bKeepPredecessors ) 695 ClearPredecessors(); 696 bBoundRectsDirty = sal_False; 697 SetOrigin( Point() ); 698 VisRectChanged(); 699 RecalcAllBoundingRectsSmart(); 700 // in der Detailsview muss das Invalidieren intelligenter erfolgen 701 //if( !(nWinBits & WB_DETAILS )) 702 pView->Invalidate( INVALIDATE_NOCHILDREN ); 703 nFlags &= ~F_ARRANGING; 704 if( (nWinBits & WB_SMART_ARRANGE) && aCurOutputArea.TopLeft() != aEmptyPoint ) 705 { 706 MakeVisible( aCurOutputArea ); 707 SetUpdateMode( bOldUpdate ); 708 } 709 ShowCursor( sal_True ); 710 } 711 712 void SvxIconChoiceCtrl_Impl::Paint( const Rectangle& rRect ) 713 { 714 bEndScrollInvalidate = sal_False; 715 716 #if defined(OV_DRAWGRID) 717 Color aOldColor ( pView->GetLineColor() ); 718 Color aColor( COL_BLACK ); 719 pView->SetLineColor( aColor ); 720 Point aOffs( pView->GetMapMode().GetOrigin()); 721 Size aXSize( pView->GetOutputSizePixel() ); 722 723 { 724 Point aStart( LROFFS_WINBORDER, 0 ); 725 Point aEnd( LROFFS_WINBORDER, aXSize.Height()); 726 aStart -= aOffs; 727 aEnd -= aOffs; 728 pView->DrawLine( aStart, aEnd ); 729 } 730 { 731 Point aStart( 0, TBOFFS_WINBORDER ); 732 Point aEnd( aXSize.Width(), TBOFFS_WINBORDER ); 733 aStart -= aOffs; 734 aEnd -= aOffs; 735 pView->DrawLine( aStart, aEnd ); 736 } 737 738 for( long nDX = nGridDX; nDX <= aXSize.Width(); nDX += nGridDX ) 739 { 740 Point aStart( nDX+LROFFS_WINBORDER, 0 ); 741 Point aEnd( nDX+LROFFS_WINBORDER, aXSize.Height()); 742 aStart -= aOffs; 743 aEnd -= aOffs; 744 pView->DrawLine( aStart, aEnd ); 745 } 746 for( long nDY = nGridDY; nDY <= aXSize.Height(); nDY += nGridDY ) 747 { 748 Point aStart( 0, nDY+TBOFFS_WINBORDER ); 749 Point aEnd( aXSize.Width(), nDY+TBOFFS_WINBORDER ); 750 aStart -= aOffs; 751 aEnd -= aOffs; 752 pView->DrawLine( aStart, aEnd ); 753 } 754 pView->SetLineColor( aOldColor ); 755 #endif 756 nFlags |= F_PAINTED; 757 758 if( !aEntries.Count() ) 759 return; 760 if( !pCursor ) 761 { 762 // set cursor to item with focus-flag 763 sal_Bool bfound = sal_False; 764 for ( sal_uLong i = 0; i < pView->GetEntryCount() && !bfound; i++) 765 { 766 SvxIconChoiceCtrlEntry* pEntry = pView->GetEntry ( i ); 767 if( pEntry->IsFocused() ) 768 { 769 pCursor = pEntry; 770 bfound=sal_True; 771 } 772 } 773 774 if( !bfound ) 775 pCursor = (SvxIconChoiceCtrlEntry*)aEntries.First(); 776 } 777 778 // Show Focus at Init-Time 779 if ( pView->HasFocus() ) 780 GetFocus(); 781 782 sal_uLong nCount = pZOrderList->Count(); 783 if( !nCount ) 784 return; 785 786 sal_Bool bResetClipRegion = sal_False; 787 if( !pView->IsClipRegion() ) 788 { 789 Rectangle aOutputArea( GetOutputRect() ); 790 bResetClipRegion = sal_True; 791 pView->SetClipRegion( aOutputArea ); 792 } 793 794 const sal_uInt16 nListInitSize = aEntries.Count() > USHRT_MAX ? 795 USHRT_MAX : (sal_uInt16)aEntries.Count(); 796 List* pNewZOrderList = new List( nListInitSize ); 797 List* pPaintedEntries = new List( nListInitSize ); 798 799 sal_uLong nPos = 0; 800 while( nCount ) 801 { 802 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nPos )); 803 const Rectangle& rBoundRect = GetEntryBoundRect( pEntry ); 804 if( rRect.IsOver( rBoundRect ) ) 805 { 806 PaintEntry( pEntry, rBoundRect.TopLeft(), pView, sal_True ); 807 // Eintraege, die neu gezeichnet werden, auf Top setzen 808 pPaintedEntries->Insert( pEntry, LIST_APPEND ); 809 } 810 else 811 pNewZOrderList->Insert( pEntry, LIST_APPEND ); 812 813 nCount--; 814 nPos++; 815 } 816 delete pZOrderList; 817 pZOrderList = pNewZOrderList; 818 nCount = pPaintedEntries->Count(); 819 if( nCount ) 820 { 821 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 822 pZOrderList->Insert( pPaintedEntries->GetObject(nCur), LIST_APPEND); 823 } 824 delete pPaintedEntries; 825 826 if( bResetClipRegion ) 827 pView->SetClipRegion(); 828 } 829 830 void SvxIconChoiceCtrl_Impl::RepaintEntries( sal_uInt16 nEntryFlagsMask ) 831 { 832 const sal_uLong nCount = pZOrderList->Count(); 833 if( !nCount ) 834 return; 835 836 sal_Bool bResetClipRegion = sal_False; 837 Rectangle aOutRect( GetOutputRect() ); 838 if( !pView->IsClipRegion() ) 839 { 840 bResetClipRegion = sal_True; 841 pView->SetClipRegion( aOutRect ); 842 } 843 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 844 { 845 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCur)); 846 if( pEntry->GetFlags() & nEntryFlagsMask ) 847 { 848 const Rectangle& rBoundRect = GetEntryBoundRect( pEntry ); 849 if( aOutRect.IsOver( rBoundRect ) ) 850 PaintEntry( pEntry, rBoundRect.TopLeft() ); 851 } 852 } 853 if( bResetClipRegion ) 854 pView->SetClipRegion(); 855 } 856 857 858 void SvxIconChoiceCtrl_Impl::InitScrollBarBox() 859 { 860 aScrBarBox.SetSizePixel( Size(nVerSBarWidth-1, nHorSBarHeight-1) ); 861 Size aSize( pView->GetOutputSizePixel() ); 862 aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth+1, aSize.Height()-nHorSBarHeight+1)); 863 } 864 865 IcnViewFieldType SvxIconChoiceCtrl_Impl::GetItem( SvxIconChoiceCtrlEntry* pEntry, 866 const Point& rAbsPos ) 867 { 868 Rectangle aRect( CalcTextRect( pEntry ) ); 869 if( aRect.IsInside( rAbsPos ) ) 870 return IcnViewFieldTypeText; 871 872 aRect = CalcBmpRect( pEntry ); 873 if( aRect.IsInside( rAbsPos ) ) 874 return IcnViewFieldTypeImage; 875 876 return IcnViewFieldTypeDontknow; 877 } 878 879 sal_Bool SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent& rMEvt) 880 { 881 sal_Bool bHandled = sal_True; 882 bHighlightFramePressed = sal_False; 883 StopEditTimer(); 884 sal_Bool bGotFocus = (sal_Bool)(!pView->HasFocus() && !(nWinBits & WB_NOPOINTERFOCUS)); 885 if( !(nWinBits & WB_NOPOINTERFOCUS) ) 886 pView->GrabFocus(); 887 888 Point aDocPos( rMEvt.GetPosPixel() ); 889 if(aDocPos.X()>=aOutputSize.Width() || aDocPos.Y()>=aOutputSize.Height()) 890 return sal_False; 891 ToDocPos( aDocPos ); 892 SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, sal_True ); 893 if( pEntry ) 894 MakeEntryVisible( pEntry, sal_False ); 895 896 if( rMEvt.IsShift() && eSelectionMode != SINGLE_SELECTION ) 897 { 898 if( pEntry ) 899 SetCursor_Impl( pCursor, pEntry, rMEvt.IsMod1(), rMEvt.IsShift(), sal_True); 900 return sal_True; 901 } 902 903 if( pAnchor && (rMEvt.IsShift() || rMEvt.IsMod1())) // Tastaturselektion? 904 { 905 DBG_ASSERT(eSelectionMode != SINGLE_SELECTION,"Invalid selection mode"); 906 if( rMEvt.IsMod1() ) 907 nFlags |= F_ADD_MODE; 908 909 if( rMEvt.IsShift() ) 910 { 911 Rectangle aRect( GetEntryBoundRect( pAnchor )); 912 if( pEntry ) 913 aRect.Union( GetEntryBoundRect( pEntry ) ); 914 else 915 { 916 Rectangle aTempRect( aDocPos, Size(1,1)); 917 aRect.Union( aTempRect ); 918 } 919 aCurSelectionRect = aRect; 920 SelectRect( aRect, (nFlags & F_ADD_MODE)!=0, &aSelectedRectList ); 921 } 922 else if( rMEvt.IsMod1() ) 923 { 924 AddSelectedRect( aCurSelectionRect ); 925 pAnchor = 0; 926 aCurSelectionRect.SetPos( aDocPos ); 927 } 928 929 if( !pEntry && !(nWinBits & WB_NODRAGSELECTION)) 930 pView->StartTracking( STARTTRACK_SCROLLREPEAT ); 931 return sal_True; 932 } 933 else 934 { 935 if( !pEntry ) 936 { 937 if( eSelectionMode == MULTIPLE_SELECTION ) 938 { 939 if( !rMEvt.IsMod1() ) // Ctrl 940 { 941 if( !bGotFocus ) 942 { 943 SetNoSelection(); 944 ClearSelectedRectList(); 945 } 946 } 947 else 948 nFlags |= F_ADD_MODE; 949 aCurSelectionRect.SetPos( aDocPos ); 950 pView->StartTracking( STARTTRACK_SCROLLREPEAT ); 951 } 952 else 953 bHandled = sal_False; 954 return bHandled; 955 } 956 } 957 sal_Bool bSelected = pEntry->IsSelected(); 958 sal_Bool bEditingEnabled = IsEntryEditingEnabled(); 959 960 if( rMEvt.GetClicks() == 2 ) 961 { 962 DeselectAllBut( pEntry ); 963 SelectEntry( pEntry, sal_True, sal_True, sal_False, sal_True ); 964 pHdlEntry = pEntry; 965 pView->ClickIcon(); 966 } 967 else 968 { 969 // Inplace-Editing ? 970 if( rMEvt.IsMod2() ) // Alt? 971 { 972 if( bEntryEditingEnabled && pEntry && 973 pEntry->IsSelected()) 974 { 975 if( pView->EditingEntry( pEntry )) 976 EditEntry( pEntry ); 977 } 978 } 979 else if( eSelectionMode == SINGLE_SELECTION ) 980 { 981 DeselectAllBut( pEntry ); 982 SetCursor( pEntry ); 983 if( bEditingEnabled && bSelected && !rMEvt.GetModifier() && 984 rMEvt.IsLeft() && IsTextHit( pEntry, aDocPos ) ) 985 { 986 nFlags |= F_START_EDITTIMER_IN_MOUSEUP; 987 } 988 } 989 else if( eSelectionMode == NO_SELECTION ) 990 { 991 if( rMEvt.IsLeft() && (nWinBits & WB_HIGHLIGHTFRAME) ) 992 { 993 pCurHighlightFrame = 0; // Neues painten des Frames erzwingen 994 bHighlightFramePressed = sal_True; 995 SetEntryHighlightFrame( pEntry, sal_True ); 996 } 997 } 998 else 999 { 1000 if( !rMEvt.GetModifier() && rMEvt.IsLeft() ) 1001 { 1002 if( !bSelected ) 1003 { 1004 DeselectAllBut( pEntry, sal_True /* Synchron painten */ ); 1005 SetCursor( pEntry ); 1006 SelectEntry( pEntry, sal_True, sal_True, sal_False, sal_True ); 1007 } 1008 else 1009 { 1010 // erst im Up deselektieren, falls Move per D&D! 1011 nFlags |= F_DOWN_DESELECT; 1012 if( bEditingEnabled && IsTextHit( pEntry, aDocPos ) && 1013 rMEvt.IsLeft()) 1014 { 1015 nFlags |= F_START_EDITTIMER_IN_MOUSEUP; 1016 } 1017 } 1018 } 1019 else if( rMEvt.IsMod1() ) 1020 nFlags |= F_DOWN_CTRL; 1021 } 1022 } 1023 return bHandled; 1024 } 1025 1026 sal_Bool SvxIconChoiceCtrl_Impl::MouseButtonUp( const MouseEvent& rMEvt ) 1027 { 1028 sal_Bool bHandled = sal_False; 1029 if( rMEvt.IsRight() && (nFlags & (F_DOWN_CTRL | F_DOWN_DESELECT) )) 1030 { 1031 nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT); 1032 bHandled = sal_True; 1033 } 1034 1035 Point aDocPos( rMEvt.GetPosPixel() ); 1036 ToDocPos( aDocPos ); 1037 SvxIconChoiceCtrlEntry* pDocEntry = GetEntry( aDocPos ); 1038 if( pDocEntry ) 1039 { 1040 if( nFlags & F_DOWN_CTRL ) 1041 { 1042 // Ctrl & MultiSelection 1043 ToggleSelection( pDocEntry ); 1044 SetCursor( pDocEntry ); 1045 bHandled = sal_True; 1046 } 1047 else if( nFlags & F_DOWN_DESELECT ) 1048 { 1049 DeselectAllBut( pDocEntry ); 1050 SetCursor( pDocEntry ); 1051 SelectEntry( pDocEntry, sal_True, sal_True, sal_False, sal_True ); 1052 bHandled = sal_True; 1053 } 1054 } 1055 1056 nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT); 1057 if( nFlags & F_START_EDITTIMER_IN_MOUSEUP ) 1058 { 1059 bHandled = sal_True; 1060 StartEditTimer(); 1061 nFlags &= ~F_START_EDITTIMER_IN_MOUSEUP; 1062 } 1063 1064 if((nWinBits & WB_HIGHLIGHTFRAME) && bHighlightFramePressed && pCurHighlightFrame) 1065 { 1066 bHandled = sal_True; 1067 SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame; 1068 pCurHighlightFrame = 0; // Neues painten des Frames erzwingen 1069 bHighlightFramePressed = sal_False; 1070 SetEntryHighlightFrame( pEntry, sal_True ); 1071 #if 0 1072 CallSelectHandler( pCurHighlightFrame ); 1073 #else 1074 pHdlEntry = pCurHighlightFrame; 1075 pView->ClickIcon(); 1076 1077 // set focus on Icon 1078 SvxIconChoiceCtrlEntry* pOldCursor = pCursor; 1079 SetCursor_Impl( pOldCursor, pHdlEntry, sal_False, sal_False, sal_True ); 1080 #endif 1081 pHdlEntry = 0; 1082 } 1083 return bHandled; 1084 } 1085 1086 sal_Bool SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent& rMEvt ) 1087 { 1088 const Point aDocPos( pView->PixelToLogic(rMEvt.GetPosPixel()) ); 1089 1090 if( pView->IsTracking() ) 1091 return sal_False; 1092 else if( nWinBits & WB_HIGHLIGHTFRAME ) 1093 { 1094 SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, sal_True ); 1095 SetEntryHighlightFrame( pEntry ); 1096 } 1097 else 1098 return sal_False; 1099 return sal_True; 1100 } 1101 1102 void SvxIconChoiceCtrl_Impl::Tracking( const TrackingEvent& rTEvt ) 1103 { 1104 if ( rTEvt.IsTrackingEnded() ) 1105 { 1106 // Das Rechteck darf nicht "justified" sein, da seine 1107 // TopLeft-Position u.U. zur Berechnung eines Ankers 1108 // benutzt wird. 1109 AddSelectedRect( aCurSelectionRect ); 1110 pView->HideTracking(); 1111 nFlags &= ~(F_ADD_MODE); 1112 if( rTEvt.IsTrackingCanceled() ) 1113 SetNoSelection(); 1114 } 1115 else 1116 { 1117 Point aPosPixel = rTEvt.GetMouseEvent().GetPosPixel(); 1118 Point aDocPos( aPosPixel ); 1119 ToDocPos( aDocPos ); 1120 1121 long nScrollDX, nScrollDY; 1122 1123 CalcScrollOffsets( aPosPixel, nScrollDX, nScrollDY, sal_False ); 1124 if( nScrollDX || nScrollDY ) 1125 { 1126 pView->HideTracking(); 1127 pView->Scroll( nScrollDX, nScrollDY ); 1128 } 1129 Rectangle aRect( aCurSelectionRect.TopLeft(), aDocPos ); 1130 if( aRect != aCurSelectionRect ) 1131 { 1132 pView->HideTracking(); 1133 sal_Bool bAdd = (nFlags & F_ADD_MODE) ? sal_True : sal_False; 1134 SelectRect( aRect, bAdd, &aSelectedRectList ); 1135 } 1136 pView->ShowTracking( aRect, SHOWTRACK_SMALL | SHOWTRACK_CLIP ); 1137 } 1138 } 1139 1140 void SvxIconChoiceCtrl_Impl::SetCursor_Impl( SvxIconChoiceCtrlEntry* pOldCursor, 1141 SvxIconChoiceCtrlEntry* pNewCursor, sal_Bool bMod1, sal_Bool bShift, sal_Bool bPaintSync ) 1142 { 1143 if( pNewCursor ) 1144 { 1145 SvxIconChoiceCtrlEntry* pFilterEntry = 0; 1146 sal_Bool bDeselectAll = sal_False; 1147 if( eSelectionMode != SINGLE_SELECTION ) 1148 { 1149 if( !bMod1 && !bShift ) 1150 bDeselectAll = sal_True; 1151 else if( bShift && !bMod1 && !pAnchor ) 1152 { 1153 bDeselectAll = sal_True; 1154 pFilterEntry = pOldCursor; 1155 } 1156 } 1157 if( bDeselectAll ) 1158 DeselectAllBut( pFilterEntry, bPaintSync ); 1159 ShowCursor( sal_False ); 1160 MakeEntryVisible( pNewCursor ); 1161 SetCursor( pNewCursor ); 1162 if( bMod1 && !bShift ) 1163 { 1164 if( pAnchor ) 1165 { 1166 AddSelectedRect( pAnchor, pOldCursor ); 1167 pAnchor = 0; 1168 } 1169 } 1170 else if( bShift ) 1171 { 1172 if( !pAnchor ) 1173 pAnchor = pOldCursor; 1174 if ( nWinBits & WB_ALIGN_LEFT ) 1175 SelectRange( pAnchor, pNewCursor, (nFlags & F_ADD_MODE)!=0 ); 1176 else 1177 SelectRect(pAnchor,pNewCursor,(nFlags & F_ADD_MODE)!=0,&aSelectedRectList); 1178 } 1179 else 1180 { 1181 SelectEntry( pCursor, sal_True, sal_True, sal_False, bPaintSync ); 1182 aCurSelectionRect = GetEntryBoundRect( pCursor ); 1183 //IAccessibility2 Implementation 2009----- 1184 CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor ); 1185 //-----IAccessibility2 Implementation 2009 1186 } 1187 } 1188 } 1189 1190 sal_Bool SvxIconChoiceCtrl_Impl::KeyInput( const KeyEvent& rKEvt ) 1191 { 1192 StopEditTimer(); 1193 1194 sal_Bool bMod2 = rKEvt.GetKeyCode().IsMod2(); 1195 sal_Unicode cChar = rKEvt.GetCharCode(); 1196 sal_uLong nPos = (sal_uLong)-1; 1197 if ( bMod2 && cChar && IsMnemonicChar( cChar, nPos ) ) 1198 { 1199 // shortcut is clicked 1200 SvxIconChoiceCtrlEntry* pNewCursor = GetEntry( nPos ); 1201 SvxIconChoiceCtrlEntry* pOldCursor = pCursor; 1202 if ( pNewCursor != pOldCursor ) 1203 SetCursor_Impl( pOldCursor, pNewCursor, sal_False, sal_False, sal_False ); 1204 return sal_True; 1205 } 1206 1207 if ( bMod2 ) 1208 // no actions with <ALT> 1209 return sal_False; 1210 1211 sal_Bool bKeyUsed = sal_True; 1212 sal_Bool bMod1 = rKEvt.GetKeyCode().IsMod1(); 1213 sal_Bool bShift = rKEvt.GetKeyCode().IsShift(); 1214 1215 if( eSelectionMode == SINGLE_SELECTION || eSelectionMode == NO_SELECTION) 1216 { 1217 bShift = sal_False; 1218 bMod1 = sal_False; 1219 } 1220 1221 if( bMod1 ) 1222 nFlags |= F_ADD_MODE; 1223 sal_Bool bDeselectAll = sal_False; 1224 if( eSelectionMode != SINGLE_SELECTION ) 1225 { 1226 if( !bMod1 && !bShift ) 1227 bDeselectAll = sal_True; 1228 if( bShift && !bMod1 && !pAnchor ) 1229 bDeselectAll = sal_True; 1230 } 1231 1232 SvxIconChoiceCtrlEntry* pNewCursor; 1233 SvxIconChoiceCtrlEntry* pOldCursor = pCursor; 1234 1235 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); 1236 switch( nCode ) 1237 { 1238 case KEY_UP: 1239 case KEY_PAGEUP: 1240 if( pCursor ) 1241 { 1242 MakeEntryVisible( pCursor ); 1243 if( nCode == KEY_UP ) 1244 pNewCursor = pImpCursor->GoUpDown(pCursor,sal_False); 1245 else 1246 pNewCursor = pImpCursor->GoPageUpDown(pCursor,sal_False); 1247 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1248 if( !pNewCursor ) 1249 { 1250 Rectangle aRect( GetEntryBoundRect( pCursor ) ); 1251 if( aRect.Top()) 1252 { 1253 aRect.Bottom() -= aRect.Top(); 1254 aRect.Top() = 0; 1255 MakeVisible( aRect ); 1256 } 1257 } 1258 1259 if ( bChooseWithCursor && pNewCursor != NULL ) 1260 { 1261 pHdlEntry = pNewCursor;//GetCurEntry(); 1262 pCurHighlightFrame = pHdlEntry; 1263 pView->ClickIcon(); 1264 pCurHighlightFrame = NULL; 1265 } 1266 } 1267 break; 1268 1269 case KEY_DOWN: 1270 case KEY_PAGEDOWN: 1271 if( pCursor ) 1272 { 1273 if( nCode == KEY_DOWN ) 1274 pNewCursor=pImpCursor->GoUpDown( pCursor,sal_True ); 1275 else 1276 pNewCursor=pImpCursor->GoPageUpDown( pCursor,sal_True ); 1277 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1278 1279 if ( bChooseWithCursor && pNewCursor != NULL) 1280 { 1281 pHdlEntry = pNewCursor;//GetCurEntry(); 1282 pCurHighlightFrame = pHdlEntry; 1283 pView->ClickIcon(); 1284 pCurHighlightFrame = NULL; 1285 } 1286 } 1287 break; 1288 1289 case KEY_RIGHT: 1290 if( pCursor ) 1291 { 1292 pNewCursor=pImpCursor->GoLeftRight(pCursor,sal_True ); 1293 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1294 } 1295 break; 1296 1297 case KEY_LEFT: 1298 if( pCursor ) 1299 { 1300 MakeEntryVisible( pCursor ); 1301 pNewCursor = pImpCursor->GoLeftRight(pCursor,sal_False ); 1302 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1303 if( !pNewCursor ) 1304 { 1305 Rectangle aRect( GetEntryBoundRect(pCursor)); 1306 if( aRect.Left() ) 1307 { 1308 aRect.Right() -= aRect.Left(); 1309 aRect.Left() = 0; 1310 MakeVisible( aRect ); 1311 } 1312 } 1313 } 1314 break; 1315 1316 // wird vom VCL-Tracking gesteuert 1317 #if 0 1318 case KEY_ESCAPE: 1319 if( pView->IsTracking() ) 1320 { 1321 HideSelectionRect(); 1322 //SelectAll( sal_False ); 1323 SetNoSelection(); 1324 ClearSelectedRectList(); 1325 nFlags &= ~F_TRACKING; 1326 } 1327 else 1328 bKeyUsed = sal_False; 1329 break; 1330 #endif 1331 1332 1333 case KEY_F2: 1334 if( !bMod1 && !bShift ) 1335 EditTimeoutHdl( 0 ); 1336 else 1337 bKeyUsed = sal_False; 1338 break; 1339 1340 case KEY_F8: 1341 if( rKEvt.GetKeyCode().IsShift() ) 1342 { 1343 if( nFlags & F_ADD_MODE ) 1344 nFlags &= (~F_ADD_MODE); 1345 else 1346 nFlags |= F_ADD_MODE; 1347 } 1348 else 1349 bKeyUsed = sal_False; 1350 break; 1351 1352 case KEY_SPACE: 1353 if( pCursor && eSelectionMode != SINGLE_SELECTION ) 1354 { 1355 if( !bMod1 ) 1356 { 1357 //SelectAll( sal_False ); 1358 SetNoSelection(); 1359 ClearSelectedRectList(); 1360 1361 // click Icon with spacebar 1362 SetEntryHighlightFrame( GetCurEntry(), sal_True ); 1363 pView->ClickIcon(); 1364 pHdlEntry = pCurHighlightFrame; 1365 pCurHighlightFrame=0; 1366 } 1367 else 1368 ToggleSelection( pCursor ); 1369 } 1370 break; 1371 1372 #ifdef DBG_UTIL 1373 case KEY_F10: 1374 if( rKEvt.GetKeyCode().IsShift() ) 1375 { 1376 if( pCursor ) 1377 pView->SetEntryTextMode( IcnShowTextFull, pCursor ); 1378 } 1379 if( rKEvt.GetKeyCode().IsMod1() ) 1380 { 1381 if( pCursor ) 1382 pView->SetEntryTextMode( IcnShowTextShort, pCursor ); 1383 } 1384 break; 1385 #endif 1386 1387 case KEY_ADD: 1388 case KEY_DIVIDE : 1389 case KEY_A: 1390 if( bMod1 && (eSelectionMode != SINGLE_SELECTION)) 1391 SelectAll( sal_True ); 1392 else 1393 bKeyUsed = sal_False; 1394 break; 1395 1396 case KEY_SUBTRACT: 1397 case KEY_COMMA : 1398 if( bMod1 ) 1399 SetNoSelection(); 1400 else 1401 bKeyUsed = sal_False; 1402 break; 1403 1404 case KEY_RETURN: 1405 if( bMod1 ) 1406 { 1407 if( pCursor && bEntryEditingEnabled ) 1408 /*pView->*/EditEntry( pCursor ); 1409 } 1410 else 1411 bKeyUsed = sal_False; 1412 break; 1413 1414 case KEY_END: 1415 if( pCursor ) 1416 { 1417 pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( aEntries.Count() - 1 ); 1418 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1419 } 1420 break; 1421 1422 case KEY_HOME: 1423 if( pCursor ) 1424 { 1425 pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( 0 ); 1426 SetCursor_Impl( pOldCursor, pNewCursor, bMod1, bShift, sal_True ); 1427 } 1428 break; 1429 1430 default: 1431 bKeyUsed = sal_False; 1432 1433 } 1434 return bKeyUsed; 1435 } 1436 1437 // Berechnet TopLeft der Scrollbars (nicht ihre Groessen!) 1438 void SvxIconChoiceCtrl_Impl::PositionScrollBars( long nRealWidth, long nRealHeight ) 1439 { 1440 // hor scrollbar 1441 Point aPos( 0, nRealHeight ); 1442 aPos.Y() -= nHorSBarHeight; 1443 1444 if( aHorSBar.GetPosPixel() != aPos ) 1445 aHorSBar.SetPosPixel( aPos ); 1446 1447 // ver scrollbar 1448 aPos.X() = nRealWidth; aPos.Y() = 0; 1449 aPos.X() -= nVerSBarWidth; 1450 aPos.X()++; 1451 aPos.Y()--; 1452 1453 if( aVerSBar.GetPosPixel() != aPos ) 1454 aVerSBar.SetPosPixel( aPos ); 1455 } 1456 1457 void SvxIconChoiceCtrl_Impl::AdjustScrollBars( sal_Bool ) 1458 { 1459 Rectangle aOldOutRect( GetOutputRect() ); 1460 long nVirtHeight = aVirtOutputSize.Height(); 1461 long nVirtWidth = aVirtOutputSize.Width(); 1462 1463 Size aOSize( pView->Control::GetOutputSizePixel() ); 1464 long nRealHeight = aOSize.Height(); 1465 long nRealWidth = aOSize.Width(); 1466 1467 PositionScrollBars( nRealWidth, nRealHeight ); 1468 1469 const MapMode& rMapMode = pView->GetMapMode(); 1470 Point aOrigin( rMapMode.GetOrigin() ); 1471 1472 long nVisibleWidth; 1473 if( nRealWidth > nVirtWidth ) 1474 nVisibleWidth = nVirtWidth + aOrigin.X(); 1475 else 1476 nVisibleWidth = nRealWidth; 1477 1478 long nVisibleHeight; 1479 if( nRealHeight > nVirtHeight ) 1480 nVisibleHeight = nVirtHeight + aOrigin.Y(); 1481 else 1482 nVisibleHeight = nRealHeight; 1483 1484 sal_Bool bVerSBar = ( nWinBits & WB_VSCROLL ) != 0; 1485 sal_Bool bHorSBar = ( nWinBits & WB_HSCROLL ) != 0; 1486 sal_Bool bNoVerSBar = ( nWinBits & WB_NOVSCROLL ) != 0; 1487 sal_Bool bNoHorSBar = ( nWinBits & WB_NOHSCROLL ) != 0; 1488 1489 sal_uInt16 nResult = 0; 1490 if( nVirtHeight ) 1491 { 1492 // activate ver scrollbar ? 1493 if( !bNoVerSBar && (bVerSBar || ( nVirtHeight > nVisibleHeight)) ) 1494 { 1495 nResult = 0x0001; 1496 nRealWidth -= nVerSBarWidth; 1497 1498 if( nRealWidth > nVirtWidth ) 1499 nVisibleWidth = nVirtWidth + aOrigin.X(); 1500 else 1501 nVisibleWidth = nRealWidth; 1502 1503 nFlags |= F_HOR_SBARSIZE_WITH_VBAR; 1504 } 1505 // activate hor scrollbar ? 1506 if( !bNoHorSBar && (bHorSBar || (nVirtWidth > nVisibleWidth)) ) 1507 { 1508 nResult |= 0x0002; 1509 nRealHeight -= nHorSBarHeight; 1510 1511 if( nRealHeight > nVirtHeight ) 1512 nVisibleHeight = nVirtHeight + aOrigin.Y(); 1513 else 1514 nVisibleHeight = nRealHeight; 1515 1516 // brauchen wir jetzt doch eine senkrechte Scrollbar ? 1517 if( !(nResult & 0x0001) && // nur wenn nicht schon da 1518 ( !bNoVerSBar && ((nVirtHeight > nVisibleHeight) || bVerSBar)) ) 1519 { 1520 nResult = 3; // beide sind an 1521 nRealWidth -= nVerSBarWidth; 1522 1523 if( nRealWidth > nVirtWidth ) 1524 nVisibleWidth = nVirtWidth + aOrigin.X(); 1525 else 1526 nVisibleWidth = nRealWidth; 1527 1528 nFlags |= F_VER_SBARSIZE_WITH_HBAR; 1529 } 1530 } 1531 } 1532 1533 // size ver scrollbar 1534 long nThumb = aVerSBar.GetThumbPos(); 1535 Size aSize( nVerSBarWidth, nRealHeight ); 1536 aSize.Height() += 2; 1537 if( aSize != aVerSBar.GetSizePixel() ) 1538 aVerSBar.SetSizePixel( aSize ); 1539 aVerSBar.SetVisibleSize( nVisibleHeight ); 1540 aVerSBar.SetPageSize( GetScrollBarPageSize( nVisibleHeight )); 1541 1542 if( nResult & 0x0001 ) 1543 { 1544 aVerSBar.SetThumbPos( nThumb ); 1545 aVerSBar.Show(); 1546 } 1547 else 1548 { 1549 aVerSBar.SetThumbPos( 0 ); 1550 aVerSBar.Hide(); 1551 } 1552 1553 // size hor scrollbar 1554 nThumb = aHorSBar.GetThumbPos(); 1555 aSize.Width() = nRealWidth; 1556 aSize.Height() = nHorSBarHeight; 1557 aSize.Width()++; 1558 if( nResult & 0x0001 ) // vertikale Scrollbar ? 1559 { 1560 aSize.Width()++; 1561 nRealWidth++; 1562 } 1563 if( aSize != aHorSBar.GetSizePixel() ) 1564 aHorSBar.SetSizePixel( aSize ); 1565 aHorSBar.SetVisibleSize( nVisibleWidth ); 1566 aHorSBar.SetPageSize( GetScrollBarPageSize(nVisibleWidth )); 1567 if( nResult & 0x0002 ) 1568 { 1569 aHorSBar.SetThumbPos( nThumb ); 1570 aHorSBar.Show(); 1571 } 1572 else 1573 { 1574 aHorSBar.SetThumbPos( 0 ); 1575 aHorSBar.Hide(); 1576 } 1577 1578 aOutputSize.Width() = nRealWidth; 1579 if( nResult & 0x0002 ) // hor scrollbar ? 1580 nRealHeight++; // weil unterer Rand geclippt wird 1581 aOutputSize.Height() = nRealHeight; 1582 1583 Rectangle aNewOutRect( GetOutputRect() ); 1584 if( aNewOutRect != aOldOutRect && pView->HasBackground() ) 1585 { 1586 Wallpaper aPaper( pView->GetBackground() ); 1587 aPaper.SetRect( aNewOutRect ); 1588 pView->SetBackground( aPaper ); 1589 } 1590 1591 if( (nResult & (0x0001|0x0002)) == (0x0001|0x0002) ) 1592 aScrBarBox.Show(); 1593 else 1594 aScrBarBox.Hide(); 1595 } 1596 1597 void SvxIconChoiceCtrl_Impl::Resize() 1598 { 1599 StopEditTimer(); 1600 InitScrollBarBox(); 1601 aOutputSize = pView->GetOutputSizePixel(); 1602 pImpCursor->Clear(); 1603 pGridMap->OutputSizeChanged(); 1604 1605 const Size& rSize = pView->Control::GetOutputSizePixel(); 1606 PositionScrollBars( rSize.Width(), rSize.Height() ); 1607 // Die ScrollBars werden asynchron ein/ausgeblendet, damit abgeleitete 1608 // Klassen im Resize ein Arrange durchfuehren koennen, ohne dass 1609 // die ScrollBars aufblitzen 1610 // Wenn schon ein Event unterwegs ist, dann braucht kein neues verschickt werden, 1611 // zumindest, solange es nur einen EventTypen gibt 1612 if ( ! nUserEventAdjustScrBars ) 1613 nUserEventAdjustScrBars = 1614 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl), 1615 EVENTID_ADJUST_SCROLLBARS); 1616 1617 if( pView->HasBackground() && !pView->GetBackground().IsScrollable() ) 1618 { 1619 Rectangle aRect( GetOutputRect()); 1620 Wallpaper aPaper( pView->GetBackground() ); 1621 aPaper.SetRect( aRect ); 1622 pView->SetBackground( aPaper ); 1623 } 1624 VisRectChanged(); 1625 } 1626 1627 sal_Bool SvxIconChoiceCtrl_Impl::CheckHorScrollBar() 1628 { 1629 if( !pZOrderList || !aHorSBar.IsVisible() ) 1630 return sal_False; 1631 const MapMode& rMapMode = pView->GetMapMode(); 1632 Point aOrigin( rMapMode.GetOrigin() ); 1633 if(!( nWinBits & WB_HSCROLL) && !aOrigin.X() ) 1634 { 1635 long nWidth = aOutputSize.Width(); 1636 const sal_uLong nCount = pZOrderList->Count(); 1637 long nMostRight = 0; 1638 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 1639 { 1640 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pZOrderList->GetObject(nCur); 1641 long nRight = GetEntryBoundRect(pEntry).Right(); 1642 if( nRight > nWidth ) 1643 return sal_False; 1644 if( nRight > nMostRight ) 1645 nMostRight = nRight; 1646 } 1647 aHorSBar.Hide(); 1648 aOutputSize.Height() += nHorSBarHeight; 1649 aVirtOutputSize.Width() = nMostRight; 1650 aHorSBar.SetThumbPos( 0 ); 1651 Range aRange; 1652 aRange.Max() = nMostRight - 1; 1653 aHorSBar.SetRange( aRange ); 1654 if( aVerSBar.IsVisible() ) 1655 { 1656 Size aSize( aVerSBar.GetSizePixel()); 1657 aSize.Height() += nHorSBarHeight; 1658 aVerSBar.SetSizePixel( aSize ); 1659 } 1660 return sal_True; 1661 } 1662 return sal_False; 1663 } 1664 1665 sal_Bool SvxIconChoiceCtrl_Impl::CheckVerScrollBar() 1666 { 1667 if( !pZOrderList || !aVerSBar.IsVisible() ) 1668 return sal_False; 1669 const MapMode& rMapMode = pView->GetMapMode(); 1670 Point aOrigin( rMapMode.GetOrigin() ); 1671 if(!( nWinBits & WB_VSCROLL) && !aOrigin.Y() ) 1672 { 1673 long nDeepest = 0; 1674 long nHeight = aOutputSize.Height(); 1675 const sal_uLong nCount = pZOrderList->Count(); 1676 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 1677 { 1678 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)pZOrderList->GetObject(nCur); 1679 long nBottom = GetEntryBoundRect(pEntry).Bottom(); 1680 if( nBottom > nHeight ) 1681 return sal_False; 1682 if( nBottom > nDeepest ) 1683 nDeepest = nBottom; 1684 } 1685 aVerSBar.Hide(); 1686 aOutputSize.Width() += nVerSBarWidth; 1687 aVirtOutputSize.Height() = nDeepest; 1688 aVerSBar.SetThumbPos( 0 ); 1689 Range aRange; 1690 aRange.Max() = nDeepest - 1; 1691 aVerSBar.SetRange( aRange ); 1692 if( aHorSBar.IsVisible() ) 1693 { 1694 Size aSize( aHorSBar.GetSizePixel()); 1695 aSize.Width() += nVerSBarWidth; 1696 aHorSBar.SetSizePixel( aSize ); 1697 } 1698 return sal_True; 1699 } 1700 return sal_False; 1701 } 1702 1703 1704 // blendet Scrollbars aus, wenn sie nicht mehr benoetigt werden 1705 void SvxIconChoiceCtrl_Impl::CheckScrollBars() 1706 { 1707 CheckVerScrollBar(); 1708 if( CheckHorScrollBar() ) 1709 CheckVerScrollBar(); 1710 if( aVerSBar.IsVisible() && aHorSBar.IsVisible() ) 1711 aScrBarBox.Show(); 1712 else 1713 aScrBarBox.Hide(); 1714 } 1715 1716 1717 void SvxIconChoiceCtrl_Impl::GetFocus() 1718 { 1719 RepaintEntries( ICNVIEW_FLAG_SELECTED ); 1720 if( pCursor ) 1721 { 1722 pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED ); 1723 ShowCursor( sal_True ); 1724 } 1725 } 1726 1727 void SvxIconChoiceCtrl_Impl::LoseFocus() 1728 { 1729 StopEditTimer(); 1730 if( pCursor ) 1731 pCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED ); 1732 ShowCursor( sal_False ); 1733 1734 // HideFocus (); 1735 // pView->Invalidate ( aFocus.aRect ); 1736 1737 RepaintEntries( ICNVIEW_FLAG_SELECTED ); 1738 } 1739 1740 void SvxIconChoiceCtrl_Impl::SetUpdateMode( sal_Bool bUpdate ) 1741 { 1742 if( bUpdate != bUpdateMode ) 1743 { 1744 bUpdateMode = bUpdate; 1745 if( bUpdate ) 1746 { 1747 AdjustScrollBars(); 1748 pImpCursor->Clear(); 1749 pGridMap->Clear(); 1750 pView->Invalidate(INVALIDATE_NOCHILDREN); 1751 } 1752 } 1753 } 1754 1755 void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bIsBackgroundPainted ) 1756 { 1757 Point aPos( GetEntryPos( pEntry ) ); 1758 PaintEntry( pEntry, aPos, 0, bIsBackgroundPainted ); 1759 } 1760 1761 // Prios der Emphasis: bDropTarget => bCursored => bSelected 1762 void SvxIconChoiceCtrl_Impl::PaintEmphasis( 1763 const Rectangle& rTextRect, const Rectangle& rImageRect, 1764 sal_Bool bSelected, sal_Bool bDropTarget, sal_Bool bCursored, OutputDevice* pOut, 1765 sal_Bool bIsBackgroundPainted ) 1766 { 1767 static Color aTransparent( COL_TRANSPARENT ); 1768 1769 if( !pOut ) 1770 pOut = pView; 1771 1772 #ifdef OV_CHECK_EMPH_RECTS 1773 { 1774 Color aXOld( pOut->GetFillColor() ); 1775 pOut->SetFillColor( Color( COL_GREEN )); 1776 pOut->DrawRect( rTextRect ); 1777 pOut->DrawRect( rImageRect ); 1778 pOut->SetFillColor( aXOld ); 1779 } 1780 #endif 1781 1782 const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings(); 1783 Color aOldFillColor( pOut->GetFillColor() ); 1784 1785 sal_Bool bSolidTextRect = sal_False; 1786 sal_Bool bSolidImageRect = sal_False; 1787 1788 if( bDropTarget && ( eSelectionMode != NO_SELECTION ) ) 1789 { 1790 pOut->SetFillColor( rSettings.GetHighlightColor() ); 1791 bSolidTextRect = sal_True; 1792 bSolidImageRect = sal_True; 1793 } 1794 else 1795 { 1796 if ( !bSelected || bCursored ) 1797 { 1798 if( !pView->HasFontFillColor() ) 1799 pOut->SetFillColor( pOut->GetBackground().GetColor() ); 1800 else 1801 { 1802 const Color& rFillColor = pView->GetFont().GetFillColor(); 1803 pOut->SetFillColor( rFillColor ); 1804 if( rFillColor != aTransparent ) 1805 bSolidTextRect = sal_True; 1806 } 1807 } 1808 } 1809 1810 // Textrechteck zeichnen 1811 if( !bSolidTextRect ) 1812 { 1813 if( !bIsBackgroundPainted ) 1814 pOut->Erase( rTextRect ); 1815 } 1816 else 1817 { 1818 Color aOldLineColor; 1819 if( bCursored ) 1820 { 1821 aOldLineColor = pOut->GetLineColor(); 1822 pOut->SetLineColor( Color( COL_GRAY ) ); 1823 } 1824 pOut->DrawRect( rTextRect ); 1825 if( bCursored ) 1826 pOut->SetLineColor( aOldLineColor ); 1827 } 1828 1829 // Bildrechteck zeichnen 1830 if( !bSolidImageRect ) 1831 { 1832 if( !bIsBackgroundPainted ) 1833 pOut->Erase( rImageRect ); 1834 } 1835 // die Emphasis des Images muss von der abgeleiteten Klasse gezeichnet werden 1836 // (in der virtuellen Funktion DrawEntryImage) 1837 // else 1838 // pOut->DrawRect( rImageRect ); 1839 1840 pOut->SetFillColor( aOldFillColor ); 1841 } 1842 1843 1844 void SvxIconChoiceCtrl_Impl::PaintItem( const Rectangle& rRect, 1845 IcnViewFieldType eItem, SvxIconChoiceCtrlEntry* pEntry, sal_uInt16 nPaintFlags, 1846 OutputDevice* pOut, const String* pStr, ::vcl::ControlLayoutData* _pLayoutData ) 1847 { 1848 if( eItem == IcnViewFieldTypeText ) 1849 { 1850 String aText; 1851 if( !pStr ) 1852 aText = pView->GetEntryText( pEntry, sal_False ); 1853 else 1854 aText = *pStr; 1855 1856 if ( _pLayoutData ) 1857 { 1858 pOut->DrawText( rRect, aText, nCurTextDrawFlags, 1859 &_pLayoutData->m_aUnicodeBoundRects, &_pLayoutData->m_aDisplayText ); 1860 } 1861 else 1862 { 1863 Color aOldFontColor = pOut->GetTextColor(); 1864 if ( pView->AutoFontColor() ) 1865 { 1866 Color aBkgColor( pOut->GetBackground().GetColor() ); 1867 Color aFontColor; 1868 sal_uInt16 nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3; 1869 if ( nColor > 127 ) 1870 aFontColor.SetColor ( COL_BLACK ); 1871 else 1872 aFontColor.SetColor( COL_WHITE ); 1873 pOut->SetTextColor( aFontColor ); 1874 } 1875 1876 pOut->DrawText( rRect, aText, nCurTextDrawFlags ); 1877 1878 if ( pView->AutoFontColor() ) 1879 pOut->SetTextColor( aOldFontColor ); 1880 1881 if( pEntry->IsFocused() ) 1882 { 1883 Rectangle aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry*)pEntry ) ); 1884 /*pView->*/ShowFocus( aRect ); 1885 DrawFocusRect( pOut ); 1886 } 1887 } 1888 } 1889 else 1890 { 1891 Point aPos( rRect.TopLeft() ); 1892 if( nPaintFlags & PAINTFLAG_HOR_CENTERED ) 1893 aPos.X() += (rRect.GetWidth() - aImageSize.Width() ) / 2; 1894 if( nPaintFlags & PAINTFLAG_VER_CENTERED ) 1895 aPos.Y() += (rRect.GetHeight() - aImageSize.Height() ) / 2; 1896 pView->DrawEntryImage( pEntry, aPos, *pOut ); 1897 } 1898 } 1899 1900 void SvxIconChoiceCtrl_Impl::PaintEntryVirtOutDev( SvxIconChoiceCtrlEntry* pEntry ) 1901 { 1902 #ifdef OV_NO_VIRT_OUTDEV 1903 PaintEntry( pEntry ); 1904 #else 1905 if( !pEntryPaintDev ) 1906 { 1907 pEntryPaintDev = new VirtualDevice( *pView ); 1908 pEntryPaintDev->SetFont( pView->GetFont() ); 1909 pEntryPaintDev->SetLineColor(); 1910 //pEntryPaintDev->SetBackground( pView->GetBackground() ); 1911 } 1912 const Rectangle& rRect = GetEntryBoundRect( pEntry ); 1913 Rectangle aOutRect( GetOutputRect() ); 1914 if( !rRect.IsOver( aOutRect ) ) 1915 return; 1916 Wallpaper aPaper( pView->GetBackground() ); 1917 Rectangle aRect( aPaper.GetRect() ); 1918 1919 // Rechteck verschieben, so dass das Boundrect des Entries im 1920 // VirtOut-Dev bei 0,0 liegt. 1921 aRect.Move( -rRect.Left(), -rRect.Top() ); 1922 aPaper.SetRect( aRect ); 1923 pEntryPaintDev->SetBackground( aPaper ); 1924 pEntryPaintDev->SetFont( pView->GetFont() ); 1925 Rectangle aPix ( pEntryPaintDev->LogicToPixel(aRect) ); 1926 1927 1928 Size aSize( rRect.GetSize() ); 1929 pEntryPaintDev->SetOutputSizePixel( aSize ); 1930 pEntryPaintDev->DrawOutDev( 1931 Point(), aSize, rRect.TopLeft(), aSize, *pView ); 1932 1933 PaintEntry( pEntry, Point(), pEntryPaintDev ); 1934 1935 pView->DrawOutDev( 1936 rRect.TopLeft(), 1937 aSize, 1938 Point(), 1939 aSize, 1940 *pEntryPaintDev ); 1941 #endif 1942 } 1943 1944 1945 void SvxIconChoiceCtrl_Impl::PaintEntry( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos, 1946 OutputDevice* pOut, sal_Bool bIsBackgroundPainted ) 1947 { 1948 if( !pOut ) 1949 pOut = pView; 1950 1951 sal_Bool bSelected = sal_False; 1952 1953 if( eSelectionMode != NO_SELECTION ) 1954 bSelected = pEntry->IsSelected(); 1955 1956 sal_Bool bCursored = pEntry->IsCursored(); 1957 sal_Bool bDropTarget = pEntry->IsDropTarget(); 1958 sal_Bool bNoEmphasis = pEntry->IsBlockingEmphasis(); 1959 1960 Font aTempFont( pOut->GetFont() ); 1961 1962 // AutoFontColor 1963 /* 1964 if ( pView->AutoFontColor() ) 1965 { 1966 aTempFont.SetColor ( aFontColor ); 1967 } 1968 */ 1969 1970 String aEntryText( pView->GetEntryText( pEntry, sal_False ) ); 1971 Rectangle aTextRect( CalcTextRect(pEntry,&rPos,sal_False,&aEntryText)); 1972 Rectangle aBmpRect( CalcBmpRect(pEntry, &rPos ) ); 1973 1974 sal_Bool bShowSelection = 1975 ( ( ( bSelected && !bCursored ) 1976 || bDropTarget 1977 ) 1978 && !bNoEmphasis 1979 && ( eSelectionMode != NO_SELECTION ) 1980 ); 1981 sal_Bool bActiveSelection = ( 0 != ( nWinBits & WB_NOHIDESELECTION ) ) || pView->HasFocus(); 1982 1983 if ( bShowSelection ) 1984 { 1985 const StyleSettings& rSettings = pOut->GetSettings().GetStyleSettings(); 1986 Font aNewFont( aTempFont ); 1987 1988 // bei hart attributierter Font-Fuellcolor muessen wir diese 1989 // hart auf die Highlight-Color setzen 1990 if( pView->HasFontFillColor() ) 1991 { 1992 if( (nWinBits & WB_NOHIDESELECTION) || pView->HasFocus() ) 1993 aNewFont.SetFillColor( rSettings.GetHighlightColor() ); 1994 else 1995 aNewFont.SetFillColor( rSettings.GetDeactiveColor() ); 1996 } 1997 1998 Color aWinCol = rSettings.GetWindowTextColor(); 1999 if ( !bActiveSelection && rSettings.GetFaceColor().IsBright() == aWinCol.IsBright() ) 2000 aNewFont.SetColor( rSettings.GetWindowTextColor() ); 2001 else 2002 aNewFont.SetColor( rSettings.GetHighlightTextColor() ); 2003 2004 pOut->SetFont( aNewFont ); 2005 2006 pOut->SetFillColor( pOut->GetBackground().GetColor() ); 2007 pOut->DrawRect( CalcFocusRect( pEntry ) ); 2008 pOut->SetFillColor( ); 2009 } 2010 2011 sal_Bool bResetClipRegion = sal_False; 2012 if( !pView->IsClipRegion() && (aVerSBar.IsVisible() || aHorSBar.IsVisible()) ) 2013 { 2014 Rectangle aOutputArea( GetOutputRect() ); 2015 if( aOutputArea.IsOver(aTextRect) || aOutputArea.IsOver(aBmpRect) ) 2016 { 2017 pView->SetClipRegion( aOutputArea ); 2018 bResetClipRegion = sal_True; 2019 } 2020 } 2021 2022 #ifdef OV_DRAWBOUNDRECT 2023 { 2024 Color aXOldColor = pOut->GetLineColor(); 2025 pOut->SetLineColor( Color( COL_LIGHTRED ) ); 2026 Rectangle aXRect( pEntry->aRect ); 2027 aXRect.SetPos( rPos ); 2028 pOut->DrawRect( aXRect ); 2029 pOut->SetLineColor( aXOldColor ); 2030 } 2031 #endif 2032 2033 sal_Bool bLargeIconMode = WB_ICON == ( nWinBits & (VIEWMODE_MASK) ); 2034 sal_uInt16 nBmpPaintFlags = PAINTFLAG_VER_CENTERED; 2035 if ( bLargeIconMode ) 2036 nBmpPaintFlags |= PAINTFLAG_HOR_CENTERED; 2037 sal_uInt16 nTextPaintFlags = bLargeIconMode ? PAINTFLAG_HOR_CENTERED : PAINTFLAG_VER_CENTERED; 2038 2039 if( !bNoEmphasis ) 2040 PaintEmphasis(aTextRect,aBmpRect,bSelected,bDropTarget,bCursored,pOut,bIsBackgroundPainted); 2041 2042 if ( bShowSelection ) 2043 pView->DrawSelectionBackground( CalcFocusRect( pEntry ), 2044 bActiveSelection ? 1 : 2 /* highlight */, sal_False /* check */, sal_True /* border */, sal_False /* ext border only */ ); 2045 2046 PaintItem( aBmpRect, IcnViewFieldTypeImage, pEntry, nBmpPaintFlags, pOut ); 2047 2048 PaintItem( aTextRect, IcnViewFieldTypeText, pEntry, 2049 nTextPaintFlags, pOut ); 2050 2051 // Highlight-Frame zeichnen 2052 if( pEntry == pCurHighlightFrame && !bNoEmphasis ) 2053 DrawHighlightFrame( pOut, CalcFocusRect( pEntry ), sal_False ); 2054 2055 pOut->SetFont( aTempFont ); 2056 if( bResetClipRegion ) 2057 pView->SetClipRegion(); 2058 } 2059 2060 void SvxIconChoiceCtrl_Impl::SetEntryPos( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos, 2061 sal_Bool bAdjustAtGrid, sal_Bool bCheckScrollBars, sal_Bool bKeepGridMap ) 2062 { 2063 ShowCursor( sal_False ); 2064 Rectangle aBoundRect( GetEntryBoundRect( pEntry )); 2065 pView->Invalidate( aBoundRect ); 2066 ToTop( pEntry ); 2067 if( !IsAutoArrange() ) 2068 { 2069 sal_Bool bAdjustVirtSize = sal_False; 2070 if( rPos != aBoundRect.TopLeft() ) 2071 { 2072 Point aGridOffs( 2073 pEntry->aGridRect.TopLeft() - pEntry->aRect.TopLeft() ); 2074 pImpCursor->Clear(); 2075 if( !bKeepGridMap ) 2076 pGridMap->Clear(); 2077 aBoundRect.SetPos( rPos ); 2078 pEntry->aRect = aBoundRect; 2079 pEntry->aGridRect.SetPos( rPos + aGridOffs ); 2080 bAdjustVirtSize = sal_True; 2081 } 2082 if( bAdjustAtGrid ) 2083 { 2084 if( bAdjustVirtSize ) 2085 { 2086 // Durch das Ausrichten des (ggf. gerade neu positionierten) Eintrags, 2087 // kann er wieder komplett 2088 // in den sichtbaren Bereich rutschen, so dass u.U. doch keine Scrollbar 2089 // eingeblendet werden muss. Um deshalb ein 'Aufblitzen' der 2090 // Scrollbar(s) zu vermeiden, wird zum Aufplustern der virtuellen 2091 // Ausgabegroesse bereits das ausgerichtete Boundrect des 2092 // Eintrags genommen. Die virtuelle Groesse muss angepasst werden, 2093 // da AdjustEntryAtGrid von ihr abhaengt. 2094 const Rectangle& rBoundRect = GetEntryBoundRect( pEntry ); 2095 Rectangle aCenterRect( CalcBmpRect( pEntry, 0 )); 2096 Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) ); 2097 Rectangle aNewBoundRect( aNewPos, pEntry->aRect.GetSize()); 2098 AdjustVirtSize( aNewBoundRect ); 2099 bAdjustVirtSize = sal_False; 2100 } 2101 AdjustEntryAtGrid( pEntry ); 2102 ToTop( pEntry ); 2103 } 2104 if( bAdjustVirtSize ) 2105 AdjustVirtSize( pEntry->aRect ); 2106 2107 if( bCheckScrollBars && bUpdateMode ) 2108 CheckScrollBars(); 2109 2110 pView->Invalidate( pEntry->aRect ); 2111 pGridMap->OccupyGrids( pEntry ); 2112 } 2113 else 2114 { 2115 SvxIconChoiceCtrlEntry* pPrev = FindEntryPredecessor( pEntry, rPos ); 2116 SetEntryPredecessor( pEntry, pPrev ); 2117 aAutoArrangeTimer.Start(); 2118 } 2119 ShowCursor( sal_True ); 2120 } 2121 2122 void SvxIconChoiceCtrl_Impl::SetNoSelection() 2123 { 2124 // rekursive Aufrufe ueber SelectEntry abblocken 2125 if( !(nFlags & F_CLEARING_SELECTION )) 2126 { 2127 nFlags |= F_CLEARING_SELECTION; 2128 DeselectAllBut( 0, sal_True ); 2129 nFlags &= ~F_CLEARING_SELECTION; 2130 } 2131 } 2132 2133 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos, sal_Bool bHit ) 2134 { 2135 CheckBoundingRects(); 2136 // Z-Order-Liste vom Ende her absuchen 2137 sal_uLong nCount = pZOrderList->Count(); 2138 while( nCount ) 2139 { 2140 nCount--; 2141 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCount)); 2142 if( pEntry->aRect.IsInside( rDocPos ) ) 2143 { 2144 if( bHit ) 2145 { 2146 Rectangle aRect = CalcBmpRect( pEntry ); 2147 aRect.Top() -= 3; 2148 aRect.Bottom() += 3; 2149 aRect.Left() -= 3; 2150 aRect.Right() += 3; 2151 if( aRect.IsInside( rDocPos ) ) 2152 return pEntry; 2153 aRect = CalcTextRect( pEntry ); 2154 if( aRect.IsInside( rDocPos ) ) 2155 return pEntry; 2156 } 2157 else 2158 return pEntry; 2159 } 2160 } 2161 return 0; 2162 } 2163 2164 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetNextEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry ) 2165 { 2166 CheckBoundingRects(); 2167 SvxIconChoiceCtrlEntry* pTarget = 0; 2168 const sal_uLong nStartPos = pZOrderList->GetPos( (void*)pCurEntry ); 2169 if( nStartPos != LIST_ENTRY_NOTFOUND ) 2170 { 2171 const sal_uLong nCount = pZOrderList->Count(); 2172 for( sal_uLong nCur = nStartPos+1; nCur < nCount; nCur++ ) 2173 { 2174 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nCur)); 2175 if( pEntry->aRect.IsInside( rDocPos ) ) 2176 { 2177 pTarget = pEntry; 2178 break; 2179 } 2180 } 2181 } 2182 return pTarget; 2183 } 2184 2185 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetPrevEntry( const Point& rDocPos, SvxIconChoiceCtrlEntry* pCurEntry ) 2186 { 2187 CheckBoundingRects(); 2188 SvxIconChoiceCtrlEntry* pTarget = 0; 2189 sal_uLong nStartPos = pZOrderList->GetPos( (void*)pCurEntry ); 2190 if( nStartPos != LIST_ENTRY_NOTFOUND && nStartPos != 0 ) 2191 { 2192 nStartPos--; 2193 do 2194 { 2195 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nStartPos)); 2196 if( pEntry->aRect.IsInside( rDocPos ) ) 2197 { 2198 pTarget = pEntry; 2199 break; 2200 } 2201 } while( nStartPos > 0 ); 2202 } 2203 return pTarget; 2204 } 2205 2206 Point SvxIconChoiceCtrl_Impl::GetEntryPos( SvxIconChoiceCtrlEntry* pEntry ) 2207 { 2208 return pEntry->aRect.TopLeft(); 2209 } 2210 2211 void SvxIconChoiceCtrl_Impl::MakeEntryVisible( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bBound ) 2212 { 2213 if ( bBound ) 2214 { 2215 const Rectangle& rRect = GetEntryBoundRect( pEntry ); 2216 MakeVisible( rRect ); 2217 } 2218 else 2219 { 2220 Rectangle aRect = CalcBmpRect( pEntry ); 2221 aRect.Union( CalcTextRect( pEntry ) ); 2222 aRect.Top() += TBOFFS_BOUND; 2223 aRect.Bottom() += TBOFFS_BOUND; 2224 aRect.Left() += LROFFS_BOUND; 2225 aRect.Right() += LROFFS_BOUND; 2226 MakeVisible( aRect ); 2227 } 2228 } 2229 2230 const Rectangle& SvxIconChoiceCtrl_Impl::GetEntryBoundRect( SvxIconChoiceCtrlEntry* pEntry ) 2231 { 2232 if( !IsBoundingRectValid( pEntry->aRect )) 2233 FindBoundingRect( pEntry ); 2234 return pEntry->aRect; 2235 } 2236 2237 Rectangle SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry* pEntry, const Point* pPos ) 2238 { 2239 Rectangle aBound = GetEntryBoundRect( pEntry ); 2240 if( pPos ) 2241 aBound.SetPos( *pPos ); 2242 Point aPos( aBound.TopLeft() ); 2243 2244 switch( nWinBits & (VIEWMODE_MASK) ) 2245 { 2246 case WB_ICON: 2247 { 2248 aPos.X() += ( aBound.GetWidth() - aImageSize.Width() ) / 2; 2249 return Rectangle( aPos, aImageSize ); 2250 } 2251 2252 case WB_SMALLICON: 2253 case WB_DETAILS: 2254 aPos.Y() += ( aBound.GetHeight() - aImageSize.Height() ) / 2; 2255 //todo: hor. Abstand zum BoundRect? 2256 return Rectangle( aPos, aImageSize ); 2257 2258 default: 2259 DBG_ERROR("IconView: Viewmode not set"); 2260 return aBound; 2261 } 2262 } 2263 2264 Rectangle SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry* pEntry, 2265 const Point* pEntryPos, sal_Bool bEdit, const String* pStr ) 2266 { 2267 String aEntryText; 2268 if( !pStr ) 2269 aEntryText = pView->GetEntryText( pEntry, bEdit ); 2270 else 2271 aEntryText = *pStr; 2272 2273 const Rectangle aMaxTextRect( CalcMaxTextRect( pEntry ) ); 2274 Rectangle aBound( GetEntryBoundRect( pEntry ) ); 2275 if( pEntryPos ) 2276 aBound.SetPos( *pEntryPos ); 2277 2278 Rectangle aTextRect( aMaxTextRect ); 2279 if( !bEdit ) 2280 aTextRect = pView->GetTextRect( aTextRect, aEntryText, nCurTextDrawFlags ); 2281 2282 Size aTextSize( aTextRect.GetSize() ); 2283 2284 Point aPos( aBound.TopLeft() ); 2285 long nBoundWidth = aBound.GetWidth(); 2286 long nBoundHeight = aBound.GetHeight(); 2287 2288 switch( nWinBits & (VIEWMODE_MASK) ) 2289 { 2290 case WB_ICON: 2291 aPos.Y() += aImageSize.Height(); 2292 aPos.Y() += VER_DIST_BMP_STRING; 2293 // beim Editieren etwas mehr Platz 2294 if( bEdit ) 2295 { 2296 // 20% rauf 2297 long nMinWidth = (( (aImageSize.Width()*10) / 100 ) * 2 ) + 2298 aImageSize.Width(); 2299 if( nMinWidth > nBoundWidth ) 2300 nMinWidth = nBoundWidth; 2301 2302 if( aTextSize.Width() < nMinWidth ) 2303 aTextSize.Width() = nMinWidth; 2304 2305 // beim Editieren ist Ueberlappung nach unten erlaubt 2306 Size aOptSize = aMaxTextRect.GetSize(); 2307 if( aOptSize.Height() > aTextSize.Height() ) 2308 aTextSize.Height() = aOptSize.Height(); 2309 } 2310 aPos.X() += (nBoundWidth - aTextSize.Width()) / 2; 2311 break; 2312 2313 case WB_SMALLICON: 2314 case WB_DETAILS: 2315 aPos.X() += aImageSize.Width(); 2316 aPos.X() += HOR_DIST_BMP_STRING; 2317 aPos.Y() += (nBoundHeight - aTextSize.Height()) / 2; 2318 break; 2319 } 2320 return Rectangle( aPos, aTextSize ); 2321 } 2322 2323 2324 long SvxIconChoiceCtrl_Impl::CalcBoundingWidth( SvxIconChoiceCtrlEntry* pEntry ) const 2325 { 2326 long nStringWidth = GetItemSize( pEntry, IcnViewFieldTypeText ).Width(); 2327 // nStringWidth += 2*LROFFS_TEXT; 2328 long nWidth = 0; 2329 2330 switch( nWinBits & (VIEWMODE_MASK) ) 2331 { 2332 case WB_ICON: 2333 nWidth = Max( nStringWidth, aImageSize.Width() ); 2334 break; 2335 2336 case WB_SMALLICON: 2337 case WB_DETAILS: 2338 nWidth = aImageSize.Width(); 2339 nWidth += HOR_DIST_BMP_STRING; 2340 nWidth += nStringWidth; 2341 break; 2342 } 2343 return nWidth; 2344 } 2345 2346 long SvxIconChoiceCtrl_Impl::CalcBoundingHeight( SvxIconChoiceCtrlEntry* pEntry ) const 2347 { 2348 long nStringHeight = GetItemSize( pEntry, IcnViewFieldTypeText).Height(); 2349 long nHeight = 0; 2350 2351 switch( nWinBits & (VIEWMODE_MASK) ) 2352 { 2353 case WB_ICON: 2354 nHeight = aImageSize.Height(); 2355 nHeight += VER_DIST_BMP_STRING; 2356 nHeight += nStringHeight; 2357 break; 2358 2359 case WB_SMALLICON: 2360 case WB_DETAILS: 2361 nHeight = Max( aImageSize.Height(), nStringHeight ); 2362 break; 2363 } 2364 if( nHeight > nMaxBoundHeight ) 2365 { 2366 ((SvxIconChoiceCtrl_Impl*)this)->nMaxBoundHeight = nHeight; 2367 ((SvxIconChoiceCtrl_Impl*)this)->aHorSBar.SetLineSize( GetScrollBarLineSize() ); 2368 ((SvxIconChoiceCtrl_Impl*)this)->aVerSBar.SetLineSize( GetScrollBarLineSize() ); 2369 } 2370 return nHeight; 2371 } 2372 2373 Size SvxIconChoiceCtrl_Impl::CalcBoundingSize( SvxIconChoiceCtrlEntry* pEntry ) const 2374 { 2375 return Size( CalcBoundingWidth( pEntry ), 2376 CalcBoundingHeight( pEntry ) ); 2377 } 2378 2379 void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRects() 2380 { 2381 nMaxBoundHeight = 0; 2382 pZOrderList->Clear(); 2383 sal_uLong nCount = aEntries.Count(); 2384 sal_uLong nCur; 2385 SvxIconChoiceCtrlEntry* pEntry; 2386 2387 if( !IsAutoArrange() || !pHead ) 2388 { 2389 for( nCur = 0; nCur < nCount; nCur++ ) 2390 { 2391 pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 2392 FindBoundingRect( pEntry ); 2393 pZOrderList->Insert( pEntry, LIST_APPEND ); 2394 } 2395 } 2396 else 2397 { 2398 nCur = 0; 2399 pEntry = pHead; 2400 while( nCur != nCount ) 2401 { 2402 DBG_ASSERT(pEntry->pflink&&pEntry->pblink,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)"); 2403 FindBoundingRect( pEntry ); 2404 pZOrderList->Insert( pEntry, pZOrderList->Count() ); 2405 pEntry = pEntry->pflink; 2406 nCur++; 2407 } 2408 } 2409 bBoundRectsDirty = sal_False; 2410 AdjustScrollBars(); 2411 } 2412 2413 void SvxIconChoiceCtrl_Impl::RecalcAllBoundingRectsSmart() 2414 { 2415 nMaxBoundHeight = 0; 2416 pZOrderList->Clear(); 2417 sal_uLong nCur; 2418 SvxIconChoiceCtrlEntry* pEntry; 2419 const sal_uLong nCount = aEntries.Count(); 2420 2421 if( !IsAutoArrange() || !pHead ) 2422 { 2423 for( nCur = 0; nCur < nCount; nCur++ ) 2424 { 2425 pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 2426 if( IsBoundingRectValid( pEntry->aRect )) 2427 { 2428 Size aBoundSize( pEntry->aRect.GetSize() ); 2429 if( aBoundSize.Height() > nMaxBoundHeight ) 2430 nMaxBoundHeight = aBoundSize.Height(); 2431 } 2432 else 2433 FindBoundingRect( pEntry ); 2434 pZOrderList->Insert( pEntry, LIST_APPEND ); 2435 } 2436 } 2437 else 2438 { 2439 nCur = 0; 2440 pEntry = pHead; 2441 while( nCur != nCount ) 2442 { 2443 DBG_ASSERT(pEntry->pflink&&pEntry->pblink,"SvxIconChoiceCtrl_Impl::RecalcAllBoundingRect > Bad link(s)"); 2444 if( IsBoundingRectValid( pEntry->aRect )) 2445 { 2446 Size aBoundSize( pEntry->aRect.GetSize() ); 2447 if( aBoundSize.Height() > nMaxBoundHeight ) 2448 nMaxBoundHeight = aBoundSize.Height(); 2449 } 2450 else 2451 FindBoundingRect( pEntry ); 2452 pZOrderList->Insert( pEntry, LIST_APPEND ); 2453 pEntry = pEntry->pflink; 2454 nCur++; 2455 } 2456 } 2457 AdjustScrollBars(); 2458 } 2459 2460 void SvxIconChoiceCtrl_Impl::UpdateBoundingRects() 2461 { 2462 const sal_uLong nCount = aEntries.Count(); 2463 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 2464 { 2465 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 2466 GetEntryBoundRect( pEntry ); 2467 } 2468 } 2469 2470 void SvxIconChoiceCtrl_Impl::FindBoundingRect( SvxIconChoiceCtrlEntry* pEntry ) 2471 { 2472 DBG_ASSERT(!pEntry->IsPosLocked(),"Locked entry pos in FindBoundingRect"); 2473 if( pEntry->IsPosLocked() && IsBoundingRectValid( pEntry->aRect) ) 2474 { 2475 AdjustVirtSize( pEntry->aRect ); 2476 return; 2477 } 2478 Size aSize( CalcBoundingSize( pEntry ) ); 2479 Point aPos(pGridMap->GetGridRect(pGridMap->GetUnoccupiedGrid(sal_True)).TopLeft()); 2480 SetBoundingRect_Impl( pEntry, aPos, aSize ); 2481 } 2482 2483 void SvxIconChoiceCtrl_Impl::SetBoundingRect_Impl( SvxIconChoiceCtrlEntry* pEntry, const Point& rPos, 2484 const Size& /*rBoundingSize*/ ) 2485 { 2486 Rectangle aGridRect( rPos, Size(nGridDX, nGridDY) ); 2487 pEntry->aGridRect = aGridRect; 2488 Center( pEntry ); 2489 AdjustVirtSize( pEntry->aRect ); 2490 pGridMap->OccupyGrids( pEntry ); 2491 } 2492 2493 2494 void SvxIconChoiceCtrl_Impl::SetCursor( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bSyncSingleSelection, 2495 sal_Bool bShowFocusAsync ) 2496 { 2497 if( pEntry == pCursor ) 2498 { 2499 if( pCursor && eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection && 2500 !pCursor->IsSelected() ) 2501 SelectEntry( pCursor, sal_True, sal_True ); 2502 return; 2503 } 2504 ShowCursor( sal_False ); 2505 SvxIconChoiceCtrlEntry* pOldCursor = pCursor; 2506 pCursor = pEntry; 2507 if( pOldCursor ) 2508 { 2509 pOldCursor->ClearFlags( ICNVIEW_FLAG_FOCUSED ); 2510 if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection ) 2511 SelectEntry( pOldCursor, sal_False, sal_True ); // alten Cursor deselektieren 2512 } 2513 if( pCursor ) 2514 { 2515 ToTop( pCursor ); 2516 pCursor->SetFlags( ICNVIEW_FLAG_FOCUSED ); 2517 if( eSelectionMode == SINGLE_SELECTION && bSyncSingleSelection ) 2518 SelectEntry( pCursor, sal_True, sal_True ); 2519 if( !bShowFocusAsync ) 2520 ShowCursor( sal_True ); 2521 else 2522 { 2523 if( !nUserEventShowCursor ) 2524 nUserEventShowCursor = 2525 Application::PostUserEvent( LINK( this, SvxIconChoiceCtrl_Impl, UserEventHdl), 2526 EVENTID_SHOW_CURSOR ); 2527 } 2528 } 2529 } 2530 2531 2532 void SvxIconChoiceCtrl_Impl::ShowCursor( sal_Bool bShow ) 2533 { 2534 if( !pCursor || !bShow || !pView->HasFocus() ) 2535 { 2536 pView->HideFocus(); 2537 return; 2538 } 2539 Rectangle aRect ( CalcFocusRect( pCursor ) ); 2540 /*pView->*/ShowFocus( aRect ); 2541 } 2542 2543 2544 void SvxIconChoiceCtrl_Impl::HideDDIcon() 2545 { 2546 pView->Update(); 2547 ImpHideDDIcon(); 2548 pDDBufDev = pDDDev; 2549 pDDDev = 0; 2550 } 2551 2552 void SvxIconChoiceCtrl_Impl::ImpHideDDIcon() 2553 { 2554 if( pDDDev ) 2555 { 2556 Size aSize( pDDDev->GetOutputSizePixel() ); 2557 // pView restaurieren 2558 pView->DrawOutDev( aDDLastRectPos, aSize, Point(), aSize, *pDDDev ); 2559 } 2560 } 2561 2562 2563 void SvxIconChoiceCtrl_Impl::ShowDDIcon( SvxIconChoiceCtrlEntry* pRefEntry, const Point& rPosPix ) 2564 { 2565 pView->Update(); 2566 if( pRefEntry != pDDRefEntry ) 2567 { 2568 DELETEZ(pDDDev); 2569 DELETEZ(pDDBufDev); 2570 } 2571 sal_Bool bSelected = pRefEntry->IsSelected(); 2572 pRefEntry->ClearFlags( ICNVIEW_FLAG_SELECTED ); 2573 if( !pDDDev ) 2574 { 2575 if( pDDBufDev ) 2576 { 2577 // nicht bei jedem Move ein Device anlegen, da dies besonders 2578 // auf Remote-Clients zu langsam ist 2579 pDDDev = pDDBufDev; 2580 pDDBufDev = 0; 2581 } 2582 else 2583 { 2584 pDDDev = new VirtualDevice( *pView ); 2585 pDDDev->SetFont( pView->GetFont() ); 2586 } 2587 } 2588 else 2589 { 2590 ImpHideDDIcon(); 2591 } 2592 const Rectangle& rRect = GetEntryBoundRect( pRefEntry ); 2593 pDDDev->SetOutputSizePixel( rRect.GetSize() ); 2594 2595 Point aPos( rPosPix ); 2596 ToDocPos( aPos ); 2597 2598 Size aSize( pDDDev->GetOutputSizePixel() ); 2599 pDDRefEntry = pRefEntry; 2600 aDDLastEntryPos = aPos; 2601 aDDLastRectPos = aPos; 2602 2603 // Hintergrund sichern 2604 pDDDev->DrawOutDev( Point(), aSize, aPos, aSize, *pView ); 2605 // Icon in pView malen 2606 pRefEntry->SetFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS ); 2607 PaintEntry( pRefEntry, aPos ); 2608 pRefEntry->ClearFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS ); 2609 if( bSelected ) 2610 pRefEntry->SetFlags( ICNVIEW_FLAG_SELECTED ); 2611 } 2612 2613 void SvxIconChoiceCtrl_Impl::HideShowDDIcon( SvxIconChoiceCtrlEntry* pRefEntry, const Point& rPosPix ) 2614 { 2615 /* In Notfaellen folgenden flackernden Code aktivieren: 2616 2617 HideDDIcon(); 2618 ShowDDIcon( pRefEntry, rPosPix ); 2619 return; 2620 */ 2621 if( !pDDDev ) 2622 { 2623 ShowDDIcon( pRefEntry, rPosPix ); 2624 return; 2625 } 2626 2627 if( pRefEntry != pDDRefEntry ) 2628 { 2629 HideDDIcon(); 2630 ShowDDIcon( pRefEntry, rPosPix ); 2631 return; 2632 } 2633 2634 Point aEmptyPoint; 2635 2636 Point aCurEntryPos( rPosPix ); 2637 ToDocPos( aCurEntryPos ); 2638 2639 const Rectangle& rRect = GetEntryBoundRect( pRefEntry ); 2640 Size aEntrySize( rRect.GetSize() ); 2641 Rectangle aPrevEntryRect( aDDLastEntryPos, aEntrySize ); 2642 Rectangle aCurEntryRect( aCurEntryPos, aEntrySize ); 2643 2644 if( !aPrevEntryRect.IsOver( aCurEntryRect ) ) 2645 { 2646 HideDDIcon(); 2647 ShowDDIcon( pRefEntry, rPosPix ); 2648 return; 2649 } 2650 2651 // Ueberlappung des neuen und alten D&D-Pointers! 2652 2653 Rectangle aFullRect( aPrevEntryRect.Union( aCurEntryRect ) ); 2654 if( !pDDTempDev ) 2655 { 2656 pDDTempDev = new VirtualDevice( *pView ); 2657 pDDTempDev->SetFont( pView->GetFont() ); 2658 } 2659 2660 Size aFullSize( aFullRect.GetSize() ); 2661 Point aFullPos( aFullRect.TopLeft() ); 2662 2663 pDDTempDev->SetOutputSizePixel( aFullSize ); 2664 2665 // Hintergrund (mit dem alten D&D-Pointer!) sichern 2666 pDDTempDev->DrawOutDev( aEmptyPoint, aFullSize, aFullPos, aFullSize, *pView ); 2667 // den alten Buffer in den neuen Buffer pasten 2668 aDDLastRectPos = aDDLastRectPos - aFullPos; 2669 2670 pDDTempDev->DrawOutDev( 2671 aDDLastRectPos, 2672 pDDDev->GetOutputSizePixel(), 2673 aEmptyPoint, 2674 pDDDev->GetOutputSizePixel(), 2675 *pDDDev ); 2676 2677 // Swap 2678 VirtualDevice* pTemp = pDDDev; 2679 pDDDev = pDDTempDev; 2680 pDDTempDev = pTemp; 2681 2682 // in den restaurierten Hintergrund den neuen D&D-Pointer zeichnen 2683 pDDTempDev->SetOutputSizePixel( pDDDev->GetOutputSizePixel() ); 2684 pDDTempDev->DrawOutDev( 2685 aEmptyPoint, aFullSize, aEmptyPoint, aFullSize, *pDDDev ); 2686 Point aRelPos = aCurEntryPos - aFullPos; 2687 pRefEntry->SetFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS ); 2688 PaintEntry( pRefEntry, aRelPos, pDDTempDev ); 2689 pRefEntry->ClearFlags( ICNVIEW_FLAG_BLOCK_EMPHASIS ); 2690 2691 aDDLastRectPos = aFullPos; 2692 aDDLastEntryPos = aCurEntryPos; 2693 2694 pView->DrawOutDev( 2695 aDDLastRectPos, 2696 pDDDev->GetOutputSizePixel(), 2697 aEmptyPoint, 2698 pDDDev->GetOutputSizePixel(), 2699 *pDDTempDev ); 2700 } 2701 2702 void SvxIconChoiceCtrl_Impl::InvalidateBoundingRect( SvxIconChoiceCtrlEntry* pEntry ) 2703 { 2704 InvalidateBoundingRect( pEntry->aRect ); 2705 } 2706 2707 2708 sal_Bool SvxIconChoiceCtrl_Impl::HandleScrollCommand( const CommandEvent& rCmd ) 2709 { 2710 Rectangle aDocRect( GetDocumentRect() ); 2711 Rectangle aVisRect( GetVisibleRect() ); 2712 if( aVisRect.IsInside( aDocRect )) 2713 return sal_False; 2714 Size aDocSize( aDocRect.GetSize() ); 2715 Size aVisSize( aVisRect.GetSize() ); 2716 sal_Bool bHor = aDocSize.Width() > aVisSize.Width(); 2717 sal_Bool bVer = aDocSize.Height() > aVisSize.Height(); 2718 2719 long nScrollDX = 0, nScrollDY = 0; 2720 2721 switch( rCmd.GetCommand() ) 2722 { 2723 case COMMAND_STARTAUTOSCROLL: 2724 { 2725 pView->EndTracking(); 2726 sal_uInt16 nScrollFlags = 0; 2727 if( bHor ) 2728 nScrollFlags |= AUTOSCROLL_HORZ; 2729 if( bVer ) 2730 nScrollFlags |= AUTOSCROLL_VERT; 2731 if( nScrollFlags ) 2732 { 2733 pView->StartAutoScroll( nScrollFlags ); 2734 return sal_True; 2735 } 2736 } 2737 break; 2738 2739 case COMMAND_WHEEL: 2740 { 2741 const CommandWheelData* pData = rCmd.GetWheelData(); 2742 if( pData && (COMMAND_WHEEL_SCROLL == pData->GetMode()) && !pData->IsHorz() ) 2743 { 2744 sal_uLong nScrollLines = pData->GetScrollLines(); 2745 if( nScrollLines == COMMAND_WHEEL_PAGESCROLL ) 2746 { 2747 nScrollDY = GetScrollBarPageSize( aVisSize.Width() ); 2748 if( pData->GetDelta() < 0 ) 2749 nScrollDY *= -1; 2750 } 2751 else 2752 { 2753 nScrollDY = pData->GetNotchDelta() * (long)nScrollLines; 2754 nScrollDY *= GetScrollBarLineSize(); 2755 } 2756 } 2757 } 2758 break; 2759 2760 case COMMAND_AUTOSCROLL: 2761 { 2762 const CommandScrollData* pData = rCmd.GetAutoScrollData(); 2763 if( pData ) 2764 { 2765 nScrollDX = pData->GetDeltaX() * GetScrollBarLineSize(); 2766 nScrollDY = pData->GetDeltaY() * GetScrollBarLineSize(); 2767 } 2768 } 2769 break; 2770 } 2771 2772 if( nScrollDX || nScrollDY ) 2773 { 2774 aVisRect.Top() -= nScrollDY; 2775 aVisRect.Bottom() -= nScrollDY; 2776 aVisRect.Left() -= nScrollDX; 2777 aVisRect.Right() -= nScrollDX; 2778 MakeVisible( aVisRect ); 2779 return sal_True; 2780 } 2781 return sal_False; 2782 } 2783 2784 2785 void SvxIconChoiceCtrl_Impl::Command( const CommandEvent& rCEvt ) 2786 { 2787 // Rollmaus-Event? 2788 if( (rCEvt.GetCommand() == COMMAND_WHEEL) || 2789 (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) || 2790 (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) ) 2791 { 2792 #if 1 2793 if( HandleScrollCommand( rCEvt ) ) 2794 return; 2795 #else 2796 ScrollBar* pHor = aHorSBar.IsVisible() ? &aHorSBar : 0; 2797 ScrollBar* pVer = aVerSBar.IsVisible() ? &aVerSBar : 0; 2798 if( pView->HandleScrollCommand( rCEvt, pHor, pVer ) ) 2799 return; 2800 #endif 2801 } 2802 } 2803 2804 void SvxIconChoiceCtrl_Impl::ToTop( SvxIconChoiceCtrlEntry* pEntry ) 2805 { 2806 if( pZOrderList->GetObject( pZOrderList->Count() - 1 ) != pEntry ) 2807 { 2808 sal_uLong nPos = pZOrderList->GetPos( (void*)pEntry ); 2809 pZOrderList->Remove( nPos ); 2810 pZOrderList->Insert( pEntry, LIST_APPEND ); 2811 } 2812 } 2813 2814 void SvxIconChoiceCtrl_Impl::ClipAtVirtOutRect( Rectangle& rRect ) const 2815 { 2816 if( rRect.Bottom() >= aVirtOutputSize.Height() ) 2817 rRect.Bottom() = aVirtOutputSize.Height() - 1; 2818 if( rRect.Right() >= aVirtOutputSize.Width() ) 2819 rRect.Right() = aVirtOutputSize.Width() - 1; 2820 if( rRect.Top() < 0 ) 2821 rRect.Top() = 0; 2822 if( rRect.Left() < 0 ) 2823 rRect.Left() = 0; 2824 } 2825 2826 // rRect: Bereich des Dokumentes (in Dokumentkoordinaten), der 2827 // sichtbar gemacht werden soll. 2828 // bScrBar == sal_True: Das Rect wurde aufgrund eines ScrollBar-Events berechnet 2829 2830 void SvxIconChoiceCtrl_Impl::MakeVisible( const Rectangle& rRect, sal_Bool bScrBar, 2831 sal_Bool bCallRectChangedHdl ) 2832 { 2833 Rectangle aVirtRect( rRect ); 2834 ClipAtVirtOutRect( aVirtRect ); 2835 Point aOrigin( pView->GetMapMode().GetOrigin() ); 2836 // in Dokumentkoordinate umwandeln 2837 aOrigin *= -1; 2838 Rectangle aOutputArea( GetOutputRect() ); 2839 if( aOutputArea.IsInside( aVirtRect ) ) 2840 return; // ist schon sichtbar 2841 2842 long nDy; 2843 if( aVirtRect.Top() < aOutputArea.Top() ) 2844 { 2845 // nach oben scrollen (nDy < 0) 2846 nDy = aVirtRect.Top() - aOutputArea.Top(); 2847 } 2848 else if( aVirtRect.Bottom() > aOutputArea.Bottom() ) 2849 { 2850 // nach unten scrollen (nDy > 0) 2851 nDy = aVirtRect.Bottom() - aOutputArea.Bottom(); 2852 } 2853 else 2854 nDy = 0; 2855 2856 long nDx; 2857 if( aVirtRect.Left() < aOutputArea.Left() ) 2858 { 2859 // nach links scrollen (nDx < 0) 2860 nDx = aVirtRect.Left() - aOutputArea.Left(); 2861 } 2862 else if( aVirtRect.Right() > aOutputArea.Right() ) 2863 { 2864 // nach rechts scrollen (nDx > 0) 2865 nDx = aVirtRect.Right() - aOutputArea.Right(); 2866 } 2867 else 2868 nDx = 0; 2869 2870 aOrigin.X() += nDx; 2871 aOrigin.Y() += nDy; 2872 aOutputArea.SetPos( aOrigin ); 2873 if( GetUpdateMode() ) 2874 { 2875 HideDDIcon(); 2876 pView->Update(); 2877 ShowCursor( sal_False ); 2878 } 2879 2880 // Origin fuer SV invertieren (damit wir in 2881 // Dokumentkoordinaten scrollen/painten koennen) 2882 aOrigin *= -1; 2883 SetOrigin( aOrigin ); 2884 2885 sal_Bool bScrollable = pView->GetBackground().IsScrollable(); 2886 if( pView->HasBackground() && !bScrollable ) 2887 { 2888 Rectangle aRect( GetOutputRect()); 2889 Wallpaper aPaper( pView->GetBackground() ); 2890 aPaper.SetRect( aRect ); 2891 pView->SetBackground( aPaper ); 2892 } 2893 2894 if( bScrollable && GetUpdateMode() ) 2895 { 2896 // in umgekehrte Richtung scrollen! 2897 pView->Control::Scroll( -nDx, -nDy, aOutputArea, 2898 SCROLL_NOCHILDREN | SCROLL_USECLIPREGION | SCROLL_CLIP ); 2899 } 2900 else 2901 pView->Invalidate(INVALIDATE_NOCHILDREN); 2902 2903 if( aHorSBar.IsVisible() || aVerSBar.IsVisible() ) 2904 { 2905 if( !bScrBar ) 2906 { 2907 aOrigin *= -1; 2908 // Thumbs korrigieren 2909 if(aHorSBar.IsVisible() && aHorSBar.GetThumbPos() != aOrigin.X()) 2910 aHorSBar.SetThumbPos( aOrigin.X() ); 2911 if(aVerSBar.IsVisible() && aVerSBar.GetThumbPos() != aOrigin.Y()) 2912 aVerSBar.SetThumbPos( aOrigin.Y() ); 2913 } 2914 } 2915 2916 if( GetUpdateMode() ) 2917 ShowCursor( sal_True ); 2918 2919 // pruefen, ob ScrollBars noch benoetigt werden 2920 CheckScrollBars(); 2921 if( bScrollable && GetUpdateMode() ) 2922 pView->Update(); 2923 2924 // kann der angeforderte Bereich nicht komplett sichtbar gemacht werden, 2925 // wird auf jeden Fall der Vis-Rect-Changed-Handler gerufen. Eintreten kann der 2926 // Fall z.B. wenn nur wenige Pixel des unteren Randes nicht sichtbar sind, 2927 // eine ScrollBar aber eine groessere Line-Size eingestellt hat. 2928 if( bCallRectChangedHdl || GetOutputRect() != rRect ) 2929 VisRectChanged(); 2930 } 2931 2932 2933 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::FindNewCursor() 2934 { 2935 SvxIconChoiceCtrlEntry* pNewCursor; 2936 if( pCursor ) 2937 { 2938 pNewCursor = pImpCursor->GoLeftRight( pCursor, sal_False ); 2939 if( !pNewCursor ) 2940 { 2941 pNewCursor = pImpCursor->GoLeftRight( pCursor, sal_True ); 2942 if( !pNewCursor ) 2943 { 2944 pNewCursor = pImpCursor->GoUpDown( pCursor, sal_False ); 2945 if( !pNewCursor ) 2946 pNewCursor = pImpCursor->GoUpDown( pCursor, sal_True ); 2947 } 2948 } 2949 } 2950 else 2951 pNewCursor = (SvxIconChoiceCtrlEntry*)aEntries.First(); 2952 DBG_ASSERT(!pNewCursor|| (pCursor&&pCursor!=pNewCursor),"FindNewCursor failed"); 2953 return pNewCursor; 2954 } 2955 2956 sal_uLong SvxIconChoiceCtrl_Impl::GetSelectionCount() const 2957 { 2958 if( (nWinBits & WB_HIGHLIGHTFRAME) && pCurHighlightFrame ) 2959 return 1; 2960 return nSelectionCount; 2961 } 2962 2963 void SvxIconChoiceCtrl_Impl::ToggleSelection( SvxIconChoiceCtrlEntry* pEntry ) 2964 { 2965 sal_Bool bSel; 2966 if( pEntry->IsSelected() ) 2967 bSel = sal_False; 2968 else 2969 bSel = sal_True; 2970 SelectEntry( pEntry, bSel, sal_True, sal_True ); 2971 } 2972 2973 void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry* pThisEntryNot, 2974 sal_Bool bPaintSync ) 2975 { 2976 ClearSelectedRectList(); 2977 // 2978 // !!!!!!! Todo: Evtl. Z-Orderlist abarbeiten !!!!!!! 2979 // 2980 sal_uLong nCount = aEntries.Count(); 2981 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 2982 { 2983 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 2984 if( pEntry != pThisEntryNot && pEntry->IsSelected() ) 2985 SelectEntry( pEntry, sal_False, sal_True, sal_True, bPaintSync ); 2986 } 2987 pAnchor = 0; 2988 nFlags &= (~F_ADD_MODE); 2989 } 2990 2991 Size SvxIconChoiceCtrl_Impl::GetMinGrid() const 2992 { 2993 Size aMinSize( aImageSize ); 2994 aMinSize.Width() += 2 * LROFFS_BOUND; 2995 aMinSize.Height() += TBOFFS_BOUND; // PB: einmal Offset reicht (FileDlg) 2996 String aStrDummy( RTL_CONSTASCII_USTRINGPARAM( "XXX" ) ); 2997 Size aTextSize( pView->GetTextWidth( aStrDummy ), pView->GetTextHeight() ); 2998 if( nWinBits & WB_ICON ) 2999 { 3000 aMinSize.Height() += VER_DIST_BMP_STRING; 3001 aMinSize.Height() += aTextSize.Height(); 3002 } 3003 else 3004 { 3005 aMinSize.Width() += HOR_DIST_BMP_STRING; 3006 aMinSize.Width() += aTextSize.Width(); 3007 } 3008 return aMinSize; 3009 } 3010 3011 void SvxIconChoiceCtrl_Impl::SetGrid( const Size& rSize ) 3012 { 3013 Size aSize( rSize ); 3014 Size aMinSize( GetMinGrid() ); 3015 if( aSize.Width() < aMinSize.Width() ) 3016 aSize.Width() = aMinSize.Width(); 3017 if( aSize.Height() < aMinSize.Height() ) 3018 aSize.Height() = aMinSize.Height(); 3019 3020 nGridDX = aSize.Width(); 3021 // HACK(Detail-Modus ist noch nicht vollstaendig implementiert!) 3022 // dieses Workaround bringts mit einer Spalte zum Fliegen 3023 if( nWinBits & WB_DETAILS ) 3024 { 3025 const SvxIconChoiceCtrlColumnInfo* pCol = GetColumn( 0 ); 3026 if( pCol ) 3027 ((SvxIconChoiceCtrlColumnInfo*)pCol)->SetWidth( nGridDX ); 3028 } 3029 nGridDY = aSize.Height(); 3030 SetDefaultTextSize(); 3031 } 3032 3033 // berechnet die maximale Groesse, die das Textrechteck innerhalb des 3034 // umschliessenden Rechtecks einnehmen kann. Im Modus WB_ICON und 3035 // IcnShowTextFull wird Bottom auf LONG_MAX gesetzt 3036 3037 Rectangle SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtrlEntry* pEntry ) const 3038 { 3039 Rectangle aBoundRect; 3040 // keine Endlosrekursion! deshalb das Bound-Rect hier nicht berechnen 3041 if( IsBoundingRectValid( pEntry->aRect ) ) 3042 aBoundRect = pEntry->aRect; 3043 else 3044 aBoundRect = pEntry->aGridRect; 3045 3046 Rectangle aBmpRect( ((SvxIconChoiceCtrl_Impl*)this)->CalcBmpRect( 3047 (SvxIconChoiceCtrlEntry*)pEntry ) ); 3048 if( nWinBits & WB_ICON ) 3049 { 3050 aBoundRect.Top() = aBmpRect.Bottom(); 3051 aBoundRect.Top() += VER_DIST_BMP_STRING; 3052 if( aBoundRect.Top() > aBoundRect.Bottom()) 3053 aBoundRect.Top() = aBoundRect.Bottom(); 3054 aBoundRect.Left() += LROFFS_BOUND; 3055 aBoundRect.Left()++; 3056 aBoundRect.Right() -= LROFFS_BOUND; 3057 aBoundRect.Right()--; 3058 if( aBoundRect.Left() > aBoundRect.Right()) 3059 aBoundRect.Left() = aBoundRect.Right(); 3060 if( GetEntryTextModeSmart( pEntry ) == IcnShowTextFull ) 3061 aBoundRect.Bottom() = LONG_MAX; 3062 } 3063 else 3064 { 3065 aBoundRect.Left() = aBmpRect.Right(); 3066 aBoundRect.Left() += HOR_DIST_BMP_STRING; 3067 aBoundRect.Right() -= LROFFS_BOUND; 3068 if( aBoundRect.Left() > aBoundRect.Right() ) 3069 aBoundRect.Left() = aBoundRect.Right(); 3070 long nHeight = aBoundRect.GetSize().Height(); 3071 nHeight = nHeight - aDefaultTextSize.Height(); 3072 nHeight /= 2; 3073 aBoundRect.Top() += nHeight; 3074 aBoundRect.Bottom() -= nHeight; 3075 } 3076 return aBoundRect; 3077 } 3078 3079 void SvxIconChoiceCtrl_Impl::SetDefaultTextSize() 3080 { 3081 long nDY = nGridDY; 3082 nDY -= aImageSize.Height(); 3083 nDY -= VER_DIST_BMP_STRING; 3084 nDY -= 2*TBOFFS_BOUND; 3085 if( nDY <= 0 ) 3086 nDY = 2; 3087 3088 long nDX = nGridDX; 3089 nDX -= 2*LROFFS_BOUND; 3090 nDX -= 2; 3091 if( nDX <= 0 ) 3092 nDX = 2; 3093 3094 String aStrDummy( RTL_CONSTASCII_USTRINGPARAM( "X" ) ); 3095 long nHeight = pView->GetTextHeight(); 3096 if( nDY < nHeight ) 3097 nDY = nHeight; 3098 aDefaultTextSize = Size( nDX, nDY ); 3099 } 3100 3101 3102 void SvxIconChoiceCtrl_Impl::Center( SvxIconChoiceCtrlEntry* pEntry ) const 3103 { 3104 pEntry->aRect = pEntry->aGridRect; 3105 Size aSize( CalcBoundingSize( pEntry ) ); 3106 if( nWinBits & WB_ICON ) 3107 { 3108 // horizontal zentrieren 3109 long nBorder = pEntry->aGridRect.GetWidth() - aSize.Width(); 3110 pEntry->aRect.Left() += nBorder / 2; 3111 pEntry->aRect.Right() -= nBorder / 2; 3112 } 3113 // vertikal zentrieren 3114 pEntry->aRect.Bottom() = pEntry->aRect.Top() + aSize.Height(); 3115 } 3116 3117 3118 // Die Deltas entsprechen Offsets, um die die View auf dem Doc verschoben wird 3119 // links, hoch: Offsets < 0 3120 // rechts, runter: Offsets > 0 3121 void SvxIconChoiceCtrl_Impl::Scroll( long nDeltaX, long nDeltaY, sal_Bool bScrollBar ) 3122 { 3123 const MapMode& rMapMode = pView->GetMapMode(); 3124 Point aOrigin( rMapMode.GetOrigin() ); 3125 // in Dokumentkoordinate umwandeln 3126 aOrigin *= -1; 3127 aOrigin.Y() += nDeltaY; 3128 aOrigin.X() += nDeltaX; 3129 Rectangle aRect( aOrigin, aOutputSize ); 3130 MakeVisible( aRect, bScrollBar ); 3131 } 3132 3133 3134 const Size& SvxIconChoiceCtrl_Impl::GetItemSize( SvxIconChoiceCtrlEntry*, 3135 IcnViewFieldType eItem ) const 3136 { 3137 if( eItem == IcnViewFieldTypeText ) 3138 return aDefaultTextSize; 3139 return aImageSize; 3140 } 3141 3142 Rectangle SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry* pEntry ) 3143 { 3144 Rectangle aBmpRect( CalcBmpRect( pEntry ) ); 3145 Rectangle aTextRect( CalcTextRect( pEntry ) ); 3146 Rectangle aBoundRect( GetEntryBoundRect( pEntry ) ); 3147 Rectangle aFocusRect( aBoundRect.Left(), aBmpRect.Top() - 1, 3148 aBoundRect.Right() - 4, aTextRect.Bottom() + 1 ); 3149 // Das Fokusrechteck soll nicht den Text beruehren 3150 if( aFocusRect.Left() - 1 >= pEntry->aRect.Left() ) 3151 aFocusRect.Left()--; 3152 if( aFocusRect.Right() + 1 <= pEntry->aRect.Right() ) 3153 aFocusRect.Right()++; 3154 3155 return aFocusRect; 3156 } 3157 3158 // Der 'Hot Spot' sind die inneren 50% der Rechteckflaeche 3159 static Rectangle GetHotSpot( const Rectangle& rRect ) 3160 { 3161 Rectangle aResult( rRect ); 3162 aResult.Justify(); 3163 Size aSize( rRect.GetSize() ); 3164 long nDelta = aSize.Width() / 4; 3165 aResult.Left() += nDelta; 3166 aResult.Right() -= nDelta; 3167 nDelta = aSize.Height() / 4; 3168 aResult.Top() += nDelta; 3169 aResult.Bottom() -= nDelta; 3170 return aResult; 3171 } 3172 3173 void SvxIconChoiceCtrl_Impl::SelectRect( SvxIconChoiceCtrlEntry* pEntry1, SvxIconChoiceCtrlEntry* pEntry2, 3174 sal_Bool bAdd, SvPtrarr* pOtherRects ) 3175 { 3176 DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr"); 3177 Rectangle aRect( GetEntryBoundRect( pEntry1 ) ); 3178 aRect.Union( GetEntryBoundRect( pEntry2 ) ); 3179 SelectRect( aRect, bAdd, pOtherRects ); 3180 } 3181 3182 void SvxIconChoiceCtrl_Impl::SelectRect( const Rectangle& rRect, sal_Bool bAdd, 3183 SvPtrarr* pOtherRects ) 3184 { 3185 aCurSelectionRect = rRect; 3186 if( !pZOrderList || !pZOrderList->Count() ) 3187 return; 3188 3189 // Flag setzen, damit im Select kein ToTop gerufen wird 3190 sal_Bool bAlreadySelectingRect = nFlags & F_SELECTING_RECT ? sal_True : sal_False; 3191 nFlags |= F_SELECTING_RECT; 3192 3193 CheckBoundingRects(); 3194 pView->Update(); 3195 const sal_uLong nCount = pZOrderList->Count(); 3196 3197 Rectangle aRect( rRect ); 3198 aRect.Justify(); 3199 sal_Bool bCalcOverlap = (bAdd && pOtherRects && pOtherRects->Count()) ? sal_True : sal_False; 3200 3201 sal_Bool bResetClipRegion = sal_False; 3202 if( !pView->IsClipRegion() ) 3203 { 3204 bResetClipRegion = sal_True; 3205 pView->SetClipRegion( GetOutputRect() ); 3206 } 3207 3208 for( sal_uLong nPos = 0; nPos < nCount; nPos++ ) 3209 { 3210 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)(pZOrderList->GetObject(nPos )); 3211 3212 if( !IsBoundingRectValid( pEntry->aRect )) 3213 FindBoundingRect( pEntry ); 3214 Rectangle aBoundRect( GetHotSpot( pEntry->aRect ) ); 3215 sal_Bool bSelected = pEntry->IsSelected(); 3216 3217 sal_Bool bOverlaps; 3218 if( bCalcOverlap ) 3219 bOverlaps = IsOver( pOtherRects, aBoundRect ); 3220 else 3221 bOverlaps = sal_False; 3222 sal_Bool bOver = aRect.IsOver( aBoundRect ); 3223 3224 if( bOver && !bOverlaps ) 3225 { 3226 // Ist im neuen Selektionsrechteck und in keinem alten 3227 // => selektieren 3228 if( !bSelected ) 3229 SelectEntry( pEntry, sal_True, sal_True, sal_True ); 3230 } 3231 else if( !bAdd ) 3232 { 3233 // ist ausserhalb des Selektionsrechtecks 3234 // => Selektion entfernen 3235 if( bSelected ) 3236 SelectEntry( pEntry, sal_False, sal_True, sal_True ); 3237 } 3238 else if( bAdd && bOverlaps ) 3239 { 3240 // Der Eintrag befindet sich in einem alten (=>Aufspannen 3241 // mehrerer Rechtecke mit Ctrl!) Selektionsrechteck 3242 3243 // Hier ist noch ein Bug! Der Selektionsstatus eines Eintrags 3244 // in einem vorherigen Rechteck, muss restauriert werden, wenn 3245 // er vom aktuellen Selektionsrechteck beruehrt wurde, jetzt aber 3246 // nicht mehr in ihm liegt. Ich gehe hier der Einfachheit halber 3247 // pauschal davon aus, dass die Eintraege in den alten Rechtecken 3248 // alle selektiert sind. Ebenso ist es falsch, die Schnittmenge 3249 // nur zu deselektieren. 3250 // Loesungsmoeglichkeit: Snapshot der Selektion vor dem Auf- 3251 // spannen des Rechtecks merken 3252 if( aBoundRect.IsOver( rRect)) 3253 { 3254 // Schnittmenge zwischen alten Rects & aktuellem Rect desel. 3255 if( bSelected ) 3256 SelectEntry( pEntry, sal_False, sal_True, sal_True ); 3257 } 3258 else 3259 { 3260 // Eintrag eines alten Rects selektieren 3261 if( !bSelected ) 3262 SelectEntry( pEntry, sal_True, sal_True, sal_True ); 3263 } 3264 } 3265 else if( !bOver && bSelected ) 3266 { 3267 // Der Eintrag liegt voellig ausserhalb und wird deshalb desel. 3268 SelectEntry( pEntry, sal_False, sal_True, sal_True ); 3269 } 3270 } 3271 3272 if( !bAlreadySelectingRect ) 3273 nFlags &= ~F_SELECTING_RECT; 3274 3275 pView->Update(); 3276 if( bResetClipRegion ) 3277 pView->SetClipRegion(); 3278 } 3279 3280 void SvxIconChoiceCtrl_Impl::SelectRange( 3281 SvxIconChoiceCtrlEntry* pStart, 3282 SvxIconChoiceCtrlEntry* pEnd, 3283 sal_Bool bAdd ) 3284 { 3285 sal_uLong nFront = GetEntryListPos( pStart ); 3286 sal_uLong nBack = GetEntryListPos( pEnd ); 3287 sal_uLong nFirst = std::min( nFront, nBack ); 3288 sal_uLong nLast = std::max( nFront, nBack ); 3289 sal_uLong i; 3290 SvxIconChoiceCtrlEntry* pEntry; 3291 3292 if ( ! bAdd ) 3293 { 3294 // deselect everything before the first entry if not in 3295 // adding mode 3296 for ( i=0; i<nFirst; i++ ) 3297 { 3298 pEntry = GetEntry( i ); 3299 if( pEntry->IsSelected() ) 3300 SelectEntry( pEntry, sal_False, sal_True, sal_True, sal_True ); 3301 } 3302 } 3303 3304 // select everything between nFirst and nLast 3305 for ( i=nFirst; i<=nLast; i++ ) 3306 { 3307 pEntry = GetEntry( i ); 3308 if( ! pEntry->IsSelected() ) 3309 SelectEntry( pEntry, sal_True, sal_True, sal_True, sal_True ); 3310 } 3311 3312 if ( ! bAdd ) 3313 { 3314 // deselect everything behind the last entry if not in 3315 // adding mode 3316 sal_uLong nEnd = GetEntryCount(); 3317 for ( ; i<nEnd; i++ ) 3318 { 3319 pEntry = GetEntry( i ); 3320 if( pEntry->IsSelected() ) 3321 SelectEntry( pEntry, sal_False, sal_True, sal_True, sal_True ); 3322 } 3323 } 3324 } 3325 3326 sal_Bool SvxIconChoiceCtrl_Impl::IsOver( SvPtrarr* pRectList, const Rectangle& rBoundRect ) const 3327 { 3328 const sal_uInt16 nCount = pRectList->Count(); 3329 for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ ) 3330 { 3331 Rectangle* pRect = (Rectangle*)pRectList->GetObject( nCur ); 3332 if( rBoundRect.IsOver( *pRect )) 3333 return sal_True; 3334 } 3335 return sal_False; 3336 } 3337 3338 void SvxIconChoiceCtrl_Impl::AddSelectedRect( SvxIconChoiceCtrlEntry* pEntry1, 3339 SvxIconChoiceCtrlEntry* pEntry2 ) 3340 { 3341 DBG_ASSERT(pEntry1 && pEntry2,"SelectEntry: Invalid Entry-Ptr"); 3342 Rectangle aRect( GetEntryBoundRect( pEntry1 ) ); 3343 aRect.Union( GetEntryBoundRect( pEntry2 ) ); 3344 AddSelectedRect( aRect ); 3345 } 3346 3347 void SvxIconChoiceCtrl_Impl::AddSelectedRect( const Rectangle& rRect ) 3348 { 3349 Rectangle* pRect = new Rectangle( rRect ); 3350 pRect->Justify(); 3351 aSelectedRectList.Insert( (void*)pRect, aSelectedRectList.Count() ); 3352 } 3353 3354 void SvxIconChoiceCtrl_Impl::ClearSelectedRectList() 3355 { 3356 const sal_uInt16 nCount = aSelectedRectList.Count(); 3357 for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ ) 3358 { 3359 Rectangle* pRect = (Rectangle*)aSelectedRectList.GetObject( nCur ); 3360 delete pRect; 3361 } 3362 aSelectedRectList.Remove( 0, aSelectedRectList.Count() ); 3363 } 3364 3365 void SvxIconChoiceCtrl_Impl::CalcScrollOffsets( const Point& rPosPixel, 3366 long& rX, long& rY, sal_Bool isInDragDrop, sal_uInt16 nBorderWidth) 3367 { 3368 // Scrolling der View, falls sich der Mauszeiger im Grenzbereich des 3369 // Fensters befindet 3370 long nPixelToScrollX = 0; 3371 long nPixelToScrollY = 0; 3372 Size aWndSize = aOutputSize; 3373 3374 nBorderWidth = (sal_uInt16)(Min( (long)(aWndSize.Height()-1), (long)nBorderWidth )); 3375 nBorderWidth = (sal_uInt16)(Min( (long)(aWndSize.Width()-1), (long)nBorderWidth )); 3376 3377 if ( rPosPixel.X() < nBorderWidth ) 3378 { 3379 if( isInDragDrop ) 3380 nPixelToScrollX = -DD_SCROLL_PIXEL; 3381 else 3382 nPixelToScrollX = rPosPixel.X()- nBorderWidth; 3383 } 3384 else if ( rPosPixel.X() > aWndSize.Width() - nBorderWidth ) 3385 { 3386 if( isInDragDrop ) 3387 nPixelToScrollX = DD_SCROLL_PIXEL; 3388 else 3389 nPixelToScrollX = rPosPixel.X() - (aWndSize.Width() - nBorderWidth); 3390 } 3391 if ( rPosPixel.Y() < nBorderWidth ) 3392 { 3393 if( isInDragDrop ) 3394 nPixelToScrollY = -DD_SCROLL_PIXEL; 3395 else 3396 nPixelToScrollY = rPosPixel.Y() - nBorderWidth; 3397 } 3398 else if ( rPosPixel.Y() > aWndSize.Height() - nBorderWidth ) 3399 { 3400 if( isInDragDrop ) 3401 nPixelToScrollY = DD_SCROLL_PIXEL; 3402 else 3403 nPixelToScrollY = rPosPixel.Y() - (aWndSize.Height() - nBorderWidth); 3404 } 3405 3406 rX = nPixelToScrollX; 3407 rY = nPixelToScrollY; 3408 } 3409 3410 IMPL_LINK(SvxIconChoiceCtrl_Impl, AutoArrangeHdl, void*, EMPTYARG ) 3411 { 3412 aAutoArrangeTimer.Stop(); 3413 Arrange( IsAutoArrange() ); 3414 return 0; 3415 } 3416 3417 IMPL_LINK(SvxIconChoiceCtrl_Impl, VisRectChangedHdl, void*, EMPTYARG ) 3418 { 3419 aVisRectChangedTimer.Stop(); 3420 pView->VisibleRectChanged(); 3421 return 0; 3422 } 3423 3424 IMPL_LINK(SvxIconChoiceCtrl_Impl, DocRectChangedHdl, void*, EMPTYARG ) 3425 { 3426 aDocRectChangedTimer.Stop(); 3427 pView->DocumentRectChanged(); 3428 return 0; 3429 } 3430 3431 void SvxIconChoiceCtrl_Impl::PrepareCommandEvent( const CommandEvent& rCEvt ) 3432 { 3433 StopEditTimer(); 3434 SvxIconChoiceCtrlEntry* pEntry = pView->GetEntry( rCEvt.GetMousePosPixel() ); 3435 if( (nFlags & F_DOWN_CTRL) && pEntry && !pEntry->IsSelected() ) 3436 SelectEntry( pEntry, sal_True, sal_True ); 3437 nFlags &= ~(F_DOWN_CTRL | F_DOWN_DESELECT); 3438 } 3439 3440 sal_Bool SvxIconChoiceCtrl_Impl::IsTextHit( SvxIconChoiceCtrlEntry* pEntry, const Point& rDocPos ) 3441 { 3442 Rectangle aRect( CalcTextRect( pEntry )); 3443 if( aRect.IsInside( rDocPos ) ) 3444 return sal_True; 3445 return sal_False; 3446 } 3447 3448 IMPL_LINK(SvxIconChoiceCtrl_Impl, EditTimeoutHdl, Timer*, EMPTYARG ) 3449 { 3450 SvxIconChoiceCtrlEntry* pEntry = GetCurEntry(); 3451 if( bEntryEditingEnabled && pEntry && 3452 pEntry->IsSelected()) 3453 { 3454 if( pView->EditingEntry( pEntry )) 3455 EditEntry( pEntry ); 3456 } 3457 return 0; 3458 } 3459 3460 3461 // 3462 // Funktionen zum Ausrichten der Eintraege am Grid 3463 // 3464 3465 // pStart == 0: Alle Eintraege werden ausgerichtet 3466 // sonst: Alle Eintraege der Zeile ab einschliesslich pStart werden ausgerichtet 3467 void SvxIconChoiceCtrl_Impl::AdjustEntryAtGrid( SvxIconChoiceCtrlEntry* pStart ) 3468 { 3469 SvPtrarr aLists; 3470 pImpCursor->CreateGridAjustData( aLists, pStart ); 3471 const sal_uInt16 nCount = aLists.Count(); 3472 for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ ) 3473 AdjustAtGrid( *(SvPtrarr*)aLists[ nCur ], pStart ); 3474 IcnCursor_Impl::DestroyGridAdjustData( aLists ); 3475 CheckScrollBars(); 3476 } 3477 3478 // Richtet eine Zeile aus, erweitert ggf. die Breite; Bricht die Zeile nicht um 3479 void SvxIconChoiceCtrl_Impl::AdjustAtGrid( const SvPtrarr& rRow, SvxIconChoiceCtrlEntry* pStart ) 3480 { 3481 if( !rRow.Count() ) 3482 return; 3483 3484 sal_Bool bGo; 3485 if( !pStart ) 3486 bGo = sal_True; 3487 else 3488 bGo = sal_False; 3489 3490 long nCurRight = 0; 3491 for( sal_uInt16 nCur = 0; nCur < rRow.Count(); nCur++ ) 3492 { 3493 SvxIconChoiceCtrlEntry* pCur = (SvxIconChoiceCtrlEntry*)rRow[ nCur ]; 3494 if( !bGo && pCur == pStart ) 3495 bGo = sal_True; 3496 3497 //SvIcnVwDataEntry* pViewData = ICNVIEWDATA(pCur); 3498 // Massgebend (fuer unser Auge) ist die Bitmap, da sonst 3499 // durch lange Texte der Eintrag stark springen kann 3500 const Rectangle& rBoundRect = GetEntryBoundRect( pCur ); 3501 Rectangle aCenterRect( CalcBmpRect( pCur, 0 )); 3502 if( bGo && !pCur->IsPosLocked() ) 3503 { 3504 long nWidth = aCenterRect.GetSize().Width(); 3505 Point aNewPos( AdjustAtGrid( aCenterRect, rBoundRect ) ); 3506 while( aNewPos.X() < nCurRight ) 3507 aNewPos.X() += nGridDX; 3508 if( aNewPos != rBoundRect.TopLeft() ) 3509 { 3510 SetEntryPos( pCur, aNewPos ); 3511 pCur->SetFlags( ICNVIEW_FLAG_POS_MOVED ); 3512 nFlags |= F_MOVED_ENTRIES; 3513 } 3514 nCurRight = aNewPos.X() + nWidth; 3515 } 3516 else 3517 { 3518 nCurRight = rBoundRect.Right(); 3519 } 3520 } 3521 } 3522 3523 // Richtet Rect am Grid aus, garantiert jedoch nicht, dass die 3524 // neue Pos. frei ist. Die Pos. kann fuer SetEntryPos verwendet werden. 3525 // Das CenterRect beschreibt den Teil des BoundRects, der fuer 3526 // die Berechnung des Ziel-Rechtecks verwendet wird. 3527 Point SvxIconChoiceCtrl_Impl::AdjustAtGrid( const Rectangle& rCenterRect, 3528 const Rectangle& rBoundRect ) const 3529 { 3530 Point aPos( rCenterRect.TopLeft() ); 3531 Size aSize( rCenterRect.GetSize() ); 3532 3533 aPos.X() -= LROFFS_WINBORDER; 3534 aPos.Y() -= TBOFFS_WINBORDER; 3535 3536 // align (ref ist mitte des rects) 3537 short nGridX = (short)((aPos.X()+(aSize.Width()/2)) / nGridDX); 3538 short nGridY = (short)((aPos.Y()+(aSize.Height()/2)) / nGridDY); 3539 aPos.X() = nGridX * nGridDX; 3540 aPos.Y() = nGridY * nGridDY; 3541 // hor. center 3542 aPos.X() += (nGridDX - rBoundRect.GetSize().Width() ) / 2; 3543 3544 aPos.X() += LROFFS_WINBORDER; 3545 aPos.Y() += TBOFFS_WINBORDER; 3546 3547 return aPos; 3548 } 3549 3550 void SvxIconChoiceCtrl_Impl::SetEntryTextMode( SvxIconChoiceCtrlTextMode eMode, SvxIconChoiceCtrlEntry* pEntry ) 3551 { 3552 if( !pEntry ) 3553 { 3554 if( eTextMode != eMode ) 3555 { 3556 if( eTextMode == IcnShowTextDontKnow ) 3557 eTextMode = IcnShowTextShort; 3558 eTextMode = eMode; 3559 Arrange( sal_True ); 3560 } 3561 } 3562 else 3563 { 3564 if( pEntry->eTextMode != eMode ) 3565 { 3566 pEntry->eTextMode = eMode; 3567 InvalidateEntry( pEntry ); 3568 pView->Invalidate( GetEntryBoundRect( pEntry ) ); 3569 AdjustVirtSize( pEntry->aRect ); 3570 } 3571 } 3572 } 3573 3574 SvxIconChoiceCtrlTextMode SvxIconChoiceCtrl_Impl::GetTextMode( const SvxIconChoiceCtrlEntry* pEntry ) const 3575 { 3576 if( !pEntry ) 3577 return eTextMode; 3578 return pEntry->GetTextMode(); 3579 } 3580 3581 SvxIconChoiceCtrlTextMode SvxIconChoiceCtrl_Impl::GetEntryTextModeSmart( const SvxIconChoiceCtrlEntry* pEntry ) const 3582 { 3583 DBG_ASSERT(pEntry,"GetEntryTextModeSmart: Entry not set"); 3584 SvxIconChoiceCtrlTextMode eMode = pEntry->GetTextMode(); 3585 if( eMode == IcnShowTextDontKnow ) 3586 return eTextMode; 3587 return eMode; 3588 } 3589 3590 void SvxIconChoiceCtrl_Impl::ShowEntryFocusRect( const SvxIconChoiceCtrlEntry* pEntry ) 3591 { 3592 if( !pEntry ) 3593 { 3594 pView->HideFocus(); 3595 } 3596 else 3597 { 3598 Rectangle aRect ( CalcFocusRect( (SvxIconChoiceCtrlEntry*)pEntry ) ); 3599 /*pView->*/ShowFocus( aRect ); 3600 } 3601 } 3602 3603 //////////////////////////////////////////////////////////////////////////////////////////////// 3604 // 3605 // Draw my own focusrect, because the focusrect of the outputdevice has got the inverted color 3606 // of the background. But what will we see, if the the backgroundcolor is gray ? - We will see 3607 // a gray focusrect on a gray background !!! 3608 // 3609 void SvxIconChoiceCtrl_Impl::ShowFocus ( Rectangle& rRect ) 3610 { 3611 Color aBkgColor ( pView->GetBackground().GetColor() ); 3612 Color aPenColor; 3613 sal_uInt16 nColor = ( aBkgColor.GetRed() + aBkgColor.GetGreen() + aBkgColor.GetBlue() ) / 3; 3614 if ( nColor > 128 ) 3615 aPenColor.SetColor ( COL_BLACK ); 3616 else 3617 aPenColor.SetColor( COL_WHITE ); 3618 3619 aFocus.bOn = sal_True; 3620 aFocus.aPenColor = aPenColor; 3621 aFocus.aRect = rRect; 3622 } 3623 3624 void SvxIconChoiceCtrl_Impl::HideFocus () 3625 { 3626 aFocus.bOn = sal_False; 3627 } 3628 3629 void SvxIconChoiceCtrl_Impl::DrawFocusRect ( OutputDevice* pOut ) 3630 { 3631 pOut->SetLineColor( aFocus.aPenColor ); 3632 pOut->SetFillColor(); 3633 Polygon aPolygon ( aFocus.aRect ); 3634 3635 LineInfo aLineInfo ( LINE_DASH ); 3636 3637 aLineInfo.SetDashLen ( 1 ); 3638 3639 aLineInfo.SetDotLen ( 1L ); 3640 aLineInfo.SetDistance ( 1L ); 3641 aLineInfo.SetDotCount ( 1 ); 3642 3643 pOut->DrawPolyLine ( aPolygon, aLineInfo ); 3644 } 3645 3646 sal_Bool SvxIconChoiceCtrl_Impl::IsMnemonicChar( sal_Unicode cChar, sal_uLong& rPos ) const 3647 { 3648 sal_Bool bRet = sal_False; 3649 const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); 3650 sal_uLong nEntryCount = GetEntryCount(); 3651 for ( sal_uLong i = 0; i < nEntryCount; ++i ) 3652 { 3653 if ( rI18nHelper.MatchMnemonic( GetEntry( i )->GetText(), cChar ) ) 3654 { 3655 bRet = sal_True; 3656 rPos = i; 3657 break; 3658 } 3659 } 3660 3661 return bRet; 3662 } 3663 3664 // 3665 //////////////////////////////////////////////////////////////////////////////////////////////// 3666 3667 IMPL_LINK(SvxIconChoiceCtrl_Impl, UserEventHdl, void*, nId ) 3668 { 3669 if( nId == EVENTID_ADJUST_SCROLLBARS ) 3670 { 3671 nUserEventAdjustScrBars = 0; 3672 AdjustScrollBars(); 3673 } 3674 else if( nId == EVENTID_SHOW_CURSOR ) 3675 { 3676 nUserEventShowCursor = 0; 3677 ShowCursor( sal_True ); 3678 } 3679 return 0; 3680 } 3681 3682 void SvxIconChoiceCtrl_Impl::CancelUserEvents() 3683 { 3684 if( nUserEventAdjustScrBars ) 3685 { 3686 Application::RemoveUserEvent( nUserEventAdjustScrBars ); 3687 nUserEventAdjustScrBars = 0; 3688 } 3689 if( nUserEventShowCursor ) 3690 { 3691 Application::RemoveUserEvent( nUserEventShowCursor ); 3692 nUserEventShowCursor = 0; 3693 } 3694 } 3695 3696 void SvxIconChoiceCtrl_Impl::InvalidateEntry( SvxIconChoiceCtrlEntry* pEntry ) 3697 { 3698 if( pEntry == pCursor ) 3699 ShowCursor( sal_False ); 3700 pView->Invalidate( pEntry->aRect ); 3701 Center( pEntry ); 3702 pView->Invalidate( pEntry->aRect ); 3703 if( pEntry == pCursor ) 3704 ShowCursor( sal_True ); 3705 } 3706 3707 void SvxIconChoiceCtrl_Impl::EditEntry( SvxIconChoiceCtrlEntry* pEntry ) 3708 { 3709 DBG_ASSERT(pEntry,"EditEntry: Entry not set"); 3710 if( !pEntry ) 3711 return; 3712 3713 StopEntryEditing( sal_True ); 3714 DELETEZ(pEdit); 3715 SetNoSelection(); 3716 3717 pCurEditedEntry = pEntry; 3718 String aEntryText( pView->GetEntryText( pEntry, sal_True ) ); 3719 Rectangle aRect( CalcTextRect( pEntry, 0, sal_True, &aEntryText ) ); 3720 MakeVisible( aRect ); 3721 Point aPos( aRect.TopLeft() ); 3722 aPos = pView->GetPixelPos( aPos ); 3723 aRect.SetPos( aPos ); 3724 pView->HideFocus(); 3725 pEdit = new IcnViewEdit_Impl( 3726 pView, 3727 aRect.TopLeft(), 3728 aRect.GetSize(), 3729 aEntryText, 3730 LINK( this, SvxIconChoiceCtrl_Impl, TextEditEndedHdl ) ); 3731 } 3732 3733 IMPL_LINK( SvxIconChoiceCtrl_Impl, TextEditEndedHdl, IcnViewEdit_Impl*, EMPTYARG ) 3734 { 3735 DBG_ASSERT(pEdit,"TextEditEnded: pEdit not set"); 3736 if( !pEdit ) 3737 { 3738 pCurEditedEntry = 0; 3739 return 0; 3740 } 3741 DBG_ASSERT(pCurEditedEntry,"TextEditEnded: pCurEditedEntry not set"); 3742 3743 if( !pCurEditedEntry ) 3744 { 3745 pEdit->Hide(); 3746 if( pEdit->IsGrabFocus() ) 3747 pView->GrabFocus(); 3748 return 0; 3749 } 3750 3751 String aText; 3752 if ( !pEdit->EditingCanceled() ) 3753 aText = pEdit->GetText(); 3754 else 3755 aText = pEdit->GetSavedValue(); 3756 3757 if( pView->EditedEntry( pCurEditedEntry, aText, pEdit->EditingCanceled() ) ) 3758 InvalidateEntry( pCurEditedEntry ); 3759 if( !GetSelectionCount() ) 3760 SelectEntry( pCurEditedEntry, sal_True ); 3761 3762 pEdit->Hide(); 3763 if( pEdit->IsGrabFocus() ) 3764 pView->GrabFocus(); 3765 // Das Edit kann nicht hier geloescht werden, weil es noch in einem 3766 // Handler steht. Es wird im Dtor oder im naechsten EditEntry geloescht. 3767 pCurEditedEntry = 0; 3768 return 0; 3769 } 3770 3771 void SvxIconChoiceCtrl_Impl::StopEntryEditing( sal_Bool bCancel ) 3772 { 3773 if( pEdit ) 3774 pEdit->StopEditing( bCancel ); 3775 } 3776 3777 void SvxIconChoiceCtrl_Impl::LockEntryPos( SvxIconChoiceCtrlEntry* pEntry, sal_Bool bLock ) 3778 { 3779 if( bLock ) 3780 pEntry->SetFlags( ICNVIEW_FLAG_POS_LOCKED ); 3781 else 3782 pEntry->ClearFlags( ICNVIEW_FLAG_POS_LOCKED ); 3783 } 3784 3785 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry( sal_uLong& rPos ) const 3786 { 3787 if( !GetSelectionCount() ) 3788 return 0; 3789 3790 if( (nWinBits & WB_HIGHLIGHTFRAME) && (eSelectionMode == NO_SELECTION) ) 3791 { 3792 rPos = pView->GetEntryListPos( pCurHighlightFrame ); 3793 return pCurHighlightFrame; 3794 } 3795 3796 sal_uLong nCount = aEntries.Count(); 3797 if( !pHead ) 3798 { 3799 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 3800 { 3801 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 3802 if( pEntry->IsSelected() ) 3803 { 3804 rPos = nCur; 3805 return pEntry; 3806 } 3807 } 3808 } 3809 else 3810 { 3811 SvxIconChoiceCtrlEntry* pEntry = pHead; 3812 while( nCount-- ) 3813 { 3814 if( pEntry->IsSelected() ) 3815 { 3816 rPos = GetEntryListPos( pEntry ); 3817 return pEntry; 3818 } 3819 pEntry = pEntry->pflink; 3820 if( nCount && pEntry == pHead ) 3821 { 3822 DBG_ERROR("SvxIconChoiceCtrl_Impl::GetFirstSelectedEntry > Endlosschleife!"); 3823 return 0; 3824 } 3825 } 3826 } 3827 return 0; 3828 } 3829 3830 // kein Round Robin! 3831 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetNextSelectedEntry( sal_uLong& rStartPos ) const 3832 { 3833 sal_uLong nCount = aEntries.Count(); 3834 if( rStartPos > nCount || !GetSelectionCount() ) 3835 return 0; 3836 if( !pHead ) 3837 { 3838 for( sal_uLong nCur = rStartPos+1; nCur < nCount; nCur++ ) 3839 { 3840 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 3841 if( pEntry->IsSelected() ) 3842 { 3843 rStartPos = nCur; 3844 return pEntry; 3845 } 3846 } 3847 } 3848 else 3849 { 3850 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( rStartPos ); 3851 pEntry = pEntry->pflink; 3852 while( pEntry != pHead ) 3853 { 3854 if( pEntry->IsSelected() ) 3855 { 3856 rStartPos = GetEntryListPos( pEntry ); 3857 return pEntry; 3858 } 3859 pEntry = pEntry->pflink; 3860 } 3861 } 3862 3863 rStartPos = 0xffffffff; 3864 return 0; 3865 } 3866 3867 void SvxIconChoiceCtrl_Impl::SelectAll( sal_Bool bSelect, sal_Bool bPaint ) 3868 { 3869 bPaint = sal_True; 3870 3871 sal_uLong nCount = aEntries.Count(); 3872 for( sal_uLong nCur = 0; nCur < nCount && (bSelect || GetSelectionCount() ); nCur++ ) 3873 { 3874 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 3875 SelectEntry( pEntry, bSelect, sal_True, sal_True, bPaint ); 3876 } 3877 nFlags &= (~F_ADD_MODE); 3878 pAnchor = 0; 3879 } 3880 3881 void SvxIconChoiceCtrl_Impl::SaveSelection( List** ppList ) 3882 { 3883 if( !*ppList ) 3884 *ppList = new List; 3885 sal_uLong nPos; 3886 SvxIconChoiceCtrlEntry* pEntry = GetFirstSelectedEntry( nPos ); 3887 while( pEntry && GetSelectionCount() != (*ppList)->Count() ) 3888 { 3889 (*ppList)->Insert( pEntry, LIST_APPEND ); 3890 pEntry = GetNextSelectedEntry( nPos ); 3891 } 3892 } 3893 3894 IcnViewEdit_Impl::IcnViewEdit_Impl( SvtIconChoiceCtrl* pParent, const Point& rPos, 3895 const Size& rSize, const XubString& rData, const Link& rNotifyEditEnd ) : 3896 MultiLineEdit( pParent, (pParent->GetStyle() & WB_ICON) ? WB_CENTER : WB_LEFT), 3897 aCallBackHdl( rNotifyEditEnd ), 3898 bCanceled( sal_False ), 3899 bAlreadyInCallback( sal_False ), 3900 bGrabFocus( sal_False ) 3901 { 3902 Font aFont( pParent->GetPointFont() ); 3903 aFont.SetTransparent( sal_False ); 3904 SetControlFont( aFont ); 3905 if( !pParent->HasFontFillColor() ) 3906 { 3907 Color aColor( pParent->GetBackground().GetColor() ); 3908 SetControlBackground( aColor ); 3909 } 3910 else 3911 SetControlBackground( aFont.GetFillColor() ); 3912 SetControlForeground( aFont.GetColor() ); 3913 SetPosPixel( rPos ); 3914 SetSizePixel( CalcAdjustedSize(rSize) ); 3915 SetText( rData ); 3916 SaveValue(); 3917 3918 aAccReturn.InsertItem( IMPICNVIEW_ACC_RETURN, KeyCode(KEY_RETURN) ); 3919 aAccEscape.InsertItem( IMPICNVIEW_ACC_ESCAPE, KeyCode(KEY_ESCAPE) ); 3920 3921 aAccReturn.SetActivateHdl( LINK( this, IcnViewEdit_Impl, ReturnHdl_Impl) ); 3922 aAccEscape.SetActivateHdl( LINK( this, IcnViewEdit_Impl, EscapeHdl_Impl) ); 3923 GetpApp()->InsertAccel( &aAccReturn);//, ACCEL_ALWAYS ); 3924 GetpApp()->InsertAccel( &aAccEscape);//, ACCEL_ALWAYS ); 3925 Show(); 3926 GrabFocus(); 3927 } 3928 3929 IcnViewEdit_Impl::~IcnViewEdit_Impl() 3930 { 3931 if( !bAlreadyInCallback ) 3932 { 3933 GetpApp()->RemoveAccel( &aAccReturn ); 3934 GetpApp()->RemoveAccel( &aAccEscape ); 3935 } 3936 } 3937 3938 void IcnViewEdit_Impl::CallCallBackHdl_Impl() 3939 { 3940 aTimer.Stop(); 3941 if ( !bAlreadyInCallback ) 3942 { 3943 bAlreadyInCallback = sal_True; 3944 GetpApp()->RemoveAccel( &aAccReturn ); 3945 GetpApp()->RemoveAccel( &aAccEscape ); 3946 Hide(); 3947 aCallBackHdl.Call( this ); 3948 } 3949 } 3950 3951 IMPL_LINK( IcnViewEdit_Impl, Timeout_Impl, Timer*, EMPTYARG ) 3952 { 3953 CallCallBackHdl_Impl(); 3954 return 0; 3955 } 3956 3957 IMPL_LINK( IcnViewEdit_Impl, ReturnHdl_Impl, Accelerator*, EMPTYARG ) 3958 { 3959 bCanceled = sal_False; 3960 bGrabFocus = sal_True; 3961 CallCallBackHdl_Impl(); 3962 return 1; 3963 } 3964 3965 IMPL_LINK( IcnViewEdit_Impl, EscapeHdl_Impl, Accelerator*, EMPTYARG ) 3966 { 3967 bCanceled = sal_True; 3968 bGrabFocus = sal_True; 3969 CallCallBackHdl_Impl(); 3970 return 1; 3971 } 3972 3973 void IcnViewEdit_Impl::KeyInput( const KeyEvent& rKEvt ) 3974 { 3975 KeyCode aCode = rKEvt.GetKeyCode(); 3976 sal_uInt16 nCode = aCode.GetCode(); 3977 3978 switch ( nCode ) 3979 { 3980 case KEY_ESCAPE: 3981 bCanceled = sal_True; 3982 bGrabFocus = sal_True; 3983 CallCallBackHdl_Impl(); 3984 break; 3985 3986 case KEY_RETURN: 3987 bCanceled = sal_False; 3988 bGrabFocus = sal_True; 3989 CallCallBackHdl_Impl(); 3990 break; 3991 3992 default: 3993 MultiLineEdit::KeyInput( rKEvt ); 3994 } 3995 } 3996 3997 long IcnViewEdit_Impl::PreNotify( NotifyEvent& rNEvt ) 3998 { 3999 if( rNEvt.GetType() == EVENT_LOSEFOCUS ) 4000 { 4001 if ( !bAlreadyInCallback && 4002 ((!Application::GetFocusWindow()) || !IsChild(Application::GetFocusWindow()))) 4003 { 4004 bCanceled = sal_False; 4005 aTimer.SetTimeout(10); 4006 aTimer.SetTimeoutHdl(LINK(this,IcnViewEdit_Impl,Timeout_Impl)); 4007 aTimer.Start(); 4008 } 4009 } 4010 return 0; 4011 } 4012 4013 void IcnViewEdit_Impl::StopEditing( sal_Bool bCancel ) 4014 { 4015 if ( !bAlreadyInCallback ) 4016 { 4017 bCanceled = bCancel; 4018 CallCallBackHdl_Impl(); 4019 } 4020 } 4021 4022 sal_uLong SvxIconChoiceCtrl_Impl::GetEntryListPos( SvxIconChoiceCtrlEntry* pEntry ) const 4023 { 4024 if( !(nFlags & F_ENTRYLISTPOS_VALID )) 4025 ((SvxIconChoiceCtrl_Impl*)this)->SetListPositions(); 4026 return pEntry->nPos; 4027 } 4028 4029 void SvxIconChoiceCtrl_Impl::SetEntryListPos( SvxIconChoiceCtrlEntry* pListEntry, sal_uLong nNewPos ) 4030 { 4031 sal_uLong nCurPos = GetEntryListPos( pListEntry ); 4032 if( nCurPos == nNewPos ) 4033 return; 4034 aEntries.List::Remove( nCurPos ); 4035 aEntries.List::Insert( (void*)pListEntry, nNewPos ); 4036 // Eintragspositionen anpassen 4037 sal_uLong nStart, nEnd; 4038 if( nNewPos < nCurPos ) 4039 { 4040 nStart = nNewPos; 4041 nEnd = nCurPos; 4042 } 4043 else 4044 { 4045 nStart = nCurPos; 4046 nEnd = nNewPos; 4047 } 4048 for( ; nStart <= nEnd; nStart++ ) 4049 { 4050 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nStart ); 4051 pEntry->nPos = nStart; 4052 } 4053 } 4054 4055 void SvxIconChoiceCtrl_Impl::SetEntryFlags( SvxIconChoiceCtrlEntry* pEntry, sal_uInt16 nEntryFlags ) 4056 { 4057 pEntry->nFlags = nEntryFlags; 4058 if( nEntryFlags & ICNVIEW_FLAG_POS_MOVED ) 4059 nFlags |= F_MOVED_ENTRIES; 4060 } 4061 4062 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GoLeftRight( SvxIconChoiceCtrlEntry* pStart, sal_Bool bRight ) 4063 { 4064 return pImpCursor->GoLeftRight( pStart, bRight ); 4065 } 4066 4067 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GoUpDown( SvxIconChoiceCtrlEntry* pStart, sal_Bool bDown ) 4068 { 4069 return pImpCursor->GoUpDown( pStart, bDown ); 4070 } 4071 4072 void SvxIconChoiceCtrl_Impl::InitSettings() 4073 { 4074 const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings(); 4075 4076 if( !pView->HasFont() ) 4077 { 4078 // Unit aus den Settings ist Point 4079 Font aFont( rStyleSettings.GetFieldFont() ); 4080 //const Font& rFont = pView->GetFont(); 4081 //if( pView->HasFontTextColor() ) 4082 aFont.SetColor( rStyleSettings.GetWindowTextColor() ); 4083 //if( pView->HasFontFillColor() ) 4084 //aFont.SetFillColor( rFont.GetFillColor() ); 4085 pView->SetPointFont( aFont ); 4086 SetDefaultTextSize(); 4087 } 4088 4089 //if( !pView->HasFontTextColor() ) 4090 pView->SetTextColor( rStyleSettings.GetFieldTextColor() ); 4091 //if( !pView->HasFontFillColor() ) 4092 pView->SetTextFillColor(); 4093 4094 //if( !pView->HasBackground() ) 4095 pView->SetBackground( rStyleSettings.GetFieldColor()); 4096 4097 long nScrBarSize = rStyleSettings.GetScrollBarSize(); 4098 if( nScrBarSize != nHorSBarHeight || nScrBarSize != nVerSBarWidth ) 4099 { 4100 nHorSBarHeight = nScrBarSize; 4101 Size aSize( aHorSBar.GetSizePixel() ); 4102 aSize.Height() = nScrBarSize; 4103 aHorSBar.Hide(); 4104 aHorSBar.SetSizePixel( aSize ); 4105 4106 nVerSBarWidth = nScrBarSize; 4107 aSize = aVerSBar.GetSizePixel(); 4108 aSize.Width() = nScrBarSize; 4109 aVerSBar.Hide(); 4110 aVerSBar.SetSizePixel( aSize ); 4111 4112 Size aOSize( pView->Control::GetOutputSizePixel() ); 4113 PositionScrollBars( aOSize.Width(), aOSize.Height() ); 4114 AdjustScrollBars(); 4115 } 4116 } 4117 4118 EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl* pOwner, sal_uInt16 _nInitSize , sal_uInt16 _nReSize ) : 4119 List( _nInitSize, _nReSize ), 4120 _pOwner( pOwner ) 4121 { 4122 _pOwner->pHead = 0; 4123 } 4124 4125 EntryList_Impl::EntryList_Impl( SvxIconChoiceCtrl_Impl* pOwner, sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _nReSize ) : 4126 List( _nBlockSize, _nInitSize, _nReSize ), 4127 _pOwner( pOwner ) 4128 { 4129 _pOwner->pHead = 0; 4130 } 4131 4132 EntryList_Impl::~EntryList_Impl() 4133 { 4134 _pOwner->pHead = 0; 4135 } 4136 4137 void EntryList_Impl::Clear() 4138 { 4139 _pOwner->pHead = 0; 4140 List::Clear(); 4141 } 4142 4143 void EntryList_Impl::Insert( SvxIconChoiceCtrlEntry* pEntry, sal_uLong nPos ) 4144 { 4145 List::Insert( pEntry, nPos ); 4146 if( _pOwner->pHead ) 4147 pEntry->SetBacklink( _pOwner->pHead->pblink ); 4148 } 4149 4150 SvxIconChoiceCtrlEntry* EntryList_Impl::Remove( sal_uLong nPos ) 4151 { 4152 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)List::Remove( nPos ); 4153 DBG_ASSERT(pEntry,"EntryList_Impl::Remove > Entry not found"); 4154 Removed_Impl( pEntry ); 4155 return pEntry; 4156 } 4157 4158 void EntryList_Impl::Remove( SvxIconChoiceCtrlEntry* pEntry ) 4159 { 4160 List::Remove( (void*)pEntry ); 4161 Removed_Impl( pEntry ); 4162 } 4163 4164 void EntryList_Impl::Removed_Impl( SvxIconChoiceCtrlEntry* pEntry ) 4165 { 4166 if( _pOwner->pHead ) 4167 { 4168 if( _pOwner->pHead == pEntry ) 4169 { 4170 if( _pOwner->pHead != pEntry->pflink ) 4171 _pOwner->pHead = pEntry->pflink; 4172 else 4173 { 4174 DBG_ASSERT(!Count(),"EntryList_Impl::Remove > Invalid predecessor" ); 4175 _pOwner->pHead = 0; 4176 } 4177 } 4178 pEntry->Unlink(); 4179 } 4180 } 4181 4182 void SvxIconChoiceCtrl_Impl::SetPositionMode( SvxIconChoiceCtrlPositionMode eMode ) 4183 { 4184 sal_uLong nCur; 4185 4186 if( eMode == ePositionMode ) 4187 return; 4188 4189 SvxIconChoiceCtrlPositionMode eOldMode = ePositionMode; 4190 ePositionMode = eMode; 4191 sal_uLong nCount = aEntries.Count(); 4192 4193 if( eOldMode == IcnViewPositionModeAutoArrange ) 4194 { 4195 // positionieren wir verschobene Eintraege 'hart' gibts noch Probleme 4196 // mit ungewollten Ueberlappungen, da diese Eintrage im Arrange 4197 // nicht beruecksichtigt werden. 4198 #if 1 4199 if( aEntries.Count() ) 4200 aAutoArrangeTimer.Start(); 4201 #else 4202 if( pHead ) 4203 { 4204 // verschobene Eintraege 'hart' auf ihre Position setzen 4205 nCur = nCount; 4206 SvxIconChoiceCtrlEntry* pEntry = pHead; 4207 while( nCur ) 4208 { 4209 SvxIconChoiceCtrlEntry* pPred; 4210 if( GetEntryPredecessor( pEntry, &pPred )) 4211 SetEntryFlags( pEntry, ICNVIEW_FLAG_POS_MOVED ); 4212 pEntry = pEntry->pflink; 4213 nCur--; 4214 } 4215 ClearPredecessors(); 4216 } 4217 #endif 4218 return; 4219 } 4220 4221 if( ePositionMode == IcnViewPositionModeAutoArrange ) 4222 { 4223 List aMovedEntries; 4224 for( nCur = 0; nCur < nCount; nCur++ ) 4225 { 4226 SvxIconChoiceCtrlEntry* pEntry = (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nCur ); 4227 if( pEntry->GetFlags() & (ICNVIEW_FLAG_POS_LOCKED | ICNVIEW_FLAG_POS_MOVED)) 4228 { 4229 SvxIconChoiceCtrlEntry_Impl* pE = new SvxIconChoiceCtrlEntry_Impl( 4230 pEntry, GetEntryBoundRect( pEntry )); 4231 aMovedEntries.Insert( pE, LIST_APPEND ); 4232 } 4233 } 4234 nCount = aMovedEntries.Count(); 4235 for( nCur = 0; nCur < nCount; nCur++ ) 4236 { 4237 SvxIconChoiceCtrlEntry_Impl* pE = (SvxIconChoiceCtrlEntry_Impl*)aMovedEntries.GetObject(nCur); 4238 SetEntryPos( pE->_pEntry, pE->_aPos ); 4239 } 4240 for( nCur = 0; nCur < nCount; nCur++ ) 4241 delete (SvxIconChoiceCtrlEntry_Impl*)aMovedEntries.GetObject( nCur ); 4242 if( aEntries.Count() ) 4243 aAutoArrangeTimer.Start(); 4244 } 4245 else if( ePositionMode == IcnViewPositionModeAutoAdjust ) 4246 { 4247 AdjustEntryAtGrid( 0 ); 4248 } 4249 } 4250 4251 void SvxIconChoiceCtrl_Impl::SetEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry, 4252 SvxIconChoiceCtrlEntry* pPredecessor ) 4253 { 4254 if( !IsAutoArrange() ) 4255 return; 4256 4257 if( pEntry == pPredecessor ) 4258 return; 4259 4260 sal_uLong nPos1 = GetEntryListPos( pEntry ); 4261 if( !pHead ) 4262 { 4263 if( pPredecessor ) 4264 { 4265 sal_uLong nPos2 = GetEntryListPos( pPredecessor ); 4266 if( nPos1 == (nPos2 + 1) ) 4267 return; // ist schon Vorgaenger 4268 } 4269 else if( !nPos1 ) 4270 return; 4271 } 4272 4273 if( !pHead ) 4274 InitPredecessors(); 4275 4276 if( !pPredecessor && pHead == pEntry ) 4277 return; // ist schon der Erste 4278 4279 sal_Bool bSetHead = sal_False; 4280 if( !pPredecessor ) 4281 { 4282 bSetHead = sal_True; 4283 pPredecessor = pHead->pblink; 4284 } 4285 if( pEntry == pHead ) 4286 { 4287 pHead = pHead->pflink; 4288 bSetHead = sal_False; 4289 } 4290 if( pEntry != pPredecessor ) 4291 { 4292 pEntry->Unlink(); 4293 pEntry->SetBacklink( pPredecessor ); 4294 } 4295 if( bSetHead ) 4296 pHead = pEntry; 4297 pEntry->SetFlags( ICNVIEW_FLAG_PRED_SET ); 4298 aAutoArrangeTimer.Start(); 4299 } 4300 4301 sal_Bool SvxIconChoiceCtrl_Impl::GetEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry, 4302 SvxIconChoiceCtrlEntry** ppPredecessor ) 4303 { 4304 *ppPredecessor = 0; 4305 if( !pHead ) 4306 return sal_False; 4307 DBG_ASSERT(pEntry->pblink,"GetEntryPredecessor: Backward link not set"); 4308 DBG_ASSERT(pEntry->pflink,"GetEntryPredecessor: Forward link not set"); 4309 4310 if( pEntry == pHead ) 4311 { 4312 SvxIconChoiceCtrlEntry* pFirst = (SvxIconChoiceCtrlEntry*)aEntries.GetObject(0); 4313 if( pFirst != pEntry ) 4314 return sal_True; 4315 return sal_False; 4316 } 4317 *ppPredecessor = pEntry->pblink; 4318 if( !(pEntry->nFlags & ICNVIEW_FLAG_PRED_SET) && 4319 (GetEntryListPos( *ppPredecessor ) + 1) == GetEntryListPos( pEntry )) 4320 return sal_False; 4321 return sal_True; 4322 } 4323 4324 SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::FindEntryPredecessor( SvxIconChoiceCtrlEntry* pEntry, 4325 const Point& rPosTopLeft ) 4326 { 4327 Point aPos( rPosTopLeft ); //TopLeft 4328 Rectangle aCenterRect( CalcBmpRect( pEntry, &aPos )); 4329 Point aNewPos( aCenterRect.Center() ); 4330 sal_uLong nGrid = GetPredecessorGrid( aNewPos ); 4331 sal_uLong nCount = aEntries.Count(); 4332 if( nGrid == ULONG_MAX ) 4333 return 0; 4334 if( nGrid >= nCount ) 4335 nGrid = nCount - 1; 4336 if( !pHead ) 4337 return (SvxIconChoiceCtrlEntry*)aEntries.GetObject( nGrid ); 4338 4339 SvxIconChoiceCtrlEntry* pCur = pHead; // Grid 0 4340 // todo: Liste von hinten aufrollen wenn nGrid > nCount/2 4341 for( sal_uLong nCur = 0; nCur < nGrid; nCur++ ) 4342 pCur = pCur->pflink; 4343 4344 return pCur; 4345 } 4346 4347 sal_uLong SvxIconChoiceCtrl_Impl::GetPredecessorGrid( const Point& rPos) const 4348 { 4349 Point aPos( rPos ); 4350 aPos.X() -= LROFFS_WINBORDER; 4351 aPos.Y() -= TBOFFS_WINBORDER; 4352 sal_uInt16 nMaxCol = (sal_uInt16)(aVirtOutputSize.Width() / nGridDX); 4353 if( nMaxCol ) 4354 nMaxCol--; 4355 sal_uInt16 nGridX = (sal_uInt16)(aPos.X() / nGridDX); 4356 if( nGridX > nMaxCol ) 4357 nGridX = nMaxCol; 4358 sal_uInt16 nGridY = (sal_uInt16)(aPos.Y() / nGridDY); 4359 sal_uInt16 nGridsX = (sal_uInt16)(aOutputSize.Width() / nGridDX); 4360 sal_uLong nGrid = (nGridY * nGridsX) + nGridX; 4361 long nMiddle = (nGridX * nGridDX) + (nGridDX / 2); 4362 if( rPos.X() < nMiddle ) 4363 { 4364 if( !nGrid ) 4365 nGrid = ULONG_MAX; 4366 else 4367 nGrid--; 4368 } 4369 return nGrid; 4370 } 4371 4372 void SvxIconChoiceCtrl_Impl::Flush() 4373 { 4374 if( aAutoArrangeTimer.IsActive() ) 4375 { 4376 AutoArrangeHdl( 0 ); 4377 } 4378 } 4379 4380 sal_Bool SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent& rHEvt ) 4381 { 4382 if ( !(rHEvt.GetMode() & HELPMODE_QUICK ) ) 4383 return sal_False; 4384 4385 Point aPos( pView->ScreenToOutputPixel(rHEvt.GetMousePosPixel() ) ); 4386 aPos -= pView->GetMapMode().GetOrigin(); 4387 SvxIconChoiceCtrlEntry* pEntry = GetEntry( aPos, sal_True ); 4388 4389 if ( !pEntry ) 4390 return sal_False; 4391 4392 String sQuickHelpText = pEntry->GetQuickHelpText(); 4393 String aEntryText( pView->GetEntryText( pEntry, sal_False ) ); 4394 Rectangle aTextRect( CalcTextRect( pEntry, 0, sal_False, &aEntryText ) ); 4395 if ( ( !aTextRect.IsInside( aPos ) || !aEntryText.Len() ) && !sQuickHelpText.Len() ) 4396 return sal_False; 4397 4398 Rectangle aOptTextRect( aTextRect ); 4399 aOptTextRect.Bottom() = LONG_MAX; 4400 sal_uInt16 nNewFlags = nCurTextDrawFlags; 4401 nNewFlags &= ~( TEXT_DRAW_CLIP | TEXT_DRAW_ENDELLIPSIS ); 4402 aOptTextRect = pView->GetTextRect( aOptTextRect, aEntryText, nNewFlags ); 4403 if ( aOptTextRect != aTextRect || sQuickHelpText.Len() > 0 ) 4404 { 4405 //aTextRect.Right() = aTextRect.Left() + aRealSize.Width() + 4; 4406 Point aPt( aOptTextRect.TopLeft() ); 4407 aPt += pView->GetMapMode().GetOrigin(); 4408 aPt = pView->OutputToScreenPixel( aPt ); 4409 // Border der Tiphilfe abziehen 4410 aPt.Y() -= 1; 4411 aPt.X() -= 3; 4412 aOptTextRect.SetPos( aPt ); 4413 String sHelpText; 4414 if ( sQuickHelpText.Len() > 0 ) 4415 sHelpText = sQuickHelpText; 4416 else 4417 sHelpText = aEntryText; 4418 Help::ShowQuickHelp( (Window*)pView, aOptTextRect, sHelpText, QUICKHELP_LEFT | QUICKHELP_VCENTER ); 4419 } 4420 4421 return sal_True; 4422 } 4423 4424 void SvxIconChoiceCtrl_Impl::ClearColumnList() 4425 { 4426 if( !pColumns ) 4427 return; 4428 4429 const sal_uInt16 nCount = pColumns->Count(); 4430 for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ ) 4431 { 4432 SvxIconChoiceCtrlColumnInfo* pInfo = (SvxIconChoiceCtrlColumnInfo*) 4433 pColumns->GetObject( nCur ); 4434 delete pInfo; 4435 } 4436 DELETEZ(pColumns); 4437 } 4438 4439 void SvxIconChoiceCtrl_Impl::SetColumn( sal_uInt16 nIndex, const SvxIconChoiceCtrlColumnInfo& rInfo) 4440 { 4441 if( !pColumns ) 4442 pColumns = new SvPtrarr; 4443 while( pColumns->Count() < nIndex + 1 ) 4444 pColumns->Insert( (void*)0, pColumns->Count() ); 4445 4446 SvxIconChoiceCtrlColumnInfo* pInfo = 4447 (SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject(nIndex); 4448 if( !pInfo ) 4449 { 4450 pInfo = new SvxIconChoiceCtrlColumnInfo( rInfo ); 4451 pColumns->Insert( (void*)pInfo, nIndex ); 4452 } 4453 else 4454 { 4455 delete pInfo; 4456 pInfo = new SvxIconChoiceCtrlColumnInfo( rInfo ); 4457 pColumns->Replace( pInfo, nIndex ); 4458 } 4459 4460 // HACK(Detail-Modus ist noch nicht vollstaendig implementiert!) 4461 // dieses Workaround bringts mit einer Spalte zum Fliegen 4462 if( !nIndex && (nWinBits & WB_DETAILS) ) 4463 nGridDX = pInfo->GetWidth(); 4464 4465 if( GetUpdateMode() ) 4466 Arrange( IsAutoArrange() ); 4467 } 4468 4469 const SvxIconChoiceCtrlColumnInfo* SvxIconChoiceCtrl_Impl::GetColumn( sal_uInt16 nIndex ) const 4470 { 4471 if( !pColumns || nIndex >= pColumns->Count() ) 4472 return 0; 4473 return (const SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject( nIndex ); 4474 } 4475 4476 const SvxIconChoiceCtrlColumnInfo* SvxIconChoiceCtrl_Impl::GetItemColumn( sal_uInt16 nSubItem, 4477 long& rLeft ) const 4478 { 4479 rLeft = 0; 4480 if( !pColumns ) 4481 return 0; 4482 const sal_uInt16 nCount = pColumns->Count(); 4483 const SvxIconChoiceCtrlColumnInfo* pCol = 0; 4484 for( sal_uInt16 nCur = 0; nCur < nCount; nCur++ ) 4485 { 4486 pCol = (const SvxIconChoiceCtrlColumnInfo*)pColumns->GetObject( nCur ); 4487 if( !pCol || pCol->GetSubItem() == nSubItem ) 4488 return pCol; 4489 rLeft += pCol->GetWidth(); 4490 } 4491 return pCol; 4492 } 4493 4494 void SvxIconChoiceCtrl_Impl::DrawHighlightFrame( 4495 OutputDevice* pOut, const Rectangle& rBmpRect, sal_Bool bHide ) 4496 { 4497 Rectangle aBmpRect( rBmpRect ); 4498 long nBorder = 2; 4499 if( aImageSize.Width() < 32 ) 4500 nBorder = 1; 4501 aBmpRect.Right() += nBorder; 4502 aBmpRect.Left() -= nBorder; 4503 aBmpRect.Bottom() += nBorder; 4504 aBmpRect.Top() -= nBorder; 4505 4506 if ( bHide ) 4507 pView->Invalidate( aBmpRect ); 4508 else 4509 { 4510 DecorationView aDecoView( pOut ); 4511 sal_uInt16 nDecoFlags; 4512 if ( bHighlightFramePressed ) 4513 nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_IN; 4514 else 4515 nDecoFlags = FRAME_HIGHLIGHT_TESTBACKGROUND | FRAME_HIGHLIGHT_OUT; 4516 aDecoView.DrawHighlightFrame( aBmpRect, nDecoFlags ); 4517 } 4518 } 4519 4520 void SvxIconChoiceCtrl_Impl::SetEntryHighlightFrame( SvxIconChoiceCtrlEntry* pEntry, 4521 sal_Bool bKeepHighlightFlags ) 4522 { 4523 if( pEntry == pCurHighlightFrame ) 4524 return; 4525 4526 if( !bKeepHighlightFlags ) 4527 bHighlightFramePressed = sal_False; 4528 4529 HideEntryHighlightFrame(); 4530 pCurHighlightFrame = pEntry; 4531 if( pEntry ) 4532 { 4533 Rectangle aBmpRect( CalcFocusRect(pEntry) ); 4534 DrawHighlightFrame( pView, aBmpRect, sal_False ); 4535 } 4536 } 4537 4538 void SvxIconChoiceCtrl_Impl::HideEntryHighlightFrame() 4539 { 4540 if( !pCurHighlightFrame ) 4541 return; 4542 4543 SvxIconChoiceCtrlEntry* pEntry = pCurHighlightFrame; 4544 pCurHighlightFrame = 0; 4545 Rectangle aBmpRect( CalcFocusRect(pEntry) ); 4546 DrawHighlightFrame( pView, aBmpRect, sal_True ); 4547 } 4548 4549 void SvxIconChoiceCtrl_Impl::CallSelectHandler( SvxIconChoiceCtrlEntry* ) 4550 { 4551 // Bei aktiviertem Single-Click-Modus sollte der Selektionshandler 4552 // synchron gerufen werden, weil die Selektion automatisch 4553 // weggenommen wird, wenn der Mauszeiger nicht mehr das Objekt 4554 // beruehrt. Es kann sonst zu fehlenden Select-Aufrufen kommen, 4555 // wenn das Objekt aus einer Mausbewegung heraus selektiert wird, 4556 // weil beim Ausloesen des Timers der Mauszeiger das Objekt u.U. 4557 // schon verlassen hat. 4558 // Fuer spezielle Faelle (=>SfxFileDialog!) koennen synchrone 4559 // Aufrufe auch per WB_NOASYNCSELECTHDL erzwungen werden. 4560 if( nWinBits & (WB_NOASYNCSELECTHDL | WB_HIGHLIGHTFRAME) ) 4561 { 4562 pHdlEntry = 0; 4563 pView->ClickIcon(); 4564 //pView->Select(); 4565 } 4566 else 4567 aCallSelectHdlTimer.Start(); 4568 } 4569 4570 IMPL_LINK( SvxIconChoiceCtrl_Impl, CallSelectHdlHdl, void*, EMPTYARG ) 4571 { 4572 pHdlEntry = 0; 4573 pView->ClickIcon(); 4574 //pView->Select(); 4575 return 0; 4576 } 4577 4578 Point SvxIconChoiceCtrl_Impl::GetPopupMenuPosPixel() const 4579 { 4580 Point aResult; 4581 if( !GetSelectionCount() ) 4582 return aResult; 4583 4584 SvxIconChoiceCtrlEntry* pEntry = GetCurEntry(); 4585 if( !pEntry || !pEntry->IsSelected() ) 4586 { 4587 sal_uLong nNext; 4588 pEntry = GetFirstSelectedEntry( nNext ); 4589 } 4590 if( pEntry ) 4591 { 4592 Rectangle aRect( ((SvxIconChoiceCtrl_Impl*)this)->CalcBmpRect( pEntry ) ); 4593 aResult = aRect.Center(); 4594 aResult = pView->GetPixelPos( aResult ); 4595 } 4596 return aResult; 4597 } 4598 4599 void SvxIconChoiceCtrl_Impl::SetOrigin( const Point& rPos, sal_Bool bDoNotUpdateWallpaper ) 4600 { 4601 MapMode aMapMode( pView->GetMapMode() ); 4602 aMapMode.SetOrigin( rPos ); 4603 pView->SetMapMode( aMapMode ); 4604 if( !bDoNotUpdateWallpaper ) 4605 { 4606 sal_Bool bScrollable = pView->GetBackground().IsScrollable(); 4607 if( pView->HasBackground() && !bScrollable ) 4608 { 4609 Rectangle aRect( GetOutputRect()); 4610 Wallpaper aPaper( pView->GetBackground() ); 4611 aPaper.SetRect( aRect ); 4612 pView->SetBackground( aPaper ); 4613 } 4614 } 4615 } 4616 4617 sal_uLong SvxIconChoiceCtrl_Impl::GetGridCount( const Size& rSize, sal_Bool bCheckScrBars, 4618 sal_Bool bSmartScrBar ) const 4619 { 4620 Size aSize( rSize ); 4621 if( bCheckScrBars && aHorSBar.IsVisible() ) 4622 aSize.Height() -= nHorSBarHeight; 4623 else if( bSmartScrBar && (nWinBits & WB_ALIGN_LEFT) ) 4624 aSize.Height() -= nHorSBarHeight; 4625 4626 if( bCheckScrBars && aVerSBar.IsVisible() ) 4627 aSize.Width() -= nVerSBarWidth; 4628 else if( bSmartScrBar && (nWinBits & WB_ALIGN_TOP) ) 4629 aSize.Width() -= nVerSBarWidth; 4630 4631 if( aSize.Width() < 0 ) 4632 aSize.Width() = 0; 4633 if( aSize.Height() < 0 ) 4634 aSize.Height() = 0; 4635 4636 return IcnGridMap_Impl::GetGridCount( aSize, (sal_uInt16)nGridDX, (sal_uInt16)nGridDY ); 4637 } 4638 4639 sal_Bool SvxIconChoiceCtrl_Impl::HandleShortCutKey( const KeyEvent& rKEvt ) 4640 { 4641 StopEditTimer(); 4642 4643 sal_Bool bRet = sal_False; 4644 4645 DBG_ASSERT( rKEvt.GetKeyCode().IsMod2(), "*SvxIconChoiceCtrl_Impl::HandleShortCutKey(): no <ALT> pressed!?" ); 4646 4647 sal_Unicode cChar = rKEvt.GetCharCode(); 4648 sal_uLong nPos = (sal_uLong)-1; 4649 4650 if( cChar && IsMnemonicChar( cChar, nPos ) ) 4651 { 4652 // shortcut is clicked 4653 SvxIconChoiceCtrlEntry* pNewCursor = GetEntry( nPos ); 4654 SvxIconChoiceCtrlEntry* pOldCursor = pCursor; 4655 if( pNewCursor != pOldCursor ) 4656 { 4657 SetCursor_Impl( pOldCursor, pNewCursor, sal_False, sal_False, sal_False ); 4658 4659 if( pNewCursor != NULL ) 4660 { 4661 pHdlEntry = pNewCursor; 4662 pCurHighlightFrame = pHdlEntry; 4663 pView->ClickIcon(); 4664 pCurHighlightFrame = NULL; 4665 } 4666 } 4667 bRet = sal_True; 4668 } 4669 4670 return bRet; 4671 } 4672 4673 // ----------------------------------------------------------------------- 4674 4675 void SvxIconChoiceCtrl_Impl::CallEventListeners( sal_uLong nEvent, void* pData ) 4676 { 4677 pView->CallImplEventListeners( nEvent, pData ); 4678 } 4679 4680 4681