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