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 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/strbuf.hxx>
21 #include <osl/diagnose.h>
22 #include <tools/debug.hxx>
24 #include <globals.hxx>
25 #include <database.hxx>
28 SvMetaSlot::SvMetaSlot()
29 : aRecordPerSet( true )
30 , aRecordAbsolute( false )
33 , aReadOnlyDoc ( true )
38 SvMetaSlot::SvMetaSlot( SvMetaType
* pType
)
39 : SvMetaAttribute( pType
)
40 , aRecordPerSet( true )
41 , aRecordAbsolute( false )
44 , aReadOnlyDoc ( true )
49 bool SvMetaSlot::GetReadOnlyDoc() const
51 if( aReadOnlyDoc
.IsSet() || !GetRef() ) return aReadOnlyDoc
;
52 return static_cast<SvMetaSlot
*>(GetRef())->GetReadOnlyDoc();
55 bool SvMetaSlot::GetExport() const
57 if( aExport
.IsSet() || !GetRef() ) return aExport
;
58 return static_cast<SvMetaSlot
*>(GetRef())->GetExport();
61 bool SvMetaSlot::GetHidden() const
63 // when export is set, but hidden is not the default is used
64 if ( aExport
.IsSet() )
69 return static_cast<SvMetaSlot
*>(GetRef())->GetHidden();
72 bool SvMetaSlot::IsVariable() const
74 SvMetaType
* pType
= GetType();
75 return pType
->GetMetaTypeType() != MetaTypeType::Method
;
78 bool SvMetaSlot::IsMethod() const
80 SvMetaType
* pType
= GetType();
81 return pType
->GetMetaTypeType() == MetaTypeType::Method
;
84 /*************************************************************************
87 |* description Second FALSE in the SvBOOL-Objects means
88 |* IsSet() provides FALSE (default initialization).
89 *************************************************************************/
90 /** reference disbandment **/
91 const OString
& SvMetaSlot::GetGroupId() const
93 if( !aGroupId
.getString().isEmpty() || !GetRef() ) return aGroupId
.getString();
94 return static_cast<SvMetaSlot
*>(GetRef())->GetGroupId();
96 const OString
& SvMetaSlot::GetDisableFlags() const
98 if( !aDisableFlags
.isEmpty() || !GetRef() ) return aDisableFlags
;
99 return static_cast<SvMetaSlot
*>(GetRef())->GetDisableFlags();
101 const OString
& SvMetaSlot::GetExecMethod() const
103 if( !aExecMethod
.getString().isEmpty() || !GetRef() ) return aExecMethod
.getString();
104 return static_cast<SvMetaSlot
*>(GetRef())->GetExecMethod();
106 const OString
& SvMetaSlot::GetStateMethod() const
108 if( !aStateMethod
.getString().isEmpty() || !GetRef() ) return aStateMethod
.getString();
109 return static_cast<SvMetaSlot
*>(GetRef())->GetStateMethod();
111 bool SvMetaSlot::GetToggle() const
113 if( aToggle
.IsSet() || !GetRef() ) return aToggle
;
114 return static_cast<SvMetaSlot
*>(GetRef())->GetToggle();
116 bool SvMetaSlot::GetAutoUpdate() const
118 if( aAutoUpdate
.IsSet() || !GetRef() ) return aAutoUpdate
;
119 return static_cast<SvMetaSlot
*>(GetRef())->GetAutoUpdate();
121 bool SvMetaSlot::GetAsynchron() const
123 // Synchron and Asynchron are exclusive
124 if( !GetRef() || aAsynchron
.IsSet() )
126 return static_cast<SvMetaSlot
*>(GetRef())->GetAsynchron();
128 bool SvMetaSlot::GetRecordPerItem() const
130 // Record- PerItem, No, PerSet and Manual are exclusive
131 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
132 || aRecordPerSet
.IsSet() )
133 return aRecordPerItem
;
134 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordPerItem();
136 bool SvMetaSlot::GetRecordPerSet() const
138 // Record- PerItem, No, PerSet and Manual are exclusive
139 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
140 || aRecordPerSet
.IsSet() )
141 return aRecordPerSet
;
142 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordPerSet();
144 bool SvMetaSlot::GetNoRecord() const
146 // Record- PerItem, No, PerSet and Manual are exclusive
147 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
148 || aRecordPerSet
.IsSet() )
150 return static_cast<SvMetaSlot
*>(GetRef())->GetNoRecord();
152 bool SvMetaSlot::GetRecordAbsolute() const
154 if( !GetRef() || aRecordAbsolute
.IsSet() )
155 return aRecordAbsolute
;
156 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordAbsolute();
158 bool SvMetaSlot::GetMenuConfig() const
160 if( aMenuConfig
.IsSet() || !GetRef() ) return aMenuConfig
;
161 return static_cast<SvMetaSlot
*>(GetRef())->GetMenuConfig();
163 bool SvMetaSlot::GetToolBoxConfig() const
165 if( aToolBoxConfig
.IsSet() || !GetRef() ) return aToolBoxConfig
;
166 return static_cast<SvMetaSlot
*>(GetRef())->GetToolBoxConfig();
168 bool SvMetaSlot::GetAccelConfig() const
170 if( aAccelConfig
.IsSet() || !GetRef() ) return aAccelConfig
;
171 return static_cast<SvMetaSlot
*>(GetRef())->GetAccelConfig();
173 bool SvMetaSlot::GetFastCall() const
175 if( aFastCall
.IsSet() || !GetRef() ) return aFastCall
;
176 return static_cast<SvMetaSlot
*>(GetRef())->GetFastCall();
178 bool SvMetaSlot::GetContainer() const
180 if( aContainer
.IsSet() || !GetRef() ) return aContainer
;
181 return static_cast<SvMetaSlot
*>(GetRef())->GetContainer();
184 void SvMetaSlot::ReadAttributesSvIdl( SvIdlDataBase
& rBase
,
185 SvTokenStream
& rInStm
)
187 SvMetaAttribute::ReadAttributesSvIdl( rBase
, rInStm
);
189 aGroupId
.ReadSvIdl( SvHash_GroupId(), rInStm
);
190 aExecMethod
.ReadSvIdl( SvHash_ExecMethod(), rInStm
);
191 aStateMethod
.ReadSvIdl( SvHash_StateMethod(), rInStm
);
192 ReadStringSvIdl( SvHash_DisableFlags(), rInStm
, aDisableFlags
);
193 aReadOnlyDoc
.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm
);
194 aExport
.ReadSvIdl( SvHash_Export(), rInStm
);
195 aToggle
.ReadSvIdl( SvHash_Toggle(), rInStm
);
196 aAutoUpdate
.ReadSvIdl( SvHash_AutoUpdate(), rInStm
);
197 aAsynchron
.ReadSvIdl( SvHash_Asynchron(), rInStm
);
198 aRecordAbsolute
.ReadSvIdl( SvHash_RecordAbsolute(), rInStm
);
200 if( aRecordPerItem
.ReadSvIdl( SvHash_RecordPerItem(), rInStm
) )
202 SetRecordPerItem( aRecordPerItem
);
204 if( aRecordPerSet
.ReadSvIdl( SvHash_RecordPerSet(), rInStm
) )
206 SetRecordPerSet( aRecordPerSet
);
208 if( aNoRecord
.ReadSvIdl( SvHash_NoRecord(), rInStm
) )
210 SetNoRecord( aNoRecord
);
213 aMenuConfig
.ReadSvIdl( SvHash_MenuConfig(), rInStm
);
214 aToolBoxConfig
.ReadSvIdl( SvHash_ToolBoxConfig(), rInStm
);
215 aAccelConfig
.ReadSvIdl( SvHash_AccelConfig(), rInStm
);
217 aFastCall
.ReadSvIdl( SvHash_FastCall(), rInStm
);
218 aContainer
.ReadSvIdl( SvHash_Container(), rInStm
);
221 bool SvMetaSlot::Test( SvTokenStream
& rInStm
)
223 bool bOk
= SvMetaAttribute::Test( rInStm
);
226 SvMetaType
* pType
= GetType();
227 if( pType
->GetMetaTypeType() == MetaTypeType::Method
)
228 pType
= pType
->GetReturnType();
229 if( !pType
->IsItem() )
231 throw SvParseException( rInStm
, "this attribute is not a slot" );
238 bool SvMetaSlot::ReadSvIdl( SvIdlDataBase
& rBase
, SvTokenStream
& rInStm
)
240 sal_uInt32 nTokPos
= rInStm
.Tell();
243 SvMetaAttribute
* pAttr
= rBase
.ReadKnownAttr( rInStm
, GetType() );
247 SvMetaSlot
* pKnownSlot
= dynamic_cast<SvMetaSlot
*>( pAttr
);
249 throw SvParseException( rInStm
, "attribute " + pAttr
->GetName() + " is method or variable but not a slot" );
250 SetRef( pKnownSlot
);
251 SetName( pKnownSlot
->GetName() );
252 bOk
= SvMetaObject::ReadSvIdl( rBase
, rInStm
);
256 bOk
= SvMetaAttribute::ReadSvIdl( rBase
, rInStm
);
258 SvMetaAttribute
*pAttr2
= rBase
.FindKnownAttr( GetSlotId() );
261 // for testing purposes: reference in case of complete definition
262 SvMetaSlot
* pKnownSlot
= dynamic_cast<SvMetaSlot
*>( pAttr2
);
264 throw SvParseException( rInStm
, "attribute " + pAttr2
->GetName() + " is method or variable but not a slot" );
265 SetRef( pKnownSlot
);
267 // names may differ, because explicitly given
268 if ( pKnownSlot
->GetName() != GetName() )
270 OSL_FAIL("Illegal definition!");
271 rInStm
.Seek( nTokPos
);
275 SetName( pKnownSlot
->GetName() );
280 rInStm
.Seek( nTokPos
);
285 void SvMetaSlot::Insert( SvSlotElementList
& rList
)
287 // get insert position through binary search in slotlist
288 sal_uInt16 nId
= static_cast<sal_uInt16
>(GetSlotId().GetValue());
289 sal_uInt16 nListCount
= static_cast<sal_uInt16
>(rList
.size());
294 else if ( nListCount
== 1 )
295 nPos
= rList
[ 0 ]->GetSlotId().GetValue() >= nId
? 0 : 1;
298 sal_uInt16 nMid
= 0, nLow
= 0;
299 sal_uInt16 nHigh
= nListCount
- 1;
301 while ( !bFound
&& nLow
<= nHigh
)
303 nMid
= (nLow
+ nHigh
) >> 1;
304 DBG_ASSERT( nMid
< nListCount
, "bsearch is buggy" );
305 int nDiff
= static_cast<int>(nId
) - static_cast<int>(rList
[ nMid
]->GetSlotId().GetValue());
312 else if ( nDiff
> 0 )
322 DBG_ASSERT(!bFound
, "Duplicate SlotId!");
323 nPos
= bFound
? nMid
: nLow
;
326 DBG_ASSERT( nPos
<= nListCount
,
328 DBG_ASSERT( nPos
== nListCount
|| nId
<=
329 static_cast<sal_uInt16
>(rList
[ nPos
]->GetSlotId().GetValue()),
330 "Successor has lower SlotId" );
331 DBG_ASSERT( nPos
== 0 || nId
>
332 static_cast<sal_uInt16
>(rList
[ nPos
-1 ]->GetSlotId().GetValue()),
333 "Predecessor has higher SlotId" );
334 DBG_ASSERT( nPos
+1 >= nListCount
|| nId
<
335 static_cast<sal_uInt16
>(rList
[ nPos
+1 ]->GetSlotId().GetValue()),
336 "Successor has lower SlotId" );
338 if ( nPos
< rList
.size() )
340 SvSlotElementList::iterator it
= rList
.begin();
341 std::advance( it
, nPos
);
342 rList
.insert( it
, this );
346 rList
.push_back( this );
351 static OString
MakeSlotName( SvStringHashEntry
const * pEntry
)
353 return "SfxSlotMode::" + pEntry
->GetName().toAsciiUpperCase();
356 void SvMetaSlot::WriteSlotStubs( const OString
& rShellName
,
357 std::vector
<OString
> & rList
,
358 SvStream
& rOutStm
) const
360 if ( !GetExport() && !GetHidden() )
363 OString
aMethodName( GetExecMethod() );
364 if ( !aMethodName
.isEmpty() &&
365 aMethodName
!= "NoExec" )
368 for( size_t n
= 0; n
< rList
.size(); n
++ )
370 if (rList
[n
] == aMethodName
)
379 rList
.push_back( aMethodName
);
380 rOutStm
.WriteCharPtr( "SFX_EXEC_STUB(" )
381 .WriteOString( rShellName
)
383 .WriteOString( aMethodName
)
384 .WriteChar( ')' ) << endl
;
388 aMethodName
= GetStateMethod();
389 if (!aMethodName
.isEmpty() &&
390 aMethodName
!= "NoState")
393 for ( size_t n
=0; n
< rList
.size(); n
++ )
395 if (rList
[n
] == aMethodName
)
404 rList
.push_back( aMethodName
);
405 rOutStm
.WriteCharPtr( "SFX_STATE_STUB(" )
406 .WriteOString( rShellName
)
408 .WriteOString( aMethodName
)
409 .WriteChar( ')' ) << endl
;
414 void SvMetaSlot::WriteSlot( const OString
& rShellName
, sal_uInt16 nCount
,
415 const OString
& rSlotId
,
416 SvSlotElementList
& rSlotList
,
418 SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
420 if ( !GetExport() && !GetHidden() )
423 rOutStm
.WriteCharPtr( "// Slot Nr. " )
424 .WriteOString( OString::number(nListPos
) )
425 .WriteCharPtr( " : " );
426 OString
aSlotIdValue(OString::number(GetSlotId().GetValue()));
427 rOutStm
.WriteOString( aSlotIdValue
) << endl
;
428 WriteTab( rOutStm
, 1 );
429 rOutStm
.WriteCharPtr( "SFX_NEW_SLOT_ARG( " ).WriteOString( rShellName
).WriteChar( ',' ) ;
431 rOutStm
.WriteOString( rSlotId
).WriteChar( ',' );
434 if( !GetGroupId().isEmpty() )
435 rOutStm
.WriteOString( GetGroupId() );
437 rOutStm
.WriteCharPtr( "SfxGroupId::NONE" );
438 rOutStm
.WriteChar( ',' ) << endl
;
439 WriteTab( rOutStm
, 4 );
441 // look for the next slot with the same StateMethod like me
442 // the slotlist is set to the current slot
444 SvMetaSlot
* pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
448 if ( !pNextSlot
->pNextSlot
&&
449 pNextSlot
->GetStateMethod() == GetStateMethod()
453 pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
459 // There is no slot behind me that has the same ExecMethod.
460 // So I search for the first slot with it (could be myself).
462 pEle
= rSlotList
.empty() ? nullptr : rSlotList
[ i
];
464 while (pNextSlot
&& pNextSlot
!= this)
466 if ( pNextSlot
->GetStateMethod() == GetStateMethod() )
468 pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
475 rOutStm
.WriteCharPtr( "&a" ).WriteOString( rShellName
).WriteCharPtr( "Slots_Impl[" )
476 .WriteOString( OString::number(pNextSlot
->GetListPos()) )
477 .WriteCharPtr( "] /*Offset Next*/, " ) << endl
;
479 WriteTab( rOutStm
, 4 );
481 // write ExecMethod, with standard name if not specified
482 if( !GetExecMethod().isEmpty() &&
483 GetExecMethod() != "NoExec")
485 rOutStm
.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName
).WriteChar( ',' )
486 .WriteOString( GetExecMethod() ).WriteChar( ')' );
489 rOutStm
.WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE" );
490 rOutStm
.WriteChar( ',' );
492 // write StateMethod, with standard name if not specified
493 if( !GetStateMethod().isEmpty() &&
494 GetStateMethod() != "NoState")
496 rOutStm
.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName
).WriteChar( ',' )
497 .WriteOString( GetStateMethod() ).WriteChar( ')' );
500 rOutStm
.WriteCharPtr( "SFX_STUB_PTR_STATE_NONE" );
502 rOutStm
.WriteChar( ',' ) << endl
;
503 WriteTab( rOutStm
, 4 );
507 rOutStm
.WriteOString( MakeSlotName( SvHash_Toggle() ) ).WriteChar( '|' );
508 if( GetAutoUpdate() )
509 rOutStm
.WriteOString( MakeSlotName( SvHash_AutoUpdate() ) ).WriteChar( '|' );
511 rOutStm
.WriteOString( MakeSlotName( SvHash_Asynchron() ) ).WriteChar( '|' );
512 if( GetRecordPerItem() )
513 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordPerItem() ) ).WriteChar( '|' );
514 if( GetRecordPerSet() )
515 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordPerSet() ) ).WriteChar( '|' );
517 rOutStm
.WriteOString( MakeSlotName( SvHash_NoRecord() ) ).WriteChar( '|' );
518 if( GetRecordAbsolute() )
519 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordAbsolute() ) ).WriteChar( '|' );
520 if( GetMenuConfig() )
521 rOutStm
.WriteOString( MakeSlotName( SvHash_MenuConfig() ) ).WriteChar( '|' );
522 if( GetToolBoxConfig() )
523 rOutStm
.WriteOString( MakeSlotName( SvHash_ToolBoxConfig() ) ).WriteChar( '|' );
524 if( GetAccelConfig() )
525 rOutStm
.WriteOString( MakeSlotName( SvHash_AccelConfig() ) ).WriteChar( '|' );
527 rOutStm
.WriteOString( MakeSlotName( SvHash_FastCall() ) ).WriteChar( '|' );
529 rOutStm
.WriteOString( MakeSlotName( SvHash_Container() ) ).WriteChar( '|' );
530 if ( GetReadOnlyDoc() )
531 rOutStm
.WriteOString( MakeSlotName( SvHash_ReadOnlyDoc() ) ).WriteChar( '|' );
532 rOutStm
.WriteCharPtr( "SfxSlotMode::NONE" );
534 rOutStm
.WriteChar( ',' ) << endl
;
535 WriteTab( rOutStm
, 4 );
536 if ( GetDisableFlags().isEmpty() )
537 rOutStm
.WriteCharPtr( "SfxDisableFlags::NONE" );
539 rOutStm
.WriteOString( GetDisableFlags() );
541 // write attribute type
542 rOutStm
.WriteChar( ',' ) << endl
;
543 WriteTab( rOutStm
, 4 );
545 SvMetaType
* pT
= GetType();
548 SvMetaType
* pRT
= GetType()->GetReturnType();
549 pT
= pRT
? pRT
: rBase
.FindType( "SfxVoidItem" );
554 assert(pT
->IsItem());
555 rOutStm
.WriteOString( pT
->GetName() );
556 if( !SvIdlDataBase::FindType( pT
, rBase
.aUsedTypes
) )
557 rBase
.aUsedTypes
.push_back( pT
);
560 rOutStm
.WriteCharPtr( "SfxVoidItem not defined" );
563 rOutStm
.WriteChar( ',' ) << endl
;
564 WriteTab( rOutStm
, 4 );
566 .WriteOString( OString::number(nCount
) )
567 .WriteCharPtr( "/*Offset*/, " );
571 SvMetaType
* pType
= GetType();
572 sal_uLong nSCount
= pType
->GetAttrCount();
574 .WriteOString( OString::number(nSCount
) )
575 .WriteCharPtr( "/*Count*/," );
578 rOutStm
.WriteCharPtr( "0," );
580 rOutStm
.WriteCharPtr( " " );
582 // Method/Property flags
584 rOutStm
.WriteCharPtr( "SfxSlotMode::METHOD|" );
586 rOutStm
.WriteCharPtr( "SfxSlotMode::NONE" );
590 rOutStm
.WriteCharPtr( ",\"" );
591 rOutStm
.WriteOString( GetName() );
592 rOutStm
.WriteCharPtr( "\"" );
595 rOutStm
.WriteCharPtr( " )," ) << endl
;
598 sal_uInt16
SvMetaSlot::WriteSlotParamArray( SvIdlDataBase
& rBase
, SvStream
& rOutStm
) const
600 if ( !GetExport() && !GetHidden() )
605 SvMetaType
* pType
= GetType();
607 if( !SvIdlDataBase::FindType( pType
, rBase
.aUsedTypes
) )
608 rBase
.aUsedTypes
.push_back( pType
);
610 const SvRefMemberList
<SvMetaAttribute
*>& rList
=
611 pType
->GetAttrList();
612 for( sal_uLong n
= 0; n
< rList
.size(); n
++ )
614 SvMetaAttribute
* pPar
= rList
[n
];
615 SvMetaType
* pPType
= pPar
->GetType();
616 WriteTab( rOutStm
, 1 );
617 rOutStm
.WriteCharPtr("{ (const SfxType*) &a")
619 .WriteOString(pPType
->GetName()).WriteCharPtr("_Impl, ")
621 .WriteCharPtr("\"").WriteOString(pPar
->GetName()).WriteCharPtr("\", ")
623 .WriteOString(pPar
->GetSlotId().getString()).WriteCharPtr(" },") << endl
;
624 if( !SvIdlDataBase::FindType( pPType
, rBase
.aUsedTypes
) )
625 rBase
.aUsedTypes
.push_back( pPType
);
627 return static_cast<sal_uInt16
>(rList
.size());
632 sal_uInt16
SvMetaSlot::WriteSlotMap( const OString
& rShellName
, sal_uInt16 nCount
,
633 SvSlotElementList
& rSlotList
,
635 SvIdlDataBase
& rBase
,
638 // SlotId, if not specified generate from name
639 OString slotId
= GetSlotId().getString();
641 sal_uInt16 nSCount
= 0;
644 SvMetaType
* pType
= GetType();
645 nSCount
= static_cast<sal_uInt16
>(pType
->GetAttrCount());
648 WriteSlot( rShellName
, nCount
, slotId
, rSlotList
, nStart
, rBase
, rOutStm
);
652 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */