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