Coverage Report

Created: 2026-07-20 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libetonyek/src/lib/contexts/KEY2StyleContext.cpp
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/*
3
 * This file is part of the libetonyek 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
10
#include "KEY2StyleContext.h"
11
12
#include <string>
13
14
#include <boost/optional.hpp>
15
16
#include "libetonyek_xml.h"
17
#include "IWORKNumericPropertyContext.h"
18
#include "IWORKPropertyContext.h"
19
#include "IWORKPropertyMapElement.h"
20
#include "IWORKStyle.h"
21
#include "IWORKToken.h"
22
#include "IWORKValueContext.h"
23
#include "KEYProperties.h"
24
#include "KEYTypes.h"
25
#include "KEY2Dictionary.h"
26
#include "KEY2ParserState.h"
27
#include "KEY2Token.h"
28
29
namespace libetonyek
30
{
31
32
namespace
33
{
34
template<class Property>
35
class NumericPropertyContext : public IWORKPropertyContext<Property, IWORKNumberElement<typename IWORKPropertyInfo<Property>::ValueType>, +IWORKToken::NS_URI_SF | IWORKToken::number, +KEY2Token::NS_URI_KEY | KEY2Token::number>
36
{
37
  typedef IWORKPropertyContext<Property, IWORKNumberElement<typename IWORKPropertyInfo<Property>::ValueType>, +IWORKToken::NS_URI_SF | IWORKToken::number, +KEY2Token::NS_URI_KEY | KEY2Token::number> Parent_t;
38
39
public:
40
  NumericPropertyContext(IWORKXMLParserState &state, IWORKPropertyMap &propMap);
41
};
42
43
typedef IWORKValueContext<bool, IWORKNumberElement<bool>, +IWORKToken::NS_URI_SF | IWORKToken::number, +KEY2Token::NS_URI_KEY | KEY2Token::number> BoolProperty;
44
typedef IWORKValueContext<double, IWORKNumberElement<double>, +IWORKToken::NS_URI_SF | IWORKToken::number, +KEY2Token::NS_URI_KEY | KEY2Token::number> DoubleProperty;
45
typedef IWORKValueContext<int, IWORKNumberElement<int>, +IWORKToken::NS_URI_SF | IWORKToken::number, +KEY2Token::NS_URI_KEY | KEY2Token::number> IntProperty;
46
typedef IWORKNumericPropertyContext<property::AnimationAutoPlay, +KEY2Token::NS_URI_KEY | KEY2Token::number> AnimationAutoPlayPropertyElement;
47
typedef IWORKNumericPropertyContext<property::AnimationDelay, +KEY2Token::NS_URI_KEY | KEY2Token::number> AnimationDelayPropertyElement;
48
typedef IWORKNumericPropertyContext<property::AnimationDuration, +KEY2Token::NS_URI_KEY | KEY2Token::number> AnimationDurationPropertyElement;
49
}
50
51
namespace
52
{
53
class TransitionAttributesElement : public KEY2XMLElementContextBase
54
{
55
public:
56
  TransitionAttributesElement(KEY2ParserState &state, boost::optional<KEYTransition> &transition);
57
58
private:
59
  void attribute(int name, const char *value) override;
60
  IWORKXMLContextPtr_t element(int name) override;
61
  void endOfElement() override;
62
63
  boost::optional<KEYTransition> &m_transition;
64
};
65
66
TransitionAttributesElement::TransitionAttributesElement(KEY2ParserState &state, boost::optional<KEYTransition> &transition)
67
0
  : KEY2XMLElementContextBase(state)
68
0
  , m_transition(transition)
69
0
{
70
0
  m_transition=KEYTransition();
71
0
}
72
73
void TransitionAttributesElement::attribute(int name, const char *value)
74
0
{
75
0
  switch (name)
76
0
  {
77
0
  case +IWORKToken::ID | IWORKToken::NS_URI_SFA :
78
0
    KEY2XMLElementContextBase::attribute(name, value);
79
0
    break;
80
0
  case +KEY2Token::type | KEY2Token::NS_URI_KEY :
81
0
  {
82
0
    std::string val(value);
83
0
    if (val=="none")
84
0
      get(m_transition).m_type=KEY_TRANSITION_STYLE_TYPE_NONE;
85
0
    else if (val=="inherited") // Checkme
86
0
      get(m_transition).m_type=KEY_TRANSITION_STYLE_TYPE_INHERITED;
87
0
    else
88
0
    {
89
0
      get(m_transition).m_type=KEY_TRANSITION_STYLE_TYPE_NAMED;
90
0
      get(m_transition).m_name=value;
91
0
      static bool first=true;
92
0
      if (first)
93
0
      {
94
0
        first=false;
95
0
        ETONYEK_DEBUG_MSG(("TransitionAttributesElement::attribute[KEY2StyleContext.cpp]: find some unexpected type=%s\n", value));
96
0
      }
97
0
    }
98
0
    break;
99
0
  }
100
0
  default :
101
0
    ETONYEK_DEBUG_MSG(("TransitionAttributesElement::attribute[KEY2StyleContext.cpp]: find some unknown attribute\n"));
102
0
    break;
103
0
  }
104
0
}
105
106
IWORKXMLContextPtr_t TransitionAttributesElement::element(const int name)
107
0
{
108
  // find <animationAuto/animationDelay/animationDuration... in Keynote 5 files
109
0
  switch (name)
110
0
  {
111
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationAuto :
112
0
  case +KEY2Token::animationAuto :
113
0
    return std::make_shared<BoolProperty>(getState(), get(m_transition).m_automatic);
114
0
  case +KEY2Token::animationDelay :
115
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationDelay :
116
0
    return std::make_shared<DoubleProperty>(getState(), get(m_transition).m_delay);
117
0
  case +KEY2Token::animationDuration :
118
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationDuration :
119
0
    return std::make_shared<DoubleProperty>(getState(), get(m_transition).m_duration);
120
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::direction :
121
0
    return std::make_shared<IntProperty>(getState(), get(m_transition).m_direction);
122
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::BGBuildDurationProperty :
123
0
    break;
124
0
  default:
125
0
  {
126
    /* also <key:com.apple.iWork.Keynote.BLTFadeThruColor.color>
127
       <key:com.apple.iWork.Keynote.BLTMosaicFlip.numberOfParticles>
128
       <key:com.apple.iWork.Keynote.BLTMosaicFlip.type>
129
       <key:com.apple.iWork.Keynote.BUKTwist.twist>
130
       <key:com.apple.iWork.Keynote.KLNSparkle.color>
131
       <key:com.apple.iWork.Keynote.KLNSwap.angle>
132
       <key:com.apple.iWork.Keynote.KLNSwap.spacing*/
