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 #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>
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
;
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
)
51 IdToString::iterator it
= msoToOOcmd
.find( key
);
52 if ( it
!= msoToOOcmd
.end() )
57 OUString
MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key
)
60 IdToString::iterator it
= tcidToOOcmd
.find( key
);
61 if ( it
!= tcidToOOcmd
.end() )
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());
79 for ( sal_uInt16 index
= 0; index
< nViews
; ++index
)
81 TBVisualData aVisData
;
83 rVisualData
.push_back( aVisData
);
85 rS
.ReadUInt32( ectbid
);
87 for ( sal_Int16 index
= 0; index
< tb
.getcCL(); ++index
)
91 rTBC
.push_back( aTBC
);
97 void ScCTB::Print( FILE* fp
)
100 indent_printf( fp
, "[ 0x%x ] ScCTB -- dump\n", nOffSet
);
101 indent_printf( fp
, " nViews 0x%x\n", nViews
);
104 sal_Int32 counter
= 0;
105 for ( auto& rItem
: rVisualData
)
107 indent_printf( fp
, " TBVisualData [%d]\n", counter
++ );
111 indent_printf( fp
, " ectbid 0x%x\n", ectbid
);
113 for ( auto& rItem
: rTBC
)
115 indent_printf( fp
, " ScTBC [%d]\n", counter
++);
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() ) )
137 bool ScCTB::ImportCustomToolBar( ScCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
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() ) )
161 helper
.getCfgManager()->insertSettings( sToolBarName
, xIndexAccess
);
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();
172 catch( uno::Exception
& )
178 bool CTBS::Read( SvStream
&rS
)
180 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
182 rS
.ReadUChar( bSignature
).ReadUChar( bVersion
).ReadUInt16( reserved1
).ReadUInt16( reserved2
).ReadUInt16( reserved3
).ReadUInt16( ctb
).ReadUInt16( ctbViews
).ReadUInt16( ictbView
);
186 #ifdef DEBUG_SC_EXCEL
187 void CTBS::Print( FILE* fp
)
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
);
210 ScTBC::Read(SvStream
&rS
)
212 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
214 if ( !tbch
.Read( rS
) )
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
) )
226 tbcd
.reset( new TBCData( tbch
) );
227 if ( !tbcd
->Read( rS
) )
233 #ifdef DEBUG_SC_EXCEL
235 ScTBC::Print(FILE* fp
)
238 indent_printf( fp
, "[ 0x%x ] ScTBC -- dump\n", nOffSet
);
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;
253 std::vector
< css::beans::PropertyValue
> props
;
254 bool bBeginGroup
= false;
255 tbcd
->ImportToolBarControl( helper
, props
, bBeginGroup
, bIsMenuToolbar
);
256 TBCMenuSpecific
* pMenu
= tbcd
->getMenuSpecific();
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() );
266 uno::Reference
< container::XIndexContainer
> xMenuDesc
= document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
267 if ( !pCustTB
->ImportMenuTB( rWrapper
, xMenuDesc
, helper
) )
269 if ( !bIsMenuToolbar
)
271 if ( !helper
.createMenu( pMenu
->Name(), xMenuDesc
) )
276 beans::PropertyValue aProp
;
277 aProp
.Name
= "ItemDescriptorContainer";
278 aProp
.Value
<<= xMenuDesc
;
279 props
.push_back( aProp
);
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
) ) );
297 #ifdef DEBUG_SC_EXCEL
299 TBCCmd::Print(FILE* fp
)
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
);
312 bool TBCCmd::Read( SvStream
&rS
)
314 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
316 rS
.ReadUInt16( cmdID
);
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 );
327 ScCTBWrapper::ScCTBWrapper()
331 ScCTBWrapper::~ScCTBWrapper()
336 ScCTBWrapper::Read( SvStream
&rS
)
338 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
340 if (!ctbSet
.Read(rS
))
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
)
350 for ( sal_uInt16 index
= 0; index
< ctbSet
.ctb
; ++index
)
352 ScCTB
aCTB( ctbSet
.ctbViews
);
353 if ( !aCTB
.Read( rS
) )
355 rCTB
.push_back( aCTB
);
360 #ifdef DEBUG_SC_EXCEL
362 ScCTBWrapper::Print( FILE* fp
)
365 indent_printf( fp
, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet
);
367 for ( auto& rItem
: rCTB
)
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())
384 void ScCTBWrapper::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
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
) )
407 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */