1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 
27 #include "ChartController.hxx"
28 #include "ChartWindow.hxx"
29 #include "ChartModelHelper.hxx"
30 #include "TitleHelper.hxx"
31 #include "ThreeDHelper.hxx"
32 #include "DataSeriesHelper.hxx"
33 #include "UndoGuard.hxx"
34 #include "ControllerLockGuard.hxx"
35 #include "macros.hxx"
36 #include "ResId.hxx"
37 #include "Strings.hrc"
38 #include "ObjectIdentifier.hxx"
39 #include "ReferenceSizeProvider.hxx"
40 #include "chartview/ExplicitValueProvider.hxx"
41 #include "chartview/DrawModelWrapper.hxx"
42 #include "ChartTransferable.hxx"
43 #include "DrawViewWrapper.hxx"
44 #include "LegendHelper.hxx"
45 #include "AxisHelper.hxx"
46 #include "RegressionCurveHelper.hxx"
47 #include "ShapeController.hxx"
48 #include "DiagramHelper.hxx"
49 #include "ObjectNameProvider.hxx"
50 
51 #include <com/sun/star/chart2/DataPointLabel.hpp>
52 #include <com/sun/star/beans/XPropertyState.hpp>
53 #include <com/sun/star/drawing/CameraGeometry.hpp>
54 #include <com/sun/star/graphic/XGraphic.hpp>
55 #include <com/sun/star/io/XInputStream.hpp>
56 #include <com/sun/star/text/XTextRange.hpp>
57 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
58 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
59 #include <com/sun/star/chart/ErrorBarStyle.hpp>
60 
61 #include <svx/ActionDescriptionProvider.hxx>
62 // for TransferableDataHelper/TransferableHelper
63 #include <svtools/transfer.hxx>
64 // for SotStorageStreamRef
65 #include <sot/storage.hxx>
66 // for Graphic
67 #include <vcl/graph.hxx>
68 // for SvxDrawingLayerImport/SvxUnoDrawingModel
69 #include <svx/unomodel.hxx>
70 // for SdrModel
71 #include <svx/svdmodel.hxx>
72 // for OInputStreamWrapper
73 #include <unotools/streamwrap.hxx>
74 // for SolarMutex
75 #include <vcl/svapp.hxx>
76 #include <vos/mutex.hxx>
77 #include <svx/dialmgr.hxx>
78 #include <svx/dialogs.hrc>
79 // for OutlinerView
80 #include <editeng/outliner.hxx>
81 #include <svx/svditer.hxx>
82 #include <svx/svdpage.hxx>
83 #include <svx/svdundo.hxx>
84 #include <svx/unoapi.hxx>
85 #include <svx/unopage.hxx>
86 
87 #include <boost/scoped_ptr.hpp>
88 
89 using namespace ::com::sun::star;
90 
91 using ::com::sun::star::uno::Reference;
92 using ::com::sun::star::uno::Sequence;
93 using ::rtl::OUString;
94 
95 namespace
96 {
97 
lcl_deleteDataSeries(const OUString & rCID,const Reference<frame::XModel> & xModel,const Reference<document::XUndoManager> & xUndoManager)98 bool lcl_deleteDataSeries(
99     const OUString & rCID,
100     const Reference< frame::XModel > & xModel,
101     const Reference< document::XUndoManager > & xUndoManager )
102 {
103     bool bResult = false;
104     uno::Reference< chart2::XDataSeries > xSeries( ::chart::ObjectIdentifier::getDataSeriesForCID( rCID, xModel ));
105     uno::Reference< chart2::XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
106     if( xSeries.is() && xChartDoc.is())
107     {
108         uno::Reference< chart2::XChartType > xChartType(
109             ::chart::DataSeriesHelper::getChartTypeOfSeries( xSeries, xChartDoc->getFirstDiagram()));
110         if( xChartType.is())
111         {
112             ::chart::UndoGuard aUndoGuard(
113                 ActionDescriptionProvider::createDescription(
114                     ActionDescriptionProvider::DELETE, String( ::chart::SchResId( STR_OBJECT_DATASERIES ))),
115                 xUndoManager );
116 
117             Reference< chart2::XDiagram > xDiagram( ::chart::ChartModelHelper::findDiagram( xModel ) );
118             uno::Reference< chart2::XAxis > xAxis( ::chart::DiagramHelper::getAttachedAxis( xSeries, xDiagram ) );
119 
120             ::chart::DataSeriesHelper::deleteSeries( xSeries, xChartType );
121 
122             ::chart::AxisHelper::hideAxisIfNoDataIsAttached( xAxis, xDiagram );
123 
124             bResult = true;
125             aUndoGuard.commit();
126         }
127     }
128     return bResult;
129 }
130 
lcl_deleteDataCurve(const OUString & rCID,const Reference<frame::XModel> & xModel,const Reference<document::XUndoManager> & xUndoManager)131 bool lcl_deleteDataCurve(
132     const OUString & rCID,
133     const Reference< frame::XModel > & xModel,
134     const Reference< document::XUndoManager > & xUndoManager )
135 {
136     bool bResult = false;
137     uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt(
138         ::chart::ObjectIdentifier::getObjectPropertySet(
139             ::chart::ObjectIdentifier::getSeriesParticleFromCID( rCID ), xModel ), uno::UNO_QUERY );
140     if( xRegCurveCnt.is())
141     {
142         ::chart::UndoGuard aUndoGuard(
143             ActionDescriptionProvider::createDescription(
144                 ActionDescriptionProvider::DELETE, String( ::chart::SchResId( STR_OBJECT_CURVE ))),
145             xUndoManager );
146         ::chart::RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCurveCnt );
147         bResult = true;
148         aUndoGuard.commit();
149     }
150     return bResult;
151 }
152 
153 // void lcl_CopyPageContentToPage(
154 //     const Reference< drawing::XDrawPage > & xSourcePage,
155 //     const Reference< drawing::XDrawPage > & xDestPage )
156 // {
157 //     try
158 //     {
159 //         Reference< container::XIndexAccess > xSourceIA( xSourcePage, uno::UNO_QUERY_THROW );
160 //         sal_Int32 nCount( xSourceIA->getCount());
161 //         for( sal_Int32 i=0; i<nCount; ++i )
162 //         {
163 //             Reference< drawing::XShape > xShape;
164 //             if( xSourceIA->getByIndex( i ) >>= xShape )
165 //                 xDestPage->add( xShape );
166 //         }
167 //     }
168 //     catch( const uno::Exception & ex )
169 //     {
170 //         ASSERT_EXCEPTION( ex );
171 //     }
172 // }
173 
174 // // copies all shapes on all pages of xSource to the only page of xDestination
175 // void lcl_CopyShapesToChart(
176 //     const Reference< frame::XModel > & xSource, const Reference< frame::XModel > & xDestination )
177 // {
178 //     try
179 //     {
180 //         Reference< drawing::XDrawPageSupplier > xDestPGSupp( xDestination, uno::UNO_QUERY_THROW );
181 //         Reference< drawing::XDrawPage > xDestPage( xDestPGSupp->getDrawPage());
182 //         Reference< drawing::XDrawPagesSupplier > xSourcePGsSupp( xSource, uno::UNO_QUERY_THROW );
183 //         Reference< drawing::XDrawPages > xSourcePages( xSourcePGsSupp->getDrawPages());
184 
185 //         sal_Int32 nCount( xSourcePages->getCount());
186 //         for( sal_Int32 i=0; i<nCount; ++i )
187 //         {
188 //             Reference< drawing::XDrawPage > xSourcePage( xSourcePages->getByIndex( i ), uno::UNO_QUERY_THROW );
189 //             lcl_CopyPageContentToPage( xSourcePage, xDestPage );
190 //         }
191 //     }
192 //     catch( const uno::Exception & ex )
193 //     {
194 //         ASSERT_EXCEPTION( ex );
195 //     }
196 // }
197 
198 } // anonymous namespace
199 
200 
201 namespace chart
202 {
203 
impl_createReferenceSizeProvider()204 ::std::auto_ptr< ReferenceSizeProvider > ChartController::impl_createReferenceSizeProvider()
205 {
206     awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
207 
208     return ::std::auto_ptr< ReferenceSizeProvider >(
209         new ReferenceSizeProvider( aPageSize,
210             Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY )));
211 }
212 
impl_adaptDataSeriesAutoResize()213 void ChartController::impl_adaptDataSeriesAutoResize()
214 {
215     ::std::auto_ptr< ReferenceSizeProvider > apRefSizeProvider(
216         impl_createReferenceSizeProvider());
217     if( apRefSizeProvider.get())
218         apRefSizeProvider->setValuesAtAllDataSeries();
219 }
220 
executeDispatch_NewArrangement()221 void ChartController::executeDispatch_NewArrangement()
222 {
223     // remove manual positions at titles, legend and the diagram, remove manual
224     // size at the diagram
225 
226     try
227     {
228         Reference< frame::XModel > xModel( getModel() );
229         Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ));
230         if( xDiagram.is())
231         {
232             // using assignment for broken gcc 3.3
233             UndoGuard aUndoGuard = UndoGuard(
234                 String( SchResId( STR_ACTION_REARRANGE_CHART )),
235                 m_xUndoManager );
236             ControllerLockGuard aCtlLockGuard( xModel );
237 
238             // diagram
239             Reference< beans::XPropertyState > xState( xDiagram, uno::UNO_QUERY_THROW );
240             xState->setPropertyToDefault( C2U("RelativeSize"));
241             xState->setPropertyToDefault( C2U("RelativePosition"));
242             xState->setPropertyToDefault( C2U("PosSizeExcludeAxes"));
243 
244             // 3d rotation
245             ThreeDHelper::set3DSettingsToDefault( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ) );
246 
247             // legend
248             Reference< beans::XPropertyState > xLegendState( xDiagram->getLegend(), uno::UNO_QUERY );
249             if( xLegendState.is())
250             {
251                 xLegendState->setPropertyToDefault( C2U("RelativePosition"));
252                 xLegendState->setPropertyToDefault( C2U("RelativeSize"));
253                 xLegendState->setPropertyToDefault( C2U("AnchorPosition"));
254             }
255 
256             // titles
257             for( sal_Int32 eType = TitleHelper::TITLE_BEGIN;
258                  eType < TitleHelper::NORMAL_TITLE_END;
259                  ++eType )
260             {
261                 Reference< beans::XPropertyState > xTitleState(
262                     TitleHelper::getTitle(
263                         static_cast< TitleHelper::eTitleType >( eType ), xModel ), uno::UNO_QUERY );
264                 if( xTitleState.is())
265                     xTitleState->setPropertyToDefault( C2U("RelativePosition"));
266             }
267 
268             // regression curve equations
269             ::std::vector< Reference< chart2::XRegressionCurve > > aRegressionCurves(
270                 RegressionCurveHelper::getAllRegressionCurvesNotMeanValueLine( xDiagram ));
271             ::std::for_each( aRegressionCurves.begin(), aRegressionCurves.end(),
272                       RegressionCurveHelper::resetEquationPosition );
273 
274             aUndoGuard.commit();
275         }
276     }
277     catch( uno::RuntimeException & ex )
278     {
279         ASSERT_EXCEPTION( ex );
280     }
281 }
282 
executeDispatch_ScaleText()283 void ChartController::executeDispatch_ScaleText()
284 {
285     ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
286     // using assignment for broken gcc 3.3
287     UndoGuard aUndoGuard = UndoGuard(
288         String( SchResId( STR_ACTION_SCALE_TEXT )),
289         m_xUndoManager );
290     ControllerLockGuard aCtlLockGuard( getModel() );
291     ::std::auto_ptr< ReferenceSizeProvider > apRefSizeProv( impl_createReferenceSizeProvider());
292     OSL_ASSERT( apRefSizeProv.get());
293     if( apRefSizeProv.get())
294         apRefSizeProv->toggleAutoResizeState();
295     aUndoGuard.commit();
296 }
297 
executeDispatch_Paste()298 void ChartController::executeDispatch_Paste()
299 {
300     ::vos::OGuard aGuard( Application::GetSolarMutex() );
301     if( m_pChartWindow )
302     {
303         Graphic aGraphic;
304         // paste location: center of window
305         Point aPos;
306         aPos = m_pChartWindow->PixelToLogic( Rectangle( aPos, m_pChartWindow->GetSizePixel()).Center());
307 
308         // handle different formats
309         TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( m_pChartWindow ));
310         if( aDataHelper.GetTransferable().is())
311         {
312             if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
313             {
314                 SotStorageStreamRef xStm;
315                 if ( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
316                 {
317                     xStm->Seek( 0 );
318                     Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
319                     ::boost::scoped_ptr< SdrModel > spModel( new SdrModel() );
320                     if ( SvxDrawingLayerImport( spModel.get(), xInputStream ) )
321                     {
322                         impl_PasteShapes( spModel.get() );
323                     }
324                 }
325             }
326             else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
327             {
328                 // graphic exchange format (graphic manager bitmap format?)
329                 SotStorageStreamRef xStm;
330                 if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ))
331                     (*xStm) >> aGraphic;
332             }
333             else if( aDataHelper.HasFormat( FORMAT_GDIMETAFILE ))
334             {
335                 // meta file
336                 GDIMetaFile aMetafile;
337                 if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMetafile ))
338                     aGraphic = Graphic( aMetafile );
339             }
340             else if( aDataHelper.HasFormat( FORMAT_BITMAP ))
341             {
342                 // bitmap (non-graphic-manager)
343                 BitmapEx aBmpEx;
344                 if( aDataHelper.GetBitmapEx( FORMAT_BITMAP, aBmpEx ))
345                     aGraphic = Graphic( aBmpEx );
346             }
347             else if( aDataHelper.HasFormat( FORMAT_STRING ))
348             {
349                 OUString aString;
350                 if( aDataHelper.GetString( FORMAT_STRING, aString ) && m_pDrawModelWrapper )
351                 {
352                     if( m_pDrawViewWrapper )
353                     {
354                         OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView();
355                         if( pOutlinerView )//in case of edit mode insert into edited string
356                             pOutlinerView->InsertText( aString );
357                         else
358                         {
359                             impl_PasteStringAsTextShape( aString, awt::Point( 0, 0 ) );
360                         }
361                     }
362                 }
363             }
364         }
365 
366         if( aGraphic.GetType() != GRAPHIC_NONE )
367         {
368             Reference< graphic::XGraphic > xGraphic( aGraphic.GetXGraphic());
369             if( xGraphic.is())
370                 impl_PasteGraphic( xGraphic, aPos );
371         }
372     }
373 }
374 
375 // note: aPosition is ignored for now. The object is always pasted centered to
376 // the page
impl_PasteGraphic(uno::Reference<graphic::XGraphic> & xGraphic,const::Point &)377 void ChartController::impl_PasteGraphic(
378     uno::Reference< graphic::XGraphic > & xGraphic,
379     const ::Point & /* aPosition */ )
380 {
381     // note: the XPropertySet of the model is the old API. Also the property
382     // "AdditionalShapes" that is used there.
383     uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY );
384     DrawModelWrapper * pDrawModelWrapper( this->GetDrawModelWrapper());
385     if( ! (xGraphic.is() && xModelProp.is()))
386         return;
387     uno::Reference< lang::XMultiServiceFactory > xFact( pDrawModelWrapper->getShapeFactory());
388     uno::Reference< drawing::XShape > xGraphicShape(
389         xFact->createInstance( C2U( "com.sun.star.drawing.GraphicObjectShape" )), uno::UNO_QUERY );
390     uno::Reference< beans::XPropertySet > xGraphicShapeProp( xGraphicShape, uno::UNO_QUERY );
391     if( xGraphicShapeProp.is() && xGraphicShape.is())
392     {
393         uno::Reference< drawing::XShapes > xPage( pDrawModelWrapper->getMainDrawPage(), uno::UNO_QUERY );
394         if( xPage.is())
395         {
396             xPage->add( xGraphicShape );
397             //need to change the model state manually
398             {
399                 uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY );
400                 if( xModifiable.is() )
401                     xModifiable->setModified( true );
402             }
403             //select new shape
404             m_aSelection.setSelection( xGraphicShape );
405             m_aSelection.applySelection( m_pDrawViewWrapper );
406         }
407         xGraphicShapeProp->setPropertyValue( C2U("Graphic"), uno::makeAny( xGraphic ));
408         uno::Reference< beans::XPropertySet > xGraphicProp( xGraphic, uno::UNO_QUERY );
409 
410         awt::Size aGraphicSize( 1000, 1000 );
411         // first try size in 100th mm, then pixel size
412         if( ! ( xGraphicProp->getPropertyValue( C2U("Size100thMM")) >>= aGraphicSize ) &&
413             ( ( xGraphicProp->getPropertyValue( C2U("SizePixel")) >>= aGraphicSize ) && m_pChartWindow ))
414         {
415             ::Size aVCLSize( m_pChartWindow->PixelToLogic( Size( aGraphicSize.Width, aGraphicSize.Height )));
416             aGraphicSize.Width = aVCLSize.getWidth();
417             aGraphicSize.Height = aVCLSize.getHeight();
418         }
419         xGraphicShape->setSize( aGraphicSize );
420         xGraphicShape->setPosition( awt::Point( 0, 0 ) );
421     }
422 }
423 
impl_PasteShapes(SdrModel * pModel)424 void ChartController::impl_PasteShapes( SdrModel* pModel )
425 {
426     DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() );
427     if ( pDrawModelWrapper && m_pDrawViewWrapper )
428     {
429         Reference< drawing::XDrawPage > xDestPage( pDrawModelWrapper->getMainDrawPage() );
430         SdrPage* pDestPage = GetSdrPageFromXDrawPage( xDestPage );
431         if ( pDestPage )
432         {
433             Reference< drawing::XShape > xSelShape;
434             m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) );
435             sal_uInt16 nCount = pModel->GetPageCount();
436             for ( sal_uInt16 i = 0; i < nCount; ++i )
437             {
438                 const SdrPage* pPage = pModel->GetPage( i );
439                 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
440                 while ( aIter.IsMore() )
441                 {
442                     SdrObject* pObj = aIter.Next();
443                     SdrObject* pNewObj = ( pObj ? pObj->Clone() : NULL );
444                     if ( pNewObj )
445                     {
446                         pNewObj->SetModel( &pDrawModelWrapper->getSdrModel() );
447                         pNewObj->SetPage( pDestPage );
448 
449                         // set position
450                         Reference< drawing::XShape > xShape( pNewObj->getUnoShape(), uno::UNO_QUERY );
451                         if ( xShape.is() )
452                         {
453                             xShape->setPosition( awt::Point( 0, 0 ) );
454                         }
455 
456                         pDestPage->InsertObject( pNewObj );
457                         m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pNewObj ) );
458                         xSelShape = xShape;
459                     }
460                 }
461             }
462 
463             Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY );
464             if ( xModifiable.is() )
465             {
466                 xModifiable->setModified( true );
467             }
468 
469             // select last inserted shape
470             m_aSelection.setSelection( xSelShape );
471             m_aSelection.applySelection( m_pDrawViewWrapper );
472 
473             m_pDrawViewWrapper->EndUndo();
474 
475             impl_switchDiagramPositioningToExcludingPositioning();
476         }
477     }
478 }
479 
impl_PasteStringAsTextShape(const OUString & rString,const awt::Point & rPosition)480 void ChartController::impl_PasteStringAsTextShape( const OUString& rString, const awt::Point& rPosition )
481 {
482     DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() );
483     if ( pDrawModelWrapper && m_pDrawViewWrapper )
484     {
485         const Reference< lang::XMultiServiceFactory >& xShapeFactory( pDrawModelWrapper->getShapeFactory() );
486         const Reference< drawing::XDrawPage >& xDrawPage( pDrawModelWrapper->getMainDrawPage() );
487         OSL_ASSERT( xShapeFactory.is() && xDrawPage.is() );
488 
489         if ( xShapeFactory.is() && xDrawPage.is() )
490         {
491             try
492             {
493                 Reference< drawing::XShape > xTextShape(
494                     xShapeFactory->createInstance( C2U( "com.sun.star.drawing.TextShape" ) ), uno::UNO_QUERY_THROW );
495                 xDrawPage->add( xTextShape );
496 
497                 Reference< text::XTextRange > xRange( xTextShape, uno::UNO_QUERY_THROW );
498                 xRange->setString( rString );
499 
500                 float fCharHeight = 10.0;
501                 Reference< beans::XPropertySet > xProperties( xTextShape, uno::UNO_QUERY_THROW );
502                 xProperties->setPropertyValue( C2U( "TextAutoGrowHeight" ), uno::makeAny( true ) );
503                 xProperties->setPropertyValue( C2U( "TextAutoGrowWidth" ), uno::makeAny( true ) );
504                 xProperties->setPropertyValue( C2U( "CharHeight" ), uno::makeAny( fCharHeight ) );
505                 xProperties->setPropertyValue( C2U( "CharHeightAsian" ), uno::makeAny( fCharHeight ) );
506                 xProperties->setPropertyValue( C2U( "CharHeightComplex" ), uno::makeAny( fCharHeight ) );
507                 xProperties->setPropertyValue( C2U( "TextVerticalAdjust" ), uno::makeAny( drawing::TextVerticalAdjust_CENTER ) );
508                 xProperties->setPropertyValue( C2U( "TextHorizontalAdjust" ), uno::makeAny( drawing::TextHorizontalAdjust_CENTER ) );
509                 xProperties->setPropertyValue( C2U( "CharFontName" ), uno::makeAny( C2U( "Albany" ) ) );
510 
511                 xTextShape->setPosition( rPosition );
512 
513                 m_aSelection.setSelection( xTextShape );
514                 m_aSelection.applySelection( m_pDrawViewWrapper );
515 
516                 SdrObject* pObj = DrawViewWrapper::getSdrObject( xTextShape );
517                 if ( pObj )
518                 {
519                     m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) );
520                     m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pObj ) );
521                     m_pDrawViewWrapper->EndUndo();
522 
523                     impl_switchDiagramPositioningToExcludingPositioning();
524                 }
525             }
526             catch ( const uno::Exception& ex )
527             {
528                 ASSERT_EXCEPTION( ex );
529             }
530         }
531     }
532 }
533 
executeDispatch_Copy()534 void ChartController::executeDispatch_Copy()
535 {
536     if ( m_pDrawViewWrapper )
537     {
538         OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView();
539         if ( pOutlinerView )
540         {
541             pOutlinerView->Copy();
542         }
543         else
544         {
545             Reference< datatransfer::XTransferable > xTransferable;
546             {
547                 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
548                 SdrObject* pSelectedObj = 0;
549                 if ( m_pDrawModelWrapper )
550                 {
551                     ObjectIdentifier aSelOID( m_aSelection.getSelectedOID() );
552                     if ( aSelOID.isAutoGeneratedObject() )
553                     {
554                         pSelectedObj = m_pDrawModelWrapper->getNamedSdrObject( aSelOID.getObjectCID() );
555                     }
556                     else if ( aSelOID.isAdditionalShape() )
557                     {
558                         pSelectedObj = DrawViewWrapper::getSdrObject( aSelOID.getAdditionalShape() );
559                     }
560                     if ( pSelectedObj )
561                     {
562                         xTransferable = Reference< datatransfer::XTransferable >( new ChartTransferable(
563                                 &m_pDrawModelWrapper->getSdrModel(), pSelectedObj, aSelOID.isAdditionalShape() ) );
564                     }
565                 }
566             }
567             if ( xTransferable.is() )
568             {
569                 Reference< datatransfer::clipboard::XClipboard > xClipboard( TransferableHelper::GetSystemClipboard() );
570                 if ( xClipboard.is() )
571                 {
572                     xClipboard->setContents( xTransferable, Reference< datatransfer::clipboard::XClipboardOwner >() );
573                 }
574             }
575         }
576     }
577 }
578 
executeDispatch_Cut()579 void ChartController::executeDispatch_Cut()
580 {
581     executeDispatch_Copy();
582     executeDispatch_Delete();
583 }
584 
isObjectDeleteable(const uno::Any & rSelection)585 bool ChartController::isObjectDeleteable( const uno::Any& rSelection )
586 {
587     ObjectIdentifier aSelOID( rSelection );
588     if ( aSelOID.isAutoGeneratedObject() )
589     {
590         OUString aSelObjCID( aSelOID.getObjectCID() );
591         ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID ));
592         if( (OBJECTTYPE_TITLE == aObjectType) || (OBJECTTYPE_LEGEND == aObjectType) )
593             return true;
594         if( (OBJECTTYPE_DATA_SERIES == aObjectType) || (OBJECTTYPE_LEGEND_ENTRY == aObjectType) )
595             return true;
596         if( (OBJECTTYPE_DATA_CURVE_EQUATION == aObjectType) || (OBJECTTYPE_DATA_CURVE == aObjectType) ||
597             (OBJECTTYPE_DATA_AVERAGE_LINE == aObjectType) || (OBJECTTYPE_DATA_ERRORS == aObjectType))
598             return true;
599         if( (OBJECTTYPE_DATA_LABELS == aObjectType) || (OBJECTTYPE_DATA_LABEL == aObjectType) )
600             return true;
601         if( (OBJECTTYPE_AXIS == aObjectType) || (OBJECTTYPE_GRID == aObjectType) || (OBJECTTYPE_SUBGRID == aObjectType) )
602             return true;
603     }
604     else if ( aSelOID.isAdditionalShape() )
605     {
606         return true;
607     }
608 
609     return false;
610 }
611 
isShapeContext() const612 bool ChartController::isShapeContext() const
613 {
614     if ( m_aSelection.isAdditionalShapeSelected() ||
615          ( m_pDrawViewWrapper && m_pDrawViewWrapper->AreObjectsMarked() &&
616            ( m_pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT ) ) )
617     {
618         return true;
619     }
620 
621     return false;
622 }
623 
impl_ClearSelection()624 void ChartController::impl_ClearSelection()
625 {
626     if( m_aSelection.hasSelection())
627     {
628         m_aSelection.clearSelection();
629         impl_notifySelectionChangeListeners();
630     }
631 }
632 
executeDispatch_Delete()633 bool ChartController::executeDispatch_Delete()
634 {
635     bool bReturn = false;
636 
637     // remove the selected object
638     //
639     rtl::OUString aCID( m_aSelection.getSelectedCID() );
640     if( !aCID.isEmpty() )
641     {
642         if( !isObjectDeleteable( uno::Any( aCID ) ) )
643             return false;
644 
645         //remove chart object
646         uno::Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
647         if( !xChartDoc.is() )
648             return false;
649 
650         ObjectType aObjectType( ObjectIdentifier::getObjectType( aCID ));
651         switch( aObjectType )
652         {
653             case OBJECTTYPE_TITLE:
654             {
655                 // using assignment for broken gcc 3.3
656                 UndoGuard aUndoGuard = UndoGuard(
657                     ActionDescriptionProvider::createDescription(
658                         ActionDescriptionProvider::DELETE, String( SchResId( STR_OBJECT_TITLE ))),
659                     m_xUndoManager );
660                 TitleHelper::removeTitle(
661                     ObjectIdentifier::getTitleTypeForCID( aCID ), getModel() );
662                 bReturn = true;
663                 aUndoGuard.commit();
664                 break;
665             }
666             case OBJECTTYPE_LEGEND:
667             {
668                 uno::Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
669                 if( xDiagram.is())
670                 {
671                     uno::Reference< beans::XPropertySet > xLegendProp( xDiagram->getLegend(), uno::UNO_QUERY );
672                     if( xLegendProp.is())
673                     {
674                         // using assignment for broken gcc 3.3
675                         UndoGuard aUndoGuard = UndoGuard(
676                             ActionDescriptionProvider::createDescription(
677                                 ActionDescriptionProvider::DELETE, String( SchResId( STR_OBJECT_LEGEND ))),
678                             m_xUndoManager );
679                         xLegendProp->setPropertyValue( C2U("Show"), uno::makeAny( false ));
680                         bReturn = true;
681                         aUndoGuard.commit();
682                     }
683                 }
684                 break;
685             }
686 
687             case OBJECTTYPE_DATA_SERIES:
688                 bReturn = lcl_deleteDataSeries( aCID, getModel(), m_xUndoManager );
689                 break;
690 
691             case OBJECTTYPE_LEGEND_ENTRY:
692             {
693                 ObjectType eParentObjectType = ObjectIdentifier::getObjectType(
694                     ObjectIdentifier::getFullParentParticle( aCID ));
695                 if( eParentObjectType == OBJECTTYPE_DATA_SERIES )
696                     bReturn = lcl_deleteDataSeries( aCID, getModel(), m_xUndoManager );
697                 else if( eParentObjectType == OBJECTTYPE_DATA_CURVE )
698                     bReturn = lcl_deleteDataCurve( aCID, getModel(), m_xUndoManager );
699                 else if( eParentObjectType == OBJECTTYPE_DATA_AVERAGE_LINE )
700                 {
701                     executeDispatch_DeleteMeanValue();
702                     bReturn = true;
703                 }
704                 break;
705             }
706 
707             case OBJECTTYPE_DATA_AVERAGE_LINE:
708             {
709                 uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt(
710                     ObjectIdentifier::getObjectPropertySet(
711                         ObjectIdentifier::getFullParentParticle( aCID ), getModel()), uno::UNO_QUERY );
712                 if( xRegCurveCnt.is())
713                 {
714                     // using assignment for broken gcc 3.3
715                     UndoGuard aUndoGuard = UndoGuard(
716                         ActionDescriptionProvider::createDescription(
717                             ActionDescriptionProvider::DELETE, String( SchResId( STR_OBJECT_AVERAGE_LINE ))),
718                         m_xUndoManager );
719                     RegressionCurveHelper::removeMeanValueLine( xRegCurveCnt );
720                     bReturn = true;
721                     aUndoGuard.commit();
722                 }
723                 break;
724             }
725 
726             case OBJECTTYPE_DATA_CURVE:
727                 bReturn = lcl_deleteDataCurve( aCID, getModel(), m_xUndoManager );
728                 break;
729 
730             case OBJECTTYPE_DATA_CURVE_EQUATION:
731             {
732                 uno::Reference< beans::XPropertySet > xEqProp(
733                     ObjectIdentifier::getObjectPropertySet( aCID, getModel()));
734                 if( xEqProp.is())
735                 {
736                     uno::Reference< frame::XModel > xModel( getModel() );
737                     // using assignment for broken gcc 3.3
738                     UndoGuard aUndoGuard = UndoGuard(
739                         ActionDescriptionProvider::createDescription(
740                             ActionDescriptionProvider::DELETE, String( SchResId( STR_OBJECT_CURVE_EQUATION ))),
741                         m_xUndoManager );
742                     {
743                         ControllerLockGuard aCtlLockGuard( xModel );
744                         xEqProp->setPropertyValue( C2U("ShowEquation"), uno::makeAny( false ));
745                         xEqProp->setPropertyValue( C2U("ShowCorrelationCoefficient"), uno::makeAny( false ));
746                     }
747                     bReturn = true;
748                     aUndoGuard.commit();
749                 }
750                 break;
751             }
752 
753             case OBJECTTYPE_DATA_ERRORS:
754             {
755                 uno::Reference< beans::XPropertySet > xErrorBarProp(
756                     ObjectIdentifier::getObjectPropertySet( aCID, getModel() ));
757                 if( xErrorBarProp.is())
758                 {
759                     uno::Reference< frame::XModel > xModel( getModel() );
760                     // using assignment for broken gcc 3.3
761                     UndoGuard aUndoGuard = UndoGuard(
762                         ActionDescriptionProvider::createDescription(
763                             ActionDescriptionProvider::DELETE, String( SchResId( STR_OBJECT_ERROR_BARS ))),
764                         m_xUndoManager );
765                     {
766                         ControllerLockGuard aCtlLockGuard( xModel );
767                         xErrorBarProp->setPropertyValue(
768                             C2U("ErrorBarStyle"),
769                             uno::makeAny( ::com::sun::star::chart::ErrorBarStyle::NONE ));
770                     }
771                     bReturn = true;
772                     aUndoGuard.commit();
773                 }
774                 break;
775             }
776 
777             case OBJECTTYPE_DATA_LABELS:
778             case OBJECTTYPE_DATA_LABEL:
779             {
780                 uno::Reference< beans::XPropertySet > xObjectProperties =
781                     ObjectIdentifier::getObjectPropertySet( aCID, getModel() );
782                 if( xObjectProperties.is() )
783                 {
784                     UndoGuard aUndoGuard = UndoGuard(
785                         ActionDescriptionProvider::createDescription(
786                         ActionDescriptionProvider::DELETE, ::rtl::OUString( String(
787                             SchResId( aObjectType == OBJECTTYPE_DATA_LABEL ? STR_OBJECT_LABEL : STR_OBJECT_DATALABELS )))),
788                                 m_xUndoManager );
789                     chart2::DataPointLabel aLabel;
790                     xObjectProperties->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
791                     aLabel.ShowNumber = false;
792                     aLabel.ShowNumberInPercent = false;
793                     aLabel.ShowCategoryName = false;
794                     aLabel.ShowLegendSymbol = false;
795                     if( aObjectType == OBJECTTYPE_DATA_LABELS )
796                     {
797                         uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( aCID, getModel() ));
798                         ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "Label" ), uno::makeAny(aLabel) );
799                     }
800                     else
801                         xObjectProperties->setPropertyValue( C2U( "Label" ), uno::makeAny(aLabel) );
802                     bReturn = true;
803                     aUndoGuard.commit();
804                 }
805                 break;
806             }
807             case OBJECTTYPE_AXIS:
808             {
809                 executeDispatch_DeleteAxis();
810                 bReturn = true;
811                 break;
812             }
813             case OBJECTTYPE_GRID:
814             {
815                 executeDispatch_DeleteMajorGrid();
816                 bReturn = true;
817                 break;
818             }
819             case OBJECTTYPE_SUBGRID:
820             {
821                 executeDispatch_DeleteMinorGrid();
822                 bReturn = true;
823                 break;
824             }
825 
826             default:
827             {
828                 break;
829             }
830         }
831     }
832     else
833     {
834         //remove additional shape
835         impl_ClearSelection();
836         {
837             ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
838             if ( m_pDrawViewWrapper )
839             {
840                 m_pDrawViewWrapper->DeleteMarked();
841                 bReturn = true;
842             }
843         }
844     }
845     return bReturn;
846 }
847 
executeDispatch_ToggleLegend()848 void ChartController::executeDispatch_ToggleLegend()
849 {
850     Reference< frame::XModel > xModel( getModel() );
851     UndoGuard aUndoGuard = UndoGuard(
852         String( SchResId( STR_ACTION_TOGGLE_LEGEND )), m_xUndoManager );
853     Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend( xModel ), uno::UNO_QUERY );
854     bool bChanged = false;
855     if( xLegendProp.is())
856     {
857         try
858         {
859             bool bShow = false;
860             if( xLegendProp->getPropertyValue( C2U("Show")) >>= bShow )
861             {
862                 xLegendProp->setPropertyValue( C2U("Show"), uno::makeAny( ! bShow ));
863                 bChanged = true;
864             }
865         }
866         catch( const uno::Exception & ex )
867         {
868             ASSERT_EXCEPTION( ex );
869         }
870     }
871     else
872     {
873         xLegendProp.set( LegendHelper::getLegend( xModel, m_xCC, true ), uno::UNO_QUERY );
874         if( xLegendProp.is())
875             bChanged = true;
876     }
877 
878     if( bChanged )
879         aUndoGuard.commit();
880 }
881 
executeDispatch_ToggleGridHorizontal()882 void ChartController::executeDispatch_ToggleGridHorizontal()
883 {
884     Reference< frame::XModel > xModel( getModel() );
885     UndoGuard aUndoGuard = UndoGuard(
886         String( SchResId( STR_ACTION_TOGGLE_GRID_HORZ )), m_xUndoManager );
887     Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( getModel() ));
888     if( xDiagram.is())
889     {
890         sal_Int32 nDimensionIndex = 1;
891         sal_Int32 nCooSysIndex = 0;
892         bool bIsMainGrid = true;
893 
894         bool bHasMainYGrid = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, bIsMainGrid, xDiagram );
895 
896         if( bHasMainYGrid )
897             AxisHelper::hideGrid( nDimensionIndex, nCooSysIndex, bIsMainGrid, xDiagram );
898         else
899             AxisHelper::showGrid( nDimensionIndex, nCooSysIndex, bIsMainGrid, xDiagram, m_xCC );
900 
901         aUndoGuard.commit();
902     }
903 }
904 
impl_ShapeControllerDispatch(const util::URL & rURL,const Sequence<beans::PropertyValue> & rArgs)905 void ChartController::impl_ShapeControllerDispatch( const util::URL& rURL, const Sequence< beans::PropertyValue >& rArgs )
906 {
907     Reference< frame::XDispatch > xDispatch( m_aDispatchContainer.getShapeController() );
908     if ( xDispatch.is() )
909     {
910         xDispatch->dispatch( rURL, rArgs );
911     }
912 }
913 
impl_switchDiagramPositioningToExcludingPositioning()914 void ChartController::impl_switchDiagramPositioningToExcludingPositioning()
915 {
916     UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
917         ActionDescriptionProvider::POS_SIZE,
918         ObjectNameProvider::getName( OBJECTTYPE_DIAGRAM)),
919         m_xUndoManager );
920     if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_aModel->getModel(), true, true ) )
921         aUndoGuard.commit();
922 }
923 
924 } //  namespace chart
925