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