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 <svx/svdpagv.hxx>
21 #include <svx/svxids.hrc>
22 #include <editeng/sizeitem.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <svl/ptitem.hxx>
25
26 #include <tabvwsh.hxx>
27 #include <gridwin.hxx>
28 #include <dbfunc.hxx>
29 #include <viewdata.hxx>
30 #include <output.hxx>
31 #include <drawview.hxx>
32 #include <fupoor.hxx>
33
34 #include <drawutil.hxx>
35 #include <document.hxx>
36 #include <comphelper/lok.hxx>
37
DrawMouseButtonDown(const MouseEvent & rMEvt)38 bool ScGridWindow::DrawMouseButtonDown(const MouseEvent& rMEvt)
39 {
40 bool bRet = false;
41 FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
42 if (pDraw && !pViewData->IsRefMode())
43 {
44 pDraw->SetWindow( this );
45 Point aLogicPos = PixelToLogic(rMEvt.GetPosPixel());
46 if ( pDraw->IsDetectiveHit( aLogicPos ) )
47 {
48 // nothing on detective arrows (double click is evaluated on ButtonUp)
49 bRet = true;
50 }
51 else
52 {
53 bRet = pDraw->MouseButtonDown( rMEvt );
54 if ( bRet )
55 UpdateStatusPosSize();
56 }
57 }
58
59 // cancel draw with right key
60 ScDrawView* pDrView = pViewData->GetScDrawView();
61 if ( pDrView && !rMEvt.IsLeft() && !bRet )
62 {
63 pDrView->BrkAction();
64 bRet = true;
65 }
66 return bRet;
67 }
68
DrawMouseButtonUp(const MouseEvent & rMEvt)69 bool ScGridWindow::DrawMouseButtonUp(const MouseEvent& rMEvt)
70 {
71 ScViewFunc* pView = pViewData->GetView();
72 bool bRet = false;
73 FuPoor* pDraw = pView->GetDrawFuncPtr();
74 if (pDraw && !pViewData->IsRefMode())
75 {
76 pDraw->SetWindow( this );
77 bRet = pDraw->MouseButtonUp( rMEvt );
78
79 // execute "format paint brush" for drawing objects
80 SfxItemSet* pDrawBrush = pView->GetDrawBrushSet();
81 if ( pDrawBrush )
82 {
83 ScDrawView* pDrView = pViewData->GetScDrawView();
84 if ( pDrView )
85 {
86 pDrView->SetAttrToMarked(*pDrawBrush, true/*bReplaceAll*/);
87 }
88
89 if ( !pView->IsPaintBrushLocked() )
90 pView->ResetBrushDocument(); // end paint brush mode if not locked
91 }
92 }
93
94 return bRet;
95 }
96
DrawMouseMove(const MouseEvent & rMEvt)97 bool ScGridWindow::DrawMouseMove(const MouseEvent& rMEvt)
98 {
99 FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
100 if (pDraw && !pViewData->IsRefMode())
101 {
102 pDraw->SetWindow( this );
103 bool bRet = pDraw->MouseMove( rMEvt );
104 if ( bRet )
105 UpdateStatusPosSize();
106 return bRet;
107 }
108 else
109 {
110 SetPointer( PointerStyle::Arrow );
111 return false;
112 }
113 }
114
DrawEndAction()115 void ScGridWindow::DrawEndAction()
116 {
117 ScDrawView* pDrView = pViewData->GetScDrawView();
118 if ( pDrView && pDrView->IsAction() )
119 pDrView->BrkAction();
120
121 FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
122 if (pDraw)
123 pDraw->StopDragTimer();
124
125 // ReleaseMouse on call
126 }
127
DrawCommand(const CommandEvent & rCEvt)128 bool ScGridWindow::DrawCommand(const CommandEvent& rCEvt)
129 {
130 ScDrawView* pDrView = pViewData->GetScDrawView();
131 FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
132 if (pDrView && pDraw && !pViewData->IsRefMode())
133 {
134 pDraw->SetWindow( this );
135 sal_uInt8 nUsed = pDraw->Command( rCEvt );
136 if( nUsed == SC_CMD_USED )
137 nButtonDown = 0; // MouseButtonUp is swallowed...
138 if( nUsed || pDrView->IsAction() )
139 return true;
140 }
141
142 return false;
143 }
144
DrawKeyInput(const KeyEvent & rKEvt)145 bool ScGridWindow::DrawKeyInput(const KeyEvent& rKEvt)
146 {
147 ScDrawView* pDrView = pViewData->GetScDrawView();
148 FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
149 if (pDrView && pDraw && !pViewData->IsRefMode())
150 {
151 pDraw->SetWindow( this );
152 bool bOldMarked = pDrView->AreObjectsMarked();
153 if (pDraw->KeyInput( rKEvt ))
154 {
155 bool bLeaveDraw = false;
156 bool bUsed = true;
157 bool bNewMarked = pDrView->AreObjectsMarked();
158 if ( !pViewData->GetView()->IsDrawSelMode() )
159 if ( !bNewMarked )
160 {
161 pViewData->GetViewShell()->SetDrawShell( false );
162 bLeaveDraw = true;
163 if ( !bOldMarked &&
164 rKEvt.GetKeyCode().GetCode() == KEY_DELETE )
165 bUsed = false; // nothing deleted
166 if(bOldMarked)
167 GetFocus();
168 }
169 if (!bLeaveDraw)
170 UpdateStatusPosSize(); // for moving/resizing etc. by keyboard
171 return bUsed;
172 }
173 }
174
175 return false;
176 }
177
DrawRedraw(ScOutputData & rOutputData,SdrLayerID nLayer)178 void ScGridWindow::DrawRedraw( ScOutputData& rOutputData, SdrLayerID nLayer )
179 {
180 const ScViewOptions& rOpts = pViewData->GetOptions();
181
182 // use new flags at SdrPaintView for hiding objects
183 const bool bDrawOle(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_OLE));
184 const bool bDrawChart(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_CHART));
185 const bool bDrawDraw(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_DRAW));
186
187 if(bDrawOle || bDrawChart || bDrawDraw)
188 {
189 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
190
191 if(pDrView)
192 {
193 pDrView->setHideOle(!bDrawOle);
194 pDrView->setHideChart(!bDrawChart);
195 pDrView->setHideDraw(!bDrawDraw);
196 pDrView->setHideFormControl(!bDrawDraw);
197 }
198
199 rOutputData.DrawSelectiveObjects(nLayer);
200 }
201 }
202
DrawSdrGrid(const tools::Rectangle & rDrawingRect,OutputDevice * pContentDev)203 void ScGridWindow::DrawSdrGrid( const tools::Rectangle& rDrawingRect, OutputDevice* pContentDev )
204 {
205 // Draw grid lines
206
207 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
208 if ( pDrView && pDrView->IsGridVisible() )
209 {
210 SdrPageView* pPV = pDrView->GetSdrPageView();
211 OSL_ENSURE(pPV, "PageView not available");
212 if (pPV)
213 {
214 pContentDev->SetLineColor(COL_GRAY);
215
216 pPV->DrawPageViewGrid( *pContentDev, rDrawingRect );
217 }
218 }
219 }
220
GetDrawMapMode(bool bForce)221 MapMode ScGridWindow::GetDrawMapMode( bool bForce )
222 {
223 ScDocument* pDoc = pViewData->GetDocument();
224
225 // FIXME this shouldn't be necessary once we change the entire Calc to
226 // work in the logic coordinates (ideally 100ths of mm - so that it is
227 // the same as editeng and drawinglayer), and get rid of all the
228 // SetMapMode's and other unnecessary fun we have with pixels
229 if (comphelper::LibreOfficeKit::isActive())
230 {
231 return pViewData->GetLogicMode();
232 }
233
234 SCTAB nTab = pViewData->GetTabNo();
235 bool bNegativePage = pDoc->IsNegativePage( nTab );
236
237 MapMode aDrawMode = pViewData->GetLogicMode();
238
239 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
240 if ( pDrView || bForce )
241 {
242 Fraction aScaleX;
243 Fraction aScaleY;
244 if (pDrView)
245 pDrView->GetScale( aScaleX, aScaleY );
246 else
247 {
248 SCCOL nEndCol = 0;
249 SCROW nEndRow = 0;
250 pDoc->GetTableArea( nTab, nEndCol, nEndRow );
251 if (nEndCol<20) nEndCol = 20;
252 if (nEndRow<20) nEndRow = 1000;
253 ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this,
254 pViewData->GetZoomX(),pViewData->GetZoomY(),
255 pViewData->GetPPTX(),pViewData->GetPPTY(),
256 aScaleX,aScaleY );
257 }
258 aDrawMode.SetScaleX(aScaleX);
259 aDrawMode.SetScaleY(aScaleY);
260 }
261 aDrawMode.SetOrigin(Point());
262 Point aStartPos = pViewData->GetPixPos(eWhich);
263 if ( bNegativePage )
264 {
265 // RTL uses negative positions for drawing objects
266 aStartPos.setX( -aStartPos.X() + GetOutputSizePixel().Width() - 1 );
267 }
268 aDrawMode.SetOrigin( PixelToLogic( aStartPos, aDrawMode ) );
269
270 return aDrawMode;
271 }
272
DrawAfterScroll()273 void ScGridWindow::DrawAfterScroll()
274 {
275 Update(); // always, so the behaviour with and without DrawingLayer is the same
276
277 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
278 if (pDrView)
279 {
280 OutlinerView* pOlView = pDrView->GetTextEditOutlinerView();
281 if (pOlView && pOlView->GetWindow() == this)
282 pOlView->ShowCursor(false); // was removed at scrolling
283 }
284 }
285
CreateAnchorHandle(SdrHdlList & rHdl,const ScAddress & rAddress)286 void ScGridWindow::CreateAnchorHandle(SdrHdlList& rHdl, const ScAddress& rAddress)
287 {
288 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
289 if (pDrView)
290 {
291 const ScViewOptions& rOpts = pViewData->GetOptions();
292 if(rOpts.GetOption( VOPT_ANCHOR ))
293 {
294 bool bNegativePage = pViewData->GetDocument()->IsNegativePage( pViewData->GetTabNo() );
295 Point aPos = pViewData->GetScrPos( rAddress.Col(), rAddress.Row(), eWhich, true );
296 aPos = PixelToLogic(aPos);
297 rHdl.AddHdl(std::make_unique<SdrHdl>(aPos, bNegativePage ? SdrHdlKind::Anchor_TR : SdrHdlKind::Anchor));
298 }
299 }
300 }
301
UpdateStatusPosSize()302 void ScGridWindow::UpdateStatusPosSize()
303 {
304 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
305 if (!pDrView)
306 return; // shouldn't be called in that case
307
308 SdrPageView* pPV = pDrView->GetSdrPageView();
309 if (!pPV)
310 return; // shouldn't be called in that case either
311
312 SfxItemSet aSet(pViewData->GetViewShell()->GetPool(), svl::Items<SID_ATTR_POSITION, SID_ATTR_SIZE>{});
313
314 // Fill items for position and size:
315 // show action rectangle during action,
316 // position and size of selected object(s) if something is selected,
317 // mouse position otherwise
318
319 bool bActionItem = false;
320 if ( pDrView->IsAction() ) // action rectangle
321 {
322 tools::Rectangle aRect;
323 pDrView->TakeActionRect( aRect );
324 if ( !aRect.IsEmpty() )
325 {
326 pPV->LogicToPagePos(aRect);
327 aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
328 aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
329 Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
330 bActionItem = true;
331 }
332 }
333 if ( !bActionItem )
334 {
335 if ( pDrView->AreObjectsMarked() ) // selected objects
336 {
337 tools::Rectangle aRect = pDrView->GetAllMarkedRect();
338 pPV->LogicToPagePos(aRect);
339 aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
340 aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
341 Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
342 }
343 else // mouse position
344 {
345 Point aPos = PixelToLogic(aCurMousePos);
346 pPV->LogicToPagePos(aPos);
347 aSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos ) );
348 aSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
349 }
350 }
351
352 pViewData->GetBindings().SetState(aSet);
353 }
354
DrawHasMarkedObj()355 bool ScGridWindow::DrawHasMarkedObj()
356 {
357 ScDrawView* p = pViewData->GetScDrawView();
358 return p && p->AreObjectsMarked();
359 }
360
DrawMarkDropObj(SdrObject * pObj)361 void ScGridWindow::DrawMarkDropObj( SdrObject* pObj )
362 {
363 ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
364 if (pDrView)
365 pDrView->MarkDropObj(pObj);
366 }
367
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
369