Scribus
Open source desktop publishing at your fingertips
simple_actions.h
1 /*
2  * simple_actions.h
3  *
4  *
5  * Created by Andreas Vox on 02.06.06.
6  * Copyright 2006 under GPL2. All rights reserved.
7  *
8  */
9 
10 
11 
12 #ifndef SIMPLE_ACTIONS_H
13 #define SIMPLE_ACTIONS_H
14 
15 #include "actions.h"
16 /*****
17 
18  Defines the following actions:
19 
20  Factory<D>( fun ) - -> D
21  Factory<D>() - -> D
22  Prototype<D>( data ) - -> D
23  Top<O>( 3 ) O x x x -> O x x x O
24  Getter<O,D>( fun ) O -> O D
25  Setter<O,D>( fun ) O D -> O D
26  SetterWithConversion<O,D,S>( fun ) O S -> O S
27  SetAttribute<O,D>( fun, name, default) O -> O
28  SetAttribute<O,D>( fun, name) O -> O
29  SetAttributeWithConversion<O,D>( f, n, c, def) O -> O
30  SetAttributeWithConversion<O,D>( f, n, convert) O -> O
31  SetAttributes<O>( fun ) O -> O
32  SetText<O,D>( fun ) O -> O
33  AddText<O,D>( fun ) O -> O
34  Transform<D,E> ( fun ) D -> E
35  *TransformLater<D,E> ( fun ) D -> E
36  IdRef<O>() O -> O
37  Lookup<D>( name ) - -> D
38  PatchIdRefAttribute<O,D>( fun, name) O -> O
39  Result<O>() O -> O
40 
41 *****/
42 
43 
44 namespace desaxe {
45 
46  using namespace desaxe;
47 
52 template<class Obj_Type>
53 class Factory_body : public Generator_body<Obj_Type>
54 {
55 public:
56  typedef Obj_Type* (*FunType)();
57 
58  Factory_body()
59  : create_(NULL)
60  {}
61 
62  Factory_body(FunType create)
63  : create_(create)
64  {}
65 
66  void begin(const Xml_string&, Xml_attr)
67  {
68  this->dig->push(create_? create_() : new Obj_Type());
69  }
70 private:
71  Obj_Type* (*create_)();
72 };
73 
74 template <class Type>
75 struct Factory : public MakeGenerator<Factory_body<Type>, Type, typename Factory_body<Type>::FunType>
76 {
77  Factory(typename Factory_body<Type>::FunType create)
79 
80  Factory()
82 };
83 
84 
88 template<class Obj_Type>
89 class FactoryWithArgs_body : public Generator_body<Obj_Type>
90 {
91 public:
92  typedef Obj_Type* (*FunType)(const Xml_string&, Xml_attr);
93 
94  FactoryWithArgs_body(FunType create)
95  : create_(create)
96  {}
97 
98  void begin(const Xml_string& name, Xml_attr attr)
99  {
100  this->dig->push(create_(name, attr));
101  }
102 private:
103  Obj_Type* (*create_)(const Xml_string&, Xml_attr);
104 };
105 
106 template <class Type>
107 struct FactoryWithArgs : public MakeGenerator<FactoryWithArgs_body<Type>, Type, typename FactoryWithArgs_body<Type>::FunType>
108 {
111 };
112 
113 
118 template<class Obj_Type>
119 class FactoryWithName_body : public Generator_body<Obj_Type>
120 {
121 public:
122  typedef Obj_Type* (*FunType)(const Xml_string&);
123 
125  : create_(NULL)
126  {}
127 
128  FactoryWithName_body(FunType create)
129  : create_(create)
130  {}
131 
132  void begin(const Xml_string& tag, Xml_attr)
133  {
134  this->dig->push(create_? create_(tag) : new Obj_Type(tag));
135  }
136 private:
137  FunType create_;
138 };
139 
140 template <class Type>
141 struct FactoryWithName : public MakeGenerator<FactoryWithName_body<Type>, Type, typename FactoryWithName_body<Type>::FunType>
142 {
145 
148 };
149 
150 
154 template<class Obj_Type>
155 class Prototype_body : public Generator_body<Obj_Type>
156 {
157 public:
158  Prototype_body(const Obj_Type& proto)
159  : proto_(new Obj_Type(proto))
160  {}
161 
162  ~Prototype_body()
163  {
164  delete proto_;
165  }
166 
167  void begin(const Xml_string&, Xml_attr)
168  {
169  this->dig->push(new Obj_Type(proto_));
170  }
171 private:
172  const Obj_Type* proto_;
173 };
174 
175 
176 template <class Type>
177 struct Prototype : public MakeGenerator<Prototype_body<Type>, Type, const Type&>
178 {
179  Prototype(const Type& def)
180  : MakeGenerator<Prototype_body<Type>, Type, const Type&>::MakeGenerator(def) {}
181 };
182 
183 
184 
188 template<class Obj_Type>
189 class Top_body : public Generator_body<Obj_Type>
190 {
191 public:
192  Top_body(unsigned int n)
193  : distance(n)
194  {}
195 
196  void begin(const Xml_string&, Xml_attr)
197  {
198  this->dig->push(this->dig->template top<Obj_Type>(distance));
199  }
200 private:
201  unsigned int distance;
202 };
203 
204 
205 template <class Type>
206 struct Top : public MakeGenerator<Top_body<Type>, Type, unsigned int>
207 {
208  Top(unsigned int distance)
209  : MakeGenerator<Top_body<Type>, Type, unsigned int>::MakeGenerator(distance) {}
210  Top()
211  : MakeGenerator<Top_body<Type>, Type, unsigned int>::MakeGenerator(0) {}
212 };
213 
214 
215 
220 template<class Obj_Type, class Data_Type>
221 class Getter_body : public Generator_body<Data_Type>
222 {
223 public:
224  typedef const Data_Type& (Obj_Type::*FunType)();
225 
226  Getter_body(FunType get)
227  : get_(get)
228  {}
229 
230  void begin(const Xml_string&, Xml_attr)
231  {
232  Obj_Type* obj = this->dig->template top<Obj_Type>(1);
233  Data_Type* data = (obj->*get_)();
234  this->dig->push(data);
235  }
236 private:
237  FunType get_;
238 };
239 
240 
241 template <class Type, class Data>
242 struct Getter : public MakeGenerator<Getter_body<Type, Data>, Data, typename Getter_body<Type, Data>::FunType>
243 {
246 };
247 
248 
252 template<class Obj_Type, class Data_Type, class Store_Type>
253 class SetterP_body : public Action_body
254 {
255 public:
256  typedef void (Obj_Type::*FunType)(Data_Type*);
257 
258  SetterP_body(FunType set)
259  : set_(set)
260  {}
261 
262  void end(const Xml_string&)
263  {
264  Store_Type* data = this->dig->template top<Store_Type>();
265  Obj_Type* obj = this->dig->template top<Obj_Type>(1);
266 #ifdef DESAXE_DEBUG
267  std::cerr << "setter(ptr): " << obj << " .= " << data << "\n";
268 #endif
269  (obj->*set_)( data );
270  }
271 private:
272  FunType set_;
273 };
274 
275 
276 template <class Type, class Data, class Store = Data>
277 struct SetterP : public MakeAction<SetterP_body<Type, Data, Store>, typename SetterP_body<Type, Data, Store>::FunType>
278 {
281 };
282 
283 
287 template<class Obj_Type, class Data_Type>
288 class Setter_body : public Action_body
289 {
290 public:
291  typedef void (Obj_Type::*FunType)(Data_Type);
292 
293  Setter_body(FunType set)
294  : set_(set)
295  {}
296 
297  void end(const Xml_string&)
298  {
299  Data_Type* data = this->dig->template top<Data_Type>();
300  Obj_Type* obj = this->dig->template top<Obj_Type>(1);
301 #ifdef DESAXE_DEBUG
302  std::cerr << "setter: " << obj << " .= *(" << data << ")\n";
303 #endif
304  (obj->*set_)( *data );
305  }
306 private:
307  FunType set_;
308 };
309 
310 
311 template <class Type, class Data>
312 struct Setter : public MakeAction<Setter_body<Type, Data>, typename Setter_body<Type, Data>::FunType>
313 {
316 };
317 
318 
322 template<class Obj_Type, class Data_Type, class Store_Type>
324 {
325 public:
326  typedef void (Obj_Type::*FunType)(Data_Type);
327  typedef Data_Type (*ConvType)(Store_Type);
328 
329  SetterWithConversion_body(FunType set, ConvType conv)
330  : set_(set), conv_(conv)
331  {}
332 
333  void end(const Xml_string&)
334  {
335  Store_Type* data = this->dig->template top<Store_Type>();
336  Obj_Type* obj = this->dig->template top<Obj_Type>(1);
337 #ifdef DESAXE_DEBUG
338  std::cerr << "setter: " << obj << " .= " << conv_ << "(*" << data << ")\n";
339 #endif
340  if (conv_)
341  (obj->*set_)( conv_(*data) );
342  else
343  (obj->*set_)( static_cast<Data_Type>(*data) );
344  }
345 private:
346  FunType set_;
347  ConvType conv_;
348 };
349 
350 
351 template <class Type, class Data, class Store>
352 struct SetterWithConversion : public MakeAction<SetterWithConversion_body<Type, Data, Store>, typename SetterWithConversion_body<Type, Data, Store>::FunType, typename SetterWithConversion_body<Type, Data, Store>::ConvType>
353 {
357  SetterWithConversion(typename BodyType::FunType set, typename SetterWithConversion_body<Type, Data, Store>::ConvType conv)
358  : MakeAction<SetterWithConversion_body<Type, Data, Store>, typename SetterWithConversion_body<Type, Data, Store>::FunType, typename SetterWithConversion_body<Type, Data, Store>::ConvType>(set, conv) {}
359 };
360 
361 
365 template<class Obj_Type>
367 {
368 public:
369  typedef void (Obj_Type::*FunType)(const Xml_string&, const Xml_string&) ;
370 
371  SetAttributes_body(FunType set) : set_(set)
372  {}
373 
374  void begin(const Xml_string&, Xml_attr attr)
375  {
376  Obj_Type* obj = this->dig->template top<Obj_Type>();
377  Xml_attr::iterator it;
378  for(it=attr.begin(); it != attr.end(); ++it)
379  (obj->*set_)( Xml_key(it), Xml_data(it) );
380  }
381 private:
382  FunType set_;
383 };
384 
385 
386 template <class Type>
387 struct SetAttributes : public MakeAction<SetAttributes_body<Type>, typename SetAttributes_body<Type>::FunType>
388 {
391 };
392 
393 
394 
399 template<class Obj_Type, class Data_Type>
401 {
402 public:
403  typedef void (Obj_Type::*FunType)(Data_Type) ;
404 
405  SetAttribute_body(FunType set, const Xml_string& name)
406  : set_(set), name_(name), default_(), hasDefault_(false)
407  {}
408 
409  SetAttribute_body(FunType set, const Xml_string& name, Data_Type deflt)
410  : set_(set), name_(name), default_(deflt), hasDefault_(true)
411  {}
412 
413  void begin(const Xml_string&, Xml_attr attr)
414  {
415  Obj_Type* obj = this->dig->template top<Obj_Type>();
416  Xml_attr::iterator it = attr.find(name_);
417  if (it != attr.end() )
418  (obj->*set_)( Data_Type(Xml_data(it)) );
419  else if (hasDefault_)
420  (obj->*set_)( default_ );
421  }
422 private:
423  FunType set_;
424  Xml_string name_;
425  Data_Type default_;
426  bool hasDefault_;
427 };
428 
429 
430 template <class Type, class Data>
431 struct SetAttribute : public MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data>
432 {
433  SetAttribute(typename SetAttribute_body<Type,Data>::FunType set, const Xml_string& name)
434  : MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data>(set,name) {}
435 
436  SetAttribute(typename SetAttribute_body<Type,Data>::FunType set, const Xml_string& name, Data deflt)
437  : MakeAction<SetAttribute_body<Type,Data>, typename SetAttribute_body<Type,Data>::FunType, const Xml_string&, Data>(set,name,deflt) {}
438 };
439 
440 
441 
446 template<class Obj_Type, class Data_Type>
448 {
449 public:
450  typedef void (Obj_Type::*FunType)(Data_Type) ;
451  typedef Data_Type (*ConvType)(const Xml_string&);
452 
453  SetAttributeWithConversion_body(FunType set, const Xml_string& name, ConvType conv)
454  : set_(set), name_(name), conv_(conv), default_(), hasDefault_(false)
455  {}
456 
457  SetAttributeWithConversion_body(FunType set, const Xml_string& name, ConvType conv, Data_Type deflt)
458  : set_(set), name_(name), conv_(conv), default_(deflt), hasDefault_(true)
459  {}
460 
461  void begin(const Xml_string&, Xml_attr attr)
462  {
463  Obj_Type* obj = this->dig->template top<Obj_Type>();
464  Xml_attr::iterator it = attr.find(name_);
465  if (it != attr.end() && conv_)
466  (obj->*set_)( conv_(Xml_data(it)) );
467  else if (hasDefault_)
468  (obj->*set_)( default_ );
469  }
470 private:
471  FunType set_;
472  Xml_string name_;
473  ConvType conv_;
474  Data_Type default_;
475  bool hasDefault_;
476 };
477 
478 
479 template <class Type, class Data>
480 struct SetAttributeWithConversion : public MakeAction<SetAttributeWithConversion_body<Type,Data>, typename SetAttributeWithConversion_body<Type,Data>::FunType, const Xml_string&, typename SetAttributeWithConversion_body<Type,Data>::ConvType, Data>
481 {
483 
484  SetAttributeWithConversion(typename BodyType::FunType set, const Xml_string& name, typename BodyType::ConvType conv)
486 
487  SetAttributeWithConversion(typename BodyType::FunType set, const Xml_string& name, typename BodyType::ConvType conv, Data deflt)
489 };
490 
491 
492 
497 template<class Obj_Type>
498 class AddText_body : public Action_body
499 {
500 public:
501  typedef void (Obj_Type::*FunType)(const Xml_string&);
502 
503  AddText_body(FunType add) : addT(add)
504  {}
505 
506  void chars(const Xml_string& txt)
507  {
508  Obj_Type* obj = this->dig->template top<Obj_Type>();
509  (obj->*addT)( txt );
510  }
511 private:
512  FunType addT;
513 };
514 
515 
516 
517 template <class Type>
518 struct AddText : public MakeAction<AddText_body<Type>, typename AddText_body<Type>::FunType>
519 {
522 };
523 
524 
525 
526 
533 template<class Obj_Type>
534 class SetText_body : public Action_body
535 {
536 public:
537  typedef void (Obj_Type::*FunType)(const Xml_string&);
538 
539  SetText_body(FunType set) : setT(set)
540  {}
541 
542  void begin(const Xml_string&, Xml_attr)
543  {
544  txt = "";
545  }
546 
547  void chars(const Xml_string& chunk)
548  {
549  txt += chunk;
550  }
551 
552  void end(const Xml_string& tag)
553  {
554  Obj_Type* obj = this->dig->template top<Obj_Type>();
555  (obj->*setT)( txt );
556  }
557 
558 private:
559  FunType setT;
560  Xml_string txt;
561 };
562 
563 
564 
565 template <class Type>
566 struct SetText : public MakeAction<SetText_body<Type>, typename SetText_body<Type>::FunType>
567 {
569  SetText(typename BodyType::FunType set)
571 };
572 
573 
574 
575 
576 template<class Obj_Type>
577 class Store_body : public Action_body
578 {
579 public:
580  Store_body(const Xml_string& name) : m_name(name) {}
581 
582  void begin(const Xml_string& tag, Xml_attr attr)
583  {
584  Obj_Type* obj = this->dig->template top<Obj_Type>();
585 // qDebug() << QString("Store: %1 <- %2").arg(tag).arg(typeid(obj).name());
586  this->dig->template store<Obj_Type>(m_name, obj);
587  }
588 
589 private:
590  Xml_string m_name;
591 };
592 
593 
594 template <class Type>
595 struct Store : public MakeAction<Store_body<Type>, const Xml_string& >
596 {
597  Store(const Xml_string& name) : MakeAction<Store_body<Type>, const Xml_string& >(name) {}
598 };
599 
600 
601 
613 template<class Obj_Type>
614 class IdRef_body : public Action_body
615 {
616 public:
617  IdRef_body() : stack() {}
618 
619  void begin(const Xml_string&, Xml_attr attr)
620  {
621  Obj_Type* obj = this->dig->template top<Obj_Type>();
622  Mode mode;
623  Xml_attr::iterator it = attr.find("id");
624  if (it != attr.end())
625  {
626  mode.ID = attr["id"];
627  mode.isIdRef = false;
628  }
629  else {
630  Xml_attr::iterator it = attr.find("idref");
631  if (it != attr.end())
632  {
633  mode.ID = attr["idref"];
634  mode.isIdRef = true;
635  }
636  else {
637  mode.ID = "";
638  mode.isIdRef = false;
639  }
640  }
641  if (mode.ID != "")
642  {
643  Obj_Type* storedObj = this->dig->template lookup<Obj_Type>(mode.ID);
644  if ( !storedObj )
645  {
646  this->dig->store(mode.ID, obj);
647  }
648  else if ( !mode.isIdRef )
649  {
650  delete (this->dig->template top<Obj_Type>());
651  this->dig->pop();
652  this->dig->push(this->dig->template lookup<Obj_Type>(mode.ID));
653  }
654  else
655  {
656  // NYI: set trigger
657  }
658  }
659  stack.push_back(mode);
660 
661  }
662  void end(const Xml_string&)
663  {
664  Mode mode = stack.back();
665  stack.pop_back();
666  if (mode.isIdRef)
667  {
668  delete (this->dig->template top<Obj_Type>());
669  this->dig->pop();
670  this->dig->push(this->dig->template lookup<Obj_Type>(mode.ID));
671  // NYI reset trigger
672  }
673  }
674 private:
675  struct Mode { Xml_string ID; bool isIdRef; };
676  std::vector<Mode> stack;
677 };
678 
679 
680 template <class Type>
681 struct IdRef : public MakeAction<IdRef_body<Type> >
682 {};
683 
684 
690 template<class Data_Type>
691 class Lookup_body : public Generator_body<Data_Type>
692 {
693 public:
694  Lookup_body(const Xml_string& ID)
695  : ID_(ID)
696  {}
697 
698  void begin(const Xml_string&, Xml_attr)
699  {
700  Data_Type* data = this->dig->template lookup<Data_Type>(ID_);
701  this->dig->push(data);
702  }
703 private:
704  Xml_string ID_;
705 };
706 
707 
708 template <class Data>
709 struct Lookup : public MakeGenerator<Lookup_body<Data>, const Xml_string&>
710 {
711  Lookup(Xml_string ID)
712  : MakeGenerator<Lookup_body<Data>, const Xml_string&>::MakeGenerator(ID) {}
713 };
714 
715 
716 
720 template<class Obj_Type, class Arg_Type>
722 {
723 public:
724  typedef Obj_Type (*FunType)(const Arg_Type&);
725 
726  Transform_body(FunType fun)
727  : fun_(fun), stack()
728  {}
729 
730  void begin(const Xml_string&, Xml_attr)
731  {
732  Cell cell;
733  cell.arg = this->dig->template top<Arg_Type>();
734  cell.obj = fun_(*cell.arg);
735 #ifdef DESAXE_DEBUG
736  std::cerr << "transform: " << cell.arg << " -> " << cell.obj << ")\n";
737 #endif
738  stack.push_back(cell);
739  this->dig->pop();
740  this->dig->push(&cell.obj);
741  }
742 
743  void end(const Xml_string&)
744  {
745  Cell cell = stack.back();
746  stack.pop_back();
747  this->dig->pop();
748  this->dig->push(cell.arg);
749  }
750 private:
751  FunType fun_;
752  struct Cell { Arg_Type* arg; Obj_Type obj; };
753  std::vector<Cell> stack;
754 };
755 
756 
757 template <class Type, class Arg>
758 struct Transform : public MakeAction<Transform_body<Type, Arg>, typename Transform_body<Type, Arg>::FunType>
759 {
761  Transform(typename BodyType::FunType f) : MakeAction<BodyType, typename BodyType::FunType>(f) {}
762 };
763 
764 
765 
766 
767 template<class Obj_Type, class Data_Type>
769 {
770 public:
771  typedef void (Obj_Type::*FunType)(Data_Type*) ;
772 
773  PatchIdRefAttribute_body(FunType set, const Xml_string& name)
774  : set_(set), name_(name)
775  {}
776 
777  void begin(const Xml_string&, Xml_attr attr)
778  {
779  Xml_attr::iterator it = attr.find(name_);
780  if (it != attr.end())
781  {
782  Obj_Type* obj = this->dig->template top<Obj_Type>();
783  this->dig->template patchInvoke<Obj_Type,Data_Type>(Xml_data(it), obj, set_);
784  }
785  }
786 private:
787  FunType set_;
788  Xml_string name_;
789 };
790 
791 
792 template <class Type, class Data>
793 struct PatchIdRefAttribute : public MakeAction<PatchIdRefAttribute_body<Type,Data>, typename PatchIdRefAttribute_body<Type,Data>::FunType, const Xml_string&>
794 {
796  PatchIdRefAttribute(typename BodyType::FunType set, const Xml_string& name)
798 };
799 
800 
801 
802 
806 template<class Data_Type>
807 class Result_body : public Action_body
808 {
809 public:
810  Result_body()
811  {}
812 
813  void end(const Xml_string&)
814  {
815  this->dig->setResult(dig->template top<Data_Type>());
816  }
817 };
818 
819 
820 
821 template <class Data>
822 struct Result : public MakeAction<Result_body<Data> > {};
823 
824 
825 } // namespace
826 
827 #endif
Definition: simple_actions.h:253
Definition: simple_actions.h:498
Definition: simple_actions.h:400
Definition: simple_actions.h:431
Definition: simple_actions.h:577
Definition: actions.h:139
Definition: simple_actions.h:119
Definition: simple_actions.h:366
Definition: simple_actions.h:53
Definition: simple_actions.h:518
Definition: simple_actions.h:206
Definition: simple_actions.h:155
Definition: simple_actions.h:141
Definition: simple_actions.h:107
Definition: simple_actions.h:323
Definition: simple_actions.h:709
Definition: simple_actions.h:822
Definition: simple_actions.h:352
Definition: simple_actions.h:221
Definition: simple_actions.h:681
Definition: simple_actions.h:768
Definition: simple_actions.h:189
Definition: simple_actions.h:242
Definition: simple_actions.h:721
Definition: simple_actions.h:566
Definition: simple_actions.h:793
Definition: actions.h:28
Definition: simple_actions.h:89
Definition: simple_actions.h:614
Definition: simple_actions.h:691
Definition: simple_actions.h:177
Coord distance(Point const &a, Point const &b)
Definition: point.h:205
Definition: simple_actions.h:447
Definition: simple_actions.h:534
Definition: simple_actions.h:277
Definition: actions.h:182
Definition: simple_actions.h:758
Definition: simple_actions.h:807
Definition: simple_actions.h:288
Definition: actions.h:121
Definition: simple_actions.h:480
Definition: simple_actions.h:312
Definition: simple_actions.h:595
Definition: simple_actions.h:75
Definition: simple_actions.h:387
Definition: actions.h:18