bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / ww8toolbar.cxx
blob08807965580040e4301c5b07ed2b7f5564208671
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 "ww8toolbar.hxx"
10 #include "ww8scan.hxx"
11 #include <rtl/ustrbuf.hxx>
12 #include <stdarg.h>
13 #include <com/sun/star/document/IndexedPropertyValues.hpp>
14 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
15 #include <com/sun/star/ui/ModuleUIConfigurationManagerSupplier.hpp>
16 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
17 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
18 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
19 #include <com/sun/star/ui/XImageManager.hpp>
20 #include <com/sun/star/ui/ItemType.hpp>
21 #include <fstream>
22 #include <comphelper/processfactory.hxx>
23 #include <vcl/graph.hxx>
24 #include <map>
25 #include "sal/log.hxx"
27 using namespace com::sun::star;
29 // no. of visual data elements in a SwCTB ( fixed )
30 const short nVisualData = 5;
32 typedef std::map< sal_Int16, OUString > IdToString;
34 class MSOWordCommandConvertor : public MSOCommandConvertor
36 IdToString msoToOOcmd;
37 IdToString tcidToOOcmd;
38 public:
39 MSOWordCommandConvertor();
40 virtual OUString MSOCommandToOOCommand( sal_Int16 msoCmd );
41 virtual OUString MSOTCIDToOOCommand( sal_Int16 key );
44 MSOWordCommandConvertor::MSOWordCommandConvertor()
46 // mso command id to ooo command string
47 // #FIXME and *HUNDREDS* of id's to added here
48 msoToOOcmd[ 0x20b ] = ".uno:CloseDoc";
49 msoToOOcmd[ 0x50 ] = ".uno:Open";
51 // mso tcid to ooo command string
52 // #FIXME and *HUNDREDS* of id's to added here
53 tcidToOOcmd[ 0x9d9 ] = ".uno:Print";
56 OUString MSOWordCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
58 OUString sResult;
59 IdToString::iterator it = msoToOOcmd.find( key );
60 if ( it != msoToOOcmd.end() )
61 sResult = it->second;
62 return sResult;
65 OUString MSOWordCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
67 OUString sResult;
68 IdToString::iterator it = tcidToOOcmd.find( key );
69 if ( it != tcidToOOcmd.end() )
70 sResult = it->second;
71 return sResult;
75 SwCTBWrapper::SwCTBWrapper( bool bReadId ) : Tcg255SubStruct( bReadId )
76 ,reserved2(0)
77 ,reserved3(0)
78 ,reserved4(0)
79 ,reserved5(0)
80 ,cbTBD(0)
81 ,cCust(0)
82 ,cbDTBC(0)
83 ,rtbdc(0)
87 SwCTBWrapper::~SwCTBWrapper()
91 Customization* SwCTBWrapper::GetCustomizaton( sal_Int16 index )
93 if ( index < 0 || index >= static_cast<sal_Int16>( rCustomizations.size() ) )
94 return NULL;
95 return &rCustomizations[ index ];
98 SwCTB* SwCTBWrapper::GetCustomizationData( const OUString& sTBName )
100 SwCTB* pCTB = NULL;
101 for ( std::vector< Customization >::iterator it = rCustomizations.begin(); it != rCustomizations.end(); ++it )
103 if ( it->GetCustomizationData() && it->GetCustomizationData()->GetName().equals( sTBName ) )
105 pCTB = it->GetCustomizationData();
106 break;
109 return pCTB;
112 bool SwCTBWrapper::Read( SvStream& rS )
114 SAL_INFO("sw.ww8","SwCTBWrapper::Read() stream pos 0x" << std::hex << rS.Tell() );
115 nOffSet = rS.Tell();
116 Tcg255SubStruct::Read( rS );
117 rS >> reserved2 >> reserved3 >> reserved4 >> reserved5;
118 rS >> cbTBD >> cCust >> cbDTBC;
119 long nExpectedPos = rS.Tell() + cbDTBC;
120 if ( cbDTBC )
122 // cbDTBC is the size in bytes of the SwTBC array
123 // but the size of a SwTBC element is dynamic ( and this relates to TBDelta's
124 int nStart = rS.Tell();
126 int bytesRead = 0;
127 int bytesToRead = cbDTBC - bytesRead;
128 // cbDTBC specifies the size ( in bytes ) taken by an array ( of unspecified size )
129 // of SwTBC records ( SwTBC records have dynamic length, so we need to check our position
130 // after each read )
133 SwTBC aTBC;
134 if ( !aTBC.Read( rS ) )
135 return false;
136 rtbdc.push_back( aTBC );
137 bytesToRead = cbDTBC - ( rS.Tell() - nStart );
138 } while ( bytesToRead > 0 );
140 if ( static_cast< long >( rS.Tell() ) != nExpectedPos )
142 // Strange error condition, shouldn't happen ( but does in at least
143 // one test document ) In the case where it happens the SwTBC &
144 // TBCHeader records seem blank??? ( and incorrect )
145 SAL_WARN_IF( static_cast< long >(rS.Tell()) != nExpectedPos, "sw.ww8","### Error: Expected pos not equal to actual pos after reading rtbdc");
146 SAL_INFO("sw.ww8","\tPos now is 0x" << std::hex << rS.Tell() << " should be 0x" << std::hex << nExpectedPos );
147 // seek to correct position after rtbdc
148 rS.Seek( nExpectedPos );
150 if ( cCust )
152 for ( sal_Int32 index = 0; index < cCust; ++index )
154 Customization aCust( this );
155 if ( !aCust.Read( rS ) )
156 return false;
157 rCustomizations.push_back( aCust );
160 std::vector< sal_Int16 >::iterator it_end = dropDownMenuIndices.end();
161 for ( std::vector< sal_Int16 >::iterator it = dropDownMenuIndices.begin(); it != it_end; ++it )
163 rCustomizations[ *it ].bIsDroppedMenuTB = true;
165 return true;
168 SwTBC* SwCTBWrapper::GetTBCAtOffset( sal_uInt32 nStreamOffset )
170 for ( std::vector< SwTBC >::iterator it = rtbdc.begin(); it != rtbdc.end(); ++it )
172 if ( (*it).GetOffset() == nStreamOffset )
173 return &(*it);
175 return NULL;
178 void SwCTBWrapper::Print( FILE* fp )
180 Indent a;
181 indent_printf(fp,"[ 0x%x ] SwCTBWrapper - dump\n", nOffSet );
182 bool bRes = ( ch == 0x12 && reserved2 == 0x0 && reserved3 == 0x7 && reserved4 == 0x6 && reserved5 == 0xC );
183 if ( bRes )
184 indent_printf(fp," sanity check ( first 8 bytes conform )\n");
185 else
187 indent_printf(fp," reserved1(0x%x)\n",ch);
188 indent_printf(fp," reserved2(0x%x)\n",reserved2);
189 indent_printf(fp," reserved3(0x%x)\n",reserved3);
190 indent_printf(fp," reserved4(0x%x)\n",reserved4);
191 indent_printf(fp," reserved5(0x%x)\n",reserved5);
192 indent_printf(fp,"Quiting dump");
193 return;
195 indent_printf(fp," size of TBDelta structures 0x%x\n", cbTBD );
196 indent_printf(fp," cCust: no. of cCust structures 0x%x\n",cCust);
197 indent_printf(fp," cbDTBC: no. of bytes in rtbdc array 0x%x\n", static_cast< unsigned int >( cbDTBC ));
199 sal_Int32 index = 0;
201 for ( std::vector< SwTBC >::iterator it = rtbdc.begin(); it != rtbdc.end(); ++it, ++index )
203 indent_printf(fp," Dumping rtbdc[%d]\n", static_cast< int >( index ));
204 Indent b;
205 it->Print( fp );
208 index = 0;
210 for ( std::vector< Customization >::iterator it = rCustomizations.begin(); it != rCustomizations.end(); ++it, ++index )
212 indent_printf(fp," Dumping custimization [%d]\n", static_cast< int >( index ));
213 Indent c;
214 it->Print(fp);
218 bool SwCTBWrapper::ImportCustomToolBar( SfxObjectShell& rDocSh )
220 for ( std::vector< Customization >::iterator it = rCustomizations.begin(); it != rCustomizations.end(); ++it )
224 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
225 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( ui::ModuleUIConfigurationManagerSupplier::create(xContext) );
226 CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( "com.sun.star.text.TextDocument" ) );
227 helper.setMSOCommandMap( new MSOWordCommandConvertor() );
229 if ( !(*it).ImportCustomToolBar( *this, helper ) )
230 return false;
232 catch(...)
234 continue;
237 return false;
240 Customization::Customization( SwCTBWrapper* wrapper ) : tbidForTBD( 0 )
241 ,reserved1( 0 )
242 , ctbds( 0 )
243 , pWrapper( wrapper )
244 , bIsDroppedMenuTB( false )
248 Customization::~Customization()
252 bool Customization::Read( SvStream &rS)
254 SAL_INFO("sw.ww8","Custimization::Read() stream pos 0x" << std::hex << rS.Tell() );
255 nOffSet = rS.Tell();
256 rS >> tbidForTBD >> reserved1 >> ctbds;
257 if ( tbidForTBD )
259 for ( sal_Int32 index = 0; index < ctbds; ++index )
261 TBDelta aTBDelta;
262 if (!aTBDelta.Read( rS ) )
263 return false;
264 customizationDataTBDelta.push_back( aTBDelta );
265 // Only set the drop down for menu's associated with standard toolbar
266 if ( aTBDelta.ControlDropsToolBar() && tbidForTBD == 0x25 )
267 pWrapper->InsertDropIndex( aTBDelta.CustomizationIndex() );
270 else
272 customizationDataCTB.reset( new SwCTB() );
273 if ( !customizationDataCTB->Read( rS ) )
274 return false;
276 return true;
279 void Customization::Print( FILE* fp )
281 Indent a;
282 indent_printf( fp,"[ 0x%x ] Customization -- dump \n", nOffSet );
283 indent_printf( fp," tbidForTBD 0x%x ( should be 0 for CTBs )\n", static_cast< unsigned int >( tbidForTBD ));
284 indent_printf( fp," reserved1 0x%x \n", reserved1);
285 indent_printf( fp," ctbds - number of customisations %d(0x%x) \n", ctbds, ctbds );
286 if ( !tbidForTBD && !ctbds )
287 customizationDataCTB->Print( fp );
288 else
290 const char* pToolBar = NULL;
291 switch ( tbidForTBD )
293 case 0x9:
294 pToolBar = "Standard";
295 break;
296 case 0x25:
297 pToolBar = "Builtin-Menu";
298 break;
299 default:
300 pToolBar = "Unknown toolbar";
301 break;
304 indent_printf( fp," TBDelta(s) are associated with %s toolbar.\n", pToolBar);
305 std::vector< TBDelta >::iterator it = customizationDataTBDelta.begin();
306 for ( sal_Int32 index = 0; index < ctbds; ++it,++index )
307 it->Print( fp );
312 bool Customization::ImportMenu( SwCTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
314 if ( tbidForTBD == 0x25 ) // we can handle in a limited way additions the built-in menu bar
316 for ( std::vector< TBDelta >::iterator it = customizationDataTBDelta.begin(); it != customizationDataTBDelta.end(); ++it )
318 // for each new menu ( control that drops a toolbar )
319 // import a toolbar
320 if ( it->ControlIsInserted() && it->ControlDropsToolBar() )
322 Customization* pCust = pWrapper->GetCustomizaton( it->CustomizationIndex() );
323 if ( pCust )
325 // currently only support built-in menu
326 OUString sMenuBar( "private:resource/menubar/" );
328 sMenuBar = sMenuBar.concat( "menubar" );
329 // Get menu name
330 SwTBC* pTBC = pWrapper->GetTBCAtOffset( it->TBCStreamOffset() );
331 if ( !pTBC )
332 return false;
333 OUString sMenuName = pTBC->GetCustomText();
334 sMenuName = sMenuName.replace('&','~');
336 // see if the document has already setting for the menubar
338 uno::Reference< container::XIndexContainer > xIndexContainer;
339 bool bHasSettings = false;
340 if ( helper.getCfgManager()->hasSettings( sMenuBar ) )
342 xIndexContainer.set( helper.getCfgManager()->getSettings( sMenuBar, sal_True ), uno::UNO_QUERY_THROW );
343 bHasSettings = true;
345 else
347 if ( helper.getAppCfgManager()->hasSettings( sMenuBar ) )
348 xIndexContainer.set( helper.getAppCfgManager()->getSettings( sMenuBar, sal_True ), uno::UNO_QUERY_THROW );
349 else
350 xIndexContainer.set( helper.getAppCfgManager()->createSettings(), uno::UNO_QUERY_THROW );
353 uno::Reference< lang::XSingleComponentFactory > xSCF( xIndexContainer, uno::UNO_QUERY_THROW );
354 uno::Reference< uno::XComponentContext > xContext(
355 comphelper::getProcessComponentContext() );
356 // create the popup menu
357 uno::Sequence< beans::PropertyValue > aPopupMenu( 4 );
358 aPopupMenu[0].Name = "CommandURL";
359 aPopupMenu[0].Value = uno::makeAny( OUString( "vnd.openoffice.org:" ) + sMenuName );
360 aPopupMenu[1].Name = "Label";
361 aPopupMenu[1].Value <<= sMenuName;
362 aPopupMenu[2].Name = "Type";
363 aPopupMenu[2].Value <<= sal_Int32( 0 );
364 aPopupMenu[3].Name = "ItemDescriptorContainer";
365 uno::Reference< container::XIndexContainer > xMenuContainer( xSCF->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
366 aPopupMenu[3].Value <<= xMenuContainer;
367 if ( pCust->customizationDataCTB.get() && !pCust->customizationDataCTB->ImportMenuTB( rWrapper, xMenuContainer, helper ) )
368 return false;
369 SAL_INFO("sw.ww8","** there are " << xIndexContainer->getCount() << " menu items on the bar, inserting after that");
370 xIndexContainer->insertByIndex( xIndexContainer->getCount(), uno::makeAny( aPopupMenu ) );
372 if ( bHasSettings )
373 helper.getCfgManager()->replaceSettings( sMenuBar, uno::Reference< container::XIndexAccess >( xIndexContainer, uno::UNO_QUERY_THROW ) );
374 else
375 helper.getCfgManager()->insertSettings( sMenuBar, uno::Reference< container::XIndexAccess >( xIndexContainer, uno::UNO_QUERY_THROW ) );
376 uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager(), uno::UNO_QUERY_THROW );
377 xPersistence->store();
381 return true;
383 return true;
386 bool Customization::ImportCustomToolBar( SwCTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
388 if ( GetTBIDForTB() == 0x25 )
389 return ImportMenu( rWrapper, helper );
390 if ( !customizationDataCTB.get() )
391 return false;
392 if ( !customizationDataCTB->IsMenuToolbar() )
394 if ( !customizationDataCTB->ImportCustomToolBar( rWrapper, helper ) )
395 return false;
397 return true;
400 TBDelta::TBDelta() : doprfatendFlags(0)
401 ,ibts(0)
402 ,cidNext(0)
403 ,cid(0)
404 ,fc(0)
405 ,cbTBC(0)
409 bool TBDelta::ControlIsModified()
411 return ( ( doprfatendFlags & 0x3 ) == 0x2 );
414 bool TBDelta::ControlIsInserted()
416 return ( ( doprfatendFlags & 0x3 ) == 0x1 );
419 bool TBDelta::ControlIsChanged()
421 return ( ( doprfatendFlags & 0x3 ) == 0x1 );
424 bool TBDelta::ControlDropsToolBar()
426 return !( CiTBDE & 0x8000 );
429 sal_Int32 TBDelta::TBCStreamOffset()
431 return fc;
434 sal_Int16 TBDelta::CustomizationIndex()
436 sal_Int16 nIndex = CiTBDE;
437 nIndex = nIndex >> 1;
438 nIndex &= 0x1ff; // only 13 bits are relevant
439 return nIndex;
442 bool TBDelta::Read(SvStream &rS)
444 SAL_INFO("sw.ww8","TBDelta::Read() stream pos 0x" << std::hex << rS.Tell() );
445 nOffSet = rS.Tell();
446 rS >> doprfatendFlags >> ibts >> cidNext >> cid >> fc ;
447 rS >> CiTBDE >> cbTBC;
448 return true;
451 void TBDelta::Print( FILE* fp )
453 // Like most of the debug output, it's raw and little ( no )
454 // interpretation of the data is output ( e.g. flag values etc. )
455 indent_printf( fp, "[ 0x%x ] TBDelta -- dump\n", nOffSet );
456 indent_printf( fp, " doprfatendFlags 0x%x\n",doprfatendFlags );
458 indent_printf( fp, " ibts 0x%x\n",ibts );
459 indent_printf( fp, " cidNext 0x%x\n", static_cast< unsigned int >( cidNext ) );
460 indent_printf( fp, " cid 0x%x\n", static_cast< unsigned int >( cid ) );
461 indent_printf( fp, " fc 0x%x\n", static_cast< unsigned int >( fc ) );
462 indent_printf( fp, " CiTBDE 0x%x\n",CiTBDE );
463 indent_printf( fp, " cbTBC 0x%x\n", cbTBC );
464 if ( ControlDropsToolBar() )
466 indent_printf( fp, " this delta is associated with a control that drops a menu toolbar\n", cbTBC );
467 indent_printf( fp, " the menu toolbar drops the toolbar defined at index[%d] in the rCustomizations array of the CTBWRAPPER that contains this TBDelta\n", CustomizationIndex() );
471 SwCTB::SwCTB() : cbTBData( 0 )
472 ,iWCTBl( 0 )
473 ,reserved( 0 )
474 ,unused( 0 )
475 ,cCtls( 0 )
479 SwCTB::~SwCTB()
483 bool SwCTB::IsMenuToolbar()
485 return tb.IsMenuToolbar();
489 bool SwCTB::Read( SvStream &rS)
491 SAL_INFO("sw.ww8","SwCTB::Read() stream pos 0x" << std::hex << rS.Tell() );
492 nOffSet = rS.Tell();
493 if ( !name.Read( rS ) )
494 return false;
495 rS >> cbTBData;
496 if ( !tb.Read( rS ) )
497 return false;
498 for ( short index = 0; index < nVisualData; ++index )
500 TBVisualData aVisData;
501 aVisData.Read( rS );
502 rVisualData.push_back( aVisData );
505 rS >> iWCTBl >> reserved >> unused >> cCtls;
507 if ( cCtls )
509 for ( sal_Int32 index = 0; index < cCtls; ++index )
511 SwTBC aTBC;
512 if ( !aTBC.Read( rS ) )
513 return false;
514 rTBC.push_back( aTBC );
517 return true;
520 void
521 SwCTB::Print( FILE* fp )
523 Indent a;
524 indent_printf(fp, "[ 0x%x ] SwCTB - dump\n", nOffSet );
525 indent_printf(fp, " name %s\n", OUStringToOString( name.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
526 indent_printf(fp, " cbTBData size, in bytes, of this structure excluding the name, cCtls, and rTBC fields. %x\n", static_cast< unsigned int >( cbTBData ) );
528 tb.Print(fp);
529 for ( short counter = 0; counter < nVisualData; ++counter )
531 indent_printf( fp, " TBVisualData [%d]\n", counter);
532 Indent b;
533 rVisualData[ counter ].Print( fp );
535 indent_printf(fp, " iWCTBl 0x%x reserved 0x%x unused 0x%x cCtls( toolbar controls ) 0x%x \n", static_cast< unsigned int >( iWCTBl ), reserved, unused, static_cast< unsigned int >( cCtls ) );
536 if ( cCtls )
538 for ( sal_Int32 index = 0; index < cCtls; ++index )
541 indent_printf(fp, " dumping toolbar control 0x%x\n", static_cast< unsigned int >( index ) );
542 rTBC[ index ].Print( fp );
547 bool SwCTB::ImportCustomToolBar( SwCTBWrapper& rWrapper, CustomToolBarImportHelper& helper )
549 static OUString sToolbarPrefix( "private:resource/toolbar/custom_" );
550 bool bRes = false;
553 if ( !tb.IsEnabled() )
554 return true; // didn't fail, just ignoring
555 // Create default setting
556 uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_QUERY_THROW );
557 uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
558 uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
560 // set UI name for toolbar
561 xProps->setPropertyValue( "UIName", uno::makeAny( name.getString() ) );
563 OUString sToolBarName = sToolbarPrefix.concat( name.getString() );
564 for ( std::vector< SwTBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it )
566 // createToolBar item for control
567 if ( !it->ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
568 return false;
571 SAL_INFO("sw.ww8","Name of toolbar :-/ " << sToolBarName );
573 helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
574 helper.applyIcons();
575 #if 1 // don't think this is necessary
576 uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
577 xPersistence->store();
579 xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
580 xPersistence->store();
581 #endif
582 bRes = true;
584 catch( const uno::Exception& e )
586 SAL_INFO("sw.ww8","***** For some reason we have an exception " << e.Message );
587 bRes = false;
589 return bRes;
592 bool SwCTB::ImportMenuTB( SwCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xIndexContainer, CustomToolBarImportHelper& rHelper )
594 for ( std::vector< SwTBC >::iterator it = rTBC.begin(); it != rTBC.end(); ++it )
596 // createToolBar item for control
597 if ( !it->ImportToolBarControl( rWrapper, xIndexContainer, rHelper, true ) )
598 return false;
600 return true;
603 SwTBC::SwTBC()
607 SwTBC::~SwTBC()
611 bool SwTBC::Read( SvStream &rS )
613 SAL_INFO("sw.ww8","SwTBC::Read() stream pos 0x" << std::hex << rS.Tell() );
614 nOffSet = rS.Tell();
615 if ( !tbch.Read( rS ) )
616 return false;
617 if ( tbch.getTcID() != 0x1 && tbch.getTcID() != 0x1051 )
619 cid.reset( new sal_uInt32 );
620 rS >> *cid;
622 // MUST exist if tbch.tct is not equal to 0x16
623 if ( tbch.getTct() != 0x16 )
625 tbcd.reset( new TBCData( tbch ) );
626 if ( !tbcd->Read( rS ) )
627 return false;
629 return true;
632 void SwTBC::Print( FILE* fp )
634 Indent a;
635 indent_printf(fp,"[ 0x%x ] SwTBC -- dump\n", nOffSet );
636 indent_printf(fp," dumping header ( TBCHeader )\n");
637 tbch.Print( fp );
638 if ( cid.get() )
639 indent_printf(fp," cid = 0x%x\n", static_cast< unsigned int >( *cid ) );
640 if ( tbcd.get() )
642 indent_printf(fp," dumping toolbar data TBCData \n");
643 tbcd->Print(fp);
647 bool
648 SwTBC::ImportToolBarControl( SwCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuBar )
650 // cmtFci 0x1 Command based on a built-in command. See CidFci.
651 // cmtMacro 0x2 Macro command. See CidMacro.
652 // cmtAllocated 0x3 Allocated command. See CidAllocated.
653 // cmtNil 0x7 No command. See Cid.
654 bool bBuiltin = false;
655 sal_uInt16 cmdId = 0;
656 if ( cid.get() )
658 sal_uInt16 arg2 = ( *( cid.get() ) & 0xFFFF );
660 sal_uInt8 cmt = ( arg2 & 0x7 );
661 arg2 = ( arg2 >> 3 );
663 switch ( cmt )
665 case 1:
666 SAL_INFO("sw.ww8","cmt is cmtFci builtin command 0x" << std::hex << arg2);
667 bBuiltin = true;
668 cmdId = arg2;
669 break;
670 case 2:
671 SAL_INFO("sw.ww8","cmt is cmtMacro macro 0x" << std::hex << arg2);
672 break;
673 case 3:
674 SAL_INFO("sw.ww8","cmt is cmtAllocated [???] 0x" << std::hex << arg2);
675 break;
676 case 7:
677 SAL_INFO("sw.ww8","cmt is cmNill no-phing 0x" << std::hex << arg2);
678 break;
679 default:
680 SAL_INFO("sw.ww8","illegal 0x" << std::hex << cmt);
681 break;
685 if ( tbcd.get() )
687 std::vector< css::beans::PropertyValue > props;
688 if ( bBuiltin )
690 OUString sCommand = helper.MSOCommandToOOCommand( cmdId );
691 if ( !sCommand.isEmpty() )
693 beans::PropertyValue aProp;
695 aProp.Name = "CommandURL";
696 aProp.Value <<= sCommand;
697 props.push_back( aProp );
700 bool bBeginGroup = false;
701 if ( ! tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuBar ) )
702 return false;
704 TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
705 if ( pMenu )
707 SAL_INFO("sw.ww8","** control has a menu, name of toolbar with menu items is " << pMenu->Name() );
708 // search for SwCTB with the appropriate name ( it contains the
709 // menu items, although we cannot import ( or create ) a menu on
710 // a custom toolbar we can import the menu items in a separate
711 // toolbar ( better than nothing )
712 SwCTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
713 if ( pCustTB )
715 uno::Reference< container::XIndexContainer > xMenuDesc = document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
716 if ( !pCustTB->ImportMenuTB( rWrapper,xMenuDesc, helper ) )
717 return false;
718 if ( !bIsMenuBar )
720 if ( !helper.createMenu( pMenu->Name(), uno::Reference< container::XIndexAccess >( xMenuDesc, uno::UNO_QUERY ), true ) )
721 return false;
723 else
725 beans::PropertyValue aProp;
726 aProp.Name = "ItemDescriptorContainer";
727 aProp.Value <<= xMenuDesc;
728 props.push_back( aProp );
733 if ( bBeginGroup )
735 // insert spacer
736 uno::Sequence< beans::PropertyValue > sProps( 1 );
737 sProps[ 0 ].Name = "Type";
738 sProps[ 0 ].Value = uno::makeAny( ui::ItemType::SEPARATOR_LINE );
739 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
742 uno::Sequence< beans::PropertyValue > sProps( props.size() );
743 beans::PropertyValue* pProp = sProps.getArray();
745 for ( std::vector< css::beans::PropertyValue >::iterator it = props.begin(); it != props.end(); ++it, ++pProp )
746 *pProp = *it;
748 toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
750 return true;
753 OUString
754 SwTBC::GetCustomText()
756 OUString sCustomText;
757 if ( tbcd.get() )
758 sCustomText = tbcd->getGeneralInfo().CustomText();
759 return sCustomText;
764 bool
765 Xst::Read( SvStream& rS )
767 SAL_INFO("sw.ww8","Xst::Read() stream pos 0x" << std::hex << rS.Tell() );
768 nOffSet = rS.Tell();
769 sString = read_uInt16_PascalString(rS);
770 return true;
773 void
774 Xst::Print( FILE* fp )
776 Indent a;
777 indent_printf( fp, "[ 0x%x ] Xst -- dump\n", nOffSet );
778 indent_printf( fp, " %s", OUStringToOString( sString, RTL_TEXTENCODING_UTF8 ).getStr() );
781 Tcg::Tcg() : nTcgVer( -1 )
785 bool Tcg::Read(SvStream &rS)
787 SAL_INFO("sw.ww8","Tcg::Read() stream pos 0x" << std::hex << rS.Tell() );
788 nOffSet = rS.Tell();
789 rS >> nTcgVer;
790 if ( nTcgVer != -1 )
791 return false;
792 tcg.reset( new Tcg255() );
793 return tcg->Read( rS );
796 void Tcg::Print( FILE* fp )
798 Indent a(true);
799 indent_printf(fp, "[ 0x%x ] Tcg - dump %d\n", nOffSet, nTcgVer);
800 indent_printf(fp," nTcgVer %d\n", nTcgVer);
801 if ( tcg.get() )
802 tcg->Print( fp );
805 bool Tcg::ImportCustomToolBar( SfxObjectShell& rDocSh )
807 if ( tcg.get() )
808 return tcg->ImportCustomToolBar( rDocSh );
809 return false;
812 Tcg255::Tcg255()
816 Tcg255::~Tcg255()
818 std::vector< Tcg255SubStruct* >::iterator it = rgtcgData.begin();
819 for ( ; it != rgtcgData.end(); ++it )
820 delete *it;
823 bool Tcg255::processSubStruct( sal_uInt8 nId, SvStream &rS )
825 Tcg255SubStruct* pSubStruct = NULL;
826 switch ( nId )
828 case 0x1:
830 pSubStruct = new PlfMcd( false ); // don't read the id
831 break;
833 case 0x2:
835 pSubStruct = new PlfAcd( false );
836 break;
838 case 0x3:
839 case 0x4:
841 pSubStruct = new PlfKme( false );
842 break;
844 case 0x10:
846 pSubStruct = new TcgSttbf( false );
847 break;
849 case 0x11:
851 pSubStruct = new MacroNames( false );
852 break;
854 case 0x12:
856 pSubStruct = new SwCTBWrapper( false );
857 break;
859 default:
860 SAL_INFO("sw.ww8","Unknown id 0x" << std::hex << nId);
861 return false;
863 pSubStruct->ch = nId;
864 if ( !pSubStruct->Read( rS ) )
865 return false;
866 rgtcgData.push_back( pSubStruct );
867 return true;
870 bool Tcg255::ImportCustomToolBar( SfxObjectShell& rDocSh )
872 // Find the SwCTBWrapper
873 for ( std::vector< Tcg255SubStruct* >::const_iterator it = rgtcgData.begin(); it != rgtcgData.end(); ++it )
875 if ( (*it)->id() == 0x12 )
877 // not so great, shouldn't really have to do a horror casting
878 SwCTBWrapper* pCTBWrapper = dynamic_cast< SwCTBWrapper* > ( *it );
879 if ( pCTBWrapper )
881 if ( !pCTBWrapper->ImportCustomToolBar( rDocSh ) )
882 return false;
886 return true;
890 bool Tcg255::Read(SvStream &rS)
892 SAL_INFO("sw.ww8","Tcg255::Read() stream pos 0x" << std::hex << rS.Tell() );
893 nOffSet = rS.Tell();
894 sal_uInt8 nId = 0x40;
895 rS >> nId;
896 while ( nId != 0x40 )
898 if ( !processSubStruct( nId, rS ) )
899 return false;
900 nId = 0x40;
901 rS >> nId;
903 return true;
904 // Peek at
907 void Tcg255::Print( FILE* fp)
909 Indent a;
910 indent_printf(fp, "[ 0x%x ] Tcg255 - dump\n", nOffSet );
911 indent_printf(fp, " contains %d sub records\n", rgtcgData.size() );
912 std::vector< Tcg255SubStruct* >::iterator it = rgtcgData.begin();
913 std::vector< Tcg255SubStruct* >::iterator it_end = rgtcgData.end();
915 for( sal_Int32 count = 1; it != it_end ; ++it, ++count )
917 Indent b;
918 indent_printf(fp, " [%d] Tcg255SubStruct \n", static_cast< unsigned int >( count ) );
919 (*it)->Print(fp);
924 Tcg255SubStruct::Tcg255SubStruct( bool bReadId ) : mbReadId( bReadId ), ch(0)
928 bool Tcg255SubStruct::Read(SvStream &rS)
930 SAL_INFO("sw.ww8","Tcg255SubStruct::Read() stream pos 0x" << std::hex << rS.Tell() );
931 nOffSet = rS.Tell();
932 if ( mbReadId )
933 rS >> ch;
934 return true;
937 PlfMcd::PlfMcd(bool bReadId)
938 : Tcg255SubStruct(bReadId)
939 , iMac(0)
943 bool PlfMcd::Read(SvStream &rS)
945 SAL_INFO("sw.ww8","PffMcd::Read() stream pos 0x" << std::hex << rS.Tell() );
946 nOffSet = rS.Tell();
947 Tcg255SubStruct::Read( rS );
948 rS >> iMac;
949 if ( iMac )
951 rgmcd.resize(iMac);
952 for ( sal_Int32 index = 0; index < iMac; ++index )
954 if ( !rgmcd[ index ].Read( rS ) )
955 return false;
958 return true;
961 void PlfMcd::Print( FILE* fp )
963 Indent a;
964 indent_printf(fp, "[ 0x%x ] PlfMcd ( Tcg255SubStruct ) - dump\n", nOffSet );
965 indent_printf(fp, " contains %d MCD records\n", static_cast<int>( iMac ) );
966 for ( sal_Int32 count=0; count < iMac; ++count )
968 Indent b;
969 indent_printf(fp, "[%d] MCD\n", static_cast< int >( count ) );
970 rgmcd[ count ].Print( fp );
975 PlfAcd::PlfAcd( bool bReadId ) : Tcg255SubStruct( bReadId )
976 ,iMac(0)
977 ,rgacd(NULL)
982 PlfAcd::~PlfAcd()
984 if ( rgacd )
985 delete[] rgacd;
988 bool PlfAcd::Read( SvStream &rS)
990 SAL_INFO("sw.ww8","PffAcd::Read() stream pos 0x" << std::hex << rS.Tell() );
991 nOffSet = rS.Tell();
992 Tcg255SubStruct::Read( rS );
993 rS >> iMac;
994 if ( iMac )
996 rgacd = new Acd[ iMac ];
997 for ( sal_Int32 index = 0; index < iMac; ++index )
999 if ( !rgacd[ index ].Read( rS ) )
1000 return false;
1003 return true;
1005 void PlfAcd::Print( FILE* fp )
1007 Indent a;
1008 indent_printf(fp, "[ 0x%x ] PlfAcd ( Tcg255SubStruct ) - dump\n", nOffSet );
1009 indent_printf(fp, " contains %d ACD records\n", static_cast< int >( iMac ) );
1010 for ( sal_Int32 count=0; count < iMac; ++count )
1012 Indent b;
1013 indent_printf(fp, "[%d] ACD\n", static_cast< int >( count ) );
1014 rgacd[ count ].Print( fp );
1019 PlfKme::PlfKme( bool bReadId ) : Tcg255SubStruct( bReadId )
1020 ,iMac( 0 )
1021 ,rgkme( NULL )
1025 PlfKme::~PlfKme()
1027 if ( rgkme )
1028 delete[] rgkme;
1031 bool PlfKme::Read(SvStream &rS)
1033 SAL_INFO("sw.ww8","PlfKme::Read() stream pos 0x" << std::hex << rS.Tell() );
1034 nOffSet = rS.Tell();
1035 Tcg255SubStruct::Read( rS );
1036 rS >> iMac;
1037 if ( iMac )
1039 rgkme = new Kme[ iMac ];
1040 for( sal_Int32 index=0; index<iMac; ++index )
1042 if ( !rgkme[ index ].Read( rS ) )
1043 return false;
1046 return true;
1049 void PlfKme::Print( FILE* fp )
1051 Indent a;
1052 indent_printf(fp, "[ 0x%x ] PlfKme ( Tcg255SubStruct ) - dump\n", nOffSet );
1053 indent_printf(fp, " contains %d Kme records\n", static_cast< int >( iMac ) );
1054 for ( sal_Int32 count=0; count < iMac; ++count )
1056 Indent b;
1057 indent_printf(fp, "[%d] Kme\n", static_cast< int >( count ) );
1058 rgkme[ count ].Print( fp );
1063 TcgSttbf::TcgSttbf( bool bReadId ) : Tcg255SubStruct( bReadId )
1067 bool TcgSttbf::Read( SvStream &rS)
1069 SAL_INFO("sw.ww8","TcgSttbf::Read() stream pos 0x" << std::hex << rS.Tell() );
1070 nOffSet = rS.Tell();
1071 Tcg255SubStruct::Read( rS );
1072 return sttbf.Read( rS );
1075 void TcgSttbf::Print( FILE* fp )
1077 Indent a;
1078 indent_printf(fp,"[ 0x%x ] TcgSttbf - dump\n", nOffSet );
1079 sttbf.Print( fp );
1082 TcgSttbfCore::TcgSttbfCore() : fExtend( 0 )
1083 ,cData( 0 )
1084 ,cbExtra( 0 )
1085 ,dataItems( NULL )
1089 TcgSttbfCore::~TcgSttbfCore()
1091 if ( dataItems )
1092 delete[] dataItems;
1095 bool TcgSttbfCore::Read( SvStream& rS )
1097 SAL_INFO("sw.ww8","TcgSttbfCore::Read() stream pos 0x" << std::hex << rS.Tell() );
1098 nOffSet = rS.Tell();
1099 rS >> fExtend >> cData >> cbExtra;
1100 if ( cData )
1102 dataItems = new SBBItem[ cData ];
1103 for ( sal_Int32 index = 0; index < cData; ++index )
1105 rS >> dataItems[ index ].cchData;
1106 dataItems[ index ].data = read_uInt16s_ToOUString(rS, dataItems[index].cchData);
1107 rS >> dataItems[ index ].extraData;
1110 return true;
1113 void TcgSttbfCore::Print( FILE* fp )
1115 Indent a;
1116 indent_printf( fp, "[ 0x%x ] TcgSttbfCore - dump\n");
1117 indent_printf( fp, " fExtend 0x%x [expected 0xFFFF ]\n", fExtend );
1118 indent_printf( fp, " cbExtra 0x%x [expected 0x02 ]\n", cbExtra );
1119 indent_printf( fp, " cData no. or string data items %d (0x%x)\n", cData, cData );
1121 if ( cData )
1123 for ( sal_Int32 index = 0; index < cData; ++index )
1124 indent_printf(fp," string dataItem[ %d(0x%x) ] has name %s and if referenced %d times.\n", static_cast< int >( index ), static_cast< unsigned int >( index ), OUStringToOString( dataItems[ index ].data, RTL_TEXTENCODING_UTF8 ).getStr(), dataItems[ index ].extraData );
1128 MacroNames::MacroNames( bool bReadId ) : Tcg255SubStruct( bReadId )
1129 ,iMac( 0 )
1130 ,rgNames( NULL )
1134 MacroNames::~MacroNames()
1136 if ( rgNames )
1137 delete[] rgNames;
1140 bool MacroNames::Read( SvStream &rS)
1142 SAL_INFO("sw.ww8","MacroNames::Read() stream pos 0x" << std::hex << rS.Tell() );
1143 nOffSet = rS.Tell();
1144 Tcg255SubStruct::Read( rS );
1145 rS >> iMac;
1146 if ( iMac )
1148 rgNames = new MacroName[ iMac ];
1149 for ( sal_Int32 index = 0; index < iMac; ++index )
1151 if ( !rgNames[ index ].Read( rS ) )
1152 return false;
1155 return true;
1158 void MacroNames::Print( FILE* fp )
1160 Indent a;
1161 indent_printf(fp, "[ 0x%x ] MacroNames ( Tcg255SubStruct ) - dump\n");
1162 indent_printf(fp, " contains %d MacroName records\n", iMac );
1163 for ( sal_Int32 count=0; count < iMac; ++count )
1165 Indent b;
1166 indent_printf(fp, "[%d] MacroName\n", static_cast<int>( count ) );
1167 rgNames[ count ].Print( fp );
1172 MacroName::MacroName():ibst(0)
1177 bool MacroName::Read(SvStream &rS)
1179 SAL_INFO("sw.ww8","MacroName::Read() stream pos 0x" << std::hex << rS.Tell() );
1180 nOffSet = rS.Tell();
1181 rS >> ibst;
1182 return xstz.Read( rS );
1185 void MacroName::Print( FILE* fp )
1187 Indent a;
1188 indent_printf( fp, "[ 0x%x ] MacroName - dump");
1189 indent_printf( fp," index - 0x%x has associated following record\n", ibst );
1190 xstz.Print( fp );
1195 Xstz::Xstz():chTerm(0)
1199 bool
1200 Xstz::Read(SvStream &rS)
1202 SAL_INFO("sw.ww8","Xstz::Read() stream pos 0x" << std::hex << rS.Tell() );
1203 nOffSet = rS.Tell();
1204 if ( !xst.Read( rS ) )
1205 return false;
1206 rS >> chTerm;
1207 if ( chTerm != 0 ) // should be an assert
1208 return false;
1209 return true;
1212 void Xstz::Print( FILE* fp )
1214 Indent a;
1215 indent_printf(fp,"[ 0x%x ] Xstz -- dump\n", nOffSet );
1216 indent_printf(fp," Xst\n");
1217 xst.Print( fp );
1218 indent_printf(fp," chterm 0x%x ( should be zero )\n", chTerm);
1221 Kme::Kme() : reserved1(0)
1222 ,reserved2(0)
1223 ,kcm1(0)
1224 ,kcm2(0)
1225 ,kt(0)
1226 ,param(0)
1230 Kme::~Kme()
1234 bool
1235 Kme::Read(SvStream &rS)
1237 SAL_INFO("sw.ww8","Kme::Read() stream pos 0x" << std::hex << rS.Tell() );
1238 nOffSet = rS.Tell();
1239 rS >> reserved1 >> reserved2 >> kcm1 >> kcm2 >> kt >> param;
1240 return true;
1243 void Kme::Print( FILE* fp )
1245 Indent a;
1247 indent_printf( fp, "[ 0x%x ] Kme - dump\n", nOffSet );
1248 indent_printf( fp, " reserved1 0x%x [expected 0x0 ]\n", reserved1 );
1249 indent_printf( fp, " reserved2 0x%x [expected 0x0 ]\n", reserved2 );
1250 indent_printf( fp, " kcm1 0x%x [shortcut key]\n", kcm1 );
1251 indent_printf( fp, " kcm2 0x%x [shortcut key]\n", kcm2 );
1252 indent_printf( fp, " kt 0x%x \n", kt );
1253 indent_printf( fp, " param 0x%x \n", static_cast< unsigned int >( param ) );
1256 Acd::Acd() : ibst( 0 )
1257 , fciBasedOnABC( 0 )
1261 bool Acd::Read(SvStream &rS)
1263 SAL_INFO("sw.ww8","Acd::Read() stream pos 0x" << std::hex << rS.Tell() );
1264 nOffSet = rS.Tell();
1265 rS >> ibst >> fciBasedOnABC;
1266 return true;
1269 void Acd::Print( FILE* fp )
1271 Indent a;
1272 indent_printf( fp,"[ 0x%x ] ACD - dump\n", nOffSet );
1273 // #TODO flesh out interpretation of these values
1274 indent_printf( fp," ibst 0x%x\n", ibst);
1275 indent_printf( fp," fciBaseObABC 0x%x\n", fciBasedOnABC);
1278 MCD::MCD() : reserved1(0x56)
1279 ,reserved2( 0 )
1280 ,ibst( 0 )
1281 ,ibstName( 0 )
1282 ,reserved3( 0xFFFF )
1283 ,reserved4( 0 )
1284 ,reserved5( 0 )
1285 ,reserved6( 0 )
1286 ,reserved7( 0 )
1290 MCD::MCD(const MCD& rO)
1291 : TBBase(rO)
1292 , reserved1(rO.reserved1)
1293 , reserved2(rO.reserved2)
1294 , ibst(rO.ibst)
1295 , ibstName(rO.ibstName)
1296 , reserved3(rO.reserved3)
1297 , reserved4(rO.reserved4)
1298 , reserved5(rO.reserved5)
1299 , reserved6(rO.reserved6)
1300 , reserved7(rO.reserved7)
1304 MCD& MCD::operator=(const MCD& rO)
1306 if (this != &rO)
1308 reserved1 = rO.reserved1;
1309 reserved2 = rO.reserved2;
1310 ibst = rO.ibst;
1311 ibstName = rO.ibstName;
1312 reserved3 = rO.reserved3;
1313 reserved4 = rO.reserved4;
1314 reserved5 = rO.reserved5;
1315 reserved6 = rO.reserved6;
1316 reserved7 = rO.reserved7;
1318 return *this;
1321 bool MCD::Read(SvStream &rS)
1323 SAL_INFO("sw.ww8","MCD::Read() stream pos 0x" << rS.Tell() );
1324 nOffSet = rS.Tell();
1325 rS >> reserved1 >> reserved2 >> ibst >> ibstName >> reserved3;
1326 rS >> reserved4 >> reserved5 >> reserved6 >> reserved7;
1327 return true;
1330 void MCD::Print( FILE* fp )
1332 Indent a;
1333 indent_printf( fp, "[ 0x%x ] MCD - dump\n", nOffSet );
1334 indent_printf( fp, " reserved1 0x%x [expected 0x56 ]\n", reserved1 );
1335 indent_printf( fp, " reserved2 0x%x [expected 0x0 ]\n", reserved2 );
1336 indent_printf( fp, " ibst 0x%x specifies macro with MacroName.xstz = 0x%x\n", ibst, ibst );
1337 indent_printf( fp, " ibstName 0x%x index into command string table ( TcgSttbf.sttbf )\n", ibstName );
1339 indent_printf( fp, " reserved3 0x%x [expected 0xFFFF ]\n", reserved3 );
1340 indent_printf( fp, " reserved4 0x%x\n", static_cast< unsigned int >( reserved4 ) );
1341 indent_printf( fp, " reserved5 0x%x [expected 0x0 ]\n", static_cast< unsigned int >( reserved5 ) );
1342 indent_printf( fp, " reserved6 0x%x\n", static_cast< unsigned int >( reserved6 ) );
1343 indent_printf( fp, " reserved7 0x%x\n", static_cast< unsigned int >( reserved7 ) );
1346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */