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 <osl/diagnose.h>
21 #include <tools/debug.hxx>
23 #include <globals.hxx>
24 #include <database.hxx>
27 SvMetaSlot::SvMetaSlot()
28 : aRecordPerSet( true )
29 , aRecordAbsolute( false )
32 , aReadOnlyDoc ( true )
36 SvMetaSlot::SvMetaSlot( SvMetaType
* pType
)
37 : SvMetaAttribute( pType
)
38 , aRecordPerSet( true )
39 , aRecordAbsolute( false )
42 , aReadOnlyDoc ( true )
46 bool SvMetaSlot::GetReadOnlyDoc() const
48 if( aReadOnlyDoc
.IsSet() || !GetRef() ) return aReadOnlyDoc
;
49 return static_cast<SvMetaSlot
*>(GetRef())->GetReadOnlyDoc();
52 bool SvMetaSlot::IsVariable() const
54 SvMetaType
* pType
= GetType();
55 return pType
->GetMetaTypeType() != MetaTypeType::Method
;
58 bool SvMetaSlot::IsMethod() const
60 SvMetaType
* pType
= GetType();
61 return pType
->GetMetaTypeType() == MetaTypeType::Method
;
64 /*************************************************************************
67 |* description Second FALSE in the SvBOOL-Objects means
68 |* IsSet() provides FALSE (default initialization).
69 *************************************************************************/
70 /** reference disbandment **/
71 const OString
& SvMetaSlot::GetGroupId() const
73 if( !aGroupId
.getString().isEmpty() || !GetRef() ) return aGroupId
.getString();
74 return static_cast<SvMetaSlot
*>(GetRef())->GetGroupId();
76 const OString
& SvMetaSlot::GetDisableFlags() const
78 if( !aDisableFlags
.isEmpty() || !GetRef() ) return aDisableFlags
;
79 return static_cast<SvMetaSlot
*>(GetRef())->GetDisableFlags();
81 const OString
& SvMetaSlot::GetExecMethod() const
83 if( !aExecMethod
.getString().isEmpty() || !GetRef() ) return aExecMethod
.getString();
84 return static_cast<SvMetaSlot
*>(GetRef())->GetExecMethod();
86 const OString
& SvMetaSlot::GetStateMethod() const
88 if( !aStateMethod
.getString().isEmpty() || !GetRef() ) return aStateMethod
.getString();
89 return static_cast<SvMetaSlot
*>(GetRef())->GetStateMethod();
91 bool SvMetaSlot::GetToggle() const
93 if( aToggle
.IsSet() || !GetRef() ) return aToggle
;
94 return static_cast<SvMetaSlot
*>(GetRef())->GetToggle();
96 bool SvMetaSlot::GetAutoUpdate() const
98 if( aAutoUpdate
.IsSet() || !GetRef() ) return aAutoUpdate
;
99 return static_cast<SvMetaSlot
*>(GetRef())->GetAutoUpdate();
101 bool SvMetaSlot::GetAsynchron() const
103 // Synchron and Asynchron are exclusive
104 if( !GetRef() || aAsynchron
.IsSet() )
106 return static_cast<SvMetaSlot
*>(GetRef())->GetAsynchron();
108 bool SvMetaSlot::GetRecordPerItem() const
110 // Record- PerItem, No, PerSet and Manual are exclusive
111 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
112 || aRecordPerSet
.IsSet() )
113 return aRecordPerItem
;
114 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordPerItem();
116 bool SvMetaSlot::GetRecordPerSet() const
118 // Record- PerItem, No, PerSet and Manual are exclusive
119 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
120 || aRecordPerSet
.IsSet() )
121 return aRecordPerSet
;
122 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordPerSet();
124 bool SvMetaSlot::GetNoRecord() const
126 // Record- PerItem, No, PerSet and Manual are exclusive
127 if( !GetRef() || aRecordPerItem
.IsSet() || aNoRecord
.IsSet()
128 || aRecordPerSet
.IsSet() )
130 return static_cast<SvMetaSlot
*>(GetRef())->GetNoRecord();
132 bool SvMetaSlot::GetRecordAbsolute() const
134 if( !GetRef() || aRecordAbsolute
.IsSet() )
135 return aRecordAbsolute
;
136 return static_cast<SvMetaSlot
*>(GetRef())->GetRecordAbsolute();
138 bool SvMetaSlot::GetMenuConfig() const
140 if( aMenuConfig
.IsSet() || !GetRef() ) return aMenuConfig
;
141 return static_cast<SvMetaSlot
*>(GetRef())->GetMenuConfig();
143 bool SvMetaSlot::GetToolBoxConfig() const
145 if( aToolBoxConfig
.IsSet() || !GetRef() ) return aToolBoxConfig
;
146 return static_cast<SvMetaSlot
*>(GetRef())->GetToolBoxConfig();
148 bool SvMetaSlot::GetAccelConfig() const
150 if( aAccelConfig
.IsSet() || !GetRef() ) return aAccelConfig
;
151 return static_cast<SvMetaSlot
*>(GetRef())->GetAccelConfig();
153 bool SvMetaSlot::GetFastCall() const
155 if( aFastCall
.IsSet() || !GetRef() ) return aFastCall
;
156 return static_cast<SvMetaSlot
*>(GetRef())->GetFastCall();
158 bool SvMetaSlot::GetContainer() const
160 if( aContainer
.IsSet() || !GetRef() ) return aContainer
;
161 return static_cast<SvMetaSlot
*>(GetRef())->GetContainer();
164 void SvMetaSlot::ReadAttributesSvIdl( SvIdlDataBase
& rBase
,
165 SvTokenStream
& rInStm
)
167 SvMetaAttribute::ReadAttributesSvIdl( rBase
, rInStm
);
169 aGroupId
.ReadSvIdl( SvHash_GroupId(), rInStm
);
170 aExecMethod
.ReadSvIdl( SvHash_ExecMethod(), rInStm
);
171 aStateMethod
.ReadSvIdl( SvHash_StateMethod(), rInStm
);
172 ReadStringSvIdl( SvHash_DisableFlags(), rInStm
, aDisableFlags
);
173 aReadOnlyDoc
.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm
);
174 aToggle
.ReadSvIdl( SvHash_Toggle(), rInStm
);
175 aAutoUpdate
.ReadSvIdl( SvHash_AutoUpdate(), rInStm
);
176 aAsynchron
.ReadSvIdl( SvHash_Asynchron(), rInStm
);
177 aRecordAbsolute
.ReadSvIdl( SvHash_RecordAbsolute(), rInStm
);
179 if( aRecordPerItem
.ReadSvIdl( SvHash_RecordPerItem(), rInStm
) )
181 SetRecordPerItem( aRecordPerItem
);
183 if( aRecordPerSet
.ReadSvIdl( SvHash_RecordPerSet(), rInStm
) )
185 SetRecordPerSet( aRecordPerSet
);
187 if( aNoRecord
.ReadSvIdl( SvHash_NoRecord(), rInStm
) )
189 SetNoRecord( aNoRecord
);
192 aMenuConfig
.ReadSvIdl( SvHash_MenuConfig(), rInStm
);
193 aToolBoxConfig
.ReadSvIdl( SvHash_ToolBoxConfig(), rInStm
);
194 aAccelConfig
.ReadSvIdl( SvHash_AccelConfig(), rInStm
);
196 aFastCall
.ReadSvIdl( SvHash_FastCall(), rInStm
);
197 aContainer
.ReadSvIdl( SvHash_Container(), rInStm
);
200 bool SvMetaSlot::Test( SvTokenStream
& rInStm
)
202 bool bOk
= SvMetaAttribute::Test( rInStm
);
205 SvMetaType
* pType
= GetType();
206 if( pType
->GetMetaTypeType() == MetaTypeType::Method
)
207 pType
= pType
->GetReturnType();
208 if( !pType
->IsItem() )
210 throw SvParseException( rInStm
, "this attribute is not a slot"_ostr
);
217 bool SvMetaSlot::ReadSvIdl( SvIdlDataBase
& rBase
, SvTokenStream
& rInStm
)
219 sal_uInt32 nTokPos
= rInStm
.Tell();
222 SvMetaAttribute
* pAttr
= rBase
.ReadKnownAttr( rInStm
, GetType() );
226 SvMetaSlot
* pKnownSlot
= dynamic_cast<SvMetaSlot
*>( pAttr
);
228 throw SvParseException( rInStm
, "attribute " + pAttr
->GetName() + " is method or variable but not a slot" );
229 SetRef( pKnownSlot
);
230 SetName( pKnownSlot
->GetName() );
231 bOk
= SvMetaObject::ReadSvIdl( rBase
, rInStm
);
235 bOk
= SvMetaAttribute::ReadSvIdl( rBase
, rInStm
);
237 SvMetaAttribute
*pAttr2
= rBase
.FindKnownAttr( GetSlotId() );
240 // for testing purposes: reference in case of complete definition
241 SvMetaSlot
* pKnownSlot
= dynamic_cast<SvMetaSlot
*>( pAttr2
);
243 throw SvParseException( rInStm
, "attribute " + pAttr2
->GetName() + " is method or variable but not a slot" );
244 SetRef( pKnownSlot
);
246 // names may differ, because explicitly given
247 if ( pKnownSlot
->GetName() != GetName() )
249 OSL_FAIL("Illegal definition!");
250 rInStm
.Seek( nTokPos
);
254 SetName( pKnownSlot
->GetName() );
259 rInStm
.Seek( nTokPos
);
264 void SvMetaSlot::Insert( SvSlotElementList
& rList
)
266 // get insert position through binary search in slotlist
267 sal_uInt16 nId
= static_cast<sal_uInt16
>(GetSlotId().GetValue());
268 sal_uInt16 nListCount
= static_cast<sal_uInt16
>(rList
.size());
273 else if ( nListCount
== 1 )
274 nPos
= rList
[ 0 ]->GetSlotId().GetValue() >= nId
? 0 : 1;
277 sal_uInt16 nMid
= 0, nLow
= 0;
278 sal_uInt16 nHigh
= nListCount
- 1;
280 while ( !bFound
&& nLow
<= nHigh
)
282 nMid
= (nLow
+ nHigh
) >> 1;
283 DBG_ASSERT( nMid
< nListCount
, "bsearch is buggy" );
284 int nDiff
= static_cast<int>(nId
) - static_cast<int>(rList
[ nMid
]->GetSlotId().GetValue());
291 else if ( nDiff
> 0 )
301 DBG_ASSERT(!bFound
, "Duplicate SlotId!");
302 nPos
= bFound
? nMid
: nLow
;
305 DBG_ASSERT( nPos
<= nListCount
,
307 DBG_ASSERT( nPos
== nListCount
|| nId
<=
308 static_cast<sal_uInt16
>(rList
[ nPos
]->GetSlotId().GetValue()),
309 "Successor has lower SlotId" );
310 DBG_ASSERT( nPos
== 0 || nId
>
311 static_cast<sal_uInt16
>(rList
[ nPos
-1 ]->GetSlotId().GetValue()),
312 "Predecessor has higher SlotId" );
313 DBG_ASSERT( nPos
+1 >= nListCount
|| nId
<
314 static_cast<sal_uInt16
>(rList
[ nPos
+1 ]->GetSlotId().GetValue()),
315 "Successor has lower SlotId" );
317 if ( nPos
< rList
.size() )
319 SvSlotElementList::iterator it
= rList
.begin();
320 std::advance( it
, nPos
);
321 rList
.insert( it
, this );
325 rList
.push_back( this );
330 static OString
MakeSlotName( SvStringHashEntry
const * pEntry
)
332 return "SfxSlotMode::" + pEntry
->GetName().toAsciiUpperCase();
335 void SvMetaSlot::WriteSlotStubs( std::string_view rShellName
,
336 std::vector
<OString
> & rList
,
337 SvStream
& rOutStm
) const
339 OString
aMethodName( GetExecMethod() );
340 if ( !aMethodName
.isEmpty() &&
341 aMethodName
!= "NoExec" )
344 for( size_t n
= 0; n
< rList
.size(); n
++ )
346 if (rList
[n
] == aMethodName
)
355 rList
.push_back( aMethodName
);
356 rOutStm
.WriteOString( "SFX_EXEC_STUB(" )
357 .WriteOString( rShellName
)
359 .WriteOString( aMethodName
)
360 .WriteChar( ')' ) << endl
;
364 aMethodName
= GetStateMethod();
365 if (aMethodName
.isEmpty() || aMethodName
== "NoState")
369 for ( size_t n
=0; n
< rList
.size(); n
++ )
371 if (rList
[n
] == aMethodName
)
380 rList
.push_back( aMethodName
);
381 rOutStm
.WriteOString( "SFX_STATE_STUB(" )
382 .WriteOString( rShellName
)
384 .WriteOString( aMethodName
)
385 .WriteChar( ')' ) << endl
;
389 void SvMetaSlot::WriteSlot( std::string_view rShellName
, sal_uInt16 nCount
,
390 std::string_view rSlotId
,
391 SvSlotElementList
& rSlotList
,
393 SvIdlDataBase
& rBase
, SvStream
& rOutStm
)
395 rOutStm
.WriteOString( "// Slot Nr. " )
396 .WriteOString( OString::number(nListPos
) )
397 .WriteOString( " : " );
398 OString
aSlotIdValue(OString::number(GetSlotId().GetValue()));
399 rOutStm
.WriteOString( aSlotIdValue
) << endl
;
400 WriteTab( rOutStm
, 1 );
401 rOutStm
.WriteOString( "SFX_NEW_SLOT_ARG( " ).WriteOString( rShellName
).WriteChar( ',' ) ;
403 rOutStm
.WriteOString( rSlotId
).WriteChar( ',' );
406 if( !GetGroupId().isEmpty() )
407 rOutStm
.WriteOString( GetGroupId() );
409 rOutStm
.WriteOString( "SfxGroupId::NONE" );
410 rOutStm
.WriteChar( ',' ) << endl
;
411 WriteTab( rOutStm
, 4 );
413 // look for the next slot with the same StateMethod like me
414 // the slotlist is set to the current slot
416 SvMetaSlot
* pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
420 if ( !pNextSlot
->pNextSlot
&&
421 pNextSlot
->GetStateMethod() == GetStateMethod()
425 pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
431 // There is no slot behind me that has the same ExecMethod.
432 // So I search for the first slot with it (could be myself).
434 pEle
= rSlotList
.empty() ? nullptr : rSlotList
[ i
];
436 while (pNextSlot
&& pNextSlot
!= this)
438 if ( pNextSlot
->GetStateMethod() == GetStateMethod() )
440 pEle
= ( ++i
< rSlotList
.size() ) ? rSlotList
[ i
] : nullptr;
447 rOutStm
.WriteOString( "&a" ).WriteOString( rShellName
).WriteOString( "Slots_Impl[" )
448 .WriteOString( OString::number(pNextSlot
->GetListPos()) )
449 .WriteOString( "] /*Offset Next*/, " ) << endl
;
451 WriteTab( rOutStm
, 4 );
453 // write ExecMethod, with standard name if not specified
454 if( !GetExecMethod().isEmpty() &&
455 GetExecMethod() != "NoExec")
457 rOutStm
.WriteOString( "SFX_STUB_PTR(" ).WriteOString( rShellName
).WriteChar( ',' )
458 .WriteOString( GetExecMethod() ).WriteChar( ')' );
461 rOutStm
.WriteOString( "SFX_STUB_PTR_EXEC_NONE" );
462 rOutStm
.WriteChar( ',' );
464 // write StateMethod, with standard name if not specified
465 if( !GetStateMethod().isEmpty() &&
466 GetStateMethod() != "NoState")
468 rOutStm
.WriteOString( "SFX_STUB_PTR(" ).WriteOString( rShellName
).WriteChar( ',' )
469 .WriteOString( GetStateMethod() ).WriteChar( ')' );
472 rOutStm
.WriteOString( "SFX_STUB_PTR_STATE_NONE" );
474 rOutStm
.WriteChar( ',' ) << endl
;
475 WriteTab( rOutStm
, 4 );
479 rOutStm
.WriteOString( MakeSlotName( SvHash_Toggle() ) ).WriteChar( '|' );
480 if( GetAutoUpdate() )
481 rOutStm
.WriteOString( MakeSlotName( SvHash_AutoUpdate() ) ).WriteChar( '|' );
483 rOutStm
.WriteOString( MakeSlotName( SvHash_Asynchron() ) ).WriteChar( '|' );
484 if( GetRecordPerItem() )
485 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordPerItem() ) ).WriteChar( '|' );
486 if( GetRecordPerSet() )
487 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordPerSet() ) ).WriteChar( '|' );
489 rOutStm
.WriteOString( MakeSlotName( SvHash_NoRecord() ) ).WriteChar( '|' );
490 if( GetRecordAbsolute() )
491 rOutStm
.WriteOString( MakeSlotName( SvHash_RecordAbsolute() ) ).WriteChar( '|' );
492 if( GetMenuConfig() )
493 rOutStm
.WriteOString( MakeSlotName( SvHash_MenuConfig() ) ).WriteChar( '|' );
494 if( GetToolBoxConfig() )
495 rOutStm
.WriteOString( MakeSlotName( SvHash_ToolBoxConfig() ) ).WriteChar( '|' );
496 if( GetAccelConfig() )
497 rOutStm
.WriteOString( MakeSlotName( SvHash_AccelConfig() ) ).WriteChar( '|' );
499 rOutStm
.WriteOString( MakeSlotName( SvHash_FastCall() ) ).WriteChar( '|' );
501 rOutStm
.WriteOString( MakeSlotName( SvHash_Container() ) ).WriteChar( '|' );
502 if ( GetReadOnlyDoc() )
503 rOutStm
.WriteOString( MakeSlotName( SvHash_ReadOnlyDoc() ) ).WriteChar( '|' );
504 rOutStm
.WriteOString( "SfxSlotMode::NONE" );
506 rOutStm
.WriteChar( ',' ) << endl
;
507 WriteTab( rOutStm
, 4 );
508 if ( GetDisableFlags().isEmpty() )
509 rOutStm
.WriteOString( "SfxDisableFlags::NONE" );
511 rOutStm
.WriteOString( GetDisableFlags() );
513 // write attribute type
514 rOutStm
.WriteChar( ',' ) << endl
;
515 WriteTab( rOutStm
, 4 );
517 SvMetaType
* pT
= GetType();
520 SvMetaType
* pRT
= GetType()->GetReturnType();
521 pT
= pRT
? pRT
: rBase
.FindType( "SfxVoidItem" );
526 assert(pT
->IsItem());
527 rOutStm
.WriteOString( pT
->GetName() );
528 if( !SvIdlDataBase::FindType( pT
, rBase
.aUsedTypes
) )
529 rBase
.aUsedTypes
.push_back( pT
);
532 rOutStm
.WriteOString( "SfxVoidItem not defined" );
535 rOutStm
.WriteChar( ',' ) << endl
;
536 WriteTab( rOutStm
, 4 );
538 .WriteOString( OString::number(nCount
) )
539 .WriteOString( "/*Offset*/, " );
543 SvMetaType
* pType
= GetType();
544 size_t nSCount
= pType
->GetAttrCount();
546 .WriteOString( OString::number(nSCount
) )
547 .WriteOString( "/*Count*/," );
550 rOutStm
.WriteOString( "0," );
552 rOutStm
.WriteOString( " " );
554 // Method/Property flags
556 rOutStm
.WriteOString( "SfxSlotMode::METHOD|" );
558 rOutStm
.WriteOString( "SfxSlotMode::NONE" );
562 rOutStm
.WriteOString( ",\"" );
563 rOutStm
.WriteOString( GetName() );
564 rOutStm
.WriteOString( "\"" );
567 rOutStm
.WriteOString( " )," ) << endl
;
570 sal_uInt16
SvMetaSlot::WriteSlotParamArray( SvIdlDataBase
& rBase
, SvStream
& rOutStm
) const
575 SvMetaType
* pType
= GetType();
577 if( !SvIdlDataBase::FindType( pType
, rBase
.aUsedTypes
) )
578 rBase
.aUsedTypes
.push_back( pType
);
580 const SvRefMemberList
<SvMetaAttribute
*>& rList
=
581 pType
->GetAttrList();
582 for( size_t n
= 0; n
< rList
.size(); n
++ )
584 SvMetaAttribute
* pPar
= rList
[n
];
585 SvMetaType
* pPType
= pPar
->GetType();
586 WriteTab( rOutStm
, 1 );
587 rOutStm
.WriteOString("{ (const SfxType*) &a")
589 .WriteOString(pPType
->GetName()).WriteOString("_Impl, ")
591 .WriteOString("\"").WriteOString(pPar
->GetName()).WriteOString("\", ")
593 .WriteOString(pPar
->GetSlotId().getString()).WriteOString(" },") << endl
;
594 if( !SvIdlDataBase::FindType( pPType
, rBase
.aUsedTypes
) )
595 rBase
.aUsedTypes
.push_back( pPType
);
597 return static_cast<sal_uInt16
>(rList
.size());
600 sal_uInt16
SvMetaSlot::WriteSlotMap( std::string_view rShellName
, sal_uInt16 nCount
,
601 SvSlotElementList
& rSlotList
,
603 SvIdlDataBase
& rBase
,
606 // SlotId, if not specified generate from name
607 OString slotId
= GetSlotId().getString();
609 sal_uInt16 nSCount
= 0;
612 SvMetaType
* pType
= GetType();
613 nSCount
= static_cast<sal_uInt16
>(pType
->GetAttrCount());
616 WriteSlot( rShellName
, nCount
, slotId
, rSlotList
, nStart
, rBase
, rOutStm
);
620 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */