| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_chart2.hxx" |
| |
| #include "ChartDropTargetHelper.hxx" |
| #include "DiagramHelper.hxx" |
| #include "DataSourceHelper.hxx" |
| |
| #include <com/sun/star/chart2/XChartDocument.hpp> |
| #include <com/sun/star/chart2/data/XDataProvider.hpp> |
| #include <com/sun/star/container/XChild.hpp> |
| |
| #include <sot/formats.hxx> |
| #include <vector> |
| |
| using namespace ::com::sun::star; |
| |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::Sequence; |
| using ::rtl::OUString; |
| |
| namespace |
| { |
| |
| ::std::vector< OUString > lcl_getStringsFromByteSequence( |
| const Sequence< sal_Int8 > & aByteSequence ) |
| { |
| ::std::vector< OUString > aResult; |
| const sal_Int32 nLength = aByteSequence.getLength(); |
| const sal_Char * pBytes( reinterpret_cast< const sal_Char* >( aByteSequence.getConstArray())); |
| sal_Int32 nStartPos = 0; |
| for( sal_Int32 nPos=0; nPos<nLength; ++nPos ) |
| { |
| if( pBytes[nPos] == '\0' ) |
| { |
| aResult.push_back( OUString( pBytes + nStartPos, (nPos - nStartPos), RTL_TEXTENCODING_ASCII_US )); |
| nStartPos = nPos + 1; |
| } |
| } |
| return aResult; |
| } |
| |
| } // anonymous namespace |
| |
| namespace chart |
| { |
| |
| ChartDropTargetHelper::ChartDropTargetHelper( |
| const Reference< datatransfer::dnd::XDropTarget >& rxDropTarget, |
| const Reference< chart2::XChartDocument > & xChartDocument ) : |
| DropTargetHelper( rxDropTarget ), |
| m_xChartDocument( xChartDocument ) |
| {} |
| |
| ChartDropTargetHelper::~ChartDropTargetHelper() |
| {} |
| |
| bool ChartDropTargetHelper::satisfiesPrerequisites() const |
| { |
| return ( m_xChartDocument.is() && |
| ! m_xChartDocument->hasInternalDataProvider()); |
| } |
| |
| sal_Int8 ChartDropTargetHelper::AcceptDrop( const AcceptDropEvent& rEvt ) |
| { |
| sal_Int8 nResult = DND_ACTION_NONE; |
| |
| if( ( rEvt.mnAction == DND_ACTION_COPY || |
| rEvt.mnAction == DND_ACTION_MOVE ) && |
| satisfiesPrerequisites() && |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ) |
| { |
| // @todo: check if the data is suitable. Is this possible without XTransferable? |
| nResult = rEvt.mnAction; |
| } |
| |
| return nResult; |
| } |
| |
| sal_Int8 ChartDropTargetHelper::ExecuteDrop( const ExecuteDropEvent& rEvt ) |
| { |
| sal_Int8 nResult = DND_ACTION_NONE; |
| |
| if( ( rEvt.mnAction == DND_ACTION_COPY || |
| rEvt.mnAction == DND_ACTION_MOVE ) && |
| rEvt.maDropEvent.Transferable.is() && |
| satisfiesPrerequisites()) |
| { |
| TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable ); |
| if( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK )) |
| { |
| Sequence< sal_Int8 > aBytes; |
| if( aDataHelper.GetSequence( SOT_FORMATSTR_ID_LINK, aBytes )) |
| { |
| ::std::vector< OUString > aStrings( lcl_getStringsFromByteSequence( aBytes )); |
| if( aStrings.size() >= 3 && |
| aStrings[0].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "soffice" ))) |
| { |
| OUString aDocName( aStrings[1] ); |
| OUString aRangeString( aStrings[2] ); |
| Reference< container::XChild > xChild( m_xChartDocument, uno::UNO_QUERY ); |
| if( xChild.is()) |
| { |
| Reference< frame::XModel > xParentModel( xChild->getParent(), uno::UNO_QUERY ); |
| if( xParentModel.is() && |
| m_xChartDocument.is()) |
| { |
| bool bDataComesFromParent = true; |
| // @todo: get the title somehow and compare it to |
| // aDocName if successful (the document is the |
| // parent) |
| if( bDataComesFromParent ) |
| { |
| Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() ); |
| Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider()); |
| if( xDataProvider.is() && xDiagram.is() && |
| DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument )) |
| { |
| Reference< chart2::data::XDataSource > xDataSource( |
| DataSourceHelper::pressUsedDataIntoRectangularFormat( m_xChartDocument )); |
| Sequence< beans::PropertyValue > aArguments( |
| xDataProvider->detectArguments( xDataSource )); |
| |
| OUString aOldRange; |
| beans::PropertyValue * pCellRange = 0; |
| for( sal_Int32 i=0; i<aArguments.getLength(); ++i ) |
| { |
| if( aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation"))) |
| { |
| pCellRange = (aArguments.getArray() + i); |
| aArguments[i].Value >>= aOldRange; |
| break; |
| } |
| } |
| if( pCellRange ) |
| { |
| // copy means add ranges, move means replace |
| if( rEvt.mnAction == DND_ACTION_COPY ) |
| { |
| // @todo: using implcit knowledge that ranges can be |
| // merged with ";". This should be done more general |
| pCellRange->Value <<= (aOldRange + OUString( sal_Unicode(';')) + aRangeString ); |
| } |
| // move means replace range |
| else |
| { |
| pCellRange->Value <<= aRangeString; |
| } |
| |
| xDataSource.set( xDataProvider->createDataSource( aArguments )); |
| xDiagram->setDiagramData( xDataSource, aArguments ); |
| |
| // always return copy state to avoid deletion of the dragged range |
| nResult = DND_ACTION_COPY; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return nResult; |
| } |
| |
| } // namespace chart |