Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
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>
26 :
27 : #include "fuconstr.hxx"
28 : #include "fudraw.hxx"
29 : #include "tabvwsh.hxx"
30 : #include "futext.hxx"
31 : #include "sc.hrc"
32 : #include "drawview.hxx"
33 : #include "document.hxx"
34 : #include "gridwin.hxx"
35 :
36 : // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten
37 : //! fusel,fuconstr,futext - zusammenfassen!
38 : #define SC_MAXDRAGMOVE 3
39 :
40 : /*************************************************************************
41 : |*
42 : |* Konstruktor
43 : |*
44 : \************************************************************************/
45 :
46 0 : FuConstruct::FuConstruct(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
47 : SdrModel* pDoc, SfxRequest& rReq) :
48 0 : FuDraw(pViewSh, pWin, pViewP, pDoc, rReq)
49 : {
50 0 : }
51 :
52 : /*************************************************************************
53 : |*
54 : |* Destruktor
55 : |*
56 : \************************************************************************/
57 :
58 0 : FuConstruct::~FuConstruct()
59 : {
60 0 : }
61 :
62 0 : sal_uInt8 FuConstruct::Command(const CommandEvent& rCEvt)
63 : {
64 0 : return FuDraw::Command( rCEvt );
65 : }
66 :
67 : // Calculate and return offset at current zoom. rInOutPos is adjusted by
68 : // the calculated offset. rInOutPos now points to the position than when
69 : // scaled to 100% actually would be at the position you see at the current zoom
70 : // ( relative to the grid ) note: units are expected to be in 100th mm
71 0 : Point FuConstruct::CurrentGridSyncOffsetAndPos( Point& rInOutPos )
72 : {
73 0 : Point aRetGridOff;
74 0 : ScViewData* pViewData = pViewShell->GetViewData();
75 0 : ScDocument* pDoc = pViewData ? pViewData->GetDocument() : NULL;
76 0 : if ( pViewData && pDoc )
77 : {
78 : // rInOutPos mightn't be where you think it is if there is zoom
79 : // involved. Lets calculate where aPos would be at 100% zoom
80 : // that's the actual correct position for the object ( when you
81 : // restore the zoom.
82 0 : sal_Bool bNegative = pDoc->IsNegativePage(pView->GetTab());
83 0 : Rectangle aObjRect( rInOutPos, rInOutPos );
84 0 : ScRange aRange = pDoc->GetRange( pView->GetTab(), aObjRect );
85 0 : ScAddress aOldStt = aRange.aStart;
86 0 : Point aOldPos( pDoc->GetColOffset( aOldStt.Col(), aOldStt.Tab() ), pDoc->GetRowOffset( aOldStt.Row(), aOldStt.Tab() ) );
87 0 : aOldPos.X() = sc::TwipsToHMM( aOldPos.X() );
88 0 : aOldPos.Y() = sc::TwipsToHMM( aOldPos.Y() );
89 0 : ScSplitPos eWhich = pViewData->GetActivePart();
90 0 : ScGridWindow* pGridWin = (ScGridWindow*)pViewData->GetActiveWin();
91 : // and equiv screen pos
92 0 : Point aScreenPos = pViewShell->GetViewData()->GetScrPos( aOldStt.Col(), aOldStt.Row(), eWhich, true );
93 0 : MapMode aDrawMode = pGridWin->GetDrawMapMode();
94 0 : Point aCurPosHmm = pGridWin->PixelToLogic(aScreenPos, aDrawMode );
95 0 : Point aOff = ( rInOutPos - aCurPosHmm );
96 0 : rInOutPos = aOldPos + aOff;
97 0 : aRetGridOff = aCurPosHmm - aOldPos;
98 : // fdo#64011 fix the X position when the sheet are RTL
99 0 : if ( bNegative )
100 : {
101 0 : aRetGridOff.setX( aCurPosHmm.getX() + aOldPos.getX() );
102 0 : rInOutPos.setX( aOff.getX() - aOldPos.getX() );
103 0 : }
104 : }
105 0 : return aRetGridOff;
106 : }
107 : /*************************************************************************
108 : |*
109 : |* MouseButtonDown-event
110 : |*
111 : \************************************************************************/
112 :
113 0 : bool FuConstruct::MouseButtonDown(const MouseEvent& rMEvt)
114 : {
115 : // remember button state for creation of own MouseEvents
116 0 : SetMouseButtonCode(rMEvt.GetButtons());
117 :
118 0 : bool bReturn = FuDraw::MouseButtonDown(rMEvt);
119 :
120 0 : if ( pView->IsAction() )
121 : {
122 0 : if ( rMEvt.IsRight() )
123 0 : pView->BckAction();
124 0 : return true;
125 : }
126 :
127 0 : aDragTimer.Start();
128 :
129 0 : aMDPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
130 :
131 0 : if ( rMEvt.IsLeft() )
132 : {
133 0 : pWindow->CaptureMouse();
134 :
135 0 : SdrHdl* pHdl = pView->PickHandle(aMDPos);
136 :
137 0 : if ( pHdl != NULL || pView->IsMarkedHit(aMDPos) )
138 : {
139 0 : pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, 1);
140 0 : bReturn = true;
141 : }
142 0 : else if ( pView->AreObjectsMarked() )
143 : {
144 0 : pView->UnmarkAll();
145 0 : bReturn = true;
146 : }
147 : }
148 :
149 0 : bIsInDragMode = false;
150 :
151 0 : return bReturn;
152 : }
153 :
154 : /*************************************************************************
155 : |*
156 : |* MouseMove-event
157 : |*
158 : \************************************************************************/
159 :
160 0 : bool FuConstruct::MouseMove(const MouseEvent& rMEvt)
161 : {
162 0 : FuDraw::MouseMove(rMEvt);
163 :
164 0 : if (aDragTimer.IsActive() )
165 : {
166 0 : Point aOldPixel = pWindow->LogicToPixel( aMDPos );
167 0 : Point aNewPixel = rMEvt.GetPosPixel();
168 0 : if ( std::abs( aOldPixel.X() - aNewPixel.X() ) > SC_MAXDRAGMOVE ||
169 0 : std::abs( aOldPixel.Y() - aNewPixel.Y() ) > SC_MAXDRAGMOVE )
170 0 : aDragTimer.Stop();
171 : }
172 :
173 0 : Point aPix(rMEvt.GetPosPixel());
174 0 : Point aPnt( pWindow->PixelToLogic(aPix) );
175 :
176 : // if object is being created then more than likely the mouse
177 : // position has been 'adjusted' for the current zoom, need to
178 : // restore the mouse position here to ensure resize works as expected
179 0 : if ( pView->GetCreateObj() )
180 0 : aPnt -= pView->GetCreateObj()->GetGridOffset();
181 :
182 0 : if ( pView->IsAction() )
183 : {
184 0 : ForceScroll(aPix);
185 0 : pView->MovAction(aPnt);
186 : }
187 : else
188 : {
189 0 : SdrHdl* pHdl=pView->PickHandle(aPnt);
190 :
191 0 : if ( pHdl != NULL )
192 : {
193 0 : pViewShell->SetActivePointer(pHdl->GetPointer());
194 : }
195 0 : else if ( pView->IsMarkedHit(aPnt) )
196 : {
197 0 : pViewShell->SetActivePointer(Pointer(POINTER_MOVE));
198 : }
199 : else
200 : {
201 0 : pViewShell->SetActivePointer( aNewPointer );
202 : }
203 : }
204 0 : return true;
205 : }
206 :
207 : /*************************************************************************
208 : |*
209 : |* MouseButtonUp-event
210 : |*
211 : \************************************************************************/
212 :
213 0 : bool FuConstruct::MouseButtonUp(const MouseEvent& rMEvt)
214 : {
215 : // remember button state for creation of own MouseEvents
216 0 : SetMouseButtonCode(rMEvt.GetButtons());
217 :
218 0 : bool bReturn = SimpleMouseButtonUp( rMEvt );
219 :
220 : // Doppelklick auf Textobjekt? (->fusel)
221 :
222 0 : sal_uInt16 nClicks = rMEvt.GetClicks();
223 0 : if ( nClicks == 2 && rMEvt.IsLeft() )
224 : {
225 0 : if ( pView->AreObjectsMarked() )
226 : {
227 0 : const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
228 0 : if (rMarkList.GetMarkCount() == 1)
229 : {
230 0 : SdrMark* pMark = rMarkList.GetMark(0);
231 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
232 :
233 : // bei Uno-Controls nicht in Textmodus
234 0 : if ( pObj->ISA(SdrTextObj) && !pObj->ISA(SdrUnoObj) )
235 : {
236 0 : OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
237 0 : sal_Bool bVertical = ( pOPO && pOPO->IsVertical() );
238 0 : sal_uInt16 nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
239 :
240 0 : pViewShell->GetViewData()->GetDispatcher().
241 0 : Execute(nTextSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
242 :
243 : // jetzt den erzeugten FuText holen und in den EditModus setzen
244 0 : FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
245 0 : if ( pPoor && pPoor->GetSlotID() == nTextSlotId ) // hat keine RTTI
246 : {
247 0 : FuText* pText = (FuText*)pPoor;
248 0 : Point aMousePixel = rMEvt.GetPosPixel();
249 0 : pText->SetInEditMode( pObj, &aMousePixel );
250 : }
251 0 : bReturn = true;
252 : }
253 : }
254 : }
255 : }
256 :
257 0 : FuDraw::MouseButtonUp(rMEvt);
258 :
259 0 : return bReturn;
260 : }
261 :
262 : // SimpleMouseButtonUp - ohne Test auf Doppelklick
263 :
264 0 : bool FuConstruct::SimpleMouseButtonUp(const MouseEvent& rMEvt)
265 : {
266 0 : bool bReturn = true;
267 :
268 0 : if (aDragTimer.IsActive() )
269 : {
270 0 : aDragTimer.Stop();
271 : }
272 :
273 0 : Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
274 :
275 0 : if ( pView->IsDragObj() )
276 0 : pView->EndDragObj( rMEvt.IsMod1() );
277 :
278 0 : else if ( pView->IsMarkObj() )
279 0 : pView->EndMarkObj();
280 :
281 0 : else bReturn = false;
282 :
283 0 : if ( !pView->IsAction() )
284 : {
285 0 : pWindow->ReleaseMouse();
286 :
287 0 : if ( !pView->AreObjectsMarked() && rMEvt.GetClicks() < 2 )
288 : {
289 0 : pView->MarkObj(aPnt, -2, false, rMEvt.IsMod1());
290 :
291 0 : SfxDispatcher& rDisp = pViewShell->GetViewData()->GetDispatcher();
292 0 : if ( pView->AreObjectsMarked() )
293 0 : rDisp.Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
294 : else
295 0 : rDisp.Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
296 : }
297 : }
298 :
299 0 : return bReturn;
300 : }
301 :
302 : /*************************************************************************
303 : |*
304 : |* Tastaturereignisse bearbeiten
305 : |*
306 : |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
307 : |* FALSE.
308 : |*
309 : \************************************************************************/
310 :
311 0 : bool FuConstruct::KeyInput(const KeyEvent& rKEvt)
312 : {
313 0 : bool bReturn = false;
314 :
315 0 : switch ( rKEvt.GetKeyCode().GetCode() )
316 : {
317 : case KEY_ESCAPE:
318 0 : if ( pView->IsAction() )
319 : {
320 0 : pView->BrkAction();
321 0 : pWindow->ReleaseMouse();
322 0 : bReturn = true;
323 : }
324 : else // Zeichenmodus beenden
325 : {
326 0 : pViewShell->GetViewData()->GetDispatcher().
327 0 : Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
328 : }
329 0 : break;
330 :
331 : case KEY_DELETE:
332 0 : pView->DeleteMarked();
333 0 : bReturn = true;
334 0 : break;
335 : }
336 :
337 0 : if ( !bReturn )
338 : {
339 0 : bReturn = FuDraw::KeyInput(rKEvt);
340 : }
341 :
342 0 : return bReturn;
343 : }
344 :
345 : /*************************************************************************
346 : |*
347 : |* Function aktivieren
348 : |*
349 : \************************************************************************/
350 :
351 0 : void FuConstruct::Activate()
352 : {
353 0 : FuDraw::Activate();
354 0 : }
355 :
356 : /*************************************************************************
357 : |*
358 : |* Function deaktivieren
359 : |*
360 : \************************************************************************/
361 :
362 0 : void FuConstruct::Deactivate()
363 : {
364 0 : FuDraw::Deactivate();
365 0 : }
366 :
367 :
368 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|