1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <editeng/outliner.hxx>
22 #include <editeng/outlobj.hxx>
23 #include <svx/svdotext.hxx>
24 #include <svx/svdouno.hxx>
25 #include <sfx2/dispatch.hxx>
27 #include "fuconstr.hxx"
29 #include "tabvwsh.hxx"
32 #include "drawview.hxx"
33 #include "document.hxx"
34 #include "gridwin.hxx"
36 // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
37 //! fusel,fuconstr,futext - zusammenfassen!
38 #define SC_MAXDRAGMOVE 3
40 //------------------------------------------------------------------------
42 /*************************************************************************
46 \************************************************************************/
48 FuConstruct::FuConstruct(ScTabViewShell
* pViewSh
, Window
* pWin
, ScDrawView
* pViewP
,
49 SdrModel
* pDoc
, SfxRequest
& rReq
) :
50 FuDraw(pViewSh
, pWin
, pViewP
, pDoc
, rReq
)
54 /*************************************************************************
58 \************************************************************************/
60 FuConstruct::~FuConstruct()
64 sal_uInt8
FuConstruct::Command(const CommandEvent
& rCEvt
)
66 return FuDraw::Command( rCEvt
);
69 // Calculate and return offset at current zoom. rInOutPos is adjusted by
70 // the calculated offset. rInOutPos now points to the position than when
71 // scaled to 100% actually would be at the position you see at the current zoom
72 // ( relative to the grid ) note: units are expected to be in 100th mm
73 Point
FuConstruct::CurrentGridSyncOffsetAndPos( Point
& rInOutPos
)
76 ScViewData
* pViewData
= pViewShell
->GetViewData();
77 ScDocument
* pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
78 if ( pViewData
&& pDoc
)
80 // rInOutPos mightn't be where you think it is if there is zoom
81 // involved. Lets calculate where aPos would be at 100% zoom
82 // that's the actual correct position for the object ( when you
84 sal_Bool bNegative
= pDoc
->IsNegativePage(pView
->GetTab());
85 Rectangle
aObjRect( rInOutPos
, rInOutPos
);
86 ScRange aRange
= pDoc
->GetRange( pView
->GetTab(), aObjRect
);
87 ScAddress aOldStt
= aRange
.aStart
;
88 Point
aOldPos( pDoc
->GetColOffset( aOldStt
.Col(), aOldStt
.Tab() ), pDoc
->GetRowOffset( aOldStt
.Row(), aOldStt
.Tab() ) );
89 aOldPos
.X() = sc::TwipsToHMM( aOldPos
.X() );
90 aOldPos
.Y() = sc::TwipsToHMM( aOldPos
.Y() );
91 ScSplitPos eWhich
= pViewData
->GetActivePart();
92 ScGridWindow
* pGridWin
= (ScGridWindow
*)pViewData
->GetActiveWin();
93 // and equiv screen pos
94 Point aScreenPos
= pViewShell
->GetViewData()->GetScrPos( aOldStt
.Col(), aOldStt
.Row(), eWhich
, sal_True
);
95 MapMode aDrawMode
= pGridWin
->GetDrawMapMode();
96 Point aCurPosHmm
= pGridWin
->PixelToLogic(aScreenPos
, aDrawMode
);
97 Point aOff
= ( rInOutPos
- aCurPosHmm
);
98 rInOutPos
= aOldPos
+ aOff
;
99 aRetGridOff
= aCurPosHmm
- aOldPos
;
100 // fdo#64011 fix the X position when the sheet are RTL
103 aRetGridOff
.setX( aCurPosHmm
.getX() + aOldPos
.getX() );
104 rInOutPos
.setX( aOff
.getX() - aOldPos
.getX() );
109 /*************************************************************************
111 |* MouseButtonDown-event
113 \************************************************************************/
115 sal_Bool
FuConstruct::MouseButtonDown(const MouseEvent
& rMEvt
)
117 // remember button state for creation of own MouseEvents
118 SetMouseButtonCode(rMEvt
.GetButtons());
120 sal_Bool bReturn
= FuDraw::MouseButtonDown(rMEvt
);
122 if ( pView
->IsAction() )
124 if ( rMEvt
.IsRight() )
131 aMDPos
= pWindow
->PixelToLogic( rMEvt
.GetPosPixel() );
133 if ( rMEvt
.IsLeft() )
135 pWindow
->CaptureMouse();
137 SdrHdl
* pHdl
= pView
->PickHandle(aMDPos
);
139 if ( pHdl
!= NULL
|| pView
->IsMarkedHit(aMDPos
) )
141 pView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
, 1);
144 else if ( pView
->AreObjectsMarked() )
151 bIsInDragMode
= false;
156 /*************************************************************************
160 \************************************************************************/
162 sal_Bool
FuConstruct::MouseMove(const MouseEvent
& rMEvt
)
164 FuDraw::MouseMove(rMEvt
);
166 if (aDragTimer
.IsActive() )
168 Point aOldPixel
= pWindow
->LogicToPixel( aMDPos
);
169 Point aNewPixel
= rMEvt
.GetPosPixel();
170 if ( std::abs( aOldPixel
.X() - aNewPixel
.X() ) > SC_MAXDRAGMOVE
||
171 std::abs( aOldPixel
.Y() - aNewPixel
.Y() ) > SC_MAXDRAGMOVE
)
175 Point
aPix(rMEvt
.GetPosPixel());
176 Point
aPnt( pWindow
->PixelToLogic(aPix
) );
178 // if object is being created then more than likely the mouse
179 // position has been 'adjusted' for the current zoom, need to
180 // restore the mouse position here to ensure resize works as expected
181 if ( pView
->GetCreateObj() )
182 aPnt
-= pView
->GetCreateObj()->GetGridOffset();
184 if ( pView
->IsAction() )
187 pView
->MovAction(aPnt
);
191 SdrHdl
* pHdl
=pView
->PickHandle(aPnt
);
195 pViewShell
->SetActivePointer(pHdl
->GetPointer());
197 else if ( pView
->IsMarkedHit(aPnt
) )
199 pViewShell
->SetActivePointer(Pointer(POINTER_MOVE
));
203 pViewShell
->SetActivePointer( aNewPointer
);
209 /*************************************************************************
211 |* MouseButtonUp-event
213 \************************************************************************/
215 sal_Bool
FuConstruct::MouseButtonUp(const MouseEvent
& rMEvt
)
217 // remember button state for creation of own MouseEvents
218 SetMouseButtonCode(rMEvt
.GetButtons());
220 sal_Bool bReturn
= SimpleMouseButtonUp( rMEvt
);
222 // Doppelklick auf Textobjekt? (->fusel)
224 sal_uInt16 nClicks
= rMEvt
.GetClicks();
225 if ( nClicks
== 2 && rMEvt
.IsLeft() )
227 if ( pView
->AreObjectsMarked() )
229 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
230 if (rMarkList
.GetMarkCount() == 1)
232 SdrMark
* pMark
= rMarkList
.GetMark(0);
233 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
235 // bei Uno-Controls nicht in Textmodus
236 if ( pObj
->ISA(SdrTextObj
) && !pObj
->ISA(SdrUnoObj
) )
238 OutlinerParaObject
* pOPO
= pObj
->GetOutlinerParaObject();
239 sal_Bool bVertical
= ( pOPO
&& pOPO
->IsVertical() );
240 sal_uInt16 nTextSlotId
= bVertical
? SID_DRAW_TEXT_VERTICAL
: SID_DRAW_TEXT
;
242 pViewShell
->GetViewData()->GetDispatcher().
243 Execute(nTextSlotId
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
245 // jetzt den erzeugten FuText holen und in den EditModus setzen
246 FuPoor
* pPoor
= pViewShell
->GetViewData()->GetView()->GetDrawFuncPtr();
247 if ( pPoor
&& pPoor
->GetSlotID() == nTextSlotId
) // hat keine RTTI
249 FuText
* pText
= (FuText
*)pPoor
;
250 Point aMousePixel
= rMEvt
.GetPosPixel();
251 pText
->SetInEditMode( pObj
, &aMousePixel
);
259 FuDraw::MouseButtonUp(rMEvt
);
264 // SimpleMouseButtonUp - ohne Test auf Doppelklick
266 sal_Bool
FuConstruct::SimpleMouseButtonUp(const MouseEvent
& rMEvt
)
268 sal_Bool bReturn
= sal_True
;
270 if (aDragTimer
.IsActive() )
275 Point
aPnt( pWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
277 if ( pView
->IsDragObj() )
278 pView
->EndDragObj( rMEvt
.IsMod1() );
280 else if ( pView
->IsMarkObj() )
283 else bReturn
= false;
285 if ( !pView
->IsAction() )
287 pWindow
->ReleaseMouse();
289 if ( !pView
->AreObjectsMarked() && rMEvt
.GetClicks() < 2 )
291 pView
->MarkObj(aPnt
, -2, false, rMEvt
.IsMod1());
293 SfxDispatcher
& rDisp
= pViewShell
->GetViewData()->GetDispatcher();
294 if ( pView
->AreObjectsMarked() )
295 rDisp
.Execute(SID_OBJECT_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
297 rDisp
.Execute(aSfxRequest
.GetSlot(), SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
304 /*************************************************************************
306 |* Tastaturereignisse bearbeiten
308 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
311 \************************************************************************/
313 sal_Bool
FuConstruct::KeyInput(const KeyEvent
& rKEvt
)
315 sal_Bool bReturn
= false;
317 switch ( rKEvt
.GetKeyCode().GetCode() )
320 if ( pView
->IsAction() )
323 pWindow
->ReleaseMouse();
326 else // Zeichenmodus beenden
328 pViewShell
->GetViewData()->GetDispatcher().
329 Execute(aSfxRequest
.GetSlot(), SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
334 pView
->DeleteMarked();
341 bReturn
= FuDraw::KeyInput(rKEvt
);
347 /*************************************************************************
349 |* Function aktivieren
351 \************************************************************************/
353 void FuConstruct::Activate()
358 /*************************************************************************
360 |* Function deaktivieren
362 \************************************************************************/
364 void FuConstruct::Deactivate()
366 FuDraw::Deactivate();
372 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */