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 "CommandDispatchContainer.hxx"
28 #include "UndoCommandDispatch.hxx"
29 #include "StatusBarCommandDispatch.hxx"
30 #include "DisposeHelper.hxx"
31 #include "macros.hxx"
32 #include "ChartController.hxx"
33 #include "DrawCommandDispatch.hxx"
34 #include "ShapeController.hxx"
35 
36 #include <comphelper/InlineContainer.hxx>
37 
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 
40 using namespace ::com::sun::star;
41 
42 using ::com::sun::star::uno::Reference;
43 using ::com::sun::star::uno::Sequence;
44 using ::rtl::OUString;
45 
46 namespace chart
47 {
48 
CommandDispatchContainer(const Reference<uno::XComponentContext> & xContext,ChartController * pController)49 CommandDispatchContainer::CommandDispatchContainer(
50     const Reference< uno::XComponentContext > & xContext, ChartController* pController )
51         :m_xContext( xContext )
52         ,m_pChartController( pController )
53         ,m_pDrawCommandDispatch( NULL )
54         ,m_pShapeController( NULL )
55 {
56     m_aContainerDocumentCommands =
57         ::comphelper::MakeSet< OUString >
58         ( C2U("AddDirect"))    ( C2U("NewDoc"))             ( C2U("Open"))
59         ( C2U("Save"))         ( C2U("SaveAs"))             ( C2U("SendMail"))
60         ( C2U("EditDoc"))      ( C2U("ExportDirectToPDF"))  ( C2U("PrintDefault"))
61         ;
62 }
63 
setModel(const Reference<frame::XModel> & xModel)64 void CommandDispatchContainer::setModel(
65     const Reference< frame::XModel > & xModel )
66 {
67     // remove all existing dispatcher that base on the old model
68     m_aCachedDispatches.clear();
69     DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches );
70     m_aToBeDisposedDispatches.clear();
71     m_xModel = xModel;
72 }
73 
setChartDispatch(const Reference<frame::XDispatch> xChartDispatch,const::std::set<OUString> & rChartCommands)74 void CommandDispatchContainer::setChartDispatch(
75     const Reference< frame::XDispatch > xChartDispatch,
76     const ::std::set< OUString > & rChartCommands )
77 {
78     OSL_ENSURE(xChartDispatch.is(),"Invalid fall back dispatcher!");
79     m_xChartDispatcher.set( xChartDispatch );
80     m_aChartCommands = rChartCommands;
81     m_aToBeDisposedDispatches.push_back( m_xChartDispatcher );
82 }
83 
getDispatchForURL(const util::URL & rURL)84 Reference< frame::XDispatch > CommandDispatchContainer::getDispatchForURL(
85     const util::URL & rURL )
86 {
87     Reference< frame::XDispatch > xResult;
88     tDispatchMap::const_iterator aIt( m_aCachedDispatches.find( rURL.Complete ));
89     if( aIt != m_aCachedDispatches.end())
90     {
91         xResult.set( (*aIt).second );
92     }
93     else
94     {
95         uno::Reference< frame::XModel > xModel( m_xModel );
96 
97         if( xModel.is() && (rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Undo" ))
98             || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Redo" ))) )
99         {
100             CommandDispatch * pDispatch = new UndoCommandDispatch( m_xContext, xModel );
101             xResult.set( pDispatch );
102             pDispatch->initialize();
103             m_aCachedDispatches[ C2U(".uno:Undo") ].set( xResult );
104             m_aCachedDispatches[ C2U(".uno:Redo") ].set( xResult );
105             m_aToBeDisposedDispatches.push_back( xResult );
106         }
107         else if( xModel.is() && (rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Context" ))
108                  || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ModifiedStatus" ))) )
109         {
110             Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY );
111             CommandDispatch * pDispatch = new StatusBarCommandDispatch( m_xContext, xModel, xSelSupp );
112             xResult.set( pDispatch );
113             pDispatch->initialize();
114             m_aCachedDispatches[ C2U(".uno:Context") ].set( xResult );
115             m_aCachedDispatches[ C2U(".uno:ModifiedStatus") ].set( xResult );
116             m_aToBeDisposedDispatches.push_back( xResult );
117         }
118         else if( xModel.is() &&
119                  (m_aContainerDocumentCommands.find( rURL.Path ) != m_aContainerDocumentCommands.end()) )
120         {
121             xResult.set( getContainerDispatchForURL( xModel->getCurrentController(), rURL ));
122             // ToDo: can those dispatches be cached?
123             m_aCachedDispatches[ rURL.Complete ].set( xResult );
124         }
125         else if( m_xChartDispatcher.is() &&
126                  (m_aChartCommands.find( rURL.Path ) != m_aChartCommands.end()) )
127         {
128             xResult.set( m_xChartDispatcher );
129             m_aCachedDispatches[ rURL.Complete ].set( xResult );
130         }
131         // #i12587# support for shapes in chart
132         // Note, that the chart dispatcher must be queried first, because
133         // the chart dispatcher is the default dispatcher for all context
134         // sensitive commands.
135         else if ( m_pDrawCommandDispatch && m_pDrawCommandDispatch->isFeatureSupported( rURL.Complete ) )
136         {
137             xResult.set( m_pDrawCommandDispatch );
138             m_aCachedDispatches[ rURL.Complete ].set( xResult );
139         }
140         else if ( m_pShapeController && m_pShapeController->isFeatureSupported( rURL.Complete ) )
141         {
142             xResult.set( m_pShapeController );
143             m_aCachedDispatches[ rURL.Complete ].set( xResult );
144         }
145     }
146 
147     return xResult;
148 }
149 
getDispatchesForURLs(const Sequence<frame::DispatchDescriptor> & aDescriptors)150 Sequence< Reference< frame::XDispatch > > CommandDispatchContainer::getDispatchesForURLs(
151     const Sequence< frame::DispatchDescriptor > & aDescriptors )
152 {
153 	sal_Int32 nCount = aDescriptors.getLength();
154 	uno::Sequence< uno::Reference< frame::XDispatch > > aRet( nCount );
155 
156 	for( sal_Int32 nPos = 0; nPos < nCount; ++nPos )
157 	{
158         if( aDescriptors[ nPos ].FrameName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_self")))
159             aRet[ nPos ] = getDispatchForURL( aDescriptors[ nPos ].FeatureURL );
160 	}
161 	return aRet;
162 }
163 
DisposeAndClear()164 void CommandDispatchContainer::DisposeAndClear()
165 {
166     m_aCachedDispatches.clear();
167     DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches );
168     m_aToBeDisposedDispatches.clear();
169     m_xChartDispatcher.clear();
170     m_aChartCommands.clear();
171     m_pChartController = NULL;
172     m_pDrawCommandDispatch = NULL;
173     m_pShapeController = NULL;
174 }
175 
getContainerDispatchForURL(const Reference<frame::XController> & xChartController,const util::URL & rURL)176 Reference< frame::XDispatch > CommandDispatchContainer::getContainerDispatchForURL(
177     const Reference< frame::XController > & xChartController,
178     const util::URL & rURL )
179 {
180     Reference< frame::XDispatch > xResult;
181     if( xChartController.is())
182     {
183         Reference< frame::XFrame > xFrame( xChartController->getFrame());
184         if( xFrame.is())
185         {
186             Reference< frame::XDispatchProvider > xDispProv( xFrame->getCreator(), uno::UNO_QUERY );
187             if( xDispProv.is())
188                 xResult.set( xDispProv->queryDispatch( rURL, C2U("_self"), 0 ));
189         }
190     }
191     return xResult;
192 }
193 
setDrawCommandDispatch(DrawCommandDispatch * pDispatch)194 void CommandDispatchContainer::setDrawCommandDispatch( DrawCommandDispatch* pDispatch )
195 {
196     m_pDrawCommandDispatch = pDispatch;
197     m_aToBeDisposedDispatches.push_back( Reference< frame::XDispatch >( pDispatch ) );
198 }
199 
setShapeController(ShapeController * pController)200 void CommandDispatchContainer::setShapeController( ShapeController* pController )
201 {
202     m_pShapeController = pController;
203     m_aToBeDisposedDispatches.push_back( Reference< frame::XDispatch >( pController ) );
204 }
205 
206 } //  namespace chart
207