1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ElementSelector.hxx"
21 #include <ObjectNameProvider.hxx>
22 #include <ObjectHierarchy.hxx>
23 #include <servicenames.hxx>
24 #include <DrawViewWrapper.hxx>
26 #include <strings.hrc>
27 #include <ObjectIdentifier.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <toolkit/helper/vclunohelper.hxx>
31 #include <vcl/svapp.hxx>
33 #include <com/sun/star/chart2/XChartDocument.hpp>
34 #include <com/sun/star/view/XSelectionSupplier.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 namespace chart
{ class ExplicitValueProvider
; }
42 using namespace com::sun::star
;
43 using namespace com::sun::star::uno
;
44 using ::com::sun::star::uno::Any
;
45 using ::com::sun::star::uno::Reference
;
46 using ::com::sun::star::uno::Sequence
;
50 static const char lcl_aServiceName
[] = "com.sun.star.comp.chart.ElementSelectorToolbarController";
53 SelectorListBox::SelectorListBox( vcl::Window
* pParent
, WinBits nStyle
)
54 : ListBox( pParent
, nStyle
)
55 , m_bReleaseFocus( true )
59 static void lcl_addObjectsToList( const ObjectHierarchy
& rHierarchy
, const ObjectIdentifier
& rParent
, std::vector
< ListBoxEntryData
>& rEntries
60 , const sal_Int32 nHierarchyDepth
, const Reference
< chart2::XChartDocument
>& xChartDoc
)
62 ObjectHierarchy::tChildContainer
aChildren( rHierarchy
.getChildren(rParent
) );
63 for (auto const& child
: aChildren
)
65 ListBoxEntryData aEntry
;
67 aEntry
.UIName
= ObjectNameProvider::getNameForCID( child
.getObjectCID(), xChartDoc
);
68 aEntry
.nHierarchyDepth
= nHierarchyDepth
;
69 rEntries
.push_back(aEntry
);
70 lcl_addObjectsToList( rHierarchy
, child
, rEntries
, nHierarchyDepth
+1, xChartDoc
);
74 void SelectorListBox::SetChartController( const Reference
< frame::XController
>& xChartController
)
76 m_xChartController
= xChartController
;
79 void SelectorListBox::UpdateChartElementsListAndSelection()
84 Reference
< frame::XController
> xChartController( m_xChartController
);
85 if( xChartController
.is() )
87 Reference
< view::XSelectionSupplier
> xSelectionSupplier( xChartController
, uno::UNO_QUERY
);
88 ObjectIdentifier aSelectedOID
;
89 OUString aSelectedCID
;
90 if( xSelectionSupplier
.is() )
92 aSelectedOID
= ObjectIdentifier( xSelectionSupplier
->getSelection() );
93 aSelectedCID
= aSelectedOID
.getObjectCID();
96 Reference
< chart2::XChartDocument
> xChartDoc( xChartController
->getModel(), uno::UNO_QUERY
);
97 ObjectType
eType( aSelectedOID
.getObjectType() );
98 bool bAddSelectionToList
= false;
99 if ( eType
== OBJECTTYPE_DATA_POINT
|| eType
== OBJECTTYPE_DATA_LABEL
|| eType
== OBJECTTYPE_SHAPE
)
100 bAddSelectionToList
= true;
102 Reference
< uno::XInterface
> xChartView
;
103 Reference
< lang::XMultiServiceFactory
> xFact( xChartController
->getModel(), uno::UNO_QUERY
);
105 xChartView
= xFact
->createInstance( CHART_VIEW_SERVICE_NAME
);
106 ExplicitValueProvider
* pExplicitValueProvider
= nullptr; //ExplicitValueProvider::getExplicitValueProvider(xChartView); this creates all visible data points, that's too much
107 ObjectHierarchy
aHierarchy( xChartDoc
, pExplicitValueProvider
, true /*bFlattenDiagram*/, true /*bOrderingForElementSelector*/ );
108 lcl_addObjectsToList( aHierarchy
, ::chart::ObjectHierarchy::getRootNodeOID(), m_aEntries
, 0, xChartDoc
);
110 if( bAddSelectionToList
)
112 if ( aSelectedOID
.isAutoGeneratedObject() )
114 OUString aSeriesCID
= ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::getSeriesParticleFromCID( aSelectedCID
) );
115 std::vector
< ListBoxEntryData
>::iterator aIt
= std::find_if(m_aEntries
.begin(), m_aEntries
.end(),
116 [&aSeriesCID
](const ListBoxEntryData
& rEntry
) { return rEntry
.OID
.getObjectCID().match(aSeriesCID
); });
117 if (aIt
!= m_aEntries
.end())
119 ListBoxEntryData aEntry
;
120 aEntry
.UIName
= ObjectNameProvider::getNameForCID( aSelectedCID
, xChartDoc
);
121 aEntry
.OID
= aSelectedOID
;
123 if( aIt
!= m_aEntries
.end() )
124 m_aEntries
.insert(aIt
, aEntry
);
126 m_aEntries
.push_back( aEntry
);
129 else if ( aSelectedOID
.isAdditionalShape() )
131 ListBoxEntryData aEntry
;
132 SdrObject
* pSelectedObj
= DrawViewWrapper::getSdrObject( aSelectedOID
.getAdditionalShape() );
133 OUString aName
= pSelectedObj
? pSelectedObj
->GetName() : OUString();
134 aEntry
.UIName
= ( aName
.isEmpty() ? SchResId( STR_OBJECT_SHAPE
) : aName
);
135 aEntry
.OID
= aSelectedOID
;
136 m_aEntries
.push_back( aEntry
);
140 sal_uInt16 nEntryPosToSelect
= 0; bool bSelectionFound
= false;
142 for (auto const& entry
: m_aEntries
)
144 InsertEntry(entry
.UIName
);
145 if ( !bSelectionFound
&& aSelectedOID
== entry
.OID
)
147 nEntryPosToSelect
= nN
;
148 bSelectionFound
= true;
153 if( bSelectionFound
)
154 SelectEntryPos(nEntryPosToSelect
);
156 sal_Int32 nEntryCount
= GetEntryCount();
157 if( nEntryCount
> 100 )
159 SetDropDownLineCount( nEntryCount
);
161 SaveValue(); //remind current selection pos
164 void SelectorListBox::ReleaseFocus_Impl()
166 if ( !m_bReleaseFocus
)
168 m_bReleaseFocus
= true;
172 Reference
< frame::XController
> xController( m_xChartController
);
173 Reference
< frame::XFrame
> xFrame( xController
->getFrame() );
174 if ( xFrame
.is() && xFrame
->getContainerWindow().is() )
175 xFrame
->getContainerWindow()->setFocus();
178 void SelectorListBox::Select()
182 if ( !IsTravelSelect() )
184 const sal_Int32 nPos
= GetSelectedEntryPos();
185 if( static_cast<size_t>(nPos
) < m_aEntries
.size() )
187 ObjectIdentifier aOID
= m_aEntries
[nPos
].OID
;
188 Reference
< view::XSelectionSupplier
> xSelectionSupplier( m_xChartController
.get(), uno::UNO_QUERY
);
189 if( xSelectionSupplier
.is() )
190 xSelectionSupplier
->select( aOID
.getAny() );
196 bool SelectorListBox::EventNotify( NotifyEvent
& rNEvt
)
198 bool bHandled
= false;
200 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
202 sal_uInt16 nCode
= rNEvt
.GetKeyEvent()->GetKeyCode().GetCode();
209 if ( nCode
== KEY_TAB
)
210 m_bReleaseFocus
= false;
218 SelectEntryPos( GetSavedValue() ); //restore saved selection
223 else if ( rNEvt
.GetType() == MouseNotifyEvent::LOSEFOCUS
)
226 SelectEntryPos( GetSavedValue() );
229 return bHandled
|| ListBox::EventNotify(rNEvt
);
232 Reference
< css::accessibility::XAccessible
> SelectorListBox::CreateAccessible()
234 UpdateChartElementsListAndSelection();
235 return ListBox::CreateAccessible();
238 OUString SAL_CALL
ElementSelectorToolbarController::getImplementationName()
240 return lcl_aServiceName
;
243 sal_Bool SAL_CALL
ElementSelectorToolbarController::supportsService( const OUString
& rServiceName
)
245 return cppu::supportsService(this, rServiceName
);
248 css::uno::Sequence
< OUString
> SAL_CALL
ElementSelectorToolbarController::getSupportedServiceNames()
250 return { "com.sun.star.frame.ToolbarController" };
252 ElementSelectorToolbarController::ElementSelectorToolbarController()
255 ElementSelectorToolbarController::~ElementSelectorToolbarController()
259 Any SAL_CALL
ElementSelectorToolbarController::queryInterface( const Type
& _rType
)
261 Any aReturn
= ToolboxController::queryInterface(_rType
);
262 if (!aReturn
.hasValue())
263 aReturn
= ElementSelectorToolbarController_BASE::queryInterface(_rType
);
266 void SAL_CALL
ElementSelectorToolbarController::acquire() throw ()
268 ToolboxController::acquire();
270 void SAL_CALL
ElementSelectorToolbarController::release() throw ()
272 ToolboxController::release();
274 void SAL_CALL
ElementSelectorToolbarController::statusChanged( const frame::FeatureStateEvent
& rEvent
)
276 if( m_apSelectorListBox
.get() )
278 SolarMutexGuard aSolarMutexGuard
;
279 if ( rEvent
.FeatureURL
.Path
== "ChartElementSelector" )
281 Reference
< frame::XController
> xChartController
;
282 rEvent
.State
>>= xChartController
;
283 m_apSelectorListBox
->SetChartController( xChartController
);
284 m_apSelectorListBox
->UpdateChartElementsListAndSelection();
288 uno::Reference
< awt::XWindow
> SAL_CALL
ElementSelectorToolbarController::createItemWindow( const uno::Reference
< awt::XWindow
>& xParent
)
290 uno::Reference
< awt::XWindow
> xItemWindow
;
291 if( !m_apSelectorListBox
.get() )
293 VclPtr
<vcl::Window
> pParent
= VCLUnoHelper::GetWindow( xParent
);
296 m_apSelectorListBox
.reset( VclPtr
<SelectorListBox
>::Create( pParent
, WB_DROPDOWN
|WB_AUTOHSCROLL
|WB_BORDER
) );
297 ::Size
aLogicalSize( 75, 160 );
298 ::Size aPixelSize
= m_apSelectorListBox
->LogicToPixel(aLogicalSize
, MapMode(MapUnit::MapAppFont
));
299 m_apSelectorListBox
->SetSizePixel( aPixelSize
);
300 m_apSelectorListBox
->SetDropDownLineCount( 5 );
303 if( m_apSelectorListBox
.get() )
304 xItemWindow
= VCLUnoHelper::GetInterface( m_apSelectorListBox
.get() );
310 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
311 com_sun_star_comp_chart_ElementSelectorToolbarController_get_implementation(css::uno::XComponentContext
*,
312 css::uno::Sequence
<css::uno::Any
> const &)
314 return cppu::acquire(new chart::ElementSelectorToolbarController
);
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */