LibreOffice Module sc (master) 1
xltoolbar.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 */
9#include "xltoolbar.hxx"
10#include <sal/log.hxx>
11#include <o3tl/safeint.hxx>
12#include <com/sun/star/beans/XPropertySet.hpp>
13#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
14#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
15#include <com/sun/star/ui/ItemType.hpp>
20#include <rtl/ref.hxx>
21#include <map>
22
23using namespace com::sun::star;
24
25typedef std::map< sal_Int16, OUString > IdToString;
26
27namespace {
28
29class MSOExcelCommandConvertor : public MSOCommandConvertor
30{
31 IdToString msoToOOcmd;
32 IdToString tcidToOOcmd;
33public:
34 MSOExcelCommandConvertor();
35 virtual OUString MSOCommandToOOCommand( sal_Int16 msoCmd ) override;
36 virtual OUString MSOTCIDToOOCommand( sal_Int16 key ) override;
37};
38
39}
40
41MSOExcelCommandConvertor::MSOExcelCommandConvertor()
42{
43/*
44 // mso command id to ooo command string
45 // #FIXME and *HUNDREDS* of id's to added here
46 msoToOOcmd[ 0x20b ] = ".uno:CloseDoc";
47 msoToOOcmd[ 0x50 ] = ".uno:Open";
48
49 // mso tcid to ooo command string
50 // #FIXME and *HUNDREDS* of id's to added here
51 tcidToOOcmd[ 0x9d9 ] = ".uno:Print";
52*/
53}
54
55OUString MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
56{
57 OUString sResult;
58 IdToString::iterator it = msoToOOcmd.find( key );
59 if ( it != msoToOOcmd.end() )
60 sResult = it->second;
61 return sResult;
62}
63
64OUString MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
65{
66 OUString sResult;
67 IdToString::iterator it = tcidToOOcmd.find( key );
68 if ( it != tcidToOOcmd.end() )
69 sResult = it->second;
70 return sResult;
71}
72
73CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
74{
75}
76
77ScCTB::ScCTB(sal_uInt16 nNum ) : nViews( nNum ), ectbid(0)
78{
79}
80
82{
83 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
84 nOffSet = rS.Tell();
85 tb.Read( rS );
86
87 {
88 const size_t nMinRecordSize = 20; // TBVisualData reads 20 bytes
89 const size_t nMaxPossibleRecords = rS.remainingSize() / nMinRecordSize;
90 if (nViews > nMaxPossibleRecords)
91 {
92 SAL_WARN("sc.filter", "ScCTB::Read more entries claimed than stream could contain");
93 return false;
94 }
95 }
96
97 for ( sal_uInt16 index = 0; index < nViews; ++index )
98 {
99 TBVisualData aVisData;
100 aVisData.Read( rS );
101 rVisualData.push_back( aVisData );
102 }
103 rS.ReadUInt32( ectbid );
104
105 sal_Int16 nCL = tb.getcCL();
106 if (nCL > 0)
107 {
108 auto nIndexes = o3tl::make_unsigned(nCL);
109
110 const size_t nMinRecordSize = 11; // ScTBC's TBCHeader reads min 11 bytes
111 const size_t nMaxPossibleRecords = rS.remainingSize() / nMinRecordSize;
112 if (nIndexes > nMaxPossibleRecords)
113 {
114 SAL_WARN("sc.filter", "ScCTB::Read more entries claimed than stream could contain");
115 return false;
116 }
117
118 for (decltype(nIndexes) index = 0; index < nIndexes; ++index)
119 {
120 ScTBC aTBC;
121 aTBC.Read( rS );
122 rTBC.push_back( aTBC );
123 }
124 }
125
126 return true;
127}
128
129#ifdef DEBUG_SC_EXCEL
130void ScCTB::Print( FILE* fp )
131{
132 Indent a;
133 indent_printf( fp, "[ 0x%x ] ScCTB -- dump\n", nOffSet );
134 indent_printf( fp, " nViews 0x%x\n", nViews);
135 tb.Print( fp );
136
137 sal_Int32 counter = 0;
138 for ( auto& rItem : rVisualData )
139 {
140 indent_printf( fp, " TBVisualData [%d]\n", counter++ );
141 Indent b;
142 rItem.Print( fp );
143 }
144 indent_printf( fp, " ectbid 0x%x\n", ectbid);
145 counter = 0;
146 for ( auto& rItem : rTBC )
147 {
148 indent_printf( fp, " ScTBC [%d]\n", counter++);
149 Indent c;
150 rItem.Print( fp );
151 }
152}
153#endif
154
156{
157 return tb.IsMenuToolbar();
158}
159
160bool ScCTB::ImportMenuTB( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xMenuDesc, CustomToolBarImportHelper& helper )
161{
162 for ( auto& rItem : rTBC )
163 {
164 if ( !rItem.ImportToolBarControl( rWrapper, xMenuDesc, helper, IsMenuToolbar() ) )
165 return false;
166 }
167 return true;
168}
169
171{
172
173 bool bRes = false;
174 try
175 {
176 if ( !tb.IsEnabled() )
177 return true; // didn't fail, just ignoring
178
179 // Create default setting
180 uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_SET_THROW );
181 uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
182 uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
183 WString& name = tb.getName();
184 // set UI name for toolbar
185 xProps->setPropertyValue("UIName", uno::Any( name.getString() ) );
186
187 OUString sToolBarName = "private:resource/toolbar/custom_" + name.getString();
188 for ( auto& rItem : rTBC )
189 {
190 if ( !rItem.ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
191 return false;
192 }
193
194 helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
195 helper.applyIcons();
196
197 uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
198 xPersistence->store();
199
200 xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
201 xPersistence->store();
202
203 bRes = true;
204 }
205 catch( uno::Exception& )
206 {
207 bRes = false;
208 }
209 return bRes;
210}
212{
213 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
214 nOffSet = rS.Tell();
216 return true;
217}
218
219#ifdef DEBUG_SC_EXCEL
220void CTBS::Print( FILE* fp )
221{
222 Indent a;
223 indent_printf( fp, "[ 0x%x ] CTBS -- dump\n", nOffSet );
224
225 indent_printf( fp, " bSignature 0x%x\n", bSignature);
226 indent_printf( fp, " bVersion 0x%x\n", bVersion);
227
228 indent_printf( fp, " reserved1 0x%x\n", reserved1 );
229 indent_printf( fp, " reserved2 0x%x\n", reserved2 );
230 indent_printf( fp, " reserved3 0x%x\n", reserved3 );
231
232 indent_printf( fp, " ctb 0x%x\n", ctb );
233 indent_printf( fp, " ctbViews 0x%x\n", ctbViews );
234 indent_printf( fp, " ictbView 0x%x\n", ictbView );
235}
236#endif
237
239{
240}
241
242bool
244{
245 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
246 nOffSet = rS.Tell();
247 if ( !tbch.Read( rS ) )
248 return false;
249 sal_uInt16 tcid = tbch.getTcID();
250 sal_uInt8 tct = tbch.getTct();
251 if ( ( tcid != 0x0001 && tcid != 0x06CC && tcid != 0x03D8 && tcid != 0x03EC && tcid != 0x1051 ) && ( ( tct > 0 && tct < 0x0B ) || ( ( tct > 0x0B && tct < 0x10 ) || tct == 0x15 ) ) )
252 {
253 tbcCmd = std::make_shared<TBCCmd>();
254 if ( ! tbcCmd->Read( rS ) )
255 return false;
256 }
257 if ( tct != 0x16 )
258 {
259 tbcd = std::make_shared<TBCData>( tbch );
260 if ( !tbcd->Read( rS ) )
261 return false;
262 }
263 return true;
264}
265
266#ifdef DEBUG_SC_EXCEL
267void
268ScTBC::Print(FILE* fp)
269{
270 Indent a;
271 indent_printf( fp, "[ 0x%x ] ScTBC -- dump\n", nOffSet );
272 tbch.Print( fp );
273 if ( tbcCmd.get() )
274 tbcCmd->Print( fp );
275 if ( tbcd.get() )
276 tbcd->Print( fp );
277}
278#endif
279
280bool ScTBC::ImportToolBarControl( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuToolbar )
281{
282 // how to identify built-in-command ?
283// bool bBuiltin = false;
284 if ( tbcd )
285 {
286 std::vector< css::beans::PropertyValue > props;
287 bool bBeginGroup = false;
288 tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuToolbar );
289 TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
290 if ( pMenu )
291 {
292 // search for ScCTB with the appropriate name ( it contains the
293 // menu items, although we cannot import ( or create ) a menu on
294 // a custom toolbar we can import the menu items in a separate
295 // toolbar ( better than nothing )
296 ScCTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
297 if ( pCustTB )
298 {
300 if ( !pCustTB->ImportMenuTB( rWrapper, xMenuDesc, helper ) )
301 return false;
302 if ( !bIsMenuToolbar )
303 {
304 if ( !helper.createMenu( pMenu->Name(), xMenuDesc ) )
305 return false;
306 }
307 else
308 {
309 beans::PropertyValue aProp;
310 aProp.Name = "ItemDescriptorContainer";
311 aProp.Value <<= uno::Reference< container::XIndexContainer >(xMenuDesc);
312 props.push_back( aProp );
313 }
314 }
315 }
316
317 if ( bBeginGroup )
318 {
319 // insert spacer
320 uno::Sequence sProps{ comphelper::makePropertyValue("Type",
321 ui::ItemType::SEPARATOR_LINE) };
322 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::Any( sProps ) );
323 }
324 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::Any( comphelper::containerToSequence(props) ) );
325 }
326 return true;
327}
328
329#ifdef DEBUG_SC_EXCEL
330void
331TBCCmd::Print(FILE* fp)
332{
333 Indent a;
334 indent_printf( fp, " TBCCmd -- dump\n" );
335 indent_printf( fp, " cmdID 0x%x\n", cmdID );
336 indent_printf( fp, " A ( fHideDrawing ) %s\n", A ? "true" : "false" );
337 indent_printf( fp, " B ( reserved - ignored ) %s\n", A ? "true" : "false" );
338 indent_printf( fp, " cmdType 0x%x\n", cmdType );
339 indent_printf( fp, " C ( reserved - ignored ) %s\n", A ? "true" : "false" );
340 indent_printf( fp, " reserved3 0x%x\n", reserved3 );
341}
342#endif
343
345{
346 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
347 nOffSet = rS.Tell();
348 rS.ReadUInt16( cmdID );
349 sal_uInt16 temp;
350 rS.ReadUInt16( temp );
351 A = (temp & 0x8000 ) == 0x8000;
352 B = (temp & 0x4000) == 0x4000;
353 cmdType = ( temp & 0x3E00 ) >> 9;
354 C = ( temp & 0x100 ) == 0x100;
355 reserved3 = ( temp & 0xFF );
356 return true;
357}
358
360{
361}
362
364{
365}
366
367bool
369{
370 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
371 nOffSet = rS.Tell();
372 if (!ctbSet.Read(rS))
373 return false;
374
375 //ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
376 //and one 32bit number (4 bytes)
377 const size_t nMinRecordSize = 19 + o3tl::sanitizing_min(ctbSet.ctbViews * 20, 0);
378 const size_t nMaxPossibleRecords = rS.remainingSize()/nMinRecordSize;
379 if (ctbSet.ctb > nMaxPossibleRecords)
380 return false;
381
382 for ( sal_uInt16 index = 0; index < ctbSet.ctb; ++index )
383 {
384 ScCTB aCTB( ctbSet.ctbViews );
385 if ( !aCTB.Read( rS ) )
386 return false;
387 rCTB.push_back( aCTB );
388 }
389 return true;
390}
391
392#ifdef DEBUG_SC_EXCEL
393void
394ScCTBWrapper::Print( FILE* fp )
395{
396 Indent a;
397 indent_printf( fp, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet );
398 ctbSet.Print( fp );
399 for ( auto& rItem : rCTB )
400 {
401 Indent b;
402 rItem.Print( fp );
403 }
404}
405#endif
406
407ScCTB* ScCTBWrapper::GetCustomizationData( const OUString& sTBName )
408{
409 ScCTB* pCTB = nullptr;
410 auto it = std::find_if(rCTB.begin(), rCTB.end(), [&sTBName](ScCTB& rItem) { return rItem.GetName() == sTBName; });
411 if (it != rCTB.end())
412 pCTB = &(*it);
413 return pCTB;
414}
415
417{
418 if(rCTB.empty())
419 return;
420
421 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
422 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
423
424 for ( auto& rItem : rCTB )
425 {
426 // for each customtoolbar
427 CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( "com.sun.star.sheet.SpreadsheetDocument" ) );
428 helper.setMSOCommandMap( new MSOExcelCommandConvertor() );
429 // Ignore menu toolbars, excel doesn't ( afaics ) store
430 // menu customizations ( but you can have menus in a customtoolbar
431 // such menus will be dealt with when they are encountered
432 // as part of importing the appropriate MenuSpecific toolbar control )
433
434 if ( !rItem.IsMenuToolbar() && !rItem.ImportCustomToolBar( *this, helper ) )
435 return;
436 }
437}
438
439/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 reserved3
Definition: xltoolbar.hxx:76
sal_uInt16 ctbViews
Definition: xltoolbar.hxx:78
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:211
sal_uInt16 reserved2
Definition: xltoolbar.hxx:75
sal_uInt8 bVersion
Definition: xltoolbar.hxx:73
CTBS()
Definition: xltoolbar.cxx:73
sal_uInt8 bSignature
Definition: xltoolbar.hxx:72
sal_uInt16 reserved1
Definition: xltoolbar.hxx:74
sal_uInt16 ctb
Definition: xltoolbar.hxx:77
sal_uInt16 ictbView
Definition: xltoolbar.hxx:79
virtual OUString MSOCommandToOOCommand(sal_Int16 msoCmd)=0
virtual OUString MSOTCIDToOOCommand(sal_Int16 msoTCID)=0
void ImportCustomToolBar(SfxObjectShell &rDocSh)
Definition: xltoolbar.cxx:416
ScCTB * GetCustomizationData(const OUString &name)
Definition: xltoolbar.cxx:407
std::vector< ScCTB > rCTB
Definition: xltoolbar.hxx:93
virtual ~ScCTBWrapper() override
Definition: xltoolbar.cxx:363
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:368
bool ImportCustomToolBar(ScCTBWrapper &, CustomToolBarImportHelper &)
Definition: xltoolbar.cxx:170
sal_uInt16 nViews
Definition: xltoolbar.hxx:51
std::vector< ScTBC > rTBC
Definition: xltoolbar.hxx:55
TB tb
Definition: xltoolbar.hxx:52
bool ImportMenuTB(ScCTBWrapper &, const css::uno::Reference< css::container::XIndexContainer > &, CustomToolBarImportHelper &)
Definition: xltoolbar.cxx:160
bool IsMenuToolbar() const
Definition: xltoolbar.cxx:155
sal_uInt32 ectbid
Definition: xltoolbar.hxx:54
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:81
std::vector< TBVisualData > rVisualData
Definition: xltoolbar.hxx:53
ScCTB(sal_uInt16)
Definition: xltoolbar.cxx:77
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:243
TBCHeader tbch
Definition: xltoolbar.hxx:37
std::shared_ptr< TBCCmd > tbcCmd
Definition: xltoolbar.hxx:38
bool ImportToolBarControl(ScCTBWrapper &, const css::uno::Reference< css::container::XIndexContainer > &toolbarcontainer, CustomToolBarImportHelper &helper, bool bIsMenuBar)
Definition: xltoolbar.cxx:280
std::shared_ptr< TBCData > tbcd
Definition: xltoolbar.hxx:39
sal_uInt64 Tell() const
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
sal_uInt64 remainingSize()
SvStream & ReadUChar(unsigned char &rChar)
sal_uInt32 nOffSet
sal_uInt16 reserved3
Definition: xltoolbar.hxx:28
bool A
Definition: xltoolbar.hxx:24
sal_uInt16 cmdID
Definition: xltoolbar.hxx:23
bool C
Definition: xltoolbar.hxx:27
bool B
Definition: xltoolbar.hxx:25
sal_uInt16 cmdType
Definition: xltoolbar.hxx:26
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:344
sal_uInt16 getTcID() const
sal_uInt8 getTct() const
bool Read(SvStream &rS) override
OUString Name()
bool Read(SvStream &rS) override
bool IsEnabled() const
sal_Int16 getcCL() const
bool IsMenuToolbar() const
WString & getName()
bool Read(SvStream &rS) override
const char * name
uno_Any a
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
index
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
T sanitizing_min(T a, T b)
dictionary props
unsigned char sal_uInt8
std::map< sal_Int16, OUString > IdToString
std::map< sal_Int16, OUString > IdToString
Definition: xltoolbar.cxx:25