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 "ElementSelector.hxx"
28 #include "macros.hxx"
29 #include "ObjectNameProvider.hxx"
30 #include "ObjectHierarchy.hxx"
31 #include "servicenames.hxx"
32 #include <chartview/ExplicitValueProvider.hxx>
33 #include "DrawViewWrapper.hxx"
34 #include "ResId.hxx"
35 #include "Strings.hrc"
36
37 #include <toolkit/helper/vclunohelper.hxx>
38 #include <vos/mutex.hxx>
39 #include <vcl/svapp.hxx>
40
41 #include <com/sun/star/chart2/XChartDocument.hpp>
42 #include <com/sun/star/frame/XControlNotificationListener.hpp>
43 #include <com/sun/star/util/XURLTransformer.hpp>
44 #include <com/sun/star/view/XSelectionSupplier.hpp>
45
46 namespace chart
47 {
48
49 using namespace com::sun::star;
50 using namespace com::sun::star::uno;
51 using ::com::sun::star::uno::Any;
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::uno::Sequence;
54
55 namespace
56 {
57 static const ::rtl::OUString lcl_aServiceName(
58 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ElementSelectorToolbarController" ));
59 }
60
61 //------------------------------------------------------------------------------
62
SelectorListBox(Window * pParent,WinBits nStyle)63 SelectorListBox::SelectorListBox( Window* pParent, WinBits nStyle )
64 : ListBox( pParent, nStyle )
65 , m_bReleaseFocus( true )
66 {
67 }
68
~SelectorListBox()69 SelectorListBox::~SelectorListBox()
70 {
71 }
72
lcl_addObjectsToList(const ObjectHierarchy & rHierarchy,const ObjectHierarchy::tOID & rParent,std::vector<ListBoxEntryData> & rEntries,const sal_Int32 nHierarchyDepth,const Reference<chart2::XChartDocument> & xChartDoc)73 void lcl_addObjectsToList( const ObjectHierarchy& rHierarchy, const ObjectHierarchy::tOID & rParent, std::vector< ListBoxEntryData >& rEntries
74 , const sal_Int32 nHierarchyDepth, const Reference< chart2::XChartDocument >& xChartDoc )
75 {
76 ObjectHierarchy::tChildContainer aChildren( rHierarchy.getChildren(rParent) );
77 ObjectHierarchy::tChildContainer::const_iterator aIt( aChildren.begin());
78 while( aIt != aChildren.end() )
79 {
80 ObjectHierarchy::tOID aOID = *aIt;
81 ::rtl::OUString aCID = aOID.getObjectCID();
82 ListBoxEntryData aEntry;
83 aEntry.OID = aOID;
84 aEntry.UIName += ObjectNameProvider::getNameForCID( aCID, xChartDoc );
85 aEntry.nHierarchyDepth = nHierarchyDepth;
86 rEntries.push_back(aEntry);
87 lcl_addObjectsToList( rHierarchy, aOID, rEntries, nHierarchyDepth+1, xChartDoc );
88 ++aIt;
89 }
90 }
91
SetChartController(const Reference<frame::XController> & xChartController)92 void SelectorListBox::SetChartController( const Reference< frame::XController >& xChartController )
93 {
94 m_xChartController = xChartController;
95 }
96
UpdateChartElementsListAndSelection()97 void SelectorListBox::UpdateChartElementsListAndSelection()
98 {
99 Clear();
100 m_aEntries.clear();
101
102 Reference< frame::XController > xChartController( m_xChartController );
103 if( xChartController.is() )
104 {
105 Reference< view::XSelectionSupplier > xSelectionSupplier( xChartController, uno::UNO_QUERY);
106 ObjectHierarchy::tOID aSelectedOID;
107 rtl::OUString aSelectedCID;
108 if( xSelectionSupplier.is() )
109 {
110 aSelectedOID = ObjectIdentifier( xSelectionSupplier->getSelection() );
111 aSelectedCID = aSelectedOID.getObjectCID();
112 }
113
114 Reference< chart2::XChartDocument > xChartDoc( xChartController->getModel(), uno::UNO_QUERY );
115 ObjectType eType( aSelectedOID.getObjectType() );
116 bool bAddSelectionToList = false;
117 if ( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL || eType == OBJECTTYPE_SHAPE )
118 bAddSelectionToList = true;
119
120 Reference< uno::XInterface > xChartView;
121 Reference< lang::XMultiServiceFactory > xFact( xChartController->getModel(), uno::UNO_QUERY );
122 if( xFact.is() )
123 xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME );
124 ExplicitValueProvider* pExplicitValueProvider = 0;//ExplicitValueProvider::getExplicitValueProvider(xChartView); dies erzeugt alle sichtbaren datenpinkte, das ist zu viel
125 ObjectHierarchy aHierarchy( xChartDoc, pExplicitValueProvider, true /*bFlattenDiagram*/, true /*bOrderingForElementSelector*/ );
126 lcl_addObjectsToList( aHierarchy, aHierarchy.getRootNodeOID(), m_aEntries, 0, xChartDoc );
127
128 std::vector< ListBoxEntryData >::iterator aIt( m_aEntries.begin() );
129 if( bAddSelectionToList )
130 {
131 if ( aSelectedOID.isAutoGeneratedObject() )
132 {
133 rtl::OUString aSeriesCID = ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::getSeriesParticleFromCID( aSelectedCID ) );
134 for( aIt = m_aEntries.begin(); aIt != m_aEntries.end(); ++aIt )
135 {
136 if( aIt->OID.getObjectCID().match( aSeriesCID ) )
137 {
138 ListBoxEntryData aEntry;
139 aEntry.UIName = ObjectNameProvider::getNameForCID( aSelectedCID, xChartDoc );
140 aEntry.OID = aSelectedOID;
141 ++aIt;
142 if( aIt != m_aEntries.end() )
143 m_aEntries.insert(aIt, aEntry);
144 else
145 m_aEntries.push_back( aEntry );
146 break;
147 }
148 }
149 }
150 else if ( aSelectedOID.isAdditionalShape() )
151 {
152 ListBoxEntryData aEntry;
153 SdrObject* pSelectedObj = DrawViewWrapper::getSdrObject( aSelectedOID.getAdditionalShape() );
154 ::rtl::OUString aName( pSelectedObj ? pSelectedObj->GetName() : String() );
155 aEntry.UIName = ( !aName.isEmpty() ? aName : ::rtl::OUString( String( SchResId( STR_OBJECT_SHAPE ) ) ) );
156 aEntry.OID = aSelectedOID;
157 m_aEntries.push_back( aEntry );
158 }
159 }
160
161 sal_uInt16 nEntryPosToSelect = 0; bool bSelectionFound = false;
162 aIt = m_aEntries.begin();
163 for( sal_uInt16 nN=0; aIt != m_aEntries.end(); ++aIt, ++nN )
164 {
165 InsertEntry( aIt->UIName );
166 if ( !bSelectionFound && aSelectedOID == aIt->OID )
167 {
168 nEntryPosToSelect = nN;
169 bSelectionFound = true;
170 }
171 }
172
173 if( bSelectionFound )
174 SelectEntryPos(nEntryPosToSelect);
175
176 sal_uInt16 nEntryCount = GetEntryCount();
177 if( nEntryCount > 100 )
178 nEntryCount = 100;
179 SetDropDownLineCount( nEntryCount );
180 }
181 SaveValue();//remind current selection pos
182 }
183
ReleaseFocus_Impl()184 void SelectorListBox::ReleaseFocus_Impl()
185 {
186 if ( !m_bReleaseFocus )
187 {
188 m_bReleaseFocus = true;
189 return;
190 }
191
192 Reference< frame::XController > xController( m_xChartController );
193 Reference< frame::XFrame > xFrame( xController->getFrame() );
194 if ( xFrame.is() && xFrame->getContainerWindow().is() )
195 xFrame->getContainerWindow()->setFocus();
196 }
197
Select()198 void SelectorListBox::Select()
199 {
200 ListBox::Select();
201
202 if ( !IsTravelSelect() )
203 {
204 sal_uInt16 nPos = GetSelectEntryPos();
205 if( nPos < m_aEntries.size() )
206 {
207 ObjectHierarchy::tOID aOID = m_aEntries[nPos].OID;
208 Reference< view::XSelectionSupplier > xSelectionSupplier( m_xChartController.get(), uno::UNO_QUERY );
209 if( xSelectionSupplier.is() )
210 xSelectionSupplier->select( aOID.getAny() );
211 }
212 ReleaseFocus_Impl();
213 }
214 }
215
Notify(NotifyEvent & rNEvt)216 long SelectorListBox::Notify( NotifyEvent& rNEvt )
217 {
218 long nHandled = 0;
219
220 if ( rNEvt.GetType() == EVENT_KEYINPUT )
221 {
222 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
223
224 switch ( nCode )
225 {
226 case KEY_RETURN:
227 case KEY_TAB:
228 {
229 if ( KEY_TAB == nCode )
230 m_bReleaseFocus = false;
231 else
232 nHandled = 1;
233 Select();
234 break;
235 }
236
237 case KEY_ESCAPE:
238 SelectEntryPos( GetSavedValue() ); //restore saved selection
239 ReleaseFocus_Impl();
240 break;
241 }
242 }
243 else if ( EVENT_LOSEFOCUS == rNEvt.GetType() )
244 {
245 if ( !HasFocus() )
246 SelectEntryPos( GetSavedValue() );
247 }
248
249 return nHandled ? nHandled : ListBox::Notify( rNEvt );
250 }
251
CreateAccessible()252 Reference< ::com::sun::star::accessibility::XAccessible > SelectorListBox::CreateAccessible()
253 {
254 UpdateChartElementsListAndSelection();
255 return ListBox::CreateAccessible();
256 }
257
258 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
259 APPHELPER_XSERVICEINFO_IMPL( ElementSelectorToolbarController, lcl_aServiceName );
260
261 //------------------------------------------------------------------------------
getSupportedServiceNames_Static()262 Sequence< ::rtl::OUString > ElementSelectorToolbarController::getSupportedServiceNames_Static()
263 {
264 Sequence< ::rtl::OUString > aServices(1);
265 aServices[ 0 ] = C2U( "com.sun.star.frame.ToolbarController" );
266 return aServices;
267 }
268 // -----------------------------------------------------------------------------
ElementSelectorToolbarController(const uno::Reference<uno::XComponentContext> & xContext)269 ElementSelectorToolbarController::ElementSelectorToolbarController( const uno::Reference< uno::XComponentContext > & xContext )
270 : m_xCC( xContext )
271 {
272 }
273 // -----------------------------------------------------------------------------
~ElementSelectorToolbarController()274 ElementSelectorToolbarController::~ElementSelectorToolbarController()
275 {
276 }
277 // -----------------------------------------------------------------------------
278 // XInterface
queryInterface(const Type & _rType)279 Any SAL_CALL ElementSelectorToolbarController::queryInterface( const Type& _rType ) throw (RuntimeException)
280 {
281 Any aReturn = ToolboxController::queryInterface(_rType);
282 if (!aReturn.hasValue())
283 aReturn = ElementSelectorToolbarController_BASE::queryInterface(_rType);
284 return aReturn;
285 }
286 // -----------------------------------------------------------------------------
acquire()287 void SAL_CALL ElementSelectorToolbarController::acquire() throw ()
288 {
289 ToolboxController::acquire();
290 }
291 // -----------------------------------------------------------------------------
release()292 void SAL_CALL ElementSelectorToolbarController::release() throw ()
293 {
294 ToolboxController::release();
295 }
296 // -----------------------------------------------------------------------------
initialize(const Sequence<Any> & rArguments)297 void SAL_CALL ElementSelectorToolbarController::initialize( const Sequence< Any >& rArguments ) throw (Exception, RuntimeException)
298 {
299 ToolboxController::initialize(rArguments);
300 }
301 // -----------------------------------------------------------------------------
statusChanged(const frame::FeatureStateEvent & rEvent)302 void SAL_CALL ElementSelectorToolbarController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException )
303 {
304 if( m_apSelectorListBox.get() )
305 {
306 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
307 if( rEvent.FeatureURL.Path.equalsAscii( "ChartElementSelector" ) )
308 {
309 Reference< frame::XController > xChartController;
310 rEvent.State >>= xChartController;
311 m_apSelectorListBox->SetChartController( xChartController );
312 m_apSelectorListBox->UpdateChartElementsListAndSelection();
313 }
314 }
315 }
316 // -----------------------------------------------------------------------------
createItemWindow(const uno::Reference<awt::XWindow> & xParent)317 uno::Reference< awt::XWindow > SAL_CALL ElementSelectorToolbarController::createItemWindow( const uno::Reference< awt::XWindow >& xParent )
318 throw (uno::RuntimeException)
319 {
320 uno::Reference< awt::XWindow > xItemWindow;
321 if( !m_apSelectorListBox.get() )
322 {
323 Window* pParent = VCLUnoHelper::GetWindow( xParent );
324 if( pParent )
325 {
326 m_apSelectorListBox = ::std::auto_ptr< SelectorListBox >( new SelectorListBox( pParent, WB_DROPDOWN|WB_AUTOHSCROLL|WB_BORDER ) );
327 ::Size aLogicalSize( 95, 160 );
328 ::Size aPixelSize = m_apSelectorListBox->LogicToPixel( aLogicalSize, MAP_APPFONT );
329 m_apSelectorListBox->SetSizePixel( aPixelSize );
330 m_apSelectorListBox->SetDropDownLineCount( 5 );
331 }
332 }
333 if( m_apSelectorListBox.get() )
334 xItemWindow = VCLUnoHelper::GetInterface( m_apSelectorListBox.get() );
335 return xItemWindow;
336 }
337
338 //..........................................................................
339 } // chart2
340 //..........................................................................
341