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 "validat.hxx"
123 #include "tabprotection.hxx"
124 #include "postit.hxx"
125 #include "dpcontrol.hxx"
127 #include "drawview.hxx"
128 #include <svx/sdrpagewindow.hxx>
129 #include <svx/sdr/overlay/overlaymanager.hxx>
130 #include <vcl/svapp.hxx>
131 #include <svx/sdr/overlay/overlayselection.hxx>
133 #include "cellsuno.hxx"
135 #include <com/sun/star/document/XVbaEventsHelper.hpp>
136 #include <com/sun/star/document/VbaEventId.hpp>
138 using namespace com::sun::star
;
139 using namespace com::sun::star::document::VbaEventId
;
140 using ::com::sun::star::uno::Sequence
;
141 using ::com::sun::star::uno::Any
;
143 const BYTE SC_NESTEDBUTTON_NONE
= 0;
144 const BYTE SC_NESTEDBUTTON_DOWN
= 1;
145 const BYTE SC_NESTEDBUTTON_UP
= 2;
147 #define SC_AUTOFILTER_ALL 0
148 #define SC_AUTOFILTER_TOP10 1
149 #define SC_AUTOFILTER_CUSTOM 2
150 #define SC_AUTOFILTER_EMPTY 3
151 #define SC_AUTOFILTER_NOTEMPTY 4
153 // Modi fuer die FilterListBox
157 SC_FILTERBOX_DATASELECT
,
158 SC_FILTERBOX_SCENARIO
,
159 SC_FILTERBOX_PAGEFIELD
162 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
163 extern USHORT nScClickMouseModifier
; // global.cxx
164 extern USHORT nScFillModeMouseModifier
; // global.cxx
166 #define SC_FILTERLISTBOX_LINES 12
168 // ============================================================================
170 ScGridWindow::VisibleRange::VisibleRange() :
171 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
175 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
177 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
180 // ============================================================================
182 class ScFilterListBox
: public ListBox
185 ScGridWindow
* pGridWin
;
194 ScFilterBoxMode eMode
;
197 virtual void LoseFocus();
201 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
202 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
205 virtual long PreNotify( NotifyEvent
& rNEvt
);
206 virtual void Select();
208 SCCOL
GetCol() const { return nCol
; }
209 SCROW
GetRow() const { return nRow
; }
210 ScFilterBoxMode
GetMode() const { return eMode
; }
211 BOOL
IsDataSelect() const { return (eMode
== SC_FILTERBOX_DATASELECT
); }
213 BOOL
IsInInit() const { return bInit
; }
214 void SetCancelled() { bCancelled
= TRUE
; }
215 BOOL
IsInSelect() const { return bInSelect
; }
216 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
217 bool HasDates() const { return mbListHasDates
; }
220 //-------------------------------------------------------------------
222 // ListBox in einem FloatingWindow (pParent)
223 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
224 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
225 ListBox( pParent
, WB_AUTOHSCROLL
),
229 bButtonDown( FALSE
),
233 mbListHasDates(false),
239 __EXPORT
ScFilterListBox::~ScFilterListBox()
241 if (IsMouseCaptured())
245 void ScFilterListBox::EndInit()
247 USHORT nPos
= GetSelectEntryPos();
248 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
256 void __EXPORT
ScFilterListBox::LoseFocus()
263 // -----------------------------------------------------------------------
265 long ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
268 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
270 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
271 KeyCode aCode
= aKeyEvt
.GetKeyCode();
272 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
274 USHORT nKey
= aCode
.GetCode();
275 if ( nKey
== KEY_RETURN
)
277 SelectHdl(); // auswaehlen
280 else if ( nKey
== KEY_ESCAPE
)
282 pGridWin
->ClickExtern(); // loescht die List-Box !!!
288 return nDone
? nDone
: ListBox::PreNotify( rNEvt
);
291 void __EXPORT
ScFilterListBox::Select()
297 void __EXPORT
ScFilterListBox::SelectHdl()
299 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
301 USHORT nPos
= GetSelectEntryPos();
302 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
307 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
309 pGridWin
->FilterSelect( nSel
);
316 // ============================================================================
318 // use a System floating window for the above filter listbox
319 class ScFilterFloatingWindow
: public FloatingWindow
322 ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
323 virtual ~ScFilterFloatingWindow();
324 // required for System FloatingWindows that will not process KeyInput by themselves
325 virtual Window
* GetPreferredKeyInputWindow();
328 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
329 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
332 ScFilterFloatingWindow::~ScFilterFloatingWindow()
337 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
339 // redirect keyinput in the child window
340 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
343 // ============================================================================
345 BOOL
lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
347 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
348 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
349 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
351 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
352 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
356 const ScBaseCell
* pCell
= pDoc
->GetCell( rRange
.aEnd
);
357 return ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
&&
358 ((ScFormulaCell
*)pCell
)->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
362 void lcl_UnLockComment( ScDrawView
* pView
, SdrPageView
* pPV
, SdrModel
* pDrDoc
, const Point
& rPos
, ScViewData
* pViewData
)
364 if (!pView
&& !pPV
&& !pDrDoc
&& !pViewData
)
367 ScDocument
& rDoc
= *pViewData
->GetDocument();
368 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
369 ScPostIt
* pNote
= rDoc
.GetNote( aCellPos
);
370 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
371 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
373 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
374 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
375 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
376 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
377 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
381 sal_Bool
lcl_GetHyperlinkCell(ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScBaseCell
*& rpCell
)
386 pDoc
->GetCell( rPosX
, rPosY
, nTab
, rpCell
);
387 if ( !rpCell
|| rpCell
->GetCellType() == CELLTYPE_NOTE
)
390 return FALSE
; // alles leer bis links
392 --rPosX
; // weitersuchen
394 else if ( rpCell
->GetCellType() == CELLTYPE_EDIT
)
396 else if (rpCell
->GetCellType() == CELLTYPE_FORMULA
&&
397 static_cast<ScFormulaCell
*>(rpCell
)->IsHyperLinkCell())
400 return FALSE
; // andere Zelle
407 // ---------------------------------------------------------------------------
408 // WB_DIALOGCONTROL noetig fuer UNO-Controls
409 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
410 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
411 DropTargetHelper( this ),
412 DragSourceHelper( this ),
414 mpOOSelection( NULL
),
415 mpOOAutoFill( NULL
),
416 mpOODragRect( NULL
),
419 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
424 pFilterFloat( NULL
),
425 mpDPFieldPopup(NULL
),
426 mpFilterButton(NULL
),
427 nCursorHideCount( 0 ),
431 nMouseStatus( SC_GM_NONE
),
432 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
435 nPagebreakMouse( SC_PD_NONE
),
436 bPagebreakDrawn( FALSE
),
439 meDragInsertMode( INS_NONE
),
440 nCurrentPointer( 0 ),
441 bIsInScroll( FALSE
),
443 aComboButton( this ),
446 bNeedsRepaint( FALSE
),
447 bAutoMarkVisible( FALSE
),
448 bListValButton( FALSE
)
452 case SC_SPLIT_TOPLEFT
:
453 eHWhich
= SC_SPLIT_LEFT
;
454 eVWhich
= SC_SPLIT_TOP
;
456 case SC_SPLIT_TOPRIGHT
:
457 eHWhich
= SC_SPLIT_RIGHT
;
458 eVWhich
= SC_SPLIT_TOP
;
460 case SC_SPLIT_BOTTOMLEFT
:
461 eHWhich
= SC_SPLIT_LEFT
;
462 eVWhich
= SC_SPLIT_BOTTOM
;
464 case SC_SPLIT_BOTTOMRIGHT
:
465 eHWhich
= SC_SPLIT_RIGHT
;
466 eVWhich
= SC_SPLIT_BOTTOM
;
469 DBG_ERROR("GridWindow: falsche Position");
474 SetMapMode(pViewData
->GetLogicMode(eWhich
));
476 EnableChildTransparentMode();
477 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
479 SetHelpId( HID_SC_WIN_GRIDWIN
);
480 SetUniqueId( HID_SC_WIN_GRIDWIN
);
482 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
486 __EXPORT
ScGridWindow::~ScGridWindow()
489 ImpDestroyOverlayObjects();
496 void __EXPORT
ScGridWindow::Resize( const Size
& )
501 void ScGridWindow::ClickExtern()
505 // #i81298# don't delete the filter box when called from its select handler
506 // (possible through row header size update)
507 // #i84277# when initializing the filter box, a Basic error can deactivate the view
508 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
514 DELETEZ(pFilterFloat
);
518 if (mpDPFieldPopup
.get())
520 mpDPFieldPopup
->close(false);
521 mpDPFieldPopup
.reset();
525 IMPL_LINK( ScGridWindow
, PopupModeEndHdl
, FloatingWindow
*, EMPTYARG
)
528 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
533 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
535 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
536 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
540 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, BOOL bHasSelection
, const String
& rStr
)
544 ScDocument
* pDoc
= pViewData
->GetDocument();
545 SCTAB nTab
= pViewData
->GetTabNo();
546 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
547 if ( pDPObj
&& nCol
> 0 )
549 // look for the dimension header left of the drop-down arrow
550 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
551 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
552 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
554 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
557 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
558 if ( !bIsDataLayout
)
560 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
563 pDim
->SetCurrentPage( &rStr
);
565 pDim
->SetCurrentPage( NULL
);
567 ScDPObject
aNewObj( *pDPObj
);
568 aNewObj
.SetSaveData( aSaveData
);
569 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
570 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
571 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
577 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
579 //! merge position/size handling with DoAutoFilterMenue
585 ScDocument
* pDoc
= pViewData
->GetDocument();
586 SCTAB nTab
= pViewData
->GetTabNo();
587 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
592 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
593 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
597 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
600 aPos
.Y() += nSizeY
- 1;
602 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // not resizable etc.
603 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
604 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_PAGEFIELD
);
606 pFilterBox
->EnableMirroring();
611 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
612 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
614 nHeight
= GetTextHeight();
615 nHeight
*= SC_FILTERLISTBOX_LINES
;
617 SetMapMode( aOldMode
);
621 // SetSize comes later
623 TypedScStrCollection
aStrings( 128, 128 );
625 // get list box entries and selection
626 BOOL bHasCurrentPage
= FALSE
;
628 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
629 if ( pDPObj
&& nCol
> 0 )
631 // look for the dimension header left of the drop-down arrow
632 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
633 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
634 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
636 pDPObj
->FillPageList( aStrings
, nField
);
638 // get current page from SaveData
640 ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
642 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
643 if ( pSaveData
&& !bIsDataLayout
)
645 ScDPSaveDimension
* pDim
= pSaveData
->GetExistingDimensionByName(aDimName
);
646 if ( pDim
&& pDim
->HasCurrentPage() )
648 aCurrentPage
= pDim
->GetCurrentPage();
649 bHasCurrentPage
= TRUE
;
655 // include all entry widths for the size of the drop-down
657 USHORT nCount
= aStrings
.GetCount();
658 for (i
=0; i
<nCount
; i
++)
660 TypedStrData
* pData
= aStrings
[i
];
661 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
662 if ( nTextWidth
> nMaxText
)
663 nMaxText
= nTextWidth
;
666 // add scrollbar width if needed (string entries are counted here)
667 // (scrollbar is shown if the box is exactly full?)
668 if ( nCount
>= SC_FILTERLISTBOX_LINES
)
669 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
671 nMaxText
+= 4; // for borders
673 if ( nMaxText
> nSizeX
)
674 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
676 // adjust position and size to window
678 Size aParentSize
= GetParent()->GetOutputSizePixel();
679 Size
aSize( nSizeX
, nHeight
);
681 if ( aSize
.Height() > aParentSize
.Height() )
682 aSize
.Height() = aParentSize
.Height();
683 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
684 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
686 pFilterBox
->SetSizePixel( aSize
);
687 pFilterBox
->Show(); // Show must be called before SetUpdateMode
688 pFilterBox
->SetUpdateMode(FALSE
);
690 pFilterFloat
->SetOutputSizePixel( aSize
);
691 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
694 BOOL bWait
= ( nCount
> 100 );
699 for (i
=0; i
<nCount
; i
++)
700 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
702 pFilterBox
->SetSeparatorPos( 0 );
707 pFilterBox
->SetUpdateMode(TRUE
);
709 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
711 nSelPos
= pFilterBox
->GetEntryPos( aCurrentPage
);
713 if ( nSelPos
== LISTBOX_ENTRY_NOTFOUND
)
714 nSelPos
= 0; // first entry
716 pFilterBox
->GrabFocus();
718 // call Select after GrabFocus, so the focus rectangle ends up in the right position
719 if ( nSelPos
!= LISTBOX_ENTRY_NOTFOUND
)
720 pFilterBox
->SelectEntryPos( nSelPos
);
722 pFilterBox
->EndInit();
724 nMouseStatus
= SC_GM_FILTER
;
728 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
730 SCTAB nTab
= pViewData
->GetTabNo();
731 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
735 // Get the geometry of the cell.
736 Point aScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
738 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
739 Size
aScrSize(nSizeX
-1, nSizeY
-1);
741 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
744 void ScGridWindow::DoScenarioMenue( const ScRange
& rScenRange
)
749 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
750 SCROW nRow
= rScenRange
.aStart
.Row();
753 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
754 if (nRow
>MAXROW
) nRow
= MAXROW
;
755 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
758 ScDocument
* pDoc
= pViewData
->GetDocument();
759 SCTAB nTab
= pViewData
->GetTabNo();
760 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
765 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
766 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
769 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
770 aCellRect
.Top() -= nSizeY
;
771 aCellRect
.Bottom() -= nSizeY
- 1;
772 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
773 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
775 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
776 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
777 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
779 pFilterBox
->EnableMirroring();
784 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
785 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
787 nHeight
= GetTextHeight();
788 nHeight
*= SC_FILTERLISTBOX_LINES
;
790 SetMapMode( aOldMode
);
796 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
797 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
798 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
801 // ParentSize Abfrage fehlt
802 Size
aSize( nSizeX
, nHeight
);
803 pFilterBox
->SetSizePixel( aSize
);
804 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
805 pFilterBox
->SetUpdateMode(FALSE
);
807 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
814 SCTAB nTabCount
= pDoc
->GetTableCount();
815 SCTAB nEntryCount
= 0;
816 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
818 if (pDoc
->HasScenarioRange( i
, rScenRange
))
819 if (pDoc
->GetName( i
, aTabName
))
821 pFilterBox
->InsertEntry( aTabName
);
822 if (pDoc
->IsActiveScenario(i
))
824 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
825 if ( nTextWidth
> nMaxText
)
826 nMaxText
= nTextWidth
;
830 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
831 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
832 nMaxText
+= 4; // fuer Rand
833 if ( nMaxText
> 300 )
834 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
836 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
838 long nDiff
= nMaxText
- nSizeX
;
839 aSize
= Size( nMaxText
, nHeight
);
840 pFilterBox
->SetSizePixel( aSize
);
841 pFilterFloat
->SetOutputSizePixel( aSize
);
845 // also move popup position
846 long nNewX
= aCellRect
.Left() - nDiff
;
849 aCellRect
.Left() = nNewX
;
853 pFilterFloat
->SetOutputSizePixel( aSize
);
854 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
856 pFilterBox
->SetUpdateMode(TRUE
);
857 pFilterBox
->GrabFocus();
859 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
860 //! SvLBoxEntry* pSelect = NULL;
861 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
864 nPos
= pFilterBox
->GetEntryPos( aCurrent
);
865 //! pSelect = pFilterBox->GetEntry( nPos );
867 if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
869 //! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein
870 if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND
!= nPos
)
871 pFilterBox
->SelectEntryPos(nPos
);
873 pFilterBox
->EndInit();
875 // Szenario-Auswahl kommt aus MouseButtonDown:
876 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
878 nMouseStatus
= SC_GM_FILTER
;
882 void ScGridWindow::DoAutoFilterMenue( SCCOL nCol
, SCROW nRow
, BOOL bDataSelect
)
888 ScDocument
* pDoc
= pViewData
->GetDocument();
889 SCTAB nTab
= pViewData
->GetTabNo();
890 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
895 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
896 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
900 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
903 aPos
.Y() += nSizeY
- 1;
905 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
906 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
907 pFilterBox
= new ScFilterListBox(
908 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
910 pFilterBox
->EnableMirroring();
915 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
916 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
918 nHeight
= GetTextHeight();
919 nHeight
*= SC_FILTERLISTBOX_LINES
;
921 SetMapMode( aOldMode
);
927 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
928 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
929 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
933 TypedScStrCollection
aStrings( 128, 128 );
934 if ( bDataSelect
) // Auswahl-Liste
937 aStrings
.SetCaseSensitive( TRUE
);
938 pDoc
->GetDataEntries( nCol
, nRow
, nTab
, aStrings
);
939 if ( aStrings
.GetCount() == 0 )
944 //! wird der Titel ueberhaupt ausgewertet ???
946 pDoc
->GetString( nCol
, nRow
, nTab
, aString
);
947 pFilterBox
->SetText( aString
);
952 static const USHORT nDefIDs
[] = { SCSTR_ALLFILTER
, SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_EMPTY
, SCSTR_NOTEMPTY
};
953 const USHORT nDefCount
= sizeof(nDefIDs
) / sizeof(USHORT
);
954 for (i
=0; i
<nDefCount
; i
++)
956 String
aEntry( (ScResId
) nDefIDs
[i
] );
957 pFilterBox
->InsertEntry( aEntry
);
958 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
959 if ( nTextWidth
> nMaxText
)
960 nMaxText
= nTextWidth
;
962 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
965 bool bHasDates
= false;
966 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
967 pFilterBox
->SetListHasDates(bHasDates
);
969 // check widths of numerical entries (string entries are not included)
970 // so all numbers are completely visible
971 USHORT nCount
= aStrings
.GetCount();
972 for (i
=0; i
<nCount
; i
++)
974 TypedStrData
* pData
= aStrings
[i
];
975 if ( !pData
->IsStrData() ) // only numerical entries
977 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
978 if ( nTextWidth
> nMaxText
)
979 nMaxText
= nTextWidth
;
983 // add scrollbar width if needed (string entries are counted here)
984 // (scrollbar is shown if the box is exactly full?)
985 if ( nCount
+ nDefCount
>= SC_FILTERLISTBOX_LINES
)
986 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
988 nMaxText
+= 4; // for borders
990 if ( nMaxText
> nSizeX
)
991 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
996 // Position und Groesse an Fenster anpassen
997 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
999 Size aParentSize
= GetParent()->GetOutputSizePixel();
1000 Size
aSize( nSizeX
, nHeight
);
1002 if ( aSize
.Height() > aParentSize
.Height() )
1003 aSize
.Height() = aParentSize
.Height();
1004 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1005 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1007 pFilterBox
->SetSizePixel( aSize
);
1008 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1009 pFilterBox
->SetUpdateMode(FALSE
);
1011 pFilterFloat
->SetOutputSizePixel( aSize
);
1012 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1015 USHORT nCount
= aStrings
.GetCount();
1016 BOOL bWait
= ( nCount
> 100 );
1021 for (i
=0; i
<nCount
; i
++)
1022 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
1027 pFilterBox
->SetUpdateMode(TRUE
);
1030 //! SvLBoxEntry* pSelect = NULL;
1031 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1033 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1035 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1038 ScQueryParam aParam
;
1039 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1042 for (SCSIZE j
=0; j
<MAXQUERY
&& bValid
; j
++) // bisherige Filter-Einstellungen
1043 if (aParam
.GetEntry(j
).bDoQuery
)
1045 //! Abfrage mit DrawButtons zusammenfassen!
1047 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1049 if (rEntry
.eConnect
!= SC_AND
)
1051 if (rEntry
.nField
== nCol
)
1053 if (rEntry
.eOp
== SC_EQUAL
)
1055 String
* pStr
= rEntry
.pStr
;
1058 nSelPos
= pFilterBox
->GetEntryPos( *pStr
);
1059 //! pSelect = pFilterBox->GetEntry( nPos );
1062 else if (rEntry
.eOp
== SC_TOPVAL
&& rEntry
.pStr
&&
1063 rEntry
.pStr
->EqualsAscii("10"))
1064 nSelPos
= SC_AUTOFILTER_TOP10
;
1066 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1071 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1077 ULONG nIndex
= ((SfxUInt32Item
*)pDoc
->GetAttr(
1078 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1081 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1084 TypedStrData
* pNew
= NULL
;
1086 pDoc
->GetString( nCol
, nRow
, nTab
, aDocStr
);
1087 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1089 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1090 pNew
= new TypedStrData( aDocStr
, fVal
, SC_STRTYPE_VALUE
);
1093 pNew
= new TypedStrData( aDocStr
, 0.0, SC_STRTYPE_STANDARD
);
1095 bool bSortList
= ( pData
->GetListType() == ValidListType::SORTEDASCENDING
);
1099 if (aStrings
.Search(pNew
,nStrIndex
))
1100 nSelPos
= nStrIndex
;
1104 USHORT nCount
= aStrings
.GetCount();
1105 for (i
= 0; ((i
< nCount
) && ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
)); i
++)
1107 if ( aStrings
.Compare(aStrings
[i
], pNew
)==0 )
1116 // neu (309): irgendwas muss immer selektiert sein:
1117 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1120 // keine leere Auswahl-Liste anzeigen:
1124 DELETEZ(pFilterBox
); // war nix
1125 DELETEZ(pFilterFloat
);
1126 Sound::Beep(); // bemerkbar machen
1130 // pFilterBox->Show(); // schon vorne
1131 pFilterBox
->GrabFocus();
1133 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1134 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1135 pFilterBox
->SelectEntryPos( nSelPos
);
1139 pFilterBox
->SetNoSelection();
1142 pFilterBox
->EndInit();
1146 // AutoFilter (aus MouseButtonDown):
1147 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1149 nMouseStatus
= SC_GM_FILTER
;
1155 void ScGridWindow::FilterSelect( ULONG nSel
)
1159 SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
1162 SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
1164 aString = pStringEntry->GetText();
1167 aString
= pFilterBox
->GetEntry( static_cast< USHORT
>( nSel
) );
1169 SCCOL nCol
= pFilterBox
->GetCol();
1170 SCROW nRow
= pFilterBox
->GetRow();
1171 switch ( pFilterBox
->GetMode() )
1173 case SC_FILTERBOX_DATASELECT
:
1174 ExecDataSelect( nCol
, nRow
, aString
);
1176 case SC_FILTERBOX_FILTER
:
1177 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1179 case SC_FILTERBOX_SCENARIO
:
1180 pViewData
->GetView()->UseScenario( aString
);
1182 case SC_FILTERBOX_PAGEFIELD
:
1183 // first entry is "all"
1184 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1189 pFilterFloat
->EndPopupMode();
1191 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1194 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const String
& rStr
)
1198 SCTAB nTab
= pViewData
->GetTabNo();
1199 ScViewFunc
* pView
= pViewData
->GetView();
1200 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1202 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1203 // if the cursor is moved afterwards.
1204 pView
->CellContentChanged();
1208 void ScGridWindow::ExecFilter( ULONG nSel
,
1209 SCCOL nCol
, SCROW nRow
,
1210 const String
& aValue
, bool bCheckForDates
)
1212 SCTAB nTab
= pViewData
->GetTabNo();
1213 ScDocument
* pDoc
= pViewData
->GetDocument();
1215 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1218 ScQueryParam aParam
;
1219 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1221 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1228 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1229 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1230 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1231 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1235 BOOL bDeleteOld
= FALSE
;
1236 SCSIZE nQueryPos
= 0;
1237 BOOL bFound
= FALSE
;
1238 if (!aParam
.bInplace
)
1242 for (SCSIZE i
=0; i
<MAXQUERY
&& !bDeleteOld
; i
++) // bisherige Filter-Einstellungen
1243 if (aParam
.GetEntry(i
).bDoQuery
)
1245 //! Abfrage mit DrawButtons zusammenfassen!
1247 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1249 if (rEntry
.eConnect
!= SC_AND
)
1252 if (rEntry
.nField
== nCol
)
1254 if (bFound
) // diese Spalte zweimal?
1265 SCSIZE nEC
= aParam
.GetEntryCount();
1266 for (SCSIZE i
=0; i
<nEC
; i
++)
1267 aParam
.GetEntry(i
).Clear();
1269 aParam
.bInplace
= TRUE
;
1270 aParam
.bRegExp
= FALSE
;
1273 if ( nQueryPos
< MAXQUERY
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1277 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1279 rNewEntry
.bDoQuery
= TRUE
;
1280 rNewEntry
.bQueryByString
= TRUE
;
1281 rNewEntry
.nField
= nCol
;
1282 rNewEntry
.bQueryByDate
= bCheckForDates
;
1283 if ( nSel
== SC_AUTOFILTER_TOP10
)
1285 rNewEntry
.eOp
= SC_TOPVAL
;
1286 *rNewEntry
.pStr
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
1288 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1290 rNewEntry
.pStr
->Erase();
1291 rNewEntry
.bQueryByString
= FALSE
;
1292 rNewEntry
.eOp
= SC_EQUAL
;
1293 rNewEntry
.nVal
= SC_EMPTYFIELDS
;
1296 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1298 rNewEntry
.pStr
->Erase();
1299 rNewEntry
.bQueryByString
= FALSE
;
1300 rNewEntry
.eOp
= SC_EQUAL
;
1301 rNewEntry
.nVal
= SC_NONEMPTYFIELDS
;
1305 rNewEntry
.eOp
= SC_EQUAL
;
1306 *rNewEntry
.pStr
= aValue
;
1309 rNewEntry
.eConnect
= SC_AND
;
1314 aParam
.DeleteQuery(nQueryPos
);
1317 // #100597# end edit mode - like in ScCellShell::ExecuteDB
1318 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1320 SC_MOD()->InputEnterHandler();
1321 pViewData
->GetViewShell()->UpdateInputHandler();
1324 aParam
.bUseDynamicRange
= true;
1325 pViewData
->GetView()->Query( aParam
, NULL
, TRUE
);
1326 pDBData
->SetQueryParam( aParam
); // speichern
1328 else // "Zuviele Bedingungen"
1329 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1334 DBG_ERROR("Wo ist der Datenbankbereich?");
1338 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1340 nCurrentPointer
= 0;
1341 Window::SetPointer( rPointer
);
1344 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1348 rDestWin
.nButtonDown
= nButtonDown
;
1349 rDestWin
.nMouseStatus
= nMouseStatus
;
1354 rDestWin
.bRFMouse
= bRFMouse
;
1355 rDestWin
.bRFSize
= bRFSize
;
1356 rDestWin
.nRFIndex
= nRFIndex
;
1357 rDestWin
.nRFAddX
= nRFAddX
;
1358 rDestWin
.nRFAddY
= nRFAddY
;
1362 if (nPagebreakMouse
)
1364 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1365 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1366 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1367 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1368 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1369 nPagebreakMouse
= SC_PD_NONE
;
1373 BOOL
ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, BOOL bAction
)
1375 // MouseEvent buttons must only be checked if bAction==TRUE
1376 // to allow changing the mouse pointer in MouseMove,
1377 // but not start AutoFill with right button (#74229#).
1378 // with bAction==TRUE, SetFillMode / SetDragMode is called
1380 if ( bAction
&& !rMEvt
.IsLeft() )
1383 BOOL bNewPointer
= FALSE
;
1385 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1386 BOOL bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1388 if ( pViewData
->IsActive() && !bOleActive
)
1390 ScDocument
* pDoc
= pViewData
->GetDocument();
1391 SCTAB nTab
= pViewData
->GetTabNo();
1392 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1393 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1398 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1400 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1402 Point aMousePos
= rMEvt
.GetPosPixel();
1403 if (mpAutoFillRect
->IsInside(aMousePos
))
1405 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1408 SCCOL nX
= aMarkRange
.aEnd
.Col();
1409 SCROW nY
= aMarkRange
.aEnd
.Row();
1411 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1412 pViewData
->SetDragMode(
1413 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1415 pViewData
->SetFillMode(
1416 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1418 // #108266# The simple selection must also be recognized when dragging,
1419 // where the Marking flag is set and MarkToSimple won't work anymore.
1420 pViewData
->GetMarkData().MarkToSimple();
1427 // Embedded-Rechteck
1429 if (pDoc
->IsEmbedded())
1432 pDoc
->GetEmbedded( aRange
);
1433 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1435 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1436 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1437 Point aMousePos
= rMEvt
.GetPosPixel();
1443 BOOL bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1444 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1445 BOOL bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1446 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1447 if ( bTop
|| bBottom
)
1449 SetPointer( Pointer( POINTER_CROSS
) );
1452 BYTE nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1453 pViewData
->SetDragMode(
1454 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1455 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1463 if (!bNewPointer
&& bAction
)
1465 // SetPointer( POINTER_ARROW ); // in Fu...
1466 pViewData
->ResetFillMode();
1472 void __EXPORT
ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1474 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1476 HandleMouseButtonDown( rMEvt
);
1478 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1480 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1481 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1482 // simulate another MouseButtonUp call, so the selection state is consistent.
1484 nButtonDown
= rMEvt
.GetButtons();
1488 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1490 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1493 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
)
1495 // We have to check if a context menu is shown and we have an UI
1496 // active inplace client. In that case we have to ignore the event.
1497 // Otherwise we would crash (context menu has been
1498 // opened by inplace client and we would deactivate the inplace client,
1499 // the contex menu is closed by VCL asynchronously which in the end
1500 // would work on deleted objects or the context menu has no parent anymore)
1501 // See #126086# and #128122#
1502 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1503 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1505 pClient
->IsObjectInPlaceActive() &&
1506 PopupMenu::IsInExecute() )
1509 aCurMousePos
= rMEvt
.GetPosPixel();
1511 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1512 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1514 // merken, dass FilterBox geloescht wird, damit sichergestellt
1515 // ist, dass in diesem Handler nicht an gleicher Stelle wieder
1516 // eine neue geoeffnet wird.
1517 BOOL bWasFilterBox
= ( pFilterBox
!= NULL
&&
1518 ((Window
*)pFilterBox
)->IsVisible() &&
1519 !pFilterBox
->IsDataSelect() );
1520 SCCOL nOldColFBox
= bWasFilterBox
? pFilterBox
->GetCol() : 0;
1521 SCROW nOldRowFBox
= bWasFilterBox
? pFilterBox
->GetRow() : 0;
1523 #include "cellsuno.hxx"
1525 ClickExtern(); // loescht FilterBox, wenn vorhanden
1527 HideNoteMarker(); // Notiz-Anzeige
1531 ScModule
* pScMod
= SC_MOD();
1532 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1538 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1539 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1541 BOOL bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1542 BOOL bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1543 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1544 BOOL bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1545 BOOL bDouble
= (rMEvt
.GetClicks() == 2);
1547 // DeactivateIP passiert nur noch bei MarkListHasChanged
1549 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1550 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1552 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1553 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1555 // pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1556 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1559 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1560 // but a single (first) click is always valid
1561 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1564 nMouseStatus
= SC_GM_NONE
;
1568 if ( bDetective
) // Detektiv-Fuell-Modus
1570 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1572 Point aPos
= rMEvt
.GetPosPixel();
1575 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1577 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1578 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1579 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1580 &aPosXItem
, &aPosYItem
, (void*)0L );
1584 nMouseStatus
= SC_GM_NONE
;
1589 nMouseStatus
= SC_GM_NONE
;
1593 if ( pViewData
->GetActivePart() != eWhich
)
1594 pViewData
->GetView()->ActivatePart( eWhich
);
1598 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1599 pSelEng
->SetWindow(this);
1600 pSelEng
->SetWhich(eWhich
);
1601 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1604 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1606 Point aPos
= rMEvt
.GetPosPixel();
1609 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1611 EditView
* pEditView
;
1614 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1615 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1616 SCROW nEndRow
= pViewData
->GetEditEndRow();
1618 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1619 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1621 // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
1622 if (bFormulaMode
) // sonst ist es oben schon passiert
1625 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1627 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1632 if (pScMod
->GetIsWaterCan())
1634 //! was is mit'm Mac ???
1635 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1637 nMouseStatus
= SC_GM_WATERUNDO
;
1642 // Reihenfolge passend zum angezeigten Cursor:
1643 // RangeFinder, AutoFill, PageBreak, Drawing
1645 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bRFSize
, &nRFIndex
, &nRFAddX
, &nRFAddY
) )
1647 bRFMouse
= TRUE
; // die anderen Variablen sind oben initialisiert
1649 if ( pViewData
->GetActivePart() != eWhich
)
1650 pViewData
->GetView()->ActivatePart( eWhich
); //! schon oben immer ???
1657 BOOL bCrossPointer
= TestMouse( rMEvt
, TRUE
);
1658 if ( bCrossPointer
)
1661 pViewData
->GetView()->FillCrossDblClick();
1663 pScMod
->InputEnterHandler(); // Autofill etc.
1666 if ( !bCrossPointer
)
1668 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1669 &nPagebreakBreak
, &nPagebreakPrev
);
1670 if (nPagebreakMouse
)
1672 bPagebreakDrawn
= FALSE
;
1675 PagebreakMove( rMEvt
, FALSE
);
1680 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1682 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1684 //if (DrawHasMarkedObj())
1685 // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert
1689 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // kein Draw-Objekt selektiert
1691 // TestMouse schon oben passiert
1694 Point aPos
= rMEvt
.GetPosPixel();
1697 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1698 SCTAB nTab
= pViewData
->GetTabNo();
1699 ScDocument
* pDoc
= pViewData
->GetDocument();
1703 // AutoFilter buttons
1706 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1708 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1709 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1710 if (pAttr
->HasAutoFilter())
1712 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
1715 if (pAttr
->HasButton())
1717 DoPushButton( nPosX
, nPosY
, rMEvt
); // setzt evtl. bPivotMouse / bDPMouse
1721 // List Validity drop-down button
1723 if ( bListValButton
)
1725 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1726 if ( aButtonRect
.IsInside( aPos
) )
1728 DoAutoFilterMenue( aListValPos
.Col(), aListValPos
.Row(), TRUE
);
1730 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1738 // scenario selection
1742 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1744 DoScenarioMenue( aScenRange
);
1749 // Doppelklick angefangen ?
1752 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1754 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1756 if ( bDouble
&& !bCrossPointer
)
1758 if (nMouseStatus
== SC_GM_TABDOWN
)
1759 nMouseStatus
= SC_GM_DBLDOWN
;
1762 nMouseStatus
= SC_GM_TABDOWN
;
1766 // Links in Edit-Zellen
1769 BOOL bAlt
= rMEvt
.IsMod2();
1770 if ( !bAlt
&& rMEvt
.IsLeft() &&
1771 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1773 SetPointer( Pointer( POINTER_REFHAND
) );
1774 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1779 // Gridwin - SelectionEngine
1782 if ( rMEvt
.IsLeft() )
1784 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1785 pSelEng
->SetWindow(this);
1786 pSelEng
->SetWhich(eWhich
);
1787 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1789 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1790 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1792 if (IsMouseCaptured())
1794 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1795 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1799 pViewData
->GetMarkData().SetMarking(TRUE
);
1805 void __EXPORT
ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1807 aCurMousePos
= rMEvt
.GetPosPixel();
1808 ScDocument
* pDoc
= pViewData
->GetDocument();
1809 ScMarkData
& rMark
= pViewData
->GetMarkData();
1811 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1812 // (possible through Reschedule from storing an OLE object that is deselected)
1814 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
1815 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
1817 if (nButtonDown
!= rMEvt
.GetButtons())
1818 nMouseStatus
= SC_GM_IGNORE
; // reset und return
1822 if (nMouseStatus
== SC_GM_IGNORE
)
1824 nMouseStatus
= SC_GM_NONE
;
1825 // Selection-Engine: Markieren abbrechen
1826 pViewData
->GetView()->GetSelEngine()->Reset();
1827 rMark
.SetMarking(FALSE
);
1828 if (pViewData
->IsAnyFillMode())
1830 pViewData
->GetView()->StopRefMode();
1831 pViewData
->ResetFillMode();
1834 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1839 if (nMouseStatus
== SC_GM_FILTER
)
1841 if ( pFilterBox
&& pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
1843 if (mpFilterButton
.get())
1845 bool bFilterActive
= IsAutoFilterActive(
1846 pFilterBox
->GetCol(), pFilterBox
->GetRow(), pViewData
->GetTabNo() );
1848 mpFilterButton
->setHasHiddenMember(bFilterActive
);
1849 mpFilterButton
->setPopupPressed(false);
1851 mpFilterButton
->draw();
1855 nMouseStatus
= SC_GM_NONE
;
1857 return; // da muss nix mehr passieren
1860 ScModule
* pScMod
= SC_MOD();
1861 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1864 SfxBindings
& rBindings
= pViewData
->GetBindings();
1865 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
1867 EditView
* pEditView
;
1870 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1871 pEditView
->MouseButtonUp( rMEvt
);
1873 if ( rMEvt
.IsMiddle() &&
1874 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1876 // EditView may have pasted from selection
1877 pScMod
->InputChanged( pEditView
);
1880 pScMod
->InputSelection( pEditView
); // parentheses etc.
1882 pViewData
->GetView()->InvalidateAttribs();
1883 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
1890 DPMouseButtonUp( rMEvt
); // resets bDPMouse
1896 RFMouseMove( rMEvt
, TRUE
); // Range wieder richtigherum
1898 SetPointer( Pointer( POINTER_ARROW
) );
1903 if (nPagebreakMouse
)
1905 PagebreakMove( rMEvt
, TRUE
);
1906 nPagebreakMouse
= SC_PD_NONE
;
1907 SetPointer( Pointer( POINTER_ARROW
) );
1912 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
1914 SfxUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
1915 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
1922 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
1925 rMark
.SetMarking(FALSE
);
1927 SetPointer( Pointer( POINTER_ARROW
) );
1929 if (pViewData
->IsFillMode() ||
1930 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
1932 nScFillModeMouseModifier
= rMEvt
.GetModifier();
1937 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1938 // DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
1939 // "Block falsch fuer AutoFill" );
1941 BOOL bIsDel
= pViewData
->GetDelMark( aDelRange
);
1943 ScViewFunc
* pView
= pViewData
->GetView();
1944 pView
->StopRefMode();
1945 pViewData
->ResetFillMode();
1946 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
); // #i5819# don't use AutoFill anchor flag for selection
1950 pView
->MarkRange( aDelRange
, FALSE
);
1951 pView
->DeleteContents( IDF_CONTENTS
);
1952 SCTAB nTab
= pViewData
->GetTabNo();
1953 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1954 if ( aBlockRange
!= aDelRange
)
1956 if ( aDelRange
.aStart
.Row() == nStartRow
)
1957 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
1959 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
1960 pView
->MarkRange( aBlockRange
, FALSE
);
1964 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1966 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
1968 SCTAB nTab
= pViewData
->GetTabNo();
1973 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1974 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1975 SCCOL nFillCol
= pViewData
->GetRefEndX();
1976 SCROW nFillRow
= pViewData
->GetRefEndY();
1977 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
1979 ScTabView
* pView
= pViewData
->GetView();
1980 pView
->StopRefMode();
1981 pViewData
->ResetFillMode();
1982 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
1984 if ( aEndPos
!= aBlockRange
.aEnd
)
1986 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, FALSE
);
1987 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
1990 else if (pViewData
->IsAnyFillMode())
1992 // Embedded-Area has been changed
1993 ScTabView
* pView
= pViewData
->GetView();
1994 pView
->StopRefMode();
1995 pViewData
->ResetFillMode();
1996 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
1997 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2000 BOOL bRefMode
= pViewData
->IsRefMode();
2002 pScMod
->EndReference();
2005 // Giesskannen-Modus (Gestalter)
2008 if (pScMod
->GetIsWaterCan())
2010 // Abfrage auf Undo schon oben
2012 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
2013 (pViewData
->GetDocument()->
2014 GetStyleSheetPool());
2017 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
2018 pStylePool
->GetActualStyleSheet();
2022 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2026 case SFX_STYLE_FAMILY_PARA
:
2027 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2028 pViewData
->GetView()->DoneBlockMode();
2031 case SFX_STYLE_FAMILY_PAGE
:
2032 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2033 pStyleSheet
->GetName() );
2035 ScPrintFunc( pViewData
->GetDocShell(),
2036 pViewData
->GetViewShell()->GetPrinter(TRUE
),
2037 pViewData
->GetTabNo() ).UpdatePages();
2039 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2049 ScDBFunc
* pView
= pViewData
->GetView();
2050 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2053 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2054 if ( !pView
->IsPaintBrushLocked() )
2055 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2059 // double click (only left button)
2062 BOOL bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2063 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2066 Point aPos
= rMEvt
.GetPosPixel();
2069 SCTAB nTab
= pViewData
->GetTabNo();
2070 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2071 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2072 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2074 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2076 // Check for header drill-down first.
2077 sheet::DataPilotTableHeaderData aData
;
2078 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2080 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2081 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2084 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2086 // execute slot to show dialog
2087 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2091 // toggle single entry
2092 ScDPObject
aNewObj( *pDPObj
);
2093 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2094 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2095 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
2096 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2101 // Check if the data area is double-clicked.
2103 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2104 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2105 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2107 Sound::Beep(); // nothing to expand/collapse/show
2113 // Check for cell protection attribute.
2114 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2115 bool bEditAllowed
= true;
2116 if ( pProtect
&& pProtect
->isProtected() )
2118 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2119 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2120 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2122 if ( bSkipProtected
&& bSkipUnprotected
)
2123 bEditAllowed
= false;
2124 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2125 bEditAllowed
= false;
2130 // edit cell contents
2131 pViewData
->GetViewShell()->UpdateInputHandler();
2132 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2133 if (pViewData
->HasEditView(eWhich
))
2135 // Text-Cursor gleich an die geklickte Stelle setzen
2136 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2137 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2138 pEditView
->MouseButtonDown( aEditEvt
);
2139 pEditView
->MouseButtonUp( aEditEvt
);
2146 // Links in edit cells
2149 BOOL bAlt
= rMEvt
.IsMod2();
2150 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2152 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2154 String aName
, aUrl
, aTarget
;
2155 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2157 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2158 ScGlobal::OpenURL( aUrl
, aTarget
);
2160 // fire worksheet_followhyperlink event
2161 Point aPos
= rMEvt
.GetPosPixel();
2164 SCTAB nTab
= pViewData
->GetTabNo();
2165 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2166 ScBaseCell
* pCell
= NULL
;
2168 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
2171 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2172 ScCellObj
* pObj
= new ScCellObj( pViewData
->GetDocShell(), aCellPos
);
2173 uno::Sequence
< uno::Any
> aArgs(1);
2174 aArgs
[0] = uno::makeAny(uno::Reference
<uno::XInterface
>(static_cast<cppu::OWeakObject
*>(pObj
)));
2175 uno::Reference
< document::XVbaEventsHelper
> xVbaEventsHelper ( pViewData
->GetDocument()->GetVbaEventsHelper(), uno::UNO_QUERY
);
2176 if( xVbaEventsHelper
.is() )
2177 xVbaEventsHelper
->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2184 // Gridwin - SelectionEngine
2187 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2188 // TRUE for any call, so IsLeft must be checked here, too.
2190 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2192 // rMark.MarkToSimple();
2193 pViewData
->GetView()->UpdateAutoFillMark();
2195 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2196 BOOL bFormulaMode
= pScMod
->IsFormulaMode();
2197 DBG_ASSERT( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2199 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2200 // multiple selection, so the argument string completely describes the selection,
2201 // and executing the slot won't change the existing selection (executing the slot
2202 // here and from a recorded macro is treated equally)
2204 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2206 String aAddr
; // CurrentCell
2207 if( rMark
.IsMarked() )
2209 // BOOL bKeep = rMark.IsMultiMarked(); //! wohin damit ???
2212 rMark
.GetMarkArea( aScRange
);
2213 aScRange
.Format( aAddr
, SCR_ABS
);
2214 if ( aScRange
.aStart
== aScRange
.aEnd
)
2216 // make sure there is a range selection string even for a single cell
2217 String aSingle
= aAddr
;
2218 aAddr
.Append( (sal_Char
) ':' );
2219 aAddr
.Append( aSingle
);
2222 //! SID_MARKAREA gibts nicht mehr ???
2223 //! was passiert beim Markieren mit dem Cursor ???
2225 else // nur Cursor bewegen
2227 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2228 aScAddress
.Format( aAddr
, SCA_ABS
);
2231 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2232 // We don't want to align to the cursor position because if the
2233 // cell cursor isn't visible after making selection, it would jump
2234 // back to the origin of the selection where the cell cursor is.
2235 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2236 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2237 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2239 pViewData
->GetView()->InvalidateAttribs();
2245 void ScGridWindow::FakeButtonUp()
2249 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2250 MouseButtonUp( aEvent
);
2254 void __EXPORT
ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2256 aCurMousePos
= rMEvt
.GetPosPixel();
2258 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2261 ScModule
* pScMod
= SC_MOD();
2262 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2265 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2266 // nicht anders mit:
2268 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2272 nMouseStatus
= SC_GM_NONE
;
2276 if (nMouseStatus
== SC_GM_IGNORE
)
2279 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2282 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2284 SetPointer( Pointer( POINTER_FILL
) );
2288 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2290 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2291 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2294 nMouseStatus
= SC_GM_NONE
;
2295 if ( pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
2297 if (mpFilterButton
.get())
2299 mpFilterButton
->setHasHiddenMember(false);
2300 mpFilterButton
->setPopupPressed(false);
2302 mpFilterButton
->draw();
2307 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2312 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2314 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2316 EditView
* pEditView
;
2319 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2320 pEditView
->MouseMove( rMEvt
);
2326 DPMouseMove( rMEvt
);
2332 RFMouseMove( rMEvt
, FALSE
);
2336 if (nPagebreakMouse
)
2338 PagebreakMove( rMEvt
, FALSE
);
2342 // anderen Mauszeiger anzeigen?
2344 BOOL bEditMode
= pViewData
->HasEditView(eWhich
);
2346 //! Testen ob RefMode-Dragging !!!
2347 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2349 Point aPos
= rMEvt
.GetPosPixel();
2352 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2354 EditView
* pEditView
;
2357 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2358 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2359 SCROW nEndRow
= pViewData
->GetEditEndRow();
2361 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2362 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2364 // Field can only be URL field
2365 BOOL bAlt
= rMEvt
.IsMod2();
2366 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2367 SetPointer( Pointer( POINTER_REFHAND
) );
2368 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2369 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2371 SetPointer( Pointer( POINTER_TEXT
) );
2376 BOOL bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2378 SetPointer( Pointer(POINTER_FILL
) );
2382 BOOL bCross
= FALSE
;
2387 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bCorner
) )
2390 SetPointer( Pointer( POINTER_CROSS
) );
2392 SetPointer( Pointer( POINTER_HAND
) );
2399 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2400 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2402 PointerStyle eNew
= POINTER_ARROW
;
2403 switch ( nBreakType
)
2408 eNew
= POINTER_ESIZE
;
2413 eNew
= POINTER_SSIZE
;
2415 case SC_PD_RANGE_TL
:
2416 case SC_PD_RANGE_BR
:
2417 eNew
= POINTER_SESIZE
;
2419 case SC_PD_RANGE_TR
:
2420 case SC_PD_RANGE_BL
:
2421 eNew
= POINTER_NESIZE
;
2424 SetPointer( Pointer( eNew
) );
2428 // Fill-Cursor anzeigen ?
2430 if ( !bFormulaMode
&& !nButtonDown
)
2431 if (TestMouse( rMEvt
, FALSE
))
2434 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2436 SetPointer( Pointer( POINTER_CROSS
) );
2438 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2443 BOOL bAlt
= rMEvt
.IsMod2();
2445 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2446 SetPointer( Pointer( POINTER_ARROW
) );
2447 else if ( !bAlt
&& !nButtonDown
&&
2448 GetEditUrl(rMEvt
.GetPosPixel()) )
2449 SetPointer( Pointer( POINTER_REFHAND
) );
2450 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2455 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2459 void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2461 rEvent
.Modifiers
= 0;
2462 if ( rEvt
.IsShift() )
2463 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2464 if ( rEvt
.IsMod1() )
2465 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2466 if ( rEvt
.IsMod2() )
2467 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2468 if ( rEvt
.IsMod3() )
2469 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD3
;
2472 if ( rEvt
.IsLeft() )
2473 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2474 if ( rEvt
.IsRight() )
2475 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2476 if ( rEvt
.IsMiddle() )
2477 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2479 rEvent
.X
= rEvt
.GetPosPixel().X();
2480 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2481 rEvent
.ClickCount
= rEvt
.GetClicks();
2482 rEvent
.PopupTrigger
= sal_False
;
2485 long ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2487 USHORT nType
= rNEvt
.GetType();
2488 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2490 Window
* pWindow
= rNEvt
.GetWindow();
2491 if (pWindow
== this && pViewData
)
2493 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2496 SfxFrame
* pFrame
= pViewFrame
->GetFrame();
2499 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pFrame
->GetController();
2500 if (xController
.is())
2502 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2503 if (pImp
&& pImp
->IsMouseListening())
2505 ::com::sun::star::awt::MouseEvent aEvent
;
2506 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2507 if ( rNEvt
.GetWindow() )
2508 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2509 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2510 pImp
->MousePressed( aEvent
);
2512 pImp
->MouseReleased( aEvent
);
2520 return Window::PreNotify( rNEvt
);
2523 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2525 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2526 // die verschiedenen MouseHandler verteilen...
2528 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2530 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2532 if (!pViewData
->GetView()->IsInActivatePart())
2535 bDPMouse
= FALSE
; // gezeichnet wird per bDragRect
2538 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2540 UpdateDragRectOverlay();
2544 RFMouseMove( rMEvt
, TRUE
); // richtig abbrechen geht dabei nicht...
2547 if (nPagebreakMouse
)
2549 // if (bPagebreakDrawn)
2550 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2551 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
2552 bPagebreakDrawn
= FALSE
;
2553 UpdateDragRectOverlay();
2554 nPagebreakMouse
= SC_PD_NONE
;
2557 SetPointer( Pointer( POINTER_ARROW
) );
2559 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2561 BOOL bRefMode
= pViewData
->IsRefMode();
2563 SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen
2566 else if ( rTEvt
.IsTrackingEnded() )
2568 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2569 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2570 // abgebrochen wurde.
2572 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2573 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2574 MouseButtonUp( aUpEvt
);
2580 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2582 if ( pFilterBox
|| nPagebreakMouse
)
2587 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, TRUE
);
2589 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2591 EditView
* pEditView
;
2594 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2596 // #63263# don't remove the edit view while switching views
2597 ScModule
* pScMod
= SC_MOD();
2598 pScMod
->SetInEditCommand( TRUE
);
2600 pEditView
->Command( aDragEvent
);
2602 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2604 pHdl
->DataChanged();
2606 pScMod
->SetInEditCommand( FALSE
);
2607 if (!pViewData
->IsActive()) // dropped to different view?
2609 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2610 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2612 pViewHdl
->CancelHandler();
2613 ShowCursor(); // missing from KillEditView
2618 if ( !DrawCommand(aDragEvent
) )
2619 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2622 void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2624 SCCOL nCol
= pViewData
->GetCurX();
2625 SCROW nRow
= pViewData
->GetCurY();
2626 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, TRUE
);
2627 aEditArea
.Right() = aEditArea
.Left();
2628 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2629 pWin
->SetCursorRect( &aEditArea
);
2632 void __EXPORT
ScGridWindow::Command( const CommandEvent
& rCEvt
)
2634 // The command event is send to the window after a possible context
2635 // menu from an inplace client is closed. Now we have the chance to
2636 // deactivate the inplace client without any problem regarding parent
2637 // windows and code on the stack.
2638 // For more information, see #126086# and #128122#
2639 USHORT nCmd
= rCEvt
.GetCommand();
2640 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2641 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2643 pClient
->IsObjectInPlaceActive() &&
2644 nCmd
== COMMAND_CONTEXTMENU
)
2646 pTabViewSh
->DeactivateOle();
2650 ScModule
* pScMod
= SC_MOD();
2651 DBG_ASSERT( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2653 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2654 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2655 nCmd
== COMMAND_EXTTEXTINPUT
||
2656 nCmd
== COMMAND_CURSORPOS
)
2658 BOOL bEditView
= pViewData
->HasEditView( eWhich
);
2661 // only if no cell editview is active, look at drawview
2662 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2665 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2666 if ( pOlView
&& pOlView
->GetWindow() == this )
2668 pOlView
->Command( rCEvt
);
2674 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2676 // #88458# CURSORPOS may be called without following text input,
2677 // to set the input method window position
2678 // -> input mode must not be started,
2679 // manually calculate text insert position if not in input mode
2681 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2685 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2688 pHdl
->InputCommand( rCEvt
, TRUE
);
2692 Window::Command( rCEvt
);
2696 if ( nCmd
== COMMAND_VOICE
)
2698 // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
2699 // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
2701 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2702 if ( pHdl
&& pViewData
->HasEditView( eWhich
) )
2704 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2705 pHdl
->DataChanging();
2706 pEditView
->Command( rCEvt
);
2707 pHdl
->DataChanged();
2710 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2713 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2714 if ( pOlView
&& pOlView
->GetWindow() == this )
2716 pOlView
->Command( rCEvt
);
2720 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
2724 if ( nCmd
== COMMAND_PASTESELECTION
)
2728 // EditEngine handles selection in MouseButtonUp - no action
2729 // needed in command handler
2733 PasteSelection( rCEvt
.GetMousePosPixel() );
2738 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2740 // #i55929# Font and font size state depends on input language if nothing is selected,
2741 // so the slots have to be invalidated when the input language is changed.
2743 SfxBindings
& rBindings
= pViewData
->GetBindings();
2744 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2745 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2749 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2751 BOOL bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2753 Window::Command(rCEvt
);
2756 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2757 BOOL bDisable
= pScMod
->IsFormulaMode() ||
2758 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2762 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2764 if (pViewData
->IsAnyFillMode())
2766 pViewData
->GetView()->StopRefMode();
2767 pViewData
->ResetFillMode();
2772 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2773 Point aMenuPos
= aPosPixel
;
2774 BOOL bMouse
= rCEvt
.IsMouseEvent();
2780 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2781 ScDocument
* pDoc
= pViewData
->GetDocument();
2782 SCTAB nTab
= pViewData
->GetTabNo();
2783 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
2784 bool bSelectAllowed
= true;
2785 if ( pProtect
&& pProtect
->isProtected() )
2787 // This sheet is protected. Check if a context menu is allowed on this cell.
2788 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
2789 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2790 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2793 bSelectAllowed
= bSelProtected
;
2795 bSelectAllowed
= bSelUnprotected
;
2797 if (!bSelectAllowed
)
2798 // Selecting this cell is not allowed, neither is context menu.
2801 // #i18735# First select the item under the mouse pointer.
2802 // This can change the selection, and the view state (edit mode, etc).
2803 SelectForContextMenu( aPosPixel
, nCellX
, nCellY
);
2807 BOOL bEdit
= pViewData
->HasEditView(eWhich
);
2810 // Edit-Zelle mit Spelling-Errors ?
2811 if ( bMouse
&& GetEditUrlOrError( TRUE
, aPosPixel
) )
2813 // GetEditUrlOrError hat den Cursor schon bewegt
2815 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2816 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
2818 DBG_ASSERT( bEdit
, "kann nicht in Edit-Modus schalten" );
2823 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2827 Cursor
* pCur
= pEditView
->GetCursor();
2830 Point aLogicPos
= pCur
->GetPos();
2831 // use the position right of the cursor (spell popup is opened if
2832 // the cursor is before the word, but not if behind it)
2833 aLogicPos
.X() += pCur
->GetWidth();
2834 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
2835 aMenuPos
= LogicToPixel( aLogicPos
);
2839 // if edit mode was just started above, online spelling may be incomplete
2840 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
2842 // IsCursorAtWrongSpelledWord could be used for !bMouse
2843 // if there was a corresponding ExecuteSpellPopup call
2845 if( pEditView
->IsWrongSpelledWordAtPos( aMenuPos
) )
2847 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2848 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2850 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2852 pHdl
->SetModified();
2854 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
2855 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
2862 // non-edit menu by keyboard -> use lower right of cell cursor position
2864 SCCOL nCurX
= pViewData
->GetCurX();
2865 SCROW nCurY
= pViewData
->GetCurY();
2866 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, TRUE
);
2869 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
2870 aMenuPos
.X() += nSizeXPix
;
2871 aMenuPos
.Y() += nSizeYPix
;
2875 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
2878 // Is a draw object selected?
2880 SdrView
* pDrawView
= pViewSh
->GetSdrView();
2881 if (pDrawView
&& pDrawView
->AreObjectsMarked())
2883 // #100442#; the conext menu should open in the middle of the selected objects
2884 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
2885 aMenuPos
= aSelectRect
.Center();
2893 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
2898 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
2900 // #i18735# if the click was outside of the current selection,
2901 // the cursor is moved or an object at the click position selected.
2902 // (see SwEditWin::SelectMenuPosition in Writer)
2904 ScTabView
* pView
= pViewData
->GetView();
2905 ScDrawView
* pDrawView
= pView
->GetScDrawView();
2907 // check cell edit mode
2909 if ( pViewData
->HasEditView(eWhich
) )
2911 ScModule
* pScMod
= SC_MOD();
2912 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
2913 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
2914 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
2915 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
2917 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
2918 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
2920 // handle selection within the EditView
2922 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
2923 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
2924 Rectangle aOutputArea
= pEditView
->GetOutputArea();
2925 Rectangle aVisArea
= pEditView
->GetVisArea();
2927 Point aTextPos
= PixelToLogic( rPosPixel
);
2928 if ( pEditEngine
->IsVertical() ) // have to manually transform position
2930 aTextPos
-= aOutputArea
.TopRight();
2931 long nTemp
= -aTextPos
.X();
2932 aTextPos
.X() = aTextPos
.Y();
2933 aTextPos
.Y() = nTemp
;
2936 aTextPos
-= aOutputArea
.TopLeft();
2937 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2939 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
2940 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2941 ESelection aSelection
= pEditView
->GetSelection();
2942 aSelection
.Adjust(); // needed for IsLess/IsGreater
2943 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2945 // clicked outside the selected text - deselect and move text cursor
2946 MouseEvent
aEvent( rPosPixel
);
2947 pEditView
->MouseButtonDown( aEvent
);
2948 pEditView
->MouseButtonUp( aEvent
);
2949 pScMod
->InputSelection( pEditView
);
2952 return; // clicked within the edit view - keep edit mode
2956 // outside of the edit view - end edit mode, regardless of cell selection, then continue
2957 pScMod
->InputEnterHandler();
2961 // check draw text edit mode
2963 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
2964 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
2966 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
2967 Rectangle aOutputArea
= pOlView
->GetOutputArea();
2968 if ( aOutputArea
.IsInside( aLogicPos
) )
2970 // handle selection within the OutlinerView
2972 Outliner
* pOutliner
= pOlView
->GetOutliner();
2973 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
2974 Rectangle aVisArea
= pOlView
->GetVisArea();
2976 Point aTextPos
= aLogicPos
;
2977 if ( pOutliner
->IsVertical() ) // have to manually transform position
2979 aTextPos
-= aOutputArea
.TopRight();
2980 long nTemp
= -aTextPos
.X();
2981 aTextPos
.X() = aTextPos
.Y();
2982 aTextPos
.Y() = nTemp
;
2985 aTextPos
-= aOutputArea
.TopLeft();
2986 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2988 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
2989 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2990 ESelection aSelection
= pOlView
->GetSelection();
2991 aSelection
.Adjust(); // needed for IsLess/IsGreater
2992 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2994 // clicked outside the selected text - deselect and move text cursor
2995 // use DrawView to allow extra handling there (none currently)
2996 MouseEvent
aEvent( rPosPixel
);
2997 pDrawView
->MouseButtonDown( aEvent
, this );
2998 pDrawView
->MouseButtonUp( aEvent
, this );
3001 return; // clicked within the edit area - keep edit mode
3005 // Outside of the edit area - end text edit mode, then continue.
3006 // DrawDeselectAll also ends text edit mode and updates the shells.
3007 // If the click was on the edited object, it will be selected again below.
3008 pView
->DrawDeselectAll();
3012 // look for existing selection
3014 BOOL bHitSelected
= FALSE
;
3015 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3017 // clicked on selected object -> don't change anything
3018 bHitSelected
= TRUE
;
3020 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3022 // clicked on selected cell -> don't change anything
3023 bHitSelected
= TRUE
;
3026 // select drawing object or move cell cursor
3028 if ( !bHitSelected
)
3030 BOOL bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3031 BOOL bHitDraw
= FALSE
;
3034 pDrawView
->UnmarkAllObj();
3035 // Unlock the Internal Layer in order to activate the context menu.
3036 // re-lock in ScDrawView::MarkListHasChanged()
3037 lcl_UnLockComment( pDrawView
, pDrawView
->GetSdrPageView(), pDrawView
->GetModel(), aLogicPos
,pViewData
);
3038 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3039 // draw shell is activated in MarkListHasChanged
3044 pView
->SetCursor(nCellX
, nCellY
);
3046 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // switch shells
3051 static void ClearSingleSelection( ScViewData
* pViewData
)
3055 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard(
3056 pViewData
->GetActiveWin() );
3060 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
3061 pClipDoc
->GetClipArea( nX
, nY
, TRUE
);
3062 if (nX
== 0 && nY
== 0)
3064 ScTabView
* pView
= pViewData
->GetView();
3069 void __EXPORT
ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3071 // #96965# Cursor control for ref input dialog
3072 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3073 if( SC_MOD()->IsRefDialogOpen() )
3075 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3077 SC_MOD()->EndReference();
3080 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3083 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3084 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3085 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3089 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3091 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3093 ScCellShell::PasteFromClipboard( pViewData
, pTabViewShell
, FALSE
);
3094 ClearSingleSelection( pViewData
);
3096 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3097 TransferableHelper::GetSystemClipboard();
3098 if (xSystemClipboard
.is())
3100 xSystemClipboard
->setContents(
3101 uno::Reference
<datatransfer::XTransferable
>(),
3102 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3105 // hide the border around the copy source
3106 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3107 UpdateCursorOverlay();
3110 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3111 else if( !pViewData
->IsAnyFillMode() )
3113 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3115 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3116 UpdateCursorOverlay();
3118 // query for existing note marker before calling ViewShell's keyboard handling
3119 // which may remove the marker
3120 BOOL bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3121 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3123 if (pViewData
->GetDocShell()->GetProgress())
3126 if (DrawKeyInput(rKEvt
))
3129 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3130 { //! DrawShell abfragen !!!
3131 if (pViewSh
->TabKeyInput(rKEvt
))
3135 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3138 KeyCode aCode
= rKEvt
.GetKeyCode();
3139 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3141 if ( bHadKeyMarker
)
3147 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3149 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3150 // (hard-coded because F1 can't be configured)
3152 if ( bHadKeyMarker
)
3153 HideNoteMarker(); // hide when previously visible
3155 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), TRUE
);
3158 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3160 pViewSh
->DetectiveMarkPred();
3163 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3165 pViewSh
->DetectiveMarkSucc();
3171 Window::KeyInput(rKEvt
);
3174 void ScGridWindow::StopMarking()
3176 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3180 pViewData
->GetMarkData().SetMarking(FALSE
);
3181 nMouseStatus
= SC_GM_IGNORE
;
3185 void ScGridWindow::UpdateInputContext()
3187 BOOL bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3188 ULONG nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3190 // when font from InputContext is used,
3191 // it must be taken from the cursor position's cell attributes
3193 InputContext aContext
;
3194 aContext
.SetOptions( nOptions
);
3195 SetInputContext( aContext
);
3198 //--------------------------------------------------------
3200 // sensitiver Bereich (Pixel)
3201 #define SCROLL_SENSITIVE 20
3203 BOOL
ScGridWindow::DropScroll( const Point
& rMousePos
)
3205 /* doch auch auf nicht aktiven Views...
3206 if ( !pViewData->IsActive() )
3211 Size aSize
= GetOutputSizePixel();
3213 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3215 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3217 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3218 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3221 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3223 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3225 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3226 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3230 if ( nDx
!= 0 || nDy
!= 0 )
3233 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3236 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3238 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3241 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3247 BOOL
lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3249 // Testet, ob bei eingeschalteten RedLining,
3250 // bei einem Drop ein Scenario betroffen ist.
3252 BOOL bReturn
= FALSE
;
3253 SCTAB nTab
= aDragRange
.aStart
.Tab();
3254 SCTAB nTabCount
= pDoc
->GetTableCount();
3256 if(pDoc
->GetChangeTrack()!=NULL
)
3258 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3264 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3266 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3277 ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3279 SCCOL nCol1
= nPosX
;
3280 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3281 if ( nCol2
> MAXCOL
)
3283 nCol1
-= nCol2
- MAXCOL
;
3286 SCROW nRow1
= nPosY
;
3287 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3288 if ( nRow2
> MAXROW
)
3290 nRow1
-= nRow2
- MAXROW
;
3294 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3297 //--------------------------------------------------------
3299 extern BOOL bPasteIsDrop
; // viewfun4 -> move to header
3300 extern BOOL bPasteIsMove
; // viewfun7 -> move to header
3302 //--------------------------------------------------------
3304 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3306 if ( rEvt
.mbLeaving
)
3309 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3311 UpdateDragRectOverlay();
3312 return rEvt
.mnAction
;
3315 const ScDragData
& rData
= SC_MOD()->GetDragData();
3316 if ( rData
.pCellTransfer
)
3318 // Don't move source that would include filtered rows.
3319 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3324 UpdateDragRectOverlay();
3326 return DND_ACTION_NONE
;
3329 Point aPos
= rEvt
.maPosPixel
;
3331 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3332 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3333 if (pSourceDoc
== pThisDoc
)
3335 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
)) )
3337 if (bDragRect
) // Rechteck loeschen
3339 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3341 UpdateDragRectOverlay();
3344 //! highlight chart? (selection border?)
3346 sal_Int8 nRet
= rEvt
.mnAction
;
3347 //! if ( rEvt.GetAction() == DROP_LINK )
3348 //! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart
3353 //! if ( rEvt.GetAction() == DROP_MOVE )
3354 //! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY
3357 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3359 BOOL bOk
= pThisDoc
->IsDocEditable();
3360 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3365 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3367 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3368 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3369 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3370 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3371 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3372 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3373 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3375 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3376 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3378 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3379 if (nNewDragX
<0) nNewDragX
=0;
3380 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3381 nNewDragX
= MAXCOL
-(nSizeX
-1);
3382 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3383 if (nNewDragY
<0) nNewDragY
=0;
3384 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3385 nNewDragY
= MAXROW
-(nSizeY
-1);
3387 // don't break scenario ranges, don't drop on filtered
3388 SCTAB nTab
= pViewData
->GetTabNo();
3389 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3390 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3391 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3392 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3396 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3398 UpdateDragRectOverlay();
3400 return DND_ACTION_NONE
;
3403 InsCellCmd eDragInsertMode
= INS_NONE
;
3404 Window::PointerState aState
= GetPointerState();
3406 // check for datapilot item sorting
3407 ScDPObject
* pDPObj
= NULL
;
3408 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3410 // drop on DataPilot table: sort or nothing
3412 bool bDPSort
= false;
3413 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3415 sheet::DataPilotTableHeaderData aDestData
;
3416 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3417 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3419 // look through the source range
3420 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3421 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3423 sheet::DataPilotTableHeaderData aSourceData
;
3424 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3425 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| !aSourceData
.MemberName
.getLength() )
3426 bValid
= false; // empty (subtotal) or different field
3432 String aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3433 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3436 ScRange aOutRange
= pDPObj
->GetOutRange();
3438 USHORT nOrient
= pDim
->GetOrientation();
3439 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3441 eDragInsertMode
= INS_CELLSRIGHT
;
3442 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3445 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3447 eDragInsertMode
= INS_CELLSDOWN
;
3448 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3457 // no valid sorting in a DataPilot table -> disallow
3461 UpdateDragRectOverlay();
3463 return DND_ACTION_NONE
;
3466 else if ( aState
.mnState
& KEY_MOD2
)
3468 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3470 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3471 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3472 if ( nDeltaX
<= nDeltaY
)
3474 eDragInsertMode
= INS_CELLSDOWN
;
3478 eDragInsertMode
= INS_CELLSRIGHT
;
3481 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3482 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3483 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3484 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3485 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3486 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3491 UpdateDragRectOverlay();
3493 return DND_ACTION_NONE
;
3498 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3500 eDragInsertMode
= INS_CELLSDOWN
;
3505 eDragInsertMode
= INS_CELLSRIGHT
;
3510 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3511 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3512 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3515 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3517 nDragStartX
= nNewDragX
;
3518 nDragStartY
= nNewDragY
;
3519 nDragEndX
= nDragStartX
+nSizeX
-1;
3520 nDragEndY
= nDragStartY
+nSizeY
-1;
3522 meDragInsertMode
= eDragInsertMode
;
3524 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3526 UpdateDragRectOverlay();
3528 // show target position as tip help
3530 if (Help::IsQuickHelpEnabled())
3532 ScRange
aRange( nDragStartX
, nDragStartY
, nTab
, nDragEndX
, nDragEndY
, nTab
);
3534 aRange
.Format( aHelpStr
, SCA_VALID
); // non-3D
3536 Point aPos
= Pointer::GetPosPixel();
3537 USHORT nAlign
= QUICKHELP_BOTTOM
|QUICKHELP_RIGHT
;
3538 Rectangle
aRect( aPos
, aPos
);
3539 Help::ShowQuickHelp(aRect
, aHelpStr
, nAlign
);
3545 return rEvt
.mnAction
;
3548 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3550 const ScDragData
& rData
= SC_MOD()->GetDragData();
3551 if ( rEvt
.mbLeaving
)
3553 DrawMarkDropObj( NULL
);
3554 if ( rData
.pCellTransfer
)
3555 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3557 return rEvt
.mnAction
;
3560 if ( pViewData
->GetDocShell()->IsReadOnly() )
3561 return DND_ACTION_NONE
;
3564 sal_Int8 nRet
= DND_ACTION_NONE
;
3566 if (rData
.pCellTransfer
)
3568 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3569 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3570 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3571 DropScroll( rEvt
.maPosPixel
);
3573 nRet
= AcceptPrivateDrop( rEvt
);
3577 if ( rData
.aLinkDoc
.Len() )
3580 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3581 if (pDocSh
&& pDocSh
->HasName())
3582 aThisName
= pDocSh
->GetMedium()->GetName();
3584 if ( rData
.aLinkDoc
!= aThisName
)
3585 nRet
= rEvt
.mnAction
;
3587 else if (rData
.aJumpTarget
.Len())
3589 // internal bookmarks (from Navigator)
3590 // local jumps from an unnamed document are possible only within a document
3592 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3593 nRet
= rEvt
.mnAction
;
3597 sal_Int8 nMyAction
= rEvt
.mnAction
;
3599 if ( !rData
.pDrawTransfer
||
3600 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3601 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3602 nMyAction
= DND_ACTION_COPY
;
3604 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3605 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3606 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3607 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
&& !rData
.pDrawTransfer
)
3609 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3610 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3611 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3613 // graphic dragged onto drawing object
3614 DrawMarkDropObj( pHitObj
);
3619 DrawMarkDropObj( NULL
);
3623 switch ( nMyAction
)
3625 case DND_ACTION_COPY
:
3626 case DND_ACTION_MOVE
:
3627 case DND_ACTION_COPYMOVE
:
3629 BOOL bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3630 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3631 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3632 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3633 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3634 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3635 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3636 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3637 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3638 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3639 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3640 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3641 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3642 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3643 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3644 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3645 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3646 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3647 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3649 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3650 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3651 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3652 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3653 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3654 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3660 case DND_ACTION_LINK
:
3661 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3662 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3663 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3664 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3665 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3666 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3667 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3668 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3669 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3678 // Simple check for protection: It's not known here if the drop will result
3679 // in cells or drawing objects (some formats can be both) and how many cells
3680 // the result will be. But if IsFormatEditable for the drop cell position
3681 // is FALSE (ignores matrix formulas), nothing can be pasted, so the drop
3682 // can already be rejected here.
3684 Point aPos
= rEvt
.maPosPixel
;
3687 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3688 SCTAB nTab
= pViewData
->GetTabNo();
3689 ScDocument
* pDoc
= pViewData
->GetDocument();
3691 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3692 if ( !aTester
.IsFormatEditable() )
3693 nRet
= DND_ACTION_NONE
; // forbidden
3698 // scroll only for accepted formats
3700 DropScroll( rEvt
.maPosPixel
);
3706 ULONG
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3708 TransferableDataHelper
aDataHelper( xTransfer
);
3710 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3712 // use bookmark formats if no sba is present
3714 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3715 return SOT_FORMATSTR_ID_SOLK
;
3716 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3717 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3718 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3719 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3720 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3721 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3724 ULONG nFormatId
= 0;
3725 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3726 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3727 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3728 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3729 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3731 // If it's a Writer object, insert RTF instead of OLE
3733 BOOL bDoRtf
= FALSE
;
3734 SotStorageStreamRef xStm
;
3735 TransferableObjectDescriptor aObjDesc
;
3736 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3737 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3739 SotStorageRef
xStore( new SotStorage( *xStm
) );
3740 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3741 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3742 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3745 nFormatId
= FORMAT_RTF
;
3747 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3749 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3750 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3751 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3752 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3753 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3754 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3755 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3756 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3757 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3758 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3759 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3760 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3761 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3762 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3763 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3764 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3765 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3766 nFormatId
= SOT_FORMAT_RTF
;
3767 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3768 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3769 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3770 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3771 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3772 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3773 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3774 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3775 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3776 nFormatId
= SOT_FORMAT_STRING
;
3777 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3778 nFormatId
= SOT_FORMAT_FILE_LIST
;
3779 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3780 nFormatId
= SOT_FORMAT_FILE
;
3781 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3782 nFormatId
= SOT_FORMAT_STRING
;
3783 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3784 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3785 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3786 nFormatId
= SOT_FORMAT_BITMAP
;
3791 ULONG
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3793 TransferableDataHelper
aDataHelper( xTransfer
);
3795 ULONG nFormatId
= 0;
3796 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3797 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3798 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3799 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3800 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3801 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3802 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3803 nFormatId
= SOT_FORMAT_FILE_LIST
;
3804 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
3805 nFormatId
= SOT_FORMAT_FILE
;
3806 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3807 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
3808 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3809 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3810 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3811 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3812 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3813 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3819 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
3823 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3825 UpdateDragRectOverlay();
3827 ScModule
* pScMod
= SC_MOD();
3828 const ScDragData
& rData
= pScMod
->GetDragData();
3830 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
3831 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
3834 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
3835 const Point
& rLogicPos
, sal_Int8 nDndAction
)
3840 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
3841 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3842 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3843 ScViewFunc
* pView
= pViewData
->GetView();
3844 SCTAB nThisTab
= pViewData
->GetTabNo();
3845 USHORT nFlags
= pTransObj
->GetDragSourceFlags();
3847 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
3848 BOOL bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
3850 // workaround for wrong nDndAction on Windows when pressing solely
3851 // the Alt key during drag and drop;
3852 // can be removed after #i79215# has been fixed
3853 if ( meDragInsertMode
!= INS_NONE
)
3855 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
3858 BOOL bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
3860 ScRange aSource
= pTransObj
->GetRange();
3862 // only use visible tab from source range - when dragging within one table,
3863 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3864 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
3865 aSource
.aStart
.SetTab( nSourceTab
);
3866 aSource
.aEnd
.SetTab( nSourceTab
);
3868 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
3869 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
3870 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
3871 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
3872 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
3875 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3876 * dragging and adapted drawing of the selection frame. We check here
3877 * (again) because this may actually also be called from PasteSelection(),
3878 * we would have to duplicate determination of flags and destination range
3879 * and would lose the context of the "filtered destination is OK" cases
3880 * below, which is already awkward enough as is. */
3882 // Don't move filtered source.
3883 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
3886 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
3887 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
3889 // Nothing. Either entire sheet to be dropped, or the one case
3890 // where PasteFromClip() is to be called that handles a filtered
3891 // destination itself. Drag-copy from another document without
3895 // Don't copy or move to filtered destination.
3896 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
3901 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
3903 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
3905 if ( pThisDoc
->IsDocEditable() )
3907 SCTAB nSrcTab
= aSource
.aStart
.Tab();
3908 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, TRUE
); // with Undo
3909 pView
->SetTabNo( nThisTab
, TRUE
);
3913 else // move/copy block
3916 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, &aChartName
))
3919 aSource
.Format( aRangeName
, SCR_ABS_3D
, pThisDoc
);
3920 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
3921 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
3922 USHORT nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
3923 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
3924 &aRangeItem
, &aNameItem
, (void*) NULL
);
3927 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
3929 // drop on DataPilot table: try to sort, fail if that isn't possible
3931 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
3932 if ( aDestPos
!= aSource
.aStart
)
3933 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
3935 bDone
= TRUE
; // same position: nothing
3937 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
3938 nSourceTab
!= nThisTab
)
3940 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
3941 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
3944 if ( meDragInsertMode
!= INS_NONE
)
3946 // call with bApi = TRUE to avoid error messages in drop handler
3947 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
3950 if ( nThisTab
== nSourceTab
)
3952 if ( meDragInsertMode
== INS_CELLSDOWN
&&
3953 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
3955 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
3957 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
3958 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
3960 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
3963 pDocSh
->UpdateOle( pViewData
);
3964 pView
->CellContentChanged();
3972 // call with bApi = TRUE to avoid error messages in drop handler
3973 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, TRUE
/*bApi*/ );
3977 // call with bApi = TRUE to avoid error messages in drop handler
3978 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, TRUE
/*bRecord*/, TRUE
/*bPaint*/, TRUE
/*bApi*/ );
3982 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
3984 DelCellCmd eCmd
= DEL_NONE
;
3985 if ( meDragInsertMode
== INS_CELLSDOWN
)
3989 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
3991 eCmd
= DEL_CELLSLEFT
;
3994 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
3995 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
3997 // call with bApi = TRUE to avoid error messages in drop handler
3998 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, TRUE
/*bRecord*/, TRUE
/*bApi*/ );
4001 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4003 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4005 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4007 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4009 pDocSh
->UpdateOle( pViewData
);
4010 pView
->CellContentChanged();
4017 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4019 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col();
4020 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row();
4021 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4024 pDocSh
->GetUndoManager()->LeaveListAction();
4027 Sound::Beep(); // instead of error message in drop handler
4030 bDone
= TRUE
; // nothing to do
4034 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4036 else if ( !bFiltered
&& pSourceDoc
) // between documents
4038 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4040 if ( pThisDoc
->IsDocEditable() )
4042 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4044 SCTAB nTabs
[MAXTABCOUNT
];
4046 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4047 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4048 SCTAB nTabSelCount
= 0;
4050 for(SCTAB i
=0; i
<nTabCount
; i
++)
4052 if(aMark
.GetTableSelect(i
))
4054 nTabs
[nTabSelCount
++]=i
;
4055 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4057 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4059 nTabs
[nTabSelCount
++]=j
;
4067 pView
->ImportTables( pSrcShell
,nTabSelCount
, nTabs
, bIsLink
, nThisTab
);
4074 // (external references might be used instead?)
4076 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4077 DBG_ASSERT(pSourceSh
, "drag document has no shell");
4080 String aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4081 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4084 if ( meDragInsertMode
!= INS_NONE
)
4086 // call with bApi = TRUE to avoid error messages in drop handler
4087 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4090 pDocSh
->UpdateOle( pViewData
);
4091 pView
->CellContentChanged();
4097 String aApp
= Application::GetAppName();
4098 String aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4100 aSource
.Format( aItem
, SCA_VALID
| SCA_TAB_3D
, pSourceDoc
);
4102 // TODO: we could define ocQuote for "
4103 const String
aQuote( '"' );
4104 const String
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4105 String
aFormula( '=' );
4106 aFormula
+= ScCompiler::GetNativeSymbol( ocDde
);
4107 aFormula
+= ScCompiler::GetNativeSymbol( ocOpen
);
4119 aFormula
+= ScCompiler::GetNativeSymbol( ocClose
);
4121 pView
->DoneBlockMode();
4122 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4123 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4124 nDestPosY
+ nSizeY
- 1, nThisTab
);
4126 pView
->EnterMatrix( aFormula
);
4128 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4129 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4132 pDocSh
->GetUndoManager()->LeaveListAction();
4137 //! HasSelectedBlockMatrixFragment without selected sheet?
4138 //! or don't start dragging on a part of a matrix
4140 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4141 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4144 if ( meDragInsertMode
!= INS_NONE
)
4146 // call with bApi = TRUE to avoid error messages in drop handler
4147 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4150 pDocSh
->UpdateOle( pViewData
);
4151 pView
->CellContentChanged();
4157 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4158 pView
->SetCursor( nDestPosX
, nDestPosY
);
4159 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4162 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4163 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4167 pDocSh
->GetUndoManager()->LeaveListAction();
4169 // no longer call ResetMark here - the inserted block has been selected
4170 // and may have been copied to primary selection
4174 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4178 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4180 DrawMarkDropObj( NULL
); // drawing layer
4182 ScModule
* pScMod
= SC_MOD();
4183 const ScDragData
& rData
= pScMod
->GetDragData();
4184 if (rData
.pCellTransfer
)
4185 return ExecutePrivateDrop( rEvt
);
4187 Point aPos
= rEvt
.maPosPixel
;
4189 if ( rData
.aLinkDoc
.Len() )
4191 // try to insert a link
4195 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4196 if (pDocSh
&& pDocSh
->HasName())
4197 aThisName
= pDocSh
->GetMedium()->GetName();
4199 if ( rData
.aLinkDoc
== aThisName
) // error - no link within a document
4203 ScViewFunc
* pView
= pViewData
->GetView();
4204 if ( rData
.aLinkTable
.Len() )
4205 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4207 else if ( rData
.aLinkArea
.Len() )
4211 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4212 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, FALSE
, FALSE
);
4214 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4215 rData
.aLinkArea
, 0 );
4219 DBG_ERROR("drop with link: no sheet nor area");
4224 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4227 Point aLogicPos
= PixelToLogic(aPos
);
4229 if (rData
.pDrawTransfer
)
4231 USHORT nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4233 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4234 BOOL bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4236 bPasteIsMove
= bIsMove
;
4238 pViewData
->GetView()->PasteDraw( aLogicPos
, rData
.pDrawTransfer
->GetModel() );
4241 rData
.pDrawTransfer
->SetDragWasInternal();
4242 bPasteIsMove
= FALSE
;
4244 return rEvt
.mnAction
;
4250 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4252 if (rData
.aJumpTarget
.Len())
4254 // internal bookmark (from Navigator)
4255 // bookmark clipboard formats are in PasteScDataObject
4257 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4259 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4261 return rEvt
.mnAction
;
4265 BOOL bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4267 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4268 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4269 if ( pHitObj
&& bIsLink
)
4271 // dropped on drawing object
4272 // PasteOnDrawObject checks for valid formats
4273 if ( pViewData
->GetView()->PasteOnDrawObject( rEvt
.maDropEvent
.Transferable
, pHitObj
, TRUE
) )
4274 return rEvt
.mnAction
;
4279 ULONG nFormatId
= bIsLink
?
4280 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4281 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4284 pScMod
->SetInExecuteDrop( TRUE
); // #i28468# prevent error messages from PasteDataFormat
4285 bPasteIsDrop
= TRUE
;
4286 bDone
= pViewData
->GetView()->PasteDataFormat(
4287 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4288 bPasteIsDrop
= FALSE
;
4289 pScMod
->SetInExecuteDrop( FALSE
);
4292 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4296 //--------------------------------------------------------
4298 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4300 Point aLogicPos
= PixelToLogic( rPosPixel
);
4304 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4306 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4307 if ( pOwnSelection
)
4311 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4312 if ( pCellTransfer
)
4314 // keep a reference to the data in case the selection is changed during paste
4315 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4316 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4320 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4321 if ( pDrawTransfer
)
4323 // keep a reference to the data in case the selection is changed during paste
4324 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4326 // #96821# bSameDocClipboard argument for PasteDraw is needed
4327 // because only DragData is checked directly inside PasteDraw
4328 pViewData
->GetView()->PasteDraw( aLogicPos
, pDrawTransfer
->GetModel(), FALSE
,
4329 pDrawTransfer
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
4335 // get selection from system
4337 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4338 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4339 if ( xTransferable
.is() )
4341 ULONG nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4344 bPasteIsDrop
= TRUE
;
4345 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4346 bPasteIsDrop
= FALSE
;
4352 //--------------------------------------------------------
4354 void ScGridWindow::UpdateEditViewPos()
4356 if (pViewData
->HasEditView(eWhich
))
4361 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4362 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4363 SCROW nEndRow
= pViewData
->GetEditEndRow();
4367 BOOL bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4368 if ( SC_MOD()->IsFormulaMode() )
4369 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4374 Rectangle aRect
= pView
->GetOutputArea();
4375 long nHeight
= aRect
.Bottom() - aRect
.Top();
4376 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4378 aRect
.Bottom() = aRect
.Top() + nHeight
;
4379 pView
->SetOutputArea( aRect
);
4380 pView
->HideCursor();
4384 // bForceToTop = TRUE for editing
4385 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, TRUE
);
4386 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4388 Rectangle aRect
= pView
->GetOutputArea();
4389 aRect
.SetPos( aScrPos
);
4390 pView
->SetOutputArea( aRect
);
4391 pView
->ShowCursor();
4396 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4402 //BOOL bXor=DrawBeforeScroll();
4404 SetMapMode(MAP_PIXEL
);
4405 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4406 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4408 UpdateEditViewPos();
4410 DrawAfterScroll(); //bXor);
4411 bIsInScroll
= FALSE
;
4414 // Formeln neu zeichnen -------------------------------------------------
4416 void ScGridWindow::UpdateFormulas()
4418 if (pViewData
->GetView()->IsMinimized())
4423 // nicht anfangen, verschachtelt zu painten
4424 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4426 bNeedsRepaint
= TRUE
; // -> am Ende vom Paint nochmal Invalidate auf alles
4427 aRepaintPixel
= Rectangle(); // alles
4431 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4432 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4433 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4434 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4436 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4437 if (nY2
> MAXROW
) nY2
= MAXROW
;
4439 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4441 // don't draw directly - instead use OutputData to find changed area and invalidate
4445 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4446 ScDocument
* pDoc
= pDocSh
->GetDocument();
4447 SCTAB nTab
= pViewData
->GetTabNo();
4449 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4451 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4452 long nMirrorWidth
= GetSizePixel().Width();
4453 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4454 // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
4457 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4458 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4459 aScrPos
.X() = nEndPixel
+ 1;
4462 long nScrX
= aScrPos
.X();
4463 long nScrY
= aScrPos
.Y();
4465 double nPPTX
= pViewData
->GetPPTX();
4466 double nPPTY
= pViewData
->GetPPTY();
4468 ScTableInfo aTabInfo
;
4469 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, FALSE
, FALSE
);
4471 Fraction aZoomX
= pViewData
->GetZoomX();
4472 Fraction aZoomY
= pViewData
->GetZoomY();
4473 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4474 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4476 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4478 aOutputData
.FindChanged();
4480 PolyPolygon
aChangedPoly( aOutputData
.GetChangedArea() ); // logic (PixelToLogic)
4481 if ( aChangedPoly
.Count() )
4483 Invalidate( aChangedPoly
);
4486 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4489 void ScGridWindow::UpdateAutoFillMark(BOOL bMarked
, const ScRange
& rMarkRange
)
4491 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4494 bAutoMarkVisible
= bMarked
;
4496 aAutoMarkPos
= rMarkRange
.aEnd
;
4499 UpdateAutoFillOverlay();
4503 void ScGridWindow::UpdateListValPos( BOOL bVisible
, const ScAddress
& rPos
)
4505 BOOL bOldButton
= bListValButton
;
4506 ScAddress aOldPos
= aListValPos
;
4508 bListValButton
= bVisible
;
4511 if ( bListValButton
)
4513 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4515 // paint area of new button
4516 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4521 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4523 // paint area of old button
4524 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4529 void ScGridWindow::HideCursor()
4532 if (nCursorHideCount
==1)
4539 void ScGridWindow::ShowCursor()
4541 if (nCursorHideCount
==0)
4543 DBG_ERROR("zuviel ShowCursor");
4547 if (nCursorHideCount
==1)
4549 // #i57745# Draw the cursor before setting the variable, in case the
4550 // GetSizePixel call from drawing causes a repaint (resize handler is called)
4558 void __EXPORT
ScGridWindow::GetFocus()
4560 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4561 pViewShell
->GotFocus();
4562 pViewShell
->SetFormShellAtTop( FALSE
); // focus in GridWindow -> FormShell no longer on top
4564 if (pViewShell
->HasAccessibilityObjects())
4565 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4568 if ( !SC_MOD()->IsFormulaMode() )
4570 pViewShell
->UpdateInputHandler();
4571 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4572 // MO: nur wenn nicht im RefInput-Modus
4573 // -> GetFocus/MouseButtonDown-Reihenfolge
4580 void __EXPORT
ScGridWindow::LoseFocus()
4582 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4583 pViewShell
->LostFocus();
4585 if (pViewShell
->HasAccessibilityObjects())
4586 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4588 Window::LoseFocus();
4591 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4593 //------------------------------------------------------------------------
4595 BOOL
ScGridWindow::HitRangeFinder( const Point
& rMouse
, BOOL
& rCorner
,
4596 USHORT
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4598 BOOL bFound
= FALSE
;
4599 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4602 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4603 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4604 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4606 ScDocument
* pDoc
= pViewData
->GetDocument();
4607 SCTAB nTab
= pViewData
->GetTabNo();
4608 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4609 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4613 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4614 // zusammengefasste (einzeln/Bereich) ???
4615 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4617 // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
4619 Point aNext
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, TRUE
);
4622 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4623 aNext
.X() += nSizeXPix
* nLayoutSign
;
4624 aNext
.Y() += nSizeYPix
;
4628 bCornerHor
= ( rMouse
.X() >= aNext
.X() && rMouse
.X() <= aNext
.X() + 8 );
4630 bCornerHor
= ( rMouse
.X() >= aNext
.X() - 8 && rMouse
.X() <= aNext
.X() );
4632 BOOL bCellCorner
= ( bCornerHor
&&
4633 rMouse
.Y() >= aNext
.Y() - 8 && rMouse
.Y() <= aNext
.Y() );
4634 // corner is hit only if the mouse is within the cell
4636 USHORT nCount
= (USHORT
)pRangeFinder
->Count();
4637 for (USHORT i
=nCount
; i
;)
4639 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4641 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4642 if ( pData
&& pData
->aRef
.In(aAddr
) )
4644 if (pIndex
) *pIndex
= i
;
4645 if (pAddX
) *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4646 if (pAddY
) *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4648 rCorner
= ( bCellCorner
&& aAddr
== pData
->aRef
.aEnd
);
4658 #define SCE_BOTTOM 2
4663 void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, USHORT nEdges
)
4665 // der Range ist immer richtigherum
4667 SCCOL nCol1
= rRange
.aStart
.Col();
4668 SCROW nRow1
= rRange
.aStart
.Row();
4669 SCTAB nTab1
= rRange
.aStart
.Tab();
4670 SCCOL nCol2
= rRange
.aEnd
.Col();
4671 SCROW nRow2
= rRange
.aEnd
.Row();
4672 SCTAB nTab2
= rRange
.aEnd
.Tab();
4673 BOOL bHiddenEdge
= FALSE
;
4676 ScDocument
* pDoc
= pDocSh
->GetDocument();
4677 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4682 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4687 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4688 if (!ValidRow(nTmp
))
4695 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4696 if (!ValidRow(nTmp
))
4704 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4706 // nur an den Raendern entlang
4707 // (die Ecken werden evtl. zweimal getroffen)
4709 if ( nEdges
& SCE_TOP
)
4710 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4711 if ( nEdges
& SCE_LEFT
)
4712 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4713 if ( nEdges
& SCE_RIGHT
)
4714 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4715 if ( nEdges
& SCE_BOTTOM
)
4716 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4718 else // everything in one call
4719 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4722 void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4724 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4726 ScRange aOld
= rOldUn
;
4727 ScRange aNew
= rNewUn
;
4731 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4732 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4733 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4734 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4736 SCCOL nOldCol1
= aOld
.aStart
.Col();
4737 SCROW nOldRow1
= aOld
.aStart
.Row();
4738 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4739 SCROW nOldRow2
= aOld
.aEnd
.Row();
4740 SCCOL nNewCol1
= aNew
.aStart
.Col();
4741 SCROW nNewRow1
= aNew
.aStart
.Row();
4742 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4743 SCROW nNewRow2
= aNew
.aEnd
.Row();
4744 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4745 SCTAB nTab2
= aOld
.aEnd
.Tab();
4747 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4748 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4749 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4750 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4752 // komplett weggeschoben oder alle Seiten veraendert
4753 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4755 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4757 else // alle vier Kanten einzeln testen
4760 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4761 lcl_PaintOneRange( pDocSh
, ScRange(
4762 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4763 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4764 lcl_PaintOneRange( pDocSh
, ScRange(
4765 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4766 SCE_ALL
&~ SCE_BOTTOM
);
4769 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4770 lcl_PaintOneRange( pDocSh
, ScRange(
4771 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4772 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4773 lcl_PaintOneRange( pDocSh
, ScRange(
4774 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4775 SCE_ALL
&~ SCE_TOP
);
4778 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
4779 lcl_PaintOneRange( pDocSh
, ScRange(
4780 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
4781 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
4782 lcl_PaintOneRange( pDocSh
, ScRange(
4783 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
4784 SCE_ALL
&~ SCE_RIGHT
);
4787 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
4788 lcl_PaintOneRange( pDocSh
, ScRange(
4789 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4790 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
4791 lcl_PaintOneRange( pDocSh
, ScRange(
4792 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4793 SCE_ALL
&~ SCE_LEFT
);
4797 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, BOOL bUp
)
4799 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4802 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4803 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
4805 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
4812 SetPointer( Pointer( POINTER_CROSS
) );
4814 SetPointer( Pointer( POINTER_HAND
) );
4818 BOOL bTimer
= FALSE
;
4819 Point aPos
= rMEvt
.GetPosPixel();
4822 if ( aPos
.X() < 0 ) nDx
= -1;
4823 if ( aPos
.Y() < 0 ) nDy
= -1;
4824 Size aSize
= GetOutputSizePixel();
4825 if ( aPos
.X() >= aSize
.Width() )
4827 if ( aPos
.Y() >= aSize
.Height() )
4829 if ( nDx
!= 0 || nDy
!= 0 )
4831 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
4832 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
4836 // Umschalten bei Fixierung (damit Scrolling funktioniert)
4838 if ( eWhich
== pViewData
->GetActivePart() ) //??
4840 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
4843 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4844 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
4845 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
4846 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4849 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
4852 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4853 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
4854 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
4855 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4863 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4865 ScRange aOld
= pData
->aRef
;
4866 ScRange aNew
= aOld
;
4869 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
4870 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
4874 long nStartX
= nPosX
- nRFAddX
;
4875 if ( nStartX
< 0 ) nStartX
= 0;
4876 long nStartY
= nPosY
- nRFAddY
;
4877 if ( nStartY
< 0 ) nStartY
= 0;
4878 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
4879 if ( nEndX
> MAXCOL
)
4881 nStartX
-= ( nEndX
- MAXROW
);
4884 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
4885 if ( nEndY
> MAXROW
)
4887 nStartY
-= ( nEndY
- MAXROW
);
4891 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
4892 aNew
.aStart
.SetRow((SCROW
)nStartY
);
4893 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
4894 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
4898 aNew
.Justify(); // beim ButtonUp wieder richtigherum
4902 pHdl
->UpdateRange( nRFIndex
, aNew
);
4904 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4906 // nur das neuzeichnen, was sich veraendert hat...
4907 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
4909 // neuen Rahmen nur drueberzeichnen (synchron)
4910 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
4912 Update(); // was man bewegt, will man auch sofort sehen
4915 // Timer fuer Scrolling
4918 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
4920 pViewData
->GetView()->ResetTimer();
4923 //------------------------------------------------------------------------
4925 BOOL
ScGridWindow::GetEditUrl( const Point
& rPos
,
4926 String
* pName
, String
* pUrl
, String
* pTarget
)
4928 return GetEditUrlOrError( FALSE
, rPos
, pName
, pUrl
, pTarget
);
4931 BOOL
ScGridWindow::GetEditUrlOrError( BOOL bSpellErr
, const Point
& rPos
,
4932 String
* pName
, String
* pUrl
, String
* pTarget
)
4934 //! nPosX/Y mit uebergeben?
4937 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
4939 SCTAB nTab
= pViewData
->GetTabNo();
4940 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4941 ScDocument
* pDoc
= pDocSh
->GetDocument();
4942 ScBaseCell
* pCell
= NULL
;
4944 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
4948 ScHideTextCursor
aHideCursor( pViewData
, eWhich
); // before GetEditArea (MapMode is changed)
4950 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
4951 // bForceToTop = FALSE, use the cell's real position
4952 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, FALSE
);
4953 if (rPos
.Y() < aEditRect
.Top())
4956 // vertikal kann (noch) nicht angeklickt werden:
4958 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
4961 BOOL bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
4962 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
4963 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
4964 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
4965 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
4969 ScFieldEditEngine
aEngine( pDoc
->GetEditPool() );
4970 ScSizeDeviceProvider
aProv(pDocSh
);
4971 aEngine
.SetRefDevice( aProv
.GetDevice() );
4972 aEngine
.SetRefMapMode( MAP_100TH_MM
);
4973 SfxItemSet
aDefault( aEngine
.GetEmptyItemSet() );
4974 pPattern
->FillEditItemSet( &aDefault
);
4975 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
4978 case SVX_HOR_JUSTIFY_LEFT
:
4979 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
4980 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
4981 eSvxAdjust
= SVX_ADJUST_LEFT
;
4983 case SVX_HOR_JUSTIFY_RIGHT
:
4984 eSvxAdjust
= SVX_ADJUST_RIGHT
;
4986 case SVX_HOR_JUSTIFY_CENTER
:
4987 eSvxAdjust
= SVX_ADJUST_CENTER
;
4989 case SVX_HOR_JUSTIFY_BLOCK
:
4990 eSvxAdjust
= SVX_ADJUST_BLOCK
;
4993 aDefault
.Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
4994 aEngine
.SetDefaults( aDefault
);
4996 aEngine
.SetControlWord( aEngine
.GetControlWord() | EE_CNTRL_ONLINESPELLING
);
4998 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
4999 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5000 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5001 Size aPaperSize
= Size( 1000000, 1000000 );
5002 if(pCell
->GetCellType() == CELLTYPE_FORMULA
)
5006 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5007 aPaperSize
= Size(nSizeX
, nSizeY
);
5008 aPaperSize
= PixelToLogic(aPaperSize
);
5012 aPaperSize
.Width() = nThisColLogic
;
5013 aEngine
.SetPaperSize( aPaperSize
);
5015 ::std::auto_ptr
< EditTextObject
> pTextObj
;
5016 const EditTextObject
* pData
;
5017 if(pCell
->GetCellType() == CELLTYPE_EDIT
)
5019 ((ScEditCell
*)pCell
)->GetData(pData
);
5021 aEngine
.SetText(*pData
);
5023 else // HyperLink Formula cell
5025 pTextObj
.reset((static_cast<ScFormulaCell
*>(pCell
))->CreateURLObject());
5027 aEngine
.SetText(*pTextObj
);
5030 long nStartX
= aLogicEdit
.Left();
5032 long nTextWidth
= aEngine
.CalcTextWidth();
5033 long nTextHeight
= aEngine
.GetTextHeight();
5034 if ( nTextWidth
< nThisColLogic
)
5036 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5037 nStartX
+= nThisColLogic
- nTextWidth
;
5038 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5039 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5042 aLogicEdit
.Left() = nStartX
;
5044 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5046 // There is one glitch when dealing with a hyperlink cell and
5047 // the cell content is NUMERIC. This defaults to right aligned and
5048 // we need to adjust accordingly.
5049 if(pCell
->GetCellType() == CELLTYPE_FORMULA
&&
5050 static_cast<ScFormulaCell
*>(pCell
)->IsValue() &&
5051 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5053 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5054 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5056 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5059 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5060 if ( aLogicEdit
.IsInside(aLogicClick
) )
5062 // aEngine.SetUpdateMode(FALSE);
5063 EditView
aTempView( &aEngine
, this );
5064 aTempView
.SetOutputArea( aLogicEdit
);
5067 MapMode aOld
= GetMapMode();
5068 SetMapMode(aEditMode
); // kein return mehr
5070 if (bSpellErr
) // Spelling-Fehler suchen
5072 bRet
= aTempView
.IsWrongSpelledWordAtPos( rPos
);
5074 pViewData
->GetView()->SetCursor( nPosX
, nPosY
); // Cursor setzen
5078 const SvxFieldItem
* pFieldItem
= aTempView
.GetFieldUnderMousePointer();
5082 const SvxFieldData
* pField
= pFieldItem
->GetField();
5083 if ( pField
&& pField
->ISA(SvxURLField
) )
5085 if ( pName
|| pUrl
|| pTarget
)
5087 const SvxURLField
* pURLField
= (const SvxURLField
*)pField
;
5089 *pName
= pURLField
->GetRepresentation();
5091 *pUrl
= pURLField
->GetURL();
5093 *pTarget
= pURLField
->GetTargetFrame();
5102 // text cursor is restored in ScHideTextCursor dtor
5109 BOOL
ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5111 ScDocument
* pDoc
= pViewData
->GetDocument();
5112 SCTAB nTab
= pViewData
->GetTabNo();
5113 SCTAB nTabCount
= pDoc
->GetTableCount();
5114 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5116 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5118 Size aButSize
= pViewData
->GetScenButSize();
5119 long nBWidth
= aButSize
.Width();
5121 return FALSE
; // noch kein Button gezeichnet -> da ist auch keiner
5122 long nBHeight
= aButSize
.Height();
5123 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5125 //! Ranges an der Table cachen!!!!
5128 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5129 pDoc
->MarkScenario( i
, nTab
, aMarks
, FALSE
, SC_SCENARIO_SHOWFRAME
);
5130 ScRangeList aRanges
;
5131 aMarks
.FillRangeListWithMarks( &aRanges
, FALSE
);
5134 ULONG nRangeCount
= aRanges
.Count();
5135 for (ULONG j
=0; j
<nRangeCount
; j
++)
5137 ScRange aRange
= *aRanges
.GetObject(j
);
5138 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5139 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5140 pDoc
->ExtendTotalMerge( aRange
);
5142 BOOL bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5147 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5152 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5154 aButtonPos
.Y() -= nBHeight
;
5157 aButtonPos
.X() -= nHSpace
- 1;
5159 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5161 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5162 if ( aButRect
.IsInside( rPosPixel
) )
5164 rScenRange
= aRange
;
5174 void ScGridWindow::DrawLayerCreated()
5176 SetMapMode( GetDrawMapMode() );
5178 // initially create overlay objects
5179 ImpCreateOverlayObjects();
5183 void ScGridWindow::CursorChanged()
5185 // here the created OverlayObjects may be transformed in later versions. For
5186 // now, just re-create them
5188 UpdateCursorOverlay();
5192 void ScGridWindow::ImpCreateOverlayObjects()
5194 UpdateCursorOverlay();
5195 UpdateSelectionOverlay();
5196 UpdateAutoFillOverlay();
5197 UpdateDragRectOverlay();
5198 UpdateHeaderOverlay();
5199 UpdateShrinkOverlay();
5203 void ScGridWindow::ImpDestroyOverlayObjects()
5205 DeleteCursorOverlay();
5206 DeleteSelectionOverlay();
5207 DeleteAutoFillOverlay();
5208 DeleteDragRectOverlay();
5209 DeleteHeaderOverlay();
5210 DeleteShrinkOverlay();
5213 void ScGridWindow::UpdateAllOverlays()
5215 // delete and re-allocate all overlay objects
5217 ImpDestroyOverlayObjects();
5218 ImpCreateOverlayObjects();
5221 void ScGridWindow::DeleteCursorOverlay()
5223 DELETEZ( mpOOCursors
);
5226 void ScGridWindow::UpdateCursorOverlay()
5228 MapMode aDrawMode
= GetDrawMapMode();
5229 MapMode aOldMode
= GetMapMode();
5230 if ( aOldMode
!= aDrawMode
)
5231 SetMapMode( aDrawMode
);
5233 // Existing OverlayObjects may be transformed in later versions.
5234 // For now, just re-create them.
5236 DeleteCursorOverlay();
5238 std::vector
<Rectangle
> aPixelRects
;
5241 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5244 SCTAB nTab
= pViewData
->GetTabNo();
5245 SCCOL nX
= pViewData
->GetCurX();
5246 SCROW nY
= pViewData
->GetCurY();
5248 if (!maVisibleRange
.isInside(nX
, nY
))
5251 // don't show the cursor in overlapped cells
5253 ScDocument
* pDoc
= pViewData
->GetDocument();
5254 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5255 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5256 BOOL bOverlapped
= rMergeFlag
.IsOverlapped();
5258 // left or above of the screen?
5260 BOOL bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5265 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5266 if (rMerge
.GetColMerge() > 1)
5267 nEndX
+= rMerge
.GetColMerge()-1;
5268 if (rMerge
.GetRowMerge() > 1)
5269 nEndY
+= rMerge
.GetRowMerge()-1;
5270 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5273 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5275 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5276 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5278 // completely right of/below the screen?
5279 // (test with logical start position in aScrPos)
5282 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5285 Size aOutSize
= GetOutputSizePixel();
5286 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5288 if ( bMaybeVisible
)
5292 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5295 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5297 // Now, draw the cursor.
5301 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5303 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5304 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5305 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5306 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5310 if ( aPixelRects
.size() )
5312 // #i70788# get the OverlayManager safely
5313 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5317 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5318 if (pViewData
->GetActivePart() != eWhich
)
5319 // non-active pane uses a different color.
5320 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5321 std::vector
< basegfx::B2DRange
> aRanges
;
5322 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5324 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5326 const Rectangle
aRA(aPixelRects
[a
]);
5327 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5328 aRB
.transform(aTransform
);
5329 aRanges
.push_back(aRB
);
5332 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5333 sdr::overlay::OVERLAY_SOLID
,
5338 pOverlayManager
->add(*pOverlay
);
5339 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5340 mpOOCursors
->append(*pOverlay
);
5344 if ( aOldMode
!= aDrawMode
)
5345 SetMapMode( aOldMode
);
5348 void ScGridWindow::DeleteSelectionOverlay()
5350 DELETEZ( mpOOSelection
);
5353 void ScGridWindow::UpdateSelectionOverlay()
5355 MapMode aDrawMode
= GetDrawMapMode();
5356 MapMode aOldMode
= GetMapMode();
5357 if ( aOldMode
!= aDrawMode
)
5358 SetMapMode( aDrawMode
);
5360 DeleteSelectionOverlay();
5361 std::vector
<Rectangle
> aPixelRects
;
5362 GetSelectionRects( aPixelRects
);
5364 if ( aPixelRects
.size() && pViewData
->IsActive() )
5366 // #i70788# get the OverlayManager safely
5367 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5371 std::vector
< basegfx::B2DRange
> aRanges
;
5372 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5374 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5376 const Rectangle
aRA(aPixelRects
[a
]);
5377 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
5378 aRB
.transform(aTransform
);
5379 aRanges
.push_back(aRB
);
5382 // #i97672# get the system's hilight color and limit it to the maximum
5383 // allowed luminance. This is needed to react on too bright hilight colors
5384 // which would otherwise vive a bad visualisation
5385 Color
aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
5386 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
5387 const basegfx::BColor
aSelection(aHighlight
.getBColor());
5388 const double fLuminance(aSelection
.luminance());
5389 const double fMaxLum(aSvtOptionsDrawinglayer
.GetSelectionMaximumLuminancePercent() / 100.0);
5391 if(fLuminance
> fMaxLum
)
5393 const double fFactor(fMaxLum
/ fLuminance
);
5394 const basegfx::BColor
aNewSelection(
5395 aSelection
.getRed() * fFactor
,
5396 aSelection
.getGreen() * fFactor
,
5397 aSelection
.getBlue() * fFactor
);
5399 aHighlight
= Color(aNewSelection
);
5402 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5403 sdr::overlay::OVERLAY_TRANSPARENT
,
5408 pOverlayManager
->add(*pOverlay
);
5409 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5410 mpOOSelection
->append(*pOverlay
);
5414 if ( aOldMode
!= aDrawMode
)
5415 SetMapMode( aOldMode
);
5418 void ScGridWindow::DeleteAutoFillOverlay()
5420 DELETEZ( mpOOAutoFill
);
5421 mpAutoFillRect
.reset();
5424 void ScGridWindow::UpdateAutoFillOverlay()
5426 MapMode aDrawMode
= GetDrawMapMode();
5427 MapMode aOldMode
= GetMapMode();
5428 if ( aOldMode
!= aDrawMode
)
5429 SetMapMode( aDrawMode
);
5431 DeleteAutoFillOverlay();
5434 // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
5437 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5438 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5440 SCCOL nX
= aAutoMarkPos
.Col();
5441 SCROW nY
= aAutoMarkPos
.Row();
5443 if (!maVisibleRange
.isInside(nX
, nY
))
5444 // Autofill mark is not visible. Bail out.
5447 SCTAB nTab
= pViewData
->GetTabNo();
5448 ScDocument
* pDoc
= pViewData
->GetDocument();
5449 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5451 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5454 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5456 aFillPos
.X() -= nSizeXPix
+ 3;
5458 aFillPos
.X() += nSizeXPix
- 2;
5460 aFillPos
.Y() += nSizeYPix
;
5462 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
5464 // #i70788# get the OverlayManager safely
5465 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5469 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5470 if (pViewData
->GetActivePart() != eWhich
)
5471 // non-active pane uses a different color.
5472 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5473 std::vector
< basegfx::B2DRange
> aRanges
;
5474 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5475 basegfx::B2DRange
aRB(mpAutoFillRect
->Left(), mpAutoFillRect
->Top(), mpAutoFillRect
->Right() + 1, mpAutoFillRect
->Bottom() + 1);
5477 aRB
.transform(aTransform
);
5478 aRanges
.push_back(aRB
);
5480 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5481 sdr::overlay::OVERLAY_SOLID
,
5486 pOverlayManager
->add(*pOverlay
);
5487 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
5488 mpOOAutoFill
->append(*pOverlay
);
5491 if ( aOldMode
!= aDrawMode
)
5492 SetMapMode( aOldMode
);
5496 void ScGridWindow::DeleteDragRectOverlay()
5498 DELETEZ( mpOODragRect
);
5501 void ScGridWindow::UpdateDragRectOverlay()
5503 MapMode aDrawMode
= GetDrawMapMode();
5504 MapMode aOldMode
= GetMapMode();
5505 if ( aOldMode
!= aDrawMode
)
5506 SetMapMode( aDrawMode
);
5508 DeleteDragRectOverlay();
5511 // get the rectangles in pixels (moved from DrawDragRect)
5514 if ( bDragRect
|| bPagebreakDrawn
)
5516 std::vector
<Rectangle
> aPixelRects
;
5518 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
5519 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
5520 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
5521 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
5523 SCTAB nTab
= pViewData
->GetTabNo();
5525 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
5526 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
5527 if (nX1
< nPosX
) nX1
= nPosX
;
5528 if (nX2
< nPosX
) nX2
= nPosX
;
5529 if (nY1
< nPosY
) nY1
= nPosY
;
5530 if (nY2
< nPosY
) nY2
= nPosY
;
5532 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
5536 ScDocument
* pDoc
= pViewData
->GetDocument();
5537 double nPPTX
= pViewData
->GetPPTX();
5538 double nPPTY
= pViewData
->GetPPTY();
5541 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5542 long nLayoutSign
= bLayoutRTL
? -1 : 1;
5544 if (ValidCol(nX2
) && nX2
>=nX1
)
5545 for (i
=nX1
; i
<=nX2
; i
++)
5546 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
5549 aScrPos
.X() -= nLayoutSign
;
5553 if (ValidRow(nY2
) && nY2
>=nY1
)
5554 for (i
=nY1
; i
<=nY2
; i
++)
5555 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
5562 aScrPos
.X() -= 2 * nLayoutSign
;
5564 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5565 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
5566 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
5569 aRect
.Left() = aRect
.Right(); // end position is left
5570 aRect
.Right() = aScrPos
.X();
5573 if ( meDragInsertMode
== INS_CELLSDOWN
)
5575 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
5576 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
5577 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
5578 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5580 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
5582 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
5583 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5584 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
5585 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
5589 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
5590 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
5591 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
5592 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
5595 // #i70788# get the OverlayManager safely
5596 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5600 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5601 std::vector
< basegfx::B2DRange
> aRanges
;
5602 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5604 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5606 const Rectangle
aRA(aPixelRects
[a
]);
5607 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5608 aRB
.transform(aTransform
);
5609 aRanges
.push_back(aRB
);
5612 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5613 sdr::overlay::OVERLAY_INVERT
,
5618 pOverlayManager
->add(*pOverlay
);
5619 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
5620 mpOODragRect
->append(*pOverlay
);
5624 if ( aOldMode
!= aDrawMode
)
5625 SetMapMode( aOldMode
);
5628 void ScGridWindow::DeleteHeaderOverlay()
5630 DELETEZ( mpOOHeader
);
5633 void ScGridWindow::UpdateHeaderOverlay()
5635 MapMode aDrawMode
= GetDrawMapMode();
5636 MapMode aOldMode
= GetMapMode();
5637 if ( aOldMode
!= aDrawMode
)
5638 SetMapMode( aDrawMode
);
5640 DeleteHeaderOverlay();
5642 // Pixel rectangle is in aInvertRect
5643 if ( !aInvertRect
.IsEmpty() )
5645 // #i70788# get the OverlayManager safely
5646 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5650 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5651 std::vector
< basegfx::B2DRange
> aRanges
;
5652 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5653 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
5655 aRB
.transform(aTransform
);
5656 aRanges
.push_back(aRB
);
5658 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5659 sdr::overlay::OVERLAY_INVERT
,
5664 pOverlayManager
->add(*pOverlay
);
5665 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
5666 mpOOHeader
->append(*pOverlay
);
5670 if ( aOldMode
!= aDrawMode
)
5671 SetMapMode( aOldMode
);
5674 void ScGridWindow::DeleteShrinkOverlay()
5676 DELETEZ( mpOOShrink
);
5679 void ScGridWindow::UpdateShrinkOverlay()
5681 MapMode aDrawMode
= GetDrawMapMode();
5682 MapMode aOldMode
= GetMapMode();
5683 if ( aOldMode
!= aDrawMode
)
5684 SetMapMode( aDrawMode
);
5686 DeleteShrinkOverlay();
5689 // get the rectangle in pixels
5694 SCTAB nTab
= pViewData
->GetTabNo();
5695 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
5696 pViewData
->GetDelMark( aRange
) )
5698 //! limit to visible area
5699 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
5700 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
5702 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
5703 aRange
.aStart
.Row(), eWhich
);
5704 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
5705 aRange
.aEnd
.Row()+1, eWhich
);
5709 aPixRect
= Rectangle( aStart
,aEnd
);
5713 if ( !aPixRect
.IsEmpty() )
5715 // #i70788# get the OverlayManager safely
5716 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5720 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5721 std::vector
< basegfx::B2DRange
> aRanges
;
5722 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5723 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
5725 aRB
.transform(aTransform
);
5726 aRanges
.push_back(aRB
);
5728 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5729 sdr::overlay::OVERLAY_INVERT
,
5734 pOverlayManager
->add(*pOverlay
);
5735 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
5736 mpOOShrink
->append(*pOverlay
);
5740 if ( aOldMode
!= aDrawMode
)
5741 SetMapMode( aOldMode
);
5744 // #i70788# central method to get the OverlayManager safely
5745 ::sdr::overlay::OverlayManager
* ScGridWindow::getOverlayManager()
5747 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
5751 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
5755 return (pPageWin
->GetOverlayManager());
5762 void ScGridWindow::flushOverlayManager()
5764 // #i70788# get the OverlayManager safely
5765 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5769 pOverlayManager
->flush();
5773 // ---------------------------------------------------------------------------