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