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 <sal/config.h>
22 #include <o3tl/safeint.hxx>
23 #include <sal/log.hxx>
24 #include <comphelper/fileformat.h>
25 #include <tools/stream.hxx>
27 #include <svl/macitem.hxx>
28 #include <stringio.hxx>
32 SvxMacro::SvxMacro( OUString _aMacName
, const OUString
&rLanguage
)
33 : aMacName(std::move( _aMacName
)), aLibName( rLanguage
),
34 eType( EXTENDED_STYPE
)
36 if ( rLanguage
== SVX_MACRO_LANGUAGE_STARBASIC
)
38 else if ( rLanguage
== SVX_MACRO_LANGUAGE_JAVASCRIPT
)
42 const OUString
& SvxMacro::GetLanguage()const
46 return SVX_MACRO_LANGUAGE_STARBASIC
;
48 else if(eType
==JAVASCRIPT
)
50 return SVX_MACRO_LANGUAGE_JAVASCRIPT
;
52 else if(eType
==EXTENDED_STYPE
)
54 return SVX_MACRO_LANGUAGE_SF
;
60 SvxMacroTableDtor
& SvxMacroTableDtor::operator=( const SvxMacroTableDtor
& rTbl
)
64 aSvxMacroTable
.clear();
65 aSvxMacroTable
.insert(rTbl
.aSvxMacroTable
.begin(), rTbl
.aSvxMacroTable
.end());
70 bool SvxMacroTableDtor::operator==( const SvxMacroTableDtor
& rOther
) const
72 // Count different => odd in any case
73 // Compare single ones; the sequence matters due to performance reasons
74 return std::equal(aSvxMacroTable
.begin(), aSvxMacroTable
.end(),
75 rOther
.aSvxMacroTable
.begin(), rOther
.aSvxMacroTable
.end(),
76 [](const SvxMacroTable::value_type
& rOwnEntry
, const SvxMacroTable::value_type
& rOtherEntry
) {
77 const SvxMacro
& rOwnMac
= rOwnEntry
.second
;
78 const SvxMacro
& rOtherMac
= rOtherEntry
.second
;
79 return rOwnEntry
.first
== rOtherEntry
.first
80 && rOwnMac
.GetLibName() == rOtherMac
.GetLibName()
81 && rOwnMac
.GetMacName() == rOtherMac
.GetMacName();
85 void SvxMacroTableDtor::Read( SvStream
& rStrm
)
88 rStrm
.ReadUInt16( nVersion
);
91 rStrm
.ReadInt16(nReadMacro
);
94 SAL_WARN("editeng", "Parsing error: negative value " << nReadMacro
);
98 auto nMacro
= o3tl::make_unsigned(nReadMacro
);
100 const size_t nMinStringSize
= rStrm
.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE
? 4 : 2;
101 size_t nMinRecordSize
= 2 + 2*nMinStringSize
;
102 if( SVX_MACROTBL_VERSION40
<= nVersion
)
105 const size_t nMaxRecords
= rStrm
.remainingSize() / nMinRecordSize
;
106 if (nMacro
> nMaxRecords
)
108 SAL_WARN("editeng", "Parsing error: " << nMaxRecords
<<
109 " max possible entries, but " << nMacro
<< " claimed, truncating");
110 nMacro
= nMaxRecords
;
113 for (decltype(nMacro
) i
= 0; i
< nMacro
; ++i
)
115 sal_uInt16 nCurKey
, eType
= STARBASIC
;
116 OUString aLibName
, aMacName
;
117 rStrm
.ReadUInt16( nCurKey
);
118 aLibName
= readByteString(rStrm
);
119 aMacName
= readByteString(rStrm
);
121 if( SVX_MACROTBL_VERSION40
<= nVersion
)
122 rStrm
.ReadUInt16( eType
);
124 aSvxMacroTable
.emplace( SvMacroItemId(nCurKey
), SvxMacro( aMacName
, aLibName
, static_cast<ScriptType
>(eType
) ) );
128 SvStream
& SvxMacroTableDtor::Write( SvStream
& rStream
) const
130 sal_uInt16 nVersion
= SOFFICE_FILEFORMAT_31
== rStream
.GetVersion()
131 ? SVX_MACROTBL_VERSION31
132 : SVX_MACROTBL_VERSION40
;
134 if( SVX_MACROTBL_VERSION40
<= nVersion
)
135 rStream
.WriteUInt16( nVersion
);
137 rStream
.WriteUInt16( aSvxMacroTable
.size() );
139 for( const auto& rEntry
: aSvxMacroTable
)
141 if (rStream
.GetError() != ERRCODE_NONE
)
143 const SvxMacro
& rMac
= rEntry
.second
;
144 rStream
.WriteUInt16( static_cast<sal_uInt16
>(rEntry
.first
) );
145 writeByteString(rStream
, rMac
.GetLibName());
146 writeByteString(rStream
, rMac
.GetMacName());
148 if( SVX_MACROTBL_VERSION40
<= nVersion
)
149 rStream
.WriteUInt16( rMac
.GetScriptType() );
154 // returns NULL if no entry exists, or a pointer to the internal value
155 const SvxMacro
* SvxMacroTableDtor::Get(SvMacroItemId nEvent
) const
157 SvxMacroTable::const_iterator it
= aSvxMacroTable
.find(nEvent
);
158 return it
== aSvxMacroTable
.end() ? nullptr : &(it
->second
);
161 // returns NULL if no entry exists, or a pointer to the internal value
162 SvxMacro
* SvxMacroTableDtor::Get(SvMacroItemId nEvent
)
164 SvxMacroTable::iterator it
= aSvxMacroTable
.find(nEvent
);
165 return it
== aSvxMacroTable
.end() ? nullptr : &(it
->second
);
168 // return true if the key exists
169 bool SvxMacroTableDtor::IsKeyValid(SvMacroItemId nEvent
) const
171 SvxMacroTable::const_iterator it
= aSvxMacroTable
.find(nEvent
);
172 return it
!= aSvxMacroTable
.end();
175 // This stores a copy of the rMacro parameter
176 SvxMacro
& SvxMacroTableDtor::Insert(SvMacroItemId nEvent
, const SvxMacro
& rMacro
)
178 return aSvxMacroTable
.emplace( nEvent
, rMacro
).first
->second
;
181 // If the entry exists, remove it from the map and release it's storage
182 void SvxMacroTableDtor::Erase(SvMacroItemId nEvent
)
184 SvxMacroTable::iterator it
= aSvxMacroTable
.find(nEvent
);
185 if ( it
!= aSvxMacroTable
.end())
187 aSvxMacroTable
.erase(it
);
191 bool SvxMacroItem::operator==( const SfxPoolItem
& rAttr
) const
193 assert(SfxPoolItem::operator==(rAttr
));
195 const SvxMacroTableDtor
& rOwn
= aMacroTable
;
196 const SvxMacroTableDtor
& rOther
= static_cast<const SvxMacroItem
&>(rAttr
).aMacroTable
;
198 return rOwn
== rOther
;
201 SvxMacroItem
* SvxMacroItem::Clone( SfxItemPool
* ) const
203 return new SvxMacroItem( *this );
206 bool SvxMacroItem::GetPresentation
208 SfxItemPresentation
/*ePres*/,
209 MapUnit
/*eCoreUnit*/,
210 MapUnit
/*ePresUnit*/,
216 SvxMacroTableDtor& rTbl = (SvxMacroTableDtor&)GetMacroTable();
217 SvxMacro* pMac = rTbl.First();
221 rText += pMac->GetLibName();
223 rText += pMac->GetMacName();
234 void SvxMacroItem::SetMacro( SvMacroItemId nEvent
, const SvxMacro
& rMacro
)
236 // tdf#141123: emplace doesn't replace the element in the map if already exists
237 // see https://en.cppreference.com/w/cpp/container/map/emplace
238 // so first erase the macro if there's one for this event
239 aMacroTable
.Erase(nEvent
);
240 aMacroTable
.Insert( nEvent
, rMacro
);
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */