bump product version to 5.0.4.1
[LibreOffice.git] / reportdesign / source / ui / report / ViewsWindow.cxx
blobc46d935c0129b53f7b76baf8ad5699fefa5763ac
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 "RptResId.hrc"
30 #include "SectionView.hxx"
31 #include "ReportSection.hxx"
32 #include "uistrings.hrc"
33 #include "rptui_slotid.hrc"
34 #include "dlgedclip.hxx"
35 #include "ColorChanger.hxx"
36 #include "RptObject.hxx"
37 #include "ModuleHelper.hxx"
38 #include "EndMarker.hxx"
39 #include <svx/svdpagv.hxx>
40 #include <svx/unoshape.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/settings.hxx>
44 #include <boost/bind.hpp>
46 #include "helpids.hrc"
47 #include <svx/svdundo.hxx>
48 #include <toolkit/helper/convert.hxx>
49 #include <algorithm>
50 #include <cstdlib>
51 #include <numeric>
52 #include <o3tl/compat_functional.hxx>
54 namespace rptui
56 #define DEFAUL_MOVE_SIZE 100
58 using namespace ::com::sun::star;
59 using namespace ::comphelper;
61 bool lcl_getNewRectSize(const Rectangle& _aObjRect,long& _nXMov, long& _nYMov,SdrObject* _pObj,SdrView* _pView,sal_Int32 _nControlModification, bool _bBoundRects)
63 bool bMoveAllowed = _nXMov != 0 || _nYMov != 0;
64 if ( bMoveAllowed )
66 Rectangle aNewRect = _aObjRect;
67 SdrObject* pOverlappedObj = NULL;
70 aNewRect = _aObjRect;
71 switch(_nControlModification)
73 case ControlModification::HEIGHT_GREATEST:
74 case ControlModification::WIDTH_GREATEST:
75 aNewRect.setWidth(_nXMov);
76 aNewRect.setHeight(_nYMov);
77 break;
78 default:
79 aNewRect.Move(_nXMov,_nYMov);
80 break;
82 if (dynamic_cast<OUnoObject*>(_pObj) != NULL || dynamic_cast<OOle2Obj*>(_pObj) != NULL)
84 pOverlappedObj = isOver(aNewRect,*_pObj->GetPage(),*_pView,true,_pObj);
85 if ( pOverlappedObj && _pObj != pOverlappedObj )
87 Rectangle aOverlappingRect = (_bBoundRects ? pOverlappedObj->GetCurrentBoundRect() : pOverlappedObj->GetSnapRect());
88 sal_Int32 nXTemp = _nXMov;
89 sal_Int32 nYTemp = _nYMov;
90 switch(_nControlModification)
92 case ControlModification::LEFT:
93 nXTemp += aOverlappingRect.Right() - aNewRect.Left();
94 bMoveAllowed = _nXMov != nXTemp;
95 break;
96 case ControlModification::RIGHT:
97 nXTemp += aOverlappingRect.Left() - aNewRect.Right();
98 bMoveAllowed = _nXMov != nXTemp;
99 break;
100 case ControlModification::TOP:
101 nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
102 bMoveAllowed = _nYMov != nYTemp;
103 break;
104 case ControlModification::BOTTOM:
105 nYTemp += aOverlappingRect.Top() - aNewRect.Bottom();
106 bMoveAllowed = _nYMov != nYTemp;
107 break;
108 case ControlModification::CENTER_HORIZONTAL:
109 if ( _aObjRect.Left() < aOverlappingRect.Left() )
110 nXTemp += aOverlappingRect.Left() - aNewRect.Left() - aNewRect.getWidth();
111 else
112 nXTemp += aOverlappingRect.Right() - aNewRect.Left();
113 bMoveAllowed = _nXMov != nXTemp;
114 break;
115 case ControlModification::CENTER_VERTICAL:
116 if ( _aObjRect.Top() < aOverlappingRect.Top() )
117 nYTemp += aOverlappingRect.Top() - aNewRect.Top() - aNewRect.getHeight();
118 else
119 nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
120 bMoveAllowed = _nYMov != nYTemp;
121 break;
122 case ControlModification::HEIGHT_GREATEST:
123 case ControlModification::WIDTH_GREATEST:
125 Rectangle aIntersectionRect = aNewRect.GetIntersection(aOverlappingRect);
126 if ( !aIntersectionRect.IsEmpty() )
128 if ( _nControlModification == ControlModification::WIDTH_GREATEST )
130 if ( aNewRect.Left() < aIntersectionRect.Left() )
132 aNewRect.Right() = aIntersectionRect.Left();
134 else if ( aNewRect.Left() < aIntersectionRect.Right() )
136 aNewRect.Left() = aIntersectionRect.Right();
139 else if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
141 if ( aNewRect.Top() < aIntersectionRect.Top() )
143 aNewRect.Bottom() = aIntersectionRect.Top();
145 else if ( aNewRect.Top() < aIntersectionRect.Bottom() )
147 aNewRect.Top() = aIntersectionRect.Bottom();
150 nYTemp = aNewRect.getHeight();
151 bMoveAllowed = _nYMov != nYTemp;
152 nXTemp = aNewRect.getWidth();
153 bMoveAllowed = bMoveAllowed && _nXMov != nXTemp;
156 break;
157 default:
158 break;
161 _nXMov = nXTemp;
162 _nYMov = nYTemp;
164 else
165 pOverlappedObj = NULL;
168 while ( pOverlappedObj && bMoveAllowed );
170 return bMoveAllowed;
174 OViewsWindow::OViewsWindow( OReportWindow* _pReportWindow)
175 : Window( _pReportWindow,WB_DIALOGCONTROL)
176 , m_pParent(_pReportWindow)
177 , m_bInUnmark(false)
179 SetPaintTransparent(true);
180 SetUniqueId(UID_RPT_VIEWSWINDOW);
181 SetMapMode(MapMode(MAP_100TH_MM));
182 m_aColorConfig.AddListener(this);
183 ImplInitSettings();
186 OViewsWindow::~OViewsWindow()
188 disposeOnce();
191 void OViewsWindow::dispose()
193 m_aColorConfig.RemoveListener(this);
194 for (auto i = m_aSections.begin(); i != m_aSections.end(); ++i)
195 i->disposeAndClear();
196 m_aSections.clear();
197 m_pParent.clear();
198 vcl::Window::dispose();
201 void OViewsWindow::impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet)
203 const uno::Reference< report::XSection> xSection = _rSectionWindow.getReportSection().getSection();
205 Size aSectionSize = _rSectionWindow.LogicToPixel( Size( 0,xSection->getHeight() ) );
206 aSectionSize.Width() = getView()->GetTotalWidth();
208 const sal_Int32 nMinHeight = _rSectionWindow.getStartMarker().getMinHeight();
209 if ( _rSectionWindow.getStartMarker().isCollapsed() || nMinHeight > aSectionSize.Height() )
211 aSectionSize.Height() = nMinHeight;
213 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
214 aSectionSize.Height() += (long)(rSettings.GetSplitSize() * (double)_rSectionWindow.GetMapMode().GetScaleY());
216 if ( _bSet )
217 _rSectionWindow.SetPosSizePixel(_rStartPoint,aSectionSize);
219 _rStartPoint.Y() += aSectionSize.Height();
223 void OViewsWindow::resize(const OSectionWindow& _rSectionWindow)
225 bool bSet = false;
226 Point aStartPoint;
227 TSectionsMap::iterator aIter = m_aSections.begin();
228 TSectionsMap::iterator aEnd = m_aSections.end();
229 for (;aIter != aEnd ; ++aIter)
231 OSectionWindow* pSectionWindow = (*aIter);
232 if ( pSectionWindow == &_rSectionWindow )
234 aStartPoint = pSectionWindow->GetPosPixel();
235 bSet = true;
238 if ( bSet )
240 impl_resizeSectionWindow(*pSectionWindow,aStartPoint,bSet);
241 static sal_Int32 nIn = INVALIDATE_UPDATE | INVALIDATE_TRANSPARENT;
242 pSectionWindow->getStartMarker().Invalidate( nIn ); // INVALIDATE_NOERASE |INVALIDATE_NOCHILDREN| INVALIDATE_TRANSPARENT
243 pSectionWindow->getEndMarker().Invalidate( nIn );
246 m_pParent->notifySizeChanged();
249 void OViewsWindow::Resize()
251 Window::Resize();
252 if ( !m_aSections.empty() )
254 const Point aOffset(m_pParent->getThumbPos());
255 Point aStartPoint(0,-aOffset.Y());
256 TSectionsMap::iterator aIter = m_aSections.begin();
257 TSectionsMap::iterator aEnd = m_aSections.end();
258 for (;aIter != aEnd ; ++aIter)
260 OSectionWindow* pSectionWindow = (*aIter);
261 impl_resizeSectionWindow(*pSectionWindow,aStartPoint,true);
266 void OViewsWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
268 Window::Paint(rRenderContext, rRect);
270 rRenderContext.SetBackground();
271 rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
272 rRenderContext.SetTextFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
274 Size aOut(GetOutputSizePixel());
275 Fraction aStartWidth(long(REPORT_STARTMARKER_WIDTH));
276 aStartWidth *= rRenderContext.GetMapMode().GetScaleX();
278 aOut.Width() -= long(aStartWidth);
279 aOut = rRenderContext.PixelToLogic(aOut);
281 Rectangle aRect(rRenderContext.PixelToLogic(Point(aStartWidth,0)), aOut);
282 Wallpaper aWall(m_aColorConfig.GetColorValue(::svtools::APPBACKGROUND).nColor);
283 rRenderContext.DrawWallpaper(aRect, aWall);
286 void OViewsWindow::ImplInitSettings()
288 EnableChildTransparentMode(true);
291 void OViewsWindow::DataChanged( const DataChangedEvent& rDCEvt )
293 Window::DataChanged( rDCEvt );
295 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
296 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
298 ImplInitSettings();
299 Invalidate();
303 void OViewsWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition)
305 VclPtrInstance<OSectionWindow> pSectionWindow(this,_xSection,_sColorEntry);
306 m_aSections.insert(getIteratorAtPos(_nPosition) , TSectionsMap::value_type(pSectionWindow));
307 m_pParent->setMarked(&pSectionWindow->getReportSection().getSectionView(),m_aSections.size() == 1);
308 Resize();
311 void OViewsWindow::removeSection(sal_uInt16 _nPosition)
313 if ( _nPosition < m_aSections.size() )
315 TSectionsMap::iterator aPos = getIteratorAtPos(_nPosition);
316 TSectionsMap::iterator aNew = getIteratorAtPos(_nPosition == 0 ? _nPosition+1: _nPosition - 1);
318 m_pParent->getReportView()->UpdatePropertyBrowserDelayed((*aNew)->getReportSection().getSectionView());
320 aPos->disposeAndClear();;
321 m_aSections.erase(aPos);
322 Resize();
326 void OViewsWindow::toggleGrid(bool _bVisible)
328 ::std::for_each(m_aSections.begin(),m_aSections.end(),
329 ::o3tl::compose1(::boost::bind(&OReportSection::SetGridVisible,_1,_bVisible),TReportPairHelper()));
330 ::std::for_each(m_aSections.begin(),m_aSections.end(),
331 ::o3tl::compose1(::boost::bind(&OReportSection::Window::Invalidate,_1,INVALIDATE_NOERASE),TReportPairHelper()));
334 sal_Int32 OViewsWindow::getTotalHeight() const
336 sal_Int32 nHeight = 0;
337 TSectionsMap::const_iterator aIter = m_aSections.begin();
338 TSectionsMap::const_iterator aEnd = m_aSections.end();
339 for (;aIter != aEnd ; ++aIter)
341 nHeight += (*aIter)->GetSizePixel().Height();
343 return nHeight;
346 sal_uInt16 OViewsWindow::getSectionCount() const
348 return static_cast<sal_uInt16>(m_aSections.size());
351 void OViewsWindow::SetInsertObj( sal_uInt16 eObj,const OUString& _sShapeType )
353 TSectionsMap::iterator aIter = m_aSections.begin();
354 TSectionsMap::iterator aEnd = m_aSections.end();
355 for (;aIter != aEnd ; ++aIter)
356 (*aIter)->getReportSection().getSectionView().SetCurrentObj( eObj, ReportInventor );
358 m_sShapeType = _sShapeType;
363 void OViewsWindow::SetMode( DlgEdMode eNewMode )
365 ::std::for_each(m_aSections.begin(),m_aSections.end(),
366 ::o3tl::compose1(::boost::bind(&OReportSection::SetMode,_1,eNewMode),TReportPairHelper()));
369 bool OViewsWindow::HasSelection() const
371 TSectionsMap::const_iterator aIter = m_aSections.begin();
372 TSectionsMap::const_iterator aEnd = m_aSections.end();
373 for (;aIter != aEnd && !(*aIter)->getReportSection().getSectionView().AreObjectsMarked(); ++aIter)
375 return aIter != aEnd;
378 void OViewsWindow::Delete()
380 m_bInUnmark = true;
381 ::std::for_each(m_aSections.begin(),m_aSections.end(),
382 ::o3tl::compose1(::boost::mem_fn(&OReportSection::Delete),TReportPairHelper()));
383 m_bInUnmark = false;
386 void OViewsWindow::Copy()
388 uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
389 ::std::for_each(m_aSections.begin(),m_aSections.end(),
390 ::o3tl::compose1(::boost::bind(&OReportSection::Copy,_1,::boost::ref(aAllreadyCopiedObjects)),TReportPairHelper()));
392 OReportExchange* pCopy = new OReportExchange(aAllreadyCopiedObjects);
393 uno::Reference< datatransfer::XTransferable> aEnsureDelete = pCopy;
394 pCopy->CopyToClipboard(this);
397 void OViewsWindow::Paste()
399 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(this));
400 OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aTransferData);
401 if ( aCopies.getLength() > 1 )
402 ::std::for_each(m_aSections.begin(),m_aSections.end(),
403 ::o3tl::compose1(::boost::bind(&OReportSection::Paste,_1,aCopies,false),TReportPairHelper()));
404 else
406 OSectionWindow* pMarkedSection = getMarkedSection();
407 if ( pMarkedSection )
408 pMarkedSection->getReportSection().Paste(aCopies,true);
412 OSectionWindow* OViewsWindow::getSectionWindow(const uno::Reference< report::XSection>& _xSection) const
414 OSL_ENSURE(_xSection.is(),"Section is NULL!");
416 OSectionWindow* pSectionWindow = NULL;
417 TSectionsMap::const_iterator aIter = m_aSections.begin();
418 TSectionsMap::const_iterator aEnd = m_aSections.end();
419 for (; aIter != aEnd ; ++aIter)
421 if ((*aIter)->getReportSection().getSection() == _xSection)
423 pSectionWindow = (*aIter);
424 break;
428 return pSectionWindow;
432 OSectionWindow* OViewsWindow::getMarkedSection(NearSectionAccess nsa) const
434 OSectionWindow* pRet = NULL;
435 TSectionsMap::const_iterator aIter = m_aSections.begin();
436 TSectionsMap::const_iterator aEnd = m_aSections.end();
437 sal_uInt32 nCurrentPosition = 0;
438 for (; aIter != aEnd ; ++aIter)
440 if ( (*aIter)->getStartMarker().isMarked() )
442 if (nsa == CURRENT)
444 pRet = (*aIter);
445 break;
447 else if ( nsa == PREVIOUS )
449 if (nCurrentPosition > 0)
451 pRet = (*(--aIter));
452 if (pRet == 0)
454 pRet = (*m_aSections.begin());
457 else
459 // if we are out of bounds return the first one
460 pRet = (*m_aSections.begin());
462 break;
464 else if ( nsa == POST )
466 sal_uInt32 nSize = m_aSections.size();
467 if ((nCurrentPosition + 1) < nSize)
469 pRet = *(++aIter);
470 if (pRet == 0)
472 pRet = (*(--aEnd));
475 else
477 // if we are out of bounds return the last one
478 pRet = (*(--aEnd));
480 break;
483 ++nCurrentPosition;
486 return pRet;
489 void OViewsWindow::markSection(const sal_uInt16 _nPos)
491 if ( _nPos < m_aSections.size() )
492 m_pParent->setMarked(m_aSections[_nPos]->getReportSection().getSection(),true);
495 bool OViewsWindow::IsPasteAllowed() const
497 TransferableDataHelper aTransferData( TransferableDataHelper::CreateFromSystemClipboard( const_cast< OViewsWindow* >( this ) ) );
498 return aTransferData.HasFormat(OReportExchange::getDescriptorFormatId());
501 void OViewsWindow::SelectAll(const sal_uInt16 _nObjectType)
503 m_bInUnmark = true;
504 ::std::for_each(m_aSections.begin(),m_aSections.end(),
505 ::o3tl::compose1(::boost::bind(::boost::mem_fn(&OReportSection::SelectAll),_1,_nObjectType),TReportPairHelper()));
506 m_bInUnmark = false;
509 void OViewsWindow::unmarkAllObjects(OSectionView* _pSectionView)
511 if ( !m_bInUnmark )
513 m_bInUnmark = true;
514 TSectionsMap::iterator aIter = m_aSections.begin();
515 TSectionsMap::iterator aEnd = m_aSections.end();
516 for (; aIter != aEnd ; ++aIter)
518 if ( &(*aIter)->getReportSection().getSectionView() != _pSectionView )
520 (*aIter)->getReportSection().deactivateOle();
521 (*aIter)->getReportSection().getSectionView().UnmarkAllObj();
524 m_bInUnmark = false;
528 void OViewsWindow::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32)
530 ImplInitSettings();
531 Invalidate();
534 void OViewsWindow::MouseButtonDown( const MouseEvent& rMEvt )
536 if ( rMEvt.IsLeft() )
538 GrabFocus();
539 const uno::Sequence< beans::PropertyValue> aArgs;
540 getView()->getReportView()->getController().executeChecked(SID_SELECT_REPORT,aArgs);
542 Window::MouseButtonDown(rMEvt);
545 void OViewsWindow::showRuler(bool _bShow)
547 ::std::for_each(m_aSections.begin(),m_aSections.end(),
548 ::o3tl::compose1(::boost::bind(&OStartMarker::showRuler,_1,_bShow),TStartMarkerHelper()));
549 ::std::for_each(m_aSections.begin(),m_aSections.end(),
550 ::o3tl::compose1(::boost::bind(&OStartMarker::Window::Invalidate, _1, sal_uInt16(INVALIDATE_NOERASE)), TStartMarkerHelper()));
553 void OViewsWindow::MouseButtonUp( const MouseEvent& rMEvt )
555 if ( rMEvt.IsLeft() )
557 TSectionsMap::iterator aIter = m_aSections.begin();
558 TSectionsMap::iterator aEnd = m_aSections.end();
559 for (;aIter != aEnd ; ++aIter)
561 if ( (*aIter)->getReportSection().getSectionView().AreObjectsMarked() )
563 (*aIter)->getReportSection().MouseButtonUp(rMEvt);
564 break;
568 // remove special insert mode
569 for (aIter = m_aSections.begin();aIter != aEnd ; ++aIter)
571 (*aIter)->getReportSection().getPage()->resetSpecialMode();
576 bool OViewsWindow::handleKeyEvent(const KeyEvent& _rEvent)
578 bool bRet = false;
579 TSectionsMap::iterator aIter = m_aSections.begin();
580 TSectionsMap::iterator aEnd = m_aSections.end();
581 for (;aIter != aEnd ; ++aIter)
583 if ( (*aIter)->getStartMarker().isMarked() )
585 bRet = (*aIter)->getReportSection().handleKeyEvent(_rEvent);
588 return bRet;
591 OViewsWindow::TSectionsMap::iterator OViewsWindow::getIteratorAtPos(sal_uInt16 _nPos)
593 TSectionsMap::iterator aRet = m_aSections.end();
594 if ( _nPos < m_aSections.size() )
595 aRet = m_aSections.begin() + _nPos;
596 return aRet;
599 void OViewsWindow::setMarked(OSectionView* _pSectionView, bool _bMark)
601 OSL_ENSURE(_pSectionView != NULL,"SectionView is NULL!");
602 if ( _pSectionView )
603 setMarked(_pSectionView->getReportSection()->getSection(),_bMark);
606 void OViewsWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark)
608 TSectionsMap::iterator aIter = m_aSections.begin();
609 TSectionsMap::iterator aEnd = m_aSections.end();
610 for (; aIter != aEnd ; ++aIter)
612 if ( (*aIter)->getReportSection().getSection() != _xSection )
614 (*aIter)->setMarked(false);
616 else if ( (*aIter)->getStartMarker().isMarked() != _bMark )
618 (*aIter)->setMarked(_bMark);
623 void OViewsWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes, bool _bMark)
625 bool bFirst = true;
626 const uno::Reference< report::XReportComponent>* pIter = _aShapes.getConstArray();
627 const uno::Reference< report::XReportComponent>* pEnd = pIter + _aShapes.getLength();
628 for(;pIter != pEnd;++pIter)
630 const uno::Reference< report::XSection> xSection = (*pIter)->getSection();
631 if ( xSection.is() )
633 if ( bFirst )
635 bFirst = false;
636 m_pParent->setMarked(xSection,_bMark);
638 OSectionWindow* pSectionWindow = getSectionWindow(xSection);
639 if ( pSectionWindow )
641 SvxShape* pShape = SvxShape::getImplementation( *pIter );
642 SdrObject* pObject = pShape ? pShape->GetSdrObject() : NULL;
643 OSL_ENSURE( pObject, "OViewsWindow::setMarked: no SdrObject for the shape!" );
644 if ( pObject )
645 pSectionWindow->getReportSection().getSectionView().MarkObj( pObject, pSectionWindow->getReportSection().getSectionView().GetSdrPageView(), !_bMark );
651 void OViewsWindow::collectRectangles(TRectangleMap& _rSortRectangles, bool _bBoundRects)
653 TSectionsMap::iterator aIter = m_aSections.begin();
654 TSectionsMap::iterator aEnd = m_aSections.end();
655 for (aIter = m_aSections.begin();aIter != aEnd ; ++aIter)
657 OSectionView& rView = (*aIter)->getReportSection().getSectionView();
658 if ( rView.AreObjectsMarked() )
660 rView.SortMarkedObjects();
661 const size_t nCount = rView.GetMarkedObjectCount();
662 for (size_t i=0; i < nCount; ++i)
664 const SdrMark* pM = rView.GetSdrMarkByIndex(i);
665 SdrObject* pObj = pM->GetMarkedSdrObj();
666 Rectangle aObjRect(_bBoundRects ? pObj->GetCurrentBoundRect() : pObj->GetSnapRect());
667 _rSortRectangles.insert(TRectangleMap::value_type(aObjRect,TRectangleMap::mapped_type(pObj,&rView)));
673 void OViewsWindow::collectBoundResizeRect(const TRectangleMap& _rSortRectangles,sal_Int32 _nControlModification,bool _bAlignAtSection, bool _bBoundRects,Rectangle& _rBound,Rectangle& _rResize)
675 bool bOnlyOnce = false;
676 TRectangleMap::const_iterator aRectIter = _rSortRectangles.begin();
677 TRectangleMap::const_iterator aRectEnd = _rSortRectangles.end();
678 for (;aRectIter != aRectEnd ; ++aRectIter)
680 Rectangle aObjRect = aRectIter->first;
681 if ( _rResize.IsEmpty() )
682 _rResize = aObjRect;
683 switch(_nControlModification)
685 case ControlModification::WIDTH_SMALLEST:
686 if ( _rResize.getWidth() > aObjRect.getWidth() )
687 _rResize = aObjRect;
688 break;
689 case ControlModification::HEIGHT_SMALLEST:
690 if ( _rResize.getHeight() > aObjRect.getHeight() )
691 _rResize = aObjRect;
692 break;
693 case ControlModification::WIDTH_GREATEST:
694 if ( _rResize.getWidth() < aObjRect.getWidth() )
695 _rResize = aObjRect;
696 break;
697 case ControlModification::HEIGHT_GREATEST:
698 if ( _rResize.getHeight() < aObjRect.getHeight() )
699 _rResize = aObjRect;
700 break;
703 SdrObjTransformInfoRec aInfo;
704 const SdrObject* pObj = aRectIter->second.first;
705 pObj->TakeObjInfo(aInfo);
706 bool bHasFixed = !aInfo.bMoveAllowed || pObj->IsMoveProtect();
707 if ( bHasFixed )
708 _rBound.Union(aObjRect);
709 else
711 if ( _bAlignAtSection || _rSortRectangles.size() == 1 )
712 { // einzelnes Obj an der Seite ausrichten
713 if ( ! bOnlyOnce )
715 bOnlyOnce = true;
716 OReportSection* pReportSection = aRectIter->second.second->getReportSection();
717 const uno::Reference< report::XSection> xSection = pReportSection->getSection();
720 uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
721 _rBound.Union(Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
722 getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
723 xSection->getHeight()));
725 catch(const uno::Exception &){}
728 else
730 if (_bBoundRects)
731 _rBound.Union(aRectIter->second.second->GetMarkedObjBoundRect());
732 else
733 _rBound.Union(aRectIter->second.second->GetMarkedObjRect());
739 void OViewsWindow::alignMarkedObjects(sal_Int32 _nControlModification,bool _bAlignAtSection, bool _bBoundRects)
741 if ( _nControlModification == ControlModification::NONE )
742 return;
744 Point aRefPoint;
745 RectangleLess::CompareMode eCompareMode = RectangleLess::POS_LEFT;
746 switch (_nControlModification)
748 case ControlModification::TOP : eCompareMode = RectangleLess::POS_UPPER; break;
749 case ControlModification::BOTTOM: eCompareMode = RectangleLess::POS_DOWN; break;
750 case ControlModification::LEFT : eCompareMode = RectangleLess::POS_LEFT; break;
751 case ControlModification::RIGHT : eCompareMode = RectangleLess::POS_RIGHT; break;
752 case ControlModification::CENTER_HORIZONTAL :
753 case ControlModification::CENTER_VERTICAL :
755 eCompareMode = (ControlModification::CENTER_VERTICAL == _nControlModification) ? RectangleLess::POS_CENTER_VERTICAL : RectangleLess::POS_CENTER_HORIZONTAL;
756 uno::Reference<report::XSection> xSection = (*m_aSections.begin())->getReportSection().getSection();
757 uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
758 aRefPoint = Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
759 getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
760 xSection->getHeight()).Center();
762 break;
763 default: break;
765 RectangleLess aCompare(eCompareMode,aRefPoint);
766 TRectangleMap aSortRectangles(aCompare);
767 collectRectangles(aSortRectangles,_bBoundRects);
769 Rectangle aBound;
770 Rectangle aResize;
771 collectBoundResizeRect(aSortRectangles,_nControlModification,_bAlignAtSection,_bBoundRects,aBound,aResize);
773 bool bMove = true;
775 ::std::mem_fun_t<long&,Rectangle> aGetFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Bottom);
776 ::std::mem_fun_t<long&,Rectangle> aRefFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Top);
777 TRectangleMap::iterator aRectIter = aSortRectangles.begin();
778 TRectangleMap::iterator aRectEnd = aSortRectangles.end();
779 for (;aRectIter != aRectEnd ; ++aRectIter)
781 Rectangle aObjRect = aRectIter->first;
782 SdrObject* pObj = aRectIter->second.first;
783 SdrView* pView = aRectIter->second.second;
784 Point aCenter(aBound.Center());
785 SdrObjTransformInfoRec aInfo;
786 pObj->TakeObjInfo(aInfo);
787 if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
789 long nXMov = 0;
790 long nYMov = 0;
791 long* pValue = &nXMov;
792 switch(_nControlModification)
794 case ControlModification::TOP :
795 aGetFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Top);
796 aRefFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Bottom);
797 pValue = &nYMov;
798 break;
799 case ControlModification::BOTTOM:
800 // defaults are already set
801 pValue = &nYMov;
802 break;
803 case ControlModification::CENTER_VERTICAL:
804 nYMov = aCenter.Y() - aObjRect.Center().Y();
805 pValue = &nYMov;
806 bMove = false;
807 break;
808 case ControlModification::RIGHT :
809 aGetFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Right);
810 aRefFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Left);
811 break;
812 case ControlModification::CENTER_HORIZONTAL:
813 nXMov = aCenter.X() - aObjRect.Center().X();
814 bMove = false;
815 break;
816 case ControlModification::LEFT :
817 aGetFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Left);
818 aRefFun = ::std::mem_fun<long&,Rectangle>(&Rectangle::Right);
819 break;
820 default:
821 bMove = false;
822 break;
824 if ( bMove )
826 Rectangle aTest = aObjRect;
827 aGetFun(&aTest) = aGetFun(&aBound);
828 TRectangleMap::iterator aInterSectRectIter = aSortRectangles.begin();
829 for (; aInterSectRectIter != aRectIter; ++aInterSectRectIter)
831 if ( pView == aInterSectRectIter->second.second && (dynamic_cast<OUnoObject*>(aInterSectRectIter->second.first) || dynamic_cast<OOle2Obj*>(aInterSectRectIter->second.first)))
833 SdrObject* pPreviousObj = aInterSectRectIter->second.first;
834 Rectangle aIntersectRect = aTest.GetIntersection(_bBoundRects ? pPreviousObj->GetCurrentBoundRect() : pPreviousObj->GetSnapRect());
835 if ( !aIntersectRect.IsEmpty() && (aIntersectRect.Left() != aIntersectRect.Right() && aIntersectRect.Top() != aIntersectRect.Bottom() ) )
837 *pValue = aRefFun(&aIntersectRect) - aGetFun(&aObjRect);
838 break;
842 if ( aInterSectRectIter == aRectIter )
843 *pValue = aGetFun(&aBound) - aGetFun(&aObjRect);
846 if ( lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification,_bBoundRects) )
848 const Size aSize(nXMov,nYMov);
849 pView->AddUndo(pView->GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,aSize));
850 pObj->Move(aSize);
851 aObjRect = (_bBoundRects ? pObj->GetCurrentBoundRect() : pObj->GetSnapRect());
854 // resizing control
855 if ( !aResize.IsEmpty() && aObjRect != aResize )
857 nXMov = aResize.getWidth();
858 nYMov = aResize.getHeight();
859 switch(_nControlModification)
861 case ControlModification::WIDTH_GREATEST:
862 case ControlModification::HEIGHT_GREATEST:
863 if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
864 nXMov = aObjRect.getWidth();
865 else if ( _nControlModification == ControlModification::WIDTH_GREATEST )
866 nYMov = aObjRect.getHeight();
867 lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification,_bBoundRects);
868 // run through
869 case ControlModification::WIDTH_SMALLEST:
870 case ControlModification::HEIGHT_SMALLEST:
871 pView->AddUndo( pView->GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
873 OObjectBase* pObjBase = dynamic_cast<OObjectBase*>(pObj);
874 OSL_ENSURE(pObjBase,"Where comes this object from?");
875 if ( pObjBase )
877 if ( _nControlModification == ControlModification::WIDTH_SMALLEST || _nControlModification == ControlModification::WIDTH_GREATEST )
878 pObjBase->getReportComponent()->setSize(awt::Size(nXMov,aObjRect.getHeight()));
879 else if ( _nControlModification == ControlModification::HEIGHT_GREATEST || _nControlModification == ControlModification::HEIGHT_SMALLEST )
880 pObjBase->getReportComponent()->setSize(awt::Size(aObjRect.getWidth(),nYMov));
883 break;
884 default:
885 break;
889 pView->AdjustMarkHdl();
893 void OViewsWindow::createDefault()
895 OSectionWindow* pMarkedSection = getMarkedSection();
896 if ( pMarkedSection )
897 pMarkedSection->getReportSection().createDefault(m_sShapeType);
900 void OViewsWindow::setGridSnap(bool bOn)
902 TSectionsMap::iterator aIter = m_aSections.begin();
903 TSectionsMap::iterator aEnd = m_aSections.end();
904 for (; aIter != aEnd ; ++aIter)
906 (*aIter)->getReportSection().getSectionView().SetGridSnap(bOn);
907 static sal_Int32 nIn = 0;
908 (*aIter)->getReportSection().Invalidate(nIn);
912 void OViewsWindow::setDragStripes(bool bOn)
914 TSectionsMap::iterator aIter = m_aSections.begin();
915 TSectionsMap::iterator aEnd = m_aSections.end();
916 for (; aIter != aEnd ; ++aIter)
917 (*aIter)->getReportSection().getSectionView().SetDragStripes(bOn);
920 sal_uInt16 OViewsWindow::getPosition(const OSectionWindow* _pSectionWindow) const
922 TSectionsMap::const_iterator aIter = m_aSections.begin();
923 TSectionsMap::const_iterator aEnd = m_aSections.end();
924 sal_uInt16 nPosition = 0;
925 for (; aIter != aEnd ; ++aIter)
927 if ( _pSectionWindow == (*aIter).get() )
929 break;
931 ++nPosition;
933 return nPosition;
936 OSectionWindow* OViewsWindow::getSectionWindow(const sal_uInt16 _nPos) const
938 OSectionWindow* aReturn = NULL;
940 if ( _nPos < m_aSections.size() )
941 aReturn = m_aSections[_nPos];
943 return aReturn;
946 namespace
948 enum SectionViewAction
950 eEndDragObj,
951 eEndAction,
952 eForceToAnotherPage,
953 eBreakAction
955 class ApplySectionViewAction : public ::std::unary_function< OViewsWindow::TSectionsMap::value_type, void >
957 private:
958 SectionViewAction m_eAction;
959 bool m_bCopy;
961 public:
962 ApplySectionViewAction(bool _bCopy)
963 : m_eAction(eEndDragObj)
964 , m_bCopy(_bCopy)
968 ApplySectionViewAction(SectionViewAction _eAction = eEndAction)
969 : m_eAction(_eAction)
970 , m_bCopy(false)
974 void operator() ( const OViewsWindow::TSectionsMap::value_type& _rhs )
976 OSectionView& rView( _rhs->getReportSection().getSectionView() );
977 switch ( m_eAction )
979 case eEndDragObj:
980 rView.EndDragObj( m_bCopy );
981 break;
982 case eEndAction:
983 if ( rView.IsAction() )
984 rView.EndAction ( );
985 break;
986 case eForceToAnotherPage:
987 rView.ForceMarkedToAnotherPage();
988 break;
989 case eBreakAction:
990 if ( rView.IsAction() )
991 rView.BrkAction ( );
992 break;
993 // default:
1000 void OViewsWindow::BrkAction()
1002 EndDragObj_removeInvisibleObjects();
1003 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eBreakAction) );
1006 void OViewsWindow::BegDragObj_createInvisibleObjectAtPosition(const Rectangle& _aRect, const OSectionView& _rSection)
1008 TSectionsMap::iterator aIter = m_aSections.begin();
1009 TSectionsMap::iterator aEnd = m_aSections.end();
1010 Point aNewPos(0,0);
1012 for (; aIter != aEnd; ++aIter)
1014 OReportSection& rReportSection = (*aIter)->getReportSection();
1015 rReportSection.getPage()->setSpecialMode();
1016 OSectionView& rView = rReportSection.getSectionView();
1018 if ( &rView != &_rSection )
1020 SdrObject *pNewObj = new SdrUnoObj(OUString("com.sun.star.form.component.FixedText"));
1021 pNewObj->SetLogicRect(_aRect);
1023 pNewObj->Move(Size(0, aNewPos.Y()));
1024 bool bChanged = rView.GetModel()->IsChanged();
1025 rReportSection.getPage()->InsertObject(pNewObj);
1026 rView.GetModel()->SetChanged(bChanged);
1027 m_aBegDragTempList.push_back(pNewObj);
1029 rView.MarkObj( pNewObj, rView.GetSdrPageView() );
1031 const long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1032 aNewPos.Y() -= nSectionHeight;
1036 bool OViewsWindow::isObjectInMyTempList(SdrObject *_pObj)
1038 return ::std::find(m_aBegDragTempList.begin(),m_aBegDragTempList.end(),_pObj) != m_aBegDragTempList.end();
1042 void OViewsWindow::BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection)
1044 SAL_INFO(
1045 "reportdesign", "Clickpoint X:" << _aPnt.X() << " Y:" << _aPnt.Y());
1047 m_aBegDragTempList.clear();
1049 // Calculate the absolute clickpoint in the views
1050 Point aAbsolutePnt = _aPnt;
1051 TSectionsMap::iterator aIter = m_aSections.begin();
1052 TSectionsMap::iterator aEnd = m_aSections.end();
1053 for (; aIter != aEnd; ++aIter)
1055 OReportSection& rReportSection = (*aIter)->getReportSection();
1056 OSectionView* pView = &rReportSection.getSectionView();
1057 if (pView == _pSection)
1058 break;
1059 const long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1060 aAbsolutePnt.Y() += nSectionHeight;
1062 m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
1063 SAL_INFO(
1064 "reportdesign",
1065 "Absolute X:" << aAbsolutePnt.X() << " Y:" << aAbsolutePnt.Y());
1067 // Create drag lines over all viewable Views
1068 // Therefore we need to identify the marked objects
1069 // and create temporary objects on all other views at the same position
1070 // relative to its occurrence.
1072 OSL_TRACE("BegDragObj createInvisible Objects" );
1073 int nViewCount = 0;
1074 Point aNewObjPos(0,0);
1075 Point aLeftTop = Point(SAL_MAX_INT32, SAL_MAX_INT32);
1076 for (aIter = m_aSections.begin(); aIter != aEnd; ++aIter)
1078 OReportSection& rReportSection = (*aIter)->getReportSection();
1080 OSectionView& rView = rReportSection.getSectionView();
1082 if ( rView.AreObjectsMarked() )
1084 const size_t nCount = rView.GetMarkedObjectCount();
1085 for (size_t i=0; i < nCount; ++i)
1087 const SdrMark* pM = rView.GetSdrMarkByIndex(i);
1088 SdrObject* pObj = pM->GetMarkedSdrObj();
1089 if (!isObjectInMyTempList(pObj))
1091 Rectangle aRect( pObj->GetCurrentBoundRect() );
1092 aRect.Move(0, aNewObjPos.Y());
1094 aLeftTop.X() = ::std::min( aRect.Left(), aLeftTop.X() );
1095 aLeftTop.Y() = ::std::min( aRect.Top(), aLeftTop.Y() );
1097 SAL_INFO(
1098 "reportdesign",
1099 "createInvisible X:" << aRect.Left() << " Y:"
1100 << aRect.Top() << " on View #" << nViewCount);
1102 BegDragObj_createInvisibleObjectAtPosition(aRect, rView);
1106 ++nViewCount;
1107 Rectangle aClipRect = rView.GetWorkArea();
1108 aClipRect.Top() = -aNewObjPos.Y();
1109 rView.SetWorkArea( aClipRect );
1111 const long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1112 aNewObjPos.Y() += nSectionHeight;
1115 const sal_Int32 nDeltaX = std::abs(aLeftTop.X() - aAbsolutePnt.X());
1116 const sal_Int32 nDeltaY = std::abs(aLeftTop.Y() - aAbsolutePnt.Y());
1117 m_aDragDelta.X() = nDeltaX;
1118 m_aDragDelta.Y() = nDeltaY;
1120 Point aNewPos = aAbsolutePnt;
1122 const short nDrgLog = static_cast<short>(PixelToLogic(Size(3,0)).Width());
1123 nViewCount = 0;
1124 for (aIter = m_aSections.begin(); aIter != aEnd; ++aIter)
1126 OReportSection& rReportSection = (*aIter)->getReportSection();
1128 SdrHdl* pHdl = _pHdl;
1129 if ( pHdl )
1131 if ( &rReportSection.getSectionView() != _pSection )
1133 const SdrHdlList& rHdlList = rReportSection.getSectionView().GetHdlList();
1134 pHdl = rHdlList.GetHdl(_pHdl->GetKind());
1137 SAL_INFO(
1138 "reportdesign",
1139 "X:" << aNewPos.X() << " Y:" << aNewPos.Y() << " on View#"
1140 << nViewCount++);
1141 rReportSection.getSectionView().BegDragObj(aNewPos, (OutputDevice*)NULL, pHdl, nDrgLog, NULL);
1143 const long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1144 aNewPos.Y() -= nSectionHeight;
1149 void OViewsWindow::ForceMarkedToAnotherPage()
1151 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eForceToAnotherPage ) );
1154 void OViewsWindow::BegMarkObj(const Point& _aPnt,const OSectionView* _pSection)
1156 bool bAdd = true;
1157 Point aNewPos = _aPnt;
1159 TSectionsMap::iterator aIter = m_aSections.begin();
1160 TSectionsMap::iterator aEnd = m_aSections.end();
1161 long nLastSectionHeight = 0;
1162 for (; aIter != aEnd; ++aIter)
1164 OReportSection& rReportSection = (*aIter)->getReportSection();
1165 if ( &rReportSection.getSectionView() == _pSection )
1167 bAdd = false;
1168 aNewPos = _aPnt; // 2,2
1170 else if ( bAdd )
1172 const long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1173 aNewPos.Y() += nSectionHeight;
1175 else
1177 aNewPos.Y() -= nLastSectionHeight;
1179 rReportSection.getSectionView().BegMarkObj ( aNewPos );
1180 nLastSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1184 OSectionView* OViewsWindow::getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt)
1186 OSectionView* pSection = NULL;
1187 sal_Int32 nCount = 0;
1188 TSectionsMap::iterator aIter = m_aSections.begin();
1189 const TSectionsMap::iterator aEnd = m_aSections.end();
1190 for (; aIter != aEnd ; ++aIter,++nCount)
1192 OReportSection& rReportSection = (*aIter)->getReportSection();
1193 if ( &rReportSection.getSectionView() == _pSection)
1194 break;
1196 OSL_ENSURE(aIter != aEnd,"This can never happen!");
1197 if ( _rPnt.Y() < 0 )
1199 if ( nCount )
1200 --aIter;
1201 for (; nCount && (_rPnt.Y() < 0); --nCount)
1203 OReportSection& rReportSection = (*aIter)->getReportSection();
1204 const sal_Int32 nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1205 _rPnt.Y() += nHeight;
1206 if ( (nCount -1) > 0 && (_rPnt.Y() < 0) )
1207 --aIter;
1209 if ( nCount == 0 )
1210 pSection = &(*m_aSections.begin())->getReportSection().getSectionView();
1211 else
1212 pSection = &(*aIter)->getReportSection().getSectionView();
1214 else
1216 for (; aIter != aEnd; ++aIter)
1218 OReportSection& rReportSection = (*aIter)->getReportSection();
1219 const long nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1220 if ( (_rPnt.Y() - nHeight) < 0 )
1221 break;
1222 _rPnt.Y() -= nHeight;
1224 if ( aIter != aEnd )
1225 pSection = &(*aIter)->getReportSection().getSectionView();
1226 else
1227 pSection = &(*(aEnd-1))->getReportSection().getSectionView();
1230 return pSection;
1233 void OViewsWindow::EndDragObj_removeInvisibleObjects()
1235 TSectionsMap::iterator aIter = m_aSections.begin();
1236 TSectionsMap::iterator aEnd = m_aSections.end();
1238 for (; aIter != aEnd; ++aIter)
1240 OReportSection& rReportSection = (*aIter)->getReportSection();
1241 rReportSection.getPage()->resetSpecialMode();
1245 void OViewsWindow::EndDragObj(bool _bControlKeyPressed, const OSectionView* _pSection, const Point& _aPnt)
1247 const OUString sUndoAction = ModuleRes(RID_STR_UNDO_CHANGEPOSITION);
1248 const UndoContext aUndoContext( getView()->getReportView()->getController().getUndoManager(), sUndoAction );
1250 Point aNewPos = _aPnt;
1251 OSectionView* pInSection = getSectionRelativeToPosition(_pSection, aNewPos);
1252 if (!_bControlKeyPressed &&
1253 _pSection && !_pSection->IsDragResize() && /* Not in resize mode */
1254 _pSection != pInSection)
1256 EndDragObj_removeInvisibleObjects();
1258 // we need to manipulate the current clickpoint, we subtract the old delta from BeginDrag
1259 aNewPos -= m_aDragDelta;
1261 uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
1262 TSectionsMap::iterator aIter = m_aSections.begin();
1263 const TSectionsMap::iterator aEnd = m_aSections.end();
1264 for (; aIter != aEnd; ++aIter)
1266 OReportSection& rReportSection = (*aIter)->getReportSection();
1267 if ( pInSection != &rReportSection.getSectionView() )
1269 rReportSection.getSectionView().BrkAction();
1270 rReportSection.Copy(aAllreadyCopiedObjects,true);
1272 else
1273 pInSection->EndDragObj(false);
1276 if ( aAllreadyCopiedObjects.getLength() )
1278 beans::NamedValue* pIter = aAllreadyCopiedObjects.getArray();
1279 const beans::NamedValue* pEnd = pIter + aAllreadyCopiedObjects.getLength();
1282 uno::Reference<report::XReportDefinition> xReportDefinition = getView()->getReportView()->getController().getReportDefinition();
1283 const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
1284 const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
1285 const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width;
1287 if ( aNewPos.X() < nLeftMargin )
1288 aNewPos.X() = nLeftMargin;
1289 if ( aNewPos.Y() < 0 )
1290 aNewPos.Y() = 0;
1292 Point aPrevious;
1293 for (; pIter != pEnd; ++pIter)
1295 uno::Sequence< uno::Reference<report::XReportComponent> > aClones;
1296 pIter->Value >>= aClones;
1297 uno::Reference<report::XReportComponent>* pColIter = aClones.getArray();
1298 const uno::Reference<report::XReportComponent>* pColEnd = pColIter + aClones.getLength();
1300 // move the cloned Components to new positions
1301 for (; pColIter != pColEnd; ++pColIter)
1303 uno::Reference< report::XReportComponent> xRC(*pColIter);
1304 aPrevious = VCLPoint(xRC->getPosition());
1305 awt::Size aSize = xRC->getSize();
1307 if ( aNewPos.X() < nLeftMargin )
1309 aNewPos.X() = nLeftMargin;
1311 else if ( (aNewPos.X() + aSize.Width) > (nPaperWidth - nRightMargin) )
1313 aNewPos.X() = nPaperWidth - nRightMargin - aSize.Width;
1315 if ( aNewPos.Y() < 0 )
1317 aNewPos.Y() = 0;
1319 if ( aNewPos.X() < 0 )
1321 aSize.Width += aNewPos.X();
1322 aNewPos.X()= 0;
1323 xRC->setSize(aSize);
1325 xRC->setPosition(AWTPoint(aNewPos));
1326 if ( (pColIter+1) != pColEnd )
1328 // bring aNewPos to the position of the next object
1329 uno::Reference< report::XReportComponent> xRCNext(*(pColIter + 1),uno::UNO_QUERY);
1330 Point aNextPosition = VCLPoint(xRCNext->getPosition());
1331 aNewPos += (aNextPosition - aPrevious);
1336 catch(uno::Exception&)
1339 pInSection->getReportSection()->Paste(aAllreadyCopiedObjects,true);
1342 else
1344 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction( false ) );
1345 EndDragObj_removeInvisibleObjects();
1347 m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
1350 void OViewsWindow::EndAction()
1352 ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction() );
1355 void OViewsWindow::MovAction(const Point& _aPnt,const OSectionView* _pSection,bool _bMove, bool _bControlKeySet)
1357 (void)_bMove;
1359 Point aRealMousePos = _aPnt;
1360 Point aCurrentSectionPos;
1361 SAL_INFO(
1362 "reportdesign",
1363 "X:" << aRealMousePos.X() << " Y:" << aRealMousePos.Y());
1365 Point aHdlPos;
1366 SdrHdl* pHdl = _pSection->GetDragHdl();
1367 if ( pHdl )
1369 aHdlPos = pHdl->GetPos();
1372 TSectionsMap::iterator aIter;
1373 TSectionsMap::iterator aEnd = m_aSections.end();
1375 for (aIter = m_aSections.begin(); aIter != aEnd; ++aIter)
1377 OReportSection& rReportSection = (*aIter)->getReportSection();
1378 if ( &rReportSection.getSectionView() == _pSection )
1379 break;
1380 const long nSectionHeight = (*aIter)->PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
1381 aCurrentSectionPos.Y() += nSectionHeight;
1383 aRealMousePos += aCurrentSectionPos;
1385 // If control key is pressed the work area is limited to the section with the current selection.
1386 Point aPosForWorkArea(0,0);
1387 for (aIter = m_aSections.begin(); aIter != aEnd; ++aIter)
1389 OReportSection& rReportSection = (*aIter)->getReportSection();
1390 OSectionView& rView = rReportSection.getSectionView();
1391 const long nSectionHeight = (*aIter)->PixelToLogic((*aIter)->GetOutputSizePixel()).Height();
1393 if (_bControlKeySet)
1395 Rectangle aClipRect = rView.GetWorkArea();
1396 aClipRect.Top() = aCurrentSectionPos.Y() - aPosForWorkArea.Y();
1397 aClipRect.Bottom() = aClipRect.Top() + nSectionHeight;
1398 rView.SetWorkArea( aClipRect );
1400 else
1402 Rectangle aClipRect = rView.GetWorkArea();
1403 aClipRect.Top() = -aPosForWorkArea.Y();
1404 rView.SetWorkArea( aClipRect );
1406 aPosForWorkArea.Y() += nSectionHeight;
1410 for (aIter = m_aSections.begin(); aIter != aEnd; ++aIter)
1412 OReportSection& rReportSection = (*aIter)->getReportSection();
1413 SdrHdl* pCurrentHdl = rReportSection.getSectionView().GetDragHdl();
1414 if ( pCurrentHdl )
1416 if ( aRealMousePos.Y() > 0 )
1417 aRealMousePos = _aPnt + pCurrentHdl->GetPos() - aHdlPos;
1419 rReportSection.getSectionView().MovAction ( aRealMousePos );
1420 const long nSectionHeight = (*aIter)->PixelToLogic((*aIter)->GetOutputSizePixel()).Height();
1421 aRealMousePos.Y() -= nSectionHeight;
1425 bool OViewsWindow::IsAction() const
1427 bool bAction = false;
1428 TSectionsMap::const_iterator aIter = m_aSections.begin();
1429 TSectionsMap::const_iterator aEnd = m_aSections.end();
1430 for (; !bAction && aIter != aEnd; ++aIter)
1431 bAction = (*aIter)->getReportSection().getSectionView().IsAction();
1432 return bAction;
1435 bool OViewsWindow::IsDragObj() const
1437 bool bAction = false;
1438 TSectionsMap::const_iterator aIter = m_aSections.begin();
1439 TSectionsMap::const_iterator aEnd = m_aSections.end();
1440 for (; !bAction && aIter != aEnd; ++aIter)
1441 bAction = (*aIter)->getReportSection().getSectionView().IsAction();
1442 return bAction;
1445 sal_uInt32 OViewsWindow::getMarkedObjectCount() const
1447 sal_uInt32 nCount = 0;
1448 TSectionsMap::const_iterator aIter = m_aSections.begin();
1449 TSectionsMap::const_iterator aEnd = m_aSections.end();
1450 for (; aIter != aEnd; ++aIter)
1451 nCount += static_cast<sal_uInt32>((*aIter)->getReportSection().getSectionView().GetMarkedObjectCount());
1452 return nCount;
1455 void OViewsWindow::handleKey(const vcl::KeyCode& _rCode)
1457 const sal_uInt16 nCode = _rCode.GetCode();
1458 if ( _rCode.IsMod1() )
1460 // scroll page
1461 OScrollWindowHelper* pScrollWindow = getView()->getScrollWindow();
1462 ScrollBar& rScrollBar = ( nCode == KEY_LEFT || nCode == KEY_RIGHT ) ? pScrollWindow->GetHScroll() : pScrollWindow->GetVScroll();
1463 if ( rScrollBar.IsVisible() )
1464 rScrollBar.DoScrollAction(( nCode == KEY_RIGHT || nCode == KEY_UP ) ? SCROLL_LINEUP : SCROLL_LINEDOWN );
1465 return;
1467 TSectionsMap::const_iterator aIter = m_aSections.begin();
1468 TSectionsMap::const_iterator aEnd = m_aSections.end();
1469 for (; aIter != aEnd; ++aIter)
1471 OReportSection& rReportSection = (*aIter)->getReportSection();
1472 long nX = 0;
1473 long nY = 0;
1475 if ( nCode == KEY_UP )
1476 nY = -1;
1477 else if ( nCode == KEY_DOWN )
1478 nY = 1;
1479 else if ( nCode == KEY_LEFT )
1480 nX = -1;
1481 else if ( nCode == KEY_RIGHT )
1482 nX = 1;
1484 if ( rReportSection.getSectionView().AreObjectsMarked() )
1486 if ( _rCode.IsMod2() )
1488 // move in 1 pixel distance
1489 const Size aPixelSize = rReportSection.PixelToLogic( Size( 1, 1 ) );
1490 nX *= aPixelSize.Width();
1491 nY *= aPixelSize.Height();
1493 else
1495 // move in 1 mm distance
1496 nX *= DEFAUL_MOVE_SIZE;
1497 nY *= DEFAUL_MOVE_SIZE;
1500 OSectionView& rView = rReportSection.getSectionView();
1501 const SdrHdlList& rHdlList = rView.GetHdlList();
1502 SdrHdl* pHdl = rHdlList.GetFocusHdl();
1504 if ( pHdl == 0 )
1506 // no handle selected
1507 if ( rView.IsMoveAllowed() )
1509 // restrict movement to work area
1510 Rectangle rWorkArea = rView.GetWorkArea();
1511 rWorkArea.Right()++;
1513 if ( !rWorkArea.IsEmpty() )
1515 if ( rWorkArea.Top() < 0 )
1516 rWorkArea.Top() = 0;
1517 Rectangle aMarkRect( rView.GetMarkedObjRect() );
1518 aMarkRect.Move( nX, nY );
1520 if ( !rWorkArea.IsInside( aMarkRect ) )
1522 if ( aMarkRect.Left() < rWorkArea.Left() )
1523 nX += rWorkArea.Left() - aMarkRect.Left();
1525 if ( aMarkRect.Right() > rWorkArea.Right() )
1526 nX -= aMarkRect.Right() - rWorkArea.Right();
1528 if ( aMarkRect.Top() < rWorkArea.Top() )
1529 nY += rWorkArea.Top() - aMarkRect.Top();
1531 if ( aMarkRect.Bottom() > rWorkArea.Bottom() )
1532 nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
1534 bool bCheck = false;
1535 const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
1536 for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
1538 SdrMark* pMark = rMarkList.GetMark(i);
1539 bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != NULL|| dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj());
1543 if ( bCheck )
1545 SdrObject* pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
1546 if ( pOverlapped )
1550 Rectangle aOver = pOverlapped->GetLastBoundRect();
1551 Point aPos;
1552 if ( nCode == KEY_UP )
1554 aPos.X() = aMarkRect.Left();
1555 aPos.Y() = aOver.Top() - aMarkRect.getHeight();
1556 nY += (aPos.Y() - aMarkRect.Top());
1558 else if ( nCode == KEY_DOWN )
1560 aPos.X() = aMarkRect.Left();
1561 aPos.Y() = aOver.Bottom();
1562 nY += (aPos.Y() - aMarkRect.Top());
1564 else if ( nCode == KEY_LEFT )
1566 aPos.X() = aOver.Left() - aMarkRect.getWidth();
1567 aPos.Y() = aMarkRect.Top();
1568 nX += (aPos.X() - aMarkRect.Left());
1570 else if ( nCode == KEY_RIGHT )
1572 aPos.X() = aOver.Right();
1573 aPos.Y() = aMarkRect.Top();
1574 nX += (aPos.X() - aMarkRect.Left());
1577 aMarkRect.SetPos(aPos);
1578 if ( !rWorkArea.IsInside( aMarkRect ) )
1580 break;
1582 pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
1584 while(pOverlapped != NULL);
1585 if (pOverlapped != NULL)
1586 break;
1591 if ( nX != 0 || nY != 0 )
1593 rView.MoveAllMarked( Size( nX, nY ) );
1594 rView.MakeVisible( rView.GetAllMarkedRect(), rReportSection);
1598 else
1600 // move the handle
1601 if ( pHdl && ( nX || nY ) )
1603 const Point aStartPoint( pHdl->GetPos() );
1604 const Point aEndPoint( pHdl->GetPos() + Point( nX, nY ) );
1605 const SdrDragStat& rDragStat = rView.GetDragStat();
1607 // start dragging
1608 rView.BegDragObj( aStartPoint, 0, pHdl, 0 );
1610 if ( rView.IsDragObj() )
1612 const bool bWasNoSnap = rDragStat.IsNoSnap();
1613 const bool bWasSnapEnabled = rView.IsSnapEnabled();
1615 // switch snapping off
1616 if ( !bWasNoSnap )
1617 ((SdrDragStat&)rDragStat).SetNoSnap( true );
1618 if ( bWasSnapEnabled )
1619 rView.SetSnapEnabled( false );
1621 Rectangle aNewRect;
1622 bool bCheck = false;
1623 const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
1624 for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
1626 SdrMark* pMark = rMarkList.GetMark(i);
1627 bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != NULL || dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()) != NULL;
1628 if ( bCheck )
1629 aNewRect.Union(pMark->GetMarkedSdrObj()->GetLastBoundRect());
1632 switch(pHdl->GetKind())
1634 case HDL_LEFT:
1635 case HDL_UPLFT:
1636 case HDL_LWLFT:
1637 case HDL_UPPER:
1638 aNewRect.Left() += nX;
1639 aNewRect.Top() += nY;
1640 break;
1641 case HDL_UPRGT:
1642 case HDL_RIGHT:
1643 case HDL_LWRGT:
1644 case HDL_LOWER:
1645 aNewRect.setWidth(aNewRect.getWidth() + nX);
1646 aNewRect.setHeight(aNewRect.getHeight() + nY);
1647 break;
1648 default:
1649 break;
1651 if ( !(bCheck && isOver(aNewRect,*rReportSection.getPage(),rView)) )
1652 rView.MovAction(aEndPoint);
1653 rView.EndDragObj();
1655 // restore snap
1656 if ( !bWasNoSnap )
1657 ((SdrDragStat&)rDragStat).SetNoSnap( bWasNoSnap );
1658 if ( bWasSnapEnabled )
1659 rView.SetSnapEnabled( bWasSnapEnabled );
1662 // make moved handle visible
1663 const Rectangle aVisRect( aEndPoint - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) );
1664 rView.MakeVisible( aVisRect, rReportSection);
1667 rView.AdjustMarkHdl();
1672 void OViewsWindow::stopScrollTimer()
1674 ::std::for_each(m_aSections.begin(),m_aSections.end(),
1675 ::o3tl::compose1(::boost::mem_fn(&OReportSection::stopScrollTimer),TReportPairHelper()));
1678 void OViewsWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
1680 TSectionsMap::const_iterator aIter = m_aSections.begin();
1681 TSectionsMap::const_iterator aEnd = m_aSections.end();
1682 for (sal_uInt16 i = 0;aIter != aEnd ; ++aIter,++i)
1684 if ( (*aIter)->getStartMarker().isCollapsed() )
1685 _rCollapsedPositions.push_back(i);
1689 void OViewsWindow::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollpasedSections)
1691 const beans::PropertyValue* pIter = _aCollpasedSections.getConstArray();
1692 const beans::PropertyValue* pEnd = pIter + _aCollpasedSections.getLength();
1693 for (; pIter != pEnd; ++pIter)
1695 sal_uInt16 nPos = sal_uInt16(-1);
1696 if ( (pIter->Value >>= nPos) && nPos < m_aSections.size() )
1698 m_aSections[nPos]->setCollapsed(true);
1703 void OViewsWindow::zoom(const Fraction& _aZoom)
1705 const MapMode& aMapMode = GetMapMode();
1707 Fraction aStartWidth(long(REPORT_STARTMARKER_WIDTH));
1708 if ( _aZoom < aMapMode.GetScaleX() )
1709 aStartWidth *= aMapMode.GetScaleX();
1710 else
1711 aStartWidth *= _aZoom;
1713 setZoomFactor(_aZoom,*this);
1715 TSectionsMap::iterator aIter = m_aSections.begin();
1716 TSectionsMap::iterator aEnd = m_aSections.end();
1717 for (;aIter != aEnd ; ++aIter)
1719 (*aIter)->zoom(_aZoom);
1722 Resize();
1724 Size aOut = GetOutputSizePixel();
1725 aOut.Width() = aStartWidth;
1726 aOut = PixelToLogic(aOut);
1728 Rectangle aRect(PixelToLogic(Point(0,0)),aOut);
1729 static sal_Int32 nIn = INVALIDATE_NOCHILDREN;
1730 Invalidate(aRect,nIn);
1733 void OViewsWindow::scrollChildren(const Point& _aThumbPos)
1735 const Point aPos(PixelToLogic(_aThumbPos));
1737 MapMode aMapMode = GetMapMode();
1738 const Point aOld = aMapMode.GetOrigin();
1739 aMapMode.SetOrigin(m_pParent->GetMapMode().GetOrigin());
1741 const Point aPosY(m_pParent->PixelToLogic(_aThumbPos,aMapMode));
1743 aMapMode.SetOrigin( Point(aOld.X() , - aPosY.Y()));
1744 SetMapMode( aMapMode );
1745 Scroll(0, -( aOld.Y() + aPosY.Y()),SCROLL_CHILDREN);
1748 TSectionsMap::iterator aIter = m_aSections.begin();
1749 TSectionsMap::iterator aEnd = m_aSections.end();
1750 for (;aIter != aEnd ; ++aIter)
1752 (*aIter)->scrollChildren(aPos.X());
1756 void OViewsWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
1758 TSectionsMap::const_iterator aIter = m_aSections.begin();
1759 TSectionsMap::const_iterator aEnd = m_aSections.end();
1760 for(;aIter != aEnd; ++aIter)
1762 (*aIter)->getReportSection().fillControlModelSelection(_rSelection);
1766 } // rptui
1769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */