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