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