Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / excel / xltoolbar.cxx
blobcd3a355f252ab2fc1405b67cfd23ef424337e362
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
9 #include "xltoolbar.hxx"
10 #include <sal/log.hxx>
11 #include <com/sun/star/beans/XPropertySet.hpp>
12 #include <com/sun/star/document/IndexedPropertyValues.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>
16 #include <comphelper/processfactory.hxx>
17 #include <comphelper/sequence.hxx>
18 #include <map>
20 using namespace com::sun::star;
22 typedef std::map< sal_Int16, OUString > IdToString;
24 class MSOExcelCommandConvertor : public MSOCommandConvertor
26 IdToString msoToOOcmd;
27 IdToString tcidToOOcmd;
28 public:
29 MSOExcelCommandConvertor();
30 virtual OUString MSOCommandToOOCommand( sal_Int16 msoCmd ) override;
31 virtual OUString MSOTCIDToOOCommand( sal_Int16 key ) override;
34 MSOExcelCommandConvertor::MSOExcelCommandConvertor()
37 // mso command id to ooo command string
38 // #FIXME and *HUNDREDS* of id's to added here
39 msoToOOcmd[ 0x20b ] = ".uno:CloseDoc";
40 msoToOOcmd[ 0x50 ] = ".uno:Open";
42 // mso tcid to ooo command string
43 // #FIXME and *HUNDREDS* of id's to added here
44 tcidToOOcmd[ 0x9d9 ] = ".uno:Print";
48 OUString MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
50 OUString sResult;
51 IdToString::iterator it = msoToOOcmd.find( key );
52 if ( it != msoToOOcmd.end() )
53 sResult = it->second;
54 return sResult;
57 OUString MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
59 OUString sResult;
60 IdToString::iterator it = tcidToOOcmd.find( key );
61 if ( it != tcidToOOcmd.end() )
62 sResult = it->second;
63 return sResult;
66 CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
70 ScCTB::ScCTB(sal_uInt16 nNum ) : nViews( nNum ), ectbid(0)
74 bool ScCTB::Read( SvStream &rS )
76 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
77 nOffSet = rS.Tell();
78 tb.Read( rS );
79 for ( sal_uInt16 index = 0; index < nViews; ++index )
81 TBVisualData aVisData;
82 aVisData.Read( rS );
83 rVisualData.push_back( aVisData );
85 rS.ReadUInt32( ectbid );
87 for ( sal_Int16 index = 0; index < tb.getcCL(); ++index )
89 ScTBC aTBC;
90 aTBC.Read( rS );
91 rTBC.push_back( aTBC );
93 return true;
96 #ifdef DEBUG_SC_EXCEL
97 void ScCTB::Print( FILE* fp )
99 Indent a;
100 indent_printf( fp, "[ 0x%x ] ScCTB -- dump\n", nOffSet );
101 indent_printf( fp, " nViews 0x%x\n", nViews);
102 tb.Print( fp );
104 sal_Int32 counter = 0;
105 for ( auto& rItem : rVisualData )
107 indent_printf( fp, " TBVisualData [%d]\n", counter++ );
108 Indent b;
109 rItem.Print( fp );
111 indent_printf( fp, " ectbid 0x%x\n", ectbid);
112 counter = 0;
113 for ( auto& rItem : rTBC )
115 indent_printf( fp, " ScTBC [%d]\n", counter++);
116 Indent c;
117 rItem.Print( fp );
120 #endif
122 bool ScCTB::IsMenuToolbar() const
124 return tb.IsMenuToolbar();
127 bool ScCTB::ImportMenuTB( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xMenuDesc, CustomToolBarImportHelper& helper )
129 for ( auto& rItem : rTBC )
131 if ( !rItem.ImportToolBarControl( rWrapper, xMenuDesc, helper, IsMenuToolbar() ) )
132 return false;
134 return true;
137 bool ScCTB::ImportCustomToolBar( ScCTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
140 bool bRes = false;
143 if ( !tb.IsEnabled() )
144 return true; // didn't fail, just ignoring
146 // Create default setting
147 uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_SET_THROW );
148 uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
149 uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
150 WString& name = tb.getName();
151 // set UI name for toolbar
152 xProps->setPropertyValue("UIName", uno::makeAny( name.getString() ) );
154 OUString sToolBarName = "private:resource/toolbar/custom_" + name.getString();
155 for ( auto& rItem : rTBC )
157 if ( !rItem.ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
158 return false;
161 helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
162 helper.applyIcons();
164 uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
165 xPersistence->store();
167 xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
168 xPersistence->store();
170 bRes = true;
172 catch( uno::Exception& )
174 bRes = false;
176 return bRes;
178 bool CTBS::Read( SvStream &rS )
180 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
181 nOffSet = rS.Tell();
182 rS.ReadUChar( bSignature ).ReadUChar( bVersion ).ReadUInt16( reserved1 ).ReadUInt16( reserved2 ).ReadUInt16( reserved3 ).ReadUInt16( ctb ).ReadUInt16( ctbViews ).ReadUInt16( ictbView );
183 return true;
186 #ifdef DEBUG_SC_EXCEL
187 void CTBS::Print( FILE* fp )
189 Indent a;
190 indent_printf( fp, "[ 0x%x ] CTBS -- dump\n", nOffSet );
192 indent_printf( fp, " bSignature 0x%x\n", bSignature);
193 indent_printf( fp, " bVersion 0x%x\n", bVersion);
195 indent_printf( fp, " reserved1 0x%x\n", reserved1 );
196 indent_printf( fp, " reserved2 0x%x\n", reserved2 );
197 indent_printf( fp, " reserved3 0x%x\n", reserved3 );
199 indent_printf( fp, " ctb 0x%x\n", ctb );
200 indent_printf( fp, " ctbViews 0x%x\n", ctbViews );
201 indent_printf( fp, " ictbView 0x%x\n", ictbView );
203 #endif
205 ScTBC::ScTBC()
209 bool
210 ScTBC::Read(SvStream &rS)
212 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
213 nOffSet = rS.Tell();
214 if ( !tbch.Read( rS ) )
215 return false;
216 sal_uInt16 tcid = tbch.getTcID();
217 sal_uInt8 tct = tbch.getTct();
218 if ( ( tcid != 0x0001 && tcid != 0x06CC && tcid != 0x03D8 && tcid != 0x03EC && tcid != 0x1051 ) && ( ( tct > 0 && tct < 0x0B ) || ( ( tct > 0x0B && tct < 0x10 ) || tct == 0x15 ) ) )
220 tbcCmd.reset( new TBCCmd );
221 if ( ! tbcCmd->Read( rS ) )
222 return false;
224 if ( tct != 0x16 )
226 tbcd.reset( new TBCData( tbch ) );
227 if ( !tbcd->Read( rS ) )
228 return false;
230 return true;
233 #ifdef DEBUG_SC_EXCEL
234 void
235 ScTBC::Print(FILE* fp)
237 Indent a;
238 indent_printf( fp, "[ 0x%x ] ScTBC -- dump\n", nOffSet );
239 tbch.Print( fp );
240 if ( tbcCmd.get() )
241 tbcCmd->Print( fp );
242 if ( tbcd.get() )
243 tbcd->Print( fp );
245 #endif
247 bool ScTBC::ImportToolBarControl( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuToolbar )
249 // how to identify built-in-command ?
250 // bool bBuiltin = false;
251 if ( tbcd.get() )
253 std::vector< css::beans::PropertyValue > props;
254 bool bBeginGroup = false;
255 tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuToolbar );
256 TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
257 if ( pMenu )
259 // search for ScCTB with the appropriate name ( it contains the
260 // menu items, although we cannot import ( or create ) a menu on
261 // a custom toolbar we can import the menu items in a separate
262 // toolbar ( better than nothing )
263 ScCTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
264 if ( pCustTB )
266 uno::Reference< container::XIndexContainer > xMenuDesc = document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
267 if ( !pCustTB->ImportMenuTB( rWrapper, xMenuDesc, helper ) )
268 return false;
269 if ( !bIsMenuToolbar )
271 if ( !helper.createMenu( pMenu->Name(), xMenuDesc ) )
272 return false;
274 else
276 beans::PropertyValue aProp;
277 aProp.Name = "ItemDescriptorContainer";
278 aProp.Value <<= xMenuDesc;
279 props.push_back( aProp );
284 if ( bBeginGroup )
286 // insert spacer
287 uno::Sequence< beans::PropertyValue > sProps( 1 );
288 sProps[ 0 ].Name = "Type";
289 sProps[ 0 ].Value <<= ui::ItemType::SEPARATOR_LINE;
290 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
292 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( comphelper::containerToSequence(props) ) );
294 return true;
297 #ifdef DEBUG_SC_EXCEL
298 void
299 TBCCmd::Print(FILE* fp)
301 Indent a;
302 indent_printf( fp, " TBCCmd -- dump\n" );
303 indent_printf( fp, " cmdID 0x%x\n", cmdID );
304 indent_printf( fp, " A ( fHideDrawing ) %s\n", A ? "true" : "false" );
305 indent_printf( fp, " B ( reserved - ignored ) %s\n", A ? "true" : "false" );
306 indent_printf( fp, " cmdType 0x%x\n", cmdType );
307 indent_printf( fp, " C ( reserved - ignored ) %s\n", A ? "true" : "false" );
308 indent_printf( fp, " reserved3 0x%x\n", reserved3 );
310 #endif
312 bool TBCCmd::Read( SvStream &rS )
314 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
315 nOffSet = rS.Tell();
316 rS.ReadUInt16( cmdID );
317 sal_uInt16 temp;
318 rS.ReadUInt16( temp );
319 A = (temp & 0x8000 ) == 0x8000;
320 B = (temp & 0x4000) == 0x4000;
321 cmdType = ( temp & 0x3E00 ) >> 9;
322 C = ( temp & 0x100 ) == 0x100;
323 reserved3 = ( temp & 0xFF );
324 return true;
327 ScCTBWrapper::ScCTBWrapper()
331 ScCTBWrapper::~ScCTBWrapper()
335 bool
336 ScCTBWrapper::Read( SvStream &rS)
338 SAL_INFO("sc.filter", "stream pos " << rS.Tell());
339 nOffSet = rS.Tell();
340 if (!ctbSet.Read(rS))
341 return false;
343 //ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
344 //and one 32bit number (4 bytes)
345 const size_t nMinRecordSize = 19 + ctbSet.ctbViews * 20;
346 const size_t nMaxPossibleRecords = rS.remainingSize()/nMinRecordSize;
347 if (ctbSet.ctb > nMaxPossibleRecords)
348 return false;
350 for ( sal_uInt16 index = 0; index < ctbSet.ctb; ++index )
352 ScCTB aCTB( ctbSet.ctbViews );
353 if ( !aCTB.Read( rS ) )
354 return false;
355 rCTB.push_back( aCTB );
357 return true;
360 #ifdef DEBUG_SC_EXCEL
361 void
362 ScCTBWrapper::Print( FILE* fp )
364 Indent a;
365 indent_printf( fp, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet );
366 ctbSet.Print( fp );
367 for ( auto& rItem : rCTB )
369 Indent b;
370 rItem.Print( fp );
373 #endif
375 ScCTB* ScCTBWrapper::GetCustomizationData( const OUString& sTBName )
377 ScCTB* pCTB = nullptr;
378 auto it = std::find_if(rCTB.begin(), rCTB.end(), [&sTBName](ScCTB& rItem) { return rItem.GetName() == sTBName; });
379 if (it != rCTB.end())
380 pCTB = &(*it);
381 return pCTB;
384 void ScCTBWrapper::ImportCustomToolBar( SfxObjectShell& rDocSh )
386 if(rCTB.empty())
387 return;
389 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
390 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
392 for ( auto& rItem : rCTB )
394 // for each customtoolbar
395 CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( "com.sun.star.sheet.SpreadsheetDocument" ) );
396 helper.setMSOCommandMap( new MSOExcelCommandConvertor() );
397 // Ignore menu toolbars, excel doesn't ( afaics ) store
398 // menu customizations ( but you can have menus in a customtoolbar
399 // such menus will be dealt with when they are encountered
400 // as part of importing the appropriate MenuSpecific toolbar control )
402 if ( !rItem.IsMenuToolbar() && !rItem.ImportCustomToolBar( *this, helper ) )
403 return;
407 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */