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 context 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_FORMATSTR_ID_PNG) 3626 || IsDropFormatSupported(SOT_FORMAT_BITMAP) ) 3627 { 3628 // graphic dragged onto drawing object 3629 DrawMarkDropObj( pHitObj ); 3630 nRet = nMyAction; 3631 } 3632 } 3633 if (!nRet) 3634 DrawMarkDropObj( NULL ); 3635 3636 if (!nRet) 3637 { 3638 switch ( nMyAction ) 3639 { 3640 case DND_ACTION_COPY: 3641 case DND_ACTION_MOVE: 3642 case DND_ACTION_COPYMOVE: 3643 { 3644 sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE ); 3645 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) || 3646 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || 3647 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) || 3648 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 3649 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) || 3650 IsDropFormatSupported( SOT_FORMAT_STRING ) || 3651 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) || 3652 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || 3653 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) || 3654 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) || 3655 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) || 3656 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) || 3657 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) || 3658 IsDropFormatSupported( SOT_FORMAT_RTF ) || 3659 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) || 3660 IsDropFormatSupported( SOT_FORMATSTR_ID_PNG ) || 3661 IsDropFormatSupported( SOT_FORMAT_BITMAP ) || 3662 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) || 3663 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) || 3664 ( !bMove && ( 3665 IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || 3666 IsDropFormatSupported( SOT_FORMAT_FILE ) || 3667 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || 3668 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || 3669 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || 3670 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) ) 3671 { 3672 nRet = nMyAction; 3673 } 3674 } 3675 break; 3676 case DND_ACTION_LINK: 3677 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || 3678 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 3679 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || 3680 IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || 3681 IsDropFormatSupported( SOT_FORMAT_FILE ) || 3682 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || 3683 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || 3684 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || 3685 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3686 { 3687 nRet = nMyAction; 3688 } 3689 break; 3690 } 3691 3692 if ( nRet ) 3693 { 3694 // Simple check for protection: It's not known here if the drop will result 3695 // in cells or drawing objects (some formats can be both) and how many cells 3696 // the result will be. But if IsFormatEditable for the drop cell position 3697 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop 3698 // can already be rejected here. 3699 3700 Point aPos = rEvt.maPosPixel; 3701 SCsCOL nPosX; 3702 SCsROW nPosY; 3703 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 3704 SCTAB nTab = pViewData->GetTabNo(); 3705 ScDocument* pDoc = pViewData->GetDocument(); 3706 3707 ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY ); 3708 if ( !aTester.IsFormatEditable() ) 3709 nRet = DND_ACTION_NONE; // forbidden 3710 } 3711 } 3712 } 3713 3714 // scroll only for accepted formats 3715 if (nRet) 3716 DropScroll( rEvt.maPosPixel ); 3717 } 3718 3719 return nRet; 3720 } 3721 3722 sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false ) 3723 { 3724 TransferableDataHelper aDataHelper( xTransfer ); 3725 3726 if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) 3727 { 3728 // use bookmark formats if no sba is present 3729 3730 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) 3731 return SOT_FORMATSTR_ID_SOLK; 3732 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) 3733 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; 3734 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) 3735 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; 3736 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3737 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; 3738 } 3739 3740 sal_uLong nFormatId = 0; 3741 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) ) 3742 nFormatId = SOT_FORMATSTR_ID_DRAWING; 3743 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) ) 3744 nFormatId = SOT_FORMATSTR_ID_SVXB; 3745 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ) 3746 { 3747 // If it's a Writer object, insert RTF instead of OLE 3748 3749 sal_Bool bDoRtf = sal_False; 3750 SotStorageStreamRef xStm; 3751 TransferableObjectDescriptor aObjDesc; 3752 if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) && 3753 aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) ) 3754 { 3755 SotStorageRef xStore( new SotStorage( *xStm ) ); 3756 bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) || 3757 aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) ) 3758 && aDataHelper.HasFormat( SOT_FORMAT_RTF ) ); 3759 } 3760 if ( bDoRtf ) 3761 nFormatId = FORMAT_RTF; 3762 else 3763 nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE; 3764 } 3765 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) 3766 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; 3767 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) 3768 nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE; 3769 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ) 3770 nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE; 3771 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) ) 3772 nFormatId = SOT_FORMATSTR_ID_BIFF_8; 3773 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) ) 3774 nFormatId = SOT_FORMATSTR_ID_BIFF_5; 3775 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ) 3776 nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE; 3777 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ) 3778 nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE; 3779 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) 3780 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; 3781 else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) ) 3782 nFormatId = SOT_FORMAT_RTF; 3783 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) ) 3784 nFormatId = SOT_FORMATSTR_ID_HTML; 3785 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ) 3786 nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE; 3787 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) ) 3788 nFormatId = SOT_FORMATSTR_ID_SYLK; 3789 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) 3790 nFormatId = SOT_FORMATSTR_ID_LINK; 3791 else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting 3792 nFormatId = SOT_FORMAT_STRING; 3793 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) 3794 nFormatId = SOT_FORMAT_FILE_LIST; 3795 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers) 3796 nFormatId = SOT_FORMAT_FILE; 3797 else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) 3798 nFormatId = SOT_FORMAT_STRING; 3799 else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) ) 3800 nFormatId = SOT_FORMAT_GDIMETAFILE; 3801 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_PNG ) ) 3802 nFormatId = SOT_FORMATSTR_ID_PNG; 3803 else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) ) 3804 nFormatId = SOT_FORMAT_BITMAP; 3805 3806 return nFormatId; 3807 } 3808 3809 sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer ) 3810 { 3811 TransferableDataHelper aDataHelper( xTransfer ); 3812 3813 sal_uLong nFormatId = 0; 3814 if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) 3815 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; 3816 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) 3817 nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; 3818 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) 3819 nFormatId = SOT_FORMATSTR_ID_LINK; 3820 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) 3821 nFormatId = SOT_FORMAT_FILE_LIST; 3822 else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) 3823 nFormatId = SOT_FORMAT_FILE; 3824 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) 3825 nFormatId = SOT_FORMATSTR_ID_SOLK; 3826 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) 3827 nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; 3828 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) 3829 nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; 3830 else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) 3831 nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; 3832 3833 return nFormatId; 3834 } 3835 3836 3837 sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt ) 3838 { 3839 // hide drop marker 3840 // if (bDragRect) 3841 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); 3842 bDragRect = sal_False; 3843 UpdateDragRectOverlay(); 3844 3845 ScModule* pScMod = SC_MOD(); 3846 const ScDragData& rData = pScMod->GetDragData(); 3847 3848 return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY, 3849 PixelToLogic(rEvt.maPosPixel), rEvt.mnAction ); 3850 } 3851 3852 sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY, 3853 const Point& rLogicPos, sal_Int8 nDndAction ) 3854 { 3855 if ( !pTransObj ) 3856 return 0; 3857 3858 ScDocument* pSourceDoc = pTransObj->GetSourceDocument(); 3859 ScDocShell* pDocSh = pViewData->GetDocShell(); 3860 ScDocument* pThisDoc = pViewData->GetDocument(); 3861 ScViewFunc* pView = pViewData->GetView(); 3862 SCTAB nThisTab = pViewData->GetTabNo(); 3863 sal_uInt16 nFlags = pTransObj->GetDragSourceFlags(); 3864 3865 sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; 3866 sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi ); 3867 3868 // workaround for wrong nDndAction on Windows when pressing solely 3869 // the Alt key during drag and drop; 3870 // can be removed after #i79215# has been fixed 3871 if ( meDragInsertMode != INS_NONE ) 3872 { 3873 bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi ); 3874 } 3875 3876 sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK ); 3877 3878 ScRange aSource = pTransObj->GetRange(); 3879 3880 // only use visible tab from source range - when dragging within one table, 3881 // all selected tables at the time of dropping are used (handled in MoveBlockTo) 3882 SCTAB nSourceTab = pTransObj->GetVisibleTab(); 3883 aSource.aStart.SetTab( nSourceTab ); 3884 aSource.aEnd.SetTab( nSourceTab ); 3885 3886 SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1; 3887 SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) : 3888 pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows 3889 ScRange aDest( nDestPosX, nDestPosY, nThisTab, 3890 nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab ); 3891 3892 3893 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during 3894 * dragging and adapted drawing of the selection frame. We check here 3895 * (again) because this may actually also be called from PasteSelection(), 3896 * we would have to duplicate determination of flags and destination range 3897 * and would lose the context of the "filtered destination is OK" cases 3898 * below, which is already awkward enough as is. */ 3899 3900 // Don't move filtered source. 3901 bool bFiltered = (bIsMove && pTransObj->HasFilteredRows()); 3902 if (!bFiltered) 3903 { 3904 if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) || 3905 (!bIsLink && meDragInsertMode == INS_NONE))) 3906 { 3907 // Nothing. Either entire sheet to be dropped, or the one case 3908 // where PasteFromClip() is to be called that handles a filtered 3909 // destination itself. Drag-copy from another document without 3910 // inserting cells. 3911 } 3912 else 3913 // Don't copy or move to filtered destination. 3914 bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc); 3915 } 3916 3917 sal_Bool bDone = sal_False; 3918 3919 if (!bFiltered && pSourceDoc == pThisDoc) 3920 { 3921 if ( nFlags & SC_DROP_TABLE ) // whole sheet? 3922 { 3923 if ( pThisDoc->IsDocEditable() ) 3924 { 3925 SCTAB nSrcTab = aSource.aStart.Tab(); 3926 pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True ); // with Undo 3927 pView->SetTabNo( nThisTab, sal_True ); 3928 bDone = sal_True; 3929 } 3930 } 3931 else // move/copy block 3932 { 3933 String aChartName; 3934 if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName )) 3935 { 3936 String aRangeName; 3937 aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc ); 3938 SfxStringItem aNameItem( SID_CHART_NAME, aChartName ); 3939 SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName ); 3940 sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE; 3941 pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, 3942 &aRangeItem, &aNameItem, (void*) NULL ); 3943 bDone = sal_True; 3944 } 3945 else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) ) 3946 { 3947 // drop on DataPilot table: try to sort, fail if that isn't possible 3948 3949 ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab ); 3950 if ( aDestPos != aSource.aStart ) 3951 bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos ); 3952 else 3953 bDone = sal_True; // same position: nothing 3954 } 3955 else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() || 3956 nSourceTab != nThisTab ) 3957 { 3958 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); 3959 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 3960 3961 bDone = sal_True; 3962 if ( meDragInsertMode != INS_NONE ) 3963 { 3964 // call with bApi = sal_True to avoid error messages in drop handler 3965 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 3966 if ( bDone ) 3967 { 3968 if ( nThisTab == nSourceTab ) 3969 { 3970 if ( meDragInsertMode == INS_CELLSDOWN && 3971 nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() ) 3972 { 3973 bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc ); 3974 } 3975 else if ( meDragInsertMode == INS_CELLSRIGHT && 3976 nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() ) 3977 { 3978 bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc ); 3979 } 3980 } 3981 pDocSh->UpdateOle( pViewData ); 3982 pView->CellContentChanged(); 3983 } 3984 } 3985 3986 if ( bDone ) 3987 { 3988 if ( bIsLink ) 3989 { 3990 // call with bApi = sal_True to avoid error messages in drop handler 3991 bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ ); 3992 } 3993 else 3994 { 3995 // call with bApi = sal_True to avoid error messages in drop handler 3996 bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ ); 3997 } 3998 } 3999 4000 if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab ) 4001 { 4002 DelCellCmd eCmd = DEL_NONE; 4003 if ( meDragInsertMode == INS_CELLSDOWN ) 4004 { 4005 eCmd = DEL_CELLSUP; 4006 } 4007 else if ( meDragInsertMode == INS_CELLSRIGHT ) 4008 { 4009 eCmd = DEL_CELLSLEFT; 4010 } 4011 4012 if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) || 4013 ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) ) 4014 { 4015 // call with bApi = sal_True to avoid error messages in drop handler 4016 bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ ); 4017 if ( bDone ) 4018 { 4019 if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() ) 4020 { 4021 bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc ); 4022 } 4023 else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() ) 4024 { 4025 bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc ); 4026 } 4027 pDocSh->UpdateOle( pViewData ); 4028 pView->CellContentChanged(); 4029 } 4030 } 4031 } 4032 4033 if ( bDone ) 4034 { 4035 pView->MarkRange( aDest, sal_False, sal_False ); 4036 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 4037 } 4038 4039 pDocSh->GetUndoManager()->LeaveListAction(); 4040 4041 if (!bDone) 4042 Sound::Beep(); // instead of error message in drop handler 4043 } 4044 else 4045 bDone = sal_True; // nothing to do 4046 } 4047 4048 if (bDone) 4049 pTransObj->SetDragWasInternal(); // don't delete source in DragFinished 4050 } 4051 else if ( !bFiltered && pSourceDoc ) // between documents 4052 { 4053 if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents 4054 { 4055 if ( pThisDoc->IsDocEditable() ) 4056 { 4057 ScDocShell* pSrcShell = pTransObj->GetSourceDocShell(); 4058 4059 SCTAB nTabs[MAXTABCOUNT]; 4060 4061 ScMarkData aMark = pTransObj->GetSourceMarkData(); 4062 SCTAB nTabCount = pSourceDoc->GetTableCount(); 4063 SCTAB nTabSelCount = 0; 4064 4065 for(SCTAB i=0; i<nTabCount; i++) 4066 { 4067 if(aMark.GetTableSelect(i)) 4068 { 4069 nTabs[nTabSelCount++]=i; 4070 for(SCTAB j=i+1;j<nTabCount;j++) 4071 { 4072 if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j))) 4073 { 4074 nTabs[nTabSelCount++]=j; 4075 i=j; 4076 } 4077 else break; 4078 } 4079 } 4080 } 4081 4082 pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab ); 4083 bDone = sal_True; 4084 } 4085 } 4086 else if ( bIsLink ) 4087 { 4088 // as in PasteDDE 4089 // (external references might be used instead?) 4090 4091 SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell(); 4092 DBG_ASSERT(pSourceSh, "drag document has no shell"); 4093 if (pSourceSh) 4094 { 4095 String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY ); 4096 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 4097 4098 bDone = sal_True; 4099 if ( meDragInsertMode != INS_NONE ) 4100 { 4101 // call with bApi = sal_True to avoid error messages in drop handler 4102 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 4103 if ( bDone ) 4104 { 4105 pDocSh->UpdateOle( pViewData ); 4106 pView->CellContentChanged(); 4107 } 4108 } 4109 4110 if ( bDone ) 4111 { 4112 String aApp = Application::GetAppName(); 4113 String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME ); 4114 String aItem; 4115 aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc ); 4116 4117 // TODO: we could define ocQuote for " 4118 const String aQuote( '"' ); 4119 const String& sSep = ScCompiler::GetNativeSymbol( ocSep); 4120 String aFormula( '=' ); 4121 aFormula += ScCompiler::GetNativeSymbol( ocDde); 4122 aFormula += ScCompiler::GetNativeSymbol( ocOpen); 4123 aFormula += aQuote; 4124 aFormula += aApp; 4125 aFormula += aQuote; 4126 aFormula += sSep; 4127 aFormula += aQuote; 4128 aFormula += aTopic; 4129 aFormula += aQuote; 4130 aFormula += sSep; 4131 aFormula += aQuote; 4132 aFormula += aItem; 4133 aFormula += aQuote; 4134 aFormula += ScCompiler::GetNativeSymbol( ocClose); 4135 4136 pView->DoneBlockMode(); 4137 pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab ); 4138 pView->MarkCursor( nDestPosX + nSizeX - 1, 4139 nDestPosY + nSizeY - 1, nThisTab ); 4140 4141 pView->EnterMatrix( aFormula ); 4142 4143 pView->MarkRange( aDest, sal_False, sal_False ); 4144 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 4145 } 4146 4147 pDocSh->GetUndoManager()->LeaveListAction(); 4148 } 4149 } 4150 else 4151 { 4152 //! HasSelectedBlockMatrixFragment without selected sheet? 4153 //! or don't start dragging on a part of a matrix 4154 4155 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); 4156 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); 4157 4158 bDone = sal_True; 4159 if ( meDragInsertMode != INS_NONE ) 4160 { 4161 // call with bApi = sal_True to avoid error messages in drop handler 4162 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); 4163 if ( bDone ) 4164 { 4165 pDocSh->UpdateOle( pViewData ); 4166 pView->CellContentChanged(); 4167 } 4168 } 4169 4170 if ( bDone ) 4171 { 4172 pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection 4173 pView->SetCursor( nDestPosX, nDestPosY ); 4174 bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc 4175 if ( bDone ) 4176 { 4177 pView->MarkRange( aDest, sal_False, sal_False ); 4178 pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); 4179 } 4180 } 4181 4182 pDocSh->GetUndoManager()->LeaveListAction(); 4183 4184 // no longer call ResetMark here - the inserted block has been selected 4185 // and may have been copied to primary selection 4186 } 4187 } 4188 4189 sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE; 4190 return nRet; 4191 } 4192 4193 sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt ) 4194 { 4195 DrawMarkDropObj( NULL ); // drawing layer 4196 4197 ScModule* pScMod = SC_MOD(); 4198 const ScDragData& rData = pScMod->GetDragData(); 4199 if (rData.pCellTransfer) 4200 return ExecutePrivateDrop( rEvt ); 4201 4202 Point aPos = rEvt.maPosPixel; 4203 4204 if ( rData.aLinkDoc.Len() ) 4205 { 4206 // try to insert a link 4207 4208 sal_Bool bOk = sal_True; 4209 String aThisName; 4210 ScDocShell* pDocSh = pViewData->GetDocShell(); 4211 if (pDocSh && pDocSh->HasName()) 4212 aThisName = pDocSh->GetMedium()->GetName(); 4213 4214 if ( rData.aLinkDoc == aThisName ) // error - no link within a document 4215 bOk = sal_False; 4216 else 4217 { 4218 ScViewFunc* pView = pViewData->GetView(); 4219 if ( rData.aLinkTable.Len() ) 4220 pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, 4221 rData.aLinkTable ); 4222 else if ( rData.aLinkArea.Len() ) 4223 { 4224 SCsCOL nPosX; 4225 SCsROW nPosY; 4226 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4227 pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False ); 4228 4229 pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, 4230 rData.aLinkArea, 0 ); 4231 } 4232 else 4233 { 4234 DBG_ERROR("drop with link: no sheet nor area"); 4235 bOk = sal_False; 4236 } 4237 } 4238 4239 return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else 4240 } 4241 4242 Point aLogicPos = PixelToLogic(aPos); 4243 sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK ); 4244 4245 if (!bIsLink && rData.pDrawTransfer) 4246 { 4247 sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags(); 4248 4249 sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; 4250 sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi ); 4251 4252 bPasteIsMove = bIsMove; 4253 4254 pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() ); 4255 4256 if (bPasteIsMove) 4257 rData.pDrawTransfer->SetDragWasInternal(); 4258 bPasteIsMove = sal_False; 4259 4260 return rEvt.mnAction; 4261 } 4262 4263 4264 SCsCOL nPosX; 4265 SCsROW nPosY; 4266 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4267 4268 if (rData.aJumpTarget.Len()) 4269 { 4270 // internal bookmark (from Navigator) 4271 // bookmark clipboard formats are in PasteScDataObject 4272 4273 if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() ) 4274 { 4275 pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget, 4276 nPosX, nPosY ); 4277 return rEvt.mnAction; 4278 } 4279 } 4280 4281 ScDocument* pThisDoc = pViewData->GetDocument(); 4282 SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) ); 4283 if ( pHitObj && bIsLink ) 4284 { 4285 // dropped on drawing object 4286 // PasteOnDrawObjectLinked checks for valid formats 4287 if ( pViewData->GetView()->PasteOnDrawObjectLinked( rEvt.maDropEvent.Transferable, *pHitObj ) ) 4288 return rEvt.mnAction; 4289 } 4290 4291 sal_Bool bDone = sal_False; 4292 4293 sal_uLong nFormatId = bIsLink ? 4294 lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) : 4295 lcl_GetDropFormatId( rEvt.maDropEvent.Transferable ); 4296 if ( nFormatId ) 4297 { 4298 pScMod->SetInExecuteDrop( sal_True ); // #i28468# prevent error messages from PasteDataFormat 4299 bPasteIsDrop = sal_True; 4300 bDone = pViewData->GetView()->PasteDataFormat( 4301 nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink ); 4302 bPasteIsDrop = sal_False; 4303 pScMod->SetInExecuteDrop( sal_False ); 4304 } 4305 4306 sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE; 4307 return nRet; 4308 } 4309 4310 //-------------------------------------------------------- 4311 4312 void ScGridWindow::PasteSelection( const Point& rPosPixel ) 4313 { 4314 Point aLogicPos = PixelToLogic( rPosPixel ); 4315 4316 SCsCOL nPosX; 4317 SCsROW nPosY; 4318 pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY ); 4319 4320 ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer(); 4321 if ( pOwnSelection ) 4322 { 4323 // within Calc 4324 4325 ScTransferObj* pCellTransfer = pOwnSelection->GetCellData(); 4326 if ( pCellTransfer ) 4327 { 4328 // keep a reference to the data in case the selection is changed during paste 4329 uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer ); 4330 DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY ); 4331 } 4332 else 4333 { 4334 ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData(); 4335 if ( pDrawTransfer ) 4336 { 4337 // keep a reference to the data in case the selection is changed during paste 4338 uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer ); 4339 4340 // #96821# bSameDocClipboard argument for PasteDraw is needed 4341 // because only DragData is checked directly inside PasteDraw 4342 pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False, 4343 pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() ); 4344 } 4345 } 4346 } 4347 else 4348 { 4349 // get selection from system 4350 4351 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) ); 4352 uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable(); 4353 if ( xTransferable.is() ) 4354 { 4355 sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true ); 4356 if ( nFormatId ) 4357 { 4358 bPasteIsDrop = sal_True; 4359 pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos ); 4360 bPasteIsDrop = sal_False; 4361 } 4362 } 4363 } 4364 } 4365 4366 //-------------------------------------------------------- 4367 4368 void ScGridWindow::UpdateEditViewPos() 4369 { 4370 if (pViewData->HasEditView(eWhich)) 4371 { 4372 EditView* pView; 4373 SCCOL nCol; 4374 SCROW nRow; 4375 pViewData->GetEditView( eWhich, pView, nCol, nRow ); 4376 SCCOL nEndCol = pViewData->GetEditEndCol(); 4377 SCROW nEndRow = pViewData->GetEditEndRow(); 4378 4379 // hide EditView? 4380 4381 sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) ); 4382 if ( SC_MOD()->IsFormulaMode() ) 4383 if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() ) 4384 bHide = sal_True; 4385 4386 if (bHide) 4387 { 4388 Rectangle aRect = pView->GetOutputArea(); 4389 long nHeight = aRect.Bottom() - aRect.Top(); 4390 aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()). 4391 Height() * 2; 4392 aRect.Bottom() = aRect.Top() + nHeight; 4393 pView->SetOutputArea( aRect ); 4394 pView->HideCursor(); 4395 } 4396 else 4397 { 4398 // bForceToTop = sal_True for editing 4399 Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True ); 4400 Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() ); 4401 4402 Rectangle aRect = pView->GetOutputArea(); 4403 aRect.SetPos( aScrPos ); 4404 pView->SetOutputArea( aRect ); 4405 pView->ShowCursor(); 4406 } 4407 } 4408 } 4409 4410 void ScGridWindow::ScrollPixel( long nDifX, long nDifY ) 4411 { 4412 ClickExtern(); 4413 HideNoteMarker(); 4414 4415 bIsInScroll = sal_True; 4416 //sal_Bool bXor=DrawBeforeScroll(); 4417 4418 SetMapMode(MAP_PIXEL); 4419 Scroll( nDifX, nDifY, SCROLL_CHILDREN ); 4420 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen 4421 4422 UpdateEditViewPos(); 4423 4424 DrawAfterScroll(); //bXor); 4425 bIsInScroll = sal_False; 4426 } 4427 4428 // Formeln neu zeichnen ------------------------------------------------- 4429 4430 void ScGridWindow::UpdateFormulas() 4431 { 4432 if (pViewData->GetView()->IsMinimized()) 4433 return; 4434 4435 if ( nPaintCount ) 4436 { 4437 // nicht anfangen, verschachtelt zu painten 4438 // (dann wuerde zumindest der MapMode nicht mehr stimmen) 4439 4440 bNeedsRepaint = sal_True; // -> am Ende vom Paint nochmal Invalidate auf alles 4441 aRepaintPixel = Rectangle(); // alles 4442 return; 4443 } 4444 4445 SCCOL nX1 = pViewData->GetPosX( eHWhich ); 4446 SCROW nY1 = pViewData->GetPosY( eVWhich ); 4447 SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich ); 4448 SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich ); 4449 4450 if (nX2 > MAXCOL) nX2 = MAXCOL; 4451 if (nY2 > MAXROW) nY2 = MAXROW; 4452 4453 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED ); 4454 4455 // don't draw directly - instead use OutputData to find changed area and invalidate 4456 4457 SCROW nPosY = nY1; 4458 4459 ScDocShell* pDocSh = pViewData->GetDocShell(); 4460 ScDocument* pDoc = pDocSh->GetDocument(); 4461 SCTAB nTab = pViewData->GetTabNo(); 4462 4463 pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab ); 4464 4465 Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); 4466 long nMirrorWidth = GetSizePixel().Width(); 4467 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 4468 // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1; 4469 if ( bLayoutRTL ) 4470 { 4471 long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X(); 4472 nMirrorWidth = aScrPos.X() - nEndPixel; 4473 aScrPos.X() = nEndPixel + 1; 4474 } 4475 4476 long nScrX = aScrPos.X(); 4477 long nScrY = aScrPos.Y(); 4478 4479 double nPPTX = pViewData->GetPPTX(); 4480 double nPPTY = pViewData->GetPPTY(); 4481 4482 ScTableInfo aTabInfo; 4483 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False ); 4484 4485 Fraction aZoomX = pViewData->GetZoomX(); 4486 Fraction aZoomY = pViewData->GetZoomY(); 4487 ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab, 4488 nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY, 4489 &aZoomX, &aZoomY ); 4490 aOutputData.SetMirrorWidth( nMirrorWidth ); 4491 4492 aOutputData.FindChanged(); 4493 4494 // #122149# do not use old GetChangedArea() which used polygon-based Regions, but use 4495 // the region-band based new version; anyways, only rectangles are added 4496 Region aChangedRegion( aOutputData.GetChangedAreaRegion() ); // logic (PixelToLogic) 4497 if(!aChangedRegion.IsEmpty()) 4498 { 4499 Invalidate(aChangedRegion); 4500 } 4501 4502 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here 4503 } 4504 4505 void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange) 4506 { 4507 if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) ) 4508 { 4509 HideCursor(); 4510 bAutoMarkVisible = bMarked; 4511 if ( bMarked ) 4512 aAutoMarkPos = rMarkRange.aEnd; 4513 ShowCursor(); 4514 4515 UpdateAutoFillOverlay(); 4516 } 4517 } 4518 4519 void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos ) 4520 { 4521 sal_Bool bOldButton = bListValButton; 4522 ScAddress aOldPos = aListValPos; 4523 4524 bListValButton = bVisible; 4525 aListValPos = rPos; 4526 4527 if ( bListValButton ) 4528 { 4529 if ( !bOldButton || aListValPos != aOldPos ) 4530 { 4531 // paint area of new button 4532 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) ); 4533 } 4534 } 4535 if ( bOldButton ) 4536 { 4537 if ( !bListValButton || aListValPos != aOldPos ) 4538 { 4539 // paint area of old button 4540 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) ); 4541 } 4542 } 4543 } 4544 4545 void ScGridWindow::HideCursor() 4546 { 4547 ++nCursorHideCount; 4548 if (nCursorHideCount==1) 4549 { 4550 DrawCursor(); 4551 DrawAutoFillMark(); 4552 } 4553 } 4554 4555 void ScGridWindow::ShowCursor() 4556 { 4557 if (nCursorHideCount==0) 4558 { 4559 DBG_ERROR("zuviel ShowCursor"); 4560 return; 4561 } 4562 4563 if (nCursorHideCount==1) 4564 { 4565 // #i57745# Draw the cursor before setting the variable, in case the 4566 // GetSizePixel call from drawing causes a repaint (resize handler is called) 4567 DrawAutoFillMark(); 4568 DrawCursor(); 4569 } 4570 4571 --nCursorHideCount; 4572 } 4573 4574 void __EXPORT ScGridWindow::GetFocus() 4575 { 4576 ScTabViewShell* pViewShell = pViewData->GetViewShell(); 4577 pViewShell->GotFocus(); 4578 pViewShell->SetFormShellAtTop( sal_False ); // focus in GridWindow -> FormShell no longer on top 4579 4580 if (pViewShell->HasAccessibilityObjects()) 4581 pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible())); 4582 4583 4584 if ( !SC_MOD()->IsFormulaMode() ) 4585 { 4586 pViewShell->UpdateInputHandler(); 4587 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp 4588 // MO: nur wenn nicht im RefInput-Modus 4589 // -> GetFocus/MouseButtonDown-Reihenfolge 4590 // auf dem Mac 4591 } 4592 4593 Window::GetFocus(); 4594 } 4595 4596 void __EXPORT ScGridWindow::LoseFocus() 4597 { 4598 ScTabViewShell* pViewShell = pViewData->GetViewShell(); 4599 pViewShell->LostFocus(); 4600 4601 if (pViewShell->HasAccessibilityObjects()) 4602 pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible())); 4603 4604 Window::LoseFocus(); 4605 } 4606 4607 Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; } 4608 4609 //------------------------------------------------------------------------ 4610 4611 sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner, 4612 sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY ) 4613 { 4614 sal_Bool bFound = sal_False; 4615 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); 4616 if (pHdl) 4617 { 4618 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); 4619 if ( pRangeFinder && !pRangeFinder->IsHidden() && 4620 pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() ) 4621 { 4622 ScDocument* pDoc = pViewData->GetDocument(); 4623 SCTAB nTab = pViewData->GetTabNo(); 4624 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 4625 long nLayoutSign = bLayoutRTL ? -1 : 1; 4626 4627 SCsCOL nPosX; 4628 SCsROW nPosY; 4629 pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY ); 4630 // zusammengefasste (einzeln/Bereich) ??? 4631 ScAddress aAddr( nPosX, nPosY, nTab ); 4632 4633 // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich ); 4634 4635 Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True ); 4636 long nSizeXPix; 4637 long nSizeYPix; 4638 pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix ); 4639 aNext.X() += nSizeXPix * nLayoutSign; 4640 aNext.Y() += nSizeYPix; 4641 4642 sal_Bool bCornerHor; 4643 if ( bLayoutRTL ) 4644 bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 ); 4645 else 4646 bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() ); 4647 4648 sal_Bool bCellCorner = ( bCornerHor && 4649 rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() ); 4650 // corner is hit only if the mouse is within the cell 4651 4652 sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count(); 4653 for (sal_uInt16 i=nCount; i;) 4654 { 4655 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird 4656 --i; 4657 ScRangeFindData* pData = pRangeFinder->GetObject(i); 4658 if ( pData && pData->aRef.In(aAddr) ) 4659 { 4660 if (pIndex) *pIndex = i; 4661 if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col(); 4662 if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row(); 4663 bFound = sal_True; 4664 rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd ); 4665 break; 4666 } 4667 } 4668 } 4669 } 4670 return bFound; 4671 } 4672 4673 #define SCE_TOP 1 4674 #define SCE_BOTTOM 2 4675 #define SCE_LEFT 4 4676 #define SCE_RIGHT 8 4677 #define SCE_ALL 15 4678 4679 void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges ) 4680 { 4681 // der Range ist immer richtigherum 4682 4683 SCCOL nCol1 = rRange.aStart.Col(); 4684 SCROW nRow1 = rRange.aStart.Row(); 4685 SCTAB nTab1 = rRange.aStart.Tab(); 4686 SCCOL nCol2 = rRange.aEnd.Col(); 4687 SCROW nRow2 = rRange.aEnd.Row(); 4688 SCTAB nTab2 = rRange.aEnd.Tab(); 4689 sal_Bool bHiddenEdge = sal_False; 4690 SCROW nTmp; 4691 4692 ScDocument* pDoc = pDocSh->GetDocument(); 4693 while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) ) 4694 { 4695 --nCol1; 4696 bHiddenEdge = sal_True; 4697 } 4698 while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) ) 4699 { 4700 ++nCol2; 4701 bHiddenEdge = sal_True; 4702 } 4703 nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1); 4704 if (!ValidRow(nTmp)) 4705 nTmp = 0; 4706 if (nTmp < nRow1) 4707 { 4708 nRow1 = nTmp; 4709 bHiddenEdge = sal_True; 4710 } 4711 nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1); 4712 if (!ValidRow(nTmp)) 4713 nTmp = MAXROW; 4714 if (nTmp > nRow2) 4715 { 4716 nRow2 = nTmp; 4717 bHiddenEdge = sal_True; 4718 } 4719 4720 if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge ) 4721 { 4722 // nur an den Raendern entlang 4723 // (die Ecken werden evtl. zweimal getroffen) 4724 4725 if ( nEdges & SCE_TOP ) 4726 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS ); 4727 if ( nEdges & SCE_LEFT ) 4728 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS ); 4729 if ( nEdges & SCE_RIGHT ) 4730 pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4731 if ( nEdges & SCE_BOTTOM ) 4732 pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4733 } 4734 else // everything in one call 4735 pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); 4736 } 4737 4738 void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn ) 4739 { 4740 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind 4741 4742 ScRange aOld = rOldUn; 4743 ScRange aNew = rNewUn; 4744 aOld.Justify(); 4745 aNew.Justify(); 4746 4747 if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren? 4748 pDocSh->GetDocument()->ExtendMerge(aOld); 4749 if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren? 4750 pDocSh->GetDocument()->ExtendMerge(aNew); 4751 4752 SCCOL nOldCol1 = aOld.aStart.Col(); 4753 SCROW nOldRow1 = aOld.aStart.Row(); 4754 SCCOL nOldCol2 = aOld.aEnd.Col(); 4755 SCROW nOldRow2 = aOld.aEnd.Row(); 4756 SCCOL nNewCol1 = aNew.aStart.Col(); 4757 SCROW nNewRow1 = aNew.aStart.Row(); 4758 SCCOL nNewCol2 = aNew.aEnd.Col(); 4759 SCROW nNewRow2 = aNew.aEnd.Row(); 4760 SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht 4761 SCTAB nTab2 = aOld.aEnd.Tab(); 4762 4763 if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 || 4764 nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 || 4765 ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 && 4766 nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) ) 4767 { 4768 // komplett weggeschoben oder alle Seiten veraendert 4769 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten) 4770 4771 lcl_PaintOneRange( pDocSh, aOld, SCE_ALL ); 4772 } 4773 else // alle vier Kanten einzeln testen 4774 { 4775 // oberer Teil 4776 if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen 4777 lcl_PaintOneRange( pDocSh, ScRange( 4778 nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL ); 4779 else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt 4780 lcl_PaintOneRange( pDocSh, ScRange( 4781 nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ), 4782 SCE_ALL &~ SCE_BOTTOM ); 4783 4784 // unterer Teil 4785 if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen 4786 lcl_PaintOneRange( pDocSh, ScRange( 4787 nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); 4788 else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt 4789 lcl_PaintOneRange( pDocSh, ScRange( 4790 nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ), 4791 SCE_ALL &~ SCE_TOP ); 4792 4793 // linker Teil 4794 if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen 4795 lcl_PaintOneRange( pDocSh, ScRange( 4796 nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL ); 4797 else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt 4798 lcl_PaintOneRange( pDocSh, ScRange( 4799 nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ), 4800 SCE_ALL &~ SCE_RIGHT ); 4801 4802 // rechter Teil 4803 if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen 4804 lcl_PaintOneRange( pDocSh, ScRange( 4805 nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); 4806 else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt 4807 lcl_PaintOneRange( pDocSh, ScRange( 4808 nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), 4809 SCE_ALL &~ SCE_LEFT ); 4810 } 4811 } 4812 4813 void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp ) 4814 { 4815 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); 4816 if (!pHdl) 4817 return; 4818 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); 4819 if (!pRangeFinder || nRFIndex >= pRangeFinder->Count()) 4820 return; 4821 ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex ); 4822 if (!pData) 4823 return; 4824 4825 // Mauszeiger 4826 4827 if (bRFSize) 4828 SetPointer( Pointer( POINTER_CROSS ) ); 4829 else 4830 SetPointer( Pointer( POINTER_HAND ) ); 4831 4832 // Scrolling 4833 4834 sal_Bool bTimer = sal_False; 4835 Point aPos = rMEvt.GetPosPixel(); 4836 SCsCOL nDx = 0; 4837 SCsROW nDy = 0; 4838 if ( aPos.X() < 0 ) nDx = -1; 4839 if ( aPos.Y() < 0 ) nDy = -1; 4840 Size aSize = GetOutputSizePixel(); 4841 if ( aPos.X() >= aSize.Width() ) 4842 nDx = 1; 4843 if ( aPos.Y() >= aSize.Height() ) 4844 nDy = 1; 4845 if ( nDx != 0 || nDy != 0 ) 4846 { 4847 if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) ); 4848 if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) ); 4849 bTimer = sal_True; 4850 } 4851 4852 // Umschalten bei Fixierung (damit Scrolling funktioniert) 4853 4854 if ( eWhich == pViewData->GetActivePart() ) //?? 4855 { 4856 if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ) 4857 if ( nDx > 0 ) 4858 { 4859 if ( eWhich == SC_SPLIT_TOPLEFT ) 4860 pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ); 4861 else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) 4862 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); 4863 } 4864 4865 if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) 4866 if ( nDy > 0 ) 4867 { 4868 if ( eWhich == SC_SPLIT_TOPLEFT ) 4869 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ); 4870 else if ( eWhich == SC_SPLIT_TOPRIGHT ) 4871 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); 4872 } 4873 } 4874 4875 // Verschieben 4876 4877 SCsCOL nPosX; 4878 SCsROW nPosY; 4879 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); 4880 4881 ScRange aOld = pData->aRef; 4882 ScRange aNew = aOld; 4883 if ( bRFSize ) 4884 { 4885 aNew.aEnd.SetCol((SCCOL)nPosX); 4886 aNew.aEnd.SetRow((SCROW)nPosY); 4887 } 4888 else 4889 { 4890 long nStartX = nPosX - nRFAddX; 4891 if ( nStartX < 0 ) nStartX = 0; 4892 long nStartY = nPosY - nRFAddY; 4893 if ( nStartY < 0 ) nStartY = 0; 4894 long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col(); 4895 if ( nEndX > MAXCOL ) 4896 { 4897 nStartX -= ( nEndX - MAXROW ); 4898 nEndX = MAXCOL; 4899 } 4900 long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row(); 4901 if ( nEndY > MAXROW ) 4902 { 4903 nStartY -= ( nEndY - MAXROW ); 4904 nEndY = MAXROW; 4905 } 4906 4907 aNew.aStart.SetCol((SCCOL)nStartX); 4908 aNew.aStart.SetRow((SCROW)nStartY); 4909 aNew.aEnd.SetCol((SCCOL)nEndX); 4910 aNew.aEnd.SetRow((SCROW)nEndY); 4911 } 4912 4913 if ( bUp ) 4914 aNew.Justify(); // beim ButtonUp wieder richtigherum 4915 4916 if ( aNew != aOld ) 4917 { 4918 pHdl->UpdateRange( nRFIndex, aNew ); 4919 4920 ScDocShell* pDocSh = pViewData->GetDocShell(); 4921 4922 // nur das neuzeichnen, was sich veraendert hat... 4923 lcl_PaintRefChanged( pDocSh, aOld, aNew ); 4924 4925 // neuen Rahmen nur drueberzeichnen (synchron) 4926 pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) ); 4927 4928 Update(); // was man bewegt, will man auch sofort sehen 4929 } 4930 4931 // Timer fuer Scrolling 4932 4933 if (bTimer) 4934 pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen 4935 else 4936 pViewData->GetView()->ResetTimer(); 4937 } 4938 4939 //------------------------------------------------------------------------ 4940 4941 sal_Bool ScGridWindow::GetEditUrl( const Point& rPos, 4942 String* pName, String* pUrl, String* pTarget ) 4943 { 4944 return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget ); 4945 } 4946 4947 sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos, 4948 String* pName, String* pUrl, String* pTarget ) 4949 { 4950 //! nPosX/Y mit uebergeben? 4951 SCsCOL nPosX; 4952 SCsROW nPosY; 4953 pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY ); 4954 4955 SCTAB nTab = pViewData->GetTabNo(); 4956 ScDocShell* pDocSh = pViewData->GetDocShell(); 4957 ScDocument* pDoc = pDocSh->GetDocument(); 4958 ScBaseCell* pCell = NULL; 4959 4960 sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ); 4961 if( !bFound ) 4962 return sal_False; 4963 4964 ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed) 4965 4966 const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab ); 4967 // bForceToTop = sal_False, use the cell's real position 4968 Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False ); 4969 if (rPos.Y() < aEditRect.Top()) 4970 return sal_False; 4971 4972 // vertikal kann (noch) nicht angeklickt werden: 4973 4974 if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) 4975 return sal_False; 4976 4977 sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() || 4978 ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> 4979 GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK); 4980 SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern-> 4981 GetItem(ATTR_HOR_JUSTIFY)).GetValue(); 4982 4983 // EditEngine 4984 4985 ScFieldEditEngine aEngine( pDoc->GetEditPool() ); 4986 ScSizeDeviceProvider aProv(pDocSh); 4987 aEngine.SetRefDevice( aProv.GetDevice() ); 4988 aEngine.SetRefMapMode( MAP_100TH_MM ); 4989 SfxItemSet aDefault( aEngine.GetEmptyItemSet() ); 4990 pPattern->FillEditItemSet( &aDefault ); 4991 SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT; 4992 switch (eHorJust) 4993 { 4994 case SVX_HOR_JUSTIFY_LEFT: 4995 case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert 4996 case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type 4997 eSvxAdjust = SVX_ADJUST_LEFT; 4998 break; 4999 case SVX_HOR_JUSTIFY_RIGHT: 5000 eSvxAdjust = SVX_ADJUST_RIGHT; 5001 break; 5002 case SVX_HOR_JUSTIFY_CENTER: 5003 eSvxAdjust = SVX_ADJUST_CENTER; 5004 break; 5005 case SVX_HOR_JUSTIFY_BLOCK: 5006 eSvxAdjust = SVX_ADJUST_BLOCK; 5007 break; 5008 } 5009 aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); 5010 aEngine.SetDefaults( aDefault ); 5011 if (bSpellErr) 5012 aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING ); 5013 5014 MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung 5015 Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode ); 5016 long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1; 5017 Size aPaperSize = Size( 1000000, 1000000 ); 5018 if(pCell->GetCellType() == CELLTYPE_FORMULA) 5019 { 5020 long nSizeX = 0; 5021 long nSizeY = 0; 5022 pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY ); 5023 aPaperSize = Size(nSizeX, nSizeY ); 5024 aPaperSize = PixelToLogic(aPaperSize); 5025 } 5026 5027 if (bBreak) 5028 aPaperSize.Width() = nThisColLogic; 5029 aEngine.SetPaperSize( aPaperSize ); 5030 5031 ::std::auto_ptr< EditTextObject > pTextObj; 5032 const EditTextObject* pData; 5033 if(pCell->GetCellType() == CELLTYPE_EDIT) 5034 { 5035 ((ScEditCell*)pCell)->GetData(pData); 5036 if (pData) 5037 aEngine.SetText(*pData); 5038 } 5039 else // HyperLink Formula cell 5040 { 5041 pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject()); 5042 if (pTextObj.get()) 5043 aEngine.SetText(*pTextObj); 5044 } 5045 5046 long nStartX = aLogicEdit.Left(); 5047 5048 long nTextWidth = aEngine.CalcTextWidth(); 5049 long nTextHeight = aEngine.GetTextHeight(); 5050 if ( nTextWidth < nThisColLogic ) 5051 { 5052 if (eHorJust == SVX_HOR_JUSTIFY_RIGHT) 5053 nStartX += nThisColLogic - nTextWidth; 5054 else if (eHorJust == SVX_HOR_JUSTIFY_CENTER) 5055 nStartX += (nThisColLogic - nTextWidth) / 2; 5056 } 5057 5058 aLogicEdit.Left() = nStartX; 5059 if (!bBreak) 5060 aLogicEdit.Right() = nStartX + nTextWidth; 5061 5062 // There is one glitch when dealing with a hyperlink cell and 5063 // the cell content is NUMERIC. This defaults to right aligned and 5064 // we need to adjust accordingly. 5065 if(pCell->GetCellType() == CELLTYPE_FORMULA && 5066 static_cast<ScFormulaCell*>(pCell)->IsValue() && 5067 eHorJust == SVX_HOR_JUSTIFY_STANDARD) 5068 { 5069 aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1; 5070 aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth; 5071 } 5072 aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight; 5073 5074 5075 Point aLogicClick = PixelToLogic(rPos,aEditMode); 5076 if ( aLogicEdit.IsInside(aLogicClick) ) 5077 { 5078 // aEngine.SetUpdateMode(sal_False); 5079 EditView aTempView( &aEngine, this ); 5080 aTempView.SetOutputArea( aLogicEdit ); 5081 5082 sal_Bool bRet = sal_False; 5083 MapMode aOld = GetMapMode(); 5084 SetMapMode(aEditMode); // kein return mehr 5085 5086 if (bSpellErr) // Spelling-Fehler suchen 5087 { 5088 bRet = aTempView.IsWrongSpelledWordAtPos( rPos ); 5089 if ( bRet ) 5090 pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen 5091 } 5092 else // URL suchen 5093 { 5094 const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer(); 5095 5096 if (pFieldItem) 5097 { 5098 const SvxFieldData* pField = pFieldItem->GetField(); 5099 if ( pField && pField->ISA(SvxURLField) ) 5100 { 5101 if ( pName || pUrl || pTarget ) 5102 { 5103 const SvxURLField* pURLField = (const SvxURLField*)pField; 5104 if (pName) 5105 *pName = pURLField->GetRepresentation(); 5106 if (pUrl) 5107 *pUrl = pURLField->GetURL(); 5108 if (pTarget) 5109 *pTarget = pURLField->GetTargetFrame(); 5110 } 5111 bRet = sal_True; 5112 } 5113 } 5114 } 5115 5116 SetMapMode(aOld); 5117 5118 // text cursor is restored in ScHideTextCursor dtor 5119 5120 return bRet; 5121 } 5122 return sal_False; 5123 } 5124 5125 sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange ) 5126 { 5127 ScDocument* pDoc = pViewData->GetDocument(); 5128 SCTAB nTab = pViewData->GetTabNo(); 5129 SCTAB nTabCount = pDoc->GetTableCount(); 5130 if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ) 5131 { 5132 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5133 5134 Size aButSize = pViewData->GetScenButSize(); 5135 long nBWidth = aButSize.Width(); 5136 if (!nBWidth) 5137 return sal_False; // noch kein Button gezeichnet -> da ist auch keiner 5138 long nBHeight = aButSize.Height(); 5139 long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() ); 5140 5141 //! Ranges an der Table cachen!!!! 5142 5143 ScMarkData aMarks; 5144 for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) 5145 pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); 5146 ScRangeList aRanges; 5147 aMarks.FillRangeListWithMarks( &aRanges, sal_False ); 5148 5149 5150 sal_uLong nRangeCount = aRanges.Count(); 5151 for (sal_uLong j=0; j<nRangeCount; j++) 5152 { 5153 ScRange aRange = *aRanges.GetObject(j); 5154 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn 5155 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden 5156 pDoc->ExtendTotalMerge( aRange ); 5157 5158 sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); 5159 5160 Point aButtonPos; 5161 if ( bTextBelow ) 5162 { 5163 aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, 5164 eWhich, sal_True ); 5165 } 5166 else 5167 { 5168 aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(), 5169 eWhich, sal_True ); 5170 aButtonPos.Y() -= nBHeight; 5171 } 5172 if ( bLayoutRTL ) 5173 aButtonPos.X() -= nHSpace - 1; 5174 else 5175 aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom 5176 5177 Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) ); 5178 if ( aButRect.IsInside( rPosPixel ) ) 5179 { 5180 rScenRange = aRange; 5181 return sal_True; 5182 } 5183 } 5184 } 5185 5186 return sal_False; 5187 } 5188 5189 void ScGridWindow::UpdateVisibleRange() 5190 { 5191 // #163911# Update the visible range outside of paint (called when switching sheets). 5192 // Use the same logic here as in ScGridWindow::Draw. 5193 5194 SCCOL nPosX = pViewData->GetPosX( eHWhich ); 5195 SCROW nPosY = pViewData->GetPosY( eVWhich ); 5196 5197 SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); 5198 if (nXRight > MAXCOL) nXRight = MAXCOL; 5199 SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); 5200 if (nYBottom > MAXROW) nYBottom = MAXROW; 5201 5202 // Store the current visible range. 5203 maVisibleRange.mnCol1 = nPosX; 5204 maVisibleRange.mnCol2 = nXRight; 5205 maVisibleRange.mnRow1 = nPosY; 5206 maVisibleRange.mnRow2 = nYBottom; 5207 } 5208 5209 // #114409# 5210 void ScGridWindow::DrawLayerCreated() 5211 { 5212 SetMapMode( GetDrawMapMode() ); 5213 5214 // initially create overlay objects 5215 ImpCreateOverlayObjects(); 5216 } 5217 5218 // #114409# 5219 void ScGridWindow::CursorChanged() 5220 { 5221 // here the created OverlayObjects may be transformed in later versions. For 5222 // now, just re-create them 5223 5224 UpdateCursorOverlay(); 5225 } 5226 5227 // #114409# 5228 void ScGridWindow::ImpCreateOverlayObjects() 5229 { 5230 UpdateCursorOverlay(); 5231 UpdateSelectionOverlay(); 5232 UpdateAutoFillOverlay(); 5233 UpdateDragRectOverlay(); 5234 UpdateHeaderOverlay(); 5235 UpdateShrinkOverlay(); 5236 } 5237 5238 // #114409# 5239 void ScGridWindow::ImpDestroyOverlayObjects() 5240 { 5241 DeleteCursorOverlay(); 5242 DeleteSelectionOverlay(); 5243 DeleteAutoFillOverlay(); 5244 DeleteDragRectOverlay(); 5245 DeleteHeaderOverlay(); 5246 DeleteShrinkOverlay(); 5247 } 5248 5249 void ScGridWindow::UpdateAllOverlays() 5250 { 5251 // delete and re-allocate all overlay objects 5252 5253 ImpDestroyOverlayObjects(); 5254 ImpCreateOverlayObjects(); 5255 } 5256 5257 void ScGridWindow::DeleteCursorOverlay() 5258 { 5259 DELETEZ( mpOOCursors ); 5260 } 5261 5262 void ScGridWindow::UpdateCursorOverlay() 5263 { 5264 MapMode aDrawMode = GetDrawMapMode(); 5265 MapMode aOldMode = GetMapMode(); 5266 if ( aOldMode != aDrawMode ) 5267 SetMapMode( aDrawMode ); 5268 5269 // Existing OverlayObjects may be transformed in later versions. 5270 // For now, just re-create them. 5271 5272 DeleteCursorOverlay(); 5273 5274 std::vector<Rectangle> aPixelRects; 5275 5276 // 5277 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor) 5278 // 5279 5280 SCTAB nTab = pViewData->GetTabNo(); 5281 SCCOL nX = pViewData->GetCurX(); 5282 SCROW nY = pViewData->GetCurY(); 5283 5284 if (!maVisibleRange.isInside(nX, nY)) 5285 return; 5286 5287 // don't show the cursor in overlapped cells 5288 5289 ScDocument* pDoc = pViewData->GetDocument(); 5290 const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab); 5291 const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG); 5292 sal_Bool bOverlapped = rMergeFlag.IsOverlapped(); 5293 5294 // left or above of the screen? 5295 5296 sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); 5297 if (!bVis) 5298 { 5299 SCCOL nEndX = nX; 5300 SCROW nEndY = nY; 5301 const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE); 5302 if (rMerge.GetColMerge() > 1) 5303 nEndX += rMerge.GetColMerge()-1; 5304 if (rMerge.GetRowMerge() > 1) 5305 nEndY += rMerge.GetRowMerge()-1; 5306 bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) ); 5307 } 5308 5309 if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) 5310 { 5311 Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 5312 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5313 5314 // completely right of/below the screen? 5315 // (test with logical start position in aScrPos) 5316 sal_Bool bMaybeVisible; 5317 if ( bLayoutRTL ) 5318 bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 ); 5319 else 5320 { 5321 Size aOutSize = GetOutputSizePixel(); 5322 bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 ); 5323 } 5324 if ( bMaybeVisible ) 5325 { 5326 long nSizeXPix; 5327 long nSizeYPix; 5328 pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 5329 5330 if ( bLayoutRTL ) 5331 aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring 5332 5333 sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX || 5334 pViewData->GetVSplitMode() == SC_SPLIT_FIX ); 5335 if ( pViewData->GetActivePart()==eWhich || bFix ) 5336 { 5337 aScrPos.X() -= 2; 5338 aScrPos.Y() -= 2; 5339 Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 5340 5341 aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() )); 5342 aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() )); 5343 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 )); 5344 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() )); 5345 } 5346 else 5347 { 5348 Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) ); 5349 aPixelRects.push_back( aRect ); 5350 } 5351 } 5352 } 5353 5354 if ( aPixelRects.size() ) 5355 { 5356 // #i70788# get the OverlayManager safely 5357 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5358 5359 if(pOverlayManager) 5360 { 5361 const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 5362 std::vector< basegfx::B2DRange > aRanges; 5363 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5364 5365 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5366 { 5367 const Rectangle aRA(aPixelRects[a]); 5368 basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); 5369 aRB.transform(aTransform); 5370 aRanges.push_back(aRB); 5371 } 5372 5373 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5374 sdr::overlay::OVERLAY_SOLID, 5375 aCursorColor, 5376 aRanges, 5377 false); 5378 5379 pOverlayManager->add(*pOverlay); 5380 mpOOCursors = new ::sdr::overlay::OverlayObjectList; 5381 mpOOCursors->append(*pOverlay); 5382 } 5383 } 5384 5385 if ( aOldMode != aDrawMode ) 5386 SetMapMode( aOldMode ); 5387 } 5388 5389 void ScGridWindow::DeleteSelectionOverlay() 5390 { 5391 DELETEZ( mpOOSelection ); 5392 } 5393 5394 void ScGridWindow::UpdateSelectionOverlay() 5395 { 5396 MapMode aDrawMode = GetDrawMapMode(); 5397 MapMode aOldMode = GetMapMode(); 5398 if ( aOldMode != aDrawMode ) 5399 SetMapMode( aDrawMode ); 5400 5401 DeleteSelectionOverlay(); 5402 std::vector<Rectangle> aPixelRects; 5403 GetSelectionRects( aPixelRects ); 5404 5405 if ( aPixelRects.size() && pViewData->IsActive() ) 5406 { 5407 // #i70788# get the OverlayManager safely 5408 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5409 5410 if(pOverlayManager) 5411 { 5412 std::vector< basegfx::B2DRange > aRanges; 5413 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5414 5415 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5416 { 5417 const Rectangle aRA(aPixelRects[a]); 5418 basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom()); 5419 aRB.transform(aTransform); 5420 aRanges.push_back(aRB); 5421 } 5422 5423 // get the system's hilight color 5424 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 5425 const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor()); 5426 5427 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5428 sdr::overlay::OVERLAY_TRANSPARENT, 5429 aHighlight, 5430 aRanges, 5431 true); 5432 5433 pOverlayManager->add(*pOverlay); 5434 mpOOSelection = new ::sdr::overlay::OverlayObjectList; 5435 mpOOSelection->append(*pOverlay); 5436 } 5437 } 5438 5439 if ( aOldMode != aDrawMode ) 5440 SetMapMode( aOldMode ); 5441 } 5442 5443 void ScGridWindow::DeleteAutoFillOverlay() 5444 { 5445 DELETEZ( mpOOAutoFill ); 5446 mpAutoFillRect.reset(); 5447 } 5448 5449 void ScGridWindow::UpdateAutoFillOverlay() 5450 { 5451 MapMode aDrawMode = GetDrawMapMode(); 5452 MapMode aOldMode = GetMapMode(); 5453 if ( aOldMode != aDrawMode ) 5454 SetMapMode( aDrawMode ); 5455 5456 DeleteAutoFillOverlay(); 5457 5458 // 5459 // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark) 5460 // 5461 5462 if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() && 5463 !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) 5464 { 5465 SCCOL nX = aAutoMarkPos.Col(); 5466 SCROW nY = aAutoMarkPos.Row(); 5467 5468 if (!maVisibleRange.isInside(nX, nY)) 5469 // Autofill mark is not visible. Bail out. 5470 return; 5471 5472 SCTAB nTab = pViewData->GetTabNo(); 5473 ScDocument* pDoc = pViewData->GetDocument(); 5474 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5475 5476 Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 5477 long nSizeXPix; 5478 long nSizeYPix; 5479 pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 5480 if ( bLayoutRTL ) 5481 aFillPos.X() -= nSizeXPix + 3; 5482 else 5483 aFillPos.X() += nSizeXPix - 2; 5484 5485 aFillPos.Y() += nSizeYPix; 5486 aFillPos.Y() -= 2; 5487 mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6))); 5488 5489 // #i70788# get the OverlayManager safely 5490 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5491 5492 if(pOverlayManager) 5493 { 5494 const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 5495 std::vector< basegfx::B2DRange > aRanges; 5496 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5497 basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1); 5498 5499 aRB.transform(aTransform); 5500 aRanges.push_back(aRB); 5501 5502 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5503 sdr::overlay::OVERLAY_SOLID, 5504 aHandleColor, 5505 aRanges, 5506 false); 5507 5508 pOverlayManager->add(*pOverlay); 5509 mpOOAutoFill = new ::sdr::overlay::OverlayObjectList; 5510 mpOOAutoFill->append(*pOverlay); 5511 } 5512 5513 if ( aOldMode != aDrawMode ) 5514 SetMapMode( aOldMode ); 5515 } 5516 } 5517 5518 void ScGridWindow::DeleteDragRectOverlay() 5519 { 5520 DELETEZ( mpOODragRect ); 5521 } 5522 5523 void ScGridWindow::UpdateDragRectOverlay() 5524 { 5525 MapMode aDrawMode = GetDrawMapMode(); 5526 MapMode aOldMode = GetMapMode(); 5527 if ( aOldMode != aDrawMode ) 5528 SetMapMode( aDrawMode ); 5529 5530 DeleteDragRectOverlay(); 5531 5532 // 5533 // get the rectangles in pixels (moved from DrawDragRect) 5534 // 5535 5536 if ( bDragRect || bPagebreakDrawn ) 5537 { 5538 std::vector<Rectangle> aPixelRects; 5539 5540 SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col(); 5541 SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row(); 5542 SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col(); 5543 SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row(); 5544 5545 SCTAB nTab = pViewData->GetTabNo(); 5546 5547 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich)); 5548 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich)); 5549 if (nX1 < nPosX) nX1 = nPosX; 5550 if (nX2 < nPosX) nX2 = nPosX; 5551 if (nY1 < nPosY) nY1 = nPosY; 5552 if (nY2 < nPosY) nY2 = nPosY; 5553 5554 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) ); 5555 5556 long nSizeXPix=0; 5557 long nSizeYPix=0; 5558 ScDocument* pDoc = pViewData->GetDocument(); 5559 double nPPTX = pViewData->GetPPTX(); 5560 double nPPTY = pViewData->GetPPTY(); 5561 SCCOLROW i; 5562 5563 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 5564 long nLayoutSign = bLayoutRTL ? -1 : 1; 5565 5566 if (ValidCol(nX2) && nX2>=nX1) 5567 for (i=nX1; i<=nX2; i++) 5568 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX ); 5569 else 5570 { 5571 aScrPos.X() -= nLayoutSign; 5572 nSizeXPix += 2; 5573 } 5574 5575 if (ValidRow(nY2) && nY2>=nY1) 5576 for (i=nY1; i<=nY2; i++) 5577 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY ); 5578 else 5579 { 5580 aScrPos.Y() -= 1; 5581 nSizeYPix += 2; 5582 } 5583 5584 aScrPos.X() -= 2 * nLayoutSign; 5585 aScrPos.Y() -= 2; 5586 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 5587 Rectangle aRect( aScrPos.X(), aScrPos.Y(), 5588 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 ); 5589 if ( bLayoutRTL ) 5590 { 5591 aRect.Left() = aRect.Right(); // end position is left 5592 aRect.Right() = aScrPos.X(); 5593 } 5594 5595 if ( meDragInsertMode == INS_CELLSDOWN ) 5596 { 5597 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) ); 5598 aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) ); 5599 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) ); 5600 aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) ); 5601 } 5602 else if ( meDragInsertMode == INS_CELLSRIGHT ) 5603 { 5604 aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) ); 5605 aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) ); 5606 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) ); 5607 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) ); 5608 } 5609 else 5610 { 5611 aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) ); 5612 aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) ); 5613 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) ); 5614 aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) ); 5615 } 5616 5617 // #i70788# get the OverlayManager safely 5618 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5619 5620 if(pOverlayManager) 5621 { 5622 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5623 std::vector< basegfx::B2DRange > aRanges; 5624 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5625 5626 for(sal_uInt32 a(0); a < aPixelRects.size(); a++) 5627 { 5628 const Rectangle aRA(aPixelRects[a]); 5629 basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); 5630 aRB.transform(aTransform); 5631 aRanges.push_back(aRB); 5632 } 5633 5634 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5635 sdr::overlay::OVERLAY_INVERT, 5636 Color(COL_BLACK), 5637 aRanges, 5638 false); 5639 5640 pOverlayManager->add(*pOverlay); 5641 mpOODragRect = new ::sdr::overlay::OverlayObjectList; 5642 mpOODragRect->append(*pOverlay); 5643 } 5644 } 5645 5646 if ( aOldMode != aDrawMode ) 5647 SetMapMode( aOldMode ); 5648 } 5649 5650 void ScGridWindow::DeleteHeaderOverlay() 5651 { 5652 DELETEZ( mpOOHeader ); 5653 } 5654 5655 void ScGridWindow::UpdateHeaderOverlay() 5656 { 5657 MapMode aDrawMode = GetDrawMapMode(); 5658 MapMode aOldMode = GetMapMode(); 5659 if ( aOldMode != aDrawMode ) 5660 SetMapMode( aDrawMode ); 5661 5662 DeleteHeaderOverlay(); 5663 5664 // Pixel rectangle is in aInvertRect 5665 if ( !aInvertRect.IsEmpty() ) 5666 { 5667 // #i70788# get the OverlayManager safely 5668 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5669 5670 if(pOverlayManager) 5671 { 5672 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5673 std::vector< basegfx::B2DRange > aRanges; 5674 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5675 basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1); 5676 5677 aRB.transform(aTransform); 5678 aRanges.push_back(aRB); 5679 5680 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5681 sdr::overlay::OVERLAY_INVERT, 5682 Color(COL_BLACK), 5683 aRanges, 5684 false); 5685 5686 pOverlayManager->add(*pOverlay); 5687 mpOOHeader = new ::sdr::overlay::OverlayObjectList; 5688 mpOOHeader->append(*pOverlay); 5689 } 5690 } 5691 5692 if ( aOldMode != aDrawMode ) 5693 SetMapMode( aOldMode ); 5694 } 5695 5696 void ScGridWindow::DeleteShrinkOverlay() 5697 { 5698 DELETEZ( mpOOShrink ); 5699 } 5700 5701 void ScGridWindow::UpdateShrinkOverlay() 5702 { 5703 MapMode aDrawMode = GetDrawMapMode(); 5704 MapMode aOldMode = GetMapMode(); 5705 if ( aOldMode != aDrawMode ) 5706 SetMapMode( aDrawMode ); 5707 5708 DeleteShrinkOverlay(); 5709 5710 // 5711 // get the rectangle in pixels 5712 // 5713 5714 Rectangle aPixRect; 5715 ScRange aRange; 5716 SCTAB nTab = pViewData->GetTabNo(); 5717 if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() && 5718 pViewData->GetDelMark( aRange ) ) 5719 { 5720 //! limit to visible area 5721 if ( aRange.aStart.Col() <= aRange.aEnd.Col() && 5722 aRange.aStart.Row() <= aRange.aEnd.Row() ) 5723 { 5724 Point aStart = pViewData->GetScrPos( aRange.aStart.Col(), 5725 aRange.aStart.Row(), eWhich ); 5726 Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1, 5727 aRange.aEnd.Row()+1, eWhich ); 5728 aEnd.X() -= 1; 5729 aEnd.Y() -= 1; 5730 5731 aPixRect = Rectangle( aStart,aEnd ); 5732 } 5733 } 5734 5735 if ( !aPixRect.IsEmpty() ) 5736 { 5737 // #i70788# get the OverlayManager safely 5738 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5739 5740 if(pOverlayManager) 5741 { 5742 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); 5743 std::vector< basegfx::B2DRange > aRanges; 5744 const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); 5745 basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1); 5746 5747 aRB.transform(aTransform); 5748 aRanges.push_back(aRB); 5749 5750 sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 5751 sdr::overlay::OVERLAY_INVERT, 5752 Color(COL_BLACK), 5753 aRanges, 5754 false); 5755 5756 pOverlayManager->add(*pOverlay); 5757 mpOOShrink = new ::sdr::overlay::OverlayObjectList; 5758 mpOOShrink->append(*pOverlay); 5759 } 5760 } 5761 5762 if ( aOldMode != aDrawMode ) 5763 SetMapMode( aOldMode ); 5764 } 5765 5766 // #i70788# central method to get the OverlayManager safely 5767 ::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager() 5768 { 5769 SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView(); 5770 5771 if(pPV) 5772 { 5773 SdrPageWindow* pPageWin = pPV->FindPageWindow( *this ); 5774 5775 if ( pPageWin ) 5776 { 5777 return (pPageWin->GetOverlayManager()); 5778 } 5779 } 5780 5781 return 0L; 5782 } 5783 5784 void ScGridWindow::flushOverlayManager() 5785 { 5786 // #i70788# get the OverlayManager safely 5787 ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); 5788 5789 if(pOverlayManager) 5790 { 5791 pOverlayManager->flush(); 5792 } 5793 } 5794 5795 // --------------------------------------------------------------------------- 5796 // eof 5797