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