133
0
    static bool first=true;
134
0
    if (first)
135
0
    {
136
0
      first=false;
137
0
      ETONYEK_DEBUG_MSG(("TransitionAttributesElement::element[KEY2StyleContext.cpp]: found some unexpected element\n"));
138
0
    }
139
0
    break;
140
0
  }
141
0
  }
142
143
0
  return IWORKXMLContextPtr_t();
144
0
}
145
146
void TransitionAttributesElement::endOfElement()
147
0
{
148
0
  if (getId())
149
0
    getState().getDictionary().m_transitions[get(getId())]=get(m_transition);
150
0
}
151
}
152
153
namespace
154
{
155
class TransitionElement : public KEY2XMLElementContextBase
156
{
157
public:
158
  TransitionElement(KEY2ParserState &state, boost::optional<KEYTransition> &transition);
159
160
private:
161
  IWORKXMLContextPtr_t element(int name) override;
162
163
  boost::optional<KEYTransition> &m_transition;
164
};
165
166
TransitionElement::TransitionElement(KEY2ParserState &state, boost::optional<KEYTransition> &transition)
167
0
  : KEY2XMLElementContextBase(state)
168
0
  , m_transition(transition)
169
0
{
170
0
}
171
172
IWORKXMLContextPtr_t TransitionElement::element(const int name)
173
0
{
174
0
  switch (name)
175
0
  {
176
0
  case +IWORKToken::NS_URI_SF | IWORKToken::transition_attributes :
177
0
    return std::make_shared<TransitionAttributesElement>(getState(), m_transition);
178
0
  default:
179
0
    ETONYEK_DEBUG_MSG(("TransitionElement::element[KEY2StyleContext.cpp]: found unexpected element %d\n", name));
180
0
    break;
181
0
  }
182
183
0
  return IWORKXMLContextPtr_t();
184
0
}
185
}
186
187
namespace
188
{
189
190
class PropertyMapElement : public KEY2XMLElementContextBase
191
{
192
public:
193
  PropertyMapElement(KEY2ParserState &state, IWORKPropertyMap &propMap);
194
195
private:
196
  IWORKXMLContextPtr_t element(int name) override;
197
  void endOfElement() override;
198
199
private:
200
  IWORKPropertyMapElement m_base;
201
  IWORKPropertyMap &m_propMap;
202
  boost::optional<KEYTransition> m_transition;
203
};
204
205
PropertyMapElement::PropertyMapElement(KEY2ParserState &state, IWORKPropertyMap &propMap)
206
0
  : KEY2XMLElementContextBase(state)
207
0
  , m_base(state, propMap)
208
0
  , m_propMap(propMap)
209
0
  , m_transition()
210
0
{
211
0
}
212
213
IWORKXMLContextPtr_t PropertyMapElement::element(const int name)
214
0
{
215
0
  switch (name)
216
0
  {
217
0
  case +IWORKToken::NS_URI_SF | IWORKToken::animationAutoPlay :
218
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationAutoPlay :
219
0
    return std::make_shared<AnimationAutoPlayPropertyElement>(getState(), m_propMap);
220
0
  case +IWORKToken::NS_URI_SF | IWORKToken::animationDelay :
221
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationDelay :
222
0
    return std::make_shared<AnimationDelayPropertyElement>(getState(), m_propMap);
223
0
  case +IWORKToken::NS_URI_SF | IWORKToken::animationDuration :
224
0
  case +KEY2Token::NS_URI_KEY | KEY2Token::animationDuration :
225
0
    return std::make_shared<AnimationDurationPropertyElement>(getState(), m_propMap);
226
0
  case +IWORKToken::NS_URI_SF | IWORKToken::transition :
227
0
    return std::make_shared<TransitionElement>(getState(), m_transition);
228
0
  default:
229
0
    break;
230
0
  }
231
232
0
  return m_base.element(name);
233
0
}
234
235
void PropertyMapElement::endOfElement()
236
0
{
237
0
  if (m_transition)
238
0
    m_propMap.template put<property::Transition>(get(m_transition));
239
0
}
240
}
241
242
KEY2StyleContext::KEY2StyleContext(KEY2ParserState &state, IWORKStyleMap_t *const styleMap, const char *const defaultParent, const bool /*nested*/)
243
0
  : KEY2XMLElementContextBase(state)
