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