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