244
0
  , m_props()
245
0
  , m_base(state, m_props, styleMap, defaultParent)
246
0
  , m_ident()
247
0
  , m_parentIdent()
248
0
{
249
0
}
250
251
void KEY2StyleContext::attribute(const int name, const char *const value)
252
0
{
253
0
  switch (name)
254
0
  {
255
0
  case +IWORKToken::NS_URI_SF | IWORKToken::ident :
256
0
    m_ident = value;
257
0
    break;
258
0
  case +IWORKToken::NS_URI_SF | IWORKToken::parent_ident :
259
0
    m_parentIdent = value;
260
0
    break;
261
0
  default :
262
0
    KEY2XMLElementContextBase::attribute(name, value);
263
0
    break;
264
0
  }
265
266
0
  m_base.attribute(name, value);
267
0
}
268
269
IWORKXMLContextPtr_t KEY2StyleContext::element(const int name)
270
0
{
271
0
  switch (name)
272
0
  {
273
0
  case +IWORKToken::NS_URI_SF | IWORKToken::property_map :
274
0
    return std::make_shared<PropertyMapElement>(getState(), m_props);
275
0
  default:
276
0
    ETONYEK_DEBUG_MSG(("KEY2StyleContext::element: found unexpected element %d\n", name));
277
0
  }
278
279
0
  return IWORKXMLContextPtr_t();
280
0
}
281
282
void KEY2StyleContext::endOfElement()
283
0
{
284
0
  m_base.endOfElement();
285
0
}
286
287
}
288
289
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */