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