tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / reportdesign / source / ui / report / ViewsWindow.cxx
blob7ac2a49e14eb294b1beb7fbc899fa84b75d6c7fd
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 <ViewsWindow.hxx>
21 #include <ScrollHelper.hxx>
22 #include <UndoActions.hxx>
23 #include <ReportWindow.hxx>
24 #include <DesignView.hxx>
25 #include <svtools/colorcfg.hxx>
26 #include <ReportController.hxx>
27 #include <UITools.hxx>
28 #include <RptDef.hxx>
29 #include <strings.hrc>
30 #include <SectionView.hxx>
31 #include <ReportSection.hxx>
32 #include <strings.hxx>
33 #include <rptui_slotid.hrc>
34 #include <dlgedclip.hxx>
35 #include <RptObject.hxx>
36 #include <EndMarker.hxx>
37 #include <sal/log.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/settings.hxx>
40 #include <vcl/unohelp.hxx>
41 #include <core_resource.hxx>
42 #include <svx/svdundo.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <algorithm>
45 #include <cstdlib>
46 #include <numeric>
48 namespace rptui
50 #define DEFAUL_MOVE_SIZE 100
52 using namespace ::com::sun::star;
54 static bool lcl_getNewRectSize(const tools::Rectangle& _aObjRect,tools::Long& _nXMov, tools::Long& _nYMov,SdrObject const * _pObj,SdrView const * _pView, ControlModification _nControlModification)
56 bool bMoveAllowed = _nXMov != 0 || _nYMov != 0;
57 if ( bMoveAllowed )
59 tools::Rectangle aNewRect = _aObjRect;
60 SdrObject* pOverlappedObj = nullptr;
63 aNewRect = _aObjRect;
64 switch(_nControlModification)
66 case ControlModification::HEIGHT_GREATEST:
67 case ControlModification::WIDTH_GREATEST:
68 aNewRect.setWidth(_nXMov);
69 aNewRect.setHeight(_nYMov);
70 break;
71 default:
72 aNewRect.Move(_nXMov,_nYMov);
73 break;
75 if (dynamic_cast<OUnoObject const *>(_pObj) != nullptr || dynamic_cast<OOle2Obj const *>(_pObj) != nullptr)
77 pOverlappedObj = isOver(aNewRect,*_pObj->getSdrPageFromSdrObject(),*_pView,true,_pObj);
78 if ( pOverlappedObj && _pObj != pOverlappedObj )
80 tools::Rectangle aOverlappingRect = pOverlappedObj->GetSnapRect();
81 sal_Int32 nXTemp = _nXMov;
82 sal_Int32 nYTemp = _nYMov;
83 switch(_nControlModification)
85 case ControlModification::LEFT:
86 nXTemp += aOverlappingRect.Right() - aNewRect.Left();
87 bMoveAllowed = _nXMov != nXTemp;
88 break;
89 case ControlModification::RIGHT:
90 nXTemp += aOverlappingRect.Left() - aNewRect.Right();
91 bMoveAllowed = _nXMov != nXTemp;
92 break;
93 case ControlModification::TOP:
94 nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
95 bMoveAllowed = _nYMov != nYTemp;
96 break;
97 case ControlModification::BOTTOM:
98 nYTemp += aOverlappingRect.Top() - aNewRect.Bottom();
99 bMoveAllowed = _nYMov != nYTemp;
100 break;
101 case ControlModification::CENTER_HORIZONTAL:
102 if ( _aObjRect.Left() < aOverlappingRect.Left() )
103 nXTemp += aOverlappingRect.Left() - aNewRect.Left() - aNewRect.getOpenWidth();
104 else
105 nXTemp += aOverlappingRect.Right() - aNewRect.Left();
106 bMoveAllowed = _nXMov != nXTemp;
107 break;
108 case ControlModification::CENTER_VERTICAL:
109 if ( _aObjRect.Top() < aOverlappingRect.Top() )
110 nYTemp += aOverlappingRect.Top() - aNewRect.Top() - aNewRect.getOpenHeight();
111 else
112 nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
113 bMoveAllowed = _nYMov != nYTemp;
114 break;
115 case ControlModification::HEIGHT_GREATEST:
116 case ControlModification::WIDTH_GREATEST:
118 tools::Rectangle aIntersectionRect = aNewRect.GetIntersection(aOverlappingRect);
119 if ( !aIntersectionRect.IsEmpty() )
121 if ( _nControlModification == ControlModification::WIDTH_GREATEST )
123 if ( aNewRect.Left() < aIntersectionRect.Left() )
125 aNewRect.SetRight( aIntersectionRect.Left() );
127 else if ( aNewRect.Left() < aIntersectionRect.Right() )
129 aNewRect.SetLeft( aIntersectionRect.Right() );
132 else if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
134 if ( aNewRect.Top() < aIntersectionRect.Top() )
136 aNewRect.SetBottom( aIntersectionRect.Top() );
138 else if ( aNewRect.Top() < aIntersectionRect.Bottom() )
140 aNewRect.SetTop( aIntersectionRect.Bottom() );
143 nYTemp = aNewRect.getOpenHeight();
144 bMoveAllowed = _nYMov != nYTemp;
145 nXTemp = aNewRect.getOpenWidth();
146 bMoveAllowed = bMoveAllowed && _nXMov != nXTemp;
149 break;
150 default:
151 break;
154 _nXMov = nXTemp;
155 _nYMov = nYTemp;
157 else
158 pOverlappedObj = nullptr;
161 while ( pOverlappedObj && bMoveAllowed );
163 return bMoveAllowed;
166 OViewsWindow::OViewsWindow( OReportWindow* _pReportWindow)
167 : Window( _pReportWindow,WB_DIALOGCONTROL)
168 , m_pParent(_pReportWindow)
169 , m_bInUnmark(false)
171 SetPaintTransparent(true);
172 SetMapMode(MapMode(MapUnit::Map100thMM));
173 m_aColorConfig.AddListener(this);
174 ImplInitSettings();
177 OViewsWindow::~OViewsWindow()
179 disposeOnce();
182 void OViewsWindow::dispose()
184 m_aColorConfig.RemoveListener(this);
185 for (auto& rxSection : m_aSections)
186 rxSection.disposeAndClear();
187 m_aSections.clear();
188 m_pParent.clear();
189 vcl::Window::dispose();
192 void OViewsWindow::impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet)
194 const uno::Reference< report::XSection> xSection = _rSectionWindow.getReportSection().getSection();
196 Size aSectionSize = _rSectionWindow.LogicToPixel( Size( 0,xSection->getHeight() ) );
197 aSectionSize.setWidth( getView()->GetTotalWidth() );
199 const sal_Int32 nMinHeight = _rSectionWindow.getStartMarker().getMinHeight();
200 if ( _rSectionWindow.getStartMarker().isCollapsed() || nMinHeight > aSectionSize.Height() )
202 aSectionSize.setHeight( nMinHeight );
204 aSectionSize.AdjustHeight(static_cast<tools::Long>(StyleSettings::GetSplitSize() * static_cast<double>(_rSectionWindow.GetMapMode().GetScaleY())) );
206 if ( _bSet )
207 _rSectionWindow.SetPosSizePixel(_rStartPoint,aSectionSize);
209 _rStartPoint.AdjustY(aSectionSize.Height() );
213 void OViewsWindow::resize(const OSectionWindow& _rSectionWindow)
215 bool bSet = false;
216 Point aStartPoint;
217 for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections)
219 if ( pSectionWindow == &_rSectionWindow )
221 aStartPoint = pSectionWindow->GetPosPixel();
222 bSet = true;
225 if ( bSet )
227 impl_resizeSectionWindow(*pSectionWindow,aStartPoint,bSet);
228 static const InvalidateFlags nIn = InvalidateFlags::Update | InvalidateFlags::Transparent;
229 pSectionWindow->getStartMarker().Invalidate( nIn ); // InvalidateFlags::NoErase |InvalidateFlags::NoChildren| InvalidateFlags::Transparent
230 pSectionWindow->getEndMarker().Invalidate( nIn );
233 m_pParent->notifySizeChanged();
236 void OViewsWindow::Resize()
238 Window::Resize();
239 if ( !m_aSections.empty() )
241 const Point aOffset(m_pParent->getThumbPos());
242 Point aStartPoint(0,-aOffset.Y());
243 for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections)
245 impl_resizeSectionWindow(*pSectionWindow,aStartPoint,true);
250 void OViewsWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
252 Window::Paint(rRenderContext, rRect);
254 rRenderContext.SetBackground();
255 rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
256 rRenderContext.SetTextFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
258 Size aOut(GetOutputSizePixel());
259 tools::Long nStartWidth = tools::Long(REPORT_STARTMARKER_WIDTH * rRenderContext.GetMapMode().GetScaleX());
261 aOut.AdjustWidth( -nStartWidth );
262 aOut = rRenderContext.PixelToLogic(aOut);
264 tools::Rectangle aRect(rRenderContext.PixelToLogic(Point(nStartWidth,0)), aOut);
265 Wallpaper aWall(m_aColorConfig.GetColorValue(::svtools::APPBACKGROUND).nColor);
266 rRenderContext.DrawWallpaper(aRect, aWall);
269 void OViewsWindow::ImplInitSettings()
271 EnableChildTransparentMode();
274 void OViewsWindow::DataChanged( const DataChangedEvent& rDCEvt )
276 Window::DataChanged( rDCEvt );
278 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
279 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
281 ImplInitSettings();
282 Invalidate();
286 void OViewsWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition)
288 VclPtrInstance<OSectionWindow> pSectionWindow(this,_xSection,_sColorEntry);
289 m_aSections.insert(getIteratorAtPos(_nPosition) , TSectionsMap::value_type(pSectionWindow));
290 m_pParent->setMarked(&pSectionWindow->getReportSection().getSectionView(),m_aSections.size() == 1);
291 Resize();
294 void OViewsWindow::removeSection(sal_uInt16 _nPosition)
296 if ( _nPosition < m_aSections.size() )
298 TSectionsMap::iterator aPos = getIteratorAtPos(_nPosition);
299 TSectionsMap::const_iterator aNew = getIteratorAtPos(_nPosition == 0 ? _nPosition+1: _nPosition - 1);
301 m_pParent->getReportView()->UpdatePropertyBrowserDelayed((*aNew)->getReportSection().getSectionView());
303 aPos->disposeAndClear();
304 m_aSections.erase(aPos);
305 Resize();
309 void OViewsWindow::toggleGrid(bool _bVisible)
311 ::std::for_each(m_aSections.begin(),m_aSections.end(),
312 [_bVisible] (const TSectionsMap::value_type& sectionPtr) {
313 sectionPtr->getReportSection().SetGridVisible(_bVisible);
315 ::std::for_each(m_aSections.begin(),m_aSections.end(),
316 [] (const TSectionsMap::value_type& sectionPtr) {
317 sectionPtr->getReportSection().Window::Invalidate(InvalidateFlags::NoErase);
321 sal_Int32 OViewsWindow::getTotalHeight() const
323 return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_Int32(0),
324 [](const sal_Int32 nHeight, const VclPtr<OSectionWindow>& rxSection) { return nHeight + rxSection->GetSizePixel().Height(); });
327 sal_uInt16 OViewsWindow::getSectionCount() const
329 return static_cast<sal_uInt16>(m_aSections.size());
332 void OViewsWindow::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType )
334 for (const auto& rxSection : m_aSections)
335 rxSection->getReportSection().getSectionView().SetCurrentObj( eObj, SdrInventor::ReportDesign );
337 m_sShapeType = _sShapeType;
341 void OViewsWindow::SetMode( DlgEdMode eNewMode )
343 ::std::for_each(m_aSections.begin(),m_aSections.end(),
344 [&eNewMode] (const TSectionsMap::value_type& sectionPtr) {
345 sectionPtr->getReportSection().SetMode(eNewMode);
349 bool OViewsWindow::HasSelection() const
351 return std::any_of(m_aSections.begin(), m_aSections.end(),
352 [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().GetMarkedObjectList().GetMarkCount() != 0; });
355 void OViewsWindow::Delete()
357 m_bInUnmark = true;
358 ::std::for_each(m_aSections.begin(),m_aSections.end(),
359 [] (const TSectionsMap::value_type& sectionPtr) {
360 sectionPtr->getReportSection().Delete();
362 m_bInUnmark = false;
365 void OViewsWindow::Copy()
367 uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
368 ::std::for_each(m_aSections.begin(),m_aSections.end(),
369 [&aAllreadyCopiedObjects] (const TSectionsMap::value_type& sectionPtr) {
370 sectionPtr->getReportSection().Copy(aAllreadyCopiedObjects);
373 rtl::Reference<OReportExchange> pCopy = new OReportExchange(aAllreadyCopiedObjects);
374 pCopy->CopyToClipboard(this);
377 void OViewsWindow::Paste()
379 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(this));
380 OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aTransferData);
381 if ( aCopies.getLength() > 1 )
382 ::std::for_each(m_aSections.begin(),m_aSections.end(),
383 [&aCopies] (const TSectionsMap::value_type& sectionPtr) {
384 sectionPtr->getReportSection().Paste(aCopies);
386 else
388 OSectionWindow* pMarkedSection = getMarkedSection();
389 if ( pMarkedSection )
390 pMarkedSection->getReportSection().Paste(aCopies,true);
394 OSectionWindow* OViewsWindow::getSectionWindow(const uno::Reference< report::XSection>& _xSection) const
396 OSL_ENSURE(_xSection.is(),"Section is NULL!");
398 OSectionWindow* pSectionWindow = nullptr;
399 for (VclPtr<OSectionWindow> const & p : m_aSections)
401 if (p->getReportSection().getSection() == _xSection)
403 pSectionWindow = p.get();
404 break;
408 return pSectionWindow;
412 OSectionWindow* OViewsWindow::getMarkedSection(NearSectionAccess nsa) const
414 OSectionWindow* pRet = nullptr;
415 TSectionsMap::const_iterator aIter = m_aSections.begin();
416 TSectionsMap::const_iterator aEnd = m_aSections.end();
417 sal_uInt32 nCurrentPosition = 0;
418 for (; aIter != aEnd ; ++aIter)
420 if ( (*aIter)->getStartMarker().isMarked() )
422 if (nsa == CURRENT)
424 pRet = aIter->get();
425 break;
427 else if ( nsa == PREVIOUS )
429 if (nCurrentPosition > 0)
431 pRet = (--aIter)->get();
432 if (pRet == nullptr)
434 pRet = m_aSections.begin()->get();
437 else
439 // if we are out of bounds return the first one
440 pRet = m_aSections.begin()->get();
442 break;
444 else if ( nsa == POST )
446 sal_uInt32 nSize = m_aSections.size();
447 if ((nCurrentPosition + 1) < nSize)
449 pRet = (++aIter)->get();
450 if (pRet == nullptr)
452 pRet = (--aEnd)->get();
455 else
457 // if we are out of bounds return the last one
458 pRet = (--aEnd)->get();
460 break;
463 ++nCurrentPosition;
466 return pRet;
469 void OViewsWindow::markSection(const sal_uInt16 _nPos)
471 if ( _nPos < m_aSections.size() )
472 m_pParent->setMarked(m_aSections[_nPos]->getReportSection().getSection(),true);
475 bool OViewsWindow::IsPasteAllowed() const
477 TransferableDataHelper aTransferData( TransferableDataHelper::CreateFromSystemClipboard( const_cast< OViewsWindow* >( this ) ) );
478 return aTransferData.HasFormat(OReportExchange::getDescriptorFormatId());
481 void OViewsWindow::SelectAll(const SdrObjKind _nObjectType)
483 m_bInUnmark = true;
484 ::std::for_each(m_aSections.begin(),m_aSections.end(),
485 [&_nObjectType] (const TSectionsMap::value_type& sectionPtr) {
486 sectionPtr->getReportSection().SelectAll(_nObjectType);
488 m_bInUnmark = false;
491 void OViewsWindow::unmarkAllObjects(OSectionView const * _pSectionView)
493 if ( m_bInUnmark )
494 return;
496 m_bInUnmark = true;
497 for (const auto& rxSection : m_aSections)
499 if ( &rxSection->getReportSection().getSectionView() != _pSectionView )
501 rxSection->getReportSection().deactivateOle();
502 rxSection->getReportSection().getSectionView().UnmarkAllObj();
505 m_bInUnmark = false;
508 void OViewsWindow::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints)
510 ImplInitSettings();
511 Invalidate();
514 void OViewsWindow::MouseButtonDown( const MouseEvent& rMEvt )
516 if ( rMEvt.IsLeft() )
518 GrabFocus();
519 const uno::Sequence< beans::PropertyValue> aArgs;
520 getView()->getReportView()->getController().executeChecked(SID_SELECT_REPORT,aArgs);
522 Window::MouseButtonDown(rMEvt);
525 void OViewsWindow::showRuler(bool _bShow)
527 ::std::for_each(m_aSections.begin(),m_aSections.end(),
528 [_bShow] (const TSectionsMap::value_type& sectionPtr) {
529 sectionPtr->getStartMarker().showRuler(_bShow);
531 ::std::for_each(m_aSections.begin(),m_aSections.end(),
532 [] (const TSectionsMap::value_type& sectionPtr) {
533 sectionPtr->getStartMarker().Window::Invalidate(InvalidateFlags::NoErase);
537 void OViewsWindow::MouseButtonUp( const MouseEvent& rMEvt )
539 if ( !rMEvt.IsLeft() )
540 return;
542 auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(),
543 [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().GetMarkedObjectList().GetMarkCount() != 0; });
544 if (aIter != m_aSections.end())
546 (*aIter)->getReportSection().MouseButtonUp(rMEvt);
549 // remove special insert mode
550 for (const auto& rxSection : m_aSections)
552 rxSection->getReportSection().getPage()->resetSpecialMode();
556 bool OViewsWindow::handleKeyEvent(const KeyEvent& _rEvent)
558 bool bRet = false;
559 for (const auto& rxSection : m_aSections)
561 if ( rxSection->getStartMarker().isMarked() )
563 bRet = rxSection->getReportSection().handleKeyEvent(_rEvent);
566 return bRet;
569 OViewsWindow::TSectionsMap::iterator OViewsWindow::getIteratorAtPos(sal_uInt16 _nPos)
571 TSectionsMap::iterator aRet = m_aSections.end();
572 if ( _nPos < m_aSections.size() )
573 aRet = m_aSections.begin() + _nPos;
574 return aRet;
577 void OViewsWindow::setMarked(OSectionView const * _pSectionView, bool _bMark)
579 OSL_ENSURE(_pSectionView != nullptr,"SectionView is NULL!");
580 if ( _pSectionView )
581 setMarked(_pSectionView->getReportSection()->getSection(),_bMark);
584 void OViewsWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark)
586 for (const auto& rxSection : m_aSections)
588 if ( rxSection->getReportSection().getSection() != _xSection )
590 rxSection->setMarked(false);
592 else if ( rxSection->getStartMarker().isMarked() != _bMark )
594 rxSection->setMarked(_bMark);
599 void OViewsWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes, bool _bMark)
601 bool bFirst = true;
602 for(const uno::Reference< report::XReportComponent>& rShape : _aShapes)
604 const uno::Reference< report::XSection> xSection = rShape->getSection();
605 if ( xSection.is() )
607 if ( bFirst )
609 bFirst = false;
610 m_pParent->setMarked(xSection,_bMark);
612 OSectionWindow* pSectionWindow = getSectionWindow(xSection);
613 if ( pSectionWindow )
615 SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rShape );
616 OSL_ENSURE( pObject, "OViewsWindow::setMarked: no SdrObject for the shape!" );
617 if ( pObject )
618 pSectionWindow->getReportSection().getSectionView().MarkObj( pObject, pSectionWindow->getReportSection().getSectionView().GetSdrPageView(), !_bMark );
624 void OViewsWindow::collectRectangles(TRectangleMap& _rSortRectangles)
626 for (const auto& rxSection : m_aSections)
628 OSectionView& rView = rxSection->getReportSection().getSectionView();
629 if ( rView.GetMarkedObjectList().GetMarkCount() != 0 )
631 rView.GetMarkedObjectList().ForceSort();
632 const size_t nCount = rView.GetMarkedObjectList().GetMarkCount();
633 for (size_t i=0; i < nCount; ++i)
635 const SdrMark* pM = rView.GetMarkedObjectList().GetMark(i);
636 SdrObject* pObj = pM->GetMarkedSdrObj();
637 tools::Rectangle aObjRect(pObj->GetSnapRect());
638 _rSortRectangles.emplace(aObjRect,TRectangleMap::mapped_type(pObj,&rView));
644 void OViewsWindow::collectBoundResizeRect(const TRectangleMap& _rSortRectangles, ControlModification _nControlModification,bool _bAlignAtSection, tools::Rectangle& _rBound, tools::Rectangle& _rResize)
646 bool bOnlyOnce = false;
647 for (const auto& [aObjRect, rObjViewPair] : _rSortRectangles)
649 if ( _rResize.IsEmpty() )
650 _rResize = aObjRect;
651 switch(_nControlModification)
653 case ControlModification::WIDTH_SMALLEST:
654 if ( _rResize.getOpenWidth() > aObjRect.getOpenWidth() )
655 _rResize = aObjRect;
656 break;
657 case ControlModification::HEIGHT_SMALLEST:
658 if ( _rResize.getOpenHeight() > aObjRect.getOpenHeight() )
659 _rResize = aObjRect;
660 break;
661 case ControlModification::WIDTH_GREATEST:
662 if ( _rResize.getOpenWidth() < aObjRect.getOpenWidth() )
663 _rResize = aObjRect;
664 break;
665 case ControlModification::HEIGHT_GREATEST:
666 if ( _rResize.getOpenHeight() < aObjRect.getOpenHeight() )
667 _rResize = aObjRect;
668 break;
669 default: break;
672 SdrObjTransformInfoRec aInfo;
673 const SdrObject* pObj = rObjViewPair.first;
674 pObj->TakeObjInfo(aInfo);
675 bool bHasFixed = !aInfo.bMoveAllowed || pObj->IsMoveProtect();
676 if ( bHasFixed )
677 _rBound.Union(aObjRect);
678 else
680 if ( _bAlignAtSection || _rSortRectangles.size() == 1 )
681 { // align single object at the page
682 if ( ! bOnlyOnce )
684 bOnlyOnce = true;
685 OReportSection* pReportSection = rObjViewPair.second->getReportSection();
686 const uno::Reference< report::XSection>& xSection = pReportSection->getSection();
689 uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
690 _rBound.Union(tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
691 getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
692 xSection->getHeight()));
694 catch(const uno::Exception &){}
697 else
699 _rBound.Union(rObjViewPair.second->GetMarkedObjRect());
705 void OViewsWindow::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection)
707 if ( _nControlModification == ControlModification::NONE )
708 return;
710 Point aRefPoint;
711 RectangleLess::CompareMode eCompareMode = RectangleLess::POS_LEFT;
712 switch (_nControlModification)
714 case ControlModification::TOP : eCompareMode = RectangleLess::POS_UPPER; break;
715 case ControlModification::BOTTOM: eCompareMode = RectangleLess::POS_DOWN; break;
716 case ControlModification::LEFT : eCompareMode = RectangleLess::POS_LEFT; break;
717 case ControlModification::RIGHT : eCompareMode = RectangleLess::POS_RIGHT; break;
718 case ControlModification::CENTER_HORIZONTAL :
719 case ControlModification::CENTER_VERTICAL :
721 eCompareMode = (ControlModification::CENTER_VERTICAL == _nControlModification) ? RectangleLess::POS_CENTER_VERTICAL : RectangleLess::POS_CENTER_HORIZONTAL;
722 uno::Reference<report::XSection> xSection = (*m_aSections.begin())->getReportSection().getSection();
723 uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
724 aRefPoint = tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
725 getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
726 xSection->getHeight()).Center();
728 break;
729 default: break;
731 RectangleLess aCompare(eCompareMode,aRefPoint);
732 TRectangleMap aSortRectangles(aCompare);
733 collectRectangles(aSortRectangles);
735 tools::Rectangle aBound;
736 tools::Rectangle aResize;
737 collectBoundResizeRect(aSortRectangles,_nControlModification,_bAlignAtSection,aBound,aResize);
739 bool bMove = true;
741 auto aGetFun = ::std::mem_fn(&tools::Rectangle::Bottom);
742 auto aSetFun = ::std::mem_fn(&tools::Rectangle::SetBottom);
743 auto aRefFun = ::std::mem_fn(&tools::Rectangle::Top);
744 TRectangleMap::const_iterator aRectIter = aSortRectangles.begin();
745 TRectangleMap::const_iterator aRectEnd = aSortRectangles.end();
746 for (;aRectIter != aRectEnd ; ++aRectIter)
748 tools::Rectangle aObjRect = aRectIter->first;
749 SdrObject* pObj = aRectIter->second.first;
750 SdrView* pView = aRectIter->second.second;
751 Point aCenter(aBound.Center());
752 SdrObjTransformInfoRec aInfo;
753 pObj->TakeObjInfo(aInfo);
754 if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
756 tools::Long nXMov = 0;
757 tools::Long nYMov = 0;
758 tools::Long* pValue = &nXMov;
759 switch(_nControlModification)
761 case ControlModification::TOP :
762 aGetFun = ::std::mem_fn(&tools::Rectangle::Top);
763 aSetFun = ::std::mem_fn(&tools::Rectangle::SetTop);
764 aRefFun = ::std::mem_fn(&tools::Rectangle::Bottom);
765 pValue = &nYMov;
766 break;
767 case ControlModification::BOTTOM:
768 // defaults are already set
769 pValue = &nYMov;
770 break;
771 case ControlModification::CENTER_VERTICAL:
772 nYMov = aCenter.Y() - aObjRect.Center().Y();
773 pValue = &nYMov;
774 bMove = false;
775 break;
776 case ControlModification::RIGHT :
777 aGetFun = ::std::mem_fn(&tools::Rectangle::Right);
778 aSetFun = ::std::mem_fn(&tools::Rectangle::SetRight);
779 aRefFun = ::std::mem_fn(&tools::Rectangle::Left);
780 break;
781 case ControlModification::CENTER_HORIZONTAL:
782 nXMov = aCenter.X() - aObjRect.Center().X();
783 bMove = false;
784 break;
785 case ControlModification::LEFT :
786 aGetFun = ::std::mem_fn(&tools::Rectangle::Left);
787 aSetFun = ::std::mem_fn(&tools::Rectangle::SetLeft);
788 aRefFun = ::std::mem_fn(&tools::Rectangle::Right);
789 break;
790 default:
791 bMove = false;
792 break;
794 if ( bMove )
796 tools::Rectangle aTest = aObjRect;
797 aSetFun(&aTest, aGetFun(&aBound));
798 TRectangleMap::const_iterator aInterSectRectIter = aSortRectangles.begin();
799 for (; aInterSectRectIter != aRectIter; ++aInterSectRectIter)
801 if ( pView == aInterSectRectIter->second.second && (dynamic_cast<OUnoObject*>(aInterSectRectIter->second.first) || dynamic_cast<OOle2Obj*>(aInterSectRectIter->second.first)))
803 SdrObject* pPreviousObj = aInterSectRectIter->second.first;
804 tools::Rectangle aIntersectRect = aTest.GetIntersection( pPreviousObj->GetSnapRect());
805 if ( !aIntersectRect.IsEmpty() && (aIntersectRect.Left() != aIntersectRect.Right() && aIntersectRect.Top() != aIntersectRect.Bottom() ) )
807 *pValue = aRefFun(&aIntersectRect) - aGetFun(&aObjRect);
808 break;
812 if ( aInterSectRectIter == aRectIter )
813 *pValue = aGetFun(&aBound) - aGetFun(&aObjRect);
816 if ( lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification) )
818 const Size aSize(nXMov,nYMov);
819 pView->AddUndo(pView->GetModel().GetSdrUndoFactory().CreateUndoMoveObject(*pObj,aSize));
820 pObj->Move(aSize);
821 aObjRect = pObj->GetSnapRect();
824 // resizing control
825 if ( !aResize.IsEmpty() && aObjRect != aResize )
827 nXMov = aResize.getOpenWidth();
828 nYMov = aResize.getOpenHeight();
829 switch(_nControlModification)
831 case ControlModification::WIDTH_GREATEST:
832 case ControlModification::HEIGHT_GREATEST:
833 if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
834 nXMov = aObjRect.getOpenWidth();
835 else if ( _nControlModification == ControlModification::WIDTH_GREATEST )
836 nYMov = aObjRect.getOpenHeight();
837 lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification);
838 [[fallthrough]];
839 case ControlModification::WIDTH_SMALLEST:
840 case ControlModification::HEIGHT_SMALLEST:
841 pView->AddUndo( pView->GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
843 OObjectBase* pObjBase = dynamic_cast<OObjectBase*>(pObj);
844 OSL_ENSURE(pObjBase,"Where comes this object from?");
845 if ( pObjBase )
847 if ( _nControlModification == ControlModification::WIDTH_SMALLEST || _nControlModification == ControlModification::WIDTH_GREATEST )
848 pObjBase->getReportComponent()->setSize(awt::Size(nXMov,aObjRect.getOpenHeight()));
849 else if ( _nControlModification == ControlModification::HEIGHT_GREATEST || _nControlModification == ControlModification::HEIGHT_SMALLEST )
850 pObjBase->getReportComponent()->setSize(awt::Size(aObjRect.getOpenWidth(),nYMov));
853 break;
854 default:
855 break;
859 pView->AdjustMarkHdl();
863 void OViewsWindow::createDefault()
865 OSectionWindow* pMarkedSection = getMarkedSection();
866 if ( pMarkedSection )
867 pMarkedSection->getReportSection().createDefault(m_sShapeType);
870 void OViewsWindow::setGridSnap(bool bOn)
872 for (const auto& rxSection : m_aSections)
874 rxSection->getReportSection().getSectionView().SetGridSnap(bOn);
875 rxSection->getReportSection().Invalidate();
879 void OViewsWindow::setDragStripes(bool bOn)
881 for (const auto& rxSection : m_aSections)
882 rxSection->getReportSection().getSectionView().SetDragStripes(bOn);
885 sal_uInt16 OViewsWindow::getPosition(const OSectionWindow* _pSectionWindow) const
887 auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(),
888 [&_pSectionWindow](const VclPtr<OSectionWindow>& rxSection) { return _pSectionWindow == rxSection.get(); });
889 return static_cast<sal_uInt16>(std::distance(m_aSections.begin(), aIter));
892 OSectionWindow* OViewsWindow::getSectionWindow(const sal_uInt16 _nPos) const
894 OSectionWindow* aReturn = nullptr;
896 if ( _nPos < m_aSections.size() )
897 aReturn = m_aSections[_nPos].get();
899 return aReturn;
902 namespace
904 enum SectionViewAction
906 eEndDragObj,
907 eEndAction,
908 eForceToAnotherPage,
909 eBreakAction
911 class ApplySectionViewAction
913 private:
914 SectionViewAction m_eAction;
916 public:
917 explicit ApplySectionViewAction()
918 : m_eAction(eEndDragObj)
922 explicit ApplySectionViewAction(SectionViewAction _eAction)
923 : m_eAction(_eAction)
927 void operator() ( const OViewsWindow::TSectionsMap::value_type& _rhs )
929 OSectionView& rView( _rhs->getReportSection().getSectionView() );
930 switch ( m_eAction )
932 case eEndDragObj:
933 rView.EndDragObj();
934 break;
935 case eEndAction:
936 if ( rView.IsAction() )
937 rView.EndAction ( );
938 break;
939 case eForceToAnotherPage:
940 rView.ForceMarkedToAnotherPage();
941 break;
942 case eBreakAction:
943 if ( rView.IsAction() )
944 rView.BrkAction ( );
945 break;
946 // default:
953 void OViewsWindow::BrkAction()
955 EndDragObj_removeInvisibleObjects();
956 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eBreakAction) );
959 void OViewsWindow::BegDragObj_createInvisibleObjectAtPosition(const tools::Rectangle& _aRect, const OSectionView& _rSection)
961 Point aNewPos(0,0);
963 for (const auto& rxSection : m_aSections)
965 OReportSection& rReportSection = rxSection->getReportSection();
966 rReportSection.getPage()->setSpecialMode();
967 OSectionView& rView = rReportSection.getSectionView();
969 if ( &rView != &_rSection )
971 rtl::Reference<SdrObject> pNewObj = new SdrUnoObj(
972 rView.getSdrModelFromSdrView(),
973 u"com.sun.star.form.component.FixedText"_ustr);
975 pNewObj->SetLogicRect(_aRect);
976 pNewObj->Move(Size(0, aNewPos.Y()));
977 bool bChanged = rView.GetModel().IsChanged();
978 rReportSection.getPage()->InsertObject(pNewObj.get());
979 rView.GetModel().SetChanged(bChanged);
980 m_aBegDragTempList.push_back(pNewObj.get());
982 rView.MarkObj( pNewObj.get(), rView.GetSdrPageView() );
984 const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
985 aNewPos.AdjustY( -nSectionHeight );
989 void OViewsWindow::BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection)
991 SAL_INFO(
992 "reportdesign", "Clickpoint X:" << _aPnt.X() << " Y:" << _aPnt.Y());
994 m_aBegDragTempList.clear();
996 // Calculate the absolute clickpoint in the views
997 Point aAbsolutePnt = _aPnt;
998 for (const auto& rxSection : m_aSections)
1000 OReportSection& rReportSection = rxSection->getReportSection();
1001 OSectionView* pView = &rReportSection.getSectionView();
1002 if (pView == _pSection)
1003 break;
1004 const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1005 aAbsolutePnt.AdjustY(nSectionHeight );
1007 m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
1008 SAL_INFO(
1009 "reportdesign",
1010 "Absolute X:" << aAbsolutePnt.X() << " Y:" << aAbsolutePnt.Y());
1012 // Create drag lines over all viewable Views
1013 // Therefore we need to identify the marked objects
1014 // and create temporary objects on all other views at the same position
1015 // relative to its occurrence.
1017 int nViewCount = 0;
1018 Point aNewObjPos(0,0);
1019 Point aLeftTop(SAL_MAX_INT32, SAL_MAX_INT32);
1020 for (const auto& rxSection : m_aSections)
1022 OReportSection& rReportSection = rxSection->getReportSection();
1024 OSectionView& rView = rReportSection.getSectionView();
1026 if ( rView.GetMarkedObjectList().GetMarkCount() != 0 )
1028 const size_t nCount = rView.GetMarkedObjectList().GetMarkCount();
1029 for (size_t i=0; i < nCount; ++i)
1031 const SdrMark* pM = rView.GetMarkedObjectList().GetMark(i);
1032 SdrObject* pObj = pM->GetMarkedSdrObj();
1033 if (::std::find(m_aBegDragTempList.begin(),m_aBegDragTempList.end(),pObj) == m_aBegDragTempList.end())
1035 tools::Rectangle aRect( pObj->GetCurrentBoundRect() );
1036 aRect.Move(0, aNewObjPos.Y());
1038 aLeftTop.setX( ::std::min( aRect.Left(), aLeftTop.X() ) );
1039 aLeftTop.setY( ::std::min( aRect.Top(), aLeftTop.Y() ) );
1041 SAL_INFO(
1042 "reportdesign",
1043 "createInvisible X:" << aRect.Left() << " Y:"
1044 << aRect.Top() << " on View #" << nViewCount);
1046 BegDragObj_createInvisibleObjectAtPosition(aRect, rView);
1047 // BegDragObj_createInvisibleObjectAtPosition will call
1048 // SdrMarkView::MarkObj
1049 // -> SdrMarkView::AdjustMarkHdl
1050 // -> SdrDragView::SetMarkHandles
1051 // -> SdrMarkView::SetMarkHandles
1052 // which will recreate the SdrHdl objects.
1053 _pHdl = _pSection->PickHandle(_aPnt);
1057 ++nViewCount;
1058 tools::Rectangle aClipRect = rView.GetWorkArea();
1059 aClipRect.SetTop( -aNewObjPos.Y() );
1060 rView.SetWorkArea( aClipRect );
1062 const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1063 aNewObjPos.AdjustY(nSectionHeight );
1066 const sal_Int32 nDeltaX = std::abs(aLeftTop.X() - aAbsolutePnt.X());
1067 const sal_Int32 nDeltaY = std::abs(aLeftTop.Y() - aAbsolutePnt.Y());
1068 m_aDragDelta.setX( nDeltaX );
1069 m_aDragDelta.setY( nDeltaY );
1071 Point aNewPos = aAbsolutePnt;
1073 const short nDrgLog = static_cast<short>(PixelToLogic(Size(3,0)).Width());
1074 nViewCount = 0;
1075 for (const auto& rxSection : m_aSections)
1077 OReportSection& rReportSection = rxSection->getReportSection();
1079 SdrHdl* pHdl = _pHdl;
1080 if ( pHdl )
1082 if ( &rReportSection.getSectionView() != _pSection )
1084 const SdrHdlList& rHdlList = rReportSection.getSectionView().GetHdlList();
1085 pHdl = rHdlList.GetHdl(_pHdl->GetKind());
1088 SAL_INFO(
1089 "reportdesign",
1090 "X:" << aNewPos.X() << " Y:" << aNewPos.Y() << " on View#"
1091 << nViewCount++);
1092 rReportSection.getSectionView().BegDragObj(aNewPos, nullptr, pHdl, nDrgLog);
1094 const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1095 aNewPos.AdjustY( -nSectionHeight );
1100 void OViewsWindow::ForceMarkedToAnotherPage()
1102 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eForceToAnotherPage ) );
1105 void OViewsWindow::BegMarkObj(const Point& _aPnt,const OSectionView* _pSection)
1107 bool bAdd = true;
1108 Point aNewPos = _aPnt;
1110 tools::Long nLastSectionHeight = 0;
1111 for (const auto& rxSection : m_aSections)
1113 OReportSection& rReportSection = rxSection->getReportSection();
1114 if ( &rReportSection.getSectionView() == _pSection )
1116 bAdd = false;
1117 aNewPos = _aPnt; // 2,2
1119 else if ( bAdd )
1121 const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1122 aNewPos.AdjustY(nSectionHeight );
1124 else
1126 aNewPos.AdjustY( -nLastSectionHeight );
1128 rReportSection.getSectionView().BegMarkObj ( aNewPos );
1129 nLastSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1133 OSectionView* OViewsWindow::getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt)
1135 OSectionView* pSection = nullptr;
1136 TSectionsMap::const_iterator aIter = m_aSections.begin();
1137 const TSectionsMap::const_iterator aEnd = m_aSections.end();
1138 aIter = std::find_if(aIter, aEnd, [&_pSection](const VclPtr<OSectionWindow>& rxSection) {
1139 return &rxSection->getReportSection().getSectionView() == _pSection; });
1140 sal_Int32 nCount = static_cast<sal_Int32>(std::distance(m_aSections.cbegin(), aIter));
1141 OSL_ENSURE(aIter != aEnd,"This can never happen!");
1142 if ( _rPnt.Y() < 0 )
1144 if ( nCount )
1145 --aIter;
1146 for (; nCount && (_rPnt.Y() < 0); --nCount)
1148 OReportSection& rReportSection = (*aIter)->getReportSection();
1149 const sal_Int32 nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1150 _rPnt.AdjustY(nHeight );
1151 if ( (nCount -1) > 0 && (_rPnt.Y() < 0) )
1152 --aIter;
1154 if ( nCount == 0 )
1155 pSection = &(*m_aSections.begin())->getReportSection().getSectionView();
1156 else
1157 pSection = &(*aIter)->getReportSection().getSectionView();
1159 else
1161 for (; aIter != aEnd; ++aIter)
1163 OReportSection& rReportSection = (*aIter)->getReportSection();
1164 const tools::Long nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1165 if ( (_rPnt.Y() - nHeight) < 0 )
1166 break;
1167 _rPnt.AdjustY( -nHeight );
1169 if ( aIter != aEnd )
1170 pSection = &(*aIter)->getReportSection().getSectionView();
1171 else
1172 pSection = &(*(aEnd-1))->getReportSection().getSectionView();
1175 return pSection;
1178 void OViewsWindow::EndDragObj_removeInvisibleObjects()
1180 for (const auto& rxSection : m_aSections)
1182 OReportSection& rReportSection = rxSection->getReportSection();
1183 rReportSection.getPage()->resetSpecialMode();
1187 void OViewsWindow::EndDragObj(bool _bControlKeyPressed, const OSectionView* _pSection, const Point& _aPnt)
1189 const OUString sUndoAction = RptResId(RID_STR_UNDO_CHANGEPOSITION);
1190 const UndoContext aUndoContext( getView()->getReportView()->getController().getUndoManager(), sUndoAction );
1192 Point aNewPos = _aPnt;
1193 OSectionView* pInSection = getSectionRelativeToPosition(_pSection, aNewPos);
1194 if (!_bControlKeyPressed &&
1195 _pSection && !_pSection->IsDragResize() && /* Not in resize mode */
1196 _pSection != pInSection)
1198 EndDragObj_removeInvisibleObjects();
1200 // we need to manipulate the current clickpoint, we subtract the old delta from BeginDrag
1201 aNewPos -= m_aDragDelta;
1203 uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
1204 for (const auto& rxSection : m_aSections)
1206 OReportSection& rReportSection = rxSection->getReportSection();
1207 if ( pInSection != &rReportSection.getSectionView() )
1209 rReportSection.getSectionView().BrkAction();
1210 rReportSection.Copy(aAllreadyCopiedObjects,true);
1212 else
1213 pInSection->EndDragObj();
1216 if ( aAllreadyCopiedObjects.hasElements() )
1220 uno::Reference<report::XReportDefinition> xReportDefinition = getView()->getReportView()->getController().getReportDefinition();
1221 const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
1222 const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
1223 const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width;
1225 if ( aNewPos.X() < nLeftMargin )
1226 aNewPos.setX( nLeftMargin );
1227 if ( aNewPos.Y() < 0 )
1228 aNewPos.setY( 0 );
1230 Point aPrevious;
1231 for (beans::NamedValue const& namedVal : aAllreadyCopiedObjects)
1233 uno::Sequence< uno::Reference<report::XReportComponent> > aClones;
1234 namedVal.Value >>= aClones;
1235 uno::Reference<report::XReportComponent>* pColIter = aClones.getArray();
1236 const uno::Reference<report::XReportComponent>* pColEnd = pColIter + aClones.getLength();
1238 // move the cloned Components to new positions
1239 for (; pColIter != pColEnd; ++pColIter)
1241 uno::Reference< report::XReportComponent> xRC(*pColIter);
1242 aPrevious = vcl::unohelper::ConvertToVCLPoint(xRC->getPosition());
1243 awt::Size aSize = xRC->getSize();
1245 if ( aNewPos.X() < nLeftMargin )
1247 aNewPos.setX( nLeftMargin );
1249 else if ( (aNewPos.X() + aSize.Width) > (nPaperWidth - nRightMargin) )
1251 aNewPos.setX( nPaperWidth - nRightMargin - aSize.Width );
1253 if ( aNewPos.Y() < 0 )
1255 aNewPos.setY( 0 );
1257 if ( aNewPos.X() < 0 )
1259 aSize.Width += aNewPos.X();
1260 aNewPos.setX( 0 );
1261 xRC->setSize(aSize);
1263 xRC->setPosition(vcl::unohelper::ConvertToAWTPoint(aNewPos));
1264 if ( (pColIter+1) != pColEnd )
1266 // bring aNewPos to the position of the next object
1267 uno::Reference< report::XReportComponent> xRCNext = *(pColIter + 1);
1268 Point aNextPosition
1269 = vcl::unohelper::ConvertToVCLPoint(xRCNext->getPosition());
1270 aNewPos += aNextPosition - aPrevious;
1275 catch(uno::Exception&)
1278 pInSection->getReportSection()->Paste(aAllreadyCopiedObjects,true);
1281 else
1283 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction() );
1284 EndDragObj_removeInvisibleObjects();
1286 m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
1289 void OViewsWindow::EndAction()
1291 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eEndAction) );
1294 void OViewsWindow::MovAction(const Point& _aPnt,const OSectionView* _pSection, bool _bControlKeySet)
1296 Point aRealMousePos = _aPnt;
1297 Point aCurrentSectionPos;
1298 SAL_INFO(
1299 "reportdesign",
1300 "X:" << aRealMousePos.X() << " Y:" << aRealMousePos.Y());
1302 Point aHdlPos;
1303 SdrHdl* pHdl = _pSection->GetDragHdl();
1304 if ( pHdl )
1306 aHdlPos = pHdl->GetPos();
1309 for (const auto& rxSection : m_aSections)
1311 OReportSection& rReportSection = rxSection->getReportSection();
1312 if ( &rReportSection.getSectionView() == _pSection )
1313 break;
1314 const tools::Long nSectionHeight = rxSection->PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1315 aCurrentSectionPos.AdjustY(nSectionHeight );
1317 aRealMousePos += aCurrentSectionPos;
1319 // If control key is pressed the work area is limited to the section with the current selection.
1320 Point aPosForWorkArea(0,0);
1321 for (const auto& rxSection : m_aSections)
1323 OReportSection& rReportSection = rxSection->getReportSection();
1324 OSectionView& rView = rReportSection.getSectionView();
1325 const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height();
1327 if (_bControlKeySet)
1329 tools::Rectangle aClipRect = rView.GetWorkArea();
1330 aClipRect.SetTop( aCurrentSectionPos.Y() - aPosForWorkArea.Y() );
1331 aClipRect.SetBottom( aClipRect.Top() + nSectionHeight );
1332 rView.SetWorkArea( aClipRect );
1334 else
1336 tools::Rectangle aClipRect = rView.GetWorkArea();
1337 aClipRect.SetTop( -aPosForWorkArea.Y() );
1338 rView.SetWorkArea( aClipRect );
1340 aPosForWorkArea.AdjustY(nSectionHeight );
1344 for (const auto& rxSection : m_aSections)
1346 OReportSection& rReportSection = rxSection->getReportSection();
1347 SdrHdl* pCurrentHdl = rReportSection.getSectionView().GetDragHdl();
1348 if ( pCurrentHdl && aRealMousePos.Y() > 0 )
1349 aRealMousePos = _aPnt + pCurrentHdl->GetPos() - aHdlPos;
1350 rReportSection.getSectionView().MovAction ( aRealMousePos );
1351 const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height();
1352 aRealMousePos.AdjustY( -nSectionHeight );
1356 bool OViewsWindow::IsAction() const
1358 return std::any_of(m_aSections.begin(), m_aSections.end(),
1359 [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); });
1362 bool OViewsWindow::IsDragObj() const
1364 return std::any_of(m_aSections.begin(), m_aSections.end(),
1365 [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); });
1368 sal_uInt32 OViewsWindow::getMarkedObjectCount() const
1370 return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_uInt32(0),
1371 [](const sal_uInt32 nCount, const VclPtr<OSectionWindow>& rxSection) {
1372 return nCount + static_cast<sal_uInt32>(rxSection->getReportSection().getSectionView().GetMarkedObjectList().GetMarkCount()); });
1375 void OViewsWindow::handleKey(const vcl::KeyCode& _rCode)
1377 const sal_uInt16 nCode = _rCode.GetCode();
1378 if ( _rCode.IsMod1() )
1380 // scroll page
1381 OScrollWindowHelper* pScrollWindow = getView()->getScrollWindow();
1382 ScrollAdaptor& rScrollBar = ( nCode == KEY_LEFT || nCode == KEY_RIGHT ) ? pScrollWindow->GetHScroll() : pScrollWindow->GetVScroll();
1383 if ( rScrollBar.IsVisible() )
1385 auto nCurrentPos = rScrollBar.GetThumbPos();
1386 auto nLineSize = rScrollBar.GetLineSize();
1387 rScrollBar.DoScroll(( nCode == KEY_RIGHT || nCode == KEY_UP ) ? (nCurrentPos - nLineSize) : (nCurrentPos + nLineSize));
1389 return;
1392 for (const auto& rxSection : m_aSections)
1394 OReportSection& rReportSection = rxSection->getReportSection();
1395 tools::Long nX = 0;
1396 tools::Long nY = 0;
1398 if ( nCode == KEY_UP )
1399 nY = -1;
1400 else if ( nCode == KEY_DOWN )
1401 nY = 1;
1402 else if ( nCode == KEY_LEFT )
1403 nX = -1;
1404 else if ( nCode == KEY_RIGHT )
1405 nX = 1;
1407 if ( rReportSection.getSectionView().GetMarkedObjectList().GetMarkCount() != 0 )
1409 if ( _rCode.IsMod2() )
1411 // move in 1 pixel distance
1412 const Size aPixelSize = rReportSection.PixelToLogic( Size( 1, 1 ) );
1413 nX *= aPixelSize.Width();
1414 nY *= aPixelSize.Height();
1416 else
1418 // move in 1 mm distance
1419 nX *= DEFAUL_MOVE_SIZE;
1420 nY *= DEFAUL_MOVE_SIZE;
1423 OSectionView& rView = rReportSection.getSectionView();
1424 const SdrHdlList& rHdlList = rView.GetHdlList();
1425 SdrHdl* pHdl = rHdlList.GetFocusHdl();
1427 if ( pHdl == nullptr )
1429 // no handle selected
1430 if ( rView.IsMoveAllowed() )
1432 // restrict movement to work area
1433 tools::Rectangle rWorkArea = rView.GetWorkArea();
1434 rWorkArea.AdjustRight( 1 );
1436 if ( !rWorkArea.IsEmpty() )
1438 if ( rWorkArea.Top() < 0 )
1439 rWorkArea.SetTop( 0 );
1440 tools::Rectangle aMarkRect( rView.GetMarkedObjRect() );
1441 aMarkRect.Move( nX, nY );
1443 if ( !rWorkArea.Contains( aMarkRect ) )
1445 if ( aMarkRect.Left() < rWorkArea.Left() )
1446 nX += rWorkArea.Left() - aMarkRect.Left();
1448 if ( aMarkRect.Right() > rWorkArea.Right() )
1449 nX -= aMarkRect.Right() - rWorkArea.Right();
1451 if ( aMarkRect.Top() < rWorkArea.Top() )
1452 nY += rWorkArea.Top() - aMarkRect.Top();
1454 if ( aMarkRect.Bottom() > rWorkArea.Bottom() )
1455 nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
1457 bool bCheck = false;
1458 const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
1459 for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
1461 SdrMark* pMark = rMarkList.GetMark(i);
1462 bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr|| dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj());
1466 if ( bCheck )
1468 SdrObject* pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
1469 if ( pOverlapped )
1473 tools::Rectangle aOver = pOverlapped->GetLastBoundRect();
1474 Point aPos;
1475 if ( nCode == KEY_UP )
1477 aPos.setX( aMarkRect.Left() );
1478 aPos.setY( aOver.Top() - aMarkRect.getOpenHeight() );
1479 nY += (aPos.Y() - aMarkRect.Top());
1481 else if ( nCode == KEY_DOWN )
1483 aPos.setX( aMarkRect.Left() );
1484 aPos.setY( aOver.Bottom() );
1485 nY += (aPos.Y() - aMarkRect.Top());
1487 else if ( nCode == KEY_LEFT )
1489 aPos.setX( aOver.Left() - aMarkRect.getOpenWidth() );
1490 aPos.setY( aMarkRect.Top() );
1491 nX += (aPos.X() - aMarkRect.Left());
1493 else if ( nCode == KEY_RIGHT )
1495 aPos.setX( aOver.Right() );
1496 aPos.setY( aMarkRect.Top() );
1497 nX += (aPos.X() - aMarkRect.Left());
1500 aMarkRect.SetPos(aPos);
1501 if ( !rWorkArea.Contains( aMarkRect ) )
1503 break;
1505 pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
1507 while(pOverlapped != nullptr);
1508 if (pOverlapped != nullptr)
1509 break;
1514 if ( nX != 0 || nY != 0 )
1516 rView.MoveAllMarked( Size( nX, nY ) );
1517 rView.MakeVisible( rView.GetAllMarkedRect(), rReportSection);
1521 else // pHdl != nullptr
1523 // move the handle
1524 if (nX || nY)
1526 const Point aStartPoint( pHdl->GetPos() );
1527 const Point aEndPoint( pHdl->GetPos() + Point( nX, nY ) );
1528 const SdrDragStat& rDragStat = rView.GetDragStat();
1530 // start dragging
1531 rView.BegDragObj( aStartPoint, nullptr, pHdl, 0 );
1533 if ( rView.IsDragObj() )
1535 const bool bWasNoSnap = rDragStat.IsNoSnap();
1536 const bool bWasSnapEnabled = rView.IsSnapEnabled();
1538 // switch snapping off
1539 if ( !bWasNoSnap )
1540 const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
1541 if ( bWasSnapEnabled )
1542 rView.SetSnapEnabled( false );
1544 tools::Rectangle aNewRect;
1545 bool bCheck = false;
1546 const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
1547 for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
1549 SdrMark* pMark = rMarkList.GetMark(i);
1550 bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr || dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()) != nullptr;
1551 if ( bCheck )
1552 aNewRect.Union(pMark->GetMarkedSdrObj()->GetLastBoundRect());
1555 switch(pHdl->GetKind())
1557 case SdrHdlKind::Left:
1558 case SdrHdlKind::UpperLeft:
1559 case SdrHdlKind::LowerLeft:
1560 case SdrHdlKind::Upper:
1561 aNewRect.AdjustLeft(nX );
1562 aNewRect.AdjustTop(nY );
1563 break;
1564 case SdrHdlKind::UpperRight:
1565 case SdrHdlKind::Right:
1566 case SdrHdlKind::LowerRight:
1567 case SdrHdlKind::Lower:
1568 aNewRect.setWidth(aNewRect.getOpenWidth() + nX);
1569 aNewRect.setHeight(aNewRect.getOpenHeight() + nY);
1570 break;
1571 default:
1572 break;
1574 if ( !(bCheck && isOver(aNewRect,*rReportSection.getPage(),rView)) )
1575 rView.MovAction(aEndPoint);
1576 rView.EndDragObj();
1578 // restore snap
1579 if ( !bWasNoSnap )
1580 const_cast<SdrDragStat&>(rDragStat).SetNoSnap( bWasNoSnap );
1581 if ( bWasSnapEnabled )
1582 rView.SetSnapEnabled( bWasSnapEnabled );
1585 // make moved handle visible
1586 const tools::Rectangle aVisRect( aEndPoint - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) );
1587 rView.MakeVisible( aVisRect, rReportSection);
1590 rView.AdjustMarkHdl();
1595 void OViewsWindow::stopScrollTimer()
1597 ::std::for_each(m_aSections.begin(),m_aSections.end(),
1598 [] (const TSectionsMap::value_type& sectionPtr) {
1599 sectionPtr->getReportSection().stopScrollTimer();
1603 void OViewsWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
1605 sal_uInt16 i = 0;
1606 for (const auto& rxSection : m_aSections)
1608 if ( rxSection->getStartMarker().isCollapsed() )
1609 _rCollapsedPositions.push_back(i);
1610 ++i;
1614 void OViewsWindow::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollapsedSections)
1616 for (const beans::PropertyValue& rSection : _aCollapsedSections)
1618 sal_uInt16 nPos = sal_uInt16(-1);
1619 if ( (rSection.Value >>= nPos) && nPos < m_aSections.size() )
1621 m_aSections[nPos]->setCollapsed(true);
1626 void OViewsWindow::zoom(const Fraction& _aZoom)
1628 const MapMode& aMapMode = GetMapMode();
1630 Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH));
1631 if ( _aZoom < aMapMode.GetScaleX() )
1632 aStartWidth *= aMapMode.GetScaleX();
1633 else
1634 aStartWidth *= _aZoom;
1636 setZoomFactor(_aZoom,*this);
1638 for (const auto& rxSection : m_aSections)
1640 rxSection->zoom(_aZoom);
1643 Resize();
1645 Size aOut = GetOutputSizePixel();
1646 aOut.setWidth( tools::Long(aStartWidth) );
1647 aOut = PixelToLogic(aOut);
1649 tools::Rectangle aRect(PixelToLogic(Point(0,0)),aOut);
1650 Invalidate(aRect, InvalidateFlags::NoChildren);
1653 void OViewsWindow::scrollChildren(const Point& _aThumbPos)
1655 const Point aPos(PixelToLogic(_aThumbPos));
1657 MapMode aMapMode = GetMapMode();
1658 const Point aOld = aMapMode.GetOrigin();
1659 aMapMode.SetOrigin(m_pParent->GetMapMode().GetOrigin());
1661 const Point aPosY(m_pParent->PixelToLogic(_aThumbPos,aMapMode));
1663 aMapMode.SetOrigin( Point(aOld.X() , - aPosY.Y()));
1664 SetMapMode( aMapMode );
1665 Scroll(0, -( aOld.Y() + aPosY.Y()),ScrollFlags::Children);
1668 for (const auto& rxSection : m_aSections)
1670 rxSection->scrollChildren(aPos.X());
1674 void OViewsWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
1676 for (const auto& rxSection : m_aSections)
1678 rxSection->getReportSection().fillControlModelSelection(_rSelection);
1682 } // rptui
1685 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */