1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2011 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 #include "scitems.hxx" 32 33 #include <memory> //auto_ptr 34 #include <editeng/adjitem.hxx> 35 #include <svx/algitem.hxx> 36 #include <svx/dbexch.hrc> 37 #include <editeng/editview.hxx> 38 #include <editeng/editstat.hxx> 39 #include <editeng/flditem.hxx> 40 #include <svx/svdetc.hxx> 41 #include <editeng/editobj.hxx> 42 #include <sfx2/dispatch.hxx> 43 #include <sfx2/viewfrm.hxx> 44 #include <sfx2/docfile.hxx> 45 #include <svl/stritem.hxx> 46 #include <svtools/svlbox.hxx> 47 #include <svtools/svtabbx.hxx> 48 #include <svl/urlbmk.hxx> 49 #include <tools/urlobj.hxx> 50 #include <vcl/cursor.hxx> 51 #include <vcl/sound.hxx> 52 #include <vcl/graph.hxx> 53 #include <vcl/hatch.hxx> 54 #include <sot/formats.hxx> 55 #include <sot/clsids.hxx> 56 57 #include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT) 58 #include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT) 59 #include <svx/svditer.hxx> 60 #include <svx/svdocapt.hxx> 61 #include <svx/svdpagv.hxx> 62 63 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> 64 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> 65 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> 66 #include <com/sun/star/sheet/DataPilotTableResultData.hpp> 67 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp> 68 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp> 69 #include <com/sun/star/sheet/MemberResultFlags.hpp> 70 #include <com/sun/star/awt/KeyModifier.hpp> 71 #include <com/sun/star/awt/MouseButton.hpp> 72 #include <com/sun/star/script/vba/VBAEventId.hpp> 73 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> 74 75 #include "gridwin.hxx" 76 #include "tabvwsh.hxx" 77 #include "docsh.hxx" 78 #include "viewdata.hxx" 79 #include "tabview.hxx" 80 #include "select.hxx" 81 #include "scmod.hxx" 82 #include "document.hxx" 83 #include "attrib.hxx" 84 #include "dbcolect.hxx" 85 #include "stlpool.hxx" 86 #include "printfun.hxx" 87 #include "cbutton.hxx" 88 #include "sc.hrc" 89 #include "globstr.hrc" 90 #include "editutil.hxx" 91 #include "scresid.hxx" 92 #include "inputhdl.hxx" 93 #include "uiitems.hxx" // Filter-Dialog - auslagern !!! 94 #include "filtdlg.hxx" 95 #include "impex.hxx" // Sylk-ID fuer CB 96 #include "cell.hxx" // fuer Edit-Felder 97 #include "patattr.hxx" 98 #include "notemark.hxx" 99 #include "rfindlst.hxx" 100 #include "docpool.hxx" 101 #include "output.hxx" 102 #include "docfunc.hxx" 103 #include "dbdocfun.hxx" 104 #include "dpobject.hxx" 105 #include "dpoutput.hxx" 106 #include "transobj.hxx" 107 #include "drwtrans.hxx" 108 #include "seltrans.hxx" 109 #include "sizedev.hxx" 110 #include "AccessibilityHints.hxx" 111 #include "dpsave.hxx" 112 #include "viewuno.hxx" 113 #include "compiler.hxx" 114 #include "editable.hxx" 115 #include "fillinfo.hxx" 116 #include "scitems.hxx" 117 #include "userdat.hxx" 118 #include "drwlayer.hxx" 119 #include "attrib.hxx" 120 #include "validat.hxx" 121 #include "tabprotection.hxx" 122 #include "postit.hxx" 123 #include "dpcontrol.hxx" 124 #include "cellsuno.hxx" 125 126 #include "drawview.hxx" 127 #include <svx/sdrpagewindow.hxx> 128 #include <svx/sdr/overlay/overlaymanager.hxx> 129 #include <vcl/svapp.hxx> 130 #include <svx/sdr/overlay/overlayselection.hxx> 131 132 using namespace com::sun::star; 133 using ::com::sun::star::uno::Sequence; 134 using ::com::sun::star::uno::Any; 135 136 const sal_uInt8 SC_NESTEDBUTTON_NONE = 0; 137 const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1; 138 const sal_uInt8 SC_NESTEDBUTTON_UP = 2; 139 140 #define SC_AUTOFILTER_ALL 0 141 #define SC_AUTOFILTER_TOP10 1 142 #define SC_AUTOFILTER_CUSTOM 2 143 144 // Modi fuer die FilterListBox 145 enum ScFilterBoxMode 146 { 147 SC_FILTERBOX_FILTER, 148 SC_FILTERBOX_DATASELECT, 149 SC_FILTERBOX_SCENARIO, 150 SC_FILTERBOX_PAGEFIELD 151 }; 152 153 extern SfxViewShell* pScActiveViewShell; // global.cxx 154 extern sal_uInt16 nScClickMouseModifier; // global.cxx 155 extern sal_uInt16 nScFillModeMouseModifier; // global.cxx 156 157 #define SC_FILTERLISTBOX_LINES 12 158 159 // ============================================================================ 160 161 ScGridWindow::VisibleRange::VisibleRange() : 162 mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW) 163 { 164 } 165 166 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const 167 { 168 return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2; 169 } 170 171 // ============================================================================ 172 173 class ScFilterListBox : public ListBox 174 { 175 private: 176 ScGridWindow* pGridWin; 177 SCCOL nCol; 178 SCROW nRow; 179 sal_Bool bButtonDown; 180 sal_Bool bInit; 181 sal_Bool bCancelled; 182 sal_Bool bInSelect; 183 bool mbListHasDates; 184 sal_uLong nSel; 185 ScFilterBoxMode eMode; 186 187 protected: 188 virtual void LoseFocus(); 189 void SelectHdl(); 190 191 public: 192 ScFilterListBox( Window* pParent, ScGridWindow* pGrid, 193 SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ); 194 ~ScFilterListBox(); 195 196 virtual long PreNotify( NotifyEvent& rNEvt ); 197 virtual void Select(); 198 199 SCCOL GetCol() const { return nCol; } 200 SCROW GetRow() const { return nRow; } 201 ScFilterBoxMode GetMode() const { return eMode; } 202 sal_Bool IsDataSelect() const { return (eMode == SC_FILTERBOX_DATASELECT); } 203 void EndInit(); 204 sal_Bool IsInInit() const { return bInit; } 205 void SetCancelled() { bCancelled = sal_True; } 206 sal_Bool IsInSelect() const { return bInSelect; } 207 void SetListHasDates(bool b) { mbListHasDates = b; } 208 bool HasDates() const { return mbListHasDates; } 209 }; 210 211 //------------------------------------------------------------------- 212 213 // ListBox in einem FloatingWindow (pParent) 214 ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid, 215 SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) : 216 ListBox( pParent, WB_AUTOHSCROLL ), 217 pGridWin( pGrid ), 218 nCol( nNewCol ), 219 nRow( nNewRow ), 220 bButtonDown( sal_False ), 221 bInit( sal_True ), 222 bCancelled( sal_False ), 223 bInSelect( sal_False ), 224 mbListHasDates(false), 225 nSel( 0 ), 226 eMode( eNewMode ) 227 { 228 } 229 230 __EXPORT ScFilterListBox::~ScFilterListBox() 231 { 232 if (IsMouseCaptured()) 233 ReleaseMouse(); 234 } 235 236 void ScFilterListBox::EndInit() 237 { 238 sal_uInt16 nPos = GetSelectEntryPos(); 239 if ( LISTBOX_ENTRY_NOTFOUND == nPos ) 240 nSel = 0; 241 else 242 nSel = nPos; 243 244 bInit = sal_False; 245 } 246 247 void __EXPORT ScFilterListBox::LoseFocus() 248 { 249 #ifndef UNX 250 Hide(); 251 #endif 252 } 253 254 // ----------------------------------------------------------------------- 255 256 long ScFilterListBox::PreNotify( NotifyEvent& rNEvt ) 257 { 258 long nDone = 0; 259 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 260 { 261 KeyEvent aKeyEvt = *rNEvt.GetKeyEvent(); 262 KeyCode aCode = aKeyEvt.GetKeyCode(); 263 if ( !aCode.GetModifier() ) // ohne alle Modifiers 264 { 265 sal_uInt16 nKey = aCode.GetCode(); 266 if ( nKey == KEY_RETURN ) 267 { 268 SelectHdl(); // auswaehlen 269 nDone = 1; 270 } 271 else if ( nKey == KEY_ESCAPE ) 272 { 273 pGridWin->ClickExtern(); // loescht die List-Box !!! 274 nDone = 1; 275 } 276 } 277 } 278 279 return nDone ? nDone : ListBox::PreNotify( rNEvt ); 280 } 281 282 void __EXPORT ScFilterListBox::Select() 283 { 284 ListBox::Select(); 285 SelectHdl(); 286 } 287 288 void __EXPORT ScFilterListBox::SelectHdl() 289 { 290 if ( !IsTravelSelect() && !bInit && !bCancelled ) 291 { 292 sal_uInt16 nPos = GetSelectEntryPos(); 293 if ( LISTBOX_ENTRY_NOTFOUND != nPos ) 294 { 295 nSel = nPos; 296 if (!bButtonDown) 297 { 298 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect 299 bInSelect = sal_True; 300 pGridWin->FilterSelect( nSel ); 301 bInSelect = sal_False; 302 } 303 } 304 } 305 } 306 307 // ============================================================================ 308 309 // use a System floating window for the above filter listbox 310 class ScFilterFloatingWindow : public FloatingWindow 311 { 312 public: 313 ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN ); 314 virtual ~ScFilterFloatingWindow(); 315 // required for System FloatingWindows that will not process KeyInput by themselves 316 virtual Window* GetPreferredKeyInputWindow(); 317 }; 318 319 ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) : 320 FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater 321 {} 322 323 ScFilterFloatingWindow::~ScFilterFloatingWindow() 324 { 325 EndPopupMode(); 326 } 327 328 Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow() 329 { 330 // redirect keyinput in the child window 331 return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL; // will be the FilterBox 332 } 333 334 // ============================================================================ 335 336 sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange ) 337 { 338 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle 339 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix. 340 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ??? 341 342 if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(), 343 rRange.aEnd.Col(),rRange.aEnd.Row() ) ) 344 return sal_False; 345 346 ScAddress aPos; 347 const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd ); 348 return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && 349 ((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart ); 350 351 } 352 353 void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData ) 354 { 355 if (!pView && !pPV && !pDrDoc && !pViewData) 356 return; 357 358 ScDocument& rDoc = *pViewData->GetDocument(); 359 ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); 360 ScPostIt* pNote = rDoc.GetNote( aCellPos ); 361 SdrObject* pObj = pNote ? pNote->GetCaption() : 0; 362 if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) ) 363 { 364 const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) ); 365 bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ; 366 bool bProtectDoc = rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ; 367 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged() 368 pView->LockInternalLayer( bProtectDoc && bProtectAttr ); 369 } 370 } 371 372 sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell ) 373 { 374 sal_Bool bFound = sal_False; 375 do 376 { 377 pDoc->GetCell( rPosX, rPosY, nTab, rpCell ); 378 if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE ) 379 { 380 if ( rPosX <= 0 ) 381 return sal_False; // alles leer bis links 382 else 383 --rPosX; // weitersuchen 384 } 385 else if ( rpCell->GetCellType() == CELLTYPE_EDIT) 386 bFound = sal_True; 387 else if (rpCell->GetCellType() == CELLTYPE_FORMULA && 388 static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell()) 389 bFound = sal_True; 390 else 391 return sal_False; // andere Zelle 392 } 393 while ( !bFound ); 394 395 return bFound; 396 } 397 398 // --------------------------------------------------------------------------- 399 // WB_DIALOGCONTROL noetig fuer UNO-Controls 400 ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos ) 401 : Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ), 402 DropTargetHelper( this ), 403 DragSourceHelper( this ), 404 mpOOCursors( NULL ), 405 mpOOSelection( NULL ), 406 mpOOAutoFill( NULL ), 407 mpOODragRect( NULL ), 408 mpOOHeader( NULL ), 409 mpOOShrink( NULL ), 410 mpAutoFillRect(static_cast<Rectangle*>(NULL)), 411 pViewData( pData ), 412 eWhich( eWhichPos ), 413 pNoteMarker( NULL ), 414 pFilterBox( NULL ), 415 pFilterFloat( NULL ), 416 mpDPFieldPopup(NULL), 417 mpFilterButton(NULL), 418 nCursorHideCount( 0 ), 419 bMarking( sal_False ), 420 nButtonDown( 0 ), 421 bEEMouse( sal_False ), 422 nMouseStatus( SC_GM_NONE ), 423 nNestedButtonState( SC_NESTEDBUTTON_NONE ), 424 bDPMouse( sal_False ), 425 bRFMouse( sal_False ), 426 nPagebreakMouse( SC_PD_NONE ), 427 bPagebreakDrawn( sal_False ), 428 nPageScript( 0 ), 429 bDragRect( sal_False ), 430 meDragInsertMode( INS_NONE ), 431 nCurrentPointer( 0 ), 432 bIsInScroll( sal_False ), 433 bIsInPaint( sal_False ), 434 aComboButton( this ), 435 aCurMousePos( 0,0 ), 436 nPaintCount( 0 ), 437 bNeedsRepaint( sal_False ), 438 bAutoMarkVisible( sal_False ), 439 bListValButton( sal_False ) 440 { 441 switch(eWhich) 442 { 443 case SC_SPLIT_TOPLEFT: 444 eHWhich = SC_SPLIT_LEFT; 445 eVWhich = SC_SPLIT_TOP; 446 break; 447 case SC_SPLIT_TOPRIGHT: 448 eHWhich = SC_SPLIT_RIGHT; 449 eVWhich = SC_SPLIT_TOP; 450 break; 451 case SC_SPLIT_BOTTOMLEFT: 452 eHWhich = SC_SPLIT_LEFT; 453 eVWhich = SC_SPLIT_BOTTOM; 454 break; 455 case SC_SPLIT_BOTTOMRIGHT: 456 eHWhich = SC_SPLIT_RIGHT; 457 eVWhich = SC_SPLIT_BOTTOM; 458 break; 459 default: 460 DBG_ERROR("GridWindow: falsche Position"); 461 } 462 463 SetBackground(); 464 465 SetMapMode(pViewData->GetLogicMode(eWhich)); 466 // EnableDrop(); 467 EnableChildTransparentMode(); 468 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS ); 469 470 SetHelpId( HID_SC_WIN_GRIDWIN ); 471 SetUniqueId( HID_SC_WIN_GRIDWIN ); 472 473 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() ); 474 EnableRTL( sal_False ); 475 } 476 477 __EXPORT ScGridWindow::~ScGridWindow() 478 { 479 // #114409# 480 ImpDestroyOverlayObjects(); 481 482 delete pFilterBox; 483 delete pFilterFloat; 484 delete pNoteMarker; 485 } 486 487 void __EXPORT ScGridWindow::Resize( const Size& ) 488 { 489 // gar nix 490 } 491 492 void ScGridWindow::ClickExtern() 493 { 494 do 495 { 496 // #i81298# don't delete the filter box when called from its select handler 497 // (possible through row header size update) 498 // #i84277# when initializing the filter box, a Basic error can deactivate the view 499 if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) ) 500 { 501 break; 502 } 503 504 DELETEZ(pFilterBox); 505 DELETEZ(pFilterFloat); 506 } 507 while (false); 508 509 if (mpDPFieldPopup.get()) 510 { 511 mpDPFieldPopup->close(false); 512 mpDPFieldPopup.reset(); 513 } 514 } 515 516 IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG ) 517 { 518 if (pFilterBox) 519 pFilterBox->SetCancelled(); // nicht mehr auswaehlen 520 GrabFocus(); 521 return 0; 522 } 523 524 IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo ) 525 { 526 if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG ) 527 pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON ); 528 return 0; 529 } 530 531 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr ) 532 { 533 //! gridwin2 ? 534 535 ScDocument* pDoc = pViewData->GetDocument(); 536 SCTAB nTab = pViewData->GetTabNo(); 537 ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); 538 if ( pDPObj && nCol > 0 ) 539 { 540 // look for the dimension header left of the drop-down arrow 541 sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; 542 long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); 543 if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) 544 { 545 ScDPSaveData aSaveData( *pDPObj->GetSaveData() ); 546 547 sal_Bool bIsDataLayout; 548 String aDimName = pDPObj->GetDimName( nField, bIsDataLayout ); 549 if ( !bIsDataLayout ) 550 { 551 ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName); 552 553 if ( bHasSelection ) 554 pDim->SetCurrentPage( &rStr ); 555 else 556 pDim->SetCurrentPage( NULL ); 557 558 ScDPObject aNewObj( *pDPObj ); 559 aNewObj.SetSaveData( aSaveData ); 560 ScDBDocFunc aFunc( *pViewData->GetDocShell() ); 561 aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False ); 562 pViewData->GetView()->CursorPosChanged(); // shells may be switched 563 } 564 } 565 } 566 } 567 568 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) 569 { 570 //! merge position/size handling with DoAutoFilterMenue 571 572 delete pFilterBox; 573 delete pFilterFloat; 574 575 sal_uInt16 i; 576 ScDocument* pDoc = pViewData->GetDocument(); 577 SCTAB nTab = pViewData->GetTabNo(); 578 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 579 580 long nSizeX = 0; 581 long nSizeY = 0; 582 long nHeight = 0; 583 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); 584 Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); 585 if ( bLayoutRTL ) 586 aPos.X() -= nSizeX; 587 588 Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); 589 590 aPos.X() -= 1; 591 aPos.Y() += nSizeY - 1; 592 593 pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // not resizable etc. 594 pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); 595 pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD ); 596 if ( bLayoutRTL ) 597 pFilterBox->EnableMirroring(); 598 599 nSizeX += 1; 600 601 { 602 Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); 603 MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); 604 605 nHeight = GetTextHeight(); 606 nHeight *= SC_FILTERLISTBOX_LINES; 607 608 SetMapMode( aOldMode ); 609 SetFont( aOldFont ); 610 } 611 612 // SetSize comes later 613 614 TypedScStrCollection aStrings( 128, 128 ); 615 616 // get list box entries and selection 617 sal_Bool bHasCurrentPage = sal_False; 618 String aCurrentPage; 619 ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); 620 if ( pDPObj && nCol > 0 ) 621 { 622 // look for the dimension header left of the drop-down arrow 623 sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; 624 long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); 625 if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) 626 { 627 pDPObj->FillPageList( aStrings, nField ); 628 629 // get current page from SaveData 630 631 ScDPSaveData* pSaveData = pDPObj->GetSaveData(); 632 sal_Bool bIsDataLayout; 633 String aDimName = pDPObj->GetDimName( nField, bIsDataLayout ); 634 if ( pSaveData && !bIsDataLayout ) 635 { 636 ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName); 637 if ( pDim && pDim->HasCurrentPage() ) 638 { 639 aCurrentPage = pDim->GetCurrentPage(); 640 bHasCurrentPage = sal_True; 641 } 642 } 643 } 644 } 645 646 // include all entry widths for the size of the drop-down 647 long nMaxText = 0; 648 sal_uInt16 nCount = aStrings.GetCount(); 649 for (i=0; i<nCount; i++) 650 { 651 TypedStrData* pData = aStrings[i]; 652 long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); 653 if ( nTextWidth > nMaxText ) 654 nMaxText = nTextWidth; 655 } 656 657 // add scrollbar width if needed (string entries are counted here) 658 // (scrollbar is shown if the box is exactly full?) 659 if ( nCount >= SC_FILTERLISTBOX_LINES ) 660 nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); 661 662 nMaxText += 4; // for borders 663 664 if ( nMaxText > nSizeX ) 665 nSizeX = nMaxText; // just modify width - starting position is unchanged 666 667 // adjust position and size to window 668 669 Size aParentSize = GetParent()->GetOutputSizePixel(); 670 Size aSize( nSizeX, nHeight ); 671 672 if ( aSize.Height() > aParentSize.Height() ) 673 aSize.Height() = aParentSize.Height(); 674 if ( aPos.Y() + aSize.Height() > aParentSize.Height() ) 675 aPos.Y() = aParentSize.Height() - aSize.Height(); 676 677 pFilterBox->SetSizePixel( aSize ); 678 pFilterBox->Show(); // Show must be called before SetUpdateMode 679 pFilterBox->SetUpdateMode(sal_False); 680 681 pFilterFloat->SetOutputSizePixel( aSize ); 682 pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); 683 684 // fill the list box 685 sal_Bool bWait = ( nCount > 100 ); 686 687 if (bWait) 688 EnterWait(); 689 690 for (i=0; i<nCount; i++) 691 pFilterBox->InsertEntry( aStrings[i]->GetString() ); 692 693 pFilterBox->SetSeparatorPos( 0 ); 694 695 if (bWait) 696 LeaveWait(); 697 698 pFilterBox->SetUpdateMode(sal_True); 699 700 sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; 701 if (bHasCurrentPage) 702 nSelPos = pFilterBox->GetEntryPos( aCurrentPage ); 703 704 if ( nSelPos == LISTBOX_ENTRY_NOTFOUND ) 705 nSelPos = 0; // first entry 706 707 pFilterBox->GrabFocus(); 708 709 // call Select after GrabFocus, so the focus rectangle ends up in the right position 710 if ( nSelPos != LISTBOX_ENTRY_NOTFOUND ) 711 pFilterBox->SelectEntryPos( nSelPos ); 712 713 pFilterBox->EndInit(); 714 715 nMouseStatus = SC_GM_FILTER; 716 CaptureMouse(); 717 } 718 719 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) 720 { 721 SCTAB nTab = pViewData->GetTabNo(); 722 ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab); 723 if (!pDPObj) 724 return; 725 726 // Get the geometry of the cell. 727 Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); 728 long nSizeX, nSizeY; 729 pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); 730 Size aScrSize(nSizeX-1, nSizeY-1); 731 732 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj); 733 } 734 735 void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange ) 736 { 737 delete pFilterBox; 738 delete pFilterFloat; 739 740 SCCOL nCol = rScenRange.aEnd.Col(); // Zelle unterhalb des Buttons 741 SCROW nRow = rScenRange.aStart.Row(); 742 if (nRow == 0) 743 { 744 nRow = rScenRange.aEnd.Row() + 1; // Bereich ganz oben -> Button unterhalb 745 if (nRow>MAXROW) nRow = MAXROW; 746 //! Texthoehe addieren (wenn sie an der View gespeichert ist...) 747 } 748 749 ScDocument* pDoc = pViewData->GetDocument(); 750 SCTAB nTab = pViewData->GetTabNo(); 751 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 752 753 long nSizeX = 0; 754 long nSizeY = 0; 755 long nHeight = 0; 756 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); 757 Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); 758 if ( bLayoutRTL ) 759 aPos.X() -= nSizeX; 760 Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); 761 aCellRect.Top() -= nSizeY; 762 aCellRect.Bottom() -= nSizeY - 1; 763 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter 764 // (wenn die Linie verdeckt wird, sieht es komisch aus...) 765 766 pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc. 767 pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); 768 pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO ); 769 if ( bLayoutRTL ) 770 pFilterBox->EnableMirroring(); 771 772 nSizeX += 1; 773 774 { 775 Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); 776 MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); 777 778 nHeight = GetTextHeight(); 779 nHeight *= SC_FILTERLISTBOX_LINES; 780 781 SetMapMode( aOldMode ); 782 SetFont( aOldFont ); 783 } 784 785 // SetSize spaeter 786 /* 787 pFilterBox->SetSelectionMode( SINGLE_SELECTION ); 788 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT )); 789 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft ); 790 */ 791 792 // ParentSize Abfrage fehlt 793 Size aSize( nSizeX, nHeight ); 794 pFilterBox->SetSizePixel( aSize ); 795 pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!! 796 pFilterBox->SetUpdateMode(sal_False); 797 798 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht 799 800 // Listbox fuellen 801 802 long nMaxText = 0; 803 String aCurrent; 804 String aTabName; 805 SCTAB nTabCount = pDoc->GetTableCount(); 806 SCTAB nEntryCount = 0; 807 for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) 808 { 809 if (pDoc->HasScenarioRange( i, rScenRange )) 810 if (pDoc->GetName( i, aTabName )) 811 { 812 pFilterBox->InsertEntry( aTabName ); 813 if (pDoc->IsActiveScenario(i)) 814 aCurrent = aTabName; 815 long nTextWidth = pFilterBox->GetTextWidth( aTabName ); 816 if ( nTextWidth > nMaxText ) 817 nMaxText = nTextWidth; 818 ++nEntryCount; 819 } 820 } 821 if (nEntryCount > SC_FILTERLISTBOX_LINES) 822 nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); 823 nMaxText += 4; // fuer Rand 824 if ( nMaxText > 300 ) 825 nMaxText = 300; // auch nicht uebertreiben (Pixel) 826 827 if (nMaxText > nSizeX) // Groesse auf benoetigte Groesse anpassen 828 { 829 long nDiff = nMaxText - nSizeX; 830 aSize = Size( nMaxText, nHeight ); 831 pFilterBox->SetSizePixel( aSize ); 832 pFilterFloat->SetOutputSizePixel( aSize ); 833 834 if ( !bLayoutRTL ) 835 { 836 // also move popup position 837 long nNewX = aCellRect.Left() - nDiff; 838 if ( nNewX < 0 ) 839 nNewX = 0; 840 aCellRect.Left() = nNewX; 841 } 842 } 843 844 pFilterFloat->SetOutputSizePixel( aSize ); 845 pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS ); 846 847 pFilterBox->SetUpdateMode(sal_True); 848 pFilterBox->GrabFocus(); 849 850 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet 851 //! SvLBoxEntry* pSelect = NULL; 852 sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND; 853 if (aCurrent.Len()) 854 { 855 nPos = pFilterBox->GetEntryPos( aCurrent ); 856 //! pSelect = pFilterBox->GetEntry( nPos ); 857 } 858 if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 ) 859 nPos = 0; 860 //! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein 861 if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos ) 862 pFilterBox->SelectEntryPos(nPos); 863 864 pFilterBox->EndInit(); 865 866 // Szenario-Auswahl kommt aus MouseButtonDown: 867 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown 868 869 nMouseStatus = SC_GM_FILTER; 870 CaptureMouse(); 871 } 872 873 void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, sal_Bool bDataSelect ) 874 { 875 delete pFilterBox; 876 delete pFilterFloat; 877 878 sal_uInt16 i; 879 ScDocument* pDoc = pViewData->GetDocument(); 880 SCTAB nTab = pViewData->GetTabNo(); 881 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 882 883 long nSizeX = 0; 884 long nSizeY = 0; 885 long nHeight = 0; 886 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); 887 Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); 888 if ( bLayoutRTL ) 889 aPos.X() -= nSizeX; 890 891 Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); 892 893 aPos.X() -= 1; 894 aPos.Y() += nSizeY - 1; 895 896 pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc. 897 pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); 898 pFilterBox = new ScFilterListBox( 899 pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER ); 900 if ( bLayoutRTL ) 901 pFilterBox->EnableMirroring(); 902 903 nSizeX += 1; 904 905 { 906 Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); 907 MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); 908 909 nHeight = GetTextHeight(); 910 nHeight *= SC_FILTERLISTBOX_LINES; 911 912 SetMapMode( aOldMode ); 913 SetFont( aOldFont ); 914 } 915 916 // SetSize spaeter 917 /* 918 pFilterBox->SetSelectionMode( SINGLE_SELECTION ); 919 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT )); 920 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft ); 921 */ 922 923 sal_Bool bEmpty = sal_False; 924 TypedScStrCollection aStrings( 128, 128 ); 925 if ( bDataSelect ) // Auswahl-Liste 926 { 927 // Liste fuellen 928 aStrings.SetCaseSensitive( sal_True ); 929 pDoc->GetDataEntries( nCol, nRow, nTab, aStrings ); 930 if ( aStrings.GetCount() == 0 ) 931 bEmpty = sal_True; 932 } 933 else // AutoFilter 934 { 935 //! wird der Titel ueberhaupt ausgewertet ??? 936 String aString; 937 pDoc->GetString( nCol, nRow, nTab, aString ); 938 pFilterBox->SetText( aString ); 939 940 long nMaxText = 0; 941 942 // default entries 943 static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER }; 944 const sal_uInt16 nDefCount = sizeof(nDefIDs) / sizeof(sal_uInt16); 945 for (i=0; i<nDefCount; i++) 946 { 947 String aEntry( (ScResId) nDefIDs[i] ); 948 pFilterBox->InsertEntry( aEntry ); 949 long nTextWidth = pFilterBox->GetTextWidth( aEntry ); 950 if ( nTextWidth > nMaxText ) 951 nMaxText = nTextWidth; 952 } 953 pFilterBox->SetSeparatorPos( nDefCount - 1 ); 954 955 // get list entries 956 bool bHasDates = false; 957 pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates); 958 pFilterBox->SetListHasDates(bHasDates); 959 960 // check widths of numerical entries (string entries are not included) 961 // so all numbers are completely visible 962 sal_uInt16 nCount = aStrings.GetCount(); 963 for (i=0; i<nCount; i++) 964 { 965 TypedStrData* pData = aStrings[i]; 966 if ( !pData->IsStrData() ) // only numerical entries 967 { 968 long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); 969 if ( nTextWidth > nMaxText ) 970 nMaxText = nTextWidth; 971 } 972 } 973 974 // add scrollbar width if needed (string entries are counted here) 975 // (scrollbar is shown if the box is exactly full?) 976 if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES ) 977 nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); 978 979 nMaxText += 4; // for borders 980 981 if ( nMaxText > nSizeX ) 982 nSizeX = nMaxText; // just modify width - starting position is unchanged 983 } 984 985 if (!bEmpty) 986 { 987 // Position und Groesse an Fenster anpassen 988 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite) 989 990 Size aParentSize = GetParent()->GetOutputSizePixel(); 991 Size aSize( nSizeX, nHeight ); 992 993 if ( aSize.Height() > aParentSize.Height() ) 994 aSize.Height() = aParentSize.Height(); 995 if ( aPos.Y() + aSize.Height() > aParentSize.Height() ) 996 aPos.Y() = aParentSize.Height() - aSize.Height(); 997 998 pFilterBox->SetSizePixel( aSize ); 999 pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!! 1000 pFilterBox->SetUpdateMode(sal_False); 1001 1002 pFilterFloat->SetOutputSizePixel( aSize ); 1003 pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); 1004 1005 // Listbox fuellen 1006 sal_uInt16 nCount = aStrings.GetCount(); 1007 sal_Bool bWait = ( nCount > 100 ); 1008 1009 if (bWait) 1010 EnterWait(); 1011 1012 for (i=0; i<nCount; i++) 1013 pFilterBox->InsertEntry( aStrings[i]->GetString() ); 1014 1015 if (bWait) 1016 LeaveWait(); 1017 1018 pFilterBox->SetUpdateMode(sal_True); 1019 } 1020 1021 //! SvLBoxEntry* pSelect = NULL; 1022 sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; 1023 1024 if (!bDataSelect) // AutoFilter: aktiven Eintrag selektieren 1025 { 1026 ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); 1027 if (pDBData) 1028 { 1029 ScQueryParam aParam; 1030 pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben 1031 1032 sal_Bool bValid = sal_True; 1033 for (SCSIZE j=0; j<MAXQUERY && bValid; j++) // bisherige Filter-Einstellungen 1034 if (aParam.GetEntry(j).bDoQuery) 1035 { 1036 //! Abfrage mit DrawButtons zusammenfassen! 1037 1038 ScQueryEntry& rEntry = aParam.GetEntry(j); 1039 if (j>0) 1040 if (rEntry.eConnect != SC_AND) 1041 bValid = sal_False; 1042 if (rEntry.nField == nCol) 1043 { 1044 if (rEntry.eOp == SC_EQUAL) 1045 { 1046 String* pStr = rEntry.pStr; 1047 if (pStr) 1048 { 1049 nSelPos = pFilterBox->GetEntryPos( *pStr ); 1050 //! pSelect = pFilterBox->GetEntry( nPos ); 1051 } 1052 } 1053 else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr && 1054 rEntry.pStr->EqualsAscii("10")) 1055 nSelPos = SC_AUTOFILTER_TOP10; 1056 else 1057 nSelPos = SC_AUTOFILTER_CUSTOM; 1058 } 1059 } 1060 1061 if (!bValid) 1062 nSelPos = SC_AUTOFILTER_CUSTOM; 1063 } 1064 } 1065 else 1066 { 1067 1068 sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr( 1069 nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue(); 1070 if ( nIndex ) 1071 { 1072 const ScValidationData* pData = pDoc->GetValidationEntry( nIndex ); 1073 if (pData) 1074 { 1075 TypedStrData* pNew = NULL; 1076 String aDocStr; 1077 pDoc->GetString( nCol, nRow, nTab, aDocStr ); 1078 if ( pDoc->HasValueData( nCol, nRow, nTab ) ) 1079 { 1080 double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab)); 1081 pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE ); 1082 } 1083 else 1084 pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD ); 1085 1086 bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING); 1087 if ( bSortList ) 1088 { 1089 sal_uInt16 nStrIndex; 1090 if (aStrings.Search(pNew,nStrIndex)) 1091 nSelPos = nStrIndex; 1092 } 1093 else 1094 { 1095 sal_uInt16 nCount = aStrings.GetCount(); 1096 for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++) 1097 { 1098 if ( aStrings.Compare(aStrings[i], pNew)==0 ) 1099 nSelPos = i; 1100 } 1101 } 1102 delete pNew; 1103 } 1104 } 1105 } 1106 1107 // neu (309): irgendwas muss immer selektiert sein: 1108 if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect) 1109 nSelPos = 0; 1110 1111 // keine leere Auswahl-Liste anzeigen: 1112 1113 if ( bEmpty ) 1114 { 1115 DELETEZ(pFilterBox); // war nix 1116 DELETEZ(pFilterFloat); 1117 Sound::Beep(); // bemerkbar machen 1118 } 1119 else 1120 { 1121 // pFilterBox->Show(); // schon vorne 1122 pFilterBox->GrabFocus(); 1123 1124 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet 1125 if ( LISTBOX_ENTRY_NOTFOUND != nSelPos ) 1126 pFilterBox->SelectEntryPos( nSelPos ); 1127 else 1128 { 1129 if (bDataSelect) 1130 pFilterBox->SetNoSelection(); 1131 } 1132 1133 pFilterBox->EndInit(); 1134 1135 if (!bDataSelect) 1136 { 1137 // AutoFilter (aus MouseButtonDown): 1138 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown 1139 1140 nMouseStatus = SC_GM_FILTER; 1141 CaptureMouse(); 1142 } 1143 } 1144 } 1145 1146 void ScGridWindow::FilterSelect( sal_uLong nSel ) 1147 { 1148 String aString; 1149 /* 1150 SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel ); 1151 if (pEntry) 1152 { 1153 SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING ); 1154 if ( pStringEntry ) 1155 aString = pStringEntry->GetText(); 1156 } 1157 */ 1158 aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) ); 1159 1160 SCCOL nCol = pFilterBox->GetCol(); 1161 SCROW nRow = pFilterBox->GetRow(); 1162 switch ( pFilterBox->GetMode() ) 1163 { 1164 case SC_FILTERBOX_DATASELECT: 1165 ExecDataSelect( nCol, nRow, aString ); 1166 break; 1167 case SC_FILTERBOX_FILTER: 1168 ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() ); 1169 break; 1170 case SC_FILTERBOX_SCENARIO: 1171 pViewData->GetView()->UseScenario( aString ); 1172 break; 1173 case SC_FILTERBOX_PAGEFIELD: 1174 // first entry is "all" 1175 ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString ); 1176 break; 1177 } 1178 1179 if (pFilterFloat) 1180 pFilterFloat->EndPopupMode(); 1181 1182 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht 1183 } 1184 1185 void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr ) 1186 { 1187 if ( rStr.Len() ) 1188 { 1189 SCTAB nTab = pViewData->GetTabNo(); 1190 ScViewFunc* pView = pViewData->GetView(); 1191 pView->EnterData( nCol, nRow, nTab, rStr ); 1192 1193 // #i52307# CellContentChanged is not in EnterData so it isn't called twice 1194 // if the cursor is moved afterwards. 1195 pView->CellContentChanged(); 1196 } 1197 } 1198 1199 void ScGridWindow::ExecFilter( sal_uLong nSel, 1200 SCCOL nCol, SCROW nRow, 1201 const String& aValue, bool bCheckForDates ) 1202 { 1203 SCTAB nTab = pViewData->GetTabNo(); 1204 ScDocument* pDoc = pViewData->GetDocument(); 1205 1206 ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); 1207 if (pDBData) 1208 { 1209 ScQueryParam aParam; 1210 pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben 1211 1212 if (SC_AUTOFILTER_CUSTOM == nSel) 1213 { 1214 SCTAB nAreaTab; 1215 SCCOL nStartCol; 1216 SCROW nStartRow; 1217 SCCOL nEndCol; 1218 SCROW nEndRow; 1219 pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow ); 1220 pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab)); 1221 pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ?? 1222 pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); 1223 } 1224 else 1225 { 1226 sal_Bool bDeleteOld = sal_False; 1227 SCSIZE nQueryPos = 0; 1228 sal_Bool bFound = sal_False; 1229 if (!aParam.bInplace) 1230 bDeleteOld = sal_True; 1231 if (aParam.bRegExp) 1232 bDeleteOld = sal_True; 1233 for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++) // bisherige Filter-Einstellungen 1234 if (aParam.GetEntry(i).bDoQuery) 1235 { 1236 //! Abfrage mit DrawButtons zusammenfassen! 1237 1238 ScQueryEntry& rEntry = aParam.GetEntry(i); 1239 if (i>0) 1240 if (rEntry.eConnect != SC_AND) 1241 bDeleteOld = sal_True; 1242 1243 if (rEntry.nField == nCol) 1244 { 1245 if (bFound) // diese Spalte zweimal? 1246 bDeleteOld = sal_True; 1247 nQueryPos = i; 1248 bFound = sal_True; 1249 } 1250 if (!bFound) 1251 nQueryPos = i + 1; 1252 } 1253 1254 if (bDeleteOld) 1255 { 1256 SCSIZE nEC = aParam.GetEntryCount(); 1257 for (SCSIZE i=0; i<nEC; i++) 1258 aParam.GetEntry(i).Clear(); 1259 nQueryPos = 0; 1260 aParam.bInplace = sal_True; 1261 aParam.bRegExp = sal_False; 1262 } 1263 1264 if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel ) // loeschen geht immer 1265 { 1266 if (nSel) 1267 { 1268 ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos); 1269 1270 rNewEntry.bDoQuery = sal_True; 1271 rNewEntry.bQueryByString = sal_True; 1272 rNewEntry.nField = nCol; 1273 rNewEntry.bQueryByDate = bCheckForDates; 1274 if ( nSel == SC_AUTOFILTER_TOP10 ) 1275 { 1276 rNewEntry.eOp = SC_TOPVAL; 1277 *rNewEntry.pStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10")); 1278 } 1279 else 1280 { 1281 rNewEntry.eOp = SC_EQUAL; 1282 *rNewEntry.pStr = aValue; 1283 } 1284 if (nQueryPos > 0) 1285 rNewEntry.eConnect = SC_AND; 1286 } 1287 else 1288 { 1289 if (bFound) 1290 aParam.DeleteQuery(nQueryPos); 1291 } 1292 1293 // #100597# end edit mode - like in ScCellShell::ExecuteDB 1294 if ( pViewData->HasEditView( pViewData->GetActivePart() ) ) 1295 { 1296 SC_MOD()->InputEnterHandler(); 1297 pViewData->GetViewShell()->UpdateInputHandler(); 1298 } 1299 1300 pViewData->GetView()->Query( aParam, NULL, sal_True ); 1301 pDBData->SetQueryParam( aParam ); // speichern 1302 } 1303 else // "Zuviele Bedingungen" 1304 pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY ); 1305 } 1306 } 1307 else 1308 { 1309 DBG_ERROR("Wo ist der Datenbankbereich?"); 1310 } 1311 } 1312 1313 void ScGridWindow::SetPointer( const Pointer& rPointer ) 1314 { 1315 nCurrentPointer = 0; 1316 Window::SetPointer( rPointer ); 1317 } 1318 1319 void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin ) 1320 { 1321 if (nButtonDown) 1322 { 1323 rDestWin.nButtonDown = nButtonDown; 1324 rDestWin.nMouseStatus = nMouseStatus; 1325 } 1326 1327 if (bRFMouse) 1328 { 1329 rDestWin.bRFMouse = bRFMouse; 1330 rDestWin.bRFSize = bRFSize; 1331 rDestWin.nRFIndex = nRFIndex; 1332 rDestWin.nRFAddX = nRFAddX; 1333 rDestWin.nRFAddY = nRFAddY; 1334 bRFMouse = sal_False; 1335 } 1336 1337 if (nPagebreakMouse) 1338 { 1339 rDestWin.nPagebreakMouse = nPagebreakMouse; 1340 rDestWin.nPagebreakBreak = nPagebreakBreak; 1341 rDestWin.nPagebreakPrev = nPagebreakPrev; 1342 rDestWin.aPagebreakSource = aPagebreakSource; 1343 rDestWin.aPagebreakDrag = aPagebreakDrag; 1344 nPagebreakMouse = SC_PD_NONE; 1345 } 1346 } 1347 1348 sal_Bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, sal_Bool bAction ) 1349 { 1350 // MouseEvent buttons must only be checked if bAction==TRUE 1351 // to allow changing the mouse pointer in MouseMove, 1352 // but not start AutoFill with right button (#74229#). 1353 // with bAction==sal_True, SetFillMode / SetDragMode is called 1354 1355 if ( bAction && !rMEvt.IsLeft() ) 1356 return sal_False; 1357 1358 sal_Bool bNewPointer = sal_False; 1359 1360 SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient(); 1361 sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() ); 1362 1363 if ( pViewData->IsActive() && !bOleActive ) 1364 { 1365 ScDocument* pDoc = pViewData->GetDocument(); 1366 SCTAB nTab = pViewData->GetTabNo(); 1367 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1368 1369 // Auto-Fill 1370 1371 ScRange aMarkRange; 1372 if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE) 1373 { 1374 if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect) 1375 { 1376 Point aMousePos = rMEvt.GetPosPixel(); 1377 if (mpAutoFillRect->IsInside(aMousePos)) 1378 { 1379 SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ? 1380 if (bAction) 1381 { 1382 SCCOL nX = aMarkRange.aEnd.Col(); 1383 SCROW nY = aMarkRange.aEnd.Row(); 1384 1385 if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) ) 1386 pViewData->SetDragMode( 1387 aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX ); 1388 else 1389 pViewData->SetFillMode( 1390 aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY ); 1391 1392 // #108266# The simple selection must also be recognized when dragging, 1393 // where the Marking flag is set and MarkToSimple won't work anymore. 1394 pViewData->GetMarkData().MarkToSimple(); 1395 } 1396 bNewPointer = sal_True; 1397 } 1398 } 1399 } 1400 1401 // Embedded-Rechteck 1402 1403 if (pDoc->IsEmbedded()) 1404 { 1405 ScRange aRange; 1406 pDoc->GetEmbedded( aRange ); 1407 if ( pViewData->GetTabNo() == aRange.aStart.Tab() ) 1408 { 1409 Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich ); 1410 Point aEndPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich ); 1411 Point aMousePos = rMEvt.GetPosPixel(); 1412 if ( bLayoutRTL ) 1413 { 1414 aStartPos.X() += 2; 1415 aEndPos.X() += 2; 1416 } 1417 sal_Bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 && 1418 aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 ); 1419 sal_Bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 && 1420 aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 ); 1421 if ( bTop || bBottom ) 1422 { 1423 SetPointer( Pointer( POINTER_CROSS ) ); 1424 if (bAction) 1425 { 1426 sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB; 1427 pViewData->SetDragMode( 1428 aRange.aStart.Col(), aRange.aStart.Row(), 1429 aRange.aEnd.Col(), aRange.aEnd.Row(), nMode ); 1430 } 1431 bNewPointer = sal_True; 1432 } 1433 } 1434 } 1435 } 1436 1437 if (!bNewPointer && bAction) 1438 { 1439 // SetPointer( POINTER_ARROW ); // in Fu... 1440 pViewData->ResetFillMode(); 1441 } 1442 1443 return bNewPointer; 1444 } 1445 1446 void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt ) 1447 { 1448 nNestedButtonState = SC_NESTEDBUTTON_DOWN; 1449 1450 HandleMouseButtonDown( rMEvt ); 1451 1452 if ( nNestedButtonState == SC_NESTEDBUTTON_UP ) 1453 { 1454 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule, 1455 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case, 1456 // simulate another MouseButtonUp call, so the selection state is consistent. 1457 1458 nButtonDown = rMEvt.GetButtons(); 1459 FakeButtonUp(); 1460 1461 if ( IsTracking() ) 1462 EndTracking(); // normally done in VCL as part of MouseButtonUp handling 1463 } 1464 nNestedButtonState = SC_NESTEDBUTTON_NONE; 1465 } 1466 1467 void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt ) 1468 { 1469 // We have to check if a context menu is shown and we have an UI 1470 // active inplace client. In that case we have to ignore the event. 1471 // Otherwise we would crash (context menu has been 1472 // opened by inplace client and we would deactivate the inplace client, 1473 // the contex menu is closed by VCL asynchronously which in the end 1474 // would work on deleted objects or the context menu has no parent anymore) 1475 // See #126086# and #128122# 1476 SfxViewShell* pViewSh = pViewData->GetViewShell(); 1477 SfxInPlaceClient* pClient = pViewSh->GetIPClient(); 1478 if ( pClient && 1479 pClient->IsObjectInPlaceActive() && 1480 PopupMenu::IsInExecute() ) 1481 return; 1482 1483 aCurMousePos = rMEvt.GetPosPixel(); 1484 1485 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick 1486 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig: 1487 #if 0 1488 // merken, dass FilterBox geloescht wird, damit sichergestellt 1489 // ist, dass in diesem Handler nicht an gleicher Stelle wieder 1490 // eine neue geoeffnet wird. 1491 sal_Bool bWasFilterBox = ( pFilterBox != NULL && 1492 ((Window*)pFilterBox)->IsVisible() && 1493 !pFilterBox->IsDataSelect() ); 1494 SCCOL nOldColFBox = bWasFilterBox ? pFilterBox->GetCol() : 0; 1495 SCROW nOldRowFBox = bWasFilterBox ? pFilterBox->GetRow() : 0; 1496 #endif 1497 1498 ClickExtern(); // loescht FilterBox, wenn vorhanden 1499 1500 HideNoteMarker(); // Notiz-Anzeige 1501 1502 bEEMouse = sal_False; 1503 1504 ScModule* pScMod = SC_MOD(); 1505 if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) 1506 { 1507 Sound::Beep(); 1508 return; 1509 } 1510 1511 pScActiveViewShell = pViewData->GetViewShell(); // falls auf Link geklickt wird 1512 nScClickMouseModifier = rMEvt.GetModifier(); // um Control-Klick immer zu erkennen 1513 1514 sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell(); 1515 sal_Bool bRefMode = pViewData->IsRefMode(); // Referenz angefangen 1516 sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz 1517 sal_Bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE 1518 sal_Bool bDouble = (rMEvt.GetClicks() == 2); 1519 1520 // DeactivateIP passiert nur noch bei MarkListHasChanged 1521 1522 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen 1523 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter) 1524 1525 if ( !nButtonDown || !bDouble ) // single (first) click is always valid 1526 nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works 1527 1528 // pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus(); 1529 if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode ) 1530 GrabFocus(); 1531 1532 // #i31846# need to cancel a double click if the first click has set the "ignore" state, 1533 // but a single (first) click is always valid 1534 if ( nMouseStatus == SC_GM_IGNORE && bDouble ) 1535 { 1536 nButtonDown = 0; 1537 nMouseStatus = SC_GM_NONE; 1538 return; 1539 } 1540 1541 if ( bDetective ) // Detektiv-Fuell-Modus 1542 { 1543 if ( rMEvt.IsLeft() && !rMEvt.GetModifier() ) 1544 { 1545 Point aPos = rMEvt.GetPosPixel(); 1546 SCsCOL nPosX; 1547 SCsROW nPosY; 1548 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 1549 1550 SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX ); 1551 SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY ); 1552 pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 1553 &aPosXItem, &aPosYItem, (void*)0L ); 1554 1555 } 1556 nButtonDown = 0; 1557 nMouseStatus = SC_GM_NONE; 1558 return; 1559 } 1560 1561 if (!bDouble) 1562 nMouseStatus = SC_GM_NONE; 1563 1564 if (!bFormulaMode) 1565 { 1566 if ( pViewData->GetActivePart() != eWhich ) 1567 pViewData->GetView()->ActivatePart( eWhich ); 1568 } 1569 else 1570 { 1571 ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine(); 1572 pSelEng->SetWindow(this); 1573 pSelEng->SetWhich(eWhich); 1574 pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) ); 1575 } 1576 1577 if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo())) 1578 { 1579 Point aPos = rMEvt.GetPosPixel(); 1580 SCsCOL nPosX; 1581 SCsROW nPosY; 1582 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 1583 1584 EditView* pEditView; 1585 SCCOL nEditCol; 1586 SCROW nEditRow; 1587 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 1588 SCCOL nEndCol = pViewData->GetEditEndCol(); 1589 SCROW nEndRow = pViewData->GetEditEndRow(); 1590 1591 if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol && 1592 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow ) 1593 { 1594 // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen 1595 if (bFormulaMode) // sonst ist es oben schon passiert 1596 GrabFocus(); 1597 1598 pScMod->SetInputMode( SC_INPUT_TABLE ); 1599 bEEMouse = sal_True; 1600 bEditMode = pEditView->MouseButtonDown( rMEvt ); 1601 return; 1602 } 1603 } 1604 1605 if (pScMod->GetIsWaterCan()) 1606 { 1607 //! was is mit'm Mac ??? 1608 if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT ) 1609 { 1610 nMouseStatus = SC_GM_WATERUNDO; 1611 return; 1612 } 1613 } 1614 1615 // Reihenfolge passend zum angezeigten Cursor: 1616 // RangeFinder, AutoFill, PageBreak, Drawing 1617 1618 if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) ) 1619 { 1620 bRFMouse = sal_True; // die anderen Variablen sind oben initialisiert 1621 1622 if ( pViewData->GetActivePart() != eWhich ) 1623 pViewData->GetView()->ActivatePart( eWhich ); //! schon oben immer ??? 1624 1625 // CaptureMouse(); 1626 StartTracking(); 1627 return; 1628 } 1629 1630 sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True ); 1631 if ( bCrossPointer ) 1632 { 1633 if ( bDouble ) 1634 pViewData->GetView()->FillCrossDblClick(); 1635 else 1636 pScMod->InputEnterHandler(); // Autofill etc. 1637 } 1638 1639 if ( !bCrossPointer ) 1640 { 1641 nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource, 1642 &nPagebreakBreak, &nPagebreakPrev ); 1643 if (nPagebreakMouse) 1644 { 1645 bPagebreakDrawn = sal_False; 1646 // CaptureMouse(); 1647 StartTracking(); 1648 PagebreakMove( rMEvt, sal_False ); 1649 return; 1650 } 1651 } 1652 1653 if (!bFormulaMode && !bEditMode && rMEvt.IsLeft()) 1654 { 1655 if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) ) 1656 { 1657 //if (DrawHasMarkedObj()) 1658 // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert 1659 return; 1660 } 1661 1662 pViewData->GetViewShell()->SetDrawShell( sal_False ); // kein Draw-Objekt selektiert 1663 1664 // TestMouse schon oben passiert 1665 } 1666 1667 Point aPos = rMEvt.GetPosPixel(); 1668 SCsCOL nPosX; 1669 SCsROW nPosY; 1670 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 1671 SCTAB nTab = pViewData->GetTabNo(); 1672 ScDocument* pDoc = pViewData->GetDocument(); 1673 1674 1675 // 1676 // AutoFilter buttons 1677 // 1678 1679 if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() ) 1680 { 1681 ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*) 1682 pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG ); 1683 if (pAttr->HasAutoFilter()) 1684 { 1685 SC_MOD()->InputEnterHandler(); //Add for i85305 1686 if (DoAutoFilterButton(nPosX, nPosY, rMEvt)) 1687 return; 1688 } 1689 if (pAttr->HasButton()) 1690 { 1691 DoPushButton( nPosX, nPosY, rMEvt ); // setzt evtl. bPivotMouse / bDPMouse 1692 return; 1693 } 1694 1695 // List Validity drop-down button 1696 1697 if ( bListValButton ) 1698 { 1699 Rectangle aButtonRect = GetListValButtonRect( aListValPos ); 1700 if ( aButtonRect.IsInside( aPos ) ) 1701 { 1702 DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), sal_True ); 1703 1704 nMouseStatus = SC_GM_FILTER; // not set in DoAutoFilterMenue for bDataSelect 1705 CaptureMouse(); 1706 return; 1707 } 1708 } 1709 } 1710 1711 // 1712 // scenario selection 1713 // 1714 1715 ScRange aScenRange; 1716 if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) ) 1717 { 1718 DoScenarioMenue( aScenRange ); 1719 return; 1720 } 1721 1722 // 1723 // Doppelklick angefangen ? 1724 // 1725 1726 // StopMarking kann aus DrawMouseButtonDown gerufen werden 1727 1728 if ( nMouseStatus != SC_GM_IGNORE && !bRefMode ) 1729 { 1730 if ( bDouble && !bCrossPointer ) 1731 { 1732 if (nMouseStatus == SC_GM_TABDOWN) 1733 nMouseStatus = SC_GM_DBLDOWN; 1734 } 1735 else 1736 nMouseStatus = SC_GM_TABDOWN; 1737 } 1738 1739 // 1740 // Links in Edit-Zellen 1741 // 1742 1743 sal_Bool bAlt = rMEvt.IsMod2(); 1744 if ( !bAlt && rMEvt.IsLeft() && 1745 GetEditUrl(rMEvt.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen 1746 { 1747 SetPointer( Pointer( POINTER_REFHAND ) ); 1748 nMouseStatus = SC_GM_URLDOWN; // auch nur dann beim ButtonUp ausfuehren 1749 return; 1750 } 1751 1752 // 1753 // Gridwin - SelectionEngine 1754 // 1755 1756 if ( rMEvt.IsLeft() ) 1757 { 1758 ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine(); 1759 pSelEng->SetWindow(this); 1760 pSelEng->SetWhich(eWhich); 1761 pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) ); 1762 1763 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag 1764 if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) ) 1765 { 1766 if (IsMouseCaptured()) 1767 { 1768 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann 1769 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?! 1770 ReleaseMouse(); 1771 StartTracking(); 1772 } 1773 pViewData->GetMarkData().SetMarking(sal_True); 1774 return; 1775 } 1776 } 1777 } 1778 1779 void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) 1780 { 1781 aCurMousePos = rMEvt.GetPosPixel(); 1782 ScDocument* pDoc = pViewData->GetDocument(); 1783 ScMarkData& rMark = pViewData->GetMarkData(); 1784 1785 // #i41690# detect a MouseButtonUp call from within MouseButtonDown 1786 // (possible through Reschedule from storing an OLE object that is deselected) 1787 1788 if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN ) 1789 nNestedButtonState = SC_NESTEDBUTTON_UP; 1790 1791 if (nButtonDown != rMEvt.GetButtons()) 1792 nMouseStatus = SC_GM_IGNORE; // reset und return 1793 1794 nButtonDown = 0; 1795 1796 if (nMouseStatus == SC_GM_IGNORE) 1797 { 1798 nMouseStatus = SC_GM_NONE; 1799 // Selection-Engine: Markieren abbrechen 1800 pViewData->GetView()->GetSelEngine()->Reset(); 1801 rMark.SetMarking(sal_False); 1802 if (pViewData->IsAnyFillMode()) 1803 { 1804 pViewData->GetView()->StopRefMode(); 1805 pViewData->ResetFillMode(); 1806 } 1807 StopMarking(); 1808 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen 1809 ReleaseMouse(); 1810 return; 1811 } 1812 1813 if (nMouseStatus == SC_GM_FILTER) 1814 { 1815 if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) 1816 { 1817 if (mpFilterButton.get()) 1818 { 1819 bool bFilterActive = IsAutoFilterActive( 1820 pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() ); 1821 1822 mpFilterButton->setHasHiddenMember(bFilterActive); 1823 mpFilterButton->setPopupPressed(false); 1824 HideCursor(); 1825 mpFilterButton->draw(); 1826 ShowCursor(); 1827 } 1828 } 1829 nMouseStatus = SC_GM_NONE; 1830 ReleaseMouse(); 1831 return; // da muss nix mehr passieren 1832 } 1833 1834 ScModule* pScMod = SC_MOD(); 1835 if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) 1836 return; 1837 1838 SfxBindings& rBindings = pViewData->GetBindings(); 1839 if (bEEMouse && pViewData->HasEditView( eWhich )) 1840 { 1841 EditView* pEditView; 1842 SCCOL nEditCol; 1843 SCROW nEditRow; 1844 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 1845 pEditView->MouseButtonUp( rMEvt ); 1846 1847 if ( rMEvt.IsMiddle() && 1848 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) 1849 { 1850 // EditView may have pasted from selection 1851 pScMod->InputChanged( pEditView ); 1852 } 1853 else 1854 pScMod->InputSelection( pEditView ); // parentheses etc. 1855 1856 pViewData->GetView()->InvalidateAttribs(); 1857 rBindings.Invalidate( SID_HYPERLINK_GETLINK ); 1858 bEEMouse = sal_False; 1859 return; 1860 } 1861 1862 if (bDPMouse) 1863 { 1864 DPMouseButtonUp( rMEvt ); // resets bDPMouse 1865 return; 1866 } 1867 1868 if (bRFMouse) 1869 { 1870 RFMouseMove( rMEvt, sal_True ); // Range wieder richtigherum 1871 bRFMouse = sal_False; 1872 SetPointer( Pointer( POINTER_ARROW ) ); 1873 ReleaseMouse(); 1874 return; 1875 } 1876 1877 if (nPagebreakMouse) 1878 { 1879 PagebreakMove( rMEvt, sal_True ); 1880 nPagebreakMouse = SC_PD_NONE; 1881 SetPointer( Pointer( POINTER_ARROW ) ); 1882 ReleaseMouse(); 1883 return; 1884 } 1885 1886 if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus 1887 { 1888 ::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager(); 1889 if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE ) 1890 pMgr->Undo(); 1891 else 1892 Sound::Beep(); 1893 return; 1894 } 1895 1896 if (DrawMouseButtonUp(rMEvt)) // includes format paint brush handling for drawing objects 1897 return; 1898 1899 rMark.SetMarking(sal_False); 1900 1901 SetPointer( Pointer( POINTER_ARROW ) ); 1902 1903 if (pViewData->IsFillMode() || 1904 ( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() )) 1905 { 1906 nScFillModeMouseModifier = rMEvt.GetModifier(); 1907 SCCOL nStartCol; 1908 SCROW nStartRow; 1909 SCCOL nEndCol; 1910 SCROW nEndRow; 1911 pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow ); 1912 // DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(), 1913 // "Block falsch fuer AutoFill" ); 1914 ScRange aDelRange; 1915 sal_Bool bIsDel = pViewData->GetDelMark( aDelRange ); 1916 1917 ScViewFunc* pView = pViewData->GetView(); 1918 pView->StopRefMode(); 1919 pViewData->ResetFillMode(); 1920 pView->GetFunctionSet()->SetAnchorFlag( sal_False ); // #i5819# don't use AutoFill anchor flag for selection 1921 1922 if ( bIsDel ) 1923 { 1924 pView->MarkRange( aDelRange, sal_False ); 1925 pView->DeleteContents( IDF_CONTENTS ); 1926 SCTAB nTab = pViewData->GetTabNo(); 1927 ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ); 1928 if ( aBlockRange != aDelRange ) 1929 { 1930 if ( aDelRange.aStart.Row() == nStartRow ) 1931 aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 ); 1932 else 1933 aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 ); 1934 pView->MarkRange( aBlockRange, sal_False ); 1935 } 1936 } 1937 else 1938 pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); 1939 } 1940 else if (pViewData->GetFillMode() == SC_FILL_MATRIX) 1941 { 1942 SCTAB nTab = pViewData->GetTabNo(); 1943 SCCOL nStartCol; 1944 SCROW nStartRow; 1945 SCCOL nEndCol; 1946 SCROW nEndRow; 1947 pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow ); 1948 ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ); 1949 SCCOL nFillCol = pViewData->GetRefEndX(); 1950 SCROW nFillRow = pViewData->GetRefEndY(); 1951 ScAddress aEndPos( nFillCol, nFillRow, nTab ); 1952 1953 ScTabView* pView = pViewData->GetView(); 1954 pView->StopRefMode(); 1955 pViewData->ResetFillMode(); 1956 pView->GetFunctionSet()->SetAnchorFlag( sal_False ); 1957 1958 if ( aEndPos != aBlockRange.aEnd ) 1959 { 1960 pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, sal_False ); 1961 pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) ); 1962 } 1963 } 1964 else if (pViewData->IsAnyFillMode()) 1965 { 1966 // Embedded-Area has been changed 1967 ScTabView* pView = pViewData->GetView(); 1968 pView->StopRefMode(); 1969 pViewData->ResetFillMode(); 1970 pView->GetFunctionSet()->SetAnchorFlag( sal_False ); 1971 pViewData->GetDocShell()->UpdateOle(pViewData); 1972 } 1973 1974 sal_Bool bRefMode = pViewData->IsRefMode(); 1975 if (bRefMode) 1976 pScMod->EndReference(); 1977 1978 // 1979 // Giesskannen-Modus (Gestalter) 1980 // 1981 1982 if (pScMod->GetIsWaterCan()) 1983 { 1984 // Abfrage auf Undo schon oben 1985 1986 ScStyleSheetPool* pStylePool = (ScStyleSheetPool*) 1987 (pViewData->GetDocument()-> 1988 GetStyleSheetPool()); 1989 if ( pStylePool ) 1990 { 1991 SfxStyleSheet* pStyleSheet = (SfxStyleSheet*) 1992 pStylePool->GetActualStyleSheet(); 1993 1994 if ( pStyleSheet ) 1995 { 1996 SfxStyleFamily eFamily = pStyleSheet->GetFamily(); 1997 1998 switch ( eFamily ) 1999 { 2000 case SFX_STYLE_FAMILY_PARA: 2001 pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet ); 2002 pViewData->GetView()->DoneBlockMode(); 2003 break; 2004 2005 case SFX_STYLE_FAMILY_PAGE: 2006 pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(), 2007 pStyleSheet->GetName() ); 2008 2009 ScPrintFunc( pViewData->GetDocShell(), 2010 pViewData->GetViewShell()->GetPrinter(sal_True), 2011 pViewData->GetTabNo() ).UpdatePages(); 2012 2013 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); 2014 break; 2015 2016 default: 2017 break; 2018 } 2019 } 2020 } 2021 } 2022 2023 ScDBFunc* pView = pViewData->GetView(); 2024 ScDocument* pBrushDoc = pView->GetBrushDocument(); 2025 if ( pBrushDoc ) 2026 { 2027 pView->PasteFromClip( IDF_ATTRIB, pBrushDoc ); 2028 if ( !pView->IsPaintBrushLocked() ) 2029 pView->ResetBrushDocument(); // invalidates pBrushDoc pointer 2030 } 2031 2032 // 2033 // double click (only left button) 2034 // 2035 2036 sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() ); 2037 if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() ) 2038 { 2039 // data pilot table 2040 Point aPos = rMEvt.GetPosPixel(); 2041 SCsCOL nPosX; 2042 SCsROW nPosY; 2043 SCTAB nTab = pViewData->GetTabNo(); 2044 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 2045 ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab ); 2046 if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() ) 2047 { 2048 ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() ); 2049 2050 // Check for header drill-down first. 2051 sheet::DataPilotTableHeaderData aData; 2052 pDPObj->GetHeaderPositionData(aCellPos, aData); 2053 2054 if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) && 2055 ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) ) 2056 { 2057 sal_uInt16 nDummy; 2058 if ( pView->HasSelectionForDrillDown( nDummy ) ) 2059 { 2060 // execute slot to show dialog 2061 pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); 2062 } 2063 else 2064 { 2065 // toggle single entry 2066 ScDPObject aNewObj( *pDPObj ); 2067 pDPObj->ToggleDetails( aData, &aNewObj ); 2068 ScDBDocFunc aFunc( *pViewData->GetDocShell() ); 2069 aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False ); 2070 pViewData->GetView()->CursorPosChanged(); // shells may be switched 2071 } 2072 } 2073 else 2074 { 2075 // Check if the data area is double-clicked. 2076 2077 Sequence<sheet::DataPilotFieldFilter> aFilters; 2078 if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) ) 2079 pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters ); 2080 else 2081 Sound::Beep(); // nothing to expand/collapse/show 2082 } 2083 2084 return; 2085 } 2086 2087 // Check for cell protection attribute. 2088 ScTableProtection* pProtect = pDoc->GetTabProtection( nTab ); 2089 bool bEditAllowed = true; 2090 if ( pProtect && pProtect->isProtected() ) 2091 { 2092 bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED); 2093 bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); 2094 bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); 2095 2096 if ( bSkipProtected && bSkipUnprotected ) 2097 bEditAllowed = false; 2098 else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) ) 2099 bEditAllowed = false; 2100 } 2101 2102 if ( bEditAllowed ) 2103 { 2104 // edit cell contents 2105 pViewData->GetViewShell()->UpdateInputHandler(); 2106 pScMod->SetInputMode( SC_INPUT_TABLE ); 2107 if (pViewData->HasEditView(eWhich)) 2108 { 2109 // Text-Cursor gleich an die geklickte Stelle setzen 2110 EditView* pEditView = pViewData->GetEditView( eWhich ); 2111 MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 ); 2112 pEditView->MouseButtonDown( aEditEvt ); 2113 pEditView->MouseButtonUp( aEditEvt ); 2114 } 2115 } 2116 return; 2117 } 2118 2119 // 2120 // Links in edit cells 2121 // 2122 2123 sal_Bool bAlt = rMEvt.IsMod2(); 2124 if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN ) 2125 { 2126 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war 2127 2128 String aName, aUrl, aTarget; 2129 if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) ) 2130 { 2131 nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen 2132 ScGlobal::OpenURL( aUrl, aTarget ); 2133 2134 // fire worksheet_followhyperlink event 2135 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor(); 2136 if( xVbaEvents.is() ) try 2137 { 2138 Point aPos = rMEvt.GetPosPixel(); 2139 SCsCOL nPosX; 2140 SCsROW nPosY; 2141 SCTAB nTab = pViewData->GetTabNo(); 2142 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 2143 ScBaseCell* pCell = NULL; 2144 if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) ) 2145 { 2146 ScAddress aCellPos( nPosX, nPosY, nTab ); 2147 uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) ); 2148 uno::Sequence< uno::Any > aArgs(1); 2149 aArgs[0] <<= xCell; 2150 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs ); 2151 } 2152 } 2153 catch( uno::Exception& ) 2154 { 2155 } 2156 2157 return; 2158 } 2159 } 2160 2161 // 2162 // Gridwin - SelectionEngine 2163 // 2164 2165 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return 2166 // sal_True for any call, so IsLeft must be checked here, too. 2167 2168 if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) ) 2169 { 2170 // rMark.MarkToSimple(); 2171 pViewData->GetView()->UpdateAutoFillMark(); 2172 2173 SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher(); 2174 sal_Bool bFormulaMode = pScMod->IsFormulaMode(); 2175 DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" ); 2176 2177 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no 2178 // multiple selection, so the argument string completely describes the selection, 2179 // and executing the slot won't change the existing selection (executing the slot 2180 // here and from a recorded macro is treated equally) 2181 2182 if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() ) 2183 { 2184 String aAddr; // CurrentCell 2185 if( rMark.IsMarked() ) 2186 { 2187 // sal_Bool bKeep = rMark.IsMultiMarked(); //! wohin damit ??? 2188 2189 ScRange aScRange; 2190 rMark.GetMarkArea( aScRange ); 2191 aScRange.Format( aAddr, SCR_ABS ); 2192 if ( aScRange.aStart == aScRange.aEnd ) 2193 { 2194 // make sure there is a range selection string even for a single cell 2195 String aSingle = aAddr; 2196 aAddr.Append( (sal_Char) ':' ); 2197 aAddr.Append( aSingle ); 2198 } 2199 2200 //! SID_MARKAREA gibts nicht mehr ??? 2201 //! was passiert beim Markieren mit dem Cursor ??? 2202 } 2203 else // nur Cursor bewegen 2204 { 2205 ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 ); 2206 aScAddress.Format( aAddr, SCA_ABS ); 2207 } 2208 2209 SfxStringItem aPosItem( SID_CURRENTCELL, aAddr ); 2210 pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 2211 &aPosItem, (void*)0L ); 2212 2213 pViewData->GetView()->InvalidateAttribs(); 2214 } 2215 return; 2216 } 2217 } 2218 2219 void ScGridWindow::FakeButtonUp() 2220 { 2221 if ( nButtonDown ) 2222 { 2223 MouseEvent aEvent( aCurMousePos ); // nButtons = 0 -> ignore 2224 MouseButtonUp( aEvent ); 2225 } 2226 } 2227 2228 void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt ) 2229 { 2230 aCurMousePos = rMEvt.GetPosPixel(); 2231 2232 if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() ) 2233 HideNoteMarker(); 2234 2235 ScModule* pScMod = SC_MOD(); 2236 if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) 2237 return; 2238 2239 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider 2240 // nicht anders mit: 2241 2242 if (bEEMouse && nButtonDown && !rMEvt.GetButtons()) 2243 { 2244 bEEMouse = sal_False; 2245 nButtonDown = 0; 2246 nMouseStatus = SC_GM_NONE; 2247 return; 2248 } 2249 2250 if (nMouseStatus == SC_GM_IGNORE) 2251 return; 2252 2253 if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus -> nur auf Up warten 2254 return; 2255 2256 if ( pViewData->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus 2257 { 2258 SetPointer( Pointer( POINTER_FILL ) ); 2259 return; 2260 } 2261 2262 if (nMouseStatus == SC_GM_FILTER && pFilterBox) 2263 { 2264 Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); 2265 if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) ) 2266 { 2267 nButtonDown = 0; 2268 nMouseStatus = SC_GM_NONE; 2269 if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) 2270 { 2271 if (mpFilterButton.get()) 2272 { 2273 mpFilterButton->setHasHiddenMember(false); 2274 mpFilterButton->setPopupPressed(false); 2275 HideCursor(); 2276 mpFilterButton->draw(); 2277 ShowCursor(); 2278 } 2279 } 2280 ReleaseMouse(); 2281 pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) ); 2282 return; 2283 } 2284 } 2285 2286 sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz 2287 2288 if (bEEMouse && pViewData->HasEditView( eWhich )) 2289 { 2290 EditView* pEditView; 2291 SCCOL nEditCol; 2292 SCROW nEditRow; 2293 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 2294 pEditView->MouseMove( rMEvt ); 2295 return; 2296 } 2297 2298 if (bDPMouse) 2299 { 2300 DPMouseMove( rMEvt ); 2301 return; 2302 } 2303 2304 if (bRFMouse) 2305 { 2306 RFMouseMove( rMEvt, sal_False ); 2307 return; 2308 } 2309 2310 if (nPagebreakMouse) 2311 { 2312 PagebreakMove( rMEvt, sal_False ); 2313 return; 2314 } 2315 2316 // anderen Mauszeiger anzeigen? 2317 2318 sal_Bool bEditMode = pViewData->HasEditView(eWhich); 2319 2320 //! Testen ob RefMode-Dragging !!! 2321 if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) ) 2322 { 2323 Point aPos = rMEvt.GetPosPixel(); 2324 SCsCOL nPosX; 2325 SCsROW nPosY; 2326 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 2327 2328 EditView* pEditView; 2329 SCCOL nEditCol; 2330 SCROW nEditRow; 2331 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 2332 SCCOL nEndCol = pViewData->GetEditEndCol(); 2333 SCROW nEndRow = pViewData->GetEditEndRow(); 2334 2335 if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol && 2336 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow ) 2337 { 2338 // Field can only be URL field 2339 sal_Bool bAlt = rMEvt.IsMod2(); 2340 if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() ) 2341 SetPointer( Pointer( POINTER_REFHAND ) ); 2342 else if ( pEditView && pEditView->GetEditEngine()->IsVertical() ) 2343 SetPointer( Pointer( POINTER_TEXT_VERTICAL ) ); 2344 else 2345 SetPointer( Pointer( POINTER_TEXT ) ); 2346 return; 2347 } 2348 } 2349 2350 sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush(); 2351 if (bWater) 2352 SetPointer( Pointer(POINTER_FILL) ); 2353 2354 if (!bWater) 2355 { 2356 sal_Bool bCross = sal_False; 2357 2358 // Range-Finder 2359 2360 sal_Bool bCorner; 2361 if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) ) 2362 { 2363 if (bCorner) 2364 SetPointer( Pointer( POINTER_CROSS ) ); 2365 else 2366 SetPointer( Pointer( POINTER_HAND ) ); 2367 bCross = sal_True; 2368 } 2369 2370 // Page-Break-Modus 2371 2372 sal_uInt16 nBreakType; 2373 if ( !nButtonDown && pViewData->IsPagebreakMode() && 2374 ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 ) 2375 { 2376 PointerStyle eNew = POINTER_ARROW; 2377 switch ( nBreakType ) 2378 { 2379 case SC_PD_RANGE_L: 2380 case SC_PD_RANGE_R: 2381 case SC_PD_BREAK_H: 2382 eNew = POINTER_ESIZE; 2383 break; 2384 case SC_PD_RANGE_T: 2385 case SC_PD_RANGE_B: 2386 case SC_PD_BREAK_V: 2387 eNew = POINTER_SSIZE; 2388 break; 2389 case SC_PD_RANGE_TL: 2390 case SC_PD_RANGE_BR: 2391 eNew = POINTER_SESIZE; 2392 break; 2393 case SC_PD_RANGE_TR: 2394 case SC_PD_RANGE_BL: 2395 eNew = POINTER_NESIZE; 2396 break; 2397 } 2398 SetPointer( Pointer( eNew ) ); 2399 bCross = sal_True; 2400 } 2401 2402 // Fill-Cursor anzeigen ? 2403 2404 if ( !bFormulaMode && !nButtonDown ) 2405 if (TestMouse( rMEvt, sal_False )) 2406 bCross = sal_True; 2407 2408 if ( nButtonDown && pViewData->IsAnyFillMode() ) 2409 { 2410 SetPointer( Pointer( POINTER_CROSS ) ); 2411 bCross = sal_True; 2412 nScFillModeMouseModifier = rMEvt.GetModifier(); // ausgewertet bei AutoFill und Matrix 2413 } 2414 2415 if (!bCross) 2416 { 2417 sal_Bool bAlt = rMEvt.IsMod2(); 2418 2419 if (bEditMode) // Edit-Mode muss zuerst kommen! 2420 SetPointer( Pointer( POINTER_ARROW ) ); 2421 else if ( !bAlt && !nButtonDown && 2422 GetEditUrl(rMEvt.GetPosPixel()) ) 2423 SetPointer( Pointer( POINTER_REFHAND ) ); 2424 else if ( DrawMouseMove(rMEvt) ) // setzt Pointer um 2425 return; 2426 } 2427 } 2428 2429 if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) ) 2430 return; 2431 } 2432 2433 void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt ) 2434 { 2435 rEvent.Modifiers = 0; 2436 if ( rEvt.IsShift() ) 2437 rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT; 2438 if ( rEvt.IsMod1() ) 2439 rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1; 2440 if ( rEvt.IsMod2() ) 2441 rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2; 2442 if ( rEvt.IsMod3() ) 2443 rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3; 2444 2445 rEvent.Buttons = 0; 2446 if ( rEvt.IsLeft() ) 2447 rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT; 2448 if ( rEvt.IsRight() ) 2449 rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT; 2450 if ( rEvt.IsMiddle() ) 2451 rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE; 2452 2453 rEvent.X = rEvt.GetPosPixel().X(); 2454 rEvent.Y = rEvt.GetPosPixel().Y(); 2455 rEvent.ClickCount = rEvt.GetClicks(); 2456 rEvent.PopupTrigger = sal_False; 2457 } 2458 2459 long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) 2460 { 2461 bool bDone = false; 2462 sal_uInt16 nType = rNEvt.GetType(); 2463 if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN ) 2464 { 2465 Window* pWindow = rNEvt.GetWindow(); 2466 if (pWindow == this && pViewData) 2467 { 2468 SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame(); 2469 if (pViewFrame) 2470 { 2471 com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController(); 2472 if (xController.is()) 2473 { 2474 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); 2475 if (pImp && pImp->IsMouseListening()) 2476 { 2477 ::com::sun::star::awt::MouseEvent aEvent; 2478 lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); 2479 if ( rNEvt.GetWindow() ) 2480 aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); 2481 if ( nType == EVENT_MOUSEBUTTONDOWN) 2482 bDone = pImp->MousePressed( aEvent ); 2483 else 2484 bDone = pImp->MouseReleased( aEvent ); 2485 } 2486 } 2487 } 2488 } 2489 } 2490 if (bDone) // event consumed by a listener 2491 { 2492 if ( nType == EVENT_MOUSEBUTTONDOWN ) 2493 { 2494 const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent(); 2495 if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 ) 2496 { 2497 // If a listener returned true for a right-click call, also prevent opening the context menu 2498 // (this works only if the context menu is opened on mouse-down) 2499 nMouseStatus = SC_GM_IGNORE; 2500 } 2501 } 2502 2503 return 1; 2504 } 2505 else 2506 return Window::PreNotify( rNEvt ); 2507 } 2508 2509 void ScGridWindow::Tracking( const TrackingEvent& rTEvt ) 2510 { 2511 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf 2512 // die verschiedenen MouseHandler verteilen... 2513 2514 const MouseEvent& rMEvt = rTEvt.GetMouseEvent(); 2515 2516 if ( rTEvt.IsTrackingCanceled() ) // alles abbrechen... 2517 { 2518 if (!pViewData->GetView()->IsInActivatePart()) 2519 { 2520 if (bDPMouse) 2521 bDPMouse = sal_False; // gezeichnet wird per bDragRect 2522 if (bDragRect) 2523 { 2524 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 2525 bDragRect = sal_False; 2526 UpdateDragRectOverlay(); 2527 } 2528 if (bRFMouse) 2529 { 2530 RFMouseMove( rMEvt, sal_True ); // richtig abbrechen geht dabei nicht... 2531 bRFMouse = sal_False; 2532 } 2533 if (nPagebreakMouse) 2534 { 2535 // if (bPagebreakDrawn) 2536 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(), 2537 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False ); 2538 bPagebreakDrawn = sal_False; 2539 UpdateDragRectOverlay(); 2540 nPagebreakMouse = SC_PD_NONE; 2541 } 2542 2543 SetPointer( Pointer( POINTER_ARROW ) ); 2544 StopMarking(); 2545 MouseButtonUp( rMEvt ); // mit Status SC_GM_IGNORE aus StopMarking 2546 2547 sal_Bool bRefMode = pViewData->IsRefMode(); 2548 if (bRefMode) 2549 SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen 2550 } 2551 } 2552 else if ( rTEvt.IsTrackingEnded() ) 2553 { 2554 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#) 2555 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht 2556 // abgebrochen wurde. 2557 2558 MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(), 2559 rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() ); 2560 MouseButtonUp( aUpEvt ); 2561 } 2562 else 2563 MouseMove( rMEvt ); 2564 } 2565 2566 void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) 2567 { 2568 if ( pFilterBox || nPagebreakMouse ) 2569 return; 2570 2571 HideNoteMarker(); 2572 2573 CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True ); 2574 2575 if (bEEMouse && pViewData->HasEditView( eWhich )) 2576 { 2577 EditView* pEditView; 2578 SCCOL nEditCol; 2579 SCROW nEditRow; 2580 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 2581 2582 // #63263# don't remove the edit view while switching views 2583 ScModule* pScMod = SC_MOD(); 2584 pScMod->SetInEditCommand( sal_True ); 2585 2586 pEditView->Command( aDragEvent ); 2587 2588 ScInputHandler* pHdl = pScMod->GetInputHdl(); 2589 if (pHdl) 2590 pHdl->DataChanged(); 2591 2592 pScMod->SetInEditCommand( sal_False ); 2593 if (!pViewData->IsActive()) // dropped to different view? 2594 { 2595 ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); 2596 if ( pViewHdl && pViewData->HasEditView( eWhich ) ) 2597 { 2598 pViewHdl->CancelHandler(); 2599 ShowCursor(); // missing from KillEditView 2600 } 2601 } 2602 } 2603 else 2604 if ( !DrawCommand(aDragEvent) ) 2605 pViewData->GetView()->GetSelEngine()->Command( aDragEvent ); 2606 } 2607 2608 void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin ) 2609 { 2610 SCCOL nCol = pViewData->GetCurX(); 2611 SCROW nRow = pViewData->GetCurY(); 2612 Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True ); 2613 aEditArea.Right() = aEditArea.Left(); 2614 aEditArea = pWin->PixelToLogic( aEditArea ); 2615 pWin->SetCursorRect( &aEditArea ); 2616 } 2617 2618 void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) 2619 { 2620 // The command event is send to the window after a possible context 2621 // menu from an inplace client is closed. Now we have the chance to 2622 // deactivate the inplace client without any problem regarding parent 2623 // windows and code on the stack. 2624 // For more information, see #126086# and #128122# 2625 sal_uInt16 nCmd = rCEvt.GetCommand(); 2626 ScTabViewShell* pTabViewSh = pViewData->GetViewShell(); 2627 SfxInPlaceClient* pClient = pTabViewSh->GetIPClient(); 2628 if ( pClient && 2629 pClient->IsObjectInPlaceActive() && 2630 nCmd == COMMAND_CONTEXTMENU ) 2631 { 2632 pTabViewSh->DeactivateOle(); 2633 return; 2634 } 2635 2636 ScModule* pScMod = SC_MOD(); 2637 DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" ); 2638 2639 if ( nCmd == COMMAND_STARTEXTTEXTINPUT || 2640 nCmd == COMMAND_ENDEXTTEXTINPUT || 2641 nCmd == COMMAND_EXTTEXTINPUT || 2642 nCmd == COMMAND_CURSORPOS ) 2643 { 2644 sal_Bool bEditView = pViewData->HasEditView( eWhich ); 2645 if (!bEditView) 2646 { 2647 // only if no cell editview is active, look at drawview 2648 SdrView* pSdrView = pViewData->GetView()->GetSdrView(); 2649 if ( pSdrView ) 2650 { 2651 OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView(); 2652 if ( pOlView && pOlView->GetWindow() == this ) 2653 { 2654 pOlView->Command( rCEvt ); 2655 return; // done 2656 } 2657 } 2658 } 2659 2660 if ( nCmd == COMMAND_CURSORPOS && !bEditView ) 2661 { 2662 // #88458# CURSORPOS may be called without following text input, 2663 // to set the input method window position 2664 // -> input mode must not be started, 2665 // manually calculate text insert position if not in input mode 2666 2667 lcl_SetTextCursorPos( pViewData, eWhich, this ); 2668 return; 2669 } 2670 2671 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); 2672 if ( pHdl ) 2673 { 2674 pHdl->InputCommand( rCEvt, sal_True ); 2675 return; // done 2676 } 2677 2678 Window::Command( rCEvt ); 2679 return; 2680 } 2681 2682 if ( nCmd == COMMAND_VOICE ) 2683 { 2684 // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist, 2685 // also muss es eine EditView oder ein editiertes Zeichenobjekt geben 2686 2687 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); 2688 if ( pHdl && pViewData->HasEditView( eWhich ) ) 2689 { 2690 EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0 2691 pHdl->DataChanging(); 2692 pEditView->Command( rCEvt ); 2693 pHdl->DataChanged(); 2694 return; // erledigt 2695 } 2696 SdrView* pSdrView = pViewData->GetView()->GetSdrView(); 2697 if ( pSdrView ) 2698 { 2699 OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView(); 2700 if ( pOlView && pOlView->GetWindow() == this ) 2701 { 2702 pOlView->Command( rCEvt ); 2703 return; // erledigt 2704 } 2705 } 2706 Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern... 2707 return; 2708 } 2709 2710 if ( nCmd == COMMAND_PASTESELECTION ) 2711 { 2712 if ( bEEMouse ) 2713 { 2714 // EditEngine handles selection in MouseButtonUp - no action 2715 // needed in command handler 2716 } 2717 else 2718 { 2719 PasteSelection( rCEvt.GetMousePosPixel() ); 2720 } 2721 return; 2722 } 2723 2724 if ( nCmd == COMMAND_INPUTLANGUAGECHANGE ) 2725 { 2726 // #i55929# Font and font size state depends on input language if nothing is selected, 2727 // so the slots have to be invalidated when the input language is changed. 2728 2729 SfxBindings& rBindings = pViewData->GetBindings(); 2730 rBindings.Invalidate( SID_ATTR_CHAR_FONT ); 2731 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); 2732 return; 2733 } 2734 2735 if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL ) 2736 { 2737 sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich ); 2738 if (!bDone) 2739 Window::Command(rCEvt); 2740 return; 2741 } 2742 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input 2743 sal_Bool bDisable = pScMod->IsFormulaMode() || 2744 pScMod->IsModalMode(pViewData->GetSfxDocShell()); 2745 if (bDisable) 2746 return; 2747 2748 if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() ) 2749 { 2750 sal_Bool bMouse = rCEvt.IsMouseEvent(); 2751 if ( bMouse && nMouseStatus == SC_GM_IGNORE ) 2752 return; 2753 2754 if (pViewData->IsAnyFillMode()) 2755 { 2756 pViewData->GetView()->StopRefMode(); 2757 pViewData->ResetFillMode(); 2758 } 2759 ReleaseMouse(); 2760 StopMarking(); 2761 2762 Point aPosPixel = rCEvt.GetMousePosPixel(); 2763 Point aMenuPos = aPosPixel; 2764 2765 if ( bMouse ) 2766 { 2767 SCsCOL nCellX = -1; 2768 SCsROW nCellY = -1; 2769 pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY); 2770 ScDocument* pDoc = pViewData->GetDocument(); 2771 SCTAB nTab = pViewData->GetTabNo(); 2772 const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); 2773 bool bSelectAllowed = true; 2774 if ( pProtect && pProtect->isProtected() ) 2775 { 2776 // This sheet is protected. Check if a context menu is allowed on this cell. 2777 bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED); 2778 bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); 2779 bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); 2780 2781 if (bCellProtected) 2782 bSelectAllowed = bSelProtected; 2783 else 2784 bSelectAllowed = bSelUnprotected; 2785 } 2786 if (!bSelectAllowed) 2787 // Selecting this cell is not allowed, neither is context menu. 2788 return; 2789 2790 // #i18735# First select the item under the mouse pointer. 2791 // This can change the selection, and the view state (edit mode, etc). 2792 SelectForContextMenu( aPosPixel, nCellX, nCellY ); 2793 } 2794 2795 sal_Bool bDone = sal_False; 2796 sal_Bool bEdit = pViewData->HasEditView(eWhich); 2797 if ( !bEdit ) 2798 { 2799 // Edit-Zelle mit Spelling-Errors ? 2800 if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) ) 2801 { 2802 // GetEditUrlOrError hat den Cursor schon bewegt 2803 2804 pScMod->SetInputMode( SC_INPUT_TABLE ); 2805 bEdit = pViewData->HasEditView(eWhich); // hat's geklappt ? 2806 2807 DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" ); 2808 } 2809 } 2810 if ( bEdit ) 2811 { 2812 EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0 2813 2814 if ( !bMouse ) 2815 { 2816 Cursor* pCur = pEditView->GetCursor(); 2817 if ( pCur ) 2818 { 2819 Point aLogicPos = pCur->GetPos(); 2820 // use the position right of the cursor (spell popup is opened if 2821 // the cursor is before the word, but not if behind it) 2822 aLogicPos.X() += pCur->GetWidth(); 2823 aLogicPos.Y() += pCur->GetHeight() / 2; // center vertically 2824 aMenuPos = LogicToPixel( aLogicPos ); 2825 } 2826 } 2827 2828 // if edit mode was just started above, online spelling may be incomplete 2829 pEditView->GetEditEngine()->CompleteOnlineSpelling(); 2830 2831 // IsCursorAtWrongSpelledWord could be used for !bMouse 2832 // if there was a corresponding ExecuteSpellPopup call 2833 2834 if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) ) 2835 { 2836 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown 2837 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen 2838 // (Bug #40968#) 2839 ScInputHandler* pHdl = pScMod->GetInputHdl(); 2840 if (pHdl) 2841 pHdl->SetModified(); 2842 2843 Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl ); 2844 pEditView->ExecuteSpellPopup( aMenuPos, &aLink ); 2845 2846 bDone = sal_True; 2847 } 2848 } 2849 else if ( !bMouse ) 2850 { 2851 // non-edit menu by keyboard -> use lower right of cell cursor position 2852 2853 SCCOL nCurX = pViewData->GetCurX(); 2854 SCROW nCurY = pViewData->GetCurY(); 2855 aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True ); 2856 long nSizeXPix; 2857 long nSizeYPix; 2858 pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix ); 2859 aMenuPos.X() += nSizeXPix; 2860 aMenuPos.Y() += nSizeYPix; 2861 2862 if (pViewData) 2863 { 2864 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 2865 if (pViewSh) 2866 { 2867 // Is a draw object selected? 2868 2869 SdrView* pDrawView = pViewSh->GetSdrView(); 2870 if (pDrawView && pDrawView->AreObjectsMarked()) 2871 { 2872 // #100442#; the conext menu should open in the middle of the selected objects 2873 Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect())); 2874 aMenuPos = aSelectRect.Center(); 2875 } 2876 } 2877 } 2878 } 2879 2880 if (!bDone) 2881 { 2882 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos ); 2883 } 2884 } 2885 } 2886 2887 void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ) 2888 { 2889 // #i18735# if the click was outside of the current selection, 2890 // the cursor is moved or an object at the click position selected. 2891 // (see SwEditWin::SelectMenuPosition in Writer) 2892 2893 ScTabView* pView = pViewData->GetView(); 2894 ScDrawView* pDrawView = pView->GetScDrawView(); 2895 2896 // check cell edit mode 2897 2898 if ( pViewData->HasEditView(eWhich) ) 2899 { 2900 ScModule* pScMod = SC_MOD(); 2901 SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated 2902 SCROW nEditStartRow = pViewData->GetEditViewRow(); 2903 SCCOL nEditEndCol = pViewData->GetEditEndCol(); 2904 SCROW nEditEndRow = pViewData->GetEditEndRow(); 2905 2906 if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol && 2907 nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow ) 2908 { 2909 // handle selection within the EditView 2910 2911 EditView* pEditView = pViewData->GetEditView( eWhich ); // not NULL (HasEditView) 2912 EditEngine* pEditEngine = pEditView->GetEditEngine(); 2913 Rectangle aOutputArea = pEditView->GetOutputArea(); 2914 Rectangle aVisArea = pEditView->GetVisArea(); 2915 2916 Point aTextPos = PixelToLogic( rPosPixel ); 2917 if ( pEditEngine->IsVertical() ) // have to manually transform position 2918 { 2919 aTextPos -= aOutputArea.TopRight(); 2920 long nTemp = -aTextPos.X(); 2921 aTextPos.X() = aTextPos.Y(); 2922 aTextPos.Y() = nTemp; 2923 } 2924 else 2925 aTextPos -= aOutputArea.TopLeft(); 2926 aTextPos += aVisArea.TopLeft(); // position in the edit document 2927 2928 EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos); 2929 ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex); 2930 ESelection aSelection = pEditView->GetSelection(); 2931 aSelection.Adjust(); // needed for IsLess/IsGreater 2932 if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) ) 2933 { 2934 // clicked outside the selected text - deselect and move text cursor 2935 MouseEvent aEvent( rPosPixel ); 2936 pEditView->MouseButtonDown( aEvent ); 2937 pEditView->MouseButtonUp( aEvent ); 2938 pScMod->InputSelection( pEditView ); 2939 } 2940 2941 return; // clicked within the edit view - keep edit mode 2942 } 2943 else 2944 { 2945 // outside of the edit view - end edit mode, regardless of cell selection, then continue 2946 pScMod->InputEnterHandler(); 2947 } 2948 } 2949 2950 // check draw text edit mode 2951 2952 Point aLogicPos = PixelToLogic( rPosPixel ); // after cell edit mode is ended 2953 if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() ) 2954 { 2955 OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView(); 2956 Rectangle aOutputArea = pOlView->GetOutputArea(); 2957 if ( aOutputArea.IsInside( aLogicPos ) ) 2958 { 2959 // handle selection within the OutlinerView 2960 2961 Outliner* pOutliner = pOlView->GetOutliner(); 2962 const EditEngine& rEditEngine = pOutliner->GetEditEngine(); 2963 Rectangle aVisArea = pOlView->GetVisArea(); 2964 2965 Point aTextPos = aLogicPos; 2966 if ( pOutliner->IsVertical() ) // have to manually transform position 2967 { 2968 aTextPos -= aOutputArea.TopRight(); 2969 long nTemp = -aTextPos.X(); 2970 aTextPos.X() = aTextPos.Y(); 2971 aTextPos.Y() = nTemp; 2972 } 2973 else 2974 aTextPos -= aOutputArea.TopLeft(); 2975 aTextPos += aVisArea.TopLeft(); // position in the edit document 2976 2977 EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos); 2978 ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex); 2979 ESelection aSelection = pOlView->GetSelection(); 2980 aSelection.Adjust(); // needed for IsLess/IsGreater 2981 if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) ) 2982 { 2983 // clicked outside the selected text - deselect and move text cursor 2984 // use DrawView to allow extra handling there (none currently) 2985 MouseEvent aEvent( rPosPixel ); 2986 pDrawView->MouseButtonDown( aEvent, this ); 2987 pDrawView->MouseButtonUp( aEvent, this ); 2988 } 2989 2990 return; // clicked within the edit area - keep edit mode 2991 } 2992 else 2993 { 2994 // Outside of the edit area - end text edit mode, then continue. 2995 // DrawDeselectAll also ends text edit mode and updates the shells. 2996 // If the click was on the edited object, it will be selected again below. 2997 pView->DrawDeselectAll(); 2998 } 2999 } 3000 3001 // look for existing selection 3002 3003 sal_Bool bHitSelected = sal_False; 3004 if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) ) 3005 { 3006 // clicked on selected object -> don't change anything 3007 bHitSelected = sal_True; 3008 } 3009 else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) ) 3010 { 3011 // clicked on selected cell -> don't change anything 3012 bHitSelected = sal_True; 3013 } 3014 3015 // select drawing object or move cell cursor 3016 3017 if ( !bHitSelected ) 3018 { 3019 sal_Bool bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() ); 3020 sal_Bool bHitDraw = sal_False; 3021 if ( pDrawView ) 3022 { 3023 pDrawView->UnmarkAllObj(); 3024 // Unlock the Internal Layer in order to activate the context menu. 3025 // re-lock in ScDrawView::MarkListHasChanged() 3026 lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData); 3027 bHitDraw = pDrawView->MarkObj( aLogicPos ); 3028 // draw shell is activated in MarkListHasChanged 3029 } 3030 if ( !bHitDraw ) 3031 { 3032 pView->Unmark(); 3033 pView->SetCursor(nCellX, nCellY); 3034 if ( bWasDraw ) 3035 pViewData->GetViewShell()->SetDrawShell( sal_False ); // switch shells 3036 } 3037 } 3038 } 3039 3040 void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt) 3041 { 3042 // #96965# Cursor control for ref input dialog 3043 if( SC_MOD()->IsRefDialogOpen() ) 3044 { 3045 const KeyCode& rKeyCode = rKEvt.GetKeyCode(); 3046 if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) ) 3047 { 3048 SC_MOD()->EndReference(); 3049 return; 3050 } 3051 else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) ) 3052 { 3053 ScRange aRef( 3054 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(), 3055 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() ); 3056 SC_MOD()->SetReference( aRef, pViewData->GetDocument() ); 3057 return; 3058 } 3059 } 3060 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs: 3061 else if( !pViewData->IsAnyFillMode() ) 3062 { 3063 // query for existing note marker before calling ViewShell's keyboard handling 3064 // which may remove the marker 3065 sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() ); 3066 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 3067 3068 if (pViewData->GetDocShell()->GetProgress()) 3069 return; 3070 3071 if (DrawKeyInput(rKEvt)) 3072 return; 3073 3074 if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus 3075 { //! DrawShell abfragen !!! 3076 if (pViewSh->TabKeyInput(rKEvt)) 3077 return; 3078 } 3079 else 3080 if (pViewSh->SfxViewShell::KeyInput(rKEvt)) // von SfxViewShell 3081 return; 3082 3083 KeyCode aCode = rKEvt.GetKeyCode(); 3084 if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 ) 3085 { 3086 if ( bHadKeyMarker ) 3087 HideNoteMarker(); 3088 else 3089 pViewSh->Escape(); 3090 return; 3091 } 3092 if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 ) 3093 { 3094 // ctrl-F1 shows or hides the note or redlining info for the cursor position 3095 // (hard-coded because F1 can't be configured) 3096 3097 if ( bHadKeyMarker ) 3098 HideNoteMarker(); // hide when previously visible 3099 else 3100 ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True ); 3101 return; 3102 } 3103 } 3104 3105 Window::KeyInput(rKEvt); 3106 } 3107 3108 void ScGridWindow::StopMarking() 3109 { 3110 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen 3111 3112 if (nButtonDown) 3113 { 3114 pViewData->GetMarkData().SetMarking(sal_False); 3115 nMouseStatus = SC_GM_IGNORE; 3116 } 3117 } 3118 3119 void ScGridWindow::UpdateInputContext() 3120 { 3121 sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly(); 3122 sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT ); 3123 3124 // when font from InputContext is used, 3125 // it must be taken from the cursor position's cell attributes 3126 3127 InputContext aContext; 3128 aContext.SetOptions( nOptions ); 3129 SetInputContext( aContext ); 3130 } 3131 3132 //-------------------------------------------------------- 3133 3134 // sensitiver Bereich (Pixel) 3135 #define SCROLL_SENSITIVE 20 3136 3137 sal_Bool ScGridWindow::DropScroll( const Point& rMousePos ) 3138 { 3139 /* doch auch auf nicht aktiven Views... 3140 if ( !pViewData->IsActive() ) 3141 return sal_False; 3142 */ 3143 SCsCOL nDx = 0; 3144 SCsROW nDy = 0; 3145 Size aSize = GetOutputSizePixel(); 3146 3147 if (aSize.Width() > SCROLL_SENSITIVE * 3) 3148 { 3149 if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 ) 3150 nDx = -1; 3151 if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE 3152 && pViewData->GetPosX(WhichH(eWhich)) < MAXCOL ) 3153 nDx = 1; 3154 } 3155 if (aSize.Height() > SCROLL_SENSITIVE * 3) 3156 { 3157 if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 ) 3158 nDy = -1; 3159 if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE 3160 && pViewData->GetPosY(WhichV(eWhich)) < MAXROW ) 3161 nDy = 1; 3162 } 3163 3164 if ( nDx != 0 || nDy != 0 ) 3165 { 3166 // if (bDragRect) 3167 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3168 3169 if ( nDx != 0 ) 3170 pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) ); 3171 if ( nDy != 0 ) 3172 pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) ); 3173 3174 // if (bDragRect) 3175 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3176 } 3177 3178 return sal_False; 3179 } 3180 3181 sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange) 3182 { 3183 // Testet, ob bei eingeschalteten RedLining, 3184 // bei einem Drop ein Scenario betroffen ist. 3185 3186 sal_Bool bReturn = sal_False; 3187 SCTAB nTab = aDragRange.aStart.Tab(); 3188 SCTAB nTabCount = pDoc->GetTableCount(); 3189 3190 if(pDoc->GetChangeTrack()!=NULL) 3191 { 3192 if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange)) 3193 { 3194 bReturn = sal_True; 3195 } 3196 else 3197 { 3198 for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) 3199 { 3200 if(pDoc->HasScenarioRange(i, aDragRange)) 3201 { 3202 bReturn = sal_True; 3203 break; 3204 } 3205 } 3206 } 3207 } 3208 return bReturn; 3209 } 3210 3211 ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource ) 3212 { 3213 SCCOL nCol1 = nPosX; 3214 SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() ); 3215 if ( nCol2 > MAXCOL ) 3216 { 3217 nCol1 -= nCol2 - MAXCOL; 3218 nCol2 = MAXCOL; 3219 } 3220 SCROW nRow1 = nPosY; 3221 SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() ); 3222 if ( nRow2 > MAXROW ) 3223 { 3224 nRow1 -= nRow2 - MAXROW; 3225 nRow2 = MAXROW; 3226 } 3227 3228 return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ); 3229 } 3230 3231 //-------------------------------------------------------- 3232 3233 extern sal_Bool bPasteIsDrop; // viewfun4 -> move to header 3234 extern sal_Bool bPasteIsMove; // viewfun7 -> move to header 3235 3236 //-------------------------------------------------------- 3237 3238 sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt ) 3239 { 3240 if ( rEvt.mbLeaving ) 3241 { 3242 // if (bDragRect) 3243 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3244 bDragRect = sal_False; 3245 UpdateDragRectOverlay(); 3246 return rEvt.mnAction; 3247 } 3248 3249 const ScDragData& rData = SC_MOD()->GetDragData(); 3250 if ( rData.pCellTransfer ) 3251 { 3252 // Don't move source that would include filtered rows. 3253 if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows()) 3254 { 3255 if (bDragRect) 3256 { 3257 bDragRect = sal_False; 3258 UpdateDragRectOverlay(); 3259 } 3260 return DND_ACTION_NONE; 3261 } 3262 3263 Point aPos = rEvt.maPosPixel; 3264 3265 ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument(); 3266 ScDocument* pThisDoc = pViewData->GetDocument(); 3267 if (pSourceDoc == pThisDoc) 3268 { 3269 if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) ) 3270 { 3271 if (bDragRect) // Rechteck loeschen 3272 { 3273 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3274 bDragRect = sal_False; 3275 UpdateDragRectOverlay(); 3276 } 3277 3278 //! highlight chart? (selection border?) 3279 3280 sal_Int8 nRet = rEvt.mnAction; 3281 //! if ( rEvt.GetAction() == DROP_LINK ) 3282 //! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart 3283 return nRet; 3284 } 3285 } 3286 //! else 3287 //! if ( rEvt.GetAction() == DROP_MOVE ) 3288 //! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY 3289 3290 3291 if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) // whole sheet? 3292 { 3293 sal_Bool bOk = pThisDoc->IsDocEditable(); 3294 return bOk ? rEvt.mnAction : 0; // don't draw selection frame 3295 } 3296 3297 SCsCOL nPosX; 3298 SCsROW nPosY; 3299 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 3300 3301 ScRange aSourceRange = rData.pCellTransfer->GetRange(); 3302 SCCOL nSourceStartX = aSourceRange.aStart.Col(); 3303 SCROW nSourceStartY = aSourceRange.aStart.Row(); 3304 SCCOL nSourceEndX = aSourceRange.aEnd.Col(); 3305 SCROW nSourceEndY = aSourceRange.aEnd.Row(); 3306 SCCOL nSizeX = nSourceEndX - nSourceStartX + 1; 3307 SCROW nSizeY = nSourceEndY - nSourceStartY + 1; 3308 3309 if ( rEvt.mnAction != DND_ACTION_MOVE ) 3310 nSizeY = rData.pCellTransfer->GetNonFilteredRows(); // copy/link: no filtered rows 3311 3312 SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX(); 3313 if (nNewDragX<0) nNewDragX=0; 3314 if (nNewDragX+(nSizeX-1) > MAXCOL) 3315 nNewDragX = MAXCOL-(nSizeX-1); 3316 SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY(); 3317 if (nNewDragY<0) nNewDragY=0; 3318 if (nNewDragY+(nSizeY-1) > MAXROW) 3319 nNewDragY = MAXROW-(nSizeY-1); 3320 3321 // don't break scenario ranges, don't drop on filtered 3322 SCTAB nTab = pViewData->GetTabNo(); 3323 ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange ); 3324 if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) || 3325 lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) || 3326 ScViewUtil::HasFiltered( aDropRange, pThisDoc) ) 3327 { 3328 if (bDragRect) 3329 { 3330 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3331 bDragRect = sal_False; 3332 UpdateDragRectOverlay(); 3333 } 3334 return DND_ACTION_NONE; 3335 } 3336 3337 InsCellCmd eDragInsertMode = INS_NONE; 3338 Window::PointerState aState = GetPointerState(); 3339 3340 // check for datapilot item sorting 3341 ScDPObject* pDPObj = NULL; 3342 if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL ) 3343 { 3344 // drop on DataPilot table: sort or nothing 3345 3346 bool bDPSort = false; 3347 if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj ) 3348 { 3349 sheet::DataPilotTableHeaderData aDestData; 3350 pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData ); 3351 bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field 3352 3353 // look through the source range 3354 for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow ) 3355 for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol ) 3356 { 3357 sheet::DataPilotTableHeaderData aSourceData; 3358 pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData ); 3359 if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() ) 3360 bValid = false; // empty (subtotal) or different field 3361 } 3362 3363 if ( bValid ) 3364 { 3365 sal_Bool bIsDataLayout; 3366 String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout ); 3367 const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName ); 3368 if ( pDim ) 3369 { 3370 ScRange aOutRange = pDPObj->GetOutRange(); 3371 3372 sal_uInt16 nOrient = pDim->GetOrientation(); 3373 if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN ) 3374 { 3375 eDragInsertMode = INS_CELLSRIGHT; 3376 nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1; 3377 bDPSort = true; 3378 } 3379 else if ( nOrient == sheet::DataPilotFieldOrientation_ROW ) 3380 { 3381 eDragInsertMode = INS_CELLSDOWN; 3382 nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1; 3383 bDPSort = true; 3384 } 3385 } 3386 } 3387 } 3388 3389 if ( !bDPSort ) 3390 { 3391 // no valid sorting in a DataPilot table -> disallow 3392 if ( bDragRect ) 3393 { 3394 bDragRect = sal_False; 3395 UpdateDragRectOverlay(); 3396 } 3397 return DND_ACTION_NONE; 3398 } 3399 } 3400 else if ( aState.mnState & KEY_MOD2 ) 3401 { 3402 if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() ) 3403 { 3404 long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) ); 3405 long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) ); 3406 if ( nDeltaX <= nDeltaY ) 3407 { 3408 eDragInsertMode = INS_CELLSDOWN; 3409 } 3410 else 3411 { 3412 eDragInsertMode = INS_CELLSRIGHT; 3413 } 3414 3415 if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY && 3416 ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX && 3417 ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) || 3418 ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX && 3419 ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY && 3420 ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) ) 3421 { 3422 if ( bDragRect ) 3423 { 3424 bDragRect = sal_False; 3425 UpdateDragRectOverlay(); 3426 } 3427 return DND_ACTION_NONE; 3428 } 3429 } 3430 else 3431 { 3432 if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) ) 3433 { 3434 eDragInsertMode = INS_CELLSDOWN; 3435 3436 } 3437 else 3438 { 3439 eDragInsertMode = INS_CELLSRIGHT; 3440 } 3441 } 3442 } 3443 3444 if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY || 3445 nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY || 3446 !bDragRect || eDragInsertMode != meDragInsertMode ) 3447 { 3448 // if (bDragRect) 3449 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3450 3451 nDragStartX = nNewDragX; 3452 nDragStartY = nNewDragY; 3453 nDragEndX = nDragStartX+nSizeX-1; 3454 nDragEndY = nDragStartY+nSizeY-1; 3455 bDragRect = sal_True; 3456 meDragInsertMode = eDragInsertMode; 3457 3458 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3459 3460 UpdateDragRectOverlay(); 3461 3462 // show target position as tip help 3463 #if 0 3464 if (Help::IsQuickHelpEnabled()) 3465 { 3466 ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab ); 3467 String aHelpStr; 3468 aRange.Format( aHelpStr, SCA_VALID ); // non-3D 3469 3470 Point aPos = Pointer::GetPosPixel(); 3471 sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT; 3472 Rectangle aRect( aPos, aPos ); 3473 Help::ShowQuickHelp(aRect, aHelpStr, nAlign); 3474 } 3475 #endif 3476 } 3477 } 3478 3479 return rEvt.mnAction; 3480 } 3481 3482 sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt ) 3483 { 3484 const ScDragData& rData = SC_MOD()->GetDragData(); 3485 if ( rEvt.mbLeaving ) 3486 { 3487 DrawMarkDropObj( NULL ); 3488 if ( rData.pCellTransfer ) 3489 return AcceptPrivateDrop( rEvt ); // hide drop marker for internal D&D 3490 else 3491 return rEvt.mnAction; 3492 } 3493 3494 if ( pViewData->GetDocShell()->IsReadOnly() ) 3495 return DND_ACTION_NONE; 3496 3497 3498 sal_Int8 nRet = DND_ACTION_NONE; 3499 3500 if (rData.pCellTransfer) 3501 { 3502 ScRange aSource = rData.pCellTransfer->GetRange(); 3503 if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL || 3504 aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW ) 3505 DropScroll( rEvt.maPosPixel ); 3506 3507 nRet = AcceptPrivateDrop( rEvt ); 3508 } 3509 else 3510 { 3511 if ( rData.aLinkDoc.Len() ) 3512 { 3513 String aThisName; 3514 ScDocShell* pDocSh = pViewData->GetDocShell(); 3515 if (pDocSh && pDocSh->HasName()) 3516 aThisName = pDocSh->GetMedium()->GetName(); 3517 3518 if ( rData.aLinkDoc != aThisName ) 3519 nRet = rEvt.mnAction; 3520 } 3521 else if (rData.aJumpTarget.Len()) 3522 { 3523 // internal bookmarks (from Navigator) 3524 // local jumps from an unnamed document are possible only within a document 3525 3526 if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() ) 3527 nRet = rEvt.mnAction; 3528 } 3529 else 3530 { 3531 sal_Int8 nMyAction = rEvt.mnAction; 3532 3533 if ( !rData.pDrawTransfer || 3534 !IsMyModel(rData.pDrawTransfer->GetDragSourceView()) ) // drawing within the document 3535 if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE ) 3536 nMyAction = DND_ACTION_COPY; 3537 3538 ScDocument* pThisDoc = pViewData->GetDocument(); 3539 SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( 3540 pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) ); 3541 if ( pHitObj && nMyAction == DND_ACTION_LINK && !rData.pDrawTransfer ) 3542 { 3543 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB) 3544 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE) 3545 || IsDropFormatSupported(SOT_FORMAT_BITMAP) ) 3546 { 3547 // graphic dragged onto drawing object 3548 DrawMarkDropObj( pHitObj ); 3549 nRet = nMyAction; 3550 } 3551 } 3552 if (!nRet) 3553 DrawMarkDropObj( NULL ); 3554 3555 if (!nRet) 3556 { 3557 switch ( nMyAction ) 3558 { 3559 case DND_ACTION_COPY: 3560 case DND_ACTION_MOVE: 3561 case DND_ACTION_COPYMOVE: 3562 { 3563 sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE ); 3564 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) || 3565 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || 3566 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) || 3567 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 3568 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) || 3569 IsDropFormatSupported( SOT_FORMAT_STRING ) || 3570 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) || 3571 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || 3572 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) || 3573 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) || 3574 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) || 3575 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) || 3576 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) || 3577 IsDropFormatSupported( SOT_FORMAT_RTF ) || 3578 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) || 3579 IsDropFormatSupported( SOT_FORMAT_BITMAP ) || 3580 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) || 3581 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) || 3582 ( !bMove && ( 3583 IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || 3584 IsDropFormatSupported( SOT_FORMAT_FILE ) || 3585 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || 3586 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || 3587 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || 3588 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) ) 3589 { 3590 nRet = nMyAction; 3591 } 3592 } 3593 break; 3594 case DND_ACTION_LINK: 3595 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || 3596 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 3597 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || 3598 IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || 3599 IsDropFormatSupported( SOT_FORMAT_FILE ) || 3600 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || 3601 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || 3602 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || 3603 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3604 { 3605 nRet = nMyAction; 3606 } 3607 break; 3608 } 3609 3610 if ( nRet ) 3611 { 3612 // Simple check for protection: It's not known here if the drop will result 3613 // in cells or drawing objects (some formats can be both) and how many cells 3614 // the result will be. But if IsFormatEditable for the drop cell position 3615 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop 3616 // can already be rejected here. 3617 3618 Point aPos = rEvt.maPosPixel; 3619 SCsCOL nPosX; 3620 SCsROW nPosY; 3621 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 3622 SCTAB nTab = pViewData->GetTabNo(); 3623 ScDocument* pDoc = pViewData->GetDocument(); 3624 3625 ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY ); 3626 if ( !aTester.IsFormatEditable() ) 3627 nRet = DND_ACTION_NONE; // forbidden 3628 } 3629 } 3630 } 3631 3632 // scroll only for accepted formats 3633 if (nRet) 3634 DropScroll( rEvt.maPosPixel ); 3635 } 3636 3637 return nRet; 3638 } 3639 3640 sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false ) 3641 { 3642 TransferableDataHelper aDataHelper( xTransfer ); 3643 3644 if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) 3645 { 3646 // use bookmark formats if no sba is present 3647 3648 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) 3649 return SOT_FORMATSTR_ID_SOLK; 3650 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) 3651 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; 3652 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) 3653 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; 3654 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3655 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; 3656 } 3657 3658 sal_uLong nFormatId = 0; 3659 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) ) 3660 nFormatId = SOT_FORMATSTR_ID_DRAWING; 3661 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) ) 3662 nFormatId = SOT_FORMATSTR_ID_SVXB; 3663 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ) 3664 { 3665 // If it's a Writer object, insert RTF instead of OLE 3666 3667 sal_Bool bDoRtf = sal_False; 3668 SotStorageStreamRef xStm; 3669 TransferableObjectDescriptor aObjDesc; 3670 if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) && 3671 aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) ) 3672 { 3673 SotStorageRef xStore( new SotStorage( *xStm ) ); 3674 bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) || 3675 aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) ) 3676 && aDataHelper.HasFormat( SOT_FORMAT_RTF ) ); 3677 } 3678 if ( bDoRtf ) 3679 nFormatId = FORMAT_RTF; 3680 else 3681 nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE; 3682 } 3683 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) 3684 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; 3685 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) 3686 nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE; 3687 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ) 3688 nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE; 3689 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) ) 3690 nFormatId = SOT_FORMATSTR_ID_BIFF_8; 3691 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) ) 3692 nFormatId = SOT_FORMATSTR_ID_BIFF_5; 3693 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ) 3694 nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE; 3695 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ) 3696 nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE; 3697 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) 3698 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; 3699 else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) ) 3700 nFormatId = SOT_FORMAT_RTF; 3701 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) ) 3702 nFormatId = SOT_FORMATSTR_ID_HTML; 3703 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ) 3704 nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE; 3705 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) ) 3706 nFormatId = SOT_FORMATSTR_ID_SYLK; 3707 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) 3708 nFormatId = SOT_FORMATSTR_ID_LINK; 3709 else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting 3710 nFormatId = SOT_FORMAT_STRING; 3711 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) 3712 nFormatId = SOT_FORMAT_FILE_LIST; 3713 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers) 3714 nFormatId = SOT_FORMAT_FILE; 3715 else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) 3716 nFormatId = SOT_FORMAT_STRING; 3717 else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) ) 3718 nFormatId = SOT_FORMAT_GDIMETAFILE; 3719 else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) ) 3720 nFormatId = SOT_FORMAT_BITMAP; 3721 3722 return nFormatId; 3723 } 3724 3725 sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer ) 3726 { 3727 TransferableDataHelper aDataHelper( xTransfer ); 3728 3729 sal_uLong nFormatId = 0; 3730 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) 3731 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; 3732 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) 3733 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; 3734 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) 3735 nFormatId = SOT_FORMATSTR_ID_LINK; 3736 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) 3737 nFormatId = SOT_FORMAT_FILE_LIST; 3738 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) 3739 nFormatId = SOT_FORMAT_FILE; 3740 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) 3741 nFormatId = SOT_FORMATSTR_ID_SOLK; 3742 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) 3743 nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; 3744 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) 3745 nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; 3746 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3747 nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; 3748 3749 return nFormatId; 3750 } 3751 3752 3753 sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt ) 3754 { 3755 // hide drop marker 3756 // if (bDragRect) 3757 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3758 bDragRect = sal_False; 3759 UpdateDragRectOverlay(); 3760 3761 ScModule* pScMod = SC_MOD(); 3762 const ScDragData& rData = pScMod->GetDragData(); 3763 3764 return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY, 3765 PixelToLogic(rEvt.maPosPixel), rEvt.mnAction ); 3766 } 3767 3768 sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY, 3769 const Point& rLogicPos, sal_Int8 nDndAction ) 3770 { 3771 if ( !pTransObj ) 3772 return 0; 3773 3774 ScDocument* pSourceDoc = pTransObj->GetSourceDocument(); 3775 ScDocShell* pDocSh = pViewData->GetDocShell(); 3776 ScDocument* pThisDoc = pViewData->GetDocument(); 3777 ScViewFunc* pView = pViewData->GetView(); 3778 SCTAB nThisTab = pViewData->GetTabNo(); 3779 sal_uInt16 nFlags = pTransObj->GetDragSourceFlags(); 3780 3781 sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; 3782 sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi ); 3783 3784 // workaround for wrong nDndAction on Windows when pressing solely 3785 // the Alt key during drag and drop; 3786 // can be removed after #i79215# has been fixed 3787 if ( meDragInsertMode != INS_NONE ) 3788 { 3789 bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi ); 3790 } 3791 3792 sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK ); 3793 3794 ScRange aSource = pTransObj->GetRange(); 3795 3796 // only use visible tab from source range - when dragging within one table, 3797 // all selected tables at the time of dropping are used (handled in MoveBlockTo) 3798 SCTAB nSourceTab = pTransObj->GetVisibleTab(); 3799 aSource.aStart.SetTab( nSourceTab ); 3800 aSource.aEnd.SetTab( nSourceTab ); 3801 3802 SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1; 3803 SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) : 3804 pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows 3805 ScRange aDest( nDestPosX, nDestPosY, nThisTab, 3806 nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab ); 3807 3808 3809 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during 3810 * dragging and adapted drawing of the selection frame. We check here 3811 * (again) because this may actually also be called from PasteSelection(), 3812 * we would have to duplicate determination of flags and destination range 3813 * and would lose the context of the "filtered destination is OK" cases 3814 * below, which is already awkward enough as is. */ 3815 3816 // Don't move filtered source. 3817 bool bFiltered = (bIsMove && pTransObj->HasFilteredRows()); 3818 if (!bFiltered) 3819 { 3820 if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) || 3821 (!bIsLink && meDragInsertMode == INS_NONE))) 3822 { 3823 // Nothing. Either entire sheet to be dropped, or the one case 3824 // where PasteFromClip() is to be called that handles a filtered 3825 // destination itself. Drag-copy from another document without 3826 // inserting cells. 3827 } 3828 else 3829 // Don't copy or move to filtered destination. 3830 bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc); 3831 } 3832 3833 sal_Bool bDone = sal_False; 3834 3835 if (!bFiltered && pSourceDoc == pThisDoc) 3836 { 3837 if ( nFlags & SC_DROP_TABLE ) // whole sheet? 3838 { 3839 if ( pThisDoc->IsDocEditable() ) 3840 { 3841 SCTAB nSrcTab = aSource.aStart.Tab(); 3842 pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True ); // with Undo 3843 pView->SetTabNo( nThisTab, sal_True ); 3844 bDone = sal_True; 3845 } 3846 } 3847 else // move/copy block 3848 { 3849 String aChartName; 3850 if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName )) 3851 { 3852 String aRangeName; 3853 aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc ); 3854 SfxStringItem aNameItem( SID_CHART_NAME, aChartName ); 3855 SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName ); 3856 sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE; 3857 pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, 3858 &aRangeItem, &aNameItem, (void*) NULL ); 3859 bDone = sal_True; 3860 } 3861 else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) ) 3862 { 3863 // drop on DataPilot table: try to sort, fail if that isn't possible 3864 3865 ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab ); 3866 if ( aDestPos != aSource.aStart ) 3867 bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos ); 3868 else 3869 bDone = sal_True; // same position: nothing 3870 } 3871 else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() || 3872 nSourceTab != nThisTab ) 3873 { 3874 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); 3875 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 3876 3877 bDone = sal_True; 3878 if ( meDragInsertMode != INS_NONE ) 3879 { 3880 // call with bApi = sal_True to avoid error messages in drop handler 3881 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 3882 if ( bDone ) 3883 { 3884 if ( nThisTab == nSourceTab ) 3885 { 3886 if ( meDragInsertMode == INS_CELLSDOWN && 3887 nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() ) 3888 { 3889 bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc ); 3890 } 3891 else if ( meDragInsertMode == INS_CELLSRIGHT && 3892 nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() ) 3893 { 3894 bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc ); 3895 } 3896 } 3897 pDocSh->UpdateOle( pViewData ); 3898 pView->CellContentChanged(); 3899 } 3900 } 3901 3902 if ( bDone ) 3903 { 3904 if ( bIsLink ) 3905 { 3906 // call with bApi = sal_True to avoid error messages in drop handler 3907 bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ ); 3908 } 3909 else 3910 { 3911 // call with bApi = sal_True to avoid error messages in drop handler 3912 bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ ); 3913 } 3914 } 3915 3916 if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab ) 3917 { 3918 DelCellCmd eCmd = DEL_NONE; 3919 if ( meDragInsertMode == INS_CELLSDOWN ) 3920 { 3921 eCmd = DEL_CELLSUP; 3922 } 3923 else if ( meDragInsertMode == INS_CELLSRIGHT ) 3924 { 3925 eCmd = DEL_CELLSLEFT; 3926 } 3927 3928 if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) || 3929 ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) ) 3930 { 3931 // call with bApi = sal_True to avoid error messages in drop handler 3932 bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ ); 3933 if ( bDone ) 3934 { 3935 if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() ) 3936 { 3937 bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc ); 3938 } 3939 else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() ) 3940 { 3941 bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc ); 3942 } 3943 pDocSh->UpdateOle( pViewData ); 3944 pView->CellContentChanged(); 3945 } 3946 } 3947 } 3948 3949 if ( bDone ) 3950 { 3951 pView->MarkRange( aDest, sal_False, sal_False ); 3952 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 3953 } 3954 3955 pDocSh->GetUndoManager()->LeaveListAction(); 3956 3957 if (!bDone) 3958 Sound::Beep(); // instead of error message in drop handler 3959 } 3960 else 3961 bDone = sal_True; // nothing to do 3962 } 3963 3964 if (bDone) 3965 pTransObj->SetDragWasInternal(); // don't delete source in DragFinished 3966 } 3967 else if ( !bFiltered && pSourceDoc ) // between documents 3968 { 3969 if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents 3970 { 3971 if ( pThisDoc->IsDocEditable() ) 3972 { 3973 ScDocShell* pSrcShell = pTransObj->GetSourceDocShell(); 3974 3975 SCTAB nTabs[MAXTABCOUNT]; 3976 3977 ScMarkData aMark = pTransObj->GetSourceMarkData(); 3978 SCTAB nTabCount = pSourceDoc->GetTableCount(); 3979 SCTAB nTabSelCount = 0; 3980 3981 for(SCTAB i=0; i<nTabCount; i++) 3982 { 3983 if(aMark.GetTableSelect(i)) 3984 { 3985 nTabs[nTabSelCount++]=i; 3986 for(SCTAB j=i+1;j<nTabCount;j++) 3987 { 3988 if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j))) 3989 { 3990 nTabs[nTabSelCount++]=j; 3991 i=j; 3992 } 3993 else break; 3994 } 3995 } 3996 } 3997 3998 pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab ); 3999 bDone = sal_True; 4000 } 4001 } 4002 else if ( bIsLink ) 4003 { 4004 // as in PasteDDE 4005 // (external references might be used instead?) 4006 4007 SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell(); 4008 DBG_ASSERT(pSourceSh, "drag document has no shell"); 4009 if (pSourceSh) 4010 { 4011 String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY ); 4012 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 4013 4014 bDone = sal_True; 4015 if ( meDragInsertMode != INS_NONE ) 4016 { 4017 // call with bApi = sal_True to avoid error messages in drop handler 4018 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 4019 if ( bDone ) 4020 { 4021 pDocSh->UpdateOle( pViewData ); 4022 pView->CellContentChanged(); 4023 } 4024 } 4025 4026 if ( bDone ) 4027 { 4028 String aApp = Application::GetAppName(); 4029 String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME ); 4030 String aItem; 4031 aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc ); 4032 4033 // TODO: we could define ocQuote for " 4034 const String aQuote( '"' ); 4035 const String& sSep = ScCompiler::GetNativeSymbol( ocSep); 4036 String aFormula( '=' ); 4037 aFormula += ScCompiler::GetNativeSymbol( ocDde); 4038 aFormula += ScCompiler::GetNativeSymbol( ocOpen); 4039 aFormula += aQuote; 4040 aFormula += aApp; 4041 aFormula += aQuote; 4042 aFormula += sSep; 4043 aFormula += aQuote; 4044 aFormula += aTopic; 4045 aFormula += aQuote; 4046 aFormula += sSep; 4047 aFormula += aQuote; 4048 aFormula += aItem; 4049 aFormula += aQuote; 4050 aFormula += ScCompiler::GetNativeSymbol( ocClose); 4051 4052 pView->DoneBlockMode(); 4053 pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab ); 4054 pView->MarkCursor( nDestPosX + nSizeX - 1, 4055 nDestPosY + nSizeY - 1, nThisTab ); 4056 4057 pView->EnterMatrix( aFormula ); 4058 4059 pView->MarkRange( aDest, sal_False, sal_False ); 4060 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 4061 } 4062 4063 pDocSh->GetUndoManager()->LeaveListAction(); 4064 } 4065 } 4066 else 4067 { 4068 //! HasSelectedBlockMatrixFragment without selected sheet? 4069 //! or don't start dragging on a part of a matrix 4070 4071 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); 4072 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 4073 4074 bDone = sal_True; 4075 if ( meDragInsertMode != INS_NONE ) 4076 { 4077 // call with bApi = sal_True to avoid error messages in drop handler 4078 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 4079 if ( bDone ) 4080 { 4081 pDocSh->UpdateOle( pViewData ); 4082 pView->CellContentChanged(); 4083 } 4084 } 4085 4086 if ( bDone ) 4087 { 4088 pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection 4089 pView->SetCursor( nDestPosX, nDestPosY ); 4090 bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc 4091 if ( bDone ) 4092 { 4093 pView->MarkRange( aDest, sal_False, sal_False ); 4094 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 4095 } 4096 } 4097 4098 pDocSh->GetUndoManager()->LeaveListAction(); 4099 4100 // no longer call ResetMark here - the inserted block has been selected 4101 // and may have been copied to primary selection 4102 } 4103 } 4104 4105 sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE; 4106 return nRet; 4107 } 4108 4109 sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt ) 4110 { 4111 DrawMarkDropObj( NULL ); // drawing layer 4112 4113 ScModule* pScMod = SC_MOD(); 4114 const ScDragData& rData = pScMod->GetDragData(); 4115 if (rData.pCellTransfer) 4116 return ExecutePrivateDrop( rEvt ); 4117 4118 Point aPos = rEvt.maPosPixel; 4119 4120 if ( rData.aLinkDoc.Len() ) 4121 { 4122 // try to insert a link 4123 4124 sal_Bool bOk = sal_True; 4125 String aThisName; 4126 ScDocShell* pDocSh = pViewData->GetDocShell(); 4127 if (pDocSh && pDocSh->HasName()) 4128 aThisName = pDocSh->GetMedium()->GetName(); 4129 4130 if ( rData.aLinkDoc == aThisName ) // error - no link within a document 4131 bOk = sal_False; 4132 else 4133 { 4134 ScViewFunc* pView = pViewData->GetView(); 4135 if ( rData.aLinkTable.Len() ) 4136 pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, 4137 rData.aLinkTable ); 4138 else if ( rData.aLinkArea.Len() ) 4139 { 4140 SCsCOL nPosX; 4141 SCsROW nPosY; 4142 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4143 pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False ); 4144 4145 pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, 4146 rData.aLinkArea, 0 ); 4147 } 4148 else 4149 { 4150 DBG_ERROR("drop with link: no sheet nor area"); 4151 bOk = sal_False; 4152 } 4153 } 4154 4155 return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else 4156 } 4157 4158 Point aLogicPos = PixelToLogic(aPos); 4159 4160 if (rData.pDrawTransfer) 4161 { 4162 sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags(); 4163 4164 sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; 4165 sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi ); 4166 4167 bPasteIsMove = bIsMove; 4168 4169 pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() ); 4170 4171 if (bPasteIsMove) 4172 rData.pDrawTransfer->SetDragWasInternal(); 4173 bPasteIsMove = sal_False; 4174 4175 return rEvt.mnAction; 4176 } 4177 4178 4179 SCsCOL nPosX; 4180 SCsROW nPosY; 4181 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4182 4183 if (rData.aJumpTarget.Len()) 4184 { 4185 // internal bookmark (from Navigator) 4186 // bookmark clipboard formats are in PasteScDataObject 4187 4188 if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() ) 4189 { 4190 pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget, 4191 nPosX, nPosY ); 4192 return rEvt.mnAction; 4193 } 4194 } 4195 4196 sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK ); 4197 4198 ScDocument* pThisDoc = pViewData->GetDocument(); 4199 SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) ); 4200 if ( pHitObj && bIsLink ) 4201 { 4202 // dropped on drawing object 4203 // PasteOnDrawObject checks for valid formats 4204 if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, sal_True ) ) 4205 return rEvt.mnAction; 4206 } 4207 4208 sal_Bool bDone = sal_False; 4209 4210 sal_uLong nFormatId = bIsLink ? 4211 lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) : 4212 lcl_GetDropFormatId( rEvt.maDropEvent.Transferable ); 4213 if ( nFormatId ) 4214 { 4215 pScMod->SetInExecuteDrop( sal_True ); // #i28468# prevent error messages from PasteDataFormat 4216 bPasteIsDrop = sal_True; 4217 bDone = pViewData->GetView()->PasteDataFormat( 4218 nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink ); 4219 bPasteIsDrop = sal_False; 4220 pScMod->SetInExecuteDrop( sal_False ); 4221 } 4222 4223 sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE; 4224 return nRet; 4225 } 4226 4227 //-------------------------------------------------------- 4228 4229 void ScGridWindow::PasteSelection( const Point& rPosPixel ) 4230 { 4231 Point aLogicPos = PixelToLogic( rPosPixel ); 4232 4233 SCsCOL nPosX; 4234 SCsROW nPosY; 4235 pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY ); 4236 4237 ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer(); 4238 if ( pOwnSelection ) 4239 { 4240 // within Calc 4241 4242 ScTransferObj* pCellTransfer = pOwnSelection->GetCellData(); 4243 if ( pCellTransfer ) 4244 { 4245 // keep a reference to the data in case the selection is changed during paste 4246 uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer ); 4247 DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY ); 4248 } 4249 else 4250 { 4251 ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData(); 4252 if ( pDrawTransfer ) 4253 { 4254 // keep a reference to the data in case the selection is changed during paste 4255 uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer ); 4256 4257 // #96821# bSameDocClipboard argument for PasteDraw is needed 4258 // because only DragData is checked directly inside PasteDraw 4259 pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False, 4260 pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() ); 4261 } 4262 } 4263 } 4264 else 4265 { 4266 // get selection from system 4267 4268 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) ); 4269 uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable(); 4270 if ( xTransferable.is() ) 4271 { 4272 sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true ); 4273 if ( nFormatId ) 4274 { 4275 bPasteIsDrop = sal_True; 4276 pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos ); 4277 bPasteIsDrop = sal_False; 4278 } 4279 } 4280 } 4281 } 4282 4283 //-------------------------------------------------------- 4284 4285 void ScGridWindow::UpdateEditViewPos() 4286 { 4287 if (pViewData->HasEditView(eWhich)) 4288 { 4289 EditView* pView; 4290 SCCOL nCol; 4291 SCROW nRow; 4292 pViewData->GetEditView( eWhich, pView, nCol, nRow ); 4293 SCCOL nEndCol = pViewData->GetEditEndCol(); 4294 SCROW nEndRow = pViewData->GetEditEndRow(); 4295 4296 // hide EditView? 4297 4298 sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) ); 4299 if ( SC_MOD()->IsFormulaMode() ) 4300 if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() ) 4301 bHide = sal_True; 4302 4303 if (bHide) 4304 { 4305 Rectangle aRect = pView->GetOutputArea(); 4306 long nHeight = aRect.Bottom() - aRect.Top(); 4307 aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()). 4308 Height() * 2; 4309 aRect.Bottom() = aRect.Top() + nHeight; 4310 pView->SetOutputArea( aRect ); 4311 pView->HideCursor(); 4312 } 4313 else 4314 { 4315 // bForceToTop = sal_True for editing 4316 Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True ); 4317 Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() ); 4318 4319 Rectangle aRect = pView->GetOutputArea(); 4320 aRect.SetPos( aScrPos ); 4321 pView->SetOutputArea( aRect ); 4322 pView->ShowCursor(); 4323 } 4324 } 4325 } 4326 4327 void ScGridWindow::ScrollPixel( long nDifX, long nDifY ) 4328 { 4329 ClickExtern(); 4330 HideNoteMarker(); 4331 4332 bIsInScroll = sal_True; 4333 //sal_Bool bXor=DrawBeforeScroll(); 4334 4335 SetMapMode(MAP_PIXEL); 4336 Scroll( nDifX, nDifY, SCROLL_CHILDREN ); 4337 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen 4338 4339 UpdateEditViewPos(); 4340 4341 DrawAfterScroll(); //bXor); 4342 bIsInScroll = sal_False; 4343 } 4344 4345 // Formeln neu zeichnen ------------------------------------------------- 4346 4347 void ScGridWindow::UpdateFormulas() 4348 { 4349 if (pViewData->GetView()->IsMinimized()) 4350 return; 4351 4352 if ( nPaintCount ) 4353 { 4354 // nicht anfangen, verschachtelt zu painten 4355 // (dann wuerde zumindest der MapMode nicht mehr stimmen) 4356 4357 bNeedsRepaint = sal_True; // -> am Ende vom Paint nochmal Invalidate auf alles 4358 aRepaintPixel = Rectangle(); // alles 4359 return; 4360 } 4361 4362 SCCOL nX1 = pViewData->GetPosX( eHWhich ); 4363 SCROW nY1 = pViewData->GetPosY( eVWhich ); 4364 SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich ); 4365 SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich ); 4366 4367 if (nX2 > MAXCOL) nX2 = MAXCOL; 4368 if (nY2 > MAXROW) nY2 = MAXROW; 4369 4370 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED ); 4371 4372 // don't draw directly - instead use OutputData to find changed area and invalidate 4373 4374 SCROW nPosY = nY1; 4375 4376 ScDocShell* pDocSh = pViewData->GetDocShell(); 4377 ScDocument* pDoc = pDocSh->GetDocument(); 4378 SCTAB nTab = pViewData->GetTabNo(); 4379 4380 pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab ); 4381 4382 Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); 4383 long nMirrorWidth = GetSizePixel().Width(); 4384 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 4385 // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1; 4386 if ( bLayoutRTL ) 4387 { 4388 long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X(); 4389 nMirrorWidth = aScrPos.X() - nEndPixel; 4390 aScrPos.X() = nEndPixel + 1; 4391 } 4392 4393 long nScrX = aScrPos.X(); 4394 long nScrY = aScrPos.Y(); 4395 4396 double nPPTX = pViewData->GetPPTX(); 4397 double nPPTY = pViewData->GetPPTY(); 4398 4399 ScTableInfo aTabInfo; 4400 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False ); 4401 4402 Fraction aZoomX = pViewData->GetZoomX(); 4403 Fraction aZoomY = pViewData->GetZoomY(); 4404 ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab, 4405 nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY, 4406 &aZoomX, &aZoomY ); 4407 aOutputData.SetMirrorWidth( nMirrorWidth ); 4408 4409 aOutputData.FindChanged(); 4410 4411 PolyPolygon aChangedPoly( aOutputData.GetChangedArea() ); // logic (PixelToLogic) 4412 if ( aChangedPoly.Count() ) 4413 { 4414 Invalidate( aChangedPoly ); 4415 } 4416 4417 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here 4418 } 4419 4420 void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange) 4421 { 4422 if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) ) 4423 { 4424 HideCursor(); 4425 bAutoMarkVisible = bMarked; 4426 if ( bMarked ) 4427 aAutoMarkPos = rMarkRange.aEnd; 4428 ShowCursor(); 4429 4430 UpdateAutoFillOverlay(); 4431 } 4432 } 4433 4434 void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos ) 4435 { 4436 sal_Bool bOldButton = bListValButton; 4437 ScAddress aOldPos = aListValPos; 4438 4439 bListValButton = bVisible; 4440 aListValPos = rPos; 4441 4442 if ( bListValButton ) 4443 { 4444 if ( !bOldButton || aListValPos != aOldPos ) 4445 { 4446 // paint area of new button 4447 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) ); 4448 } 4449 } 4450 if ( bOldButton ) 4451 { 4452 if ( !bListValButton || aListValPos != aOldPos ) 4453 { 4454 // paint area of old button 4455 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) ); 4456 } 4457 } 4458 } 4459 4460 void ScGridWindow::HideCursor() 4461 { 4462 ++nCursorHideCount; 4463 if (nCursorHideCount==1) 4464 { 4465 DrawCursor(); 4466 DrawAutoFillMark(); 4467 } 4468 } 4469 4470 void ScGridWindow::ShowCursor() 4471 { 4472 if (nCursorHideCount==0) 4473 { 4474 DBG_ERROR("zuviel ShowCursor"); 4475 return; 4476 } 4477 4478 if (nCursorHideCount==1) 4479 { 4480 // #i57745# Draw the cursor before setting the variable, in case the 4481 // GetSizePixel call from drawing causes a repaint (resize handler is called) 4482 DrawAutoFillMark(); 4483 DrawCursor(); 4484 } 4485 4486 --nCursorHideCount; 4487 } 4488 4489 void __EXPORT ScGridWindow::GetFocus() 4490 { 4491 ScTabViewShell* pViewShell = pViewData->GetViewShell(); 4492 pViewShell->GotFocus(); 4493 pViewShell->SetFormShellAtTop( sal_False ); // focus in GridWindow -> FormShell no longer on top 4494 4495 if (pViewShell->HasAccessibilityObjects()) 4496 pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible())); 4497 4498 4499 if ( !SC_MOD()->IsFormulaMode() ) 4500 { 4501 pViewShell->UpdateInputHandler(); 4502 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp 4503 // MO: nur wenn nicht im RefInput-Modus 4504 // -> GetFocus/MouseButtonDown-Reihenfolge 4505 // auf dem Mac 4506 } 4507 4508 Window::GetFocus(); 4509 } 4510 4511 void __EXPORT ScGridWindow::LoseFocus() 4512 { 4513 ScTabViewShell* pViewShell = pViewData->GetViewShell(); 4514 pViewShell->LostFocus(); 4515 4516 if (pViewShell->HasAccessibilityObjects()) 4517 pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible())); 4518 4519 Window::LoseFocus(); 4520 } 4521 4522 Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; } 4523 4524 //------------------------------------------------------------------------ 4525 4526 sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner, 4527 sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY ) 4528 { 4529 sal_Bool bFound = sal_False; 4530 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); 4531 if (pHdl) 4532 { 4533 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); 4534 if ( pRangeFinder && !pRangeFinder->IsHidden() && 4535 pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() ) 4536 { 4537 ScDocument* pDoc = pViewData->GetDocument(); 4538 SCTAB nTab = pViewData->GetTabNo(); 4539 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 4540 long nLayoutSign = bLayoutRTL ? -1 : 1; 4541 4542 SCsCOL nPosX; 4543 SCsROW nPosY; 4544 pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY ); 4545 // zusammengefasste (einzeln/Bereich) ??? 4546 ScAddress aAddr( nPosX, nPosY, nTab ); 4547 4548 // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich ); 4549 4550 Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True ); 4551 long nSizeXPix; 4552 long nSizeYPix; 4553 pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix ); 4554 aNext.X() += nSizeXPix * nLayoutSign; 4555 aNext.Y() += nSizeYPix; 4556 4557 sal_Bool bCornerHor; 4558 if ( bLayoutRTL ) 4559 bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 ); 4560 else 4561 bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() ); 4562 4563 sal_Bool bCellCorner = ( bCornerHor && 4564 rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() ); 4565 // corner is hit only if the mouse is within the cell 4566 4567 sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count(); 4568 for (sal_uInt16 i=nCount; i;) 4569 { 4570 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird 4571 --i; 4572 ScRangeFindData* pData = pRangeFinder->GetObject(i); 4573 if ( pData && pData->aRef.In(aAddr) ) 4574 { 4575 if (pIndex) *pIndex = i; 4576 if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col(); 4577 if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row(); 4578 bFound = sal_True; 4579 rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd ); 4580 break; 4581 } 4582 } 4583 } 4584 } 4585 return bFound; 4586 } 4587 4588 #define SCE_TOP 1 4589 #define SCE_BOTTOM 2 4590 #define SCE_LEFT 4 4591 #define SCE_RIGHT 8 4592 #define SCE_ALL 15 4593 4594 void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges ) 4595 { 4596 // der Range ist immer richtigherum 4597 4598 SCCOL nCol1 = rRange.aStart.Col(); 4599 SCROW nRow1 = rRange.aStart.Row(); 4600 SCTAB nTab1 = rRange.aStart.Tab(); 4601 SCCOL nCol2 = rRange.aEnd.Col(); 4602 SCROW nRow2 = rRange.aEnd.Row(); 4603 SCTAB nTab2 = rRange.aEnd.Tab(); 4604 sal_Bool bHiddenEdge = sal_False; 4605 SCROW nTmp; 4606 4607 ScDocument* pDoc = pDocSh->GetDocument(); 4608 while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) ) 4609 { 4610 --nCol1; 4611 bHiddenEdge = sal_True; 4612 } 4613 while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) ) 4614 { 4615 ++nCol2; 4616 bHiddenEdge = sal_True; 4617 } 4618 nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1); 4619 if (!ValidRow(nTmp)) 4620 nTmp = 0; 4621 if (nTmp < nRow1) 4622 { 4623 nRow1 = nTmp; 4624 bHiddenEdge = sal_True; 4625 } 4626 nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1); 4627 if (!ValidRow(nTmp)) 4628 nTmp = MAXROW; 4629 if (nTmp > nRow2) 4630 { 4631 nRow2 = nTmp; 4632 bHiddenEdge = sal_True; 4633 } 4634 4635 if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge ) 4636 { 4637 // nur an den Raendern entlang 4638 // (die Ecken werden evtl. zweimal getroffen) 4639 4640 if ( nEdges & SCE_TOP ) 4641 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS ); 4642 if ( nEdges & SCE_LEFT ) 4643 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS ); 4644 if ( nEdges & SCE_RIGHT ) 4645 pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4646 if ( nEdges & SCE_BOTTOM ) 4647 pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4648 } 4649 else // everything in one call 4650 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4651 } 4652 4653 void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn ) 4654 { 4655 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind 4656 4657 ScRange aOld = rOldUn; 4658 ScRange aNew = rNewUn; 4659 aOld.Justify(); 4660 aNew.Justify(); 4661 4662 if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren? 4663 pDocSh->GetDocument()->ExtendMerge(aOld); 4664 if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren? 4665 pDocSh->GetDocument()->ExtendMerge(aNew); 4666 4667 SCCOL nOldCol1 = aOld.aStart.Col(); 4668 SCROW nOldRow1 = aOld.aStart.Row(); 4669 SCCOL nOldCol2 = aOld.aEnd.Col(); 4670 SCROW nOldRow2 = aOld.aEnd.Row(); 4671 SCCOL nNewCol1 = aNew.aStart.Col(); 4672 SCROW nNewRow1 = aNew.aStart.Row(); 4673 SCCOL nNewCol2 = aNew.aEnd.Col(); 4674 SCROW nNewRow2 = aNew.aEnd.Row(); 4675 SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht 4676 SCTAB nTab2 = aOld.aEnd.Tab(); 4677 4678 if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 || 4679 nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 || 4680 ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 && 4681 nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) ) 4682 { 4683 // komplett weggeschoben oder alle Seiten veraendert 4684 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten) 4685 4686 lcl_PaintOneRange( pDocSh, aOld, SCE_ALL ); 4687 } 4688 else // alle vier Kanten einzeln testen 4689 { 4690 // oberer Teil 4691 if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen 4692 lcl_PaintOneRange( pDocSh, ScRange( 4693 nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL ); 4694 else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt 4695 lcl_PaintOneRange( pDocSh, ScRange( 4696 nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ), 4697 SCE_ALL &~ SCE_BOTTOM ); 4698 4699 // unterer Teil 4700 if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen 4701 lcl_PaintOneRange( pDocSh, ScRange( 4702 nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); 4703 else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt 4704 lcl_PaintOneRange( pDocSh, ScRange( 4705 nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ), 4706 SCE_ALL &~ SCE_TOP ); 4707 4708 // linker Teil 4709 if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen 4710 lcl_PaintOneRange( pDocSh, ScRange( 4711 nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL ); 4712 else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt 4713 lcl_PaintOneRange( pDocSh, ScRange( 4714 nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ), 4715 SCE_ALL &~ SCE_RIGHT ); 4716 4717 // rechter Teil 4718 if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen 4719 lcl_PaintOneRange( pDocSh, ScRange( 4720 nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); 4721 else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt 4722 lcl_PaintOneRange( pDocSh, ScRange( 4723 nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), 4724 SCE_ALL &~ SCE_LEFT ); 4725 } 4726 } 4727 4728 void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp ) 4729 { 4730 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); 4731 if (!pHdl) 4732 return; 4733 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); 4734 if (!pRangeFinder || nRFIndex >= pRangeFinder->Count()) 4735 return; 4736 ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex ); 4737 if (!pData) 4738 return; 4739 4740 // Mauszeiger 4741 4742 if (bRFSize) 4743 SetPointer( Pointer( POINTER_CROSS ) ); 4744 else 4745 SetPointer( Pointer( POINTER_HAND ) ); 4746 4747 // Scrolling 4748 4749 sal_Bool bTimer = sal_False; 4750 Point aPos = rMEvt.GetPosPixel(); 4751 SCsCOL nDx = 0; 4752 SCsROW nDy = 0; 4753 if ( aPos.X() < 0 ) nDx = -1; 4754 if ( aPos.Y() < 0 ) nDy = -1; 4755 Size aSize = GetOutputSizePixel(); 4756 if ( aPos.X() >= aSize.Width() ) 4757 nDx = 1; 4758 if ( aPos.Y() >= aSize.Height() ) 4759 nDy = 1; 4760 if ( nDx != 0 || nDy != 0 ) 4761 { 4762 if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) ); 4763 if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) ); 4764 bTimer = sal_True; 4765 } 4766 4767 // Umschalten bei Fixierung (damit Scrolling funktioniert) 4768 4769 if ( eWhich == pViewData->GetActivePart() ) //?? 4770 { 4771 if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ) 4772 if ( nDx > 0 ) 4773 { 4774 if ( eWhich == SC_SPLIT_TOPLEFT ) 4775 pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ); 4776 else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) 4777 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); 4778 } 4779 4780 if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) 4781 if ( nDy > 0 ) 4782 { 4783 if ( eWhich == SC_SPLIT_TOPLEFT ) 4784 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ); 4785 else if ( eWhich == SC_SPLIT_TOPRIGHT ) 4786 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); 4787 } 4788 } 4789 4790 // Verschieben 4791 4792 SCsCOL nPosX; 4793 SCsROW nPosY; 4794 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4795 4796 ScRange aOld = pData->aRef; 4797 ScRange aNew = aOld; 4798 if ( bRFSize ) 4799 { 4800 aNew.aEnd.SetCol((SCCOL)nPosX); 4801 aNew.aEnd.SetRow((SCROW)nPosY); 4802 } 4803 else 4804 { 4805 long nStartX = nPosX - nRFAddX; 4806 if ( nStartX < 0 ) nStartX = 0; 4807 long nStartY = nPosY - nRFAddY; 4808 if ( nStartY < 0 ) nStartY = 0; 4809 long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col(); 4810 if ( nEndX > MAXCOL ) 4811 { 4812 nStartX -= ( nEndX - MAXROW ); 4813 nEndX = MAXCOL; 4814 } 4815 long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row(); 4816 if ( nEndY > MAXROW ) 4817 { 4818 nStartY -= ( nEndY - MAXROW ); 4819 nEndY = MAXROW; 4820 } 4821 4822 aNew.aStart.SetCol((SCCOL)nStartX); 4823 aNew.aStart.SetRow((SCROW)nStartY); 4824 aNew.aEnd.SetCol((SCCOL)nEndX); 4825 aNew.aEnd.SetRow((SCROW)nEndY); 4826 } 4827 4828 if ( bUp ) 4829 aNew.Justify(); // beim ButtonUp wieder richtigherum 4830 4831 if ( aNew != aOld ) 4832 { 4833 pHdl->UpdateRange( nRFIndex, aNew ); 4834 4835 ScDocShell* pDocSh = pViewData->GetDocShell(); 4836 4837 // nur das neuzeichnen, was sich veraendert hat... 4838 lcl_PaintRefChanged( pDocSh, aOld, aNew ); 4839 4840 // neuen Rahmen nur drueberzeichnen (synchron) 4841 pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) ); 4842 4843 Update(); // was man bewegt, will man auch sofort sehen 4844 } 4845 4846 // Timer fuer Scrolling 4847 4848 if (bTimer) 4849 pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen 4850 else 4851 pViewData->GetView()->ResetTimer(); 4852 } 4853 4854 //------------------------------------------------------------------------ 4855 4856 sal_Bool ScGridWindow::GetEditUrl( const Point& rPos, 4857 String* pName, String* pUrl, String* pTarget ) 4858 { 4859 return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget ); 4860 } 4861 4862 sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos, 4863 String* pName, String* pUrl, String* pTarget ) 4864 { 4865 //! nPosX/Y mit uebergeben? 4866 SCsCOL nPosX; 4867 SCsROW nPosY; 4868 pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY ); 4869 4870 SCTAB nTab = pViewData->GetTabNo(); 4871 ScDocShell* pDocSh = pViewData->GetDocShell(); 4872 ScDocument* pDoc = pDocSh->GetDocument(); 4873 ScBaseCell* pCell = NULL; 4874 4875 sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ); 4876 if( !bFound ) 4877 return sal_False; 4878 4879 ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed) 4880 4881 const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab ); 4882 // bForceToTop = sal_False, use the cell's real position 4883 Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False ); 4884 if (rPos.Y() < aEditRect.Top()) 4885 return sal_False; 4886 4887 // vertikal kann (noch) nicht angeklickt werden: 4888 4889 if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) 4890 return sal_False; 4891 4892 sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() || 4893 ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> 4894 GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK); 4895 SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern-> 4896 GetItem(ATTR_HOR_JUSTIFY)).GetValue(); 4897 4898 // EditEngine 4899 4900 ScFieldEditEngine aEngine( pDoc->GetEditPool() ); 4901 ScSizeDeviceProvider aProv(pDocSh); 4902 aEngine.SetRefDevice( aProv.GetDevice() ); 4903 aEngine.SetRefMapMode( MAP_100TH_MM ); 4904 SfxItemSet aDefault( aEngine.GetEmptyItemSet() ); 4905 pPattern->FillEditItemSet( &aDefault ); 4906 SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT; 4907 switch (eHorJust) 4908 { 4909 case SVX_HOR_JUSTIFY_LEFT: 4910 case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert 4911 case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type 4912 eSvxAdjust = SVX_ADJUST_LEFT; 4913 break; 4914 case SVX_HOR_JUSTIFY_RIGHT: 4915 eSvxAdjust = SVX_ADJUST_RIGHT; 4916 break; 4917 case SVX_HOR_JUSTIFY_CENTER: 4918 eSvxAdjust = SVX_ADJUST_CENTER; 4919 break; 4920 case SVX_HOR_JUSTIFY_BLOCK: 4921 eSvxAdjust = SVX_ADJUST_BLOCK; 4922 break; 4923 } 4924 aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); 4925 aEngine.SetDefaults( aDefault ); 4926 if (bSpellErr) 4927 aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING ); 4928 4929 MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung 4930 Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode ); 4931 long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1; 4932 Size aPaperSize = Size( 1000000, 1000000 ); 4933 if(pCell->GetCellType() == CELLTYPE_FORMULA) 4934 { 4935 long nSizeX = 0; 4936 long nSizeY = 0; 4937 pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY ); 4938 aPaperSize = Size(nSizeX, nSizeY ); 4939 aPaperSize = PixelToLogic(aPaperSize); 4940 } 4941 4942 if (bBreak) 4943 aPaperSize.Width() = nThisColLogic; 4944 aEngine.SetPaperSize( aPaperSize ); 4945 4946 ::std::auto_ptr< EditTextObject > pTextObj; 4947 const EditTextObject* pData; 4948 if(pCell->GetCellType() == CELLTYPE_EDIT) 4949 { 4950 ((ScEditCell*)pCell)->GetData(pData); 4951 if (pData) 4952 aEngine.SetText(*pData); 4953 } 4954 else // HyperLink Formula cell 4955 { 4956 pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject()); 4957 if (pTextObj.get()) 4958 aEngine.SetText(*pTextObj); 4959 } 4960 4961 long nStartX = aLogicEdit.Left(); 4962 4963 long nTextWidth = aEngine.CalcTextWidth(); 4964 long nTextHeight = aEngine.GetTextHeight(); 4965 if ( nTextWidth < nThisColLogic ) 4966 { 4967 if (eHorJust == SVX_HOR_JUSTIFY_RIGHT) 4968 nStartX += nThisColLogic - nTextWidth; 4969 else if (eHorJust == SVX_HOR_JUSTIFY_CENTER) 4970 nStartX += (nThisColLogic - nTextWidth) / 2; 4971 } 4972 4973 aLogicEdit.Left() = nStartX; 4974 if (!bBreak) 4975 aLogicEdit.Right() = nStartX + nTextWidth; 4976 4977 // There is one glitch when dealing with a hyperlink cell and 4978 // the cell content is NUMERIC. This defaults to right aligned and 4979 // we need to adjust accordingly. 4980 if(pCell->GetCellType() == CELLTYPE_FORMULA && 4981 static_cast<ScFormulaCell*>(pCell)->IsValue() && 4982 eHorJust == SVX_HOR_JUSTIFY_STANDARD) 4983 { 4984 aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1; 4985 aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth; 4986 } 4987 aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight; 4988 4989 4990 Point aLogicClick = PixelToLogic(rPos,aEditMode); 4991 if ( aLogicEdit.IsInside(aLogicClick) ) 4992 { 4993 // aEngine.SetUpdateMode(sal_False); 4994 EditView aTempView( &aEngine, this ); 4995 aTempView.SetOutputArea( aLogicEdit ); 4996 4997 sal_Bool bRet = sal_False; 4998 MapMode aOld = GetMapMode(); 4999 SetMapMode(aEditMode); // kein return mehr 5000 5001 if (bSpellErr) // Spelling-Fehler suchen 5002 { 5003 bRet = aTempView.IsWrongSpelledWordAtPos( rPos ); 5004 if ( bRet ) 5005 pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen 5006 } 5007 else // URL suchen 5008 { 5009 const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer(); 5010 5011 if (pFieldItem) 5012 { 5013 const SvxFieldData* pField = pFieldItem->GetField(); 5014 if ( pField && pField->ISA(SvxURLField) ) 5015 { 5016 if ( pName || pUrl || pTarget ) 5017 { 5018 const SvxURLField* pURLField = (const SvxURLField*)pField; 5019 if (pName) 5020 *pName = pURLField->GetRepresentation(); 5021 if (pUrl) 5022 *pUrl = pURLField->GetURL(); 5023 if (pTarget) 5024 *pTarget = pURLField->GetTargetFrame(); 5025 } 5026 bRet = sal_True; 5027 } 5028 } 5029 } 5030 5031 SetMapMode(aOld); 5032 5033 // text cursor is restored in ScHideTextCursor dtor 5034 5035 return bRet; 5036 } 5037 return sal_False; 5038 } 5039 5040 sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange ) 5041 { 5042 ScDocument* pDoc = pViewData->GetDocument(); 5043 SCTAB nTab = pViewData->GetTabNo(); 5044 SCTAB nTabCount = pDoc->GetTableCount(); 5045 if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ) 5046 { 5047 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5048 5049 Size aButSize = pViewData->GetScenButSize(); 5050 long nBWidth = aButSize.Width(); 5051 if (!nBWidth) 5052 return sal_False; // noch kein Button gezeichnet -> da ist auch keiner 5053 long nBHeight = aButSize.Height(); 5054 long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() ); 5055 5056 //! Ranges an der Table cachen!!!! 5057 5058 ScMarkData aMarks; 5059 for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) 5060 pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); 5061 ScRangeList aRanges; 5062 aMarks.FillRangeListWithMarks( &aRanges, sal_False ); 5063 5064 5065 sal_uLong nRangeCount = aRanges.Count(); 5066 for (sal_uLong j=0; j<nRangeCount; j++) 5067 { 5068 ScRange aRange = *aRanges.GetObject(j); 5069 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn 5070 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden 5071 pDoc->ExtendTotalMerge( aRange ); 5072 5073 sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); 5074 5075 Point aButtonPos; 5076 if ( bTextBelow ) 5077 { 5078 aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, 5079 eWhich, sal_True ); 5080 } 5081 else 5082 { 5083 aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(), 5084 eWhich, sal_True ); 5085 aButtonPos.Y() -= nBHeight; 5086 } 5087 if ( bLayoutRTL ) 5088 aButtonPos.X() -= nHSpace - 1; 5089 else 5090 aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom 5091 5092 Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) ); 5093 if ( aButRect.IsInside( rPosPixel ) ) 5094 { 5095 rScenRange = aRange; 5096 return sal_True; 5097 } 5098 } 5099 } 5100 5101 return sal_False; 5102 } 5103 5104 void ScGridWindow::UpdateVisibleRange() 5105 { 5106 // #163911# Update the visible range outside of paint (called when switching sheets). 5107 // Use the same logic here as in ScGridWindow::Draw. 5108 5109 SCCOL nPosX = pViewData->GetPosX( eHWhich ); 5110 SCROW nPosY = pViewData->GetPosY( eVWhich ); 5111 5112 SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); 5113 if (nXRight > MAXCOL) nXRight = MAXCOL; 5114 SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); 5115 if (nYBottom > MAXROW) nYBottom = MAXROW; 5116 5117 // Store the current visible range. 5118 maVisibleRange.mnCol1 = nPosX; 5119 maVisibleRange.mnCol2 = nXRight; 5120 maVisibleRange.mnRow1 = nPosY; 5121 maVisibleRange.mnRow2 = nYBottom; 5122 } 5123 5124 // #114409# 5125 void ScGridWindow::DrawLayerCreated() 5126 { 5127 SetMapMode( GetDrawMapMode() ); 5128 5129 // initially create overlay objects 5130 ImpCreateOverlayObjects(); 5131 } 5132 5133 // #114409# 5134 void ScGridWindow::CursorChanged() 5135 { 5136 // here the created OverlayObjects may be transformed in later versions. For 5137 // now, just re-create them 5138 5139 UpdateCursorOverlay(); 5140 } 5141 5142 // #114409# 5143 void ScGridWindow::ImpCreateOverlayObjects() 5144 { 5145 UpdateCursorOverlay(); 5146 UpdateSelectionOverlay(); 5147 UpdateAutoFillOverlay(); 5148 UpdateDragRectOverlay(); 5149 UpdateHeaderOverlay(); 5150 UpdateShrinkOverlay(); 5151 } 5152 5153 // #114409# 5154 void ScGridWindow::ImpDestroyOverlayObjects() 5155 { 5156 DeleteCursorOverlay(); 5157 DeleteSelectionOverlay(); 5158 DeleteAutoFillOverlay(); 5159 DeleteDragRectOverlay(); 5160 DeleteHeaderOverlay(); 5161 DeleteShrinkOverlay(); 5162 } 5163 5164 void ScGridWindow::UpdateAllOverlays() 5165 { 5166 // delete and re-allocate all overlay objects 5167 5168 ImpDestroyOverlayObjects(); 5169 ImpCreateOverlayObjects(); 5170 } 5171 5172 void ScGridWindow::DeleteCursorOverlay() 5173 { 5174 DELETEZ( mpOOCursors ); 5175 } 5176 5177 void ScGridWindow::UpdateCursorOverlay() 5178 { 5179 MapMode aDrawMode = GetDrawMapMode(); 5180 MapMode aOldMode = GetMapMode(); 5181 if ( aOldMode != aDrawMode ) 5182 SetMapMode( aDrawMode ); 5183 5184 // Existing OverlayObjects may be transformed in later versions. 5185 // For now, just re-create them. 5186 5187 DeleteCursorOverlay(); 5188 5189 std::vector<Rectangle> aPixelRects; 5190 5191 // 5192 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor) 5193 // 5194 5195 SCTAB nTab = pViewData->GetTabNo(); 5196 SCCOL nX = pViewData->GetCurX(); 5197 SCROW nY = pViewData->GetCurY(); 5198 5199 if (!maVisibleRange.isInside(nX, nY)) 5200 return; 5201 5202 // don't show the cursor in overlapped cells 5203 5204 ScDocument* pDoc = pViewData->GetDocument(); 5205 const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab); 5206 const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG); 5207 sal_Bool bOverlapped = rMergeFlag.IsOverlapped(); 5208 5209 // left or above of the screen? 5210 5211 sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); 5212 if (!bVis) 5213 { 5214 SCCOL nEndX = nX; 5215 SCROW nEndY = nY; 5216 const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE); 5217 if (rMerge.GetColMerge() > 1) 5218 nEndX += rMerge.GetColMerge()-1; 5219 if (rMerge.GetRowMerge() > 1) 5220 nEndY += rMerge.GetRowMerge()-1; 5221 bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) ); 5222 } 5223 5224 if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) 5225 { 5226 Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 5227 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5228 5229 // completely right of/below the screen? 5230 // (test with logical start position in aScrPos) 5231 sal_Bool bMaybeVisible; 5232 if ( bLayoutRTL ) 5233 bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 ); 5234 else 5235 { 5236 Size aOutSize = GetOutputSizePixel(); 5237 bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 ); 5238 } 5239 if ( bMaybeVisible ) 5240 { 5241 long nSizeXPix; 5242 long nSizeYPix; 5243 pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 5244 5245 if ( bLayoutRTL ) 5246 aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring 5247 5248 sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX || 5249 pViewData->GetVSplitMode() == SC_SPLIT_FIX ); 5250 if ( pViewData->GetActivePart()==eWhich || bFix ) 5251 { 5252 aScrPos.X() -= 2; 5253 aScrPos.Y() -= 2; 5254 Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 5255 5256 aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() )); 5257 aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() )); 5258 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 )); 5259 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() )); 5260 } 5261 else 5262 { 5263 Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) ); 5264 aPixelRects.push_back( aRect ); 5265 } 5266 } 5267 } 5268 5269 if ( aPixelRects.size() ) 5270 { 5271 // #i70788# get the OverlayManager safely 5272 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5273 5274 if(pOverlayManager) 5275 { 5276 const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 5277 std::vector< basegfx::B2DRange > aRanges; 5278 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5279 5280 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5281 { 5282 const Rectangle aRA(aPixelRects[a]); 5283 basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); 5284 aRB.transform(aTransform); 5285 aRanges.push_back(aRB); 5286 } 5287 5288 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5289 sdr::overlay::OVERLAY_SOLID, 5290 aCursorColor, 5291 aRanges, 5292 false); 5293 5294 pOverlayManager->add(*pOverlay); 5295 mpOOCursors = new ::sdr::overlay::OverlayObjectList; 5296 mpOOCursors->append(*pOverlay); 5297 } 5298 } 5299 5300 if ( aOldMode != aDrawMode ) 5301 SetMapMode( aOldMode ); 5302 } 5303 5304 void ScGridWindow::DeleteSelectionOverlay() 5305 { 5306 DELETEZ( mpOOSelection ); 5307 } 5308 5309 void ScGridWindow::UpdateSelectionOverlay() 5310 { 5311 MapMode aDrawMode = GetDrawMapMode(); 5312 MapMode aOldMode = GetMapMode(); 5313 if ( aOldMode != aDrawMode ) 5314 SetMapMode( aDrawMode ); 5315 5316 DeleteSelectionOverlay(); 5317 std::vector<Rectangle> aPixelRects; 5318 GetSelectionRects( aPixelRects ); 5319 5320 if ( aPixelRects.size() && pViewData->IsActive() ) 5321 { 5322 // #i70788# get the OverlayManager safely 5323 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5324 5325 if(pOverlayManager) 5326 { 5327 std::vector< basegfx::B2DRange > aRanges; 5328 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5329 5330 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5331 { 5332 const Rectangle aRA(aPixelRects[a]); 5333 basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom()); 5334 aRB.transform(aTransform); 5335 aRanges.push_back(aRB); 5336 } 5337 5338 // #i97672# get the system's hilight color and limit it to the maximum 5339 // allowed luminance. This is needed to react on too bright hilight colors 5340 // which would otherwise vive a bad visualisation 5341 Color aHighlight(GetSettings().GetStyleSettings().GetHighlightColor()); 5342 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 5343 const basegfx::BColor aSelection(aHighlight.getBColor()); 5344 const double fLuminance(aSelection.luminance()); 5345 const double fMaxLum(aSvtOptionsDrawinglayer.GetSelectionMaximumLuminancePercent() / 100.0); 5346 5347 if(fLuminance > fMaxLum) 5348 { 5349 const double fFactor(fMaxLum / fLuminance); 5350 const basegfx::BColor aNewSelection( 5351 aSelection.getRed() * fFactor, 5352 aSelection.getGreen() * fFactor, 5353 aSelection.getBlue() * fFactor); 5354 5355 aHighlight = Color(aNewSelection); 5356 } 5357 5358 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5359 sdr::overlay::OVERLAY_TRANSPARENT, 5360 aHighlight, 5361 aRanges, 5362 true); 5363 5364 pOverlayManager->add(*pOverlay); 5365 mpOOSelection = new ::sdr::overlay::OverlayObjectList; 5366 mpOOSelection->append(*pOverlay); 5367 } 5368 } 5369 5370 if ( aOldMode != aDrawMode ) 5371 SetMapMode( aOldMode ); 5372 } 5373 5374 void ScGridWindow::DeleteAutoFillOverlay() 5375 { 5376 DELETEZ( mpOOAutoFill ); 5377 mpAutoFillRect.reset(); 5378 } 5379 5380 void ScGridWindow::UpdateAutoFillOverlay() 5381 { 5382 MapMode aDrawMode = GetDrawMapMode(); 5383 MapMode aOldMode = GetMapMode(); 5384 if ( aOldMode != aDrawMode ) 5385 SetMapMode( aDrawMode ); 5386 5387 DeleteAutoFillOverlay(); 5388 5389 // 5390 // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark) 5391 // 5392 5393 if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() && 5394 !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) 5395 { 5396 SCCOL nX = aAutoMarkPos.Col(); 5397 SCROW nY = aAutoMarkPos.Row(); 5398 5399 if (!maVisibleRange.isInside(nX, nY)) 5400 // Autofill mark is not visible. Bail out. 5401 return; 5402 5403 SCTAB nTab = pViewData->GetTabNo(); 5404 ScDocument* pDoc = pViewData->GetDocument(); 5405 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5406 5407 Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 5408 long nSizeXPix; 5409 long nSizeYPix; 5410 pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 5411 if ( bLayoutRTL ) 5412 aFillPos.X() -= nSizeXPix + 3; 5413 else 5414 aFillPos.X() += nSizeXPix - 2; 5415 5416 aFillPos.Y() += nSizeYPix; 5417 aFillPos.Y() -= 2; 5418 mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6))); 5419 5420 // #i70788# get the OverlayManager safely 5421 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5422 5423 if(pOverlayManager) 5424 { 5425 const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 5426 std::vector< basegfx::B2DRange > aRanges; 5427 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5428 basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1); 5429 5430 aRB.transform(aTransform); 5431 aRanges.push_back(aRB); 5432 5433 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5434 sdr::overlay::OVERLAY_SOLID, 5435 aHandleColor, 5436 aRanges, 5437 false); 5438 5439 pOverlayManager->add(*pOverlay); 5440 mpOOAutoFill = new ::sdr::overlay::OverlayObjectList; 5441 mpOOAutoFill->append(*pOverlay); 5442 } 5443 5444 if ( aOldMode != aDrawMode ) 5445 SetMapMode( aOldMode ); 5446 } 5447 } 5448 5449 void ScGridWindow::DeleteDragRectOverlay() 5450 { 5451 DELETEZ( mpOODragRect ); 5452 } 5453 5454 void ScGridWindow::UpdateDragRectOverlay() 5455 { 5456 MapMode aDrawMode = GetDrawMapMode(); 5457 MapMode aOldMode = GetMapMode(); 5458 if ( aOldMode != aDrawMode ) 5459 SetMapMode( aDrawMode ); 5460 5461 DeleteDragRectOverlay(); 5462 5463 // 5464 // get the rectangles in pixels (moved from DrawDragRect) 5465 // 5466 5467 if ( bDragRect || bPagebreakDrawn ) 5468 { 5469 std::vector<Rectangle> aPixelRects; 5470 5471 SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col(); 5472 SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row(); 5473 SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col(); 5474 SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row(); 5475 5476 SCTAB nTab = pViewData->GetTabNo(); 5477 5478 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich)); 5479 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich)); 5480 if (nX1 < nPosX) nX1 = nPosX; 5481 if (nX2 < nPosX) nX2 = nPosX; 5482 if (nY1 < nPosY) nY1 = nPosY; 5483 if (nY2 < nPosY) nY2 = nPosY; 5484 5485 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) ); 5486 5487 long nSizeXPix=0; 5488 long nSizeYPix=0; 5489 ScDocument* pDoc = pViewData->GetDocument(); 5490 double nPPTX = pViewData->GetPPTX(); 5491 double nPPTY = pViewData->GetPPTY(); 5492 SCCOLROW i; 5493 5494 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5495 long nLayoutSign = bLayoutRTL ? -1 : 1; 5496 5497 if (ValidCol(nX2) && nX2>=nX1) 5498 for (i=nX1; i<=nX2; i++) 5499 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX ); 5500 else 5501 { 5502 aScrPos.X() -= nLayoutSign; 5503 nSizeXPix += 2; 5504 } 5505 5506 if (ValidRow(nY2) && nY2>=nY1) 5507 for (i=nY1; i<=nY2; i++) 5508 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY ); 5509 else 5510 { 5511 aScrPos.Y() -= 1; 5512 nSizeYPix += 2; 5513 } 5514 5515 aScrPos.X() -= 2 * nLayoutSign; 5516 aScrPos.Y() -= 2; 5517 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 5518 Rectangle aRect( aScrPos.X(), aScrPos.Y(), 5519 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 ); 5520 if ( bLayoutRTL ) 5521 { 5522 aRect.Left() = aRect.Right(); // end position is left 5523 aRect.Right() = aScrPos.X(); 5524 } 5525 5526 if ( meDragInsertMode == INS_CELLSDOWN ) 5527 { 5528 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) ); 5529 aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) ); 5530 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) ); 5531 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) ); 5532 } 5533 else if ( meDragInsertMode == INS_CELLSRIGHT ) 5534 { 5535 aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) ); 5536 aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) ); 5537 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) ); 5538 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) ); 5539 } 5540 else 5541 { 5542 aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) ); 5543 aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) ); 5544 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) ); 5545 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) ); 5546 } 5547 5548 // #i70788# get the OverlayManager safely 5549 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5550 5551 if(pOverlayManager) 5552 { 5553 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5554 std::vector< basegfx::B2DRange > aRanges; 5555 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5556 5557 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5558 { 5559 const Rectangle aRA(aPixelRects[a]); 5560 basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); 5561 aRB.transform(aTransform); 5562 aRanges.push_back(aRB); 5563 } 5564 5565 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5566 sdr::overlay::OVERLAY_INVERT, 5567 Color(COL_BLACK), 5568 aRanges, 5569 false); 5570 5571 pOverlayManager->add(*pOverlay); 5572 mpOODragRect = new ::sdr::overlay::OverlayObjectList; 5573 mpOODragRect->append(*pOverlay); 5574 } 5575 } 5576 5577 if ( aOldMode != aDrawMode ) 5578 SetMapMode( aOldMode ); 5579 } 5580 5581 void ScGridWindow::DeleteHeaderOverlay() 5582 { 5583 DELETEZ( mpOOHeader ); 5584 } 5585 5586 void ScGridWindow::UpdateHeaderOverlay() 5587 { 5588 MapMode aDrawMode = GetDrawMapMode(); 5589 MapMode aOldMode = GetMapMode(); 5590 if ( aOldMode != aDrawMode ) 5591 SetMapMode( aDrawMode ); 5592 5593 DeleteHeaderOverlay(); 5594 5595 // Pixel rectangle is in aInvertRect 5596 if ( !aInvertRect.IsEmpty() ) 5597 { 5598 // #i70788# get the OverlayManager safely 5599 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5600 5601 if(pOverlayManager) 5602 { 5603 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5604 std::vector< basegfx::B2DRange > aRanges; 5605 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5606 basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1); 5607 5608 aRB.transform(aTransform); 5609 aRanges.push_back(aRB); 5610 5611 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5612 sdr::overlay::OVERLAY_INVERT, 5613 Color(COL_BLACK), 5614 aRanges, 5615 false); 5616 5617 pOverlayManager->add(*pOverlay); 5618 mpOOHeader = new ::sdr::overlay::OverlayObjectList; 5619 mpOOHeader->append(*pOverlay); 5620 } 5621 } 5622 5623 if ( aOldMode != aDrawMode ) 5624 SetMapMode( aOldMode ); 5625 } 5626 5627 void ScGridWindow::DeleteShrinkOverlay() 5628 { 5629 DELETEZ( mpOOShrink ); 5630 } 5631 5632 void ScGridWindow::UpdateShrinkOverlay() 5633 { 5634 MapMode aDrawMode = GetDrawMapMode(); 5635 MapMode aOldMode = GetMapMode(); 5636 if ( aOldMode != aDrawMode ) 5637 SetMapMode( aDrawMode ); 5638 5639 DeleteShrinkOverlay(); 5640 5641 // 5642 // get the rectangle in pixels 5643 // 5644 5645 Rectangle aPixRect; 5646 ScRange aRange; 5647 SCTAB nTab = pViewData->GetTabNo(); 5648 if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() && 5649 pViewData->GetDelMark( aRange ) ) 5650 { 5651 //! limit to visible area 5652 if ( aRange.aStart.Col() <= aRange.aEnd.Col() && 5653 aRange.aStart.Row() <= aRange.aEnd.Row() ) 5654 { 5655 Point aStart = pViewData->GetScrPos( aRange.aStart.Col(), 5656 aRange.aStart.Row(), eWhich ); 5657 Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1, 5658 aRange.aEnd.Row()+1, eWhich ); 5659 aEnd.X() -= 1; 5660 aEnd.Y() -= 1; 5661 5662 aPixRect = Rectangle( aStart,aEnd ); 5663 } 5664 } 5665 5666 if ( !aPixRect.IsEmpty() ) 5667 { 5668 // #i70788# get the OverlayManager safely 5669 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5670 5671 if(pOverlayManager) 5672 { 5673 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5674 std::vector< basegfx::B2DRange > aRanges; 5675 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5676 basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1); 5677 5678 aRB.transform(aTransform); 5679 aRanges.push_back(aRB); 5680 5681 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5682 sdr::overlay::OVERLAY_INVERT, 5683 Color(COL_BLACK), 5684 aRanges, 5685 false); 5686 5687 pOverlayManager->add(*pOverlay); 5688 mpOOShrink = new ::sdr::overlay::OverlayObjectList; 5689 mpOOShrink->append(*pOverlay); 5690 } 5691 } 5692 5693 if ( aOldMode != aDrawMode ) 5694 SetMapMode( aOldMode ); 5695 } 5696 5697 // #i70788# central method to get the OverlayManager safely 5698 ::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager() 5699 { 5700 SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView(); 5701 5702 if(pPV) 5703 { 5704 SdrPageWindow* pPageWin = pPV->FindPageWindow( *this ); 5705 5706 if ( pPageWin ) 5707 { 5708 return (pPageWin->GetOverlayManager()); 5709 } 5710 } 5711 5712 return 0L; 5713 } 5714 5715 void ScGridWindow::flushOverlayManager() 5716 { 5717 // #i70788# get the OverlayManager safely 5718 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5719 5720 if(pOverlayManager) 5721 { 5722 pOverlayManager->flush(); 5723 } 5724 } 5725 5726 // --------------------------------------------------------------------------- 5727 // eof 5728