1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gridwin.cxx,v $
10 * $Revision: 1.96.50.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "scitems.hxx"
36 #include <memory> //auto_ptr
37 #include <svx/adjitem.hxx>
38 #include <svx/algitem.hxx>
39 #include <svx/dbexch.hrc>
40 #include <svx/editview.hxx>
41 #include <svx/editstat.hxx>
42 #include <svx/flditem.hxx>
43 #include <svx/svdetc.hxx>
44 #include <svx/editobj.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <sfx2/viewfrm.hxx>
47 #include <sfx2/docfile.hxx>
48 #include <svtools/stritem.hxx>
49 #include <svtools/svlbox.hxx>
50 #include <svtools/svtabbx.hxx>
51 #include <svtools/urlbmk.hxx>
52 #include <tools/urlobj.hxx>
53 #include <vcl/cursor.hxx>
54 #include <vcl/sound.hxx>
55 #include <vcl/graph.hxx>
56 #include <vcl/hatch.hxx>
57 #include <sot/formats.hxx>
58 #include <sot/clsids.hxx>
60 #include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
61 #include <svx/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
62 #include <svx/svditer.hxx>
63 #include <svx/svdocapt.hxx>
64 #include <svx/svdpagv.hxx>
66 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
67 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
68 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
69 #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
70 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
71 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
72 #include <com/sun/star/sheet/MemberResultFlags.hpp>
73 #include <com/sun/star/awt/KeyModifier.hpp>
74 #include <com/sun/star/awt/MouseButton.hpp>
76 #include "gridwin.hxx"
77 #include "tabvwsh.hxx"
79 #include "viewdata.hxx"
80 #include "tabview.hxx"
83 #include "document.hxx"
85 #include "dbcolect.hxx"
86 #include "stlpool.hxx"
87 #include "printfun.hxx"
88 #include "cbutton.hxx"
90 #include "globstr.hrc"
91 #include "editutil.hxx"
92 #include "scresid.hxx"
93 #include "inputhdl.hxx"
94 #include "uiitems.hxx" // Filter-Dialog - auslagern !!!
95 #include "filtdlg.hxx"
96 #include "impex.hxx" // Sylk-ID fuer CB
97 #include "cell.hxx" // fuer Edit-Felder
98 #include "patattr.hxx"
99 #include "notemark.hxx"
100 #include "rfindlst.hxx"
101 #include "docpool.hxx"
102 #include "output.hxx"
103 #include "docfunc.hxx"
104 #include "dbdocfun.hxx"
105 #include "dpobject.hxx"
106 #include "dpoutput.hxx"
107 #include "transobj.hxx"
108 #include "drwtrans.hxx"
109 #include "seltrans.hxx"
110 #include "sizedev.hxx"
111 #include "AccessibilityHints.hxx"
112 #include "dpsave.hxx"
113 #include "viewuno.hxx"
114 #include "compiler.hxx"
115 #include "editable.hxx"
116 #include "fillinfo.hxx"
117 #include "scitems.hxx"
118 #include "userdat.hxx"
119 #include "drwlayer.hxx"
120 #include "attrib.hxx"
121 #include "cellsh.hxx"
122 #include "tabprotection.hxx"
123 #include "clipparam.hxx"
124 #include "dpcontrol.hxx"
127 #include <vcl/salbtype.hxx> // FRound
128 #include "drawview.hxx"
129 #include <svx/sdrpagewindow.hxx>
130 #include <svx/sdrpaintwindow.hxx>
131 #include <svx/sdr/overlay/overlaymanager.hxx>
132 #include <vcl/svapp.hxx>
134 #include "cellsuno.hxx"
136 #include <com/sun/star/document/XVbaEventsHelper.hpp>
137 #include <com/sun/star/document/VbaEventId.hpp>
139 using namespace com::sun::star
;
140 using namespace com::sun::star::document::VbaEventId
;
141 using ::com::sun::star::uno::Sequence
;
142 using ::com::sun::star::uno::Any
;
144 const BYTE SC_NESTEDBUTTON_NONE
= 0;
145 const BYTE SC_NESTEDBUTTON_DOWN
= 1;
146 const BYTE SC_NESTEDBUTTON_UP
= 2;
148 #define SC_AUTOFILTER_ALL 0
149 #define SC_AUTOFILTER_TOP10 1
150 #define SC_AUTOFILTER_CUSTOM 2
151 #define SC_AUTOFILTER_EMPTY 3
152 #define SC_AUTOFILTER_NOTEMPTY 4
154 // Modi fuer die FilterListBox
158 SC_FILTERBOX_DATASELECT
,
159 SC_FILTERBOX_SCENARIO
,
160 SC_FILTERBOX_PAGEFIELD
163 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
164 extern USHORT nScClickMouseModifier
; // global.cxx
165 extern USHORT nScFillModeMouseModifier
; // global.cxx
167 #define SC_FILTERLISTBOX_LINES 12
169 //==================================================================
171 class ScFilterListBox
: public ListBox
174 ScGridWindow
* pGridWin
;
183 ScFilterBoxMode eMode
;
186 virtual void LoseFocus();
190 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
191 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
194 virtual long PreNotify( NotifyEvent
& rNEvt
);
195 virtual void Select();
197 SCCOL
GetCol() const { return nCol
; }
198 SCROW
GetRow() const { return nRow
; }
199 ScFilterBoxMode
GetMode() const { return eMode
; }
200 BOOL
IsDataSelect() const { return (eMode
== SC_FILTERBOX_DATASELECT
); }
202 BOOL
IsInInit() const { return bInit
; }
203 void SetCancelled() { bCancelled
= TRUE
; }
204 BOOL
IsInSelect() const { return bInSelect
; }
205 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
206 bool HasDates() const { return mbListHasDates
; }
209 //-------------------------------------------------------------------
211 // ListBox in einem FloatingWindow (pParent)
212 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
213 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
214 ListBox( pParent
, WB_AUTOHSCROLL
),
218 bButtonDown( FALSE
),
222 mbListHasDates(false),
228 __EXPORT
ScFilterListBox::~ScFilterListBox()
230 if (IsMouseCaptured())
234 void ScFilterListBox::EndInit()
236 USHORT nPos
= GetSelectEntryPos();
237 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
245 void __EXPORT
ScFilterListBox::LoseFocus()
252 // -----------------------------------------------------------------------
254 long ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
257 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
259 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
260 KeyCode aCode
= aKeyEvt
.GetKeyCode();
261 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
263 USHORT nKey
= aCode
.GetCode();
264 if ( nKey
== KEY_RETURN
)
266 SelectHdl(); // auswaehlen
269 else if ( nKey
== KEY_ESCAPE
)
271 pGridWin
->ClickExtern(); // loescht die List-Box !!!
277 return nDone
? nDone
: ListBox::PreNotify( rNEvt
);
280 void __EXPORT
ScFilterListBox::Select()
286 void __EXPORT
ScFilterListBox::SelectHdl()
288 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
290 USHORT nPos
= GetSelectEntryPos();
291 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
296 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
298 pGridWin
->FilterSelect( nSel
);
305 // ============================================================================
307 // use a System floating window for the above filter listbox
308 class ScFilterFloatingWindow
: public FloatingWindow
311 ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
312 virtual ~ScFilterFloatingWindow();
313 // required for System FloatingWindows that will not process KeyInput by themselves
314 virtual Window
* GetPreferredKeyInputWindow();
317 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
318 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
321 ScFilterFloatingWindow::~ScFilterFloatingWindow()
326 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
328 // redirect keyinput in the child window
329 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
332 // ============================================================================
334 BOOL
lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
336 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
337 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
338 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
340 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
341 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
345 const ScBaseCell
* pCell
= pDoc
->GetCell( rRange
.aEnd
);
346 return ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
&&
347 ((ScFormulaCell
*)pCell
)->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
351 void lcl_UnLockComment( ScDrawView
* pView
, SdrPageView
* pPV
, SdrModel
* pDrDoc
, const Point
& rPos
, ScViewData
* pViewData
)
353 if (!pView
&& !pPV
&& !pDrDoc
&& !pViewData
)
356 ScDocument
& rDoc
= *pViewData
->GetDocument();
357 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
358 ScPostIt
* pNote
= rDoc
.GetNote( aCellPos
);
359 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
360 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
362 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
363 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
364 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
365 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
366 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
370 sal_Bool
lcl_GetHyperlinkCell(ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScBaseCell
*& rpCell
)
375 pDoc
->GetCell( rPosX
, rPosY
, nTab
, rpCell
);
376 if ( !rpCell
|| rpCell
->GetCellType() == CELLTYPE_NOTE
)
379 return FALSE
; // alles leer bis links
381 --rPosX
; // weitersuchen
383 else if ( rpCell
->GetCellType() == CELLTYPE_EDIT
)
385 else if (rpCell
->GetCellType() == CELLTYPE_FORMULA
&&
386 static_cast<ScFormulaCell
*>(rpCell
)->IsHyperLinkCell())
389 return FALSE
; // andere Zelle
396 // ============================================================================
398 ScGridWindow::VisibleRange::VisibleRange() :
399 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
403 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
405 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
408 // ============================================================================
410 // WB_DIALOGCONTROL noetig fuer UNO-Controls
411 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
412 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
413 DropTargetHelper( this ),
414 DragSourceHelper( this ),
416 mpOOSelection( NULL
),
417 mpOOSelectionBorder( NULL
),
418 mpOOAutoFill( NULL
),
419 mpOODragRect( NULL
),
422 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
427 pFilterFloat( NULL
),
428 mpDPFieldPopup(NULL
),
429 nCursorHideCount( 0 ),
433 nMouseStatus( SC_GM_NONE
),
434 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
435 #if OLD_PIVOT_IMPLEMENTATION
436 bPivotMouse( FALSE
),
440 nPagebreakMouse( SC_PD_NONE
),
441 bPagebreakDrawn( FALSE
),
444 meDragInsertMode( INS_NONE
),
445 nCurrentPointer( 0 ),
446 bIsInScroll( FALSE
),
448 aComboButton( this ),
451 bNeedsRepaint( FALSE
),
452 bAutoMarkVisible( FALSE
),
453 bListValButton( FALSE
)
457 case SC_SPLIT_TOPLEFT
:
458 eHWhich
= SC_SPLIT_LEFT
;
459 eVWhich
= SC_SPLIT_TOP
;
461 case SC_SPLIT_TOPRIGHT
:
462 eHWhich
= SC_SPLIT_RIGHT
;
463 eVWhich
= SC_SPLIT_TOP
;
465 case SC_SPLIT_BOTTOMLEFT
:
466 eHWhich
= SC_SPLIT_LEFT
;
467 eVWhich
= SC_SPLIT_BOTTOM
;
469 case SC_SPLIT_BOTTOMRIGHT
:
470 eHWhich
= SC_SPLIT_RIGHT
;
471 eVWhich
= SC_SPLIT_BOTTOM
;
474 DBG_ERROR("GridWindow: falsche Position");
479 SetMapMode(pViewData
->GetLogicMode(eWhich
));
481 EnableChildTransparentMode();
482 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
484 SetHelpId( HID_SC_WIN_GRIDWIN
);
485 SetUniqueId( HID_SC_WIN_GRIDWIN
);
487 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
491 __EXPORT
ScGridWindow::~ScGridWindow()
494 ImpDestroyOverlayObjects();
501 void __EXPORT
ScGridWindow::Resize( const Size
& )
506 void ScGridWindow::ClickExtern()
508 // #i81298# don't delete the filter box when called from its select handler
509 // (possible through row header size update)
510 // #i84277# when initializing the filter box, a Basic error can deactivate the view
511 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
515 DELETEZ(pFilterFloat
);
518 IMPL_LINK( ScGridWindow
, PopupModeEndHdl
, FloatingWindow
*, EMPTYARG
)
521 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
526 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
528 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
529 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
533 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, BOOL bHasSelection
, const String
& rStr
)
537 ScDocument
* pDoc
= pViewData
->GetDocument();
538 SCTAB nTab
= pViewData
->GetTabNo();
539 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
540 if ( pDPObj
&& nCol
> 0 )
542 // look for the dimension header left of the drop-down arrow
543 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
544 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
545 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
547 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
550 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
551 if ( !bIsDataLayout
)
553 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
556 pDim
->SetCurrentPage( &rStr
);
558 pDim
->SetCurrentPage( NULL
);
560 ScDPObject
aNewObj( *pDPObj
);
561 aNewObj
.SetSaveData( aSaveData
);
562 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
563 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
564 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
570 void ScGridWindow::DoPageFieldMenue( SCCOL nCol
, SCROW nRow
)
572 //! merge position/size handling with DoAutoFilterMenue
578 ScDocument
* pDoc
= pViewData
->GetDocument();
579 SCTAB nTab
= pViewData
->GetTabNo();
580 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
585 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
586 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
590 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
593 aPos
.Y() += nSizeY
- 1;
595 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // not resizable etc.
596 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
597 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_PAGEFIELD
);
599 pFilterBox
->EnableMirroring();
604 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
605 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
607 nHeight
= GetTextHeight();
608 nHeight
*= SC_FILTERLISTBOX_LINES
;
610 SetMapMode( aOldMode
);
614 // SetSize comes later
616 TypedScStrCollection
aStrings( 128, 128 );
618 // get list box entries and selection
619 BOOL bHasCurrentPage
= FALSE
;
621 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
622 if ( pDPObj
&& nCol
> 0 )
624 // look for the dimension header left of the drop-down arrow
625 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
626 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
627 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
629 pDPObj
->FillPageList( aStrings
, nField
);
631 // get current page from SaveData
633 ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
635 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
636 if ( pSaveData
&& !bIsDataLayout
)
638 ScDPSaveDimension
* pDim
= pSaveData
->GetExistingDimensionByName(aDimName
);
639 if ( pDim
&& pDim
->HasCurrentPage() )
641 aCurrentPage
= pDim
->GetCurrentPage();
642 bHasCurrentPage
= TRUE
;
648 // include all entry widths for the size of the drop-down
650 USHORT nCount
= aStrings
.GetCount();
651 for (i
=0; i
<nCount
; i
++)
653 TypedStrData
* pData
= aStrings
[i
];
654 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
655 if ( nTextWidth
> nMaxText
)
656 nMaxText
= nTextWidth
;
659 // add scrollbar width if needed (string entries are counted here)
660 // (scrollbar is shown if the box is exactly full?)
661 if ( nCount
>= SC_FILTERLISTBOX_LINES
)
662 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
664 nMaxText
+= 4; // for borders
666 if ( nMaxText
> nSizeX
)
667 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
669 // adjust position and size to window
671 Size aParentSize
= GetParent()->GetOutputSizePixel();
672 Size
aSize( nSizeX
, nHeight
);
674 if ( aSize
.Height() > aParentSize
.Height() )
675 aSize
.Height() = aParentSize
.Height();
676 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
677 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
679 pFilterBox
->SetSizePixel( aSize
);
680 pFilterBox
->Show(); // Show must be called before SetUpdateMode
681 pFilterBox
->SetUpdateMode(FALSE
);
683 pFilterFloat
->SetOutputSizePixel( aSize
);
684 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
687 BOOL bWait
= ( nCount
> 100 );
692 for (i
=0; i
<nCount
; i
++)
693 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
695 pFilterBox
->SetSeparatorPos( 0 );
700 pFilterBox
->SetUpdateMode(TRUE
);
702 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
704 nSelPos
= pFilterBox
->GetEntryPos( aCurrentPage
);
706 if ( nSelPos
== LISTBOX_ENTRY_NOTFOUND
)
707 nSelPos
= 0; // first entry
709 pFilterBox
->GrabFocus();
711 // call Select after GrabFocus, so the focus rectangle ends up in the right position
712 if ( nSelPos
!= LISTBOX_ENTRY_NOTFOUND
)
713 pFilterBox
->SelectEntryPos( nSelPos
);
715 pFilterBox
->EndInit();
717 nMouseStatus
= SC_GM_FILTER
;
721 void ScGridWindow::DoScenarioMenue( const ScRange
& rScenRange
)
726 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
727 SCROW nRow
= rScenRange
.aStart
.Row();
730 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
731 if (nRow
>MAXROW
) nRow
= MAXROW
;
732 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
735 ScDocument
* pDoc
= pViewData
->GetDocument();
736 SCTAB nTab
= pViewData
->GetTabNo();
737 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
742 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
743 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
746 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
747 aCellRect
.Top() -= nSizeY
;
748 aCellRect
.Bottom() -= nSizeY
- 1;
749 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
750 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
752 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
753 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
754 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
756 pFilterBox
->EnableMirroring();
761 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
762 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
764 nHeight
= GetTextHeight();
765 nHeight
*= SC_FILTERLISTBOX_LINES
;
767 SetMapMode( aOldMode
);
773 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
774 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
775 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
778 // ParentSize Abfrage fehlt
779 Size
aSize( nSizeX
, nHeight
);
780 pFilterBox
->SetSizePixel( aSize
);
781 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
782 pFilterBox
->SetUpdateMode(FALSE
);
784 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
791 SCTAB nTabCount
= pDoc
->GetTableCount();
792 SCTAB nEntryCount
= 0;
793 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
795 if (pDoc
->HasScenarioRange( i
, rScenRange
))
796 if (pDoc
->GetName( i
, aTabName
))
798 pFilterBox
->InsertEntry( aTabName
);
799 if (pDoc
->IsActiveScenario(i
))
801 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
802 if ( nTextWidth
> nMaxText
)
803 nMaxText
= nTextWidth
;
807 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
808 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
809 nMaxText
+= 4; // fuer Rand
810 if ( nMaxText
> 300 )
811 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
813 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
815 long nDiff
= nMaxText
- nSizeX
;
816 aSize
= Size( nMaxText
, nHeight
);
817 pFilterBox
->SetSizePixel( aSize
);
818 pFilterFloat
->SetOutputSizePixel( aSize
);
822 // also move popup position
823 long nNewX
= aCellRect
.Left() - nDiff
;
826 aCellRect
.Left() = nNewX
;
830 pFilterFloat
->SetOutputSizePixel( aSize
);
831 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
833 pFilterBox
->SetUpdateMode(TRUE
);
834 pFilterBox
->GrabFocus();
836 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
837 //! SvLBoxEntry* pSelect = NULL;
838 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
841 nPos
= pFilterBox
->GetEntryPos( aCurrent
);
842 //! pSelect = pFilterBox->GetEntry( nPos );
844 if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
846 //! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein
847 if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND
!= nPos
)
848 pFilterBox
->SelectEntryPos(nPos
);
850 pFilterBox
->EndInit();
852 // Szenario-Auswahl kommt aus MouseButtonDown:
853 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
855 nMouseStatus
= SC_GM_FILTER
;
859 void ScGridWindow::DoAutoFilterMenue( SCCOL nCol
, SCROW nRow
, BOOL bDataSelect
)
865 ScDocument
* pDoc
= pViewData
->GetDocument();
866 SCTAB nTab
= pViewData
->GetTabNo();
867 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
872 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
873 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
877 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
880 aPos
.Y() += nSizeY
- 1;
882 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
883 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
884 pFilterBox
= new ScFilterListBox(
885 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
887 pFilterBox
->EnableMirroring();
892 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
893 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
895 nHeight
= GetTextHeight();
896 nHeight
*= SC_FILTERLISTBOX_LINES
;
898 SetMapMode( aOldMode
);
904 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
905 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
906 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
910 TypedScStrCollection
aStrings( 128, 128 );
911 if ( bDataSelect
) // Auswahl-Liste
914 aStrings
.SetCaseSensitive( TRUE
);
915 pDoc
->GetDataEntries( nCol
, nRow
, nTab
, aStrings
);
916 if ( aStrings
.GetCount() == 0 )
921 //! wird der Titel ueberhaupt ausgewertet ???
923 pDoc
->GetString( nCol
, nRow
, nTab
, aString
);
924 pFilterBox
->SetText( aString
);
929 static const USHORT nDefIDs
[] = { SCSTR_ALLFILTER
, SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_EMPTY
, SCSTR_NOTEMPTY
};
930 const USHORT nDefCount
= sizeof(nDefIDs
) / sizeof(USHORT
);
931 for (i
=0; i
<nDefCount
; i
++)
933 String
aEntry( (ScResId
) nDefIDs
[i
] );
934 pFilterBox
->InsertEntry( aEntry
);
935 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
936 if ( nTextWidth
> nMaxText
)
937 nMaxText
= nTextWidth
;
939 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
942 bool bHasDates
= false;
943 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
944 pFilterBox
->SetListHasDates(bHasDates
);
946 // check widths of numerical entries (string entries are not included)
947 // so all numbers are completely visible
948 USHORT nCount
= aStrings
.GetCount();
949 for (i
=0; i
<nCount
; i
++)
951 TypedStrData
* pData
= aStrings
[i
];
952 if ( !pData
->IsStrData() ) // only numerical entries
954 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
955 if ( nTextWidth
> nMaxText
)
956 nMaxText
= nTextWidth
;
960 // add scrollbar width if needed (string entries are counted here)
961 // (scrollbar is shown if the box is exactly full?)
962 if ( nCount
+ nDefCount
>= SC_FILTERLISTBOX_LINES
)
963 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
965 nMaxText
+= 4; // for borders
967 if ( nMaxText
> nSizeX
)
968 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
973 // Position und Groesse an Fenster anpassen
974 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
976 Size aParentSize
= GetParent()->GetOutputSizePixel();
977 Size
aSize( nSizeX
, nHeight
);
979 if ( aSize
.Height() > aParentSize
.Height() )
980 aSize
.Height() = aParentSize
.Height();
981 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
982 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
984 pFilterBox
->SetSizePixel( aSize
);
985 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
986 pFilterBox
->SetUpdateMode(FALSE
);
988 pFilterFloat
->SetOutputSizePixel( aSize
);
989 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
992 USHORT nCount
= aStrings
.GetCount();
993 BOOL bWait
= ( nCount
> 100 );
998 for (i
=0; i
<nCount
; i
++)
999 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
1004 pFilterBox
->SetUpdateMode(TRUE
);
1007 //! SvLBoxEntry* pSelect = NULL;
1008 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1010 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1012 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1015 ScQueryParam aParam
;
1016 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1019 for (SCSIZE j
=0; j
<MAXQUERY
&& bValid
; j
++) // bisherige Filter-Einstellungen
1020 if (aParam
.GetEntry(j
).bDoQuery
)
1022 //! Abfrage mit DrawButtons zusammenfassen!
1024 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1026 if (rEntry
.eConnect
!= SC_AND
)
1028 if (rEntry
.nField
== nCol
)
1030 if (rEntry
.eOp
== SC_EQUAL
)
1032 String
* pStr
= rEntry
.pStr
;
1035 nSelPos
= pFilterBox
->GetEntryPos( *pStr
);
1036 //! pSelect = pFilterBox->GetEntry( nPos );
1039 else if (rEntry
.eOp
== SC_TOPVAL
&& rEntry
.pStr
&&
1040 rEntry
.pStr
->EqualsAscii("10"))
1041 nSelPos
= SC_AUTOFILTER_TOP10
;
1043 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1048 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1052 // neu (309): irgendwas muss immer selektiert sein:
1053 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 )
1056 // keine leere Auswahl-Liste anzeigen:
1060 DELETEZ(pFilterBox
); // war nix
1061 DELETEZ(pFilterFloat
);
1062 Sound::Beep(); // bemerkbar machen
1066 // pFilterBox->Show(); // schon vorne
1067 pFilterBox
->GrabFocus();
1069 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1070 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1071 pFilterBox
->SelectEntryPos( nSelPos
);
1073 pFilterBox
->EndInit();
1077 // AutoFilter (aus MouseButtonDown):
1078 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1080 nMouseStatus
= SC_GM_FILTER
;
1086 void ScGridWindow::FilterSelect( ULONG nSel
)
1090 SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
1093 SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
1095 aString = pStringEntry->GetText();
1098 aString
= pFilterBox
->GetEntry( static_cast< USHORT
>( nSel
) );
1100 SCCOL nCol
= pFilterBox
->GetCol();
1101 SCROW nRow
= pFilterBox
->GetRow();
1102 switch ( pFilterBox
->GetMode() )
1104 case SC_FILTERBOX_DATASELECT
:
1105 ExecDataSelect( nCol
, nRow
, aString
);
1107 case SC_FILTERBOX_FILTER
:
1108 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1110 case SC_FILTERBOX_SCENARIO
:
1111 pViewData
->GetView()->UseScenario( aString
);
1113 case SC_FILTERBOX_PAGEFIELD
:
1114 // first entry is "all"
1115 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1120 pFilterFloat
->EndPopupMode();
1122 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1125 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const String
& rStr
)
1129 SCTAB nTab
= pViewData
->GetTabNo();
1130 ScViewFunc
* pView
= pViewData
->GetView();
1131 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1133 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1134 // if the cursor is moved afterwards.
1135 pView
->CellContentChanged();
1139 void ScGridWindow::ExecFilter( ULONG nSel
,
1140 SCCOL nCol
, SCROW nRow
,
1141 const String
& aValue
, bool bCheckForDates
)
1143 SCTAB nTab
= pViewData
->GetTabNo();
1144 ScDocument
* pDoc
= pViewData
->GetDocument();
1146 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1149 ScQueryParam aParam
;
1150 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1152 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1154 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1155 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1159 BOOL bDeleteOld
= FALSE
;
1160 SCSIZE nQueryPos
= 0;
1161 BOOL bFound
= FALSE
;
1162 if (!aParam
.bInplace
)
1166 for (SCSIZE i
=0; i
<MAXQUERY
&& !bDeleteOld
; i
++) // bisherige Filter-Einstellungen
1167 if (aParam
.GetEntry(i
).bDoQuery
)
1169 //! Abfrage mit DrawButtons zusammenfassen!
1171 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1173 if (rEntry
.eConnect
!= SC_AND
)
1176 if (rEntry
.nField
== nCol
)
1178 if (bFound
) // diese Spalte zweimal?
1189 SCSIZE nEC
= aParam
.GetEntryCount();
1190 for (SCSIZE i
=0; i
<nEC
; i
++)
1191 aParam
.GetEntry(i
).Clear();
1193 aParam
.bInplace
= TRUE
;
1194 aParam
.bRegExp
= FALSE
;
1197 if ( nQueryPos
< MAXQUERY
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1201 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1203 rNewEntry
.bDoQuery
= TRUE
;
1204 rNewEntry
.bQueryByString
= TRUE
;
1205 rNewEntry
.nField
= nCol
;
1206 rNewEntry
.bQueryByDate
= bCheckForDates
;
1207 if ( nSel
== SC_AUTOFILTER_TOP10
)
1209 rNewEntry
.eOp
= SC_TOPVAL
;
1210 *rNewEntry
.pStr
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
1212 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1214 rNewEntry
.pStr
->Erase();
1215 rNewEntry
.bQueryByString
= FALSE
;
1216 rNewEntry
.eOp
= SC_EQUAL
;
1217 rNewEntry
.nVal
= SC_EMPTYFIELDS
;
1220 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1222 rNewEntry
.pStr
->Erase();
1223 rNewEntry
.bQueryByString
= FALSE
;
1224 rNewEntry
.eOp
= SC_EQUAL
;
1225 rNewEntry
.nVal
= SC_NONEMPTYFIELDS
;
1229 rNewEntry
.eOp
= SC_EQUAL
;
1230 *rNewEntry
.pStr
= aValue
;
1233 rNewEntry
.eConnect
= SC_AND
;
1238 aParam
.DeleteQuery(nQueryPos
);
1241 // #100597# end edit mode - like in ScCellShell::ExecuteDB
1242 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1244 SC_MOD()->InputEnterHandler();
1245 pViewData
->GetViewShell()->UpdateInputHandler();
1248 aParam
.bUseDynamicRange
= true;
1249 pViewData
->GetView()->Query( aParam
, NULL
, TRUE
);
1250 pDBData
->SetQueryParam( aParam
); // speichern
1252 else // "Zuviele Bedingungen"
1253 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1258 DBG_ERROR("Wo ist der Datenbankbereich?");
1262 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1264 nCurrentPointer
= 0;
1265 Window::SetPointer( rPointer
);
1268 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1272 rDestWin
.nButtonDown
= nButtonDown
;
1273 rDestWin
.nMouseStatus
= nMouseStatus
;
1278 rDestWin
.bRFMouse
= bRFMouse
;
1279 rDestWin
.bRFSize
= bRFSize
;
1280 rDestWin
.nRFIndex
= nRFIndex
;
1281 rDestWin
.nRFAddX
= nRFAddX
;
1282 rDestWin
.nRFAddY
= nRFAddY
;
1286 if (nPagebreakMouse
)
1288 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1289 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1290 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1291 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1292 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1293 nPagebreakMouse
= SC_PD_NONE
;
1297 BOOL
ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, BOOL bAction
)
1299 // MouseEvent buttons must only be checked if bAction==TRUE
1300 // to allow changing the mouse pointer in MouseMove,
1301 // but not start AutoFill with right button (#74229#).
1302 // with bAction==TRUE, SetFillMode / SetDragMode is called
1304 if ( bAction
&& !rMEvt
.IsLeft() )
1307 BOOL bNewPointer
= FALSE
;
1309 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1310 BOOL bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1312 if ( pViewData
->IsActive() && !bOleActive
)
1314 ScDocument
* pDoc
= pViewData
->GetDocument();
1315 SCTAB nTab
= pViewData
->GetTabNo();
1316 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1317 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1322 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1324 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1326 Point aMousePos
= rMEvt
.GetPosPixel();
1327 if (mpAutoFillRect
->IsInside(aMousePos
))
1329 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1332 SCCOL nX
= aMarkRange
.aEnd
.Col();
1333 SCROW nY
= aMarkRange
.aEnd
.Row();
1335 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1336 pViewData
->SetDragMode(
1337 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1339 pViewData
->SetFillMode(
1340 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1342 // #108266# The simple selection must also be recognized when dragging,
1343 // where the Marking flag is set and MarkToSimple won't work anymore.
1344 pViewData
->GetMarkData().MarkToSimple();
1351 // Embedded-Rechteck
1353 if (pDoc
->IsEmbedded())
1356 pDoc
->GetEmbedded( aRange
);
1357 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1359 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1360 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1361 Point aMousePos
= rMEvt
.GetPosPixel();
1367 BOOL bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1368 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1369 BOOL bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1370 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1371 if ( bTop
|| bBottom
)
1373 SetPointer( Pointer( POINTER_CROSS
) );
1376 BYTE nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1377 pViewData
->SetDragMode(
1378 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1379 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1387 if (!bNewPointer
&& bAction
)
1389 // SetPointer( POINTER_ARROW ); // in Fu...
1390 pViewData
->ResetFillMode();
1396 void __EXPORT
ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1398 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1400 HandleMouseButtonDown( rMEvt
);
1402 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1404 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1405 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1406 // simulate another MouseButtonUp call, so the selection state is consistent.
1408 nButtonDown
= rMEvt
.GetButtons();
1412 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1414 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1417 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
)
1419 // We have to check if a context menu is shown and we have an UI
1420 // active inplace client. In that case we have to ignore the event.
1421 // Otherwise we would crash (context menu has been
1422 // opened by inplace client and we would deactivate the inplace client,
1423 // the contex menu is closed by VCL asynchronously which in the end
1424 // would work on deleted objects or the context menu has no parent anymore)
1425 // See #126086# and #128122#
1426 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1427 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1429 pClient
->IsObjectInPlaceActive() &&
1430 PopupMenu::IsInExecute() )
1433 aCurMousePos
= rMEvt
.GetPosPixel();
1435 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1436 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1438 // merken, dass FilterBox geloescht wird, damit sichergestellt
1439 // ist, dass in diesem Handler nicht an gleicher Stelle wieder
1440 // eine neue geoeffnet wird.
1441 BOOL bWasFilterBox
= ( pFilterBox
!= NULL
&&
1442 ((Window
*)pFilterBox
)->IsVisible() &&
1443 !pFilterBox
->IsDataSelect() );
1444 SCCOL nOldColFBox
= bWasFilterBox
? pFilterBox
->GetCol() : 0;
1445 SCROW nOldRowFBox
= bWasFilterBox
? pFilterBox
->GetRow() : 0;
1447 #include "cellsuno.hxx"
1449 ClickExtern(); // loescht FilterBox, wenn vorhanden
1451 HideNoteMarker(); // Notiz-Anzeige
1455 ScModule
* pScMod
= SC_MOD();
1456 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1462 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1463 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1465 BOOL bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1466 BOOL bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1467 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1468 BOOL bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1469 BOOL bDouble
= (rMEvt
.GetClicks() == 2);
1471 // DeactivateIP passiert nur noch bei MarkListHasChanged
1473 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1474 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1476 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1477 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1479 // pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1480 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1483 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1484 // but a single (first) click is always valid
1485 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1488 nMouseStatus
= SC_GM_NONE
;
1492 if ( bDetective
) // Detektiv-Fuell-Modus
1494 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1496 Point aPos
= rMEvt
.GetPosPixel();
1499 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1501 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1502 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1503 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1504 &aPosXItem
, &aPosYItem
, (void*)0L );
1508 nMouseStatus
= SC_GM_NONE
;
1513 nMouseStatus
= SC_GM_NONE
;
1517 if ( pViewData
->GetActivePart() != eWhich
)
1518 pViewData
->GetView()->ActivatePart( eWhich
);
1522 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1523 pSelEng
->SetWindow(this);
1524 pSelEng
->SetWhich(eWhich
);
1525 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1528 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1530 Point aPos
= rMEvt
.GetPosPixel();
1533 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1535 EditView
* pEditView
;
1538 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1539 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1540 SCROW nEndRow
= pViewData
->GetEditEndRow();
1542 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1543 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1545 // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
1546 if (bFormulaMode
) // sonst ist es oben schon passiert
1549 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1551 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1556 if (pScMod
->GetIsWaterCan())
1558 //! was is mit'm Mac ???
1559 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1561 nMouseStatus
= SC_GM_WATERUNDO
;
1566 // Reihenfolge passend zum angezeigten Cursor:
1567 // RangeFinder, AutoFill, PageBreak, Drawing
1569 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bRFSize
, &nRFIndex
, &nRFAddX
, &nRFAddY
) )
1571 bRFMouse
= TRUE
; // die anderen Variablen sind oben initialisiert
1573 if ( pViewData
->GetActivePart() != eWhich
)
1574 pViewData
->GetView()->ActivatePart( eWhich
); //! schon oben immer ???
1581 BOOL bCrossPointer
= TestMouse( rMEvt
, TRUE
);
1582 if ( bCrossPointer
)
1585 pViewData
->GetView()->FillCrossDblClick();
1587 pScMod
->InputEnterHandler(); // Autofill etc.
1590 if ( !bCrossPointer
)
1592 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1593 &nPagebreakBreak
, &nPagebreakPrev
);
1594 if (nPagebreakMouse
)
1596 bPagebreakDrawn
= FALSE
;
1599 PagebreakMove( rMEvt
, FALSE
);
1604 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1606 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1608 //if (DrawHasMarkedObj())
1609 // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert
1613 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // kein Draw-Objekt selektiert
1615 // TestMouse schon oben passiert
1618 Point aPos
= rMEvt
.GetPosPixel();
1621 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1622 SCTAB nTab
= pViewData
->GetTabNo();
1623 ScDocument
* pDoc
= pViewData
->GetDocument();
1627 // AutoFilter buttons
1630 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1632 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1633 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1634 if (pAttr
->HasAutoFilter())
1636 Point aScrPos
= pViewData
->GetScrPos(nPosX
,nPosY
,eWhich
);
1639 Point aDiffPix
= aPos
;
1641 aDiffPix
-= aScrPos
;
1642 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1644 aDiffPix
.X() = -aDiffPix
.X();
1646 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
1648 // Breite des Buttons ist nicht von der Zellhoehe abhaengig
1649 Size aButSize
= aComboButton
.GetSizePixel();
1650 long nButWidth
= Min( aButSize
.Width(), nSizeX
);
1651 long nButHeight
= Min( aButSize
.Height(), nSizeY
);
1653 if ( aDiffPix
.X() >= nSizeX
- nButWidth
&&
1654 aDiffPix
.Y() >= nSizeY
- nButHeight
)
1656 if ( DoPageFieldSelection( nPosX
, nPosY
) )
1659 BOOL bFilterActive
= IsAutoFilterActive( nPosX
, nPosY
,
1660 pViewData
->GetTabNo() );
1662 aComboButton
.SetOptSizePixel();
1663 DrawComboButton( aScrPos
, nSizeX
, nSizeY
, bFilterActive
, TRUE
);
1667 && (SCsCOL
)nOldColFBox
== nPosX
1668 && (SCsROW
)nOldRowFBox
== nPosY
)
1670 // Verhindern, dass an gleicher Stelle eine
1671 // FilterBox geoeffnet wird, wenn diese gerade
1674 nMouseStatus
= SC_GM_FILTER
; // fuer ButtonDraw im MouseButtonUp();
1678 DoAutoFilterMenue( nPosX
, nPosY
, FALSE
);
1683 if (pAttr
->HasButton())
1685 DoPushButton( nPosX
, nPosY
, rMEvt
); // setzt evtl. bPivotMouse / bDPMouse
1689 // List Validity drop-down button
1691 if ( bListValButton
)
1693 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1694 if ( aButtonRect
.IsInside( aPos
) )
1696 DoAutoFilterMenue( aListValPos
.Col(), aListValPos
.Row(), TRUE
);
1698 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1706 // scenario selection
1710 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1712 DoScenarioMenue( aScenRange
);
1717 // Doppelklick angefangen ?
1720 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1722 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1724 if ( bDouble
&& !bCrossPointer
)
1726 if (nMouseStatus
== SC_GM_TABDOWN
)
1727 nMouseStatus
= SC_GM_DBLDOWN
;
1730 nMouseStatus
= SC_GM_TABDOWN
;
1734 // Links in Edit-Zellen
1737 BOOL bAlt
= rMEvt
.IsMod2();
1738 if ( !bAlt
&& rMEvt
.IsLeft() &&
1739 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1741 SetPointer( Pointer( POINTER_REFHAND
) );
1742 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1747 // Gridwin - SelectionEngine
1750 if ( rMEvt
.IsLeft() )
1752 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1753 pSelEng
->SetWindow(this);
1754 pSelEng
->SetWhich(eWhich
);
1755 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1757 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1758 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1760 if (IsMouseCaptured())
1762 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1763 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1767 pViewData
->GetMarkData().SetMarking(TRUE
);
1773 void __EXPORT
ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1775 aCurMousePos
= rMEvt
.GetPosPixel();
1776 ScDocument
* pDoc
= pViewData
->GetDocument();
1777 ScMarkData
& rMark
= pViewData
->GetMarkData();
1779 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1780 // (possible through Reschedule from storing an OLE object that is deselected)
1782 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
1783 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
1785 if (nButtonDown
!= rMEvt
.GetButtons())
1786 nMouseStatus
= SC_GM_IGNORE
; // reset und return
1790 if (nMouseStatus
== SC_GM_IGNORE
)
1792 nMouseStatus
= SC_GM_NONE
;
1793 // Selection-Engine: Markieren abbrechen
1794 pViewData
->GetView()->GetSelEngine()->Reset();
1795 rMark
.SetMarking(FALSE
);
1796 if (pViewData
->IsAnyFillMode())
1798 pViewData
->GetView()->StopRefMode();
1799 pViewData
->ResetFillMode();
1802 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1807 if (nMouseStatus
== SC_GM_FILTER
)
1809 if ( pFilterBox
&& pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
1811 BOOL bFilterActive
= IsAutoFilterActive( pFilterBox
->GetCol(), pFilterBox
->GetRow(),
1812 pViewData
->GetTabNo() );
1814 aComboButton
.Draw( bFilterActive
);
1817 nMouseStatus
= SC_GM_NONE
;
1819 return; // da muss nix mehr passieren
1822 ScModule
* pScMod
= SC_MOD();
1823 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1826 SfxBindings
& rBindings
= pViewData
->GetBindings();
1827 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
1829 EditView
* pEditView
;
1832 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1833 pEditView
->MouseButtonUp( rMEvt
);
1835 if ( rMEvt
.IsMiddle() &&
1836 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1838 // EditView may have pasted from selection
1839 pScMod
->InputChanged( pEditView
);
1842 pScMod
->InputSelection( pEditView
); // parentheses etc.
1844 pViewData
->GetView()->InvalidateAttribs();
1845 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
1850 #if OLD_PIVOT_IMPLEMENTATION
1853 PivotMouseButtonUp( rMEvt
);
1854 bPivotMouse
= FALSE
;
1861 DPMouseButtonUp( rMEvt
); // resets bDPMouse
1867 RFMouseMove( rMEvt
, TRUE
); // Range wieder richtigherum
1869 SetPointer( Pointer( POINTER_ARROW
) );
1874 if (nPagebreakMouse
)
1876 PagebreakMove( rMEvt
, TRUE
);
1877 nPagebreakMouse
= SC_PD_NONE
;
1878 SetPointer( Pointer( POINTER_ARROW
) );
1883 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
1885 SfxUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
1886 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
1893 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
1896 rMark
.SetMarking(FALSE
);
1898 SetPointer( Pointer( POINTER_ARROW
) );
1900 if (pViewData
->IsFillMode() ||
1901 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
1903 nScFillModeMouseModifier
= rMEvt
.GetModifier();
1908 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1909 // DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
1910 // "Block falsch fuer AutoFill" );
1912 BOOL bIsDel
= pViewData
->GetDelMark( aDelRange
);
1914 ScViewFunc
* pView
= pViewData
->GetView();
1915 pView
->StopRefMode();
1916 pViewData
->ResetFillMode();
1917 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
); // #i5819# don't use AutoFill anchor flag for selection
1921 pView
->MarkRange( aDelRange
, FALSE
);
1922 pView
->DeleteContents( IDF_CONTENTS
);
1923 SCTAB nTab
= pViewData
->GetTabNo();
1924 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1925 if ( aBlockRange
!= aDelRange
)
1927 if ( aDelRange
.aStart
.Row() == nStartRow
)
1928 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
1930 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
1931 pView
->MarkRange( aBlockRange
, FALSE
);
1935 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1937 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
1939 SCTAB nTab
= pViewData
->GetTabNo();
1944 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1945 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1946 SCCOL nFillCol
= pViewData
->GetRefEndX();
1947 SCROW nFillRow
= pViewData
->GetRefEndY();
1948 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
1950 ScTabView
* pView
= pViewData
->GetView();
1951 pView
->StopRefMode();
1952 pViewData
->ResetFillMode();
1953 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
1955 if ( aEndPos
!= aBlockRange
.aEnd
)
1957 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, FALSE
);
1958 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
1961 else if (pViewData
->IsAnyFillMode())
1963 // Embedded-Area has been changed
1964 ScTabView
* pView
= pViewData
->GetView();
1965 pView
->StopRefMode();
1966 pViewData
->ResetFillMode();
1967 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
1968 pViewData
->GetDocShell()->UpdateOle(pViewData
);
1971 BOOL bRefMode
= pViewData
->IsRefMode();
1973 pScMod
->EndReference();
1976 // Giesskannen-Modus (Gestalter)
1979 if (pScMod
->GetIsWaterCan())
1981 // Abfrage auf Undo schon oben
1983 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
1984 (pViewData
->GetDocument()->
1985 GetStyleSheetPool());
1988 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
1989 pStylePool
->GetActualStyleSheet();
1993 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
1997 case SFX_STYLE_FAMILY_PARA
:
1998 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
1999 pViewData
->GetView()->DoneBlockMode();
2002 case SFX_STYLE_FAMILY_PAGE
:
2003 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2004 pStyleSheet
->GetName() );
2006 ScPrintFunc( pViewData
->GetDocShell(),
2007 pViewData
->GetViewShell()->GetPrinter(TRUE
),
2008 pViewData
->GetTabNo() ).UpdatePages();
2010 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2020 ScDBFunc
* pView
= pViewData
->GetView();
2021 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2024 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2025 if ( !pView
->IsPaintBrushLocked() )
2026 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2030 // double click (only left button)
2033 BOOL bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2034 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2037 Point aPos
= rMEvt
.GetPosPixel();
2040 SCTAB nTab
= pViewData
->GetTabNo();
2041 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2042 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2043 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2045 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2047 // Check for header drill-down first.
2048 sheet::DataPilotTableHeaderData aData
;
2049 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2051 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2052 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2055 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2057 // execute slot to show dialog
2058 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2062 // toggle single entry
2063 ScDPObject
aNewObj( *pDPObj
);
2064 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2065 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2066 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
2067 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2072 // Check if the data area is double-clicked.
2074 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2075 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2076 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2078 Sound::Beep(); // nothing to expand/collapse/show
2084 // Check for cell protection attribute.
2085 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2086 bool bEditAllowed
= true;
2087 if ( pProtect
&& pProtect
->isProtected() )
2089 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2090 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2091 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2093 if ( bSkipProtected
&& bSkipUnprotected
)
2094 bEditAllowed
= false;
2095 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2096 bEditAllowed
= false;
2101 // edit cell contents
2102 pViewData
->GetViewShell()->UpdateInputHandler();
2103 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2104 if (pViewData
->HasEditView(eWhich
))
2106 // Text-Cursor gleich an die geklickte Stelle setzen
2107 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2108 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2109 pEditView
->MouseButtonDown( aEditEvt
);
2110 pEditView
->MouseButtonUp( aEditEvt
);
2117 // Links in edit cells
2120 BOOL bAlt
= rMEvt
.IsMod2();
2121 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2123 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2125 String aName
, aUrl
, aTarget
;
2126 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2128 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2129 ScGlobal::OpenURL( aUrl
, aTarget
);
2131 // fire worksheet_followhyperlink event
2132 Point aPos
= rMEvt
.GetPosPixel();
2135 SCTAB nTab
= pViewData
->GetTabNo();
2136 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2137 ScBaseCell
* pCell
= NULL
;
2139 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
2142 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2143 ScCellObj
* pObj
= new ScCellObj( pViewData
->GetDocShell(), aCellPos
);
2144 uno::Sequence
< uno::Any
> aArgs(1);
2145 aArgs
[0] = uno::makeAny(uno::Reference
<uno::XInterface
>(static_cast<cppu::OWeakObject
*>(pObj
)));
2146 uno::Reference
< document::XVbaEventsHelper
> xVbaEventsHelper ( pViewData
->GetDocument()->GetVbaEventsHelper(), uno::UNO_QUERY
);
2147 if( xVbaEventsHelper
.is() )
2148 xVbaEventsHelper
->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2155 // Gridwin - SelectionEngine
2158 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2159 // TRUE for any call, so IsLeft must be checked here, too.
2161 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2163 // rMark.MarkToSimple();
2164 pViewData
->GetView()->UpdateAutoFillMark();
2166 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2167 BOOL bFormulaMode
= pScMod
->IsFormulaMode();
2168 DBG_ASSERT( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2170 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2171 // multiple selection, so the argument string completely describes the selection,
2172 // and executing the slot won't change the existing selection (executing the slot
2173 // here and from a recorded macro is treated equally)
2175 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2177 String aAddr
; // CurrentCell
2178 if( rMark
.IsMarked() )
2180 // BOOL bKeep = rMark.IsMultiMarked(); //! wohin damit ???
2183 rMark
.GetMarkArea( aScRange
);
2184 aScRange
.Format( aAddr
, SCR_ABS
);
2185 if ( aScRange
.aStart
== aScRange
.aEnd
)
2187 // make sure there is a range selection string even for a single cell
2188 String aSingle
= aAddr
;
2189 aAddr
.Append( (sal_Char
) ':' );
2190 aAddr
.Append( aSingle
);
2193 //! SID_MARKAREA gibts nicht mehr ???
2194 //! was passiert beim Markieren mit dem Cursor ???
2196 else // nur Cursor bewegen
2198 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2199 aScAddress
.Format( aAddr
, SCA_ABS
);
2202 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2203 // We don't want to align to the cursor position because if the
2204 // cell cursor isn't visible after making selection, it would jump
2205 // back to the origin of the selection where the cell cursor is.
2206 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2207 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2208 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2210 pViewData
->GetView()->InvalidateAttribs();
2216 void ScGridWindow::FakeButtonUp()
2220 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2221 MouseButtonUp( aEvent
);
2225 void __EXPORT
ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2227 aCurMousePos
= rMEvt
.GetPosPixel();
2229 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2232 ScModule
* pScMod
= SC_MOD();
2233 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2236 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2237 // nicht anders mit:
2239 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2243 nMouseStatus
= SC_GM_NONE
;
2247 if (nMouseStatus
== SC_GM_IGNORE
)
2250 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2253 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2255 SetPointer( Pointer( POINTER_FILL
) );
2259 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2261 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2262 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2265 nMouseStatus
= SC_GM_NONE
;
2266 if ( pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
2269 aComboButton
.Draw( FALSE
);
2273 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2278 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2280 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2282 EditView
* pEditView
;
2285 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2286 pEditView
->MouseMove( rMEvt
);
2290 #if OLD_PIVOT_IMPLEMENTATION
2293 PivotMouseMove( rMEvt
);
2300 DPMouseMove( rMEvt
);
2306 RFMouseMove( rMEvt
, FALSE
);
2310 if (nPagebreakMouse
)
2312 PagebreakMove( rMEvt
, FALSE
);
2316 // anderen Mauszeiger anzeigen?
2318 BOOL bEditMode
= pViewData
->HasEditView(eWhich
);
2320 //! Testen ob RefMode-Dragging !!!
2321 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2323 Point aPos
= rMEvt
.GetPosPixel();
2326 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2328 EditView
* pEditView
;
2331 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2332 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2333 SCROW nEndRow
= pViewData
->GetEditEndRow();
2335 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2336 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2338 // Field can only be URL field
2339 BOOL bAlt
= rMEvt
.IsMod2();
2340 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2341 SetPointer( Pointer( POINTER_REFHAND
) );
2342 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2343 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2345 SetPointer( Pointer( POINTER_TEXT
) );
2350 BOOL bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2352 SetPointer( Pointer(POINTER_FILL
) );
2356 BOOL bCross
= FALSE
;
2361 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bCorner
) )
2364 SetPointer( Pointer( POINTER_CROSS
) );
2366 SetPointer( Pointer( POINTER_HAND
) );
2373 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2374 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2376 PointerStyle eNew
= POINTER_ARROW
;
2377 switch ( nBreakType
)
2382 eNew
= POINTER_ESIZE
;
2387 eNew
= POINTER_SSIZE
;
2389 case SC_PD_RANGE_TL
:
2390 case SC_PD_RANGE_BR
:
2391 eNew
= POINTER_SESIZE
;
2393 case SC_PD_RANGE_TR
:
2394 case SC_PD_RANGE_BL
:
2395 eNew
= POINTER_NESIZE
;
2398 SetPointer( Pointer( eNew
) );
2402 // Fill-Cursor anzeigen ?
2404 if ( !bFormulaMode
&& !nButtonDown
)
2405 if (TestMouse( rMEvt
, FALSE
))
2408 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2410 SetPointer( Pointer( POINTER_CROSS
) );
2412 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2417 BOOL bAlt
= rMEvt
.IsMod2();
2419 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2420 SetPointer( Pointer( POINTER_ARROW
) );
2421 else if ( !bAlt
&& !nButtonDown
&&
2422 GetEditUrl(rMEvt
.GetPosPixel()) )
2423 SetPointer( Pointer( POINTER_REFHAND
) );
2424 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2429 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2433 void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2435 rEvent
.Modifiers
= 0;
2436 if ( rEvt
.IsShift() )
2437 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2438 if ( rEvt
.IsMod1() )
2439 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2440 if ( rEvt
.IsMod2() )
2441 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2444 if ( rEvt
.IsLeft() )
2445 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2446 if ( rEvt
.IsRight() )
2447 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2448 if ( rEvt
.IsMiddle() )
2449 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2451 rEvent
.X
= rEvt
.GetPosPixel().X();
2452 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2453 rEvent
.ClickCount
= rEvt
.GetClicks();
2454 rEvent
.PopupTrigger
= sal_False
;
2457 long ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2459 USHORT nType
= rNEvt
.GetType();
2460 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2462 Window
* pWindow
= rNEvt
.GetWindow();
2463 if (pWindow
== this && pViewData
)
2465 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2468 SfxFrame
* pFrame
= pViewFrame
->GetFrame();
2471 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pFrame
->GetController();
2472 if (xController
.is())
2474 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2475 if (pImp
&& pImp
->IsMouseListening())
2477 ::com::sun::star::awt::MouseEvent aEvent
;
2478 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2479 if ( rNEvt
.GetWindow() )
2480 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2481 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2482 pImp
->MousePressed( aEvent
);
2484 pImp
->MouseReleased( aEvent
);
2492 return Window::PreNotify( rNEvt
);
2495 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2497 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2498 // die verschiedenen MouseHandler verteilen...
2500 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2502 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2504 if (!pViewData
->GetView()->IsInActivatePart())
2506 #if OLD_PIVOT_IMPLEMENTATION
2508 bPivotMouse
= FALSE
; // gezeichnet wird per bDragRect
2511 bDPMouse
= FALSE
; // gezeichnet wird per bDragRect
2514 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2516 UpdateDragRectOverlay();
2520 RFMouseMove( rMEvt
, TRUE
); // richtig abbrechen geht dabei nicht...
2523 if (nPagebreakMouse
)
2525 // if (bPagebreakDrawn)
2526 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2527 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
2528 bPagebreakDrawn
= FALSE
;
2529 UpdateDragRectOverlay();
2530 nPagebreakMouse
= SC_PD_NONE
;
2533 SetPointer( Pointer( POINTER_ARROW
) );
2535 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2537 BOOL bRefMode
= pViewData
->IsRefMode();
2539 SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen
2542 else if ( rTEvt
.IsTrackingEnded() )
2544 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2545 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2546 // abgebrochen wurde.
2548 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2549 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2550 MouseButtonUp( aUpEvt
);
2556 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2558 if ( pFilterBox
|| nPagebreakMouse
)
2563 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, TRUE
);
2565 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2567 EditView
* pEditView
;
2570 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2572 // #63263# don't remove the edit view while switching views
2573 ScModule
* pScMod
= SC_MOD();
2574 pScMod
->SetInEditCommand( TRUE
);
2576 pEditView
->Command( aDragEvent
);
2578 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2580 pHdl
->DataChanged();
2582 pScMod
->SetInEditCommand( FALSE
);
2583 if (!pViewData
->IsActive()) // dropped to different view?
2585 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2586 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2588 pViewHdl
->CancelHandler();
2589 ShowCursor(); // missing from KillEditView
2594 if ( !DrawCommand(aDragEvent
) )
2595 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2598 void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2600 SCCOL nCol
= pViewData
->GetCurX();
2601 SCROW nRow
= pViewData
->GetCurY();
2602 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, TRUE
);
2603 aEditArea
.Right() = aEditArea
.Left();
2604 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2605 pWin
->SetCursorRect( &aEditArea
);
2608 void __EXPORT
ScGridWindow::Command( const CommandEvent
& rCEvt
)
2610 // The command event is send to the window after a possible context
2611 // menu from an inplace client is closed. Now we have the chance to
2612 // deactivate the inplace client without any problem regarding parent
2613 // windows and code on the stack.
2614 // For more information, see #126086# and #128122#
2615 USHORT nCmd
= rCEvt
.GetCommand();
2616 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2617 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2619 pClient
->IsObjectInPlaceActive() &&
2620 nCmd
== COMMAND_CONTEXTMENU
)
2622 pTabViewSh
->DeactivateOle();
2626 ScModule
* pScMod
= SC_MOD();
2627 DBG_ASSERT( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2629 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2630 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2631 nCmd
== COMMAND_EXTTEXTINPUT
||
2632 nCmd
== COMMAND_CURSORPOS
)
2634 BOOL bEditView
= pViewData
->HasEditView( eWhich
);
2637 // only if no cell editview is active, look at drawview
2638 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2641 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2642 if ( pOlView
&& pOlView
->GetWindow() == this )
2644 pOlView
->Command( rCEvt
);
2650 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2652 // #88458# CURSORPOS may be called without following text input,
2653 // to set the input method window position
2654 // -> input mode must not be started,
2655 // manually calculate text insert position if not in input mode
2657 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2661 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2664 pHdl
->InputCommand( rCEvt
, TRUE
);
2668 Window::Command( rCEvt
);
2672 if ( nCmd
== COMMAND_VOICE
)
2674 // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
2675 // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
2677 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2678 if ( pHdl
&& pViewData
->HasEditView( eWhich
) )
2680 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2681 pHdl
->DataChanging();
2682 pEditView
->Command( rCEvt
);
2683 pHdl
->DataChanged();
2686 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2689 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2690 if ( pOlView
&& pOlView
->GetWindow() == this )
2692 pOlView
->Command( rCEvt
);
2696 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
2700 if ( nCmd
== COMMAND_PASTESELECTION
)
2704 // EditEngine handles selection in MouseButtonUp - no action
2705 // needed in command handler
2709 PasteSelection( rCEvt
.GetMousePosPixel() );
2714 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2716 // #i55929# Font and font size state depends on input language if nothing is selected,
2717 // so the slots have to be invalidated when the input language is changed.
2719 SfxBindings
& rBindings
= pViewData
->GetBindings();
2720 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2721 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2725 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2727 BOOL bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2729 Window::Command(rCEvt
);
2732 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2733 BOOL bDisable
= pScMod
->IsFormulaMode() ||
2734 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2738 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2740 if (pViewData
->IsAnyFillMode())
2742 pViewData
->GetView()->StopRefMode();
2743 pViewData
->ResetFillMode();
2748 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2749 Point aMenuPos
= aPosPixel
;
2750 BOOL bMouse
= rCEvt
.IsMouseEvent();
2754 // #i18735# First select the item under the mouse pointer.
2755 // This can change the selection, and the view state (edit mode, etc).
2756 SelectForContextMenu( aPosPixel
);
2760 BOOL bEdit
= pViewData
->HasEditView(eWhich
);
2763 // Edit-Zelle mit Spelling-Errors ?
2764 if ( bMouse
&& GetEditUrlOrError( TRUE
, aPosPixel
) )
2766 // GetEditUrlOrError hat den Cursor schon bewegt
2768 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2769 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
2771 DBG_ASSERT( bEdit
, "kann nicht in Edit-Modus schalten" );
2776 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2780 Cursor
* pCur
= pEditView
->GetCursor();
2783 Point aLogicPos
= pCur
->GetPos();
2784 // use the position right of the cursor (spell popup is opened if
2785 // the cursor is before the word, but not if behind it)
2786 aLogicPos
.X() += pCur
->GetWidth();
2787 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
2788 aMenuPos
= LogicToPixel( aLogicPos
);
2792 // if edit mode was just started above, online spelling may be incomplete
2793 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
2795 // IsCursorAtWrongSpelledWord could be used for !bMouse
2796 // if there was a corresponding ExecuteSpellPopup call
2798 if( pEditView
->IsWrongSpelledWordAtPos( aMenuPos
) )
2800 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2801 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2803 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2805 pHdl
->SetModified();
2807 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
2808 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
2815 // non-edit menu by keyboard -> use lower right of cell cursor position
2817 SCCOL nCurX
= pViewData
->GetCurX();
2818 SCROW nCurY
= pViewData
->GetCurY();
2819 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, TRUE
);
2822 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
2823 aMenuPos
.X() += nSizeXPix
;
2824 aMenuPos
.Y() += nSizeYPix
;
2828 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
2831 // Is a draw object selected?
2833 SdrView
* pDrawView
= pViewSh
->GetSdrView();
2834 if (pDrawView
&& pDrawView
->AreObjectsMarked())
2836 // #100442#; the conext menu should open in the middle of the selected objects
2837 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
2838 aMenuPos
= aSelectRect
.Center();
2846 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
2851 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
)
2853 // #i18735# if the click was outside of the current selection,
2854 // the cursor is moved or an object at the click position selected.
2855 // (see SwEditWin::SelectMenuPosition in Writer)
2859 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2860 ScTabView
* pView
= pViewData
->GetView();
2861 ScDrawView
* pDrawView
= pView
->GetScDrawView();
2863 // check cell edit mode
2865 if ( pViewData
->HasEditView(eWhich
) )
2867 ScModule
* pScMod
= SC_MOD();
2868 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
2869 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
2870 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
2871 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
2873 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
2874 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
2876 // handle selection within the EditView
2878 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
2879 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
2880 Rectangle aOutputArea
= pEditView
->GetOutputArea();
2881 Rectangle aVisArea
= pEditView
->GetVisArea();
2883 Point aTextPos
= PixelToLogic( rPosPixel
);
2884 if ( pEditEngine
->IsVertical() ) // have to manually transform position
2886 aTextPos
-= aOutputArea
.TopRight();
2887 long nTemp
= -aTextPos
.X();
2888 aTextPos
.X() = aTextPos
.Y();
2889 aTextPos
.Y() = nTemp
;
2892 aTextPos
-= aOutputArea
.TopLeft();
2893 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2895 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
2896 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2897 ESelection aSelection
= pEditView
->GetSelection();
2898 aSelection
.Adjust(); // needed for IsLess/IsGreater
2899 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2901 // clicked outside the selected text - deselect and move text cursor
2902 MouseEvent
aEvent( rPosPixel
);
2903 pEditView
->MouseButtonDown( aEvent
);
2904 pEditView
->MouseButtonUp( aEvent
);
2905 pScMod
->InputSelection( pEditView
);
2908 return; // clicked within the edit view - keep edit mode
2912 // outside of the edit view - end edit mode, regardless of cell selection, then continue
2913 pScMod
->InputEnterHandler();
2917 // check draw text edit mode
2919 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
2920 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
2922 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
2923 Rectangle aOutputArea
= pOlView
->GetOutputArea();
2924 if ( aOutputArea
.IsInside( aLogicPos
) )
2926 // handle selection within the OutlinerView
2928 Outliner
* pOutliner
= pOlView
->GetOutliner();
2929 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
2930 Rectangle aVisArea
= pOlView
->GetVisArea();
2932 Point aTextPos
= aLogicPos
;
2933 if ( pOutliner
->IsVertical() ) // have to manually transform position
2935 aTextPos
-= aOutputArea
.TopRight();
2936 long nTemp
= -aTextPos
.X();
2937 aTextPos
.X() = aTextPos
.Y();
2938 aTextPos
.Y() = nTemp
;
2941 aTextPos
-= aOutputArea
.TopLeft();
2942 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2944 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
2945 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2946 ESelection aSelection
= pOlView
->GetSelection();
2947 aSelection
.Adjust(); // needed for IsLess/IsGreater
2948 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2950 // clicked outside the selected text - deselect and move text cursor
2951 // use DrawView to allow extra handling there (none currently)
2952 MouseEvent
aEvent( rPosPixel
);
2953 pDrawView
->MouseButtonDown( aEvent
, this );
2954 pDrawView
->MouseButtonUp( aEvent
, this );
2957 return; // clicked within the edit area - keep edit mode
2961 // Outside of the edit area - end text edit mode, then continue.
2962 // DrawDeselectAll also ends text edit mode and updates the shells.
2963 // If the click was on the edited object, it will be selected again below.
2964 pView
->DrawDeselectAll();
2968 // look for existing selection
2970 BOOL bHitSelected
= FALSE
;
2971 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
2973 // clicked on selected object -> don't change anything
2974 bHitSelected
= TRUE
;
2976 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
2978 // clicked on selected cell -> don't change anything
2979 bHitSelected
= TRUE
;
2982 // select drawing object or move cell cursor
2984 if ( !bHitSelected
)
2986 BOOL bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
2987 BOOL bHitDraw
= FALSE
;
2990 pDrawView
->UnmarkAllObj();
2991 // Unlock the Internal Layer in order to activate the context menu.
2992 // re-lock in ScDrawView::MarkListHasChanged()
2993 lcl_UnLockComment( pDrawView
, pDrawView
->GetSdrPageView(), pDrawView
->GetModel(), aLogicPos
,pViewData
);
2994 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
2995 // draw shell is activated in MarkListHasChanged
3000 pView
->SetCursor(nCellX
, nCellY
);
3002 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // switch shells
3007 static void ClearSingleSelection( ScViewData
* pViewData
)
3011 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard(
3012 pViewData
->GetActiveWin() );
3016 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
3017 pClipDoc
->GetClipArea( nX
, nY
, TRUE
);
3018 if (nX
== 0 && nY
== 0)
3020 ScTabView
* pView
= pViewData
->GetView();
3025 void __EXPORT
ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3027 // #96965# Cursor control for ref input dialog
3028 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3029 if( SC_MOD()->IsRefDialogOpen() )
3031 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3033 SC_MOD()->EndReference();
3036 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3039 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3040 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3041 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3045 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3047 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3049 ScCellShell::PasteFromClipboard( pViewData
, pTabViewShell
, FALSE
);
3050 ClearSingleSelection( pViewData
);
3052 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3053 TransferableHelper::GetSystemClipboard();
3054 if (xSystemClipboard
.is())
3056 xSystemClipboard
->setContents(
3057 uno::Reference
<datatransfer::XTransferable
>(),
3058 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3061 // hide the border around the copy source
3062 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3063 UpdateCursorOverlay();
3066 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3067 else if( !pViewData
->IsAnyFillMode() )
3069 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3071 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3072 UpdateCursorOverlay();
3074 // query for existing note marker before calling ViewShell's keyboard handling
3075 // which may remove the marker
3076 BOOL bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3077 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3079 if (pViewData
->GetDocShell()->GetProgress())
3082 if (DrawKeyInput(rKEvt
))
3085 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3086 { //! DrawShell abfragen !!!
3087 if (pViewSh
->TabKeyInput(rKEvt
))
3091 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3094 KeyCode aCode
= rKEvt
.GetKeyCode();
3095 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3097 if ( bHadKeyMarker
)
3103 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3105 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3106 // (hard-coded because F1 can't be configured)
3108 if ( bHadKeyMarker
)
3109 HideNoteMarker(); // hide when previously visible
3111 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), TRUE
);
3114 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3116 pViewSh
->DetectiveMarkPred();
3119 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3121 pViewSh
->DetectiveMarkSucc();
3127 Window::KeyInput(rKEvt
);
3130 void ScGridWindow::StopMarking()
3132 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3136 pViewData
->GetMarkData().SetMarking(FALSE
);
3137 nMouseStatus
= SC_GM_IGNORE
;
3141 void ScGridWindow::UpdateInputContext()
3143 BOOL bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3144 ULONG nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3146 // when font from InputContext is used,
3147 // it must be taken from the cursor position's cell attributes
3149 InputContext aContext
;
3150 aContext
.SetOptions( nOptions
);
3151 SetInputContext( aContext
);
3154 //--------------------------------------------------------
3156 // sensitiver Bereich (Pixel)
3157 #define SCROLL_SENSITIVE 20
3159 BOOL
ScGridWindow::DropScroll( const Point
& rMousePos
)
3161 /* doch auch auf nicht aktiven Views...
3162 if ( !pViewData->IsActive() )
3167 Size aSize
= GetOutputSizePixel();
3169 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3171 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3173 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3174 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3177 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3179 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3181 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3182 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3186 if ( nDx
!= 0 || nDy
!= 0 )
3189 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3192 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3194 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3197 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3203 BOOL
lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3205 // Testet, ob bei eingeschalteten RedLining,
3206 // bei einem Drop ein Scenario betroffen ist.
3208 BOOL bReturn
= FALSE
;
3209 SCTAB nTab
= aDragRange
.aStart
.Tab();
3210 SCTAB nTabCount
= pDoc
->GetTableCount();
3212 if(pDoc
->GetChangeTrack()!=NULL
)
3214 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3220 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3222 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3233 ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3235 SCCOL nCol1
= nPosX
;
3236 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3237 if ( nCol2
> MAXCOL
)
3239 nCol1
-= nCol2
- MAXCOL
;
3242 SCROW nRow1
= nPosY
;
3243 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3244 if ( nRow2
> MAXROW
)
3246 nRow1
-= nRow2
- MAXROW
;
3250 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3253 //--------------------------------------------------------
3255 extern BOOL bPasteIsDrop
; // viewfun4 -> move to header
3256 extern BOOL bPasteIsMove
; // viewfun7 -> move to header
3258 //--------------------------------------------------------
3260 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3262 if ( rEvt
.mbLeaving
)
3265 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3267 UpdateDragRectOverlay();
3268 return rEvt
.mnAction
;
3271 const ScDragData
& rData
= SC_MOD()->GetDragData();
3272 if ( rData
.pCellTransfer
)
3274 // Don't move source that would include filtered rows.
3275 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3280 UpdateDragRectOverlay();
3282 return DND_ACTION_NONE
;
3285 Point aPos
= rEvt
.maPosPixel
;
3287 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3288 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3289 if (pSourceDoc
== pThisDoc
)
3291 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
)) )
3293 if (bDragRect
) // Rechteck loeschen
3295 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3297 UpdateDragRectOverlay();
3300 //! highlight chart? (selection border?)
3302 sal_Int8 nRet
= rEvt
.mnAction
;
3303 //! if ( rEvt.GetAction() == DROP_LINK )
3304 //! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart
3309 //! if ( rEvt.GetAction() == DROP_MOVE )
3310 //! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY
3313 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3315 BOOL bOk
= pThisDoc
->IsDocEditable();
3316 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3321 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3323 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3324 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3325 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3326 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3327 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3328 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3329 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3331 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3332 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3334 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3335 if (nNewDragX
<0) nNewDragX
=0;
3336 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3337 nNewDragX
= MAXCOL
-(nSizeX
-1);
3338 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3339 if (nNewDragY
<0) nNewDragY
=0;
3340 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3341 nNewDragY
= MAXROW
-(nSizeY
-1);
3343 // don't break scenario ranges, don't drop on filtered
3344 SCTAB nTab
= pViewData
->GetTabNo();
3345 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3346 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3347 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3348 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3352 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3354 UpdateDragRectOverlay();
3356 return DND_ACTION_NONE
;
3359 InsCellCmd eDragInsertMode
= INS_NONE
;
3360 Window::PointerState aState
= GetPointerState();
3362 // check for datapilot item sorting
3363 ScDPObject
* pDPObj
= NULL
;
3364 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3366 // drop on DataPilot table: sort or nothing
3368 bool bDPSort
= false;
3369 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3371 sheet::DataPilotTableHeaderData aDestData
;
3372 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3373 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3375 // look through the source range
3376 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3377 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3379 sheet::DataPilotTableHeaderData aSourceData
;
3380 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3381 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| !aSourceData
.MemberName
.getLength() )
3382 bValid
= false; // empty (subtotal) or different field
3388 String aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3389 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3392 ScRange aOutRange
= pDPObj
->GetOutRange();
3394 USHORT nOrient
= pDim
->GetOrientation();
3395 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3397 eDragInsertMode
= INS_CELLSRIGHT
;
3398 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3401 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3403 eDragInsertMode
= INS_CELLSDOWN
;
3404 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3413 // no valid sorting in a DataPilot table -> disallow
3417 UpdateDragRectOverlay();
3419 return DND_ACTION_NONE
;
3422 else if ( aState
.mnState
& KEY_MOD2
)
3424 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3426 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3427 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3428 if ( nDeltaX
<= nDeltaY
)
3430 eDragInsertMode
= INS_CELLSDOWN
;
3434 eDragInsertMode
= INS_CELLSRIGHT
;
3437 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3438 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3439 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3440 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3441 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3442 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3447 UpdateDragRectOverlay();
3449 return DND_ACTION_NONE
;
3454 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3456 eDragInsertMode
= INS_CELLSDOWN
;
3461 eDragInsertMode
= INS_CELLSRIGHT
;
3466 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3467 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3468 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3471 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3473 nDragStartX
= nNewDragX
;
3474 nDragStartY
= nNewDragY
;
3475 nDragEndX
= nDragStartX
+nSizeX
-1;
3476 nDragEndY
= nDragStartY
+nSizeY
-1;
3478 meDragInsertMode
= eDragInsertMode
;
3480 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3482 UpdateDragRectOverlay();
3484 // show target position as tip help
3486 if (Help::IsQuickHelpEnabled())
3488 ScRange
aRange( nDragStartX
, nDragStartY
, nTab
, nDragEndX
, nDragEndY
, nTab
);
3490 aRange
.Format( aHelpStr
, SCA_VALID
); // non-3D
3492 Point aPos
= Pointer::GetPosPixel();
3493 USHORT nAlign
= QUICKHELP_BOTTOM
|QUICKHELP_RIGHT
;
3494 Rectangle
aRect( aPos
, aPos
);
3495 Help::ShowQuickHelp(aRect
, aHelpStr
, nAlign
);
3501 return rEvt
.mnAction
;
3504 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3506 const ScDragData
& rData
= SC_MOD()->GetDragData();
3507 if ( rEvt
.mbLeaving
)
3509 DrawMarkDropObj( NULL
);
3510 if ( rData
.pCellTransfer
)
3511 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3513 return rEvt
.mnAction
;
3516 if ( pViewData
->GetDocShell()->IsReadOnly() )
3517 return DND_ACTION_NONE
;
3520 sal_Int8 nRet
= DND_ACTION_NONE
;
3522 if (rData
.pCellTransfer
)
3524 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3525 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3526 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3527 DropScroll( rEvt
.maPosPixel
);
3529 nRet
= AcceptPrivateDrop( rEvt
);
3533 if ( rData
.aLinkDoc
.Len() )
3536 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3537 if (pDocSh
&& pDocSh
->HasName())
3538 aThisName
= pDocSh
->GetMedium()->GetName();
3540 if ( rData
.aLinkDoc
!= aThisName
)
3541 nRet
= rEvt
.mnAction
;
3543 else if (rData
.aJumpTarget
.Len())
3545 // internal bookmarks (from Navigator)
3546 // local jumps from an unnamed document are possible only within a document
3548 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3549 nRet
= rEvt
.mnAction
;
3553 sal_Int8 nMyAction
= rEvt
.mnAction
;
3555 if ( !rData
.pDrawTransfer
||
3556 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3557 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3558 nMyAction
= DND_ACTION_COPY
;
3560 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3561 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3562 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3563 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
&& !rData
.pDrawTransfer
)
3565 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3566 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3567 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3569 // graphic dragged onto drawing object
3570 DrawMarkDropObj( pHitObj
);
3575 DrawMarkDropObj( NULL
);
3579 switch ( nMyAction
)
3581 case DND_ACTION_COPY
:
3582 case DND_ACTION_MOVE
:
3583 case DND_ACTION_COPYMOVE
:
3585 BOOL bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3586 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3587 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3588 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3589 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3590 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3591 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3592 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3593 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3594 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3595 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3596 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3597 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3598 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3599 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3600 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3601 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3602 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3603 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3605 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3606 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3607 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3608 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3609 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3610 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3616 case DND_ACTION_LINK
:
3617 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3618 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3619 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3620 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3621 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3622 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3623 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3624 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3625 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3634 // Simple check for protection: It's not known here if the drop will result
3635 // in cells or drawing objects (some formats can be both) and how many cells
3636 // the result will be. But if IsFormatEditable for the drop cell position
3637 // is FALSE (ignores matrix formulas), nothing can be pasted, so the drop
3638 // can already be rejected here.
3640 Point aPos
= rEvt
.maPosPixel
;
3643 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3644 SCTAB nTab
= pViewData
->GetTabNo();
3645 ScDocument
* pDoc
= pViewData
->GetDocument();
3647 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3648 if ( !aTester
.IsFormatEditable() )
3649 nRet
= DND_ACTION_NONE
; // forbidden
3654 // scroll only for accepted formats
3656 DropScroll( rEvt
.maPosPixel
);
3662 ULONG
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3664 TransferableDataHelper
aDataHelper( xTransfer
);
3666 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3668 // use bookmark formats if no sba is present
3670 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3671 return SOT_FORMATSTR_ID_SOLK
;
3672 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3673 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3674 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3675 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3676 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3677 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3680 ULONG nFormatId
= 0;
3681 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3682 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3683 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3684 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3685 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3687 // If it's a Writer object, insert RTF instead of OLE
3689 BOOL bDoRtf
= FALSE
;
3690 SotStorageStreamRef xStm
;
3691 TransferableObjectDescriptor aObjDesc
;
3692 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3693 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3695 SotStorageRef
xStore( new SotStorage( *xStm
) );
3696 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3697 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3698 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3701 nFormatId
= FORMAT_RTF
;
3703 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3705 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3706 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3707 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3708 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3709 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3710 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3711 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3712 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3713 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3714 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3715 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3716 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3717 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3718 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3719 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3720 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3721 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3722 nFormatId
= SOT_FORMAT_RTF
;
3723 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3724 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3725 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3726 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3727 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3728 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3729 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3730 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3731 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3732 nFormatId
= SOT_FORMAT_STRING
;
3733 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3734 nFormatId
= SOT_FORMAT_FILE_LIST
;
3735 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3736 nFormatId
= SOT_FORMAT_FILE
;
3737 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3738 nFormatId
= SOT_FORMAT_STRING
;
3739 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3740 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3741 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3742 nFormatId
= SOT_FORMAT_BITMAP
;
3747 ULONG
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3749 TransferableDataHelper
aDataHelper( xTransfer
);
3751 ULONG nFormatId
= 0;
3752 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3753 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3754 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3755 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3756 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3757 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3758 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3759 nFormatId
= SOT_FORMAT_FILE_LIST
;
3760 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
3761 nFormatId
= SOT_FORMAT_FILE
;
3762 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3763 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
3764 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3765 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3766 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3767 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3768 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3769 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3775 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
3779 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3781 UpdateDragRectOverlay();
3783 ScModule
* pScMod
= SC_MOD();
3784 const ScDragData
& rData
= pScMod
->GetDragData();
3786 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
3787 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
3790 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
3791 const Point
& rLogicPos
, sal_Int8 nDndAction
)
3796 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
3797 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3798 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3799 ScViewFunc
* pView
= pViewData
->GetView();
3800 SCTAB nThisTab
= pViewData
->GetTabNo();
3801 USHORT nFlags
= pTransObj
->GetDragSourceFlags();
3803 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
3804 BOOL bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
3806 // workaround for wrong nDndAction on Windows when pressing solely
3807 // the Alt key during drag and drop;
3808 // can be removed after #i79215# has been fixed
3809 if ( meDragInsertMode
!= INS_NONE
)
3811 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
3814 BOOL bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
3816 ScRange aSource
= pTransObj
->GetRange();
3818 // only use visible tab from source range - when dragging within one table,
3819 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3820 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
3821 aSource
.aStart
.SetTab( nSourceTab
);
3822 aSource
.aEnd
.SetTab( nSourceTab
);
3824 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
3825 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
3826 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
3827 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
3828 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
3831 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3832 * dragging and adapted drawing of the selection frame. We check here
3833 * (again) because this may actually also be called from PasteSelection(),
3834 * we would have to duplicate determination of flags and destination range
3835 * and would lose the context of the "filtered destination is OK" cases
3836 * below, which is already awkward enough as is. */
3838 // Don't move filtered source.
3839 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
3842 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
3843 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
3845 // Nothing. Either entire sheet to be dropped, or the one case
3846 // where PasteFromClip() is to be called that handles a filtered
3847 // destination itself. Drag-copy from another document without
3851 // Don't copy or move to filtered destination.
3852 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
3857 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
3859 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
3861 if ( pThisDoc
->IsDocEditable() )
3863 SCTAB nSrcTab
= aSource
.aStart
.Tab();
3864 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, TRUE
); // with Undo
3865 pView
->SetTabNo( nThisTab
, TRUE
);
3869 else // move/copy block
3872 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, &aChartName
))
3875 aSource
.Format( aRangeName
, SCR_ABS_3D
, pThisDoc
);
3876 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
3877 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
3878 USHORT nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
3879 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
3880 &aRangeItem
, &aNameItem
, (void*) NULL
);
3883 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
3885 // drop on DataPilot table: try to sort, fail if that isn't possible
3887 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
3888 if ( aDestPos
!= aSource
.aStart
)
3889 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
3891 bDone
= TRUE
; // same position: nothing
3893 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
3894 nSourceTab
!= nThisTab
)
3896 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
3897 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
3900 if ( meDragInsertMode
!= INS_NONE
)
3902 // call with bApi = TRUE to avoid error messages in drop handler
3903 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
3906 if ( nThisTab
== nSourceTab
)
3908 if ( meDragInsertMode
== INS_CELLSDOWN
&&
3909 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
3911 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
3913 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
3914 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
3916 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
3919 pDocSh
->UpdateOle( pViewData
);
3920 pView
->CellContentChanged();
3928 // call with bApi = TRUE to avoid error messages in drop handler
3929 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, TRUE
/*bApi*/ );
3933 // call with bApi = TRUE to avoid error messages in drop handler
3934 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, TRUE
/*bRecord*/, TRUE
/*bPaint*/, TRUE
/*bApi*/ );
3938 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
3940 DelCellCmd eCmd
= DEL_NONE
;
3941 if ( meDragInsertMode
== INS_CELLSDOWN
)
3945 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
3947 eCmd
= DEL_CELLSLEFT
;
3950 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
3951 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
3953 // call with bApi = TRUE to avoid error messages in drop handler
3954 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, TRUE
/*bRecord*/, TRUE
/*bApi*/ );
3957 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
3959 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
3961 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
3963 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
3965 pDocSh
->UpdateOle( pViewData
);
3966 pView
->CellContentChanged();
3973 pView
->MarkRange( aDest
, FALSE
, FALSE
);
3975 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col();
3976 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row();
3977 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
3980 pDocSh
->GetUndoManager()->LeaveListAction();
3983 Sound::Beep(); // instead of error message in drop handler
3986 bDone
= TRUE
; // nothing to do
3990 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
3992 else if ( !bFiltered
&& pSourceDoc
) // between documents
3994 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
3996 if ( pThisDoc
->IsDocEditable() )
3998 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4000 SCTAB nTabs
[MAXTABCOUNT
];
4002 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4003 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4004 SCTAB nTabSelCount
= 0;
4006 for(SCTAB i
=0; i
<nTabCount
; i
++)
4008 if(aMark
.GetTableSelect(i
))
4010 nTabs
[nTabSelCount
++]=i
;
4011 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4013 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4015 nTabs
[nTabSelCount
++]=j
;
4023 pView
->ImportTables( pSrcShell
,nTabSelCount
, nTabs
, bIsLink
, nThisTab
);
4030 // (external references might be used instead?)
4032 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4033 DBG_ASSERT(pSourceSh
, "drag document has no shell");
4036 String aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4037 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4040 if ( meDragInsertMode
!= INS_NONE
)
4042 // call with bApi = TRUE to avoid error messages in drop handler
4043 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4046 pDocSh
->UpdateOle( pViewData
);
4047 pView
->CellContentChanged();
4053 String aApp
= Application::GetAppName();
4054 String aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4056 aSource
.Format( aItem
, SCA_VALID
| SCA_TAB_3D
, pSourceDoc
);
4058 // TODO: we could define ocQuote for "
4059 const String
aQuote( '"' );
4060 const String
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4061 String
aFormula( '=' );
4062 aFormula
+= ScCompiler::GetNativeSymbol( ocDde
);
4063 aFormula
+= ScCompiler::GetNativeSymbol( ocOpen
);
4075 aFormula
+= ScCompiler::GetNativeSymbol( ocClose
);
4077 pView
->DoneBlockMode();
4078 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4079 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4080 nDestPosY
+ nSizeY
- 1, nThisTab
);
4082 pView
->EnterMatrix( aFormula
);
4084 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4085 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4088 pDocSh
->GetUndoManager()->LeaveListAction();
4093 //! HasSelectedBlockMatrixFragment without selected sheet?
4094 //! or don't start dragging on a part of a matrix
4096 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4097 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4100 if ( meDragInsertMode
!= INS_NONE
)
4102 // call with bApi = TRUE to avoid error messages in drop handler
4103 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4106 pDocSh
->UpdateOle( pViewData
);
4107 pView
->CellContentChanged();
4113 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4114 pView
->SetCursor( nDestPosX
, nDestPosY
);
4115 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4118 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4119 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4123 pDocSh
->GetUndoManager()->LeaveListAction();
4125 // no longer call ResetMark here - the inserted block has been selected
4126 // and may have been copied to primary selection
4130 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4134 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4136 DrawMarkDropObj( NULL
); // drawing layer
4138 ScModule
* pScMod
= SC_MOD();
4139 const ScDragData
& rData
= pScMod
->GetDragData();
4140 if (rData
.pCellTransfer
)
4141 return ExecutePrivateDrop( rEvt
);
4143 Point aPos
= rEvt
.maPosPixel
;
4145 if ( rData
.aLinkDoc
.Len() )
4147 // try to insert a link
4151 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4152 if (pDocSh
&& pDocSh
->HasName())
4153 aThisName
= pDocSh
->GetMedium()->GetName();
4155 if ( rData
.aLinkDoc
== aThisName
) // error - no link within a document
4159 ScViewFunc
* pView
= pViewData
->GetView();
4160 if ( rData
.aLinkTable
.Len() )
4161 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4163 else if ( rData
.aLinkArea
.Len() )
4167 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4168 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, FALSE
, FALSE
);
4170 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4171 rData
.aLinkArea
, 0 );
4175 DBG_ERROR("drop with link: no sheet nor area");
4180 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4183 Point aLogicPos
= PixelToLogic(aPos
);
4185 if (rData
.pDrawTransfer
)
4187 USHORT nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4189 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4190 BOOL bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4192 bPasteIsMove
= bIsMove
;
4194 pViewData
->GetView()->PasteDraw( aLogicPos
, rData
.pDrawTransfer
->GetModel() );
4197 rData
.pDrawTransfer
->SetDragWasInternal();
4198 bPasteIsMove
= FALSE
;
4200 return rEvt
.mnAction
;
4206 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4208 if (rData
.aJumpTarget
.Len())
4210 // internal bookmark (from Navigator)
4211 // bookmark clipboard formats are in PasteScDataObject
4213 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4215 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4217 return rEvt
.mnAction
;
4221 BOOL bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4223 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4224 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4225 if ( pHitObj
&& bIsLink
)
4227 // dropped on drawing object
4228 // PasteOnDrawObject checks for valid formats
4229 if ( pViewData
->GetView()->PasteOnDrawObject( rEvt
.maDropEvent
.Transferable
, pHitObj
, TRUE
) )
4230 return rEvt
.mnAction
;
4235 ULONG nFormatId
= bIsLink
?
4236 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4237 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4240 pScMod
->SetInExecuteDrop( TRUE
); // #i28468# prevent error messages from PasteDataFormat
4241 bPasteIsDrop
= TRUE
;
4242 bDone
= pViewData
->GetView()->PasteDataFormat(
4243 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4244 bPasteIsDrop
= FALSE
;
4245 pScMod
->SetInExecuteDrop( FALSE
);
4248 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4252 //--------------------------------------------------------
4254 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4256 Point aLogicPos
= PixelToLogic( rPosPixel
);
4260 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4262 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4263 if ( pOwnSelection
)
4267 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4268 if ( pCellTransfer
)
4270 // keep a reference to the data in case the selection is changed during paste
4271 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4272 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4276 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4277 if ( pDrawTransfer
)
4279 // keep a reference to the data in case the selection is changed during paste
4280 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4282 // #96821# bSameDocClipboard argument for PasteDraw is needed
4283 // because only DragData is checked directly inside PasteDraw
4284 pViewData
->GetView()->PasteDraw( aLogicPos
, pDrawTransfer
->GetModel(), FALSE
,
4285 pDrawTransfer
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
4291 // get selection from system
4293 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4294 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4295 if ( xTransferable
.is() )
4297 ULONG nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4300 bPasteIsDrop
= TRUE
;
4301 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4302 bPasteIsDrop
= FALSE
;
4308 //--------------------------------------------------------
4310 void ScGridWindow::UpdateEditViewPos()
4312 if (pViewData
->HasEditView(eWhich
))
4317 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4318 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4319 SCROW nEndRow
= pViewData
->GetEditEndRow();
4323 BOOL bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4324 if ( SC_MOD()->IsFormulaMode() )
4325 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4330 Rectangle aRect
= pView
->GetOutputArea();
4331 long nHeight
= aRect
.Bottom() - aRect
.Top();
4332 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4334 aRect
.Bottom() = aRect
.Top() + nHeight
;
4335 pView
->SetOutputArea( aRect
);
4336 pView
->HideCursor();
4340 // bForceToTop = TRUE for editing
4341 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, TRUE
);
4342 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4344 Rectangle aRect
= pView
->GetOutputArea();
4345 aRect
.SetPos( aScrPos
);
4346 pView
->SetOutputArea( aRect
);
4347 pView
->ShowCursor();
4352 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4358 //BOOL bXor=DrawBeforeScroll();
4360 SetMapMode(MAP_PIXEL
);
4361 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4362 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4364 UpdateEditViewPos();
4366 DrawAfterScroll(); //bXor);
4367 bIsInScroll
= FALSE
;
4370 // Formeln neu zeichnen -------------------------------------------------
4372 void ScGridWindow::UpdateFormulas()
4374 if (pViewData
->GetView()->IsMinimized())
4379 // nicht anfangen, verschachtelt zu painten
4380 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4382 bNeedsRepaint
= TRUE
; // -> am Ende vom Paint nochmal Invalidate auf alles
4383 aRepaintPixel
= Rectangle(); // alles
4387 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4388 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4389 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4390 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4392 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4393 if (nY2
> MAXROW
) nY2
= MAXROW
;
4395 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4397 // don't draw directly - instead use OutputData to find changed area and invalidate
4401 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4402 ScDocument
* pDoc
= pDocSh
->GetDocument();
4403 SCTAB nTab
= pViewData
->GetTabNo();
4405 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4407 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4408 long nMirrorWidth
= GetSizePixel().Width();
4409 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4410 // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
4413 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4414 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4415 aScrPos
.X() = nEndPixel
+ 1;
4418 long nScrX
= aScrPos
.X();
4419 long nScrY
= aScrPos
.Y();
4421 double nPPTX
= pViewData
->GetPPTX();
4422 double nPPTY
= pViewData
->GetPPTY();
4424 ScTableInfo aTabInfo
;
4425 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, FALSE
, FALSE
);
4427 Fraction aZoomX
= pViewData
->GetZoomX();
4428 Fraction aZoomY
= pViewData
->GetZoomY();
4429 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4430 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4432 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4434 aOutputData
.FindChanged();
4436 PolyPolygon
aChangedPoly( aOutputData
.GetChangedArea() ); // logic (PixelToLogic)
4437 if ( aChangedPoly
.Count() )
4439 Invalidate( aChangedPoly
);
4442 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4445 void ScGridWindow::UpdateAutoFillMark(BOOL bMarked
, const ScRange
& rMarkRange
)
4447 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4450 bAutoMarkVisible
= bMarked
;
4452 aAutoMarkPos
= rMarkRange
.aEnd
;
4455 UpdateAutoFillOverlay();
4459 void ScGridWindow::UpdateListValPos( BOOL bVisible
, const ScAddress
& rPos
)
4461 BOOL bOldButton
= bListValButton
;
4462 ScAddress aOldPos
= aListValPos
;
4464 bListValButton
= bVisible
;
4467 if ( bListValButton
)
4469 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4471 // paint area of new button
4472 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4477 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4479 // paint area of old button
4480 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4485 void ScGridWindow::HideCursor()
4488 if (nCursorHideCount
==1)
4495 void ScGridWindow::ShowCursor()
4497 if (nCursorHideCount
==0)
4499 DBG_ERROR("zuviel ShowCursor");
4503 if (nCursorHideCount
==1)
4505 // #i57745# Draw the cursor before setting the variable, in case the
4506 // GetSizePixel call from drawing causes a repaint (resize handler is called)
4514 void __EXPORT
ScGridWindow::GetFocus()
4516 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4517 pViewShell
->GotFocus();
4518 pViewShell
->SetFormShellAtTop( FALSE
); // focus in GridWindow -> FormShell no longer on top
4520 if (pViewShell
->HasAccessibilityObjects())
4521 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4524 if ( !SC_MOD()->IsFormulaMode() )
4526 pViewShell
->UpdateInputHandler();
4527 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4528 // MO: nur wenn nicht im RefInput-Modus
4529 // -> GetFocus/MouseButtonDown-Reihenfolge
4536 void __EXPORT
ScGridWindow::LoseFocus()
4538 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4539 pViewShell
->LostFocus();
4541 if (pViewShell
->HasAccessibilityObjects())
4542 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4544 Window::LoseFocus();
4547 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4549 //------------------------------------------------------------------------
4551 BOOL
ScGridWindow::HitRangeFinder( const Point
& rMouse
, BOOL
& rCorner
,
4552 USHORT
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4554 BOOL bFound
= FALSE
;
4555 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4558 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4559 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4560 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4562 ScDocument
* pDoc
= pViewData
->GetDocument();
4563 SCTAB nTab
= pViewData
->GetTabNo();
4564 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4565 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4569 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4570 // zusammengefasste (einzeln/Bereich) ???
4571 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4573 // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
4575 Point aNext
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, TRUE
);
4578 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4579 aNext
.X() += nSizeXPix
* nLayoutSign
;
4580 aNext
.Y() += nSizeYPix
;
4584 bCornerHor
= ( rMouse
.X() >= aNext
.X() && rMouse
.X() <= aNext
.X() + 8 );
4586 bCornerHor
= ( rMouse
.X() >= aNext
.X() - 8 && rMouse
.X() <= aNext
.X() );
4588 BOOL bCellCorner
= ( bCornerHor
&&
4589 rMouse
.Y() >= aNext
.Y() - 8 && rMouse
.Y() <= aNext
.Y() );
4590 // corner is hit only if the mouse is within the cell
4592 USHORT nCount
= (USHORT
)pRangeFinder
->Count();
4593 for (USHORT i
=nCount
; i
;)
4595 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4597 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4598 if ( pData
&& pData
->aRef
.In(aAddr
) )
4600 if (pIndex
) *pIndex
= i
;
4601 if (pAddX
) *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4602 if (pAddY
) *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4604 rCorner
= ( bCellCorner
&& aAddr
== pData
->aRef
.aEnd
);
4614 #define SCE_BOTTOM 2
4619 void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, USHORT nEdges
)
4621 // der Range ist immer richtigherum
4623 SCCOL nCol1
= rRange
.aStart
.Col();
4624 SCROW nRow1
= rRange
.aStart
.Row();
4625 SCTAB nTab1
= rRange
.aStart
.Tab();
4626 SCCOL nCol2
= rRange
.aEnd
.Col();
4627 SCROW nRow2
= rRange
.aEnd
.Row();
4628 SCTAB nTab2
= rRange
.aEnd
.Tab();
4629 BOOL bHiddenEdge
= FALSE
;
4632 ScDocument
* pDoc
= pDocSh
->GetDocument();
4633 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4638 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4643 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4644 if (!ValidRow(nTmp
))
4651 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4652 if (!ValidRow(nTmp
))
4660 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4662 // nur an den Raendern entlang
4663 // (die Ecken werden evtl. zweimal getroffen)
4665 if ( nEdges
& SCE_TOP
)
4666 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4667 if ( nEdges
& SCE_LEFT
)
4668 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4669 if ( nEdges
& SCE_RIGHT
)
4670 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4671 if ( nEdges
& SCE_BOTTOM
)
4672 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4674 else // everything in one call
4675 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4678 void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4680 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4682 ScRange aOld
= rOldUn
;
4683 ScRange aNew
= rNewUn
;
4687 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4688 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4689 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4690 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4692 SCCOL nOldCol1
= aOld
.aStart
.Col();
4693 SCROW nOldRow1
= aOld
.aStart
.Row();
4694 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4695 SCROW nOldRow2
= aOld
.aEnd
.Row();
4696 SCCOL nNewCol1
= aNew
.aStart
.Col();
4697 SCROW nNewRow1
= aNew
.aStart
.Row();
4698 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4699 SCROW nNewRow2
= aNew
.aEnd
.Row();
4700 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4701 SCTAB nTab2
= aOld
.aEnd
.Tab();
4703 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4704 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4705 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4706 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4708 // komplett weggeschoben oder alle Seiten veraendert
4709 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4711 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4713 else // alle vier Kanten einzeln testen
4716 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4717 lcl_PaintOneRange( pDocSh
, ScRange(
4718 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4719 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4720 lcl_PaintOneRange( pDocSh
, ScRange(
4721 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4722 SCE_ALL
&~ SCE_BOTTOM
);
4725 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4726 lcl_PaintOneRange( pDocSh
, ScRange(
4727 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4728 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4729 lcl_PaintOneRange( pDocSh
, ScRange(
4730 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4731 SCE_ALL
&~ SCE_TOP
);
4734 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
4735 lcl_PaintOneRange( pDocSh
, ScRange(
4736 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
4737 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
4738 lcl_PaintOneRange( pDocSh
, ScRange(
4739 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
4740 SCE_ALL
&~ SCE_RIGHT
);
4743 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
4744 lcl_PaintOneRange( pDocSh
, ScRange(
4745 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4746 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
4747 lcl_PaintOneRange( pDocSh
, ScRange(
4748 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4749 SCE_ALL
&~ SCE_LEFT
);
4753 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, BOOL bUp
)
4755 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4758 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4759 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
4761 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
4768 SetPointer( Pointer( POINTER_CROSS
) );
4770 SetPointer( Pointer( POINTER_HAND
) );
4774 BOOL bTimer
= FALSE
;
4775 Point aPos
= rMEvt
.GetPosPixel();
4778 if ( aPos
.X() < 0 ) nDx
= -1;
4779 if ( aPos
.Y() < 0 ) nDy
= -1;
4780 Size aSize
= GetOutputSizePixel();
4781 if ( aPos
.X() >= aSize
.Width() )
4783 if ( aPos
.Y() >= aSize
.Height() )
4785 if ( nDx
!= 0 || nDy
!= 0 )
4787 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
4788 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
4792 // Umschalten bei Fixierung (damit Scrolling funktioniert)
4794 if ( eWhich
== pViewData
->GetActivePart() ) //??
4796 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
4799 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4800 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
4801 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
4802 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4805 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
4808 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4809 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
4810 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
4811 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4819 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4821 ScRange aOld
= pData
->aRef
;
4822 ScRange aNew
= aOld
;
4825 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
4826 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
4830 long nStartX
= nPosX
- nRFAddX
;
4831 if ( nStartX
< 0 ) nStartX
= 0;
4832 long nStartY
= nPosY
- nRFAddY
;
4833 if ( nStartY
< 0 ) nStartY
= 0;
4834 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
4835 if ( nEndX
> MAXCOL
)
4837 nStartX
-= ( nEndX
- MAXROW
);
4840 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
4841 if ( nEndY
> MAXROW
)
4843 nStartY
-= ( nEndY
- MAXROW
);
4847 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
4848 aNew
.aStart
.SetRow((SCROW
)nStartY
);
4849 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
4850 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
4854 aNew
.Justify(); // beim ButtonUp wieder richtigherum
4858 pHdl
->UpdateRange( nRFIndex
, aNew
);
4860 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4862 // nur das neuzeichnen, was sich veraendert hat...
4863 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
4865 // neuen Rahmen nur drueberzeichnen (synchron)
4866 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
4868 Update(); // was man bewegt, will man auch sofort sehen
4871 // Timer fuer Scrolling
4874 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
4876 pViewData
->GetView()->ResetTimer();
4879 //------------------------------------------------------------------------
4881 BOOL
ScGridWindow::GetEditUrl( const Point
& rPos
,
4882 String
* pName
, String
* pUrl
, String
* pTarget
)
4884 return GetEditUrlOrError( FALSE
, rPos
, pName
, pUrl
, pTarget
);
4887 BOOL
ScGridWindow::GetEditUrlOrError( BOOL bSpellErr
, const Point
& rPos
,
4888 String
* pName
, String
* pUrl
, String
* pTarget
)
4890 //! nPosX/Y mit uebergeben?
4893 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
4895 SCTAB nTab
= pViewData
->GetTabNo();
4896 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4897 ScDocument
* pDoc
= pDocSh
->GetDocument();
4898 ScBaseCell
* pCell
= NULL
;
4900 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
4904 ScHideTextCursor
aHideCursor( pViewData
, eWhich
); // before GetEditArea (MapMode is changed)
4906 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
4907 // bForceToTop = FALSE, use the cell's real position
4908 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, FALSE
);
4909 if (rPos
.Y() < aEditRect
.Top())
4912 // vertikal kann (noch) nicht angeklickt werden:
4914 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
4917 BOOL bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
4918 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
4919 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
4920 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
4921 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
4925 ScFieldEditEngine
aEngine( pDoc
->GetEditPool() );
4926 ScSizeDeviceProvider
aProv(pDocSh
);
4927 aEngine
.SetRefDevice( aProv
.GetDevice() );
4928 aEngine
.SetRefMapMode( MAP_100TH_MM
);
4929 SfxItemSet
aDefault( aEngine
.GetEmptyItemSet() );
4930 pPattern
->FillEditItemSet( &aDefault
);
4931 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
4934 case SVX_HOR_JUSTIFY_LEFT
:
4935 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
4936 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
4937 eSvxAdjust
= SVX_ADJUST_LEFT
;
4939 case SVX_HOR_JUSTIFY_RIGHT
:
4940 eSvxAdjust
= SVX_ADJUST_RIGHT
;
4942 case SVX_HOR_JUSTIFY_CENTER
:
4943 eSvxAdjust
= SVX_ADJUST_CENTER
;
4945 case SVX_HOR_JUSTIFY_BLOCK
:
4946 eSvxAdjust
= SVX_ADJUST_BLOCK
;
4949 aDefault
.Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
4950 aEngine
.SetDefaults( aDefault
);
4952 aEngine
.SetControlWord( aEngine
.GetControlWord() | EE_CNTRL_ONLINESPELLING
);
4954 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
4955 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
4956 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
4958 Size aPaperSize
= Size( 1000000, 1000000 );
4959 if(pCell
->GetCellType() == CELLTYPE_FORMULA
)
4963 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
4964 aPaperSize
= Size(nSizeX
, nSizeY
);
4965 aPaperSize
= PixelToLogic(aPaperSize
);
4969 aPaperSize
.Width() = nThisColLogic
;
4970 aEngine
.SetPaperSize( aPaperSize
);
4972 ::std::auto_ptr
< EditTextObject
> pTextObj
;
4973 const EditTextObject
* pData
;
4974 if(pCell
->GetCellType() == CELLTYPE_EDIT
)
4976 ((ScEditCell
*)pCell
)->GetData(pData
);
4978 aEngine
.SetText(*pData
);
4980 else // HyperLink Formula cell
4982 pTextObj
.reset((static_cast<ScFormulaCell
*>(pCell
))->CreateURLObject());
4984 aEngine
.SetText(*pTextObj
);
4987 long nStartX
= aLogicEdit
.Left();
4989 long nTextWidth
= aEngine
.CalcTextWidth();
4990 long nTextHeight
= aEngine
.GetTextHeight();
4991 if ( nTextWidth
< nThisColLogic
)
4993 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
4994 nStartX
+= nThisColLogic
- nTextWidth
;
4995 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
4996 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
4999 aLogicEdit
.Left() = nStartX
;
5001 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5003 // There is one glitch when dealing with a hyperlink cell and
5004 // the cell content is NUMERIC. This defaults to right aligned and
5005 // we need to adjust accordingly.
5006 if(pCell
->GetCellType() == CELLTYPE_FORMULA
&&
5007 static_cast<ScFormulaCell
*>(pCell
)->IsValue() &&
5008 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5010 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5011 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5013 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5016 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5017 if ( aLogicEdit
.IsInside(aLogicClick
) )
5019 // aEngine.SetUpdateMode(FALSE);
5020 EditView
aTempView( &aEngine
, this );
5021 aTempView
.SetOutputArea( aLogicEdit
);
5024 MapMode aOld
= GetMapMode();
5025 SetMapMode(aEditMode
); // kein return mehr
5027 if (bSpellErr
) // Spelling-Fehler suchen
5029 bRet
= aTempView
.IsWrongSpelledWordAtPos( rPos
);
5031 pViewData
->GetView()->SetCursor( nPosX
, nPosY
); // Cursor setzen
5035 const SvxFieldItem
* pFieldItem
= aTempView
.GetFieldUnderMousePointer();
5039 const SvxFieldData
* pField
= pFieldItem
->GetField();
5040 if ( pField
&& pField
->ISA(SvxURLField
) )
5042 if ( pName
|| pUrl
|| pTarget
)
5044 const SvxURLField
* pURLField
= (const SvxURLField
*)pField
;
5046 *pName
= pURLField
->GetRepresentation();
5048 *pUrl
= pURLField
->GetURL();
5050 *pTarget
= pURLField
->GetTargetFrame();
5059 // text cursor is restored in ScHideTextCursor dtor
5066 BOOL
ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5068 ScDocument
* pDoc
= pViewData
->GetDocument();
5069 SCTAB nTab
= pViewData
->GetTabNo();
5070 SCTAB nTabCount
= pDoc
->GetTableCount();
5071 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5073 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5075 Size aButSize
= pViewData
->GetScenButSize();
5076 long nBWidth
= aButSize
.Width();
5078 return FALSE
; // noch kein Button gezeichnet -> da ist auch keiner
5079 long nBHeight
= aButSize
.Height();
5080 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5082 //! Ranges an der Table cachen!!!!
5085 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5086 pDoc
->MarkScenario( i
, nTab
, aMarks
, FALSE
, SC_SCENARIO_SHOWFRAME
);
5087 ScRangeList aRanges
;
5088 aMarks
.FillRangeListWithMarks( &aRanges
, FALSE
);
5091 ULONG nRangeCount
= aRanges
.Count();
5092 for (ULONG j
=0; j
<nRangeCount
; j
++)
5094 ScRange aRange
= *aRanges
.GetObject(j
);
5095 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5096 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5097 pDoc
->ExtendTotalMerge( aRange
);
5099 BOOL bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5104 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5109 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5111 aButtonPos
.Y() -= nBHeight
;
5114 aButtonPos
.X() -= nHSpace
- 1;
5116 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5118 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5119 if ( aButRect
.IsInside( rPosPixel
) )
5121 rScenRange
= aRange
;
5131 void ScGridWindow::DrawLayerCreated()
5133 SetMapMode( GetDrawMapMode() );
5135 // initially create overlay objects
5136 ImpCreateOverlayObjects();
5140 void ScGridWindow::CursorChanged()
5142 // here the created OverlayObjects may be transformed in later versions. For
5143 // now, just re-create them
5145 UpdateCursorOverlay();
5149 void ScGridWindow::ImpCreateOverlayObjects()
5151 UpdateCursorOverlay();
5152 UpdateSelectionOverlay();
5153 UpdateAutoFillOverlay();
5154 UpdateDragRectOverlay();
5155 UpdateHeaderOverlay();
5156 UpdateShrinkOverlay();
5160 void ScGridWindow::ImpDestroyOverlayObjects()
5162 DeleteCursorOverlay();
5163 DeleteSelectionOverlay();
5164 DeleteAutoFillOverlay();
5165 DeleteDragRectOverlay();
5166 DeleteHeaderOverlay();
5167 DeleteShrinkOverlay();
5170 void ScGridWindow::UpdateAllOverlays()
5172 // delete and re-allocate all overlay objects
5174 ImpDestroyOverlayObjects();
5175 ImpCreateOverlayObjects();
5178 void ScGridWindow::DeleteCursorOverlay()
5180 DELETEZ( mpOOCursors
);
5181 DELETEZ( mpOOSelectionBorder
);
5184 void ScGridWindow::ConvertPixelRectsToRangeVector( const ::std::vector
< Rectangle
>& rPixelRects
,
5185 sdr::overlay::OverlayObjectCell::RangeVector
* pRanges
,
5186 const MapMode
& rDrawMode
,
5187 const ScGridWindow::RectangleConverter
* pConverter
)
5189 std::vector
<Rectangle
>::const_iterator
aPixelEnd( rPixelRects
.end() );
5190 for ( std::vector
<Rectangle
>::const_iterator
aPixelIter( rPixelRects
.begin() );
5191 aPixelIter
!= aPixelEnd
; ++aPixelIter
)
5193 Rectangle
aLogic( PixelToLogic(
5194 (pConverter
== NULL
? *aPixelIter
: pConverter
->Convert (*aPixelIter
)),
5197 const basegfx::B2DPoint
aTopLeft(aLogic
.Left(), aLogic
.Top());
5198 const basegfx::B2DPoint
aBottomRight(aLogic
.Right(), aLogic
.Bottom());
5199 const basegfx::B2DRange
a2DRange(aTopLeft
, aBottomRight
);
5201 pRanges
->push_back( a2DRange
);
5205 void ScGridWindow::UpdateCopySourceOverlay( const MapMode
& rDrawMode
)
5207 if (!pViewData
->ShowPasteSource())
5209 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5210 if (!pOverlayManager
)
5212 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5215 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5219 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5221 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5222 mpOOSelectionBorder
= new ::sdr::overlay::OverlayObjectList
;
5223 for (ScRange
* p
= rClipParam
.maRanges
.First(); p
; p
= rClipParam
.maRanges
.Next())
5225 if (p
->aStart
.Tab() != nCurTab
)
5228 SCCOL nClipStartX
= p
->aStart
.Col();
5229 SCROW nClipStartY
= p
->aStart
.Row();
5230 SCCOL nClipEndX
= p
->aEnd
.Col();
5231 SCROW nClipEndY
= p
->aEnd
.Row();
5233 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5234 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5236 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5237 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5239 aClipStartScrPos
.X() -= 2;
5240 aClipStartScrPos
.Y() -= 2;
5242 Rectangle
aRect( aClipStartScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5244 std::vector
<Rectangle
> aPixelRects
;
5246 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5247 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5248 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5249 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5251 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5252 ConvertPixelRectsToRangeVector( aPixelRects
, &aRanges
, rDrawMode
);
5254 ScOverlayType eType
= SC_OVERLAY_BORDER_TRANSPARENT
;
5256 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5257 sdr::overlay::OverlayObjectCell
* pOverlay
= new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
5259 pOverlayManager
->add(*pOverlay
);
5260 mpOOSelectionBorder
->append(*pOverlay
);
5264 void ScGridWindow::UpdateCursorOverlay()
5266 MapMode aDrawMode
= GetDrawMapMode();
5267 MapMode aOldMode
= GetMapMode();
5268 if ( aOldMode
!= aDrawMode
)
5269 SetMapMode( aDrawMode
);
5271 // Existing OverlayObjects may be transformed in later versions.
5272 // For now, just re-create them.
5274 DeleteCursorOverlay();
5276 UpdateCopySourceOverlay( aDrawMode
);
5278 std::vector
<Rectangle
> aPixelRects
;
5281 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5284 SCTAB nTab
= pViewData
->GetTabNo();
5285 SCCOL nX
= pViewData
->GetCurX();
5286 SCROW nY
= pViewData
->GetCurY();
5288 if (!maVisibleRange
.isInside(nX
, nY
))
5291 // don't show the cursor in overlapped cells
5293 ScDocument
* pDoc
= pViewData
->GetDocument();
5294 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5295 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5296 BOOL bOverlapped
= rMergeFlag
.IsOverlapped();
5298 // left or above of the screen?
5300 BOOL bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5305 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5306 if (rMerge
.GetColMerge() > 1)
5307 nEndX
+= rMerge
.GetColMerge()-1;
5308 if (rMerge
.GetRowMerge() > 1)
5309 nEndY
+= rMerge
.GetRowMerge()-1;
5310 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5313 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5315 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5316 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5318 // completely right of/below the screen?
5319 // (test with logical start position in aScrPos)
5322 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5325 Size aOutSize
= GetOutputSizePixel();
5326 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5328 if ( bMaybeVisible
)
5332 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5335 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5337 // Now, draw the cursor.
5341 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5343 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5344 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5345 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5346 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5351 // convert into logic units and create overlay object
5354 if ( aPixelRects
.size() )
5356 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5357 ConvertPixelRectsToRangeVector( aPixelRects
, &aRanges
, aDrawMode
);
5359 // #i70788# get the OverlayManager safely
5360 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5364 BOOL bOld
= pViewData
->GetView()->IsOldSelection();
5366 ScOverlayType eType
= bOld
? SC_OVERLAY_INVERT
: SC_OVERLAY_SOLID
;
5367 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5368 if (pViewData
->GetActivePart() != eWhich
)
5369 // non-active pane uses a different color.
5370 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5372 sdr::overlay::OverlayObjectCell
* pOverlay
= new sdr::overlay::OverlayObjectCell( eType
, aCursorColor
, aRanges
);
5374 pOverlayManager
->add(*pOverlay
);
5375 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5376 mpOOCursors
->append(*pOverlay
);
5380 if ( aOldMode
!= aDrawMode
)
5381 SetMapMode( aOldMode
);
5384 void ScGridWindow::DeleteSelectionOverlay()
5386 DELETEZ( mpOOSelection
);
5389 void ScGridWindow::UpdateSelectionOverlay()
5391 MapMode aDrawMode
= GetDrawMapMode();
5392 MapMode aOldMode
= GetMapMode();
5393 if ( aOldMode
!= aDrawMode
)
5394 SetMapMode( aDrawMode
);
5396 DeleteSelectionOverlay();
5398 std::vector
<Rectangle
> aPixelRects
;
5399 GetSelectionRects( aPixelRects
);
5401 if ( aPixelRects
.size() && pViewData
->IsActive() )
5403 struct SelectionConverter
: RectangleConverter
{
5408 SelectionConverter (ScViewData
* pViewData
)
5409 : nTab (pViewData
->GetTabNo())
5410 , bLayoutRTL (pViewData
->GetDocument()->IsLayoutRTL( nTab
))
5411 , bOld (pViewData
->GetView()->IsOldSelection())
5415 Rectangle
Convert (const Rectangle
& rRect
) const
5419 // for transparent selection, add a pixel so the border is on the grid on all edges
5420 Rectangle
aPixel (rRect
);
5422 aPixel
.Right() += 1;
5429 SelectionConverter
aConverter (pViewData
);
5431 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5432 ConvertPixelRectsToRangeVector( aPixelRects
, &aRanges
, aDrawMode
, &aConverter
);
5434 // #i70788# get the OverlayManager safely
5435 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5439 ScOverlayType eType
= aConverter
.bOld
? SC_OVERLAY_INVERT
: SC_OVERLAY_BORDER_TRANSPARENT
;
5440 Color
aHighlight( GetSettings().GetStyleSettings().GetHighlightColor() );
5441 sdr::overlay::OverlayObjectCell
* pOverlay
=
5442 new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
5444 pOverlayManager
->add(*pOverlay
);
5445 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5446 mpOOSelection
->append(*pOverlay
);
5450 if ( aOldMode
!= aDrawMode
)
5451 SetMapMode( aOldMode
);
5454 void ScGridWindow::DeleteAutoFillOverlay()
5456 DELETEZ( mpOOAutoFill
);
5457 mpAutoFillRect
.reset();
5460 void ScGridWindow::UpdateAutoFillOverlay()
5462 MapMode aDrawMode
= GetDrawMapMode();
5463 MapMode aOldMode
= GetMapMode();
5464 if ( aOldMode
!= aDrawMode
)
5465 SetMapMode( aDrawMode
);
5467 DeleteAutoFillOverlay();
5470 // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
5473 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5474 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5476 SCCOL nX
= aAutoMarkPos
.Col();
5477 SCROW nY
= aAutoMarkPos
.Row();
5479 if (!maVisibleRange
.isInside(nX
, nY
))
5480 // Autofill mark is not visible. Bail out.
5483 SCTAB nTab
= pViewData
->GetTabNo();
5484 ScDocument
* pDoc
= pViewData
->GetDocument();
5485 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5487 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5490 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5492 aFillPos
.X() -= nSizeXPix
+ 3;
5494 aFillPos
.X() += nSizeXPix
- 2;
5496 aFillPos
.Y() += nSizeYPix
;
5498 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
5501 // convert into logic units
5504 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5506 Rectangle
aLogic( PixelToLogic( *mpAutoFillRect
, aDrawMode
) );
5508 const basegfx::B2DPoint
aTopLeft(aLogic
.Left(), aLogic
.Top());
5509 const basegfx::B2DPoint
aBottomRight(aLogic
.Right(), aLogic
.Bottom());
5510 const basegfx::B2DRange
a2DRange(aTopLeft
, aBottomRight
);
5512 aRanges
.push_back( a2DRange
);
5514 // #i70788# get the OverlayManager safely
5515 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5519 BOOL bOld
= pViewData
->GetView()->IsOldSelection();
5521 ScOverlayType eType
= bOld
? SC_OVERLAY_INVERT
: SC_OVERLAY_SOLID
;
5522 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5523 if (pViewData
->GetActivePart() != eWhich
)
5524 // non-active pane uses a different color.
5525 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5527 sdr::overlay::OverlayObjectCell
* pOverlay
=
5528 new sdr::overlay::OverlayObjectCell( eType
, aHandleColor
, aRanges
);
5530 pOverlayManager
->add(*pOverlay
);
5531 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
5532 mpOOAutoFill
->append(*pOverlay
);
5535 if ( aOldMode
!= aDrawMode
)
5536 SetMapMode( aOldMode
);
5540 void ScGridWindow::DeleteDragRectOverlay()
5542 DELETEZ( mpOODragRect
);
5545 void ScGridWindow::UpdateDragRectOverlay()
5547 MapMode aDrawMode
= GetDrawMapMode();
5548 MapMode aOldMode
= GetMapMode();
5549 if ( aOldMode
!= aDrawMode
)
5550 SetMapMode( aDrawMode
);
5552 DeleteDragRectOverlay();
5555 // get the rectangles in pixels (moved from DrawDragRect)
5558 if ( bDragRect
|| bPagebreakDrawn
)
5560 std::vector
<Rectangle
> aPixelRects
;
5562 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
5563 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
5564 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
5565 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
5567 SCTAB nTab
= pViewData
->GetTabNo();
5569 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
5570 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
5571 if (nX1
< nPosX
) nX1
= nPosX
;
5572 if (nX2
< nPosX
) nX2
= nPosX
;
5573 if (nY1
< nPosY
) nY1
= nPosY
;
5574 if (nY2
< nPosY
) nY2
= nPosY
;
5576 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
5580 ScDocument
* pDoc
= pViewData
->GetDocument();
5581 double nPPTX
= pViewData
->GetPPTX();
5582 double nPPTY
= pViewData
->GetPPTY();
5585 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5586 long nLayoutSign
= bLayoutRTL
? -1 : 1;
5588 if (ValidCol(nX2
) && nX2
>=nX1
)
5589 for (i
=nX1
; i
<=nX2
; i
++)
5590 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
5593 aScrPos
.X() -= nLayoutSign
;
5597 if (ValidRow(nY2
) && nY2
>=nY1
)
5598 for (i
=nY1
; i
<=nY2
; i
++)
5599 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
5606 aScrPos
.X() -= 2 * nLayoutSign
;
5608 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5609 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
5610 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
5613 aRect
.Left() = aRect
.Right(); // end position is left
5614 aRect
.Right() = aScrPos
.X();
5617 if ( meDragInsertMode
== INS_CELLSDOWN
)
5619 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
5620 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
5621 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
5622 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5624 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
5626 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
5627 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5628 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
5629 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
5633 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
5634 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
5635 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
5636 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
5640 // convert into logic units and create overlay object
5643 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5644 ConvertPixelRectsToRangeVector( aPixelRects
, &aRanges
, aDrawMode
);
5646 // #i70788# get the OverlayManager safely
5647 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5651 ScOverlayType eType
= SC_OVERLAY_INVERT
;
5652 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5653 sdr::overlay::OverlayObjectCell
* pOverlay
=
5654 new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
5656 pOverlayManager
->add(*pOverlay
);
5657 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
5658 mpOODragRect
->append(*pOverlay
);
5662 if ( aOldMode
!= aDrawMode
)
5663 SetMapMode( aOldMode
);
5666 void ScGridWindow::DeleteHeaderOverlay()
5668 DELETEZ( mpOOHeader
);
5671 void ScGridWindow::UpdateHeaderOverlay()
5673 MapMode aDrawMode
= GetDrawMapMode();
5674 MapMode aOldMode
= GetMapMode();
5675 if ( aOldMode
!= aDrawMode
)
5676 SetMapMode( aDrawMode
);
5678 DeleteHeaderOverlay();
5680 // Pixel rectangle is in aInvertRect
5683 // convert into logic units and create overlay object
5686 if ( !aInvertRect
.IsEmpty() )
5688 Rectangle
aLogic( PixelToLogic( aInvertRect
, aDrawMode
) );
5690 const basegfx::B2DPoint
aTopLeft(aLogic
.Left(), aLogic
.Top());
5691 const basegfx::B2DPoint
aBottomRight(aLogic
.Right(), aLogic
.Bottom());
5692 const basegfx::B2DRange
a2DRange(aTopLeft
, aBottomRight
);
5694 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5695 aRanges
.push_back( a2DRange
);
5697 // #i70788# get the OverlayManager safely
5698 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5702 ScOverlayType eType
= SC_OVERLAY_INVERT
;
5703 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5704 sdr::overlay::OverlayObjectCell
* pOverlay
=
5705 new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
5707 pOverlayManager
->add(*pOverlay
);
5708 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
5709 mpOOHeader
->append(*pOverlay
);
5713 if ( aOldMode
!= aDrawMode
)
5714 SetMapMode( aOldMode
);
5717 void ScGridWindow::DeleteShrinkOverlay()
5719 DELETEZ( mpOOShrink
);
5722 void ScGridWindow::UpdateShrinkOverlay()
5724 MapMode aDrawMode
= GetDrawMapMode();
5725 MapMode aOldMode
= GetMapMode();
5726 if ( aOldMode
!= aDrawMode
)
5727 SetMapMode( aDrawMode
);
5729 DeleteShrinkOverlay();
5732 // get the rectangle in pixels
5737 SCTAB nTab
= pViewData
->GetTabNo();
5738 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
5739 pViewData
->GetDelMark( aRange
) )
5741 //! limit to visible area
5742 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
5743 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
5745 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
5746 aRange
.aStart
.Row(), eWhich
);
5747 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
5748 aRange
.aEnd
.Row()+1, eWhich
);
5752 aPixRect
= Rectangle( aStart
,aEnd
);
5757 // convert into logic units and create overlay object
5760 if ( !aPixRect
.IsEmpty() )
5762 Rectangle
aLogic( PixelToLogic( aPixRect
, aDrawMode
) );
5764 const basegfx::B2DPoint
aTopLeft(aLogic
.Left(), aLogic
.Top());
5765 const basegfx::B2DPoint
aBottomRight(aLogic
.Right(), aLogic
.Bottom());
5766 const basegfx::B2DRange
a2DRange(aTopLeft
, aBottomRight
);
5768 sdr::overlay::OverlayObjectCell::RangeVector aRanges
;
5769 aRanges
.push_back( a2DRange
);
5771 // #i70788# get the OverlayManager safely
5772 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5776 ScOverlayType eType
= SC_OVERLAY_INVERT
;
5777 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5778 sdr::overlay::OverlayObjectCell
* pOverlay
=
5779 new sdr::overlay::OverlayObjectCell( eType
, aHighlight
, aRanges
);
5781 pOverlayManager
->add(*pOverlay
);
5782 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
5783 mpOOShrink
->append(*pOverlay
);
5787 if ( aOldMode
!= aDrawMode
)
5788 SetMapMode( aOldMode
);
5791 // #i70788# central method to get the OverlayManager safely
5792 ::sdr::overlay::OverlayManager
* ScGridWindow::getOverlayManager()
5794 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
5798 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
5802 return (pPageWin
->GetOverlayManager());
5809 void ScGridWindow::flushOverlayManager()
5811 // #i70788# get the OverlayManager safely
5812 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5816 pOverlayManager
->flush();
5820 // ---------------------------------------------------------------------------
5827 OverlayObjectCell::OverlayObjectCell( ScOverlayType eType
, const Color
& rColor
, const RangeVector
& rRects
)
5828 : OverlayObject( rColor
),
5829 mePaintType( eType
),
5830 maRectangles( rRects
)
5834 OverlayObjectCell::~OverlayObjectCell()
5838 void OverlayObjectCell::drawGeometry(OutputDevice
& rOutputDevice
)
5840 // safe original AA and switch off for selection
5841 const sal_uInt16
nOriginalAA(rOutputDevice
.GetAntialiasing());
5842 rOutputDevice
.SetAntialiasing(0);
5845 rOutputDevice
.SetLineColor();
5846 rOutputDevice
.SetFillColor(getBaseColor());
5848 if ( mePaintType
== SC_OVERLAY_BORDER_TRANSPARENT
)
5850 // to draw the border, all rectangles have to be collected into a PolyPolygon
5852 PolyPolygon aPolyPoly
;
5853 sal_uInt32 nRectCount
= maRectangles
.size();
5854 for(sal_uInt32 nRect
=0; nRect
< nRectCount
; ++nRect
)
5856 const basegfx::B2DRange
& rRange(maRectangles
[nRect
]);
5857 Rectangle
aRectangle(FRound(rRange
.getMinX()), FRound(rRange
.getMinY()), FRound(rRange
.getMaxX()), FRound(rRange
.getMaxY()));
5858 if ( nRectCount
== 1 || nRect
+1 < nRectCount
)
5860 // simply add for all except the last rect
5861 aPolyPoly
.Insert( Polygon( aRectangle
) );
5865 PolyPolygon
aTemp( aPolyPoly
);
5866 aTemp
.GetUnion( PolyPolygon( Polygon( aRectangle
) ), aPolyPoly
);
5870 rOutputDevice
.DrawTransparent(aPolyPoly
, 75);
5872 rOutputDevice
.SetLineColor(getBaseColor());
5873 rOutputDevice
.SetFillColor();
5875 rOutputDevice
.DrawPolyPolygon(aPolyPoly
);
5879 if ( mePaintType
== SC_OVERLAY_INVERT
)
5881 rOutputDevice
.Push();
5882 rOutputDevice
.SetRasterOp( ROP_XOR
);
5883 rOutputDevice
.SetFillColor( COL_WHITE
);
5886 for(sal_uInt32
a(0L);a
< maRectangles
.size(); a
++)
5888 const basegfx::B2DRange
& rRange(maRectangles
[a
]);
5889 const Rectangle
aRectangle(FRound(rRange
.getMinX()), FRound(rRange
.getMinY()), FRound(rRange
.getMaxX()), FRound(rRange
.getMaxY()));
5893 case SC_OVERLAY_INVERT
:
5895 rOutputDevice
.DrawRect( aRectangle
);
5898 case SC_OVERLAY_SOLID
:
5900 rOutputDevice
.DrawRect(aRectangle
);
5905 // SC_OVERLAY_BORDER_TRANSPARENT is handled separately
5910 if ( mePaintType
== SC_OVERLAY_INVERT
)
5912 rOutputDevice
.Pop();
5916 // restore original AA
5917 rOutputDevice
.SetAntialiasing(nOriginalAA
);
5920 void OverlayObjectCell::createBaseRange(OutputDevice
& /* rOutputDevice */)
5922 maBaseRange
.reset();
5924 for(sal_uInt32
a(0L); a
< maRectangles
.size(); a
++)
5926 maBaseRange
.expand(maRectangles
[a
]);
5930 void OverlayObjectCell::transform(const basegfx::B2DHomMatrix
& rMatrix
)
5932 for(sal_uInt32
a(0L); a
< maRectangles
.size(); a
++)
5934 maRectangles
[a
].transform(rMatrix
);
5938 } // end of namespace overlay
5939 } // end of namespace sdr
5941 // ---------------------------------------------------------------------------