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 <rtl/ustrbuf.hxx>
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/lang/XMultiServiceFactory.hpp>
16 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
17 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
18 #include <com/sun/star/ui/XImageManager.hpp>
19 #include <com/sun/star/ui/ItemType.hpp>
21 #include <comphelper/processfactory.hxx>
22 #include <vcl/graph.hxx>
24 using namespace com::sun::star
;
26 typedef std::map
< sal_Int16
, OUString
> IdToString
;
28 class MSOExcelCommandConvertor
: public MSOCommandConvertor
30 IdToString msoToOOcmd
;
31 IdToString tcidToOOcmd
;
33 MSOExcelCommandConvertor();
34 virtual OUString
MSOCommandToOOCommand( sal_Int16 msoCmd
) SAL_OVERRIDE
;
35 virtual OUString
MSOTCIDToOOCommand( sal_Int16 key
) SAL_OVERRIDE
;
38 MSOExcelCommandConvertor::MSOExcelCommandConvertor()
41 // mso command id to ooo command string
42 // #FIXME and *HUNDREDS* of id's to added here
43 msoToOOcmd[ 0x20b ] = ".uno:CloseDoc";
44 msoToOOcmd[ 0x50 ] = ".uno:Open";
46 // mso tcid to ooo command string
47 // #FIXME and *HUNDREDS* of id's to added here
48 tcidToOOcmd[ 0x9d9 ] = ".uno:Print";
52 OUString
MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key
)
55 IdToString::iterator it
= msoToOOcmd
.find( key
);
56 if ( it
!= msoToOOcmd
.end() )
61 OUString
MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key
)
64 IdToString::iterator it
= tcidToOOcmd
.find( key
);
65 if ( it
!= tcidToOOcmd
.end() )
70 CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
74 ScCTB::ScCTB(sal_uInt16 nNum
) : nViews( nNum
), ectbid(0)
78 bool ScCTB::Read( SvStream
&rS
)
80 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
83 for ( sal_uInt16 index
= 0; index
< nViews
; ++index
)
85 TBVisualData aVisData
;
87 rVisualData
.push_back( aVisData
);
89 rS
.ReadUInt32( ectbid
);
91 for ( sal_Int16 index
= 0; index
< tb
.getcCL(); ++index
)
95 rTBC
.push_back( aTBC
);
100 #if OSL_DEBUG_LEVEL > 1
101 void ScCTB::Print( FILE* fp
)
104 indent_printf( fp
, "[ 0x%x ] ScCTB -- dump\n", nOffSet
);
105 indent_printf( fp
, " nViews 0x%x\n", nViews
);
108 std::vector
<TBVisualData
>::iterator visData_end
= rVisualData
.end();
109 sal_Int32 counter
= 0;
110 for ( std::vector
<TBVisualData
>::iterator it
= rVisualData
.begin(); it
!= visData_end
; ++it
)
113 indent_printf( fp
, " TBVisualData [%d]\n", counter
++ );
117 indent_printf( fp
, " ectbid 0x%x\n", ectbid
);
118 std::vector
<ScTBC
>::iterator it_end
= rTBC
.end();
120 for ( std::vector
<ScTBC
>::iterator it
= rTBC
.begin(); it
!= it_end
; ++it
)
122 indent_printf( fp
, " ScTBC [%d]\n", counter
++);
129 bool ScCTB::IsMenuToolbar()
131 return tb
.IsMenuToolbar();
134 bool ScCTB::ImportMenuTB( ScCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& xMenuDesc
, CustomToolBarImportHelper
& helper
)
137 for ( std::vector
< ScTBC
>::iterator it
= rTBC
.begin(); it
!= rTBC
.end(); ++it
, ++index
)
139 if ( !it
->ImportToolBarControl( rWrapper
, xMenuDesc
, helper
, IsMenuToolbar() ) )
145 bool ScCTB::ImportCustomToolBar( ScCTBWrapper
& rWrapper
, CustomToolBarImportHelper
& helper
)
148 static const char sToolbarPrefix
[] = "private:resource/toolbar/custom_";
152 if ( !tb
.IsEnabled() )
153 return true; // didn't fail, just ignoring
155 // Create default setting
156 uno::Reference
< container::XIndexContainer
> xIndexContainer( helper
.getCfgManager()->createSettings(), uno::UNO_QUERY_THROW
);
157 uno::Reference
< container::XIndexAccess
> xIndexAccess( xIndexContainer
, uno::UNO_QUERY_THROW
);
158 uno::Reference
< beans::XPropertySet
> xProps( xIndexContainer
, uno::UNO_QUERY_THROW
);
159 WString
& name
= tb
.getName();
160 // set UI name for toolbar
161 xProps
->setPropertyValue("UIName", uno::makeAny( name
.getString() ) );
163 OUString sToolBarName
= sToolbarPrefix
+ name
.getString();
164 for ( std::vector
< ScTBC
>::iterator it
= rTBC
.begin(); it
!= rTBC
.end(); ++it
)
166 if ( !it
->ImportToolBarControl( rWrapper
, xIndexContainer
, helper
, IsMenuToolbar() ) )
170 OSL_TRACE("Name of toolbar :-/ %s", OUStringToOString( sToolBarName
, RTL_TEXTENCODING_UTF8
).getStr() );
172 helper
.getCfgManager()->insertSettings( sToolBarName
, xIndexAccess
);
175 uno::Reference
< ui::XUIConfigurationPersistence
> xPersistence( helper
.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW
);
176 xPersistence
->store();
178 xPersistence
.set( helper
.getCfgManager(), uno::UNO_QUERY_THROW
);
179 xPersistence
->store();
183 catch( uno::Exception
& )
189 bool CTBS::Read( SvStream
&rS
)
191 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
193 rS
.ReadUChar( bSignature
).ReadUChar( bVersion
).ReadUInt16( reserved1
).ReadUInt16( reserved2
).ReadUInt16( reserved3
).ReadUInt16( ctb
).ReadUInt16( ctbViews
).ReadUInt16( ictbView
);
197 #if OSL_DEBUG_LEVEL > 1
198 void CTBS::Print( FILE* fp
)
201 indent_printf( fp
, "[ 0x%x ] CTBS -- dump\n", nOffSet
);
203 indent_printf( fp
, " bSignature 0x%x\n", bSignature
);
204 indent_printf( fp
, " bVersion 0x%x\n", bVersion
);
206 indent_printf( fp
, " reserved1 0x%x\n", reserved1
);
207 indent_printf( fp
, " reserved2 0x%x\n", reserved2
);
208 indent_printf( fp
, " reserved3 0x%x\n", reserved3
);
210 indent_printf( fp
, " ctb 0x%x\n", ctb
);
211 indent_printf( fp
, " ctbViews 0x%x\n", ctbViews
);
212 indent_printf( fp
, " ictbView 0x%x\n", ictbView
);
221 ScTBC::Read(SvStream
&rS
)
223 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
225 if ( !tbch
.Read( rS
) )
227 sal_uInt16 tcid
= tbch
.getTcID();
228 sal_uInt8 tct
= tbch
.getTct();
229 if ( ( tcid
!= 0x0001 && tcid
!= 0x06CC && tcid
!= 0x03D8 && tcid
!= 0x03EC && tcid
!= 0x1051 ) && ( ( tct
> 0 && tct
< 0x0B ) || ( ( tct
> 0x0B && tct
< 0x10 ) || tct
== 0x15 ) ) )
231 tbcCmd
.reset( new TBCCmd
);
232 if ( ! tbcCmd
->Read( rS
) )
237 tbcd
.reset( new TBCData( tbch
) );
238 if ( !tbcd
->Read( rS
) )
244 #if OSL_DEBUG_LEVEL > 1
246 ScTBC::Print(FILE* fp
)
249 indent_printf( fp
, "[ 0x%x ] ScTBC -- dump\n", nOffSet
);
258 bool ScTBC::ImportToolBarControl( ScCTBWrapper
& rWrapper
, const css::uno::Reference
< css::container::XIndexContainer
>& toolbarcontainer
, CustomToolBarImportHelper
& helper
, bool bIsMenuToolbar
)
260 // how to identify built-in-command ?
261 // bool bBuiltin = false;
264 std::vector
< css::beans::PropertyValue
> props
;
265 bool bBeginGroup
= false;
266 if ( ! tbcd
->ImportToolBarControl( helper
, props
, bBeginGroup
, bIsMenuToolbar
) )
268 TBCMenuSpecific
* pMenu
= tbcd
->getMenuSpecific();
271 // search for ScCTB with the appropriate name ( it contains the
272 // menu items, although we cannot import ( or create ) a menu on
273 // a custom toolbar we can import the menu items in a separate
274 // toolbar ( better than nothing )
275 ScCTB
* pCustTB
= rWrapper
.GetCustomizationData( pMenu
->Name() );
278 uno::Reference
< container::XIndexContainer
> xMenuDesc
= document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
279 if ( !pCustTB
->ImportMenuTB( rWrapper
, xMenuDesc
, helper
) )
281 if ( !bIsMenuToolbar
)
283 if ( !helper
.createMenu( pMenu
->Name(), uno::Reference
< container::XIndexAccess
>( xMenuDesc
, uno::UNO_QUERY
), true ) )
288 beans::PropertyValue aProp
;
289 aProp
.Name
= "ItemDescriptorContainer";
290 aProp
.Value
<<= xMenuDesc
;
291 props
.push_back( aProp
);
299 uno::Sequence
< beans::PropertyValue
> sProps( 1 );
300 sProps
[ 0 ].Name
= "Type";
301 sProps
[ 0 ].Value
= uno::makeAny( ui::ItemType::SEPARATOR_LINE
);
302 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::makeAny( sProps
) );
304 uno::Sequence
< beans::PropertyValue
> sProps( props
.size() );
305 beans::PropertyValue
* pProp
= sProps
.getArray();
307 for ( std::vector
< css::beans::PropertyValue
>::iterator it
= props
.begin(); it
!= props
.end(); ++it
, ++pProp
)
310 toolbarcontainer
->insertByIndex( toolbarcontainer
->getCount(), uno::makeAny( sProps
) );
315 #if OSL_DEBUG_LEVEL > 1
317 TBCCmd::Print(FILE* fp
)
320 indent_printf( fp
, " TBCCmd -- dump\n" );
321 indent_printf( fp
, " cmdID 0x%x\n", cmdID
);
322 indent_printf( fp
, " A ( fHideDrawing ) %s\n", A
? "true" : "false" );
323 indent_printf( fp
, " B ( reserved - ignored ) %s\n", A
? "true" : "false" );
324 indent_printf( fp
, " cmdType 0x%x\n", cmdType
);
325 indent_printf( fp
, " C ( reserved - ignored ) %s\n", A
? "true" : "false" );
326 indent_printf( fp
, " reserved3 0x%x\n", reserved3
);
330 bool TBCCmd::Read( SvStream
&rS
)
332 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
334 rS
.ReadUInt16( cmdID
);
336 rS
.ReadUInt16( temp
);
337 OSL_TRACE("TBCmd temp = 0x%x", temp
);
338 A
= (temp
& 0x8000 ) == 0x8000;
339 B
= (temp
& 0x4000) == 0x4000;
340 cmdType
= ( temp
& 0x3E00 ) >> 9;
341 C
= ( temp
& 0x100 ) == 0x100;
342 reserved3
= ( temp
& 0xFF );
346 ScCTBWrapper::ScCTBWrapper()
350 ScCTBWrapper::~ScCTBWrapper()
355 ScCTBWrapper::Read( SvStream
&rS
)
357 SAL_INFO("sc.filter", "stream pos " << rS
.Tell());
359 if (!ctbSet
.Read(rS
))
362 //ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
363 //and one 32bit number (4 bytes)
364 const size_t nMinRecordSize
= 19 + ctbSet
.ctbViews
* 20;
365 const size_t nMaxPossibleRecords
= rS
.remainingSize()/nMinRecordSize
;
366 if (ctbSet
.ctb
> nMaxPossibleRecords
)
369 for ( sal_uInt16 index
= 0; index
< ctbSet
.ctb
; ++index
)
371 ScCTB
aCTB( ctbSet
.ctbViews
);
372 if ( !aCTB
.Read( rS
) )
374 rCTB
.push_back( aCTB
);
379 #if OSL_DEBUG_LEVEL > 1
381 ScCTBWrapper::Print( FILE* fp
)
384 indent_printf( fp
, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet
);
386 std::vector
<ScCTB
>::iterator it_end
= rCTB
.end();
387 for ( std::vector
<ScCTB
>::iterator it
= rCTB
.begin(); it
!= it_end
; ++it
)
395 ScCTB
* ScCTBWrapper::GetCustomizationData( const OUString
& sTBName
)
398 for ( std::vector
< ScCTB
>::iterator it
= rCTB
.begin(); it
!= rCTB
.end(); ++it
)
400 if ( it
->GetName().equals( sTBName
) )
409 bool ScCTBWrapper::ImportCustomToolBar( SfxObjectShell
& rDocSh
)
414 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
415 uno::Reference
< ui::XModuleUIConfigurationManagerSupplier
> xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext
) );
417 std::vector
<ScCTB
>::iterator it_end
= rCTB
.end();
418 for ( std::vector
<ScCTB
>::iterator it
= rCTB
.begin(); it
!= it_end
; ++it
)
420 // for each customtoolbar
421 CustomToolBarImportHelper
helper( rDocSh
, xAppCfgSupp
->getUIConfigurationManager( OUString("com.sun.star.sheet.SpreadsheetDocument" ) ) );
422 helper
.setMSOCommandMap( new MSOExcelCommandConvertor() );
423 // Ignore menu toolbars, excel doesn't ( afaics ) store
424 // menu customizations ( but you can have menus in a customtoolbar
425 // such menus will be dealt with when they are encountered
426 // as part of importing the appropriate MenuSpecific toolbar control )
428 if ( !(*it
).IsMenuToolbar() )
430 if ( !(*it
).ImportCustomToolBar( *this, helper
) )
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */