LibreOffice Module sc (master)  1
xltoolbar.cxx
Go to the documentation of this file.
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 <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>
17 #include <comphelper/sequence.hxx>
18 #include <map>
19 
20 using namespace com::sun::star;
21 
22 typedef std::map< sal_Int16, OUString > IdToString;
23 
24 namespace {
25 
26 class MSOExcelCommandConvertor : public MSOCommandConvertor
27 {
28  IdToString msoToOOcmd;
29  IdToString tcidToOOcmd;
30 public:
31  MSOExcelCommandConvertor();
32  virtual OUString MSOCommandToOOCommand( sal_Int16 msoCmd ) override;
33  virtual OUString MSOTCIDToOOCommand( sal_Int16 key ) override;
34 };
35 
36 }
37 
38 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 }
51 
52 OUString MSOExcelCommandConvertor::MSOCommandToOOCommand( sal_Int16 key )
53 {
54  OUString sResult;
55  IdToString::iterator it = msoToOOcmd.find( key );
56  if ( it != msoToOOcmd.end() )
57  sResult = it->second;
58  return sResult;
59 }
60 
61 OUString MSOExcelCommandConvertor::MSOTCIDToOOCommand( sal_Int16 key )
62 {
63  OUString sResult;
64  IdToString::iterator it = tcidToOOcmd.find( key );
65  if ( it != tcidToOOcmd.end() )
66  sResult = it->second;
67  return sResult;
68 }
69 
70 CTBS::CTBS() : bSignature(0), bVersion(0), reserved1(0), reserved2(0), reserved3(0), ctb(0), ctbViews(0), ictbView(0)
71 {
72 }
73 
74 ScCTB::ScCTB(sal_uInt16 nNum ) : nViews( nNum ), ectbid(0)
75 {
76 }
77 
78 bool ScCTB::Read( SvStream &rS )
79 {
80  SAL_INFO("sc.filter", "stream pos " << rS.Tell());
81  nOffSet = rS.Tell();
82  tb.Read( rS );
83  for ( sal_uInt16 index = 0; index < nViews; ++index )
84  {
85  TBVisualData aVisData;
86  aVisData.Read( rS );
87  rVisualData.push_back( aVisData );
88  }
89  rS.ReadUInt32( ectbid );
90 
91  for ( sal_Int16 index = 0; index < tb.getcCL(); ++index )
92  {
93  ScTBC aTBC;
94  aTBC.Read( rS );
95  rTBC.push_back( aTBC );
96  }
97  return true;
98 }
99 
100 #ifdef DEBUG_SC_EXCEL
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  sal_Int32 counter = 0;
109  for ( auto& rItem : rVisualData )
110  {
111  indent_printf( fp, " TBVisualData [%d]\n", counter++ );
112  Indent b;
113  rItem.Print( fp );
114  }
115  indent_printf( fp, " ectbid 0x%x\n", ectbid);
116  counter = 0;
117  for ( auto& rItem : rTBC )
118  {
119  indent_printf( fp, " ScTBC [%d]\n", counter++);
120  Indent c;
121  rItem.Print( fp );
122  }
123 }
124 #endif
125 
127 {
128  return tb.IsMenuToolbar();
129 }
130 
131 bool ScCTB::ImportMenuTB( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& xMenuDesc, CustomToolBarImportHelper& helper )
132 {
133  for ( auto& rItem : rTBC )
134  {
135  if ( !rItem.ImportToolBarControl( rWrapper, xMenuDesc, helper, IsMenuToolbar() ) )
136  return false;
137  }
138  return true;
139 }
140 
142 {
143 
144  bool bRes = false;
145  try
146  {
147  if ( !tb.IsEnabled() )
148  return true; // didn't fail, just ignoring
149 
150  // Create default setting
151  uno::Reference< container::XIndexContainer > xIndexContainer( helper.getCfgManager()->createSettings(), uno::UNO_SET_THROW );
152  uno::Reference< container::XIndexAccess > xIndexAccess( xIndexContainer, uno::UNO_QUERY_THROW );
153  uno::Reference< beans::XPropertySet > xProps( xIndexContainer, uno::UNO_QUERY_THROW );
154  WString& name = tb.getName();
155  // set UI name for toolbar
156  xProps->setPropertyValue("UIName", uno::makeAny( name.getString() ) );
157 
158  OUString sToolBarName = "private:resource/toolbar/custom_" + name.getString();
159  for ( auto& rItem : rTBC )
160  {
161  if ( !rItem.ImportToolBarControl( rWrapper, xIndexContainer, helper, IsMenuToolbar() ) )
162  return false;
163  }
164 
165  helper.getCfgManager()->insertSettings( sToolBarName, xIndexAccess );
166  helper.applyIcons();
167 
168  uno::Reference< ui::XUIConfigurationPersistence > xPersistence( helper.getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
169  xPersistence->store();
170 
171  xPersistence.set( helper.getCfgManager(), uno::UNO_QUERY_THROW );
172  xPersistence->store();
173 
174  bRes = true;
175  }
176  catch( uno::Exception& )
177  {
178  bRes = false;
179  }
180  return bRes;
181 }
182 bool CTBS::Read( SvStream &rS )
183 {
184  SAL_INFO("sc.filter", "stream pos " << rS.Tell());
185  nOffSet = rS.Tell();
187  return true;
188 }
189 
190 #ifdef DEBUG_SC_EXCEL
191 void CTBS::Print( FILE* fp )
192 {
193  Indent a;
194  indent_printf( fp, "[ 0x%x ] CTBS -- dump\n", nOffSet );
195 
196  indent_printf( fp, " bSignature 0x%x\n", bSignature);
197  indent_printf( fp, " bVersion 0x%x\n", bVersion);
198 
199  indent_printf( fp, " reserved1 0x%x\n", reserved1 );
200  indent_printf( fp, " reserved2 0x%x\n", reserved2 );
201  indent_printf( fp, " reserved3 0x%x\n", reserved3 );
202 
203  indent_printf( fp, " ctb 0x%x\n", ctb );
204  indent_printf( fp, " ctbViews 0x%x\n", ctbViews );
205  indent_printf( fp, " ictbView 0x%x\n", ictbView );
206 }
207 #endif
208 
210 {
211 }
212 
213 bool
215 {
216  SAL_INFO("sc.filter", "stream pos " << rS.Tell());
217  nOffSet = rS.Tell();
218  if ( !tbch.Read( rS ) )
219  return false;
220  sal_uInt16 tcid = tbch.getTcID();
221  sal_uInt8 tct = tbch.getTct();
222  if ( ( tcid != 0x0001 && tcid != 0x06CC && tcid != 0x03D8 && tcid != 0x03EC && tcid != 0x1051 ) && ( ( tct > 0 && tct < 0x0B ) || ( ( tct > 0x0B && tct < 0x10 ) || tct == 0x15 ) ) )
223  {
224  tbcCmd = std::make_shared<TBCCmd>();
225  if ( ! tbcCmd->Read( rS ) )
226  return false;
227  }
228  if ( tct != 0x16 )
229  {
230  tbcd = std::make_shared<TBCData>( tbch );
231  if ( !tbcd->Read( rS ) )
232  return false;
233  }
234  return true;
235 }
236 
237 #ifdef DEBUG_SC_EXCEL
238 void
239 ScTBC::Print(FILE* fp)
240 {
241  Indent a;
242  indent_printf( fp, "[ 0x%x ] ScTBC -- dump\n", nOffSet );
243  tbch.Print( fp );
244  if ( tbcCmd.get() )
245  tbcCmd->Print( fp );
246  if ( tbcd.get() )
247  tbcd->Print( fp );
248 }
249 #endif
250 
251 bool ScTBC::ImportToolBarControl( ScCTBWrapper& rWrapper, const css::uno::Reference< css::container::XIndexContainer >& toolbarcontainer, CustomToolBarImportHelper& helper, bool bIsMenuToolbar )
252 {
253  // how to identify built-in-command ?
254 // bool bBuiltin = false;
255  if ( tbcd )
256  {
257  std::vector< css::beans::PropertyValue > props;
258  bool bBeginGroup = false;
259  tbcd->ImportToolBarControl( helper, props, bBeginGroup, bIsMenuToolbar );
260  TBCMenuSpecific* pMenu = tbcd->getMenuSpecific();
261  if ( pMenu )
262  {
263  // search for ScCTB with the appropriate name ( it contains the
264  // menu items, although we cannot import ( or create ) a menu on
265  // a custom toolbar we can import the menu items in a separate
266  // toolbar ( better than nothing )
267  ScCTB* pCustTB = rWrapper.GetCustomizationData( pMenu->Name() );
268  if ( pCustTB )
269  {
270  uno::Reference< container::XIndexContainer > xMenuDesc = document::IndexedPropertyValues::create( comphelper::getProcessComponentContext() );
271  if ( !pCustTB->ImportMenuTB( rWrapper, xMenuDesc, helper ) )
272  return false;
273  if ( !bIsMenuToolbar )
274  {
275  if ( !helper.createMenu( pMenu->Name(), xMenuDesc ) )
276  return false;
277  }
278  else
279  {
280  beans::PropertyValue aProp;
281  aProp.Name = "ItemDescriptorContainer";
282  aProp.Value <<= xMenuDesc;
283  props.push_back( aProp );
284  }
285  }
286  }
287 
288  if ( bBeginGroup )
289  {
290  // insert spacer
291  uno::Sequence< beans::PropertyValue > sProps( 1 );
292  sProps[ 0 ].Name = "Type";
293  sProps[ 0 ].Value <<= ui::ItemType::SEPARATOR_LINE;
294  toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( sProps ) );
295  }
296  toolbarcontainer->insertByIndex( toolbarcontainer->getCount(), uno::makeAny( comphelper::containerToSequence(props) ) );
297  }
298  return true;
299 }
300 
301 #ifdef DEBUG_SC_EXCEL
302 void
303 TBCCmd::Print(FILE* fp)
304 {
305  Indent a;
306  indent_printf( fp, " TBCCmd -- dump\n" );
307  indent_printf( fp, " cmdID 0x%x\n", cmdID );
308  indent_printf( fp, " A ( fHideDrawing ) %s\n", A ? "true" : "false" );
309  indent_printf( fp, " B ( reserved - ignored ) %s\n", A ? "true" : "false" );
310  indent_printf( fp, " cmdType 0x%x\n", cmdType );
311  indent_printf( fp, " C ( reserved - ignored ) %s\n", A ? "true" : "false" );
312  indent_printf( fp, " reserved3 0x%x\n", reserved3 );
313 }
314 #endif
315 
317 {
318  SAL_INFO("sc.filter", "stream pos " << rS.Tell());
319  nOffSet = rS.Tell();
320  rS.ReadUInt16( cmdID );
321  sal_uInt16 temp;
322  rS.ReadUInt16( temp );
323  A = (temp & 0x8000 ) == 0x8000;
324  B = (temp & 0x4000) == 0x4000;
325  cmdType = ( temp & 0x3E00 ) >> 9;
326  C = ( temp & 0x100 ) == 0x100;
327  reserved3 = ( temp & 0xFF );
328  return true;
329 }
330 
332 {
333 }
334 
336 {
337 }
338 
339 bool
341 {
342  SAL_INFO("sc.filter", "stream pos " << rS.Tell());
343  nOffSet = rS.Tell();
344  try
345  {
346  if (!ctbSet.Read(rS))
347  return false;
348  }
349  catch(SvStreamEOFException&)
350  {
351  return false;
352  }
353 
354  //ScCTB is 1 TB which is min 15bytes, nViews TBVisualData which is min 20bytes
355  //and one 32bit number (4 bytes)
356  const size_t nMinRecordSize = 19 + ctbSet.ctbViews * 20;
357  const size_t nMaxPossibleRecords = rS.remainingSize()/nMinRecordSize;
358  if (ctbSet.ctb > nMaxPossibleRecords)
359  return false;
360 
361  for ( sal_uInt16 index = 0; index < ctbSet.ctb; ++index )
362  {
363  ScCTB aCTB( ctbSet.ctbViews );
364  if ( !aCTB.Read( rS ) )
365  return false;
366  rCTB.push_back( aCTB );
367  }
368  return true;
369 }
370 
371 #ifdef DEBUG_SC_EXCEL
372 void
373 ScCTBWrapper::Print( FILE* fp )
374 {
375  Indent a;
376  indent_printf( fp, "[ 0x%x ] ScCTBWrapper -- dump\n", nOffSet );
377  ctbSet.Print( fp );
378  for ( auto& rItem : rCTB )
379  {
380  Indent b;
381  rItem.Print( fp );
382  }
383 }
384 #endif
385 
386 ScCTB* ScCTBWrapper::GetCustomizationData( const OUString& sTBName )
387 {
388  ScCTB* pCTB = nullptr;
389  auto it = std::find_if(rCTB.begin(), rCTB.end(), [&sTBName](ScCTB& rItem) { return rItem.GetName() == sTBName; });
390  if (it != rCTB.end())
391  pCTB = &(*it);
392  return pCTB;
393 }
394 
396 {
397  if(rCTB.empty())
398  return;
399 
400  uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
401  uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xAppCfgSupp( ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
402 
403  for ( auto& rItem : rCTB )
404  {
405  // for each customtoolbar
406  CustomToolBarImportHelper helper( rDocSh, xAppCfgSupp->getUIConfigurationManager( "com.sun.star.sheet.SpreadsheetDocument" ) );
407  helper.setMSOCommandMap( new MSOExcelCommandConvertor() );
408  // Ignore menu toolbars, excel doesn't ( afaics ) store
409  // menu customizations ( but you can have menus in a customtoolbar
410  // such menus will be dealt with when they are encountered
411  // as part of importing the appropriate MenuSpecific toolbar control )
412 
413  if ( !rItem.IsMenuToolbar() && !rItem.ImportCustomToolBar( *this, helper ) )
414  return;
415  }
416 }
417 
418 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool A
Definition: xltoolbar.hxx:25
OUString Name()
sal_uInt32 ectbid
Definition: xltoolbar.hxx:55
sal_Int16 getcCL() const
bool Read(SvStream &rS) override
bool IsEnabled() const
sal_uInt16 ctbViews
Definition: xltoolbar.hxx:79
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:214
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
CTBS()
Definition: xltoolbar.cxx:70
bool IsMenuToolbar() const
Definition: xltoolbar.cxx:126
std::map< sal_Int16, OUString > IdToString
Definition: xltoolbar.cxx:22
sal_uInt16 reserved3
Definition: xltoolbar.hxx:77
std::vector< TBVisualData > rVisualData
Definition: xltoolbar.hxx:54
sal_uInt16 reserved2
Definition: xltoolbar.hxx:76
bool ImportToolBarControl(ScCTBWrapper &, const css::uno::Reference< css::container::XIndexContainer > &toolbarcontainer, CustomToolBarImportHelper &helper, bool bIsMenuBar)
Definition: xltoolbar.cxx:251
sal_uInt16 ctb
Definition: xltoolbar.hxx:78
void ImportCustomToolBar(SfxObjectShell &rDocSh)
Definition: xltoolbar.cxx:395
sal_uInt64 remainingSize()
sal_uInt8 bVersion
Definition: xltoolbar.hxx:74
css::uno::Reference< css::ui::XUIConfigurationManager > getCfgManager()
std::shared_ptr< TBCData > tbcd
Definition: xltoolbar.hxx:40
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
sal_uInt8 bSignature
Definition: xltoolbar.hxx:73
std::map< sal_Int16, OUString > IdToString
sal_uInt16 ictbView
Definition: xltoolbar.hxx:80
std::vector< ScCTB > rCTB
Definition: xltoolbar.hxx:94
uno_Any a
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:182
ScCTB * GetCustomizationData(const OUString &name)
Definition: xltoolbar.cxx:386
bool createMenu(const OUString &rName, const css::uno::Reference< css::container::XIndexAccess > &xMenuDesc)
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:316
sal_uInt16 reserved1
Definition: xltoolbar.hxx:75
bool IsMenuToolbar() const
bool ImportCustomToolBar(ScCTBWrapper &, CustomToolBarImportHelper &)
Definition: xltoolbar.cxx:141
dictionary props
bool Read(SvStream &rS) override
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:78
SvStream & ReadUChar(unsigned char &rChar)
tuple index
sal_uInt16 nViews
Definition: xltoolbar.hxx:52
std::vector< ScTBC > rTBC
Definition: xltoolbar.hxx:56
sal_uInt32 nOffSet
sal_uInt16 getTcID() const
ScCTB(sal_uInt16)
Definition: xltoolbar.cxx:74
unsigned char sal_uInt8
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
TBCHeader tbch
Definition: xltoolbar.hxx:38
sal_uInt16 cmdType
Definition: xltoolbar.hxx:27
bool B
Definition: xltoolbar.hxx:26
virtual ~ScCTBWrapper() override
Definition: xltoolbar.cxx:335
#define SAL_INFO(area, stream)
sal_uInt8 getTct() const
WString & getName()
sal_uInt64 Tell() const
Reference< XComponentContext > getProcessComponentContext()
const char * name
const OUString & getString() const
std::shared_ptr< TBCCmd > tbcCmd
Definition: xltoolbar.hxx:39
bool Read(SvStream &rS) override
bool Read(SvStream &rS) override
Definition: xltoolbar.cxx:340
TB tb
Definition: xltoolbar.hxx:53
sal_uInt16 reserved3
Definition: xltoolbar.hxx:29
sal_uInt16 cmdID
Definition: xltoolbar.hxx:24
bool C
Definition: xltoolbar.hxx:28
bool ImportMenuTB(ScCTBWrapper &, const css::uno::Reference< css::container::XIndexContainer > &, CustomToolBarImportHelper &)
Definition: xltoolbar.cxx:131