Line data Source code
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 <rtl/ustrbuf.hxx>
11 : #include <stdarg.h>
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>
20 : #include <fstream>
21 : #include <comphelper/processfactory.hxx>
22 : #include <vcl/graph.hxx>
23 : #include <map>
24 : using namespace com::sun::star;
25 :
26 : typedef std::map< sal_Int16, OUString > IdToString;
27 :
28 0 : class MSOExcelCommandConvertor : public MSOCommandConvertor
29 : {
30 : IdToString msoToOOcmd;
31 : IdToString tcidToOOcmd;
32 : public:
33 : MSOExcelCommandConvertor();
34 : virtual OUString MSOCommandToOOCommand( sal_Int16 msoCmd ) SAL_OVERRIDE;
35 : virtual OUString MSOTCIDToOOCommand( sal_Int16 key ) SAL_OVERRIDE;
36 : };
37 :
38 0 : MSOExcelCommandConvertor::MSOExcelCommandConvertor()
39 : {
40 : /*
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";
45 :
46 : // mso tcid to ooo command string
47 : // #FIXME and *HUNDREDS* of id's to added here
48 : tcidToOOcmd[ 0x9d9 ] = ".uno:Print";
49 : */
50 0 : }
51 :
52 0 : OUString MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
53 : {
54 0 : OUString sResult;
55 0 : IdToString::iterator it = msoToOOcmd.find( key );
56 0 : if ( it != msoToOOcmd.end() )
57 0 : sResult = it->second;
58 0 : return sResult;
59 : }
60 :
61 0 : OUString MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
62 : {
63 0 : OUString sResult;
64 0 : IdToString::iterator it = tcidToOOcmd.find( key );
65 0 : if ( it != tcidToOOcmd.end() )
66 0 : sResult = it->second;
67 0 : return sResult;
68 : }
69 :
70 30 : CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
71 : {
72 30 : }
73 :
74 0 : ScCTB::ScCTB(sal_uInt16 nNum ) : nViews( nNum ), ectbid(0)
75 : {
76 0 : }
77 :
78 0 : bool ScCTB::Read( SvStream &rS )
79 : {
80 : SAL_INFO("sc.filter", "stream pos " << rS.Tell());
81 0 : nOffSet = rS.Tell();
82 0 : tb.Read( rS );
83 0 : for ( sal_uInt16 index = 0; index < nViews; ++index )
84 : {
85 0 : TBVisualData aVisData;
86 0 : aVisData.Read( rS );
87 0 : rVisualData.push_back( aVisData );
88 0 : }
89 0 : rS.ReadUInt32( ectbid );
90 :
91 0 : for ( sal_Int16 index = 0; index < tb.getcCL(); ++index )
92 : {
93 0 : ScTBC aTBC;
94 0 : aTBC.Read( rS );
95 0 : rTBC.push_back( aTBC );
96 0 : }
97 0 : return true;
98 : }
99 :
100 : #if OSL_DEBUG_LEVEL > 1
101 : void ScCTB::Print( FILE* fp )
102 : {
103 : Indent a;
104 : indent_printf( fp, "[ 0x%x ] ScCTB -- dump\n", nOffSet );
105 : indent_printf( fp, " nViews 0x%x\n", nViews);
106 : tb.Print( fp );
107 :
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 )
111 : {
112 :
113 : indent_printf( fp, " TBVisualData [%d]\n", counter++ );
114 : Indent b;
115 : it->Print( fp );
116 : }
117 : indent_printf( fp, " ectbid 0x%x\n", ectbid);
118 : std::vector<ScTBC>::iterator it_end = rTBC.end();
119 : counter = 0;
120 : for ( std::vector<ScTBC>::iterator it = rTBC.begin(); it != it_end; ++it )
121 : {
122 : indent_printf( fp, " ScTBC [%d]\n", counter++);
123 : Indent c;
124 : it->Print( fp );
125 : }
126 : }
127 : #endif
128 :
129 0 : bool ScCTB::IsMenuToolbar()
130 : {
131 0 : return tb.IsMenuToolbar();
132 : }
133 :
134 0 : bool ScCTB::ImportMenuTB( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xMenuDesc, CustomToolBarImportHelper& helper )
135 : {
136 0 : sal_Int32 index = 0;
137 0 : for ( std::vector< ScTBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it, ++index )
138 : {
139 0 : if ( !it->ImportToolBarControl( rWrapper, xMenuDesc, helper, IsMenuToolbar() ) )
140 0 : return false;
141 : }
142 0 : return true;
143 : }
144 :
145 0 : bool ScCTB::ImportCustomToolBar( ScCTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
146 : {
147 :
148 : static const char sToolbarPrefix[] = "private:resource/toolbar/custom_";
149 0 : bool bRes = false;
150 : try
151 : {
152 0 : if ( !tb.IsEnabled() )
153 0 : return true; // didn't fail, just ignoring
154 :
155 : // Create default setting
156 0 : uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_QUERY_THROW );
157 0 : uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
158 0 : uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
159 0 : WString& name = tb.getName();
160 : // set UI name for toolbar
161 0 : xProps->setPropertyValue("UIName", uno::makeAny( name.getString() ) );
162 :
163 0 : OUString sToolBarName = sToolbarPrefix + name.getString();
164 0 : for ( std::vector< ScTBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it )
165 : {
166 0 : if ( !it->ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
167 0 : return false;
168 : }
169 :
170 : OSL_TRACE("Name of toolbar :-/ %s", OUStringToOString( sToolBarName, RTL_TEXTENCODING_UTF8 ).getStr() );
171 :
172 0 : helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
173 0 : helper.applyIcons();
174 :
175 0 : uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
176 0 : xPersistence->store();
177 :
178 0 : xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
179 0 : xPersistence->store();
180 :
181 0 : bRes = true;
182 : }
183 0 : catch( uno::Exception& )
184 : {
185 0 : bRes = false;
186 : }
187 0 : return bRes;
188 : }
189 30 : bool CTBS::Read( SvStream &rS )
190 : {
191 : SAL_INFO("sc.filter", "stream pos " << rS.Tell());
192 30 : nOffSet = rS.Tell();
193 30 : rS.ReadUChar( bSignature ).ReadUChar( bVersion ).ReadUInt16( reserved1 ).ReadUInt16( reserved2 ).ReadUInt16( reserved3 ).ReadUInt16( ctb ).ReadUInt16( ctbViews ).ReadUInt16( ictbView );
194 30 : return true;
195 : }
196 :
197 : #if OSL_DEBUG_LEVEL > 1
198 : void CTBS::Print( FILE* fp )
199 : {
200 : Indent a;
201 : indent_printf( fp, "[ 0x%x ] CTBS -- dump\n", nOffSet );
202 :
203 : indent_printf( fp, " bSignature 0x%x\n", bSignature);
204 : indent_printf( fp, " bVersion 0x%x\n", bVersion);
205 :
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 );
209 :
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 );
213 : }
214 : #endif
215 :
216 0 : ScTBC::ScTBC()
217 : {
218 0 : }
219 :
220 : bool
221 0 : ScTBC::Read(SvStream &rS)
222 : {
223 : SAL_INFO("sc.filter", "stream pos " << rS.Tell());
224 0 : nOffSet = rS.Tell();
225 0 : if ( !tbch.Read( rS ) )
226 0 : return false;
227 0 : sal_uInt16 tcid = tbch.getTcID();
228 0 : sal_uInt8 tct = tbch.getTct();
229 0 : if ( ( tcid != 0x0001 && tcid != 0x06CC && tcid != 0x03D8 && tcid != 0x03EC && tcid != 0x1051 ) && ( ( tct > 0 && tct < 0x0B ) || ( ( tct > 0x0B && tct < 0x10 ) || tct == 0x15 ) ) )
230 : {
231 0 : tbcCmd.reset( new TBCCmd );
232 0 : if ( ! tbcCmd->Read( rS ) )
233 0 : return false;
234 : }
235 0 : if ( tct != 0x16 )
236 : {
237 0 : tbcd.reset( new TBCData( tbch ) );
238 0 : if ( !tbcd->Read( rS ) )
239 0 : return false;
240 : }
241 0 : return true;
242 : }
243 :
244 : #if OSL_DEBUG_LEVEL > 1
245 : void
246 : ScTBC::Print(FILE* fp)
247 : {
248 : Indent a;
249 : indent_printf( fp, "[ 0x%x ] ScTBC -- dump\n", nOffSet );
250 : tbch.Print( fp );
251 : if ( tbcCmd.get() )
252 : tbcCmd->Print( fp );
253 : if ( tbcd.get() )
254 : tbcd->Print( fp );
255 : }
256 : #endif
257 :
258 0 : bool ScTBC::ImportToolBarControl( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuToolbar )
259 : {
260 : // how to identify built-in-command ?
261 : // bool bBuiltin = false;
262 0 : if ( tbcd.get() )
263 : {
264 0 : std::vector< css::beans::PropertyValue > props;
265 0 : bool bBeginGroup = false;
266 0 : if ( ! tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuToolbar ) )
267 0 : return false;
268 0 : TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
269 0 : if ( pMenu )
270 : {
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 0 : ScCTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
276 0 : if ( pCustTB )
277 : {
278 0 : uno::Reference< container::XIndexContainer > xMenuDesc = document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
279 0 : if ( !pCustTB->ImportMenuTB( rWrapper, xMenuDesc, helper ) )
280 0 : return false;
281 0 : if ( !bIsMenuToolbar )
282 : {
283 0 : if ( !helper.createMenu( pMenu->Name(), uno::Reference< container::XIndexAccess >( xMenuDesc, uno::UNO_QUERY ), true ) )
284 0 : return false;
285 : }
286 : else
287 : {
288 0 : beans::PropertyValue aProp;
289 0 : aProp.Name = "ItemDescriptorContainer";
290 0 : aProp.Value <<= xMenuDesc;
291 0 : props.push_back( aProp );
292 0 : }
293 : }
294 : }
295 :
296 0 : if ( bBeginGroup )
297 : {
298 : // insert spacer
299 0 : uno::Sequence< beans::PropertyValue > sProps( 1 );
300 0 : sProps[ 0 ].Name = "Type";
301 0 : sProps[ 0 ].Value = uno::makeAny( ui::ItemType::SEPARATOR_LINE );
302 0 : toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
303 : }
304 0 : uno::Sequence< beans::PropertyValue > sProps( props.size() );
305 0 : beans::PropertyValue* pProp = sProps.getArray();
306 :
307 0 : for ( std::vector< css::beans::PropertyValue >::iterator it = props.begin(); it != props.end(); ++it, ++pProp )
308 0 : *pProp = *it;
309 :
310 0 : toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
311 : }
312 0 : return true;
313 : }
314 :
315 : #if OSL_DEBUG_LEVEL > 1
316 : void
317 : TBCCmd::Print(FILE* fp)
318 : {
319 : Indent a;
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 );
327 : }
328 : #endif
329 :
330 0 : bool TBCCmd::Read( SvStream &rS )
331 : {
332 : SAL_INFO("sc.filter", "stream pos " << rS.Tell());
333 0 : nOffSet = rS.Tell();
334 0 : rS.ReadUInt16( cmdID );
335 : sal_uInt16 temp;
336 0 : rS.ReadUInt16( temp );
337 : OSL_TRACE("TBCmd temp = 0x%x", temp );
338 0 : A = (temp & 0x8000 ) == 0x8000;
339 0 : B = (temp & 0x4000) == 0x4000;
340 0 : cmdType = ( temp & 0x3E00 ) >> 9;
341 0 : C = ( temp & 0x100 ) == 0x100;
342 0 : reserved3 = ( temp & 0xFF );
343 0 : return true;
344 : }
345 :
346 30 : ScCTBWrapper::ScCTBWrapper()
347 : {
348 30 : }
349 :
350 30 : ScCTBWrapper::~ScCTBWrapper()
351 : {
352 30 : }
353 :
354 : bool
355 30 : ScCTBWrapper::Read( SvStream &rS)
356 : {
357 : SAL_INFO("sc.filter", "stream pos " << rS.Tell());
358 30 : nOffSet = rS.Tell();
359 30 : if (!ctbSet.Read(rS))
360 0 : return false;
361 :
362 : //ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
363 : //and one 32bit number (4 bytes)
364 30 : const size_t nMinRecordSize = 19 + ctbSet.ctbViews * 20;
365 30 : const size_t nMaxPossibleRecords = rS.remainingSize()/nMinRecordSize;
366 30 : if (ctbSet.ctb > nMaxPossibleRecords)
367 0 : return false;
368 :
369 30 : for ( sal_uInt16 index = 0; index < ctbSet.ctb; ++index )
370 : {
371 0 : ScCTB aCTB( ctbSet.ctbViews );
372 0 : if ( !aCTB.Read( rS ) )
373 0 : return false;
374 0 : rCTB.push_back( aCTB );
375 0 : }
376 30 : return true;
377 : }
378 :
379 : #if OSL_DEBUG_LEVEL > 1
380 : void
381 : ScCTBWrapper::Print( FILE* fp )
382 : {
383 : Indent a;
384 : indent_printf( fp, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet );
385 : ctbSet.Print( fp );
386 : std::vector<ScCTB>::iterator it_end = rCTB.end();
387 : for ( std::vector<ScCTB>::iterator it = rCTB.begin(); it != it_end; ++it )
388 : {
389 : Indent b;
390 : it->Print( fp );
391 : }
392 : }
393 : #endif
394 :
395 0 : ScCTB* ScCTBWrapper::GetCustomizationData( const OUString& sTBName )
396 : {
397 0 : ScCTB* pCTB = NULL;
398 0 : for ( std::vector< ScCTB >::iterator it = rCTB.begin(); it != rCTB.end(); ++it )
399 : {
400 0 : if ( it->GetName().equals( sTBName ) )
401 : {
402 0 : pCTB = &(*it);
403 0 : break;
404 : }
405 : }
406 0 : return pCTB;
407 : }
408 :
409 30 : bool ScCTBWrapper::ImportCustomToolBar( SfxObjectShell& rDocSh )
410 : {
411 30 : if(rCTB.empty())
412 30 : return true;
413 :
414 0 : uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
415 0 : uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
416 :
417 0 : std::vector<ScCTB>::iterator it_end = rCTB.end();
418 0 : for ( std::vector<ScCTB>::iterator it = rCTB.begin(); it != it_end; ++it )
419 : {
420 : // for each customtoolbar
421 0 : CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( OUString("com.sun.star.sheet.SpreadsheetDocument" ) ) );
422 0 : 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 )
427 :
428 0 : if ( !(*it).IsMenuToolbar() )
429 : {
430 0 : if ( !(*it).ImportCustomToolBar( *this, helper ) )
431 0 : return false;
432 : }
433 0 : }
434 0 : return true;
435 : }
436 :
437 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|