/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace rptui { using namespace ::com::sun::star; static Color lcl_getOverlappedControlColor(/*const uno::Reference _rxFactory*/) { svtools::ExtendedColorConfig aConfig; return aConfig.GetColorValue(CFG_REPORTDESIGNER, DBOVERLAPPEDCONTROL).getColor(); } OReportSection::OReportSection(OSectionWindow* _pParent,uno::Reference< report::XSection > _xSection) : Window(_pParent,WB_DIALOGCONTROL) , ::comphelper::OPropertyChangeListener(m_aMutex) , DropTargetHelper(this) , m_pPage(nullptr) , m_pView(nullptr) , m_pParent(_pParent) , m_xSection(std::move(_xSection)) , m_nPaintEntranceCount(0) , m_eMode(DlgEdMode::Select) { //EnableChildTransparentMode(); SetHelpId(HID_REPORTSECTION); SetMapMode(MapMode(MapUnit::Map100thMM)); SetParentClipMode(ParentClipMode::Clip); EnableChildTransparentMode( false ); SetPaintTransparent( false ); try { fill(); } catch(uno::Exception&) { TOOLS_WARN_EXCEPTION( "reportdesign", ""); } m_pFunc.reset(new DlgEdFuncSelect( this )); m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor() ); } OReportSection::~OReportSection() { disposeOnce(); } void OReportSection::dispose() { m_pPage = nullptr; if ( m_pMulti.is() ) m_pMulti->dispose(); m_pMulti.clear(); if ( m_pReportListener.is() ) m_pReportListener->dispose(); m_pReportListener.clear(); m_pFunc.reset(); { if ( m_pView ) m_pView->EndListening( *m_pModel ); delete m_pView; m_pView = nullptr; } m_pParent.clear(); vcl::Window::dispose(); } void OReportSection::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) { Window::Paint(rRenderContext, rRect); if ( !(m_pView && m_nPaintEntranceCount == 0)) return; ++m_nPaintEntranceCount; // repaint, get PageView and prepare Region SdrPageView* pPgView = m_pView->GetSdrPageView(); const vcl::Region aPaintRectRegion(rRect); // #i74769# SdrPaintWindow* pTargetPaintWindow = nullptr; // mark repaint start if (pPgView) { pTargetPaintWindow = pPgView->GetView().BeginDrawLayers(GetOutDev(), aPaintRectRegion); OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)"); // draw background self using wallpaper OutputDevice& rTargetOutDev = pTargetPaintWindow->GetTargetOutputDevice(); rTargetOutDev.DrawWallpaper(rRect, Wallpaper(pPgView->GetApplicationDocumentColor())); // do paint (unbuffered) and mark repaint end pPgView->DrawLayer(RPT_LAYER_FRONT, &rRenderContext); pPgView->GetView().EndDrawLayers(*pTargetPaintWindow, true); } m_pView->CompleteRedraw(&rRenderContext, aPaintRectRegion); --m_nPaintEntranceCount; } void OReportSection::fill() { if ( !m_xSection.is() ) return; m_pMulti = new comphelper::OPropertyChangeMultiplexer(this,m_xSection); m_pMulti->addProperty(PROPERTY_BACKCOLOR); m_pReportListener = addStyleListener(m_xSection->getReportDefinition(),this); m_pModel = m_pParent->getViewsWindow()->getView()->getReportView()->getController().getSdrModel(); m_pPage = m_pModel->getPage(m_xSection); m_pView = new OSectionView( *m_pModel, this, m_pParent->getViewsWindow()->getView()); // #i93597# tell SdrPage that only left and right page border is defined // instead of the full rectangle definition m_pPage->setPageBorderOnlyLeftRight(true); // without the following call, no grid is painted m_pView->ShowSdrPage( m_pPage ); m_pView->SetMoveSnapOnlyTopLeft( true ); ODesignView* pDesignView = m_pParent->getViewsWindow()->getView()->getReportView(); // #i93595# Adapted grid to a more coarse grid and subdivisions for better visualisation. This // is only for visualisation and has nothing to do with the actual snap const Size aGridSizeCoarse(pDesignView->getGridSizeCoarse()); const Size aGridSizeFine(pDesignView->getGridSizeFine()); m_pView->SetGridCoarse(aGridSizeCoarse); m_pView->SetGridFine(aGridSizeFine); // #i93595# set snap grid width to snap to all existing subdivisions const Fraction aX(aGridSizeFine.Width()); const Fraction aY(aGridSizeFine.Height()); m_pView->SetSnapGridWidth(aX, aY); m_pView->SetGridSnap( true ); m_pView->SetGridFront( false ); m_pView->SetDragStripes( true ); m_pView->SetPageVisible(); sal_Int32 nColor = m_xSection->getBackColor(); if ( nColor == static_cast(COL_TRANSPARENT) ) nColor = getStyleProperty(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR); m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor)); uno::Reference xReportDefinition = m_xSection->getReportDefinition(); const sal_Int32 nLeftMargin = getStyleProperty(xReportDefinition,PROPERTY_LEFTMARGIN); const sal_Int32 nRightMargin = getStyleProperty(xReportDefinition,PROPERTY_RIGHTMARGIN); m_pPage->SetLeftBorder(nLeftMargin); m_pPage->SetRightBorder(nRightMargin); // LLA: TODO // m_pPage->SetUpperBorder(-10000); m_pView->SetDesignMode(); m_pPage->SetSize( Size( getStyleProperty(xReportDefinition,PROPERTY_PAPERSIZE).Width,5*m_xSection->getHeight()) ); const Size aPageSize = m_pPage->GetSize(); m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) ); } void OReportSection::Paste(const uno::Sequence< beans::NamedValue >& _aAllreadyCopiedObjects,bool _bForce) { OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!"); if ( !(m_xSection.is() && _aAllreadyCopiedObjects.hasElements()) ) return; // stop all drawing actions m_pView->BrkAction(); // unmark all objects m_pView->UnmarkAll(); const OUString sSectionName = m_xSection->getName(); for(const beans::NamedValue& rObject : _aAllreadyCopiedObjects) { if ( _bForce || rObject.Name == sSectionName) { try { uno::Sequence< uno::Reference > aCopies; rObject.Value >>= aCopies; for (const uno::Reference& rCopy : std::as_const(aCopies)) { SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rCopy ); if ( pObject ) { // Clone to target SdrModel rtl::Reference pNewObj(pObject->CloneSdrObject(*m_pModel)); m_pPage->InsertObject(pNewObj.get(), SAL_MAX_SIZE); tools::Rectangle aRet(VCLPoint(rCopy->getPosition()),VCLSize(rCopy->getSize())); aRet.setHeight(aRet.getOpenHeight() + 1); aRet.setWidth(aRet.getOpenWidth() + 1); bool bOverlapping = true; while ( bOverlapping ) { bOverlapping = isOver(aRet,*m_pPage,*m_pView,true,pNewObj.get()) != nullptr; if ( bOverlapping ) { aRet.Move(0,aRet.getOpenHeight()+1); pNewObj->SetLogicRect(aRet); } } m_pView->AddUndo(m_pView->GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pNewObj)); m_pView->MarkObj( pNewObj.get(), m_pView->GetSdrPageView() ); if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getOpenHeight() + aRet.Top()) > m_xSection->getHeight()) ) m_xSection->setHeight(aRet.getOpenHeight() + aRet.Top()); } } } catch(uno::Exception&) { TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while pasting a new object!"); } if ( !_bForce ) break; } } } void OReportSection::Delete() { if( !m_pView->AreObjectsMarked() ) return; m_pView->BrkAction(); m_pView->DeleteMarked(); } void OReportSection::SetMode( DlgEdMode eNewMode ) { if ( eNewMode == m_eMode ) return; if ( eNewMode == DlgEdMode::Insert ) { m_pFunc.reset(new DlgEdFuncInsert( this )); } else { m_pFunc.reset(new DlgEdFuncSelect( this )); } m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor( ) ); m_pModel->SetReadOnly(false); m_eMode = eNewMode; } void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects) { Copy(_rAllreadyCopiedObjects,false); } void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects,bool _bEraseAnddNoClone) { OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!"); if( !m_pView->AreObjectsMarked() || !m_xSection.is() ) return; // insert control models of marked objects into clipboard dialog model const SdrMarkList& rMarkedList = m_pView->GetMarkedObjectList(); const size_t nMark = rMarkedList.GetMarkCount(); ::std::vector< uno::Reference > aCopies; aCopies.reserve(nMark); SdrUndoFactory& rUndo = m_pView->GetModel().GetSdrUndoFactory(); for( size_t i = nMark; i > 0; ) { --i; SdrObject* pSdrObject = rMarkedList.GetMark(i)->GetMarkedSdrObj(); OObjectBase* pObj = dynamic_cast(pSdrObject); if ( pObj ) { try { rtl::Reference pNewObj(pSdrObject->CloneSdrObject(pSdrObject->getSdrModelFromSdrObject())); aCopies.emplace_back(pNewObj->getUnoShape(),uno::UNO_QUERY); if ( _bEraseAnddNoClone ) { m_pView->AddUndo( rUndo.CreateUndoDeleteObject( *pSdrObject ) ); m_pPage->RemoveObject(pSdrObject->GetOrdNum()); } } catch(uno::Exception&) { OSL_FAIL("Can't copy report elements!"); } } } if ( !aCopies.empty() ) { ::std::reverse(aCopies.begin(),aCopies.end()); const sal_Int32 nLength = _rAllreadyCopiedObjects.getLength(); _rAllreadyCopiedObjects.realloc( nLength + 1); beans::NamedValue* pNewValue = _rAllreadyCopiedObjects.getArray() + nLength; pNewValue->Name = m_xSection->getName(); pNewValue->Value <<= uno::Sequence< uno::Reference >(&(*aCopies.begin()),aCopies.size()); } } void OReportSection::MouseButtonDown( const MouseEvent& rMEvt ) { m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true); // mark the section in which is clicked m_pFunc->MouseButtonDown( rMEvt ); Window::MouseButtonDown(rMEvt); } void OReportSection::MouseButtonUp( const MouseEvent& rMEvt ) { if ( !m_pFunc->MouseButtonUp( rMEvt ) ) m_pParent->getViewsWindow()->getView()->getReportView()->getController().executeUnChecked(SID_OBJECT_SELECT,uno::Sequence< beans::PropertyValue>()); } void OReportSection::MouseMove( const MouseEvent& rMEvt ) { m_pFunc->MouseMove( rMEvt ); } void OReportSection::SetGridVisible(bool _bVisible) { m_pView->SetGridVisible( _bVisible ); } void OReportSection::SelectAll(const SdrObjKind _nObjectType) { if ( !m_pView ) return; if ( _nObjectType == SdrObjKind::NONE ) m_pView->MarkAllObj(); else { m_pView->UnmarkAll(); SdrObjListIter aIter(m_pPage,SdrIterMode::DeepNoGroups); SdrObject* pObjIter = nullptr; while( (pObjIter = aIter.Next()) != nullptr ) { if ( pObjIter->GetObjIdentifier() == _nObjectType ) m_pView->MarkObj( pObjIter, m_pView->GetSdrPageView() ); } } } void OReportSection::Command( const CommandEvent& _rCEvt ) { Window::Command(_rCEvt); if (_rCEvt.GetCommand() != CommandEventId::ContextMenu) return; OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController(); uno::Reference xFrame = rController.getFrame(); css::uno::Sequence aArgs { css::uno::Any(comphelper::makePropertyValue("Value", OUString("report"))), css::uno::Any(comphelper::makePropertyValue("Frame", xFrame)), css::uno::Any(comphelper::makePropertyValue("IsContextMenu", true)) }; css::uno::Reference xContext(rController.getORB()); css::uno::Reference xMenuController( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY); if (!xMenuController.is()) return; rtl::Reference xPopupMenu = new VCLXPopupMenu(); if (!xPopupMenu.is()) return; xMenuController->setPopupMenu(xPopupMenu); Point aPos = _rCEvt.GetMousePosPixel(); m_pView->EndAction(); xPopupMenu->execute(GetComponentInterface(), css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1), css::awt::PopupMenuDirection::EXECUTE_DOWN); css::uno::Reference xComponent(xMenuController, css::uno::UNO_QUERY); xComponent->dispose(); } void OReportSection::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) { if ( !m_xSection.is() ) return; if ( _rEvent.Source == m_xSection || PROPERTY_BACKCOLOR == _rEvent.PropertyName ) { sal_Int32 nColor = m_xSection->getBackColor(); if ( nColor == static_cast(COL_TRANSPARENT) ) nColor = getStyleProperty(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR); m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor)); Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase); } else { uno::Reference xReportDefinition = m_xSection->getReportDefinition(); const sal_Int32 nLeftMargin = getStyleProperty(xReportDefinition,PROPERTY_LEFTMARGIN); const sal_Int32 nRightMargin = getStyleProperty(xReportDefinition,PROPERTY_RIGHTMARGIN); const sal_Int32 nPaperWidth = getStyleProperty(xReportDefinition,PROPERTY_PAPERSIZE).Width; if ( _rEvent.PropertyName == PROPERTY_LEFTMARGIN ) { m_pPage->SetLeftBorder(nLeftMargin); } else if ( _rEvent.PropertyName == PROPERTY_RIGHTMARGIN ) { m_pPage->SetRightBorder(nRightMargin); } const Size aOldPageSize = m_pPage->GetSize(); sal_Int32 nNewHeight = 5*m_xSection->getHeight(); if ( aOldPageSize.Height() != nNewHeight || nPaperWidth != aOldPageSize.Width() ) { m_pPage->SetSize( Size( nPaperWidth,nNewHeight) ); const Size aPageSize = m_pPage->GetSize(); m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) ); } impl_adjustObjectSizePosition(nPaperWidth,nLeftMargin,nRightMargin); m_pParent->Invalidate(InvalidateFlags::Update | InvalidateFlags::Transparent); } } void OReportSection::impl_adjustObjectSizePosition(sal_Int32 i_nPaperWidth,sal_Int32 i_nLeftMargin,sal_Int32 i_nRightMargin) { try { sal_Int32 nRightBorder = i_nPaperWidth - i_nRightMargin; const sal_Int32 nCount = m_xSection->getCount(); for (sal_Int32 i = 0; i < nCount; ++i) { uno::Reference< report::XReportComponent> xReportComponent(m_xSection->getByIndex(i),uno::UNO_QUERY_THROW); awt::Point aPos = xReportComponent->getPosition(); awt::Size aSize = xReportComponent->getSize(); SdrObject* pObject = SdrObject::getSdrObjectFromXShape( xReportComponent ); if ( pObject ) { bool bChanged = false; OObjectBase& rBase = dynamic_cast(*pObject); rBase.EndListening(); if ( aPos.X < i_nLeftMargin ) { aPos.X = i_nLeftMargin; bChanged = true; } if ( (aPos.X + aSize.Width) > nRightBorder ) { aPos.X = nRightBorder - aSize.Width; if ( aPos.X < i_nLeftMargin ) { aSize.Width += aPos.X - i_nLeftMargin; aPos.X = i_nLeftMargin; // add listener around rBase.StartListening(); xReportComponent->setSize(aSize); rBase.EndListening(); } bChanged = true; } if ( aPos.Y < 0 ) aPos.Y = 0; if ( bChanged ) { xReportComponent->setPosition(aPos); correctOverlapping(pObject,*this,false); tools::Rectangle aRet(VCLPoint(xReportComponent->getPosition()),VCLSize(xReportComponent->getSize())); aRet.setHeight(aRet.getOpenHeight() + 1); aRet.setWidth(aRet.getOpenWidth() + 1); if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getOpenHeight() + aRet.Top()) > m_xSection->getHeight()) ) m_xSection->setHeight(aRet.getOpenHeight() + aRet.Top()); pObject->RecalcBoundRect(); } rBase.StartListening(); } } } catch(const uno::Exception &) { TOOLS_WARN_EXCEPTION( "reportdesign", "OReportSection::impl_adjustObjectSizePosition()"); } } bool OReportSection::handleKeyEvent(const KeyEvent& _rEvent) { return m_pFunc && m_pFunc->handleKeyEvent(_rEvent); } void OReportSection::deactivateOle() { if (m_pFunc) m_pFunc->deactivateOle(true); } void OReportSection::createDefault(const OUString& _sType) { SdrObject* pObj = m_pView->GetCreateObj(); if ( !pObj ) return; createDefault(_sType,pObj); } void OReportSection::createDefault(const OUString& _sType,SdrObject* _pObj) { bool bAttributesAppliedFromGallery = false; if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) ) { std::vector< OUString > aObjList; if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) ) { auto aIter = std::find_if(aObjList.begin(), aObjList.end(), [&_sType](const OUString& rObj) { return rObj.equalsIgnoreAsciiCase(_sType); }); if (aIter != aObjList.end()) { auto i = static_cast(std::distance(aObjList.begin(), aIter)); OReportModel aReportModel(nullptr); SfxItemPool& rPool = aReportModel.GetItemPool(); rPool.FreezeIdRanges(); if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aReportModel ) ) { const SdrObject* pSourceObj = aReportModel.GetPage( 0 )->GetObj( 0 ); if( pSourceObj ) { const SfxItemSet& rSource = pSourceObj->GetMergedItemSet(); SfxItemSetFixed< // Ranges from SdrAttrObj: SDRATTR_START, SDRATTR_SHADOW_LAST, SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, // Graphic attributes, 3D properties, // CustomShape properties: SDRATTR_GRAF_FIRST, SDRATTR_CUSTOMSHAPE_LAST, // Range from SdrTextObj: EE_ITEMS_START, EE_ITEMS_END> aDest( _pObj->getSdrModelFromSdrObject().GetItemPool() ); aDest.Set( rSource ); _pObj->SetMergedItemSet( aDest ); Degree100 nAngle = pSourceObj->GetRotateAngle(); if ( nAngle ) _pObj->NbcRotate( _pObj->GetSnapRect().Center(), nAngle ); bAttributesAppliedFromGallery = true; } } } } } if ( !bAttributesAppliedFromGallery ) { _pObj->SetMergedItem( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST) ); _pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); _pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) ); _pObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) ); static_cast(_pObj)->MergeDefaultAttributes( &_sType ); } } uno::Reference< report::XReportComponent > OReportSection::getCurrentControlModel() const { uno::Reference< report::XReportComponent > xModel; if ( m_pView ) { const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList(); if ( rMarkList.GetMarkCount() == 1 ) { SdrObject* pDlgEdObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); OObjectBase* pObj = dynamic_cast(pDlgEdObj); if ( pObj ) xModel = pObj->getReportComponent().get(); } } return xModel; } void OReportSection::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const { if ( !m_pView ) return; const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList(); const size_t nMarkCount = rMarkList.GetMarkCount(); for (size_t i=0; i < nMarkCount; ++i) { const SdrObject* pDlgEdObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); const OObjectBase* pObj = dynamic_cast(pDlgEdObj); if ( pObj ) { uno::Reference xInterface(pObj->getReportComponent()); _rSelection.push_back(xInterface); } } } sal_Int8 OReportSection::AcceptDrop( const AcceptDropEvent& _rEvt ) { ::Point aDropPos(_rEvt.maPosPixel); const MouseEvent aMouseEvt(aDropPos); if ( m_pFunc->isOverlapping(aMouseEvt) ) return DND_ACTION_NONE; if ( _rEvt.mnAction == DND_ACTION_COPY || _rEvt.mnAction == DND_ACTION_LINK ) { if (!m_pParent) return DND_ACTION_NONE; sal_uInt16 nCurrentPosition = m_pParent->getViewsWindow()->getPosition(m_pParent); if (_rEvt.mnAction == DND_ACTION_COPY ) { // we must assure, we can't drop in the top section if (nCurrentPosition < 1) { return DND_ACTION_NONE; } return DND_ACTION_LINK; } if (_rEvt.mnAction == DND_ACTION_LINK) { // we must assure, we can't drop in the bottom section if (m_pParent->getViewsWindow()->getSectionCount() > (nCurrentPosition + 1) ) { return DND_ACTION_COPY; } return DND_ACTION_NONE; } } else { const DataFlavorExVector& rFlavors = GetDataFlavorExVector(); if ( svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors) || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) ) return _rEvt.mnAction; const sal_Int8 nDropOption = ( OReportExchange::canExtract(rFlavors) ) ? DND_ACTION_COPYMOVE : DND_ACTION_NONE; return nDropOption; } return DND_ACTION_NONE; } sal_Int8 OReportSection::ExecuteDrop( const ExecuteDropEvent& _rEvt ) { ::Point aDropPos(PixelToLogic(_rEvt.maPosPixel)); const MouseEvent aMouseEvt(aDropPos); if ( m_pFunc->isOverlapping(aMouseEvt) ) return DND_ACTION_NONE; sal_Int8 nDropOption = DND_ACTION_NONE; const TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable); const DataFlavorExVector& rFlavors = aDropped.GetDataFlavorExVector(); bool bMultipleFormat = svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors); if ( OReportExchange::canExtract(rFlavors) ) { OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aDropped); Paste(aCopies,true); nDropOption = DND_ACTION_COPYMOVE; m_pParent->getViewsWindow()->BrkAction(); m_pParent->getViewsWindow()->unmarkAllObjects(m_pView); } else if ( bMultipleFormat || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) ) { m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true); m_pView->UnmarkAll(); const tools::Rectangle& rRect = m_pView->GetWorkArea(); if ( aDropPos.X() < rRect.Left() ) aDropPos.setX( rRect.Left() ); else if ( aDropPos.X() > rRect.Right() ) aDropPos.setX( rRect.Right() ); if ( aDropPos.Y() > rRect.Bottom() ) aDropPos.setY( rRect.Bottom() ); uno::Sequence aValues; if ( !bMultipleFormat ) { svx::ODataAccessDescriptor aDescriptor = svx::OColumnTransferable::extractColumnDescriptor(aDropped); aValues.realloc(1); aValues.getArray()[0].Value <<= aDescriptor.createPropertyValueSequence(); } else aValues = svx::OMultiColumnTransferable::extractDescriptor(aDropped); for(beans::PropertyValue & propVal : asNonConstRange(aValues)) { uno::Sequence aCurrent; propVal.Value >>= aCurrent; sal_Int32 nLength = aCurrent.getLength(); if ( nLength ) { aCurrent.realloc(nLength + 3); auto pCurrent = aCurrent.getArray(); pCurrent[nLength].Name = PROPERTY_POSITION; pCurrent[nLength++].Value <<= AWTPoint(aDropPos); // give also the DND Action (Shift|Ctrl) Key to really say what we want pCurrent[nLength].Name = "DNDAction"; pCurrent[nLength++].Value <<= _rEvt.mnAction; pCurrent[nLength].Name = "Section"; pCurrent[nLength++].Value <<= getSection(); propVal.Value <<= aCurrent; } } // we use this way to create undo actions OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController(); rController.executeChecked(SID_ADD_CONTROL_PAIR,aValues); nDropOption = DND_ACTION_COPY; } return nDropOption; } void OReportSection::stopScrollTimer() { m_pFunc->stopScrollTimer(); } bool OReportSection::isUiActive() const { return m_pFunc->isUiActive(); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */