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 "validat.hxx"
122 #include "tabprotection.hxx"
123 #include "postit.hxx"
124 #include "dpcontrol.hxx"
125 #include "clipparam.hxx"
126 #include "cellsh.hxx"
127 #include "overlayobject.hxx"
129 #include "drawview.hxx"
130 #include <svx/sdrpagewindow.hxx>
131 #include <svx/sdr/overlay/overlaymanager.hxx>
132 #include <vcl/svapp.hxx>
133 #include <svx/sdr/overlay/overlayselection.hxx>
135 #include "cellsuno.hxx"
137 #include <com/sun/star/document/XVbaEventsHelper.hpp>
138 #include <com/sun/star/document/VbaEventId.hpp>
140 using namespace com::sun::star
;
141 using namespace com::sun::star::document::VbaEventId
;
142 using ::com::sun::star::uno::Sequence
;
143 using ::com::sun::star::uno::Any
;
145 const BYTE SC_NESTEDBUTTON_NONE
= 0;
146 const BYTE SC_NESTEDBUTTON_DOWN
= 1;
147 const BYTE SC_NESTEDBUTTON_UP
= 2;
149 #define SC_AUTOFILTER_ALL 0
150 #define SC_AUTOFILTER_TOP10 1
151 #define SC_AUTOFILTER_CUSTOM 2
152 #define SC_AUTOFILTER_EMPTY 3
153 #define SC_AUTOFILTER_NOTEMPTY 4
155 // Modi fuer die FilterListBox
159 SC_FILTERBOX_DATASELECT
,
160 SC_FILTERBOX_SCENARIO
,
161 SC_FILTERBOX_PAGEFIELD
164 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
165 extern USHORT nScClickMouseModifier
; // global.cxx
166 extern USHORT nScFillModeMouseModifier
; // global.cxx
168 #define SC_FILTERLISTBOX_LINES 12
170 // ============================================================================
172 ScGridWindow::VisibleRange::VisibleRange() :
173 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
177 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
179 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
182 // ============================================================================
184 class ScFilterListBox
: public ListBox
187 ScGridWindow
* pGridWin
;
196 ScFilterBoxMode eMode
;
199 virtual void LoseFocus();
203 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
204 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
207 virtual long PreNotify( NotifyEvent
& rNEvt
);
208 virtual void Select();
210 SCCOL
GetCol() const { return nCol
; }
211 SCROW
GetRow() const { return nRow
; }
212 ScFilterBoxMode
GetMode() const { return eMode
; }
213 BOOL
IsDataSelect() const { return (eMode
== SC_FILTERBOX_DATASELECT
); }
215 BOOL
IsInInit() const { return bInit
; }
216 void SetCancelled() { bCancelled
= TRUE
; }
217 BOOL
IsInSelect() const { return bInSelect
; }
218 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
219 bool HasDates() const { return mbListHasDates
; }
222 //-------------------------------------------------------------------
224 // ListBox in einem FloatingWindow (pParent)
225 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
226 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
227 ListBox( pParent
, WB_AUTOHSCROLL
),
231 bButtonDown( FALSE
),
235 mbListHasDates(false),
241 __EXPORT
ScFilterListBox::~ScFilterListBox()
243 if (IsMouseCaptured())
247 void ScFilterListBox::EndInit()
249 USHORT nPos
= GetSelectEntryPos();
250 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
258 void __EXPORT
ScFilterListBox::LoseFocus()
265 // -----------------------------------------------------------------------
267 long ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
270 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
272 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
273 KeyCode aCode
= aKeyEvt
.GetKeyCode();
274 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
276 USHORT nKey
= aCode
.GetCode();
277 if ( nKey
== KEY_RETURN
)
279 SelectHdl(); // auswaehlen
282 else if ( nKey
== KEY_ESCAPE
)
284 pGridWin
->ClickExtern(); // loescht die List-Box !!!
290 return nDone
? nDone
: ListBox::PreNotify( rNEvt
);
293 void __EXPORT
ScFilterListBox::Select()
299 void __EXPORT
ScFilterListBox::SelectHdl()
301 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
303 USHORT nPos
= GetSelectEntryPos();
304 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
309 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
311 pGridWin
->FilterSelect( nSel
);
318 // ============================================================================
320 // use a System floating window for the above filter listbox
321 class ScFilterFloatingWindow
: public FloatingWindow
324 ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
325 virtual ~ScFilterFloatingWindow();
326 // required for System FloatingWindows that will not process KeyInput by themselves
327 virtual Window
* GetPreferredKeyInputWindow();
330 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
331 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
334 ScFilterFloatingWindow::~ScFilterFloatingWindow()
339 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
341 // redirect keyinput in the child window
342 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
345 // ============================================================================
347 BOOL
lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
349 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
350 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
351 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
353 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
354 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
358 const ScBaseCell
* pCell
= pDoc
->GetCell( rRange
.aEnd
);
359 return ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
&&
360 ((ScFormulaCell
*)pCell
)->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
364 void lcl_UnLockComment( ScDrawView
* pView
, SdrPageView
* pPV
, SdrModel
* pDrDoc
, const Point
& rPos
, ScViewData
* pViewData
)
366 if (!pView
&& !pPV
&& !pDrDoc
&& !pViewData
)
369 ScDocument
& rDoc
= *pViewData
->GetDocument();
370 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
371 ScPostIt
* pNote
= rDoc
.GetNote( aCellPos
);
372 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
373 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
375 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
376 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
377 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
378 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
379 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
383 sal_Bool
lcl_GetHyperlinkCell(ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScBaseCell
*& rpCell
)
388 pDoc
->GetCell( rPosX
, rPosY
, nTab
, rpCell
);
389 if ( !rpCell
|| rpCell
->GetCellType() == CELLTYPE_NOTE
)
392 return FALSE
; // alles leer bis links
394 --rPosX
; // weitersuchen
396 else if ( rpCell
->GetCellType() == CELLTYPE_EDIT
)
398 else if (rpCell
->GetCellType() == CELLTYPE_FORMULA
&&
399 static_cast<ScFormulaCell
*>(rpCell
)->IsHyperLinkCell())
402 return FALSE
; // andere Zelle
409 // ---------------------------------------------------------------------------
410 // WB_DIALOGCONTROL noetig fuer UNO-Controls
411 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
412 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
413 DropTargetHelper( this ),
414 DragSourceHelper( this ),
416 mpOOSelection( NULL
),
417 mpOOSelectionBorder( NULL
),
418 mpOOAutoFill( NULL
),
419 mpOODragRect( NULL
),
422 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
427 pFilterFloat( NULL
),
428 mpDPFieldPopup(NULL
),
429 mpFilterButton(NULL
),
430 nCursorHideCount( 0 ),
434 nMouseStatus( SC_GM_NONE
),
435 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
438 nPagebreakMouse( SC_PD_NONE
),
439 bPagebreakDrawn( FALSE
),
442 meDragInsertMode( INS_NONE
),
443 nCurrentPointer( 0 ),
444 bIsInScroll( FALSE
),
446 aComboButton( this ),
449 bNeedsRepaint( FALSE
),
450 bAutoMarkVisible( FALSE
),
451 bListValButton( FALSE
)
455 case SC_SPLIT_TOPLEFT
:
456 eHWhich
= SC_SPLIT_LEFT
;
457 eVWhich
= SC_SPLIT_TOP
;
459 case SC_SPLIT_TOPRIGHT
:
460 eHWhich
= SC_SPLIT_RIGHT
;
461 eVWhich
= SC_SPLIT_TOP
;
463 case SC_SPLIT_BOTTOMLEFT
:
464 eHWhich
= SC_SPLIT_LEFT
;
465 eVWhich
= SC_SPLIT_BOTTOM
;
467 case SC_SPLIT_BOTTOMRIGHT
:
468 eHWhich
= SC_SPLIT_RIGHT
;
469 eVWhich
= SC_SPLIT_BOTTOM
;
472 DBG_ERROR("GridWindow: falsche Position");
477 SetMapMode(pViewData
->GetLogicMode(eWhich
));
479 EnableChildTransparentMode();
480 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
482 SetHelpId( HID_SC_WIN_GRIDWIN
);
483 SetUniqueId( HID_SC_WIN_GRIDWIN
);
485 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
489 __EXPORT
ScGridWindow::~ScGridWindow()
492 ImpDestroyOverlayObjects();
499 void __EXPORT
ScGridWindow::Resize( const Size
& )
504 void ScGridWindow::ClickExtern()
508 // #i81298# don't delete the filter box when called from its select handler
509 // (possible through row header size update)
510 // #i84277# when initializing the filter box, a Basic error can deactivate the view
511 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
517 DELETEZ(pFilterFloat
);
521 if (mpDPFieldPopup
.get())
523 mpDPFieldPopup
->close(false);
524 mpDPFieldPopup
.reset();
528 IMPL_LINK( ScGridWindow
, PopupModeEndHdl
, FloatingWindow
*, EMPTYARG
)
531 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
536 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
538 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
539 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
543 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, BOOL bHasSelection
, const String
& rStr
)
547 ScDocument
* pDoc
= pViewData
->GetDocument();
548 SCTAB nTab
= pViewData
->GetTabNo();
549 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
550 if ( pDPObj
&& nCol
> 0 )
552 // look for the dimension header left of the drop-down arrow
553 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
554 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
555 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
557 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
560 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
561 if ( !bIsDataLayout
)
563 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
566 pDim
->SetCurrentPage( &rStr
);
568 pDim
->SetCurrentPage( NULL
);
570 ScDPObject
aNewObj( *pDPObj
);
571 aNewObj
.SetSaveData( aSaveData
);
572 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
573 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
574 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
580 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
582 //! merge position/size handling with DoAutoFilterMenue
588 ScDocument
* pDoc
= pViewData
->GetDocument();
589 SCTAB nTab
= pViewData
->GetTabNo();
590 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
595 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
596 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
600 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
603 aPos
.Y() += nSizeY
- 1;
605 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // not resizable etc.
606 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
607 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_PAGEFIELD
);
609 pFilterBox
->EnableMirroring();
614 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
615 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
617 nHeight
= GetTextHeight();
618 nHeight
*= SC_FILTERLISTBOX_LINES
;
620 SetMapMode( aOldMode
);
624 // SetSize comes later
626 TypedScStrCollection
aStrings( 128, 128 );
628 // get list box entries and selection
629 BOOL bHasCurrentPage
= FALSE
;
631 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
632 if ( pDPObj
&& nCol
> 0 )
634 // look for the dimension header left of the drop-down arrow
635 USHORT nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
636 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
637 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
639 pDPObj
->FillPageList( aStrings
, nField
);
641 // get current page from SaveData
643 ScDPSaveData
* pSaveData
= pDPObj
->GetSaveData();
645 String aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
646 if ( pSaveData
&& !bIsDataLayout
)
648 ScDPSaveDimension
* pDim
= pSaveData
->GetExistingDimensionByName(aDimName
);
649 if ( pDim
&& pDim
->HasCurrentPage() )
651 aCurrentPage
= pDim
->GetCurrentPage();
652 bHasCurrentPage
= TRUE
;
658 // include all entry widths for the size of the drop-down
660 USHORT nCount
= aStrings
.GetCount();
661 for (i
=0; i
<nCount
; i
++)
663 TypedStrData
* pData
= aStrings
[i
];
664 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
665 if ( nTextWidth
> nMaxText
)
666 nMaxText
= nTextWidth
;
669 // add scrollbar width if needed (string entries are counted here)
670 // (scrollbar is shown if the box is exactly full?)
671 if ( nCount
>= SC_FILTERLISTBOX_LINES
)
672 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
674 nMaxText
+= 4; // for borders
676 if ( nMaxText
> nSizeX
)
677 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
679 // adjust position and size to window
681 Size aParentSize
= GetParent()->GetOutputSizePixel();
682 Size
aSize( nSizeX
, nHeight
);
684 if ( aSize
.Height() > aParentSize
.Height() )
685 aSize
.Height() = aParentSize
.Height();
686 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
687 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
689 pFilterBox
->SetSizePixel( aSize
);
690 pFilterBox
->Show(); // Show must be called before SetUpdateMode
691 pFilterBox
->SetUpdateMode(FALSE
);
693 pFilterFloat
->SetOutputSizePixel( aSize
);
694 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
697 BOOL bWait
= ( nCount
> 100 );
702 for (i
=0; i
<nCount
; i
++)
703 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
705 pFilterBox
->SetSeparatorPos( 0 );
710 pFilterBox
->SetUpdateMode(TRUE
);
712 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
714 nSelPos
= pFilterBox
->GetEntryPos( aCurrentPage
);
716 if ( nSelPos
== LISTBOX_ENTRY_NOTFOUND
)
717 nSelPos
= 0; // first entry
719 pFilterBox
->GrabFocus();
721 // call Select after GrabFocus, so the focus rectangle ends up in the right position
722 if ( nSelPos
!= LISTBOX_ENTRY_NOTFOUND
)
723 pFilterBox
->SelectEntryPos( nSelPos
);
725 pFilterBox
->EndInit();
727 nMouseStatus
= SC_GM_FILTER
;
731 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
733 SCTAB nTab
= pViewData
->GetTabNo();
734 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
738 // Get the geometry of the cell.
739 Point aScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
741 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
742 Size
aScrSize(nSizeX
-1, nSizeY
-1);
744 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
747 void ScGridWindow::DoScenarioMenue( const ScRange
& rScenRange
)
752 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
753 SCROW nRow
= rScenRange
.aStart
.Row();
756 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
757 if (nRow
>MAXROW
) nRow
= MAXROW
;
758 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
761 ScDocument
* pDoc
= pViewData
->GetDocument();
762 SCTAB nTab
= pViewData
->GetTabNo();
763 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
768 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
769 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
772 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
773 aCellRect
.Top() -= nSizeY
;
774 aCellRect
.Bottom() -= nSizeY
- 1;
775 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
776 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
778 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
779 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
780 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
782 pFilterBox
->EnableMirroring();
787 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
788 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
790 nHeight
= GetTextHeight();
791 nHeight
*= SC_FILTERLISTBOX_LINES
;
793 SetMapMode( aOldMode
);
799 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
800 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
801 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
804 // ParentSize Abfrage fehlt
805 Size
aSize( nSizeX
, nHeight
);
806 pFilterBox
->SetSizePixel( aSize
);
807 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
808 pFilterBox
->SetUpdateMode(FALSE
);
810 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
817 SCTAB nTabCount
= pDoc
->GetTableCount();
818 SCTAB nEntryCount
= 0;
819 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
821 if (pDoc
->HasScenarioRange( i
, rScenRange
))
822 if (pDoc
->GetName( i
, aTabName
))
824 pFilterBox
->InsertEntry( aTabName
);
825 if (pDoc
->IsActiveScenario(i
))
827 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
828 if ( nTextWidth
> nMaxText
)
829 nMaxText
= nTextWidth
;
833 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
834 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
835 nMaxText
+= 4; // fuer Rand
836 if ( nMaxText
> 300 )
837 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
839 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
841 long nDiff
= nMaxText
- nSizeX
;
842 aSize
= Size( nMaxText
, nHeight
);
843 pFilterBox
->SetSizePixel( aSize
);
844 pFilterFloat
->SetOutputSizePixel( aSize
);
848 // also move popup position
849 long nNewX
= aCellRect
.Left() - nDiff
;
852 aCellRect
.Left() = nNewX
;
856 pFilterFloat
->SetOutputSizePixel( aSize
);
857 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
859 pFilterBox
->SetUpdateMode(TRUE
);
860 pFilterBox
->GrabFocus();
862 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
863 //! SvLBoxEntry* pSelect = NULL;
864 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
867 nPos
= pFilterBox
->GetEntryPos( aCurrent
);
868 //! pSelect = pFilterBox->GetEntry( nPos );
870 if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
872 //! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein
873 if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND
!= nPos
)
874 pFilterBox
->SelectEntryPos(nPos
);
876 pFilterBox
->EndInit();
878 // Szenario-Auswahl kommt aus MouseButtonDown:
879 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
881 nMouseStatus
= SC_GM_FILTER
;
885 void ScGridWindow::DoAutoFilterMenue( SCCOL nCol
, SCROW nRow
, BOOL bDataSelect
)
891 ScDocument
* pDoc
= pViewData
->GetDocument();
892 SCTAB nTab
= pViewData
->GetTabNo();
893 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
898 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
899 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
903 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
906 aPos
.Y() += nSizeY
- 1;
908 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
909 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
910 pFilterBox
= new ScFilterListBox(
911 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
913 pFilterBox
->EnableMirroring();
918 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
919 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
921 nHeight
= GetTextHeight();
922 nHeight
*= SC_FILTERLISTBOX_LINES
;
924 SetMapMode( aOldMode
);
930 pFilterBox->SetSelectionMode( SINGLE_SELECTION );
931 pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
932 pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
936 TypedScStrCollection
aStrings( 128, 128 );
937 if ( bDataSelect
) // Auswahl-Liste
940 aStrings
.SetCaseSensitive( TRUE
);
941 pDoc
->GetDataEntries( nCol
, nRow
, nTab
, aStrings
);
942 if ( aStrings
.GetCount() == 0 )
947 //! wird der Titel ueberhaupt ausgewertet ???
949 pDoc
->GetString( nCol
, nRow
, nTab
, aString
);
950 pFilterBox
->SetText( aString
);
955 static const USHORT nDefIDs
[] = { SCSTR_ALLFILTER
, SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_EMPTY
, SCSTR_NOTEMPTY
};
956 const USHORT nDefCount
= sizeof(nDefIDs
) / sizeof(USHORT
);
957 for (i
=0; i
<nDefCount
; i
++)
959 String
aEntry( (ScResId
) nDefIDs
[i
] );
960 pFilterBox
->InsertEntry( aEntry
);
961 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
962 if ( nTextWidth
> nMaxText
)
963 nMaxText
= nTextWidth
;
965 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
968 bool bHasDates
= false;
969 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
970 pFilterBox
->SetListHasDates(bHasDates
);
972 // check widths of numerical entries (string entries are not included)
973 // so all numbers are completely visible
974 USHORT nCount
= aStrings
.GetCount();
975 for (i
=0; i
<nCount
; i
++)
977 TypedStrData
* pData
= aStrings
[i
];
978 if ( !pData
->IsStrData() ) // only numerical entries
980 long nTextWidth
= pFilterBox
->GetTextWidth( pData
->GetString() );
981 if ( nTextWidth
> nMaxText
)
982 nMaxText
= nTextWidth
;
986 // add scrollbar width if needed (string entries are counted here)
987 // (scrollbar is shown if the box is exactly full?)
988 if ( nCount
+ nDefCount
>= SC_FILTERLISTBOX_LINES
)
989 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
991 nMaxText
+= 4; // for borders
993 if ( nMaxText
> nSizeX
)
994 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
999 // Position und Groesse an Fenster anpassen
1000 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1002 Size aParentSize
= GetParent()->GetOutputSizePixel();
1003 Size
aSize( nSizeX
, nHeight
);
1005 if ( aSize
.Height() > aParentSize
.Height() )
1006 aSize
.Height() = aParentSize
.Height();
1007 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1008 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1010 pFilterBox
->SetSizePixel( aSize
);
1011 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1012 pFilterBox
->SetUpdateMode(FALSE
);
1014 pFilterFloat
->SetOutputSizePixel( aSize
);
1015 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1018 USHORT nCount
= aStrings
.GetCount();
1019 BOOL bWait
= ( nCount
> 100 );
1024 for (i
=0; i
<nCount
; i
++)
1025 pFilterBox
->InsertEntry( aStrings
[i
]->GetString() );
1030 pFilterBox
->SetUpdateMode(TRUE
);
1033 //! SvLBoxEntry* pSelect = NULL;
1034 USHORT nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1036 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1038 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1041 ScQueryParam aParam
;
1042 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1045 for (SCSIZE j
=0; j
<MAXQUERY
&& bValid
; j
++) // bisherige Filter-Einstellungen
1046 if (aParam
.GetEntry(j
).bDoQuery
)
1048 //! Abfrage mit DrawButtons zusammenfassen!
1050 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1052 if (rEntry
.eConnect
!= SC_AND
)
1054 if (rEntry
.nField
== nCol
)
1056 if (rEntry
.eOp
== SC_EQUAL
)
1058 String
* pStr
= rEntry
.pStr
;
1061 nSelPos
= pFilterBox
->GetEntryPos( *pStr
);
1062 //! pSelect = pFilterBox->GetEntry( nPos );
1065 else if (rEntry
.eOp
== SC_TOPVAL
&& rEntry
.pStr
&&
1066 rEntry
.pStr
->EqualsAscii("10"))
1067 nSelPos
= SC_AUTOFILTER_TOP10
;
1069 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1074 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1080 ULONG nIndex
= ((SfxUInt32Item
*)pDoc
->GetAttr(
1081 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1084 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1087 TypedStrData
* pNew
= NULL
;
1089 pDoc
->GetString( nCol
, nRow
, nTab
, aDocStr
);
1090 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1092 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1093 pNew
= new TypedStrData( aDocStr
, fVal
, SC_STRTYPE_VALUE
);
1096 pNew
= new TypedStrData( aDocStr
, 0.0, SC_STRTYPE_STANDARD
);
1098 bool bSortList
= ( pData
->GetListType() == ValidListType::SORTEDASCENDING
);
1102 if (aStrings
.Search(pNew
,nStrIndex
))
1103 nSelPos
= nStrIndex
;
1107 USHORT nCount
= aStrings
.GetCount();
1108 for (i
= 0; ((i
< nCount
) && ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
)); i
++)
1110 if ( aStrings
.Compare(aStrings
[i
], pNew
)==0 )
1119 // neu (309): irgendwas muss immer selektiert sein:
1120 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1123 // keine leere Auswahl-Liste anzeigen:
1127 DELETEZ(pFilterBox
); // war nix
1128 DELETEZ(pFilterFloat
);
1129 Sound::Beep(); // bemerkbar machen
1133 // pFilterBox->Show(); // schon vorne
1134 pFilterBox
->GrabFocus();
1136 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1137 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1138 pFilterBox
->SelectEntryPos( nSelPos
);
1142 pFilterBox
->SetNoSelection();
1145 pFilterBox
->EndInit();
1149 // AutoFilter (aus MouseButtonDown):
1150 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1152 nMouseStatus
= SC_GM_FILTER
;
1158 void ScGridWindow::FilterSelect( ULONG nSel
)
1162 SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
1165 SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
1167 aString = pStringEntry->GetText();
1170 aString
= pFilterBox
->GetEntry( static_cast< USHORT
>( nSel
) );
1172 SCCOL nCol
= pFilterBox
->GetCol();
1173 SCROW nRow
= pFilterBox
->GetRow();
1174 switch ( pFilterBox
->GetMode() )
1176 case SC_FILTERBOX_DATASELECT
:
1177 ExecDataSelect( nCol
, nRow
, aString
);
1179 case SC_FILTERBOX_FILTER
:
1180 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1182 case SC_FILTERBOX_SCENARIO
:
1183 pViewData
->GetView()->UseScenario( aString
);
1185 case SC_FILTERBOX_PAGEFIELD
:
1186 // first entry is "all"
1187 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1192 pFilterFloat
->EndPopupMode();
1194 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1197 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const String
& rStr
)
1201 SCTAB nTab
= pViewData
->GetTabNo();
1202 ScViewFunc
* pView
= pViewData
->GetView();
1203 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1205 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1206 // if the cursor is moved afterwards.
1207 pView
->CellContentChanged();
1211 void ScGridWindow::ExecFilter( ULONG nSel
,
1212 SCCOL nCol
, SCROW nRow
,
1213 const String
& aValue
, bool bCheckForDates
)
1215 SCTAB nTab
= pViewData
->GetTabNo();
1216 ScDocument
* pDoc
= pViewData
->GetDocument();
1218 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1221 ScQueryParam aParam
;
1222 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1224 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1231 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1232 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1233 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1234 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1238 BOOL bDeleteOld
= FALSE
;
1239 SCSIZE nQueryPos
= 0;
1240 BOOL bFound
= FALSE
;
1241 if (!aParam
.bInplace
)
1245 for (SCSIZE i
=0; i
<MAXQUERY
&& !bDeleteOld
; i
++) // bisherige Filter-Einstellungen
1246 if (aParam
.GetEntry(i
).bDoQuery
)
1248 //! Abfrage mit DrawButtons zusammenfassen!
1250 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1252 if (rEntry
.eConnect
!= SC_AND
)
1255 if (rEntry
.nField
== nCol
)
1257 if (bFound
) // diese Spalte zweimal?
1268 SCSIZE nEC
= aParam
.GetEntryCount();
1269 for (SCSIZE i
=0; i
<nEC
; i
++)
1270 aParam
.GetEntry(i
).Clear();
1272 aParam
.bInplace
= TRUE
;
1273 aParam
.bRegExp
= FALSE
;
1276 if ( nQueryPos
< MAXQUERY
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1280 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1282 rNewEntry
.bDoQuery
= TRUE
;
1283 rNewEntry
.bQueryByString
= TRUE
;
1284 rNewEntry
.nField
= nCol
;
1285 rNewEntry
.bQueryByDate
= bCheckForDates
;
1286 if ( nSel
== SC_AUTOFILTER_TOP10
)
1288 rNewEntry
.eOp
= SC_TOPVAL
;
1289 *rNewEntry
.pStr
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
1291 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1293 rNewEntry
.pStr
->Erase();
1294 rNewEntry
.bQueryByString
= FALSE
;
1295 rNewEntry
.eOp
= SC_EQUAL
;
1296 rNewEntry
.nVal
= SC_EMPTYFIELDS
;
1299 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1301 rNewEntry
.pStr
->Erase();
1302 rNewEntry
.bQueryByString
= FALSE
;
1303 rNewEntry
.eOp
= SC_EQUAL
;
1304 rNewEntry
.nVal
= SC_NONEMPTYFIELDS
;
1308 rNewEntry
.eOp
= SC_EQUAL
;
1309 *rNewEntry
.pStr
= aValue
;
1312 rNewEntry
.eConnect
= SC_AND
;
1317 aParam
.DeleteQuery(nQueryPos
);
1320 // #100597# end edit mode - like in ScCellShell::ExecuteDB
1321 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1323 SC_MOD()->InputEnterHandler();
1324 pViewData
->GetViewShell()->UpdateInputHandler();
1327 aParam
.bUseDynamicRange
= true;
1328 pViewData
->GetView()->Query( aParam
, NULL
, TRUE
);
1329 pDBData
->SetQueryParam( aParam
); // speichern
1331 else // "Zuviele Bedingungen"
1332 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1337 DBG_ERROR("Wo ist der Datenbankbereich?");
1341 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1343 nCurrentPointer
= 0;
1344 Window::SetPointer( rPointer
);
1347 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1351 rDestWin
.nButtonDown
= nButtonDown
;
1352 rDestWin
.nMouseStatus
= nMouseStatus
;
1357 rDestWin
.bRFMouse
= bRFMouse
;
1358 rDestWin
.bRFSize
= bRFSize
;
1359 rDestWin
.nRFIndex
= nRFIndex
;
1360 rDestWin
.nRFAddX
= nRFAddX
;
1361 rDestWin
.nRFAddY
= nRFAddY
;
1365 if (nPagebreakMouse
)
1367 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1368 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1369 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1370 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1371 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1372 nPagebreakMouse
= SC_PD_NONE
;
1376 BOOL
ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, BOOL bAction
)
1378 // MouseEvent buttons must only be checked if bAction==TRUE
1379 // to allow changing the mouse pointer in MouseMove,
1380 // but not start AutoFill with right button (#74229#).
1381 // with bAction==TRUE, SetFillMode / SetDragMode is called
1383 if ( bAction
&& !rMEvt
.IsLeft() )
1386 BOOL bNewPointer
= FALSE
;
1388 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1389 BOOL bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1391 if ( pViewData
->IsActive() && !bOleActive
)
1393 ScDocument
* pDoc
= pViewData
->GetDocument();
1394 SCTAB nTab
= pViewData
->GetTabNo();
1395 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1396 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1401 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1403 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1405 Point aMousePos
= rMEvt
.GetPosPixel();
1406 if (mpAutoFillRect
->IsInside(aMousePos
))
1408 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1411 SCCOL nX
= aMarkRange
.aEnd
.Col();
1412 SCROW nY
= aMarkRange
.aEnd
.Row();
1414 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1415 pViewData
->SetDragMode(
1416 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1418 pViewData
->SetFillMode(
1419 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1421 // #108266# The simple selection must also be recognized when dragging,
1422 // where the Marking flag is set and MarkToSimple won't work anymore.
1423 pViewData
->GetMarkData().MarkToSimple();
1430 // Embedded-Rechteck
1432 if (pDoc
->IsEmbedded())
1435 pDoc
->GetEmbedded( aRange
);
1436 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1438 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1439 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1440 Point aMousePos
= rMEvt
.GetPosPixel();
1446 BOOL bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1447 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1448 BOOL bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1449 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1450 if ( bTop
|| bBottom
)
1452 SetPointer( Pointer( POINTER_CROSS
) );
1455 BYTE nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1456 pViewData
->SetDragMode(
1457 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1458 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1466 if (!bNewPointer
&& bAction
)
1468 // SetPointer( POINTER_ARROW ); // in Fu...
1469 pViewData
->ResetFillMode();
1475 void __EXPORT
ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1477 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1479 HandleMouseButtonDown( rMEvt
);
1481 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1483 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1484 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1485 // simulate another MouseButtonUp call, so the selection state is consistent.
1487 nButtonDown
= rMEvt
.GetButtons();
1491 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1493 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1496 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
)
1498 // We have to check if a context menu is shown and we have an UI
1499 // active inplace client. In that case we have to ignore the event.
1500 // Otherwise we would crash (context menu has been
1501 // opened by inplace client and we would deactivate the inplace client,
1502 // the contex menu is closed by VCL asynchronously which in the end
1503 // would work on deleted objects or the context menu has no parent anymore)
1504 // See #126086# and #128122#
1505 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1506 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1508 pClient
->IsObjectInPlaceActive() &&
1509 PopupMenu::IsInExecute() )
1512 aCurMousePos
= rMEvt
.GetPosPixel();
1514 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1515 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1517 // merken, dass FilterBox geloescht wird, damit sichergestellt
1518 // ist, dass in diesem Handler nicht an gleicher Stelle wieder
1519 // eine neue geoeffnet wird.
1520 BOOL bWasFilterBox
= ( pFilterBox
!= NULL
&&
1521 ((Window
*)pFilterBox
)->IsVisible() &&
1522 !pFilterBox
->IsDataSelect() );
1523 SCCOL nOldColFBox
= bWasFilterBox
? pFilterBox
->GetCol() : 0;
1524 SCROW nOldRowFBox
= bWasFilterBox
? pFilterBox
->GetRow() : 0;
1526 #include "cellsuno.hxx"
1528 ClickExtern(); // loescht FilterBox, wenn vorhanden
1530 HideNoteMarker(); // Notiz-Anzeige
1534 ScModule
* pScMod
= SC_MOD();
1535 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1541 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1542 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1544 BOOL bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1545 BOOL bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1546 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1547 BOOL bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1548 BOOL bDouble
= (rMEvt
.GetClicks() == 2);
1550 // DeactivateIP passiert nur noch bei MarkListHasChanged
1552 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1553 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1555 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1556 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1558 // pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1559 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1562 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1563 // but a single (first) click is always valid
1564 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1567 nMouseStatus
= SC_GM_NONE
;
1571 if ( bDetective
) // Detektiv-Fuell-Modus
1573 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1575 Point aPos
= rMEvt
.GetPosPixel();
1578 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1580 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1581 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1582 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1583 &aPosXItem
, &aPosYItem
, (void*)0L );
1587 nMouseStatus
= SC_GM_NONE
;
1592 nMouseStatus
= SC_GM_NONE
;
1596 if ( pViewData
->GetActivePart() != eWhich
)
1597 pViewData
->GetView()->ActivatePart( eWhich
);
1601 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1602 pSelEng
->SetWindow(this);
1603 pSelEng
->SetWhich(eWhich
);
1604 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1607 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1609 Point aPos
= rMEvt
.GetPosPixel();
1612 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1614 EditView
* pEditView
;
1617 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1618 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1619 SCROW nEndRow
= pViewData
->GetEditEndRow();
1621 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1622 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1624 // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
1625 if (bFormulaMode
) // sonst ist es oben schon passiert
1628 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1630 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1635 if (pScMod
->GetIsWaterCan())
1637 //! was is mit'm Mac ???
1638 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1640 nMouseStatus
= SC_GM_WATERUNDO
;
1645 // Reihenfolge passend zum angezeigten Cursor:
1646 // RangeFinder, AutoFill, PageBreak, Drawing
1648 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bRFSize
, &nRFIndex
, &nRFAddX
, &nRFAddY
) )
1650 bRFMouse
= TRUE
; // die anderen Variablen sind oben initialisiert
1652 if ( pViewData
->GetActivePart() != eWhich
)
1653 pViewData
->GetView()->ActivatePart( eWhich
); //! schon oben immer ???
1660 BOOL bCrossPointer
= TestMouse( rMEvt
, TRUE
);
1661 if ( bCrossPointer
)
1664 pViewData
->GetView()->FillCrossDblClick();
1666 pScMod
->InputEnterHandler(); // Autofill etc.
1669 if ( !bCrossPointer
)
1671 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1672 &nPagebreakBreak
, &nPagebreakPrev
);
1673 if (nPagebreakMouse
)
1675 bPagebreakDrawn
= FALSE
;
1678 PagebreakMove( rMEvt
, FALSE
);
1683 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1685 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1687 //if (DrawHasMarkedObj())
1688 // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert
1692 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // kein Draw-Objekt selektiert
1694 // TestMouse schon oben passiert
1697 Point aPos
= rMEvt
.GetPosPixel();
1700 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1701 SCTAB nTab
= pViewData
->GetTabNo();
1702 ScDocument
* pDoc
= pViewData
->GetDocument();
1706 // AutoFilter buttons
1709 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1711 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1712 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1713 if (pAttr
->HasAutoFilter())
1715 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
1718 if (pAttr
->HasButton())
1720 DoPushButton( nPosX
, nPosY
, rMEvt
); // setzt evtl. bPivotMouse / bDPMouse
1724 // List Validity drop-down button
1726 if ( bListValButton
)
1728 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1729 if ( aButtonRect
.IsInside( aPos
) )
1731 DoAutoFilterMenue( aListValPos
.Col(), aListValPos
.Row(), TRUE
);
1733 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1741 // scenario selection
1745 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1747 DoScenarioMenue( aScenRange
);
1752 // Doppelklick angefangen ?
1755 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1757 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1759 if ( bDouble
&& !bCrossPointer
)
1761 if (nMouseStatus
== SC_GM_TABDOWN
)
1762 nMouseStatus
= SC_GM_DBLDOWN
;
1765 nMouseStatus
= SC_GM_TABDOWN
;
1769 // Links in Edit-Zellen
1772 BOOL bAlt
= rMEvt
.IsMod2();
1773 if ( !bAlt
&& rMEvt
.IsLeft() &&
1774 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1776 SetPointer( Pointer( POINTER_REFHAND
) );
1777 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1782 // Gridwin - SelectionEngine
1785 if ( rMEvt
.IsLeft() )
1787 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1788 pSelEng
->SetWindow(this);
1789 pSelEng
->SetWhich(eWhich
);
1790 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1792 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1793 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1795 if (IsMouseCaptured())
1797 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1798 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1802 pViewData
->GetMarkData().SetMarking(TRUE
);
1808 void __EXPORT
ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1810 aCurMousePos
= rMEvt
.GetPosPixel();
1811 ScDocument
* pDoc
= pViewData
->GetDocument();
1812 ScMarkData
& rMark
= pViewData
->GetMarkData();
1814 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1815 // (possible through Reschedule from storing an OLE object that is deselected)
1817 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
1818 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
1820 if (nButtonDown
!= rMEvt
.GetButtons())
1821 nMouseStatus
= SC_GM_IGNORE
; // reset und return
1825 if (nMouseStatus
== SC_GM_IGNORE
)
1827 nMouseStatus
= SC_GM_NONE
;
1828 // Selection-Engine: Markieren abbrechen
1829 pViewData
->GetView()->GetSelEngine()->Reset();
1830 rMark
.SetMarking(FALSE
);
1831 if (pViewData
->IsAnyFillMode())
1833 pViewData
->GetView()->StopRefMode();
1834 pViewData
->ResetFillMode();
1837 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1842 if (nMouseStatus
== SC_GM_FILTER
)
1844 if ( pFilterBox
&& pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
1846 if (mpFilterButton
.get())
1848 bool bFilterActive
= IsAutoFilterActive(
1849 pFilterBox
->GetCol(), pFilterBox
->GetRow(), pViewData
->GetTabNo() );
1851 mpFilterButton
->setHasHiddenMember(bFilterActive
);
1852 mpFilterButton
->setPopupPressed(false);
1854 mpFilterButton
->draw();
1858 nMouseStatus
= SC_GM_NONE
;
1860 return; // da muss nix mehr passieren
1863 ScModule
* pScMod
= SC_MOD();
1864 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1867 SfxBindings
& rBindings
= pViewData
->GetBindings();
1868 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
1870 EditView
* pEditView
;
1873 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1874 pEditView
->MouseButtonUp( rMEvt
);
1876 if ( rMEvt
.IsMiddle() &&
1877 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1879 // EditView may have pasted from selection
1880 pScMod
->InputChanged( pEditView
);
1883 pScMod
->InputSelection( pEditView
); // parentheses etc.
1885 pViewData
->GetView()->InvalidateAttribs();
1886 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
1893 DPMouseButtonUp( rMEvt
); // resets bDPMouse
1899 RFMouseMove( rMEvt
, TRUE
); // Range wieder richtigherum
1901 SetPointer( Pointer( POINTER_ARROW
) );
1906 if (nPagebreakMouse
)
1908 PagebreakMove( rMEvt
, TRUE
);
1909 nPagebreakMouse
= SC_PD_NONE
;
1910 SetPointer( Pointer( POINTER_ARROW
) );
1915 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
1917 SfxUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
1918 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
1925 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
1928 rMark
.SetMarking(FALSE
);
1930 SetPointer( Pointer( POINTER_ARROW
) );
1932 if (pViewData
->IsFillMode() ||
1933 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
1935 nScFillModeMouseModifier
= rMEvt
.GetModifier();
1940 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1941 // DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
1942 // "Block falsch fuer AutoFill" );
1944 BOOL bIsDel
= pViewData
->GetDelMark( aDelRange
);
1946 ScViewFunc
* pView
= pViewData
->GetView();
1947 pView
->StopRefMode();
1948 pViewData
->ResetFillMode();
1949 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
); // #i5819# don't use AutoFill anchor flag for selection
1953 pView
->MarkRange( aDelRange
, FALSE
);
1954 pView
->DeleteContents( IDF_CONTENTS
);
1955 SCTAB nTab
= pViewData
->GetTabNo();
1956 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1957 if ( aBlockRange
!= aDelRange
)
1959 if ( aDelRange
.aStart
.Row() == nStartRow
)
1960 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
1962 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
1963 pView
->MarkRange( aBlockRange
, FALSE
);
1967 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1969 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
1971 SCTAB nTab
= pViewData
->GetTabNo();
1976 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1977 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
1978 SCCOL nFillCol
= pViewData
->GetRefEndX();
1979 SCROW nFillRow
= pViewData
->GetRefEndY();
1980 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
1982 ScTabView
* pView
= pViewData
->GetView();
1983 pView
->StopRefMode();
1984 pViewData
->ResetFillMode();
1985 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
1987 if ( aEndPos
!= aBlockRange
.aEnd
)
1989 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, FALSE
);
1990 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
1993 else if (pViewData
->IsAnyFillMode())
1995 // Embedded-Area has been changed
1996 ScTabView
* pView
= pViewData
->GetView();
1997 pView
->StopRefMode();
1998 pViewData
->ResetFillMode();
1999 pView
->GetFunctionSet()->SetAnchorFlag( FALSE
);
2000 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2003 BOOL bRefMode
= pViewData
->IsRefMode();
2005 pScMod
->EndReference();
2008 // Giesskannen-Modus (Gestalter)
2011 if (pScMod
->GetIsWaterCan())
2013 // Abfrage auf Undo schon oben
2015 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
2016 (pViewData
->GetDocument()->
2017 GetStyleSheetPool());
2020 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
2021 pStylePool
->GetActualStyleSheet();
2025 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2029 case SFX_STYLE_FAMILY_PARA
:
2030 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2031 pViewData
->GetView()->DoneBlockMode();
2034 case SFX_STYLE_FAMILY_PAGE
:
2035 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2036 pStyleSheet
->GetName() );
2038 ScPrintFunc( pViewData
->GetDocShell(),
2039 pViewData
->GetViewShell()->GetPrinter(TRUE
),
2040 pViewData
->GetTabNo() ).UpdatePages();
2042 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2052 ScDBFunc
* pView
= pViewData
->GetView();
2053 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2056 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2057 if ( !pView
->IsPaintBrushLocked() )
2058 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2062 // double click (only left button)
2065 BOOL bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2066 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2069 Point aPos
= rMEvt
.GetPosPixel();
2072 SCTAB nTab
= pViewData
->GetTabNo();
2073 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2074 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2075 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2077 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2079 // Check for header drill-down first.
2080 sheet::DataPilotTableHeaderData aData
;
2081 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2083 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2084 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2087 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2089 // execute slot to show dialog
2090 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2094 // toggle single entry
2095 ScDPObject
aNewObj( *pDPObj
);
2096 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2097 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2098 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, TRUE
, FALSE
);
2099 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2104 // Check if the data area is double-clicked.
2106 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2107 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2108 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2110 Sound::Beep(); // nothing to expand/collapse/show
2116 // Check for cell protection attribute.
2117 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2118 bool bEditAllowed
= true;
2119 if ( pProtect
&& pProtect
->isProtected() )
2121 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2122 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2123 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2125 if ( bSkipProtected
&& bSkipUnprotected
)
2126 bEditAllowed
= false;
2127 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2128 bEditAllowed
= false;
2133 // edit cell contents
2134 pViewData
->GetViewShell()->UpdateInputHandler();
2135 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2136 if (pViewData
->HasEditView(eWhich
))
2138 // Text-Cursor gleich an die geklickte Stelle setzen
2139 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2140 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2141 pEditView
->MouseButtonDown( aEditEvt
);
2142 pEditView
->MouseButtonUp( aEditEvt
);
2149 // Links in edit cells
2152 BOOL bAlt
= rMEvt
.IsMod2();
2153 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2155 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2157 String aName
, aUrl
, aTarget
;
2158 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2160 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2161 ScGlobal::OpenURL( aUrl
, aTarget
);
2163 // fire worksheet_followhyperlink event
2164 Point aPos
= rMEvt
.GetPosPixel();
2167 SCTAB nTab
= pViewData
->GetTabNo();
2168 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2169 ScBaseCell
* pCell
= NULL
;
2171 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
2174 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2175 ScCellObj
* pObj
= new ScCellObj( pViewData
->GetDocShell(), aCellPos
);
2176 uno::Sequence
< uno::Any
> aArgs(1);
2177 aArgs
[0] = uno::makeAny(uno::Reference
<uno::XInterface
>(static_cast<cppu::OWeakObject
*>(pObj
)));
2178 uno::Reference
< document::XVbaEventsHelper
> xVbaEventsHelper ( pViewData
->GetDocument()->GetVbaEventsHelper(), uno::UNO_QUERY
);
2179 if( xVbaEventsHelper
.is() )
2180 xVbaEventsHelper
->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2187 // Gridwin - SelectionEngine
2190 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2191 // TRUE for any call, so IsLeft must be checked here, too.
2193 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2195 // rMark.MarkToSimple();
2196 pViewData
->GetView()->UpdateAutoFillMark();
2198 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2199 BOOL bFormulaMode
= pScMod
->IsFormulaMode();
2200 DBG_ASSERT( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2202 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2203 // multiple selection, so the argument string completely describes the selection,
2204 // and executing the slot won't change the existing selection (executing the slot
2205 // here and from a recorded macro is treated equally)
2207 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2209 String aAddr
; // CurrentCell
2210 if( rMark
.IsMarked() )
2212 // BOOL bKeep = rMark.IsMultiMarked(); //! wohin damit ???
2215 rMark
.GetMarkArea( aScRange
);
2216 aScRange
.Format( aAddr
, SCR_ABS
);
2217 if ( aScRange
.aStart
== aScRange
.aEnd
)
2219 // make sure there is a range selection string even for a single cell
2220 String aSingle
= aAddr
;
2221 aAddr
.Append( (sal_Char
) ':' );
2222 aAddr
.Append( aSingle
);
2225 //! SID_MARKAREA gibts nicht mehr ???
2226 //! was passiert beim Markieren mit dem Cursor ???
2228 else // nur Cursor bewegen
2230 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2231 aScAddress
.Format( aAddr
, SCA_ABS
);
2234 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2235 // We don't want to align to the cursor position because if the
2236 // cell cursor isn't visible after making selection, it would jump
2237 // back to the origin of the selection where the cell cursor is.
2238 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2239 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2240 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2242 pViewData
->GetView()->InvalidateAttribs();
2248 void ScGridWindow::FakeButtonUp()
2252 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2253 MouseButtonUp( aEvent
);
2257 void __EXPORT
ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2259 aCurMousePos
= rMEvt
.GetPosPixel();
2261 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2264 ScModule
* pScMod
= SC_MOD();
2265 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2268 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2269 // nicht anders mit:
2271 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2275 nMouseStatus
= SC_GM_NONE
;
2279 if (nMouseStatus
== SC_GM_IGNORE
)
2282 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2285 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2287 SetPointer( Pointer( POINTER_FILL
) );
2291 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2293 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2294 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2297 nMouseStatus
= SC_GM_NONE
;
2298 if ( pFilterBox
->GetMode() == SC_FILTERBOX_FILTER
)
2300 if (mpFilterButton
.get())
2302 mpFilterButton
->setHasHiddenMember(false);
2303 mpFilterButton
->setPopupPressed(false);
2305 mpFilterButton
->draw();
2310 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2315 BOOL bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2317 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2319 EditView
* pEditView
;
2322 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2323 pEditView
->MouseMove( rMEvt
);
2329 DPMouseMove( rMEvt
);
2335 RFMouseMove( rMEvt
, FALSE
);
2339 if (nPagebreakMouse
)
2341 PagebreakMove( rMEvt
, FALSE
);
2345 // anderen Mauszeiger anzeigen?
2347 BOOL bEditMode
= pViewData
->HasEditView(eWhich
);
2349 //! Testen ob RefMode-Dragging !!!
2350 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2352 Point aPos
= rMEvt
.GetPosPixel();
2355 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2357 EditView
* pEditView
;
2360 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2361 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2362 SCROW nEndRow
= pViewData
->GetEditEndRow();
2364 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2365 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2367 // Field can only be URL field
2368 BOOL bAlt
= rMEvt
.IsMod2();
2369 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2370 SetPointer( Pointer( POINTER_REFHAND
) );
2371 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2372 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2374 SetPointer( Pointer( POINTER_TEXT
) );
2379 BOOL bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2381 SetPointer( Pointer(POINTER_FILL
) );
2385 BOOL bCross
= FALSE
;
2390 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bCorner
) )
2393 SetPointer( Pointer( POINTER_CROSS
) );
2395 SetPointer( Pointer( POINTER_HAND
) );
2402 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2403 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2405 PointerStyle eNew
= POINTER_ARROW
;
2406 switch ( nBreakType
)
2411 eNew
= POINTER_ESIZE
;
2416 eNew
= POINTER_SSIZE
;
2418 case SC_PD_RANGE_TL
:
2419 case SC_PD_RANGE_BR
:
2420 eNew
= POINTER_SESIZE
;
2422 case SC_PD_RANGE_TR
:
2423 case SC_PD_RANGE_BL
:
2424 eNew
= POINTER_NESIZE
;
2427 SetPointer( Pointer( eNew
) );
2431 // Fill-Cursor anzeigen ?
2433 if ( !bFormulaMode
&& !nButtonDown
)
2434 if (TestMouse( rMEvt
, FALSE
))
2437 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2439 SetPointer( Pointer( POINTER_CROSS
) );
2441 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2446 BOOL bAlt
= rMEvt
.IsMod2();
2448 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2449 SetPointer( Pointer( POINTER_ARROW
) );
2450 else if ( !bAlt
&& !nButtonDown
&&
2451 GetEditUrl(rMEvt
.GetPosPixel()) )
2452 SetPointer( Pointer( POINTER_REFHAND
) );
2453 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2458 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2462 void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2464 rEvent
.Modifiers
= 0;
2465 if ( rEvt
.IsShift() )
2466 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2467 if ( rEvt
.IsMod1() )
2468 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2469 if ( rEvt
.IsMod2() )
2470 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2471 if ( rEvt
.IsMod3() )
2472 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD3
;
2475 if ( rEvt
.IsLeft() )
2476 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2477 if ( rEvt
.IsRight() )
2478 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2479 if ( rEvt
.IsMiddle() )
2480 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2482 rEvent
.X
= rEvt
.GetPosPixel().X();
2483 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2484 rEvent
.ClickCount
= rEvt
.GetClicks();
2485 rEvent
.PopupTrigger
= sal_False
;
2488 long ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2490 USHORT nType
= rNEvt
.GetType();
2491 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2493 Window
* pWindow
= rNEvt
.GetWindow();
2494 if (pWindow
== this && pViewData
)
2496 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2499 SfxFrame
* pFrame
= pViewFrame
->GetFrame();
2502 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pFrame
->GetController();
2503 if (xController
.is())
2505 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2506 if (pImp
&& pImp
->IsMouseListening())
2508 ::com::sun::star::awt::MouseEvent aEvent
;
2509 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2510 if ( rNEvt
.GetWindow() )
2511 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2512 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2513 pImp
->MousePressed( aEvent
);
2515 pImp
->MouseReleased( aEvent
);
2523 return Window::PreNotify( rNEvt
);
2526 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2528 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2529 // die verschiedenen MouseHandler verteilen...
2531 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2533 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2535 if (!pViewData
->GetView()->IsInActivatePart())
2538 bDPMouse
= FALSE
; // gezeichnet wird per bDragRect
2541 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2543 UpdateDragRectOverlay();
2547 RFMouseMove( rMEvt
, TRUE
); // richtig abbrechen geht dabei nicht...
2550 if (nPagebreakMouse
)
2552 // if (bPagebreakDrawn)
2553 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2554 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
2555 bPagebreakDrawn
= FALSE
;
2556 UpdateDragRectOverlay();
2557 nPagebreakMouse
= SC_PD_NONE
;
2560 SetPointer( Pointer( POINTER_ARROW
) );
2562 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2564 BOOL bRefMode
= pViewData
->IsRefMode();
2566 SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen
2569 else if ( rTEvt
.IsTrackingEnded() )
2571 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2572 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2573 // abgebrochen wurde.
2575 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2576 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2577 MouseButtonUp( aUpEvt
);
2583 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2585 if ( pFilterBox
|| nPagebreakMouse
)
2590 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, TRUE
);
2592 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2594 EditView
* pEditView
;
2597 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2599 // #63263# don't remove the edit view while switching views
2600 ScModule
* pScMod
= SC_MOD();
2601 pScMod
->SetInEditCommand( TRUE
);
2603 pEditView
->Command( aDragEvent
);
2605 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2607 pHdl
->DataChanged();
2609 pScMod
->SetInEditCommand( FALSE
);
2610 if (!pViewData
->IsActive()) // dropped to different view?
2612 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2613 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2615 pViewHdl
->CancelHandler();
2616 ShowCursor(); // missing from KillEditView
2621 if ( !DrawCommand(aDragEvent
) )
2622 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2625 void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2627 SCCOL nCol
= pViewData
->GetCurX();
2628 SCROW nRow
= pViewData
->GetCurY();
2629 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, TRUE
);
2630 aEditArea
.Right() = aEditArea
.Left();
2631 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2632 pWin
->SetCursorRect( &aEditArea
);
2635 void __EXPORT
ScGridWindow::Command( const CommandEvent
& rCEvt
)
2637 // The command event is send to the window after a possible context
2638 // menu from an inplace client is closed. Now we have the chance to
2639 // deactivate the inplace client without any problem regarding parent
2640 // windows and code on the stack.
2641 // For more information, see #126086# and #128122#
2642 USHORT nCmd
= rCEvt
.GetCommand();
2643 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2644 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2646 pClient
->IsObjectInPlaceActive() &&
2647 nCmd
== COMMAND_CONTEXTMENU
)
2649 pTabViewSh
->DeactivateOle();
2653 ScModule
* pScMod
= SC_MOD();
2654 DBG_ASSERT( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2656 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2657 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2658 nCmd
== COMMAND_EXTTEXTINPUT
||
2659 nCmd
== COMMAND_CURSORPOS
)
2661 BOOL bEditView
= pViewData
->HasEditView( eWhich
);
2664 // only if no cell editview is active, look at drawview
2665 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2668 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2669 if ( pOlView
&& pOlView
->GetWindow() == this )
2671 pOlView
->Command( rCEvt
);
2677 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2679 // #88458# CURSORPOS may be called without following text input,
2680 // to set the input method window position
2681 // -> input mode must not be started,
2682 // manually calculate text insert position if not in input mode
2684 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2688 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2691 pHdl
->InputCommand( rCEvt
, TRUE
);
2695 Window::Command( rCEvt
);
2699 if ( nCmd
== COMMAND_VOICE
)
2701 // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
2702 // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
2704 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2705 if ( pHdl
&& pViewData
->HasEditView( eWhich
) )
2707 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2708 pHdl
->DataChanging();
2709 pEditView
->Command( rCEvt
);
2710 pHdl
->DataChanged();
2713 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2716 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2717 if ( pOlView
&& pOlView
->GetWindow() == this )
2719 pOlView
->Command( rCEvt
);
2723 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
2727 if ( nCmd
== COMMAND_PASTESELECTION
)
2731 // EditEngine handles selection in MouseButtonUp - no action
2732 // needed in command handler
2736 PasteSelection( rCEvt
.GetMousePosPixel() );
2741 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2743 // #i55929# Font and font size state depends on input language if nothing is selected,
2744 // so the slots have to be invalidated when the input language is changed.
2746 SfxBindings
& rBindings
= pViewData
->GetBindings();
2747 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2748 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2752 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2754 BOOL bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2756 Window::Command(rCEvt
);
2759 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2760 BOOL bDisable
= pScMod
->IsFormulaMode() ||
2761 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2765 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2767 if (pViewData
->IsAnyFillMode())
2769 pViewData
->GetView()->StopRefMode();
2770 pViewData
->ResetFillMode();
2775 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2776 Point aMenuPos
= aPosPixel
;
2777 BOOL bMouse
= rCEvt
.IsMouseEvent();
2783 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2784 ScDocument
* pDoc
= pViewData
->GetDocument();
2785 SCTAB nTab
= pViewData
->GetTabNo();
2786 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
2787 bool bSelectAllowed
= true;
2788 if ( pProtect
&& pProtect
->isProtected() )
2790 // This sheet is protected. Check if a context menu is allowed on this cell.
2791 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
2792 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2793 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2796 bSelectAllowed
= bSelProtected
;
2798 bSelectAllowed
= bSelUnprotected
;
2800 if (!bSelectAllowed
)
2801 // Selecting this cell is not allowed, neither is context menu.
2804 // #i18735# First select the item under the mouse pointer.
2805 // This can change the selection, and the view state (edit mode, etc).
2806 SelectForContextMenu( aPosPixel
, nCellX
, nCellY
);
2810 BOOL bEdit
= pViewData
->HasEditView(eWhich
);
2813 // Edit-Zelle mit Spelling-Errors ?
2814 if ( bMouse
&& GetEditUrlOrError( TRUE
, aPosPixel
) )
2816 // GetEditUrlOrError hat den Cursor schon bewegt
2818 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2819 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
2821 DBG_ASSERT( bEdit
, "kann nicht in Edit-Modus schalten" );
2826 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2830 Cursor
* pCur
= pEditView
->GetCursor();
2833 Point aLogicPos
= pCur
->GetPos();
2834 // use the position right of the cursor (spell popup is opened if
2835 // the cursor is before the word, but not if behind it)
2836 aLogicPos
.X() += pCur
->GetWidth();
2837 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
2838 aMenuPos
= LogicToPixel( aLogicPos
);
2842 // if edit mode was just started above, online spelling may be incomplete
2843 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
2845 // IsCursorAtWrongSpelledWord could be used for !bMouse
2846 // if there was a corresponding ExecuteSpellPopup call
2848 if( pEditView
->IsWrongSpelledWordAtPos( aMenuPos
) )
2850 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2851 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2853 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2855 pHdl
->SetModified();
2857 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
2858 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
2865 // non-edit menu by keyboard -> use lower right of cell cursor position
2867 SCCOL nCurX
= pViewData
->GetCurX();
2868 SCROW nCurY
= pViewData
->GetCurY();
2869 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, TRUE
);
2872 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
2873 aMenuPos
.X() += nSizeXPix
;
2874 aMenuPos
.Y() += nSizeYPix
;
2878 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
2881 // Is a draw object selected?
2883 SdrView
* pDrawView
= pViewSh
->GetSdrView();
2884 if (pDrawView
&& pDrawView
->AreObjectsMarked())
2886 // #100442#; the conext menu should open in the middle of the selected objects
2887 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
2888 aMenuPos
= aSelectRect
.Center();
2896 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
2901 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
2903 // #i18735# if the click was outside of the current selection,
2904 // the cursor is moved or an object at the click position selected.
2905 // (see SwEditWin::SelectMenuPosition in Writer)
2907 ScTabView
* pView
= pViewData
->GetView();
2908 ScDrawView
* pDrawView
= pView
->GetScDrawView();
2910 // check cell edit mode
2912 if ( pViewData
->HasEditView(eWhich
) )
2914 ScModule
* pScMod
= SC_MOD();
2915 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
2916 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
2917 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
2918 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
2920 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
2921 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
2923 // handle selection within the EditView
2925 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
2926 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
2927 Rectangle aOutputArea
= pEditView
->GetOutputArea();
2928 Rectangle aVisArea
= pEditView
->GetVisArea();
2930 Point aTextPos
= PixelToLogic( rPosPixel
);
2931 if ( pEditEngine
->IsVertical() ) // have to manually transform position
2933 aTextPos
-= aOutputArea
.TopRight();
2934 long nTemp
= -aTextPos
.X();
2935 aTextPos
.X() = aTextPos
.Y();
2936 aTextPos
.Y() = nTemp
;
2939 aTextPos
-= aOutputArea
.TopLeft();
2940 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2942 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
2943 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2944 ESelection aSelection
= pEditView
->GetSelection();
2945 aSelection
.Adjust(); // needed for IsLess/IsGreater
2946 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2948 // clicked outside the selected text - deselect and move text cursor
2949 MouseEvent
aEvent( rPosPixel
);
2950 pEditView
->MouseButtonDown( aEvent
);
2951 pEditView
->MouseButtonUp( aEvent
);
2952 pScMod
->InputSelection( pEditView
);
2955 return; // clicked within the edit view - keep edit mode
2959 // outside of the edit view - end edit mode, regardless of cell selection, then continue
2960 pScMod
->InputEnterHandler();
2964 // check draw text edit mode
2966 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
2967 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
2969 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
2970 Rectangle aOutputArea
= pOlView
->GetOutputArea();
2971 if ( aOutputArea
.IsInside( aLogicPos
) )
2973 // handle selection within the OutlinerView
2975 Outliner
* pOutliner
= pOlView
->GetOutliner();
2976 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
2977 Rectangle aVisArea
= pOlView
->GetVisArea();
2979 Point aTextPos
= aLogicPos
;
2980 if ( pOutliner
->IsVertical() ) // have to manually transform position
2982 aTextPos
-= aOutputArea
.TopRight();
2983 long nTemp
= -aTextPos
.X();
2984 aTextPos
.X() = aTextPos
.Y();
2985 aTextPos
.Y() = nTemp
;
2988 aTextPos
-= aOutputArea
.TopLeft();
2989 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
2991 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
2992 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
2993 ESelection aSelection
= pOlView
->GetSelection();
2994 aSelection
.Adjust(); // needed for IsLess/IsGreater
2995 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
2997 // clicked outside the selected text - deselect and move text cursor
2998 // use DrawView to allow extra handling there (none currently)
2999 MouseEvent
aEvent( rPosPixel
);
3000 pDrawView
->MouseButtonDown( aEvent
, this );
3001 pDrawView
->MouseButtonUp( aEvent
, this );
3004 return; // clicked within the edit area - keep edit mode
3008 // Outside of the edit area - end text edit mode, then continue.
3009 // DrawDeselectAll also ends text edit mode and updates the shells.
3010 // If the click was on the edited object, it will be selected again below.
3011 pView
->DrawDeselectAll();
3015 // look for existing selection
3017 BOOL bHitSelected
= FALSE
;
3018 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3020 // clicked on selected object -> don't change anything
3021 bHitSelected
= TRUE
;
3023 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3025 // clicked on selected cell -> don't change anything
3026 bHitSelected
= TRUE
;
3029 // select drawing object or move cell cursor
3031 if ( !bHitSelected
)
3033 BOOL bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3034 BOOL bHitDraw
= FALSE
;
3037 pDrawView
->UnmarkAllObj();
3038 // Unlock the Internal Layer in order to activate the context menu.
3039 // re-lock in ScDrawView::MarkListHasChanged()
3040 lcl_UnLockComment( pDrawView
, pDrawView
->GetSdrPageView(), pDrawView
->GetModel(), aLogicPos
,pViewData
);
3041 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3042 // draw shell is activated in MarkListHasChanged
3047 pView
->SetCursor(nCellX
, nCellY
);
3049 pViewData
->GetViewShell()->SetDrawShell( FALSE
); // switch shells
3054 static void ClearSingleSelection( ScViewData
* pViewData
)
3058 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard(
3059 pViewData
->GetActiveWin() );
3063 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
3064 pClipDoc
->GetClipArea( nX
, nY
, TRUE
);
3065 if (nX
== 0 && nY
== 0)
3067 ScTabView
* pView
= pViewData
->GetView();
3072 void __EXPORT
ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3074 // #96965# Cursor control for ref input dialog
3075 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3076 if( SC_MOD()->IsRefDialogOpen() )
3078 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3080 SC_MOD()->EndReference();
3083 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3086 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3087 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3088 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3092 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3094 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3096 ScCellShell::PasteFromClipboard( pViewData
, pTabViewShell
, FALSE
);
3097 ClearSingleSelection( pViewData
);
3099 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3100 TransferableHelper::GetSystemClipboard();
3101 if (xSystemClipboard
.is())
3103 xSystemClipboard
->setContents(
3104 uno::Reference
<datatransfer::XTransferable
>(),
3105 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3108 // hide the border around the copy source
3109 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3110 UpdateCopySourceOverlay();
3113 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3114 else if( !pViewData
->IsAnyFillMode() )
3116 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3118 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3119 UpdateCopySourceOverlay();
3121 // query for existing note marker before calling ViewShell's keyboard handling
3122 // which may remove the marker
3123 BOOL bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3124 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3126 if (pViewData
->GetDocShell()->GetProgress())
3129 if (DrawKeyInput(rKEvt
))
3132 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3133 { //! DrawShell abfragen !!!
3134 if (pViewSh
->TabKeyInput(rKEvt
))
3138 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3141 KeyCode aCode
= rKEvt
.GetKeyCode();
3142 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3144 if ( bHadKeyMarker
)
3150 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3152 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3153 // (hard-coded because F1 can't be configured)
3155 if ( bHadKeyMarker
)
3156 HideNoteMarker(); // hide when previously visible
3158 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), TRUE
);
3161 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3163 pViewSh
->DetectiveMarkPred();
3166 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3168 pViewSh
->DetectiveMarkSucc();
3174 Window::KeyInput(rKEvt
);
3177 void ScGridWindow::StopMarking()
3179 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3183 pViewData
->GetMarkData().SetMarking(FALSE
);
3184 nMouseStatus
= SC_GM_IGNORE
;
3188 void ScGridWindow::UpdateInputContext()
3190 BOOL bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3191 ULONG nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3193 // when font from InputContext is used,
3194 // it must be taken from the cursor position's cell attributes
3196 InputContext aContext
;
3197 aContext
.SetOptions( nOptions
);
3198 SetInputContext( aContext
);
3201 //--------------------------------------------------------
3203 // sensitiver Bereich (Pixel)
3204 #define SCROLL_SENSITIVE 20
3206 BOOL
ScGridWindow::DropScroll( const Point
& rMousePos
)
3208 /* doch auch auf nicht aktiven Views...
3209 if ( !pViewData->IsActive() )
3214 Size aSize
= GetOutputSizePixel();
3216 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3218 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3220 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3221 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3224 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3226 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3228 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3229 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3233 if ( nDx
!= 0 || nDy
!= 0 )
3236 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3239 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3241 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3244 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3250 BOOL
lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3252 // Testet, ob bei eingeschalteten RedLining,
3253 // bei einem Drop ein Scenario betroffen ist.
3255 BOOL bReturn
= FALSE
;
3256 SCTAB nTab
= aDragRange
.aStart
.Tab();
3257 SCTAB nTabCount
= pDoc
->GetTableCount();
3259 if(pDoc
->GetChangeTrack()!=NULL
)
3261 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3267 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3269 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3280 ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3282 SCCOL nCol1
= nPosX
;
3283 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3284 if ( nCol2
> MAXCOL
)
3286 nCol1
-= nCol2
- MAXCOL
;
3289 SCROW nRow1
= nPosY
;
3290 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3291 if ( nRow2
> MAXROW
)
3293 nRow1
-= nRow2
- MAXROW
;
3297 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3300 //--------------------------------------------------------
3302 extern BOOL bPasteIsDrop
; // viewfun4 -> move to header
3303 extern BOOL bPasteIsMove
; // viewfun7 -> move to header
3305 //--------------------------------------------------------
3307 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3309 if ( rEvt
.mbLeaving
)
3312 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3314 UpdateDragRectOverlay();
3315 return rEvt
.mnAction
;
3318 const ScDragData
& rData
= SC_MOD()->GetDragData();
3319 if ( rData
.pCellTransfer
)
3321 // Don't move source that would include filtered rows.
3322 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3327 UpdateDragRectOverlay();
3329 return DND_ACTION_NONE
;
3332 Point aPos
= rEvt
.maPosPixel
;
3334 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3335 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3336 if (pSourceDoc
== pThisDoc
)
3338 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
)) )
3340 if (bDragRect
) // Rechteck loeschen
3342 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3344 UpdateDragRectOverlay();
3347 //! highlight chart? (selection border?)
3349 sal_Int8 nRet
= rEvt
.mnAction
;
3350 //! if ( rEvt.GetAction() == DROP_LINK )
3351 //! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart
3356 //! if ( rEvt.GetAction() == DROP_MOVE )
3357 //! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY
3360 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3362 BOOL bOk
= pThisDoc
->IsDocEditable();
3363 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3368 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3370 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3371 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3372 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3373 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3374 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3375 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3376 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3378 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3379 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3381 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3382 if (nNewDragX
<0) nNewDragX
=0;
3383 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3384 nNewDragX
= MAXCOL
-(nSizeX
-1);
3385 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3386 if (nNewDragY
<0) nNewDragY
=0;
3387 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3388 nNewDragY
= MAXROW
-(nSizeY
-1);
3390 // don't break scenario ranges, don't drop on filtered
3391 SCTAB nTab
= pViewData
->GetTabNo();
3392 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3393 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3394 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3395 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3399 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3401 UpdateDragRectOverlay();
3403 return DND_ACTION_NONE
;
3406 InsCellCmd eDragInsertMode
= INS_NONE
;
3407 Window::PointerState aState
= GetPointerState();
3409 // check for datapilot item sorting
3410 ScDPObject
* pDPObj
= NULL
;
3411 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3413 // drop on DataPilot table: sort or nothing
3415 bool bDPSort
= false;
3416 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3418 sheet::DataPilotTableHeaderData aDestData
;
3419 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3420 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3422 // look through the source range
3423 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3424 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3426 sheet::DataPilotTableHeaderData aSourceData
;
3427 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3428 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| !aSourceData
.MemberName
.getLength() )
3429 bValid
= false; // empty (subtotal) or different field
3435 String aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3436 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3439 ScRange aOutRange
= pDPObj
->GetOutRange();
3441 USHORT nOrient
= pDim
->GetOrientation();
3442 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3444 eDragInsertMode
= INS_CELLSRIGHT
;
3445 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3448 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3450 eDragInsertMode
= INS_CELLSDOWN
;
3451 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3460 // no valid sorting in a DataPilot table -> disallow
3464 UpdateDragRectOverlay();
3466 return DND_ACTION_NONE
;
3469 else if ( aState
.mnState
& KEY_MOD2
)
3471 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3473 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3474 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3475 if ( nDeltaX
<= nDeltaY
)
3477 eDragInsertMode
= INS_CELLSDOWN
;
3481 eDragInsertMode
= INS_CELLSRIGHT
;
3484 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3485 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3486 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3487 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3488 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3489 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3494 UpdateDragRectOverlay();
3496 return DND_ACTION_NONE
;
3501 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3503 eDragInsertMode
= INS_CELLSDOWN
;
3508 eDragInsertMode
= INS_CELLSRIGHT
;
3513 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3514 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3515 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3518 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3520 nDragStartX
= nNewDragX
;
3521 nDragStartY
= nNewDragY
;
3522 nDragEndX
= nDragStartX
+nSizeX
-1;
3523 nDragEndY
= nDragStartY
+nSizeY
-1;
3525 meDragInsertMode
= eDragInsertMode
;
3527 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3529 UpdateDragRectOverlay();
3531 // show target position as tip help
3533 if (Help::IsQuickHelpEnabled())
3535 ScRange
aRange( nDragStartX
, nDragStartY
, nTab
, nDragEndX
, nDragEndY
, nTab
);
3537 aRange
.Format( aHelpStr
, SCA_VALID
); // non-3D
3539 Point aPos
= Pointer::GetPosPixel();
3540 USHORT nAlign
= QUICKHELP_BOTTOM
|QUICKHELP_RIGHT
;
3541 Rectangle
aRect( aPos
, aPos
);
3542 Help::ShowQuickHelp(aRect
, aHelpStr
, nAlign
);
3548 return rEvt
.mnAction
;
3551 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3553 const ScDragData
& rData
= SC_MOD()->GetDragData();
3554 if ( rEvt
.mbLeaving
)
3556 DrawMarkDropObj( NULL
);
3557 if ( rData
.pCellTransfer
)
3558 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3560 return rEvt
.mnAction
;
3563 if ( pViewData
->GetDocShell()->IsReadOnly() )
3564 return DND_ACTION_NONE
;
3567 sal_Int8 nRet
= DND_ACTION_NONE
;
3569 if (rData
.pCellTransfer
)
3571 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3572 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3573 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3574 DropScroll( rEvt
.maPosPixel
);
3576 nRet
= AcceptPrivateDrop( rEvt
);
3580 if ( rData
.aLinkDoc
.Len() )
3583 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3584 if (pDocSh
&& pDocSh
->HasName())
3585 aThisName
= pDocSh
->GetMedium()->GetName();
3587 if ( rData
.aLinkDoc
!= aThisName
)
3588 nRet
= rEvt
.mnAction
;
3590 else if (rData
.aJumpTarget
.Len())
3592 // internal bookmarks (from Navigator)
3593 // local jumps from an unnamed document are possible only within a document
3595 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3596 nRet
= rEvt
.mnAction
;
3600 sal_Int8 nMyAction
= rEvt
.mnAction
;
3602 if ( !rData
.pDrawTransfer
||
3603 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3604 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3605 nMyAction
= DND_ACTION_COPY
;
3607 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3608 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3609 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3610 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
&& !rData
.pDrawTransfer
)
3612 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3613 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3614 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3616 // graphic dragged onto drawing object
3617 DrawMarkDropObj( pHitObj
);
3622 DrawMarkDropObj( NULL
);
3626 switch ( nMyAction
)
3628 case DND_ACTION_COPY
:
3629 case DND_ACTION_MOVE
:
3630 case DND_ACTION_COPYMOVE
:
3632 BOOL bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3633 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3634 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3635 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3636 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3637 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3638 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3639 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3640 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3641 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3642 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3643 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3644 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3645 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3646 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3647 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3648 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3649 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3650 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3652 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3653 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3654 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3655 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3656 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3657 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3663 case DND_ACTION_LINK
:
3664 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3665 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3666 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3667 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3668 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3669 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3670 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3671 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3672 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3681 // Simple check for protection: It's not known here if the drop will result
3682 // in cells or drawing objects (some formats can be both) and how many cells
3683 // the result will be. But if IsFormatEditable for the drop cell position
3684 // is FALSE (ignores matrix formulas), nothing can be pasted, so the drop
3685 // can already be rejected here.
3687 Point aPos
= rEvt
.maPosPixel
;
3690 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3691 SCTAB nTab
= pViewData
->GetTabNo();
3692 ScDocument
* pDoc
= pViewData
->GetDocument();
3694 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3695 if ( !aTester
.IsFormatEditable() )
3696 nRet
= DND_ACTION_NONE
; // forbidden
3701 // scroll only for accepted formats
3703 DropScroll( rEvt
.maPosPixel
);
3709 ULONG
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3711 TransferableDataHelper
aDataHelper( xTransfer
);
3713 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3715 // use bookmark formats if no sba is present
3717 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3718 return SOT_FORMATSTR_ID_SOLK
;
3719 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3720 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3721 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3722 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3723 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3724 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3727 ULONG nFormatId
= 0;
3728 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3729 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3730 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3731 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3732 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3734 // If it's a Writer object, insert RTF instead of OLE
3736 BOOL bDoRtf
= FALSE
;
3737 SotStorageStreamRef xStm
;
3738 TransferableObjectDescriptor aObjDesc
;
3739 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3740 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3742 SotStorageRef
xStore( new SotStorage( *xStm
) );
3743 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3744 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3745 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3748 nFormatId
= FORMAT_RTF
;
3750 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3752 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3753 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3754 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3755 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3756 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3757 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3758 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3759 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3760 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3761 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3762 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3763 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3764 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3765 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3766 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3767 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3768 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3769 nFormatId
= SOT_FORMAT_RTF
;
3770 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3771 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3772 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3773 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3774 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3775 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3776 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3777 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3778 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3779 nFormatId
= SOT_FORMAT_STRING
;
3780 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3781 nFormatId
= SOT_FORMAT_FILE_LIST
;
3782 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3783 nFormatId
= SOT_FORMAT_FILE
;
3784 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3785 nFormatId
= SOT_FORMAT_STRING
;
3786 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3787 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3788 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3789 nFormatId
= SOT_FORMAT_BITMAP
;
3794 ULONG
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3796 TransferableDataHelper
aDataHelper( xTransfer
);
3798 ULONG nFormatId
= 0;
3799 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3800 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3801 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3802 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3803 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3804 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3805 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3806 nFormatId
= SOT_FORMAT_FILE_LIST
;
3807 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
3808 nFormatId
= SOT_FORMAT_FILE
;
3809 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3810 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
3811 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3812 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3813 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3814 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3815 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3816 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3822 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
3826 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3828 UpdateDragRectOverlay();
3830 ScModule
* pScMod
= SC_MOD();
3831 const ScDragData
& rData
= pScMod
->GetDragData();
3833 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
3834 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
3837 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
3838 const Point
& rLogicPos
, sal_Int8 nDndAction
)
3843 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
3844 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3845 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3846 ScViewFunc
* pView
= pViewData
->GetView();
3847 SCTAB nThisTab
= pViewData
->GetTabNo();
3848 USHORT nFlags
= pTransObj
->GetDragSourceFlags();
3850 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
3851 BOOL bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
3853 // workaround for wrong nDndAction on Windows when pressing solely
3854 // the Alt key during drag and drop;
3855 // can be removed after #i79215# has been fixed
3856 if ( meDragInsertMode
!= INS_NONE
)
3858 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
3861 BOOL bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
3863 ScRange aSource
= pTransObj
->GetRange();
3865 // only use visible tab from source range - when dragging within one table,
3866 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3867 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
3868 aSource
.aStart
.SetTab( nSourceTab
);
3869 aSource
.aEnd
.SetTab( nSourceTab
);
3871 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
3872 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
3873 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
3874 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
3875 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
3878 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3879 * dragging and adapted drawing of the selection frame. We check here
3880 * (again) because this may actually also be called from PasteSelection(),
3881 * we would have to duplicate determination of flags and destination range
3882 * and would lose the context of the "filtered destination is OK" cases
3883 * below, which is already awkward enough as is. */
3885 // Don't move filtered source.
3886 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
3889 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
3890 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
3892 // Nothing. Either entire sheet to be dropped, or the one case
3893 // where PasteFromClip() is to be called that handles a filtered
3894 // destination itself. Drag-copy from another document without
3898 // Don't copy or move to filtered destination.
3899 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
3904 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
3906 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
3908 if ( pThisDoc
->IsDocEditable() )
3910 SCTAB nSrcTab
= aSource
.aStart
.Tab();
3911 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, TRUE
); // with Undo
3912 pView
->SetTabNo( nThisTab
, TRUE
);
3916 else // move/copy block
3919 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, &aChartName
))
3922 aSource
.Format( aRangeName
, SCR_ABS_3D
, pThisDoc
);
3923 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
3924 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
3925 USHORT nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
3926 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
3927 &aRangeItem
, &aNameItem
, (void*) NULL
);
3930 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
3932 // drop on DataPilot table: try to sort, fail if that isn't possible
3934 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
3935 if ( aDestPos
!= aSource
.aStart
)
3936 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
3938 bDone
= TRUE
; // same position: nothing
3940 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
3941 nSourceTab
!= nThisTab
)
3943 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
3944 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
3947 if ( meDragInsertMode
!= INS_NONE
)
3949 // call with bApi = TRUE to avoid error messages in drop handler
3950 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
3953 if ( nThisTab
== nSourceTab
)
3955 if ( meDragInsertMode
== INS_CELLSDOWN
&&
3956 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
3958 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
3960 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
3961 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
3963 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
3966 pDocSh
->UpdateOle( pViewData
);
3967 pView
->CellContentChanged();
3975 // call with bApi = TRUE to avoid error messages in drop handler
3976 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, TRUE
/*bApi*/ );
3980 // call with bApi = TRUE to avoid error messages in drop handler
3981 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, TRUE
/*bRecord*/, TRUE
/*bPaint*/, TRUE
/*bApi*/ );
3985 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
3987 DelCellCmd eCmd
= DEL_NONE
;
3988 if ( meDragInsertMode
== INS_CELLSDOWN
)
3992 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
3994 eCmd
= DEL_CELLSLEFT
;
3997 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
3998 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
4000 // call with bApi = TRUE to avoid error messages in drop handler
4001 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, TRUE
/*bRecord*/, TRUE
/*bApi*/ );
4004 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4006 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4008 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4010 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4012 pDocSh
->UpdateOle( pViewData
);
4013 pView
->CellContentChanged();
4020 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4022 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col();
4023 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row();
4024 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4027 pDocSh
->GetUndoManager()->LeaveListAction();
4030 Sound::Beep(); // instead of error message in drop handler
4033 bDone
= TRUE
; // nothing to do
4037 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4039 else if ( !bFiltered
&& pSourceDoc
) // between documents
4041 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4043 if ( pThisDoc
->IsDocEditable() )
4045 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4047 SCTAB nTabs
[MAXTABCOUNT
];
4049 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4050 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4051 SCTAB nTabSelCount
= 0;
4053 for(SCTAB i
=0; i
<nTabCount
; i
++)
4055 if(aMark
.GetTableSelect(i
))
4057 nTabs
[nTabSelCount
++]=i
;
4058 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4060 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4062 nTabs
[nTabSelCount
++]=j
;
4070 pView
->ImportTables( pSrcShell
,nTabSelCount
, nTabs
, bIsLink
, nThisTab
);
4077 // (external references might be used instead?)
4079 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4080 DBG_ASSERT(pSourceSh
, "drag document has no shell");
4083 String aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4084 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4087 if ( meDragInsertMode
!= INS_NONE
)
4089 // call with bApi = TRUE to avoid error messages in drop handler
4090 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4093 pDocSh
->UpdateOle( pViewData
);
4094 pView
->CellContentChanged();
4100 String aApp
= Application::GetAppName();
4101 String aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4103 aSource
.Format( aItem
, SCA_VALID
| SCA_TAB_3D
, pSourceDoc
);
4105 // TODO: we could define ocQuote for "
4106 const String
aQuote( '"' );
4107 const String
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4108 String
aFormula( '=' );
4109 aFormula
+= ScCompiler::GetNativeSymbol( ocDde
);
4110 aFormula
+= ScCompiler::GetNativeSymbol( ocOpen
);
4122 aFormula
+= ScCompiler::GetNativeSymbol( ocClose
);
4124 pView
->DoneBlockMode();
4125 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4126 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4127 nDestPosY
+ nSizeY
- 1, nThisTab
);
4129 pView
->EnterMatrix( aFormula
);
4131 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4132 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4135 pDocSh
->GetUndoManager()->LeaveListAction();
4140 //! HasSelectedBlockMatrixFragment without selected sheet?
4141 //! or don't start dragging on a part of a matrix
4143 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4144 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4147 if ( meDragInsertMode
!= INS_NONE
)
4149 // call with bApi = TRUE to avoid error messages in drop handler
4150 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, TRUE
/*bRecord*/, TRUE
/*bApi*/, TRUE
/*bPartOfPaste*/ );
4153 pDocSh
->UpdateOle( pViewData
);
4154 pView
->CellContentChanged();
4160 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4161 pView
->SetCursor( nDestPosX
, nDestPosY
);
4162 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4165 pView
->MarkRange( aDest
, FALSE
, FALSE
);
4166 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4170 pDocSh
->GetUndoManager()->LeaveListAction();
4172 // no longer call ResetMark here - the inserted block has been selected
4173 // and may have been copied to primary selection
4177 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4181 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4183 DrawMarkDropObj( NULL
); // drawing layer
4185 ScModule
* pScMod
= SC_MOD();
4186 const ScDragData
& rData
= pScMod
->GetDragData();
4187 if (rData
.pCellTransfer
)
4188 return ExecutePrivateDrop( rEvt
);
4190 Point aPos
= rEvt
.maPosPixel
;
4192 if ( rData
.aLinkDoc
.Len() )
4194 // try to insert a link
4198 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4199 if (pDocSh
&& pDocSh
->HasName())
4200 aThisName
= pDocSh
->GetMedium()->GetName();
4202 if ( rData
.aLinkDoc
== aThisName
) // error - no link within a document
4206 ScViewFunc
* pView
= pViewData
->GetView();
4207 if ( rData
.aLinkTable
.Len() )
4208 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4210 else if ( rData
.aLinkArea
.Len() )
4214 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4215 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, FALSE
, FALSE
);
4217 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4218 rData
.aLinkArea
, 0 );
4222 DBG_ERROR("drop with link: no sheet nor area");
4227 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4230 Point aLogicPos
= PixelToLogic(aPos
);
4232 if (rData
.pDrawTransfer
)
4234 USHORT nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4236 BOOL bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4237 BOOL bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4239 bPasteIsMove
= bIsMove
;
4241 pViewData
->GetView()->PasteDraw( aLogicPos
, rData
.pDrawTransfer
->GetModel() );
4244 rData
.pDrawTransfer
->SetDragWasInternal();
4245 bPasteIsMove
= FALSE
;
4247 return rEvt
.mnAction
;
4253 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4255 if (rData
.aJumpTarget
.Len())
4257 // internal bookmark (from Navigator)
4258 // bookmark clipboard formats are in PasteScDataObject
4260 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4262 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4264 return rEvt
.mnAction
;
4268 BOOL bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4270 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4271 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4272 if ( pHitObj
&& bIsLink
)
4274 // dropped on drawing object
4275 // PasteOnDrawObject checks for valid formats
4276 if ( pViewData
->GetView()->PasteOnDrawObject( rEvt
.maDropEvent
.Transferable
, pHitObj
, TRUE
) )
4277 return rEvt
.mnAction
;
4282 ULONG nFormatId
= bIsLink
?
4283 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4284 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4287 pScMod
->SetInExecuteDrop( TRUE
); // #i28468# prevent error messages from PasteDataFormat
4288 bPasteIsDrop
= TRUE
;
4289 bDone
= pViewData
->GetView()->PasteDataFormat(
4290 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4291 bPasteIsDrop
= FALSE
;
4292 pScMod
->SetInExecuteDrop( FALSE
);
4295 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4299 //--------------------------------------------------------
4301 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4303 Point aLogicPos
= PixelToLogic( rPosPixel
);
4307 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4309 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4310 if ( pOwnSelection
)
4314 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4315 if ( pCellTransfer
)
4317 // keep a reference to the data in case the selection is changed during paste
4318 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4319 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4323 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4324 if ( pDrawTransfer
)
4326 // keep a reference to the data in case the selection is changed during paste
4327 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4329 // #96821# bSameDocClipboard argument for PasteDraw is needed
4330 // because only DragData is checked directly inside PasteDraw
4331 pViewData
->GetView()->PasteDraw( aLogicPos
, pDrawTransfer
->GetModel(), FALSE
,
4332 pDrawTransfer
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
4338 // get selection from system
4340 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4341 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4342 if ( xTransferable
.is() )
4344 ULONG nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4347 bPasteIsDrop
= TRUE
;
4348 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4349 bPasteIsDrop
= FALSE
;
4355 //--------------------------------------------------------
4357 void ScGridWindow::UpdateEditViewPos()
4359 if (pViewData
->HasEditView(eWhich
))
4364 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4365 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4366 SCROW nEndRow
= pViewData
->GetEditEndRow();
4370 BOOL bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4371 if ( SC_MOD()->IsFormulaMode() )
4372 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4377 Rectangle aRect
= pView
->GetOutputArea();
4378 long nHeight
= aRect
.Bottom() - aRect
.Top();
4379 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4381 aRect
.Bottom() = aRect
.Top() + nHeight
;
4382 pView
->SetOutputArea( aRect
);
4383 pView
->HideCursor();
4387 // bForceToTop = TRUE for editing
4388 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, TRUE
);
4389 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4391 Rectangle aRect
= pView
->GetOutputArea();
4392 aRect
.SetPos( aScrPos
);
4393 pView
->SetOutputArea( aRect
);
4394 pView
->ShowCursor();
4399 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4405 //BOOL bXor=DrawBeforeScroll();
4407 SetMapMode(MAP_PIXEL
);
4408 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4409 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4411 UpdateEditViewPos();
4413 DrawAfterScroll(); //bXor);
4414 bIsInScroll
= FALSE
;
4417 // Formeln neu zeichnen -------------------------------------------------
4419 void ScGridWindow::UpdateFormulas()
4421 if (pViewData
->GetView()->IsMinimized())
4426 // nicht anfangen, verschachtelt zu painten
4427 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4429 bNeedsRepaint
= TRUE
; // -> am Ende vom Paint nochmal Invalidate auf alles
4430 aRepaintPixel
= Rectangle(); // alles
4434 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4435 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4436 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4437 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4439 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4440 if (nY2
> MAXROW
) nY2
= MAXROW
;
4442 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4444 // don't draw directly - instead use OutputData to find changed area and invalidate
4448 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4449 ScDocument
* pDoc
= pDocSh
->GetDocument();
4450 SCTAB nTab
= pViewData
->GetTabNo();
4452 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4454 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4455 long nMirrorWidth
= GetSizePixel().Width();
4456 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4457 // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
4460 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4461 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4462 aScrPos
.X() = nEndPixel
+ 1;
4465 long nScrX
= aScrPos
.X();
4466 long nScrY
= aScrPos
.Y();
4468 double nPPTX
= pViewData
->GetPPTX();
4469 double nPPTY
= pViewData
->GetPPTY();
4471 ScTableInfo aTabInfo
;
4472 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, FALSE
, FALSE
);
4474 Fraction aZoomX
= pViewData
->GetZoomX();
4475 Fraction aZoomY
= pViewData
->GetZoomY();
4476 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4477 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4479 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4481 aOutputData
.FindChanged();
4483 PolyPolygon
aChangedPoly( aOutputData
.GetChangedArea() ); // logic (PixelToLogic)
4484 if ( aChangedPoly
.Count() )
4486 Invalidate( aChangedPoly
);
4489 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4492 void ScGridWindow::UpdateAutoFillMark(BOOL bMarked
, const ScRange
& rMarkRange
)
4494 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4497 bAutoMarkVisible
= bMarked
;
4499 aAutoMarkPos
= rMarkRange
.aEnd
;
4502 UpdateAutoFillOverlay();
4506 void ScGridWindow::UpdateListValPos( BOOL bVisible
, const ScAddress
& rPos
)
4508 BOOL bOldButton
= bListValButton
;
4509 ScAddress aOldPos
= aListValPos
;
4511 bListValButton
= bVisible
;
4514 if ( bListValButton
)
4516 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4518 // paint area of new button
4519 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4524 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4526 // paint area of old button
4527 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4532 void ScGridWindow::HideCursor()
4535 if (nCursorHideCount
==1)
4542 void ScGridWindow::ShowCursor()
4544 if (nCursorHideCount
==0)
4546 DBG_ERROR("zuviel ShowCursor");
4550 if (nCursorHideCount
==1)
4552 // #i57745# Draw the cursor before setting the variable, in case the
4553 // GetSizePixel call from drawing causes a repaint (resize handler is called)
4561 void __EXPORT
ScGridWindow::GetFocus()
4563 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4564 pViewShell
->GotFocus();
4565 pViewShell
->SetFormShellAtTop( FALSE
); // focus in GridWindow -> FormShell no longer on top
4567 if (pViewShell
->HasAccessibilityObjects())
4568 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4571 if ( !SC_MOD()->IsFormulaMode() )
4573 pViewShell
->UpdateInputHandler();
4574 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4575 // MO: nur wenn nicht im RefInput-Modus
4576 // -> GetFocus/MouseButtonDown-Reihenfolge
4583 void __EXPORT
ScGridWindow::LoseFocus()
4585 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4586 pViewShell
->LostFocus();
4588 if (pViewShell
->HasAccessibilityObjects())
4589 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4591 Window::LoseFocus();
4594 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4596 //------------------------------------------------------------------------
4598 BOOL
ScGridWindow::HitRangeFinder( const Point
& rMouse
, BOOL
& rCorner
,
4599 USHORT
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4601 BOOL bFound
= FALSE
;
4602 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4605 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4606 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4607 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4609 ScDocument
* pDoc
= pViewData
->GetDocument();
4610 SCTAB nTab
= pViewData
->GetTabNo();
4611 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4612 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4616 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4617 // zusammengefasste (einzeln/Bereich) ???
4618 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4620 // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
4622 Point aNext
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, TRUE
);
4625 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4626 aNext
.X() += nSizeXPix
* nLayoutSign
;
4627 aNext
.Y() += nSizeYPix
;
4631 bCornerHor
= ( rMouse
.X() >= aNext
.X() && rMouse
.X() <= aNext
.X() + 8 );
4633 bCornerHor
= ( rMouse
.X() >= aNext
.X() - 8 && rMouse
.X() <= aNext
.X() );
4635 BOOL bCellCorner
= ( bCornerHor
&&
4636 rMouse
.Y() >= aNext
.Y() - 8 && rMouse
.Y() <= aNext
.Y() );
4637 // corner is hit only if the mouse is within the cell
4639 USHORT nCount
= (USHORT
)pRangeFinder
->Count();
4640 for (USHORT i
=nCount
; i
;)
4642 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4644 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4645 if ( pData
&& pData
->aRef
.In(aAddr
) )
4647 if (pIndex
) *pIndex
= i
;
4648 if (pAddX
) *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4649 if (pAddY
) *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4651 rCorner
= ( bCellCorner
&& aAddr
== pData
->aRef
.aEnd
);
4661 #define SCE_BOTTOM 2
4666 void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, USHORT nEdges
)
4668 // der Range ist immer richtigherum
4670 SCCOL nCol1
= rRange
.aStart
.Col();
4671 SCROW nRow1
= rRange
.aStart
.Row();
4672 SCTAB nTab1
= rRange
.aStart
.Tab();
4673 SCCOL nCol2
= rRange
.aEnd
.Col();
4674 SCROW nRow2
= rRange
.aEnd
.Row();
4675 SCTAB nTab2
= rRange
.aEnd
.Tab();
4676 BOOL bHiddenEdge
= FALSE
;
4679 ScDocument
* pDoc
= pDocSh
->GetDocument();
4680 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4685 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4690 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4691 if (!ValidRow(nTmp
))
4698 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4699 if (!ValidRow(nTmp
))
4707 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4709 // nur an den Raendern entlang
4710 // (die Ecken werden evtl. zweimal getroffen)
4712 if ( nEdges
& SCE_TOP
)
4713 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4714 if ( nEdges
& SCE_LEFT
)
4715 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4716 if ( nEdges
& SCE_RIGHT
)
4717 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4718 if ( nEdges
& SCE_BOTTOM
)
4719 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4721 else // everything in one call
4722 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4725 void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4727 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4729 ScRange aOld
= rOldUn
;
4730 ScRange aNew
= rNewUn
;
4734 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4735 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4736 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4737 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4739 SCCOL nOldCol1
= aOld
.aStart
.Col();
4740 SCROW nOldRow1
= aOld
.aStart
.Row();
4741 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4742 SCROW nOldRow2
= aOld
.aEnd
.Row();
4743 SCCOL nNewCol1
= aNew
.aStart
.Col();
4744 SCROW nNewRow1
= aNew
.aStart
.Row();
4745 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4746 SCROW nNewRow2
= aNew
.aEnd
.Row();
4747 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4748 SCTAB nTab2
= aOld
.aEnd
.Tab();
4750 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4751 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4752 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4753 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4755 // komplett weggeschoben oder alle Seiten veraendert
4756 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4758 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4760 else // alle vier Kanten einzeln testen
4763 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4764 lcl_PaintOneRange( pDocSh
, ScRange(
4765 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4766 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4767 lcl_PaintOneRange( pDocSh
, ScRange(
4768 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4769 SCE_ALL
&~ SCE_BOTTOM
);
4772 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4773 lcl_PaintOneRange( pDocSh
, ScRange(
4774 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4775 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4776 lcl_PaintOneRange( pDocSh
, ScRange(
4777 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4778 SCE_ALL
&~ SCE_TOP
);
4781 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
4782 lcl_PaintOneRange( pDocSh
, ScRange(
4783 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
4784 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
4785 lcl_PaintOneRange( pDocSh
, ScRange(
4786 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
4787 SCE_ALL
&~ SCE_RIGHT
);
4790 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
4791 lcl_PaintOneRange( pDocSh
, ScRange(
4792 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4793 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
4794 lcl_PaintOneRange( pDocSh
, ScRange(
4795 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4796 SCE_ALL
&~ SCE_LEFT
);
4800 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, BOOL bUp
)
4802 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4805 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4806 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
4808 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
4815 SetPointer( Pointer( POINTER_CROSS
) );
4817 SetPointer( Pointer( POINTER_HAND
) );
4821 BOOL bTimer
= FALSE
;
4822 Point aPos
= rMEvt
.GetPosPixel();
4825 if ( aPos
.X() < 0 ) nDx
= -1;
4826 if ( aPos
.Y() < 0 ) nDy
= -1;
4827 Size aSize
= GetOutputSizePixel();
4828 if ( aPos
.X() >= aSize
.Width() )
4830 if ( aPos
.Y() >= aSize
.Height() )
4832 if ( nDx
!= 0 || nDy
!= 0 )
4834 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
4835 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
4839 // Umschalten bei Fixierung (damit Scrolling funktioniert)
4841 if ( eWhich
== pViewData
->GetActivePart() ) //??
4843 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
4846 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4847 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
4848 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
4849 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4852 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
4855 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4856 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
4857 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
4858 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4866 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4868 ScRange aOld
= pData
->aRef
;
4869 ScRange aNew
= aOld
;
4872 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
4873 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
4877 long nStartX
= nPosX
- nRFAddX
;
4878 if ( nStartX
< 0 ) nStartX
= 0;
4879 long nStartY
= nPosY
- nRFAddY
;
4880 if ( nStartY
< 0 ) nStartY
= 0;
4881 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
4882 if ( nEndX
> MAXCOL
)
4884 nStartX
-= ( nEndX
- MAXROW
);
4887 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
4888 if ( nEndY
> MAXROW
)
4890 nStartY
-= ( nEndY
- MAXROW
);
4894 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
4895 aNew
.aStart
.SetRow((SCROW
)nStartY
);
4896 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
4897 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
4901 aNew
.Justify(); // beim ButtonUp wieder richtigherum
4905 pHdl
->UpdateRange( nRFIndex
, aNew
);
4907 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4909 // nur das neuzeichnen, was sich veraendert hat...
4910 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
4912 // neuen Rahmen nur drueberzeichnen (synchron)
4913 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
4915 Update(); // was man bewegt, will man auch sofort sehen
4918 // Timer fuer Scrolling
4921 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
4923 pViewData
->GetView()->ResetTimer();
4926 //------------------------------------------------------------------------
4928 BOOL
ScGridWindow::GetEditUrl( const Point
& rPos
,
4929 String
* pName
, String
* pUrl
, String
* pTarget
)
4931 return GetEditUrlOrError( FALSE
, rPos
, pName
, pUrl
, pTarget
);
4934 BOOL
ScGridWindow::GetEditUrlOrError( BOOL bSpellErr
, const Point
& rPos
,
4935 String
* pName
, String
* pUrl
, String
* pTarget
)
4937 //! nPosX/Y mit uebergeben?
4940 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
4942 SCTAB nTab
= pViewData
->GetTabNo();
4943 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4944 ScDocument
* pDoc
= pDocSh
->GetDocument();
4945 ScBaseCell
* pCell
= NULL
;
4947 BOOL bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
4951 ScHideTextCursor
aHideCursor( pViewData
, eWhich
); // before GetEditArea (MapMode is changed)
4953 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
4954 // bForceToTop = FALSE, use the cell's real position
4955 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, FALSE
);
4956 if (rPos
.Y() < aEditRect
.Top())
4959 // vertikal kann (noch) nicht angeklickt werden:
4961 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
4964 BOOL bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
4965 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
4966 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
4967 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
4968 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
4972 ScFieldEditEngine
aEngine( pDoc
->GetEditPool() );
4973 ScSizeDeviceProvider
aProv(pDocSh
);
4974 aEngine
.SetRefDevice( aProv
.GetDevice() );
4975 aEngine
.SetRefMapMode( MAP_100TH_MM
);
4976 SfxItemSet
aDefault( aEngine
.GetEmptyItemSet() );
4977 pPattern
->FillEditItemSet( &aDefault
);
4978 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
4981 case SVX_HOR_JUSTIFY_LEFT
:
4982 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
4983 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
4984 eSvxAdjust
= SVX_ADJUST_LEFT
;
4986 case SVX_HOR_JUSTIFY_RIGHT
:
4987 eSvxAdjust
= SVX_ADJUST_RIGHT
;
4989 case SVX_HOR_JUSTIFY_CENTER
:
4990 eSvxAdjust
= SVX_ADJUST_CENTER
;
4992 case SVX_HOR_JUSTIFY_BLOCK
:
4993 eSvxAdjust
= SVX_ADJUST_BLOCK
;
4996 aDefault
.Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
4997 aEngine
.SetDefaults( aDefault
);
4999 aEngine
.SetControlWord( aEngine
.GetControlWord() | EE_CNTRL_ONLINESPELLING
);
5001 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
5002 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5003 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5004 Size aPaperSize
= Size( 1000000, 1000000 );
5005 if(pCell
->GetCellType() == CELLTYPE_FORMULA
)
5009 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5010 aPaperSize
= Size(nSizeX
, nSizeY
);
5011 aPaperSize
= PixelToLogic(aPaperSize
);
5015 aPaperSize
.Width() = nThisColLogic
;
5016 aEngine
.SetPaperSize( aPaperSize
);
5018 ::std::auto_ptr
< EditTextObject
> pTextObj
;
5019 const EditTextObject
* pData
;
5020 if(pCell
->GetCellType() == CELLTYPE_EDIT
)
5022 ((ScEditCell
*)pCell
)->GetData(pData
);
5024 aEngine
.SetText(*pData
);
5026 else // HyperLink Formula cell
5028 pTextObj
.reset((static_cast<ScFormulaCell
*>(pCell
))->CreateURLObject());
5030 aEngine
.SetText(*pTextObj
);
5033 long nStartX
= aLogicEdit
.Left();
5035 long nTextWidth
= aEngine
.CalcTextWidth();
5036 long nTextHeight
= aEngine
.GetTextHeight();
5037 if ( nTextWidth
< nThisColLogic
)
5039 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5040 nStartX
+= nThisColLogic
- nTextWidth
;
5041 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5042 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5045 aLogicEdit
.Left() = nStartX
;
5047 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5049 // There is one glitch when dealing with a hyperlink cell and
5050 // the cell content is NUMERIC. This defaults to right aligned and
5051 // we need to adjust accordingly.
5052 if(pCell
->GetCellType() == CELLTYPE_FORMULA
&&
5053 static_cast<ScFormulaCell
*>(pCell
)->IsValue() &&
5054 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5056 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5057 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5059 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5062 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5063 if ( aLogicEdit
.IsInside(aLogicClick
) )
5065 // aEngine.SetUpdateMode(FALSE);
5066 EditView
aTempView( &aEngine
, this );
5067 aTempView
.SetOutputArea( aLogicEdit
);
5070 MapMode aOld
= GetMapMode();
5071 SetMapMode(aEditMode
); // kein return mehr
5073 if (bSpellErr
) // Spelling-Fehler suchen
5075 bRet
= aTempView
.IsWrongSpelledWordAtPos( rPos
);
5077 pViewData
->GetView()->SetCursor( nPosX
, nPosY
); // Cursor setzen
5081 const SvxFieldItem
* pFieldItem
= aTempView
.GetFieldUnderMousePointer();
5085 const SvxFieldData
* pField
= pFieldItem
->GetField();
5086 if ( pField
&& pField
->ISA(SvxURLField
) )
5088 if ( pName
|| pUrl
|| pTarget
)
5090 const SvxURLField
* pURLField
= (const SvxURLField
*)pField
;
5092 *pName
= pURLField
->GetRepresentation();
5094 *pUrl
= pURLField
->GetURL();
5096 *pTarget
= pURLField
->GetTargetFrame();
5105 // text cursor is restored in ScHideTextCursor dtor
5112 BOOL
ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5114 ScDocument
* pDoc
= pViewData
->GetDocument();
5115 SCTAB nTab
= pViewData
->GetTabNo();
5116 SCTAB nTabCount
= pDoc
->GetTableCount();
5117 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5119 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5121 Size aButSize
= pViewData
->GetScenButSize();
5122 long nBWidth
= aButSize
.Width();
5124 return FALSE
; // noch kein Button gezeichnet -> da ist auch keiner
5125 long nBHeight
= aButSize
.Height();
5126 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5128 //! Ranges an der Table cachen!!!!
5131 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5132 pDoc
->MarkScenario( i
, nTab
, aMarks
, FALSE
, SC_SCENARIO_SHOWFRAME
);
5133 ScRangeList aRanges
;
5134 aMarks
.FillRangeListWithMarks( &aRanges
, FALSE
);
5137 ULONG nRangeCount
= aRanges
.Count();
5138 for (ULONG j
=0; j
<nRangeCount
; j
++)
5140 ScRange aRange
= *aRanges
.GetObject(j
);
5141 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5142 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5143 pDoc
->ExtendTotalMerge( aRange
);
5145 BOOL bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5150 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5155 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5157 aButtonPos
.Y() -= nBHeight
;
5160 aButtonPos
.X() -= nHSpace
- 1;
5162 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5164 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5165 if ( aButRect
.IsInside( rPosPixel
) )
5167 rScenRange
= aRange
;
5177 void ScGridWindow::DrawLayerCreated()
5179 SetMapMode( GetDrawMapMode() );
5181 // initially create overlay objects
5182 ImpCreateOverlayObjects();
5186 void ScGridWindow::CursorChanged()
5188 // here the created OverlayObjects may be transformed in later versions. For
5189 // now, just re-create them
5191 UpdateCursorOverlay();
5195 void ScGridWindow::ImpCreateOverlayObjects()
5197 UpdateCursorOverlay();
5198 UpdateCopySourceOverlay();
5199 UpdateSelectionOverlay();
5200 UpdateAutoFillOverlay();
5201 UpdateDragRectOverlay();
5202 UpdateHeaderOverlay();
5203 UpdateShrinkOverlay();
5207 void ScGridWindow::ImpDestroyOverlayObjects()
5209 DeleteCursorOverlay();
5210 DeleteCopySourceOverlay();
5211 DeleteSelectionOverlay();
5212 DeleteAutoFillOverlay();
5213 DeleteDragRectOverlay();
5214 DeleteHeaderOverlay();
5215 DeleteShrinkOverlay();
5218 void ScGridWindow::UpdateAllOverlays()
5220 // delete and re-allocate all overlay objects
5222 ImpDestroyOverlayObjects();
5223 ImpCreateOverlayObjects();
5226 void ScGridWindow::DeleteCursorOverlay()
5228 DELETEZ( mpOOCursors
);
5231 void ScGridWindow::DeleteCopySourceOverlay()
5233 DELETEZ( mpOOSelectionBorder
);
5236 void ScGridWindow::UpdateCopySourceOverlay()
5238 MapMode aDrawMode
= GetDrawMapMode();
5239 MapMode aOldMode
= GetMapMode();
5240 if ( aOldMode
!= aDrawMode
)
5241 SetMapMode( aDrawMode
);
5243 DeleteCopySourceOverlay();
5245 if (!pViewData
->ShowPasteSource())
5247 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5248 if (!pOverlayManager
)
5250 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5253 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5257 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5259 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5260 mpOOSelectionBorder
= new ::sdr::overlay::OverlayObjectList
;
5261 for (ScRange
* p
= rClipParam
.maRanges
.First(); p
; p
= rClipParam
.maRanges
.Next())
5263 if (p
->aStart
.Tab() != nCurTab
)
5266 SCCOL nClipStartX
= p
->aStart
.Col();
5267 SCROW nClipStartY
= p
->aStart
.Row();
5268 SCCOL nClipEndX
= p
->aEnd
.Col();
5269 SCROW nClipEndY
= p
->aEnd
.Row();
5271 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5272 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5273 aClipStartScrPos
-= Point(1, 1);
5274 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5275 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5277 Rectangle
aRect( aClipStartScrPos
, Size(nSizeXPix
, nSizeYPix
) );
5280 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5282 Rectangle aLogic
= PixelToLogic(aRect
, aDrawMode
);
5283 ::basegfx::B2DRange
aRange(aLogic
.Left(), aLogic
.Top(), aLogic
.Right(), aLogic
.Bottom());
5284 ScOverlayDashedBorder
* pDashedBorder
= new ScOverlayDashedBorder(aRange
, aHighlight
, this);
5285 pOverlayManager
->add(*pDashedBorder
);
5286 mpOOSelectionBorder
->append(*pDashedBorder
);
5289 if ( aOldMode
!= aDrawMode
)
5290 SetMapMode( aOldMode
);
5293 void ScGridWindow::UpdateCursorOverlay()
5295 MapMode aDrawMode
= GetDrawMapMode();
5296 MapMode aOldMode
= GetMapMode();
5297 if ( aOldMode
!= aDrawMode
)
5298 SetMapMode( aDrawMode
);
5300 // Existing OverlayObjects may be transformed in later versions.
5301 // For now, just re-create them.
5303 DeleteCursorOverlay();
5305 std::vector
<Rectangle
> aPixelRects
;
5308 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5311 SCTAB nTab
= pViewData
->GetTabNo();
5312 SCCOL nX
= pViewData
->GetCurX();
5313 SCROW nY
= pViewData
->GetCurY();
5315 if (!maVisibleRange
.isInside(nX
, nY
))
5318 // don't show the cursor in overlapped cells
5320 ScDocument
* pDoc
= pViewData
->GetDocument();
5321 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5322 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5323 BOOL bOverlapped
= rMergeFlag
.IsOverlapped();
5325 // left or above of the screen?
5327 BOOL bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5332 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5333 if (rMerge
.GetColMerge() > 1)
5334 nEndX
+= rMerge
.GetColMerge()-1;
5335 if (rMerge
.GetRowMerge() > 1)
5336 nEndY
+= rMerge
.GetRowMerge()-1;
5337 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5340 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5342 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5343 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5345 // completely right of/below the screen?
5346 // (test with logical start position in aScrPos)
5349 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5352 Size aOutSize
= GetOutputSizePixel();
5353 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5355 if ( bMaybeVisible
)
5359 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5362 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5364 // Now, draw the cursor.
5368 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5370 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5371 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5372 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5373 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5377 if ( aPixelRects
.size() )
5379 // #i70788# get the OverlayManager safely
5380 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5384 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5385 if (pViewData
->GetActivePart() != eWhich
)
5386 // non-active pane uses a different color.
5387 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5388 std::vector
< basegfx::B2DRange
> aRanges
;
5389 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5391 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5393 const Rectangle
aRA(aPixelRects
[a
]);
5394 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5395 aRB
.transform(aTransform
);
5396 aRanges
.push_back(aRB
);
5399 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5400 sdr::overlay::OVERLAY_SOLID
,
5405 pOverlayManager
->add(*pOverlay
);
5406 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5407 mpOOCursors
->append(*pOverlay
);
5411 if ( aOldMode
!= aDrawMode
)
5412 SetMapMode( aOldMode
);
5415 void ScGridWindow::DeleteSelectionOverlay()
5417 DELETEZ( mpOOSelection
);
5420 void ScGridWindow::UpdateSelectionOverlay()
5422 MapMode aDrawMode
= GetDrawMapMode();
5423 MapMode aOldMode
= GetMapMode();
5424 if ( aOldMode
!= aDrawMode
)
5425 SetMapMode( aDrawMode
);
5427 DeleteSelectionOverlay();
5428 std::vector
<Rectangle
> aPixelRects
;
5429 GetSelectionRects( aPixelRects
);
5431 if ( aPixelRects
.size() && pViewData
->IsActive() )
5433 // #i70788# get the OverlayManager safely
5434 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5438 std::vector
< basegfx::B2DRange
> aRanges
;
5439 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5441 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5443 const Rectangle
aRA(aPixelRects
[a
]);
5444 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
5445 aRB
.transform(aTransform
);
5446 aRanges
.push_back(aRB
);
5449 // #i97672# get the system's hilight color and limit it to the maximum
5450 // allowed luminance. This is needed to react on too bright hilight colors
5451 // which would otherwise vive a bad visualisation
5452 Color
aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
5453 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
5454 const basegfx::BColor
aSelection(aHighlight
.getBColor());
5455 const double fLuminance(aSelection
.luminance());
5456 const double fMaxLum(aSvtOptionsDrawinglayer
.GetSelectionMaximumLuminancePercent() / 100.0);
5458 if(fLuminance
> fMaxLum
)
5460 const double fFactor(fMaxLum
/ fLuminance
);
5461 const basegfx::BColor
aNewSelection(
5462 aSelection
.getRed() * fFactor
,
5463 aSelection
.getGreen() * fFactor
,
5464 aSelection
.getBlue() * fFactor
);
5466 aHighlight
= Color(aNewSelection
);
5469 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5470 sdr::overlay::OVERLAY_TRANSPARENT
,
5475 pOverlayManager
->add(*pOverlay
);
5476 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5477 mpOOSelection
->append(*pOverlay
);
5481 if ( aOldMode
!= aDrawMode
)
5482 SetMapMode( aOldMode
);
5485 void ScGridWindow::DeleteAutoFillOverlay()
5487 DELETEZ( mpOOAutoFill
);
5488 mpAutoFillRect
.reset();
5491 void ScGridWindow::UpdateAutoFillOverlay()
5493 MapMode aDrawMode
= GetDrawMapMode();
5494 MapMode aOldMode
= GetMapMode();
5495 if ( aOldMode
!= aDrawMode
)
5496 SetMapMode( aDrawMode
);
5498 DeleteAutoFillOverlay();
5501 // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
5504 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5505 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5507 SCCOL nX
= aAutoMarkPos
.Col();
5508 SCROW nY
= aAutoMarkPos
.Row();
5510 if (!maVisibleRange
.isInside(nX
, nY
))
5511 // Autofill mark is not visible. Bail out.
5514 SCTAB nTab
= pViewData
->GetTabNo();
5515 ScDocument
* pDoc
= pViewData
->GetDocument();
5516 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5518 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, TRUE
);
5521 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5523 aFillPos
.X() -= nSizeXPix
+ 3;
5525 aFillPos
.X() += nSizeXPix
- 2;
5527 aFillPos
.Y() += nSizeYPix
;
5529 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
5531 // #i70788# get the OverlayManager safely
5532 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5536 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5537 if (pViewData
->GetActivePart() != eWhich
)
5538 // non-active pane uses a different color.
5539 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5540 std::vector
< basegfx::B2DRange
> aRanges
;
5541 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5542 basegfx::B2DRange
aRB(mpAutoFillRect
->Left(), mpAutoFillRect
->Top(), mpAutoFillRect
->Right() + 1, mpAutoFillRect
->Bottom() + 1);
5544 aRB
.transform(aTransform
);
5545 aRanges
.push_back(aRB
);
5547 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5548 sdr::overlay::OVERLAY_SOLID
,
5553 pOverlayManager
->add(*pOverlay
);
5554 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
5555 mpOOAutoFill
->append(*pOverlay
);
5558 if ( aOldMode
!= aDrawMode
)
5559 SetMapMode( aOldMode
);
5563 void ScGridWindow::DeleteDragRectOverlay()
5565 DELETEZ( mpOODragRect
);
5568 void ScGridWindow::UpdateDragRectOverlay()
5570 MapMode aDrawMode
= GetDrawMapMode();
5571 MapMode aOldMode
= GetMapMode();
5572 if ( aOldMode
!= aDrawMode
)
5573 SetMapMode( aDrawMode
);
5575 DeleteDragRectOverlay();
5578 // get the rectangles in pixels (moved from DrawDragRect)
5581 if ( bDragRect
|| bPagebreakDrawn
)
5583 std::vector
<Rectangle
> aPixelRects
;
5585 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
5586 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
5587 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
5588 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
5590 SCTAB nTab
= pViewData
->GetTabNo();
5592 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
5593 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
5594 if (nX1
< nPosX
) nX1
= nPosX
;
5595 if (nX2
< nPosX
) nX2
= nPosX
;
5596 if (nY1
< nPosY
) nY1
= nPosY
;
5597 if (nY2
< nPosY
) nY2
= nPosY
;
5599 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
5603 ScDocument
* pDoc
= pViewData
->GetDocument();
5604 double nPPTX
= pViewData
->GetPPTX();
5605 double nPPTY
= pViewData
->GetPPTY();
5608 BOOL bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5609 long nLayoutSign
= bLayoutRTL
? -1 : 1;
5611 if (ValidCol(nX2
) && nX2
>=nX1
)
5612 for (i
=nX1
; i
<=nX2
; i
++)
5613 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
5616 aScrPos
.X() -= nLayoutSign
;
5620 if (ValidRow(nY2
) && nY2
>=nY1
)
5621 for (i
=nY1
; i
<=nY2
; i
++)
5622 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
5629 aScrPos
.X() -= 2 * nLayoutSign
;
5631 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5632 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
5633 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
5636 aRect
.Left() = aRect
.Right(); // end position is left
5637 aRect
.Right() = aScrPos
.X();
5640 if ( meDragInsertMode
== INS_CELLSDOWN
)
5642 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
5643 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
5644 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
5645 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5647 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
5649 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
5650 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5651 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
5652 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
5656 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
5657 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
5658 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
5659 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
5662 // #i70788# get the OverlayManager safely
5663 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5667 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5668 std::vector
< basegfx::B2DRange
> aRanges
;
5669 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5671 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5673 const Rectangle
aRA(aPixelRects
[a
]);
5674 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5675 aRB
.transform(aTransform
);
5676 aRanges
.push_back(aRB
);
5679 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5680 sdr::overlay::OVERLAY_INVERT
,
5685 pOverlayManager
->add(*pOverlay
);
5686 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
5687 mpOODragRect
->append(*pOverlay
);
5691 if ( aOldMode
!= aDrawMode
)
5692 SetMapMode( aOldMode
);
5695 void ScGridWindow::DeleteHeaderOverlay()
5697 DELETEZ( mpOOHeader
);
5700 void ScGridWindow::UpdateHeaderOverlay()
5702 MapMode aDrawMode
= GetDrawMapMode();
5703 MapMode aOldMode
= GetMapMode();
5704 if ( aOldMode
!= aDrawMode
)
5705 SetMapMode( aDrawMode
);
5707 DeleteHeaderOverlay();
5709 // Pixel rectangle is in aInvertRect
5710 if ( !aInvertRect
.IsEmpty() )
5712 // #i70788# get the OverlayManager safely
5713 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5717 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5718 std::vector
< basegfx::B2DRange
> aRanges
;
5719 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5720 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
5722 aRB
.transform(aTransform
);
5723 aRanges
.push_back(aRB
);
5725 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5726 sdr::overlay::OVERLAY_INVERT
,
5731 pOverlayManager
->add(*pOverlay
);
5732 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
5733 mpOOHeader
->append(*pOverlay
);
5737 if ( aOldMode
!= aDrawMode
)
5738 SetMapMode( aOldMode
);
5741 void ScGridWindow::DeleteShrinkOverlay()
5743 DELETEZ( mpOOShrink
);
5746 void ScGridWindow::UpdateShrinkOverlay()
5748 MapMode aDrawMode
= GetDrawMapMode();
5749 MapMode aOldMode
= GetMapMode();
5750 if ( aOldMode
!= aDrawMode
)
5751 SetMapMode( aDrawMode
);
5753 DeleteShrinkOverlay();
5756 // get the rectangle in pixels
5761 SCTAB nTab
= pViewData
->GetTabNo();
5762 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
5763 pViewData
->GetDelMark( aRange
) )
5765 //! limit to visible area
5766 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
5767 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
5769 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
5770 aRange
.aStart
.Row(), eWhich
);
5771 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
5772 aRange
.aEnd
.Row()+1, eWhich
);
5776 aPixRect
= Rectangle( aStart
,aEnd
);
5780 if ( !aPixRect
.IsEmpty() )
5782 // #i70788# get the OverlayManager safely
5783 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5787 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5788 std::vector
< basegfx::B2DRange
> aRanges
;
5789 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5790 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
5792 aRB
.transform(aTransform
);
5793 aRanges
.push_back(aRB
);
5795 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5796 sdr::overlay::OVERLAY_INVERT
,
5801 pOverlayManager
->add(*pOverlay
);
5802 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
5803 mpOOShrink
->append(*pOverlay
);
5807 if ( aOldMode
!= aDrawMode
)
5808 SetMapMode( aOldMode
);
5811 // #i70788# central method to get the OverlayManager safely
5812 ::sdr::overlay::OverlayManager
* ScGridWindow::getOverlayManager()
5814 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
5818 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
5822 return (pPageWin
->GetOverlayManager());
5829 void ScGridWindow::flushOverlayManager()
5831 // #i70788# get the OverlayManager safely
5832 ::sdr::overlay::OverlayManager
* pOverlayManager
= getOverlayManager();
5836 pOverlayManager
->flush();
5840 // ---------------------------------------------------------------------------