Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / ribbar / drawbase.cxx
blob4e77bbc1f69562ef4022e1748b1c6a7ceadb5efd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hintids.hxx>
21 #include <comphelper/lok.hxx>
22 #include <svx/svdview.hxx>
23 #include <svx/svdobj.hxx>
24 #include <svl/ptitem.hxx>
25 #include <editeng/sizeitem.hxx>
26 #include <sfx2/request.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <fmtclds.hxx>
30 #include <frmfmt.hxx>
31 #include <cmdid.h>
32 #include <view.hxx>
33 #include <wrtsh.hxx>
34 #include <drawbase.hxx>
35 #include <edtwin.hxx>
36 #include <swmodule.hxx>
37 #include <swundo.hxx>
38 #include <SwCapObjType.hxx>
39 #include <SwRewriter.hxx>
40 #include <strings.hrc>
42 using namespace ::com::sun::star;
44 SwDrawBase::SwDrawBase(SwWrtShell* pSwWrtShell, SwEditWin* pWindow, SwView* pSwView) :
45 m_pView(pSwView),
46 m_pSh(pSwWrtShell),
47 m_pWin(pWindow),
48 m_nSlotId(USHRT_MAX),
49 m_bCreateObj(true),
50 m_bInsForm(false)
52 if ( !m_pSh->HasDrawView() )
53 m_pSh->MakeDrawView();
56 SwDrawBase::~SwDrawBase()
58 if (m_pView->GetWrtShellPtr()) // In the view-dtor could the wrtsh already been deleted...
59 m_pSh->GetDrawView()->SetEditMode();
62 bool SwDrawBase::MouseButtonDown(const MouseEvent& rMEvt)
64 bool bReturn = false;
66 SdrView *pSdrView = m_pSh->GetDrawView();
68 // #i33136#
69 pSdrView->SetOrtho(doConstructOrthogonal() ? !rMEvt.IsShift() : rMEvt.IsShift());
70 pSdrView->SetAngleSnapEnabled(rMEvt.IsShift());
72 if (rMEvt.IsMod2())
74 pSdrView->SetCreate1stPointAsCenter(true);
75 pSdrView->SetResizeAtCenter(true);
77 else
79 pSdrView->SetCreate1stPointAsCenter(false);
80 pSdrView->SetResizeAtCenter(false);
83 SdrViewEvent aVEvt;
84 SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
86 // Only new object, if not in the basic mode (or pure selection mode).
87 if (rMEvt.IsLeft() && !m_pWin->IsDrawAction())
89 if (IsCreateObj() && (eHit == SdrHitKind::UnmarkedObject || eHit == SdrHitKind::NONE || m_pSh->IsDrawCreate()))
91 g_bNoInterrupt = true;
92 m_pWin->CaptureMouse();
94 m_aStartPos = m_pWin->PixelToLogic(rMEvt.GetPosPixel());
96 bReturn = m_pSh->BeginCreate(m_pWin->GetSdrDrawMode(), m_aStartPos);
98 SetDrawPointer();
100 if ( bReturn )
101 m_pWin->SetDrawAction(true);
103 else if (!pSdrView->IsAction())
105 // BEZIER-EDITOR
106 m_pWin->CaptureMouse();
107 m_aStartPos = m_pWin->PixelToLogic(rMEvt.GetPosPixel());
108 sal_uInt16 nEditMode = m_pWin->GetBezierMode();
110 if (eHit == SdrHitKind::Handle && aVEvt.mpHdl->GetKind() == SdrHdlKind::BezierWeight)
112 // Drag handle
113 g_bNoInterrupt = true;
114 bReturn = pSdrView->BegDragObj(m_aStartPos, nullptr, aVEvt.mpHdl);
115 m_pWin->SetDrawAction(true);
117 else if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT)
119 // Insert gluepoint
120 g_bNoInterrupt = true;
121 bReturn = pSdrView->BegInsObjPoint(m_aStartPos, rMEvt.IsMod1());
122 m_pWin->SetDrawAction(true);
124 else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1())
126 // Select gluepoint
127 if (!rMEvt.IsShift())
128 pSdrView->UnmarkAllPoints();
130 bReturn = pSdrView->BegMarkPoints(m_aStartPos);
131 m_pWin->SetDrawAction(true);
133 else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2())
135 // Move object
136 return false;
138 else if (eHit == SdrHitKind::Handle)
140 // Select gluepoint
141 if (pSdrView->HasMarkablePoints() && (!pSdrView->IsPointMarked(*aVEvt.mpHdl) || rMEvt.IsShift()))
143 SdrHdl* pHdl = nullptr;
145 if (!rMEvt.IsShift())
147 pSdrView->UnmarkAllPoints();
148 pHdl = pSdrView->PickHandle(m_aStartPos);
150 else
152 if (pSdrView->IsPointMarked(*aVEvt.mpHdl))
154 bReturn = pSdrView->UnmarkPoint(*aVEvt.mpHdl);
155 pHdl = nullptr;
157 else
159 pHdl = pSdrView->PickHandle(m_aStartPos);
163 if (pHdl)
165 g_bNoInterrupt = true;
166 pSdrView->MarkPoint(*pHdl);
170 else
172 // Select or drag object
173 if (m_pSh->IsObjSelectable(m_aStartPos) && eHit == SdrHitKind::UnmarkedObject)
175 if (pSdrView->HasMarkablePoints())
176 pSdrView->UnmarkAllPoints();
178 g_bNoInterrupt = false;
179 // Use drag in edtwin
180 return false;
183 g_bNoInterrupt = true;
185 if (m_pSh->IsObjSelected())
187 if (!rMEvt.IsShift())
189 if (!pSdrView->HasMarkablePoints())
191 bool bUnlockView = !m_pSh->IsViewLocked();
192 m_pSh->LockView( true ); //lock visible section
193 m_pSh->SelectObj(Point(LONG_MAX, LONG_MAX)); // deselect all
194 if( bUnlockView )
195 m_pSh->LockView( false );
197 else
198 pSdrView->UnmarkAllPoints();
201 if (!m_pSh->IsSelFrameMode())
202 m_pSh->EnterSelFrameMode();
204 bReturn = m_pSh->BeginMark(m_aStartPos);
205 if( bReturn )
206 m_pWin->SetDrawAction(true);
208 SetDrawPointer();
212 return bReturn;
215 bool SwDrawBase::MouseMove(const MouseEvent& rMEvt)
217 SdrView *pSdrView = m_pSh->GetDrawView();
218 Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel()));
219 bool bRet = false;
221 if (IsCreateObj() && !m_pWin->IsDrawSelMode() && pSdrView->IsCreateObj())
223 // #i33136#
224 pSdrView->SetOrtho(doConstructOrthogonal() ? !rMEvt.IsShift() : rMEvt.IsShift());
225 pSdrView->SetAngleSnapEnabled(rMEvt.IsShift());
227 m_pSh->MoveCreate(aPnt);
228 bRet = true;
230 else if (pSdrView->IsAction() || pSdrView->IsInsObjPoint() || pSdrView->IsMarkPoints())
232 m_pSh->MoveMark(aPnt);
233 bRet = true;
236 return bRet;
239 bool SwDrawBase::MouseButtonUp(const MouseEvent& rMEvt)
241 bool bReturn = false;
242 bool bCheckShell = false;
243 bool bAutoCap = false;
245 Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel()));
247 if (IsCreateObj() && m_pSh->IsDrawCreate() && !m_pWin->IsDrawSelMode())
249 const SdrObjKind nDrawMode = m_pWin->GetSdrDrawMode();
250 //objects with multiple point may end at the start position
251 bool bMultiPoint = SdrObjKind::PolyLine == nDrawMode ||
252 SdrObjKind::Polygon == nDrawMode ||
253 SdrObjKind::PathLine == nDrawMode ||
254 SdrObjKind::PathFill == nDrawMode ||
255 SdrObjKind::FreehandLine == nDrawMode ||
256 SdrObjKind::FreehandFill == nDrawMode;
257 if(rMEvt.IsRight())
259 m_pSh->BreakCreate();
260 m_pView->LeaveDrawCreate();
262 else
264 if (SdrObjKind::NewFrame == nDrawMode)
266 SwRewriter aRewriter;
268 aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME));
269 m_pSh->StartUndo(SwUndoId::INSERT, &aRewriter);
272 bool didCreate = m_pSh->EndCreate(SdrCreateCmd::ForceEnd);
273 if(!didCreate && !bMultiPoint)
275 CreateDefaultObjectAtPosWithSize(aPnt, Size(1000, 1000));
278 if (SdrObjKind::NewFrame == nDrawMode) // Text border inserted
280 uno::Reference< frame::XDispatchRecorder > xRecorder =
281 m_pSh->GetView().GetViewFrame().GetBindings().GetRecorder();
282 if ( xRecorder.is() )
284 SfxRequest aReq(m_pSh->GetView().GetViewFrame(), FN_INSERT_FRAME);
285 aReq .AppendItem(SfxUInt16Item( FN_INSERT_FRAME,
286 static_cast<sal_uInt16>(RndStdIds::FLY_AT_PARA) ));
287 aReq.AppendItem(SfxPointItem( FN_PARAM_1, m_pSh->GetAnchorObjDiff()));
288 aReq.AppendItem(SvxSizeItem( FN_PARAM_2, m_pSh->GetObjSize()));
289 aReq.Done();
291 bAutoCap = true;
292 if(m_pWin->GetFrameColCount() > 1)
294 SfxItemSetFixed<RES_COL,RES_COL> aSet(m_pView->GetPool());
295 SwFormatCol aCol(aSet.Get(RES_COL));
296 aCol.Init(m_pWin->GetFrameColCount(), aCol.GetGutterWidth(), aCol.GetWishWidth());
297 aSet.Put(aCol);
298 // Template AutoUpdate
299 SwFrameFormat* pFormat = m_pSh->GetSelectedFrameFormat();
300 if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
301 m_pSh->AutoUpdateFrame(pFormat, aSet);
302 else
303 m_pSh->SetFlyFrameAttr( aSet );
306 if (m_pWin->GetSdrDrawMode() == SdrObjKind::NewFrame)
308 m_pSh->EndUndo();
312 bReturn = true;
314 EnterSelectMode(rMEvt);
316 else
318 SdrView *pSdrView = m_pSh->GetDrawView();
320 if (!pSdrView->HasMarkablePoints())
322 // NO BEZIER_EDITOR
323 if ((m_pSh->GetDrawView()->IsMarkObj() || m_pSh->GetDrawView()->IsMarkPoints())
324 && rMEvt.IsLeft())
326 bReturn = m_pSh->EndMark();
328 m_pWin->SetDrawAction(false);
330 if (aPnt == m_aStartPos && m_pSh->IsObjSelectable(aPnt))
332 m_pSh->SelectObj(aPnt, ( rMEvt.IsShift() &&
333 m_pSh->IsSelFrameMode()) ? SW_ADD_SELECT : 0);
335 if (!m_pSh->IsObjSelected())
337 m_pView->LeaveDrawCreate(); // Switch to selection mode
339 m_pSh->GetView().GetViewFrame().GetBindings().Invalidate(SID_INSERT_DRAW);
341 if (m_pSh->IsSelFrameMode())
342 m_pSh->LeaveSelFrameMode();
344 m_pView->NoRotate();
346 bCheckShell = true; // if necessary turn on BezierShell
348 else if (!m_pSh->IsObjSelected() && !m_pWin->IsDrawAction())
350 if (m_pSh->IsObjSelectable(aPnt))
351 m_pSh->SelectObj(aPnt, ( rMEvt.IsShift() &&
352 m_pSh->IsSelFrameMode() ) ? SW_ADD_SELECT : 0 );
353 else
355 m_pView->LeaveDrawCreate();
356 if (m_pSh->IsSelFrameMode())
357 m_pSh->LeaveSelFrameMode();
359 m_pView->NoRotate();
361 bReturn = true;
365 else
367 // BEZIER_EDITOR
368 if ( pSdrView->IsAction() )
370 if ( pSdrView->IsInsObjPoint() )
371 bReturn = pSdrView->EndInsObjPoint(SdrCreateCmd::ForceEnd);
372 else if (pSdrView->IsMarkPoints() )
373 bReturn = pSdrView->EndMarkPoints();
374 else
376 pSdrView->EndAction();
377 bReturn = true;
379 m_pWin->SetDrawAction(false);
381 if (aPnt == m_aStartPos)
383 if (!m_pSh->IsObjSelectable(aPnt))
384 m_pSh->SelectObj(Point(LONG_MAX, LONG_MAX));
385 else if (!bReturn)
387 if (!rMEvt.IsShift())
388 pSdrView->UnmarkAllPoints();
389 m_pSh->SelectObj(aPnt, (rMEvt.IsShift() &&
390 m_pSh->IsSelFrameMode()) ? SW_ADD_SELECT :0);
393 if (!m_pSh->IsObjSelected())
395 m_pView->LeaveDrawCreate(); // Switch to selection mode
397 m_pSh->GetView().GetViewFrame().GetBindings().Invalidate(SID_INSERT_DRAW);
399 if (m_pSh->IsSelFrameMode())
400 m_pSh->LeaveSelFrameMode();
402 m_pView->NoRotate();
404 bCheckShell = true; // if necessary turn on BezierShell
408 SetDrawPointer();
410 if (!m_pSh->IsObjSelected() && !m_pWin->IsDrawAction())
412 m_pView->LeaveDrawCreate();
413 if (m_pSh->IsSelFrameMode())
414 m_pSh->LeaveSelFrameMode();
416 m_pView->NoRotate();
417 bReturn = true;
422 if (bCheckShell)
423 m_pView->AttrChangedNotify(nullptr); // if necessary turn on BezierShell
425 //!!!!!!!!!! Attention suicide !!!!!!!!!!! Everything should be renewed once
426 if ( bAutoCap )
427 m_pView->AutoCaption(FRAME_CAP); //Can currently only be FRAME, otherwise convert
428 // to enums
429 return bReturn;
432 void SwDrawBase::Activate(const sal_uInt16 nSlot)
434 SetSlotId(nSlot);
435 SdrView *pSdrView = m_pSh->GetDrawView();
437 pSdrView->SetCurrentObj(m_pWin->GetSdrDrawMode());
438 pSdrView->SetEditMode(false);
440 SetDrawPointer();
441 m_pSh->NoEdit();
444 void SwDrawBase::Deactivate()
446 SdrView *pSdrView = m_pSh->GetDrawView();
447 pSdrView->SetOrtho(false);
448 pSdrView->SetAngleSnapEnabled(false);
450 if (m_pWin->IsDrawAction() && m_pSh->IsDrawCreate())
451 m_pSh->BreakCreate();
453 m_pWin->SetDrawAction(false);
455 if (m_pWin->IsMouseCaptured())
456 m_pWin->ReleaseMouse();
457 g_bNoInterrupt = false;
459 if (m_pWin->GetApplyTemplate())
460 m_pWin->SetApplyTemplate(SwApplyTemplate());
461 m_pSh->GetView().GetViewFrame().GetBindings().Invalidate(SID_INSERT_DRAW);
464 // Process keyboard events
466 // If a KeyEvent is processed then the return value is true, otherwise
467 // false.
469 void SwDrawBase::BreakCreate()
471 m_pSh->BreakCreate();
472 m_pWin->SetDrawAction(false);
473 m_pWin->ReleaseMouse();
475 Deactivate();
478 void SwDrawBase::SetDrawPointer()
480 SdrView *pSdrView = m_pSh->GetDrawView();
481 Point aPnt(m_pWin->OutputToScreenPixel(m_pWin->GetPointerPosPixel()));
482 aPnt = m_pWin->PixelToLogic(m_pWin->ScreenToOutputPixel(aPnt));
483 PointerStyle aPointTyp = pSdrView->GetPreferredPointer(aPnt, m_pSh->GetOut());
484 m_pWin->SetPointer(aPointTyp);
487 // If necessary switch into selection mode
489 void SwDrawBase::EnterSelectMode(const MouseEvent& rMEvt)
491 m_pWin->SetDrawAction(false);
493 if (m_pSh->IsObjSelected() || m_pWin->IsDrawAction())
494 return;
496 Point aPnt(m_pWin->PixelToLogic(rMEvt.GetPosPixel()));
498 if (m_pSh->IsObjSelectable(aPnt))
500 m_pSh->SelectObj(aPnt);
501 if (rMEvt.GetModifier() == KEY_SHIFT || !m_pSh->IsObjSelected())
503 m_pView->LeaveDrawCreate(); // Switch to selection mode
505 m_pSh->GetView().GetViewFrame().GetBindings().Invalidate(SID_INSERT_DRAW);
508 else
510 m_pView->LeaveDrawCreate();
511 if (m_pSh->IsSelFrameMode())
512 m_pSh->LeaveSelFrameMode();
514 m_pView->NoRotate();
517 void SwDrawBase::CreateDefaultObject()
519 constexpr tools::Long constTwips_3cm = o3tl::toTwips(3, o3tl::Length::cm);
521 Point aStartPos = GetDefaultCenterPos();
522 Point aEndPos(aStartPos);
523 aStartPos.AdjustX(-constTwips_3cm);
524 aStartPos.AdjustY(-constTwips_3cm);
525 aEndPos.AdjustX(constTwips_3cm);
526 aEndPos.AdjustY(constTwips_3cm);
527 tools::Rectangle aRect(aStartPos, aEndPos);
528 m_pSh->CreateDefaultShape(m_pWin->GetSdrDrawMode(), aRect, m_nSlotId);
531 void SwDrawBase::CreateDefaultObjectAtPosWithSize(Point aPos, Size aSize)
533 aPos.AdjustX(-sal_Int32(aSize.getWidth() / 2));
534 aPos.AdjustY(-sal_Int32(aSize.getHeight() / 2));
536 SdrView* sdrView = m_pView->GetDrawView();
537 SdrPageView *pPV = sdrView->GetSdrPageView();
539 if(sdrView->IsSnapEnabled())
540 aPos = sdrView->GetSnapPos(aPos, pPV);
542 ::tools::Rectangle aNewObjectRectangle(aPos, aSize);
543 m_pSh->CreateDefaultShape(m_pWin->GetSdrDrawMode(), aNewObjectRectangle, m_nSlotId);
546 Point SwDrawBase::GetDefaultCenterPos() const
548 Size aDocSz(m_pSh->GetDocSize());
550 SwRect aVisArea(m_pSh->VisArea());
551 if (comphelper::LibreOfficeKit::isActive())
553 aVisArea = SwRect(m_pSh->getLOKVisibleArea());
554 aVisArea.Intersection(SwRect(Point(), aDocSz));
557 Point aCenter = aVisArea.Center();
558 // To increase the chance that aCenter actually falls somewhere on a page (rather than on the
559 // background between pages), keep it centered horizontally for the "Single-page view"
560 // (GetViewLayoutColumns() == 1) and "Book view" (GetViewLayoutColumns() == 2) cases that
561 // display the pages centered on the background:
562 if (aVisArea.Width() > aDocSz.Width() && m_pSh->GetViewOptions()->GetViewLayoutColumns() == 0)
563 aCenter.setX(aDocSz.Width() / 2 + aVisArea.Left());
564 if (aVisArea.Height() > aDocSz.Height())
565 aCenter.setY(aDocSz.Height() / 2 + aVisArea.Top());
567 return aCenter;
570 // #i33136#
571 bool SwDrawBase::doConstructOrthogonal() const
573 return ( m_nSlotId == SID_DRAW_XPOLYGON || m_nSlotId == SID_DRAW_XPOLYGON_NOFILL || m_nSlotId == SID_DRAW_XLINE );
576 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */