labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

macros.h
Go to the documentation of this file.
1 /***************************************************************************
2  File : macros.h
3  Project : LabPlot
4  Description : Various preprocessor macros
5  --------------------------------------------------------------------
6  Copyright : (C) 2008 Tilman Benkert (thzs@gmx.net)
7  Copyright : (C) 2013-2015 Alexander Semke (alexander.semke@web.de)
8  Copyright : (C) 2016-2020 Stefan Gerlach (stefan.gerlach@uni.kn)
9 
10  ***************************************************************************/
11 
12 /***************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  * This program is distributed in the hope that it will be useful, *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22  * GNU General Public License for more details. *
23  * *
24  * You should have received a copy of the GNU General Public License *
25  * along with this program; if not, write to the Free Software *
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
27  * Boston, MA 02110-1301 USA *
28  * *
29  ***************************************************************************/
30 
31 #ifndef MACROS_H
32 #define MACROS_H
33 
34 // SET_NUMBER_LOCALE
35 #include <KSharedConfig>
36 #include <KConfigGroup>
37 
38 #include <QApplication>
39 #include <QMetaEnum>
40 
41 // C++ style warning (works on Windows)
42 #include <iostream>
43 #define WARN(x) std::cout << x << std::endl;
44 
45 #ifndef NDEBUG
46 #include <QDebug>
47 #define QDEBUG(x) qDebug() << x;
48 // C++ style debugging (works on Windows)
49 #include <iomanip>
50 #define DEBUG(x) std::cout << x << std::endl;
51 #else
52 #define QDEBUG(x) {}
53 #define DEBUG(x) {}
54 #endif
55 
56 #if QT_VERSION < 0x050700
57 template <class T>
58 constexpr std::add_const_t<T>& qAsConst(T& t) noexcept {
59  return t;
60 }
61 #endif
62 
63 #define WAIT_CURSOR QApplication::setOverrideCursor(QCursor(Qt::WaitCursor))
64 #define RESET_CURSOR QApplication::restoreOverrideCursor()
65 
66 #define UTF8_QSTRING(str) QString::fromUtf8(str)
67 #define STDSTRING(qstr) qstr.toUtf8().constData()
68 
69 #define ENUM_TO_STRING(class, enum, value) \
70  (class::staticMetaObject.enumerator(class::staticMetaObject.indexOfEnumerator(#enum)).valueToKey(static_cast<int>(value)))
71 #define ENUM_COUNT(class, enum) \
72  (class::staticMetaObject.enumerator(class::staticMetaObject.indexOfEnumerator(#enum)).keyCount())
73 
74 // define number locale from setting (using system locale when QLocale::AnyLanguage)
75 #define SET_NUMBER_LOCALE \
76 QLocale::Language numberLocaleLanguage = static_cast<QLocale::Language>(KSharedConfig::openConfig()->group("Settings_General").readEntry( QLatin1String("DecimalSeparatorLocale"), static_cast<int>(QLocale::Language::AnyLanguage) )); \
77 QLocale numberLocale(numberLocaleLanguage == QLocale::AnyLanguage ? QLocale() : numberLocaleLanguage); \
78 if (numberLocale.language() == QLocale::Language::C) \
79  numberLocale.setNumberOptions(QLocale::DefaultNumberOptions);
80 
81 //////////////////////// LineEdit Access ///////////////////////////////
82 #define SET_INT_FROM_LE(var, le) { \
83  bool ok; \
84  SET_NUMBER_LOCALE \
85  const int tmp = numberLocale.toInt((le)->text(), &ok); \
86  if (ok) \
87  var = tmp; \
88 }
89 
90 #define SET_DOUBLE_FROM_LE(var, le) { \
91  bool ok; \
92  SET_NUMBER_LOCALE \
93  const double tmp = numberLocale.toDouble((le)->text(), &ok); \
94  if (ok) \
95  var = tmp; \
96 }
97 
98 //////////////////////// Accessor ///////////////////////////////
99 
100 #define BASIC_ACCESSOR(type, var, method, Method) \
101  type method() const { return var; }; \
102  void set ## Method(const type value) { var = value; }
103 #define CLASS_ACCESSOR(type, var, method, Method) \
104  type method() const { return var; }; \
105  void set ## Method(const type & value) { var = value; }
106 
107 #define BASIC_D_ACCESSOR_DECL(type, method, Method) \
108  type method() const; \
109  void set ## Method(const type value);
110 
111 #define BASIC_D_ACCESSOR_IMPL(classname, type, method, Method, var) \
112  void classname::set ## Method(const type value) \
113  { \
114  d->var = value; \
115  } \
116  type classname::method() const \
117  { \
118  return d->var; \
119  }
120 
121 #define BASIC_D_READER_IMPL(classname, type, method, var) \
122  type classname::method() const \
123  { \
124  return d->var; \
125  }
126 
127 #define BASIC_SHARED_D_READER_IMPL(classname, type, method, var) \
128  type classname::method() const \
129  { \
130  Q_D(const classname); \
131  return d->var; \
132  }
133 
134 #define CLASS_D_ACCESSOR_DECL(type, method, Method) \
135  type method() const; \
136  void set ## Method(const type & value);
137 
138 #define CLASS_D_ACCESSOR_IMPL(classname, type, method, Method, var) \
139  void classname::set ## Method(const type & value) \
140  { \
141  d->var = value; \
142  } \
143  type classname::method() const \
144  { \
145  return d->var; \
146  }
147 
148 #define CLASS_D_READER_IMPL(classname, type, method, var) \
149  type classname::method() const \
150  { \
151  return d->var; \
152  }
153 
154 #define CLASS_SHARED_D_READER_IMPL(classname, type, method, var) \
155  type classname::method() const \
156  { \
157  Q_D(const classname); \
158  return d->var; \
159  }
160 
161 #define POINTER_D_ACCESSOR_DECL(type, method, Method) \
162  type *method() const; \
163  void set ## Method(type *ptr);
164 
165 #define FLAG_D_ACCESSOR_DECL(Method) \
166  bool is ## Method() const; \
167  bool has ## Method() const; \
168  void set ## Method(const bool value = true); \
169  void enable ## Method(const bool value = true);
170 
171 #define FLAG_D_ACCESSOR_IMPL(classname, Method, var) \
172  void classname::set ## Method(const bool value) \
173  { \
174  d->var = value; \
175  } \
176  void classname::enable ## Method(const bool value) \
177  { \
178  d->var = value; \
179  } \
180  bool classname::is ## Method() const \
181  { \
182  return d->var; \
183  } \
184  bool classname::has ## Method() const \
185  { \
186  return d->var; \
187  }
188 
189 //////////////////////// Standard Setter /////////////////////
190 
191 #define STD_SETTER_CMD_IMPL(class_name, cmd_name, value_type, field_name) \
192 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
193  public: \
194  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
195  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
196 };
197 
198 #define STD_SETTER_CMD_IMPL_F(class_name, cmd_name, value_type, field_name, finalize_method) \
199 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
200  public: \
201  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
202  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
203  virtual void finalize() override { m_target->finalize_method(); } \
204 };
205 
206 // setter class with finalize() and signal emitting.
207 #define STD_SETTER_CMD_IMPL_S(class_name, cmd_name, value_type, field_name) \
208 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
209  public: \
210  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
211  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
212  virtual void finalize() override { emit m_target->q->field_name##Changed(m_target->*m_field); } \
213 };
214 
215 #define STD_SETTER_CMD_IMPL_F_S(class_name, cmd_name, value_type, field_name, finalize_method) \
216 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
217  public: \
218  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
219  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
220  virtual void finalize() override { m_target->finalize_method(); emit m_target->q->field_name##Changed(m_target->*m_field); } \
221 };
222 
223 // setter class with finalize() and signal emitting for changing several properties in one single step (embedded in beginMacro/endMacro)
224 #define STD_SETTER_CMD_IMPL_M_F_S(class_name, cmd_name, value_type, field_name, finalize_method) \
225 class class_name ## cmd_name ## Cmd: public StandardMacroSetterCmd<class_name::Private, value_type> { \
226  public: \
227  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
228  : StandardMacroSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
229  virtual void finalize() override { m_target->finalize_method(); emit m_target->q->field_name##Changed(m_target->*m_field); } \
230  virtual void finalizeUndo() override { emit m_target->q->field_name##Changed(m_target->*m_field); } \
231 };
232 
233 #define STD_SETTER_CMD_IMPL_I(class_name, cmd_name, value_type, field_name, init_method) \
234 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
235  public: \
236  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
237  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
238  virtual void initialize() { m_target->init_method(); } \
239 };
240 
241 #define STD_SETTER_CMD_IMPL_IF(class_name, cmd_name, value_type, field_name, init_method, finalize_method) \
242 class class_name ## cmd_name ## Cmd: public StandardSetterCmd<class_name::Private, value_type> { \
243  public: \
244  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
245  : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) {} \
246  virtual void initialize() { m_target->init_method(); } \
247  virtual void finalize() { m_target->finalize_method(); } \
248 };
249 
250 #define STD_SWAP_METHOD_SETTER_CMD_IMPL(class_name, cmd_name, value_type, method_name) \
251 class class_name ## cmd_name ## Cmd: public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \
252  public: \
253  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
254  : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) {} \
255 };
256 
257 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_F(class_name, cmd_name, value_type, method_name, finalize_method) \
258 class class_name ## cmd_name ## Cmd: public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \
259  public: \
260  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
261  : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) {} \
262  virtual void finalize() override { m_target->finalize_method(); } \
263 };
264 
265 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_I(class_name, cmd_name, value_type, method_name, init_method) \
266 class class_name ## cmd_name ## Cmd: public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \
267  public: \
268  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
269  : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) {} \
270  virtual void initialize() { m_target->init_method(); } \
271 };
272 
273 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_IF(class_name, cmd_name, value_type, method_name, init_method, finalize_method) \
274 class class_name ## cmd_name ## Cmd: public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \
275  public: \
276  class_name ## cmd_name ## Cmd(class_name::Private *target, value_type newValue, const KLocalizedString &description) \
277  : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) {} \
278  virtual void initialize() { m_target->init_method(); } \
279  virtual void finalize() { m_target->finalize_method(); } \
280 };
281 
282 
283 //////////////////////// XML - serialization/deserialization /////
284 
285 //QColor
286 #define WRITE_QCOLOR(color) \
287 do { \
288 writer->writeAttribute( "color_r", QString::number(color.red()) ); \
289 writer->writeAttribute( "color_g", QString::number(color.green()) ); \
290 writer->writeAttribute( "color_b", QString::number(color.blue()) ); \
291 } while (0)
292 
293 #define READ_QCOLOR(color) \
294 do { \
295 str = attribs.value("color_r").toString(); \
296 if(str.isEmpty()) \
297  reader->raiseWarning(attributeWarning.subs("color_r").toString()); \
298 else \
299  color.setRed( str.toInt() ); \
300  \
301 str = attribs.value("color_g").toString(); \
302 if(str.isEmpty()) \
303  reader->raiseWarning(attributeWarning.subs("color_g").toString()); \
304 else \
305  color.setGreen( str.toInt() ); \
306  \
307 str = attribs.value("color_b").toString(); \
308 if(str.isEmpty()) \
309  reader->raiseWarning(attributeWarning.subs("color_b").toString()); \
310 else \
311  color.setBlue( str.toInt() ); \
312 } while(0)
313 
314 //QPen
315 #define WRITE_QPEN(pen) \
316 do { \
317 writer->writeAttribute( "style", QString::number(pen.style()) ); \
318 writer->writeAttribute( "color_r", QString::number(pen.color().red()) ); \
319 writer->writeAttribute( "color_g", QString::number(pen.color().green()) ); \
320 writer->writeAttribute( "color_b", QString::number(pen.color().blue()) ); \
321 writer->writeAttribute( "width", QString::number(pen.widthF()) ); \
322 } while (0)
323 
324 #define READ_QPEN(pen) \
325 do { \
326 str = attribs.value("style").toString(); \
327 if(str.isEmpty()) \
328  reader->raiseWarning(attributeWarning.subs("style").toString()); \
329 else \
330  pen.setStyle( (Qt::PenStyle)str.toInt() ); \
331  \
332 QColor color; \
333 str = attribs.value("color_r").toString(); \
334 if(str.isEmpty()) \
335  reader->raiseWarning(attributeWarning.subs("color_r").toString()); \
336 else \
337  color.setRed( str.toInt() ); \
338  \
339 str = attribs.value("color_g").toString(); \
340 if(str.isEmpty()) \
341  reader->raiseWarning(attributeWarning.subs("color_g").toString()); \
342 else \
343  color.setGreen( str.toInt() ); \
344  \
345 str = attribs.value("color_b").toString(); \
346 if(str.isEmpty()) \
347  reader->raiseWarning(attributeWarning.subs("color_b").toString()); \
348 else \
349  color.setBlue( str.toInt() ); \
350  \
351 pen.setColor(color); \
352  \
353 str = attribs.value("width").toString(); \
354 if(str.isEmpty()) \
355  reader->raiseWarning(attributeWarning.subs("width").toString()); \
356 else \
357  pen.setWidthF( str.toDouble() ); \
358 } while(0)
359 
360 //QFont
361 #define WRITE_QFONT(font) \
362 do { \
363 writer->writeAttribute( "fontFamily", font.family() ); \
364 writer->writeAttribute( "fontSize", QString::number(font.pixelSize()) ); \
365 writer->writeAttribute( "fontPointSize", QString::number(font.pointSize()));\
366 writer->writeAttribute( "fontWeight", QString::number(font.weight()) ); \
367 writer->writeAttribute( "fontItalic", QString::number(font.italic()) ); \
368 } while(0)
369 
370 #define READ_QFONT(font) \
371 do { \
372 str = attribs.value("fontFamily").toString(); \
373 if(str.isEmpty()) \
374  reader->raiseWarning(attributeWarning.subs("fontFamily").toString()); \
375 else \
376  font.setFamily( str ); \
377  \
378 str = attribs.value("fontSize").toString(); \
379 if(str.isEmpty()) \
380  reader->raiseWarning(attributeWarning.subs("fontSize").toString()); \
381 else { \
382  int size = str.toInt(); \
383  if (size != -1) \
384  font.setPixelSize(size); \
385 } \
386  \
387 str = attribs.value("fontPointSize").toString(); \
388 if(str.isEmpty()) \
389  reader->raiseWarning(attributeWarning.subs("fontPointSize").toString()); \
390 else { \
391  int size = str.toInt(); \
392  if (size != -1) \
393  font.setPointSize(size); \
394 } \
395  \
396 str = attribs.value("fontWeight").toString(); \
397 if(str.isEmpty()) \
398  reader->raiseWarning(attributeWarning.subs("fontWeight").toString()); \
399 else \
400  font.setWeight( str.toInt() ); \
401  \
402 str = attribs.value("fontItalic").toString(); \
403 if(str.isEmpty()) \
404  reader->raiseWarning(attributeWarning.subs("fontItalic").toString()); \
405 else \
406  font.setItalic( str.toInt() ); \
407 } while(0)
408 
409 //QBrush
410 #define WRITE_QBRUSH(brush) \
411 do { \
412 writer->writeAttribute("brush_style", QString::number(brush.style()) ); \
413 writer->writeAttribute("brush_color_r", QString::number(brush.color().red())); \
414 writer->writeAttribute("brush_color_g", QString::number(brush.color().green()));\
415 writer->writeAttribute("brush_color_b", QString::number(brush.color().blue())); \
416 } while(0)
417 
418 #define READ_QBRUSH(brush) \
419 do { \
420 str = attribs.value("brush_style").toString(); \
421 if(str.isEmpty()) \
422  reader->raiseWarning(attributeWarning.subs("brush_style").toString()); \
423 else \
424  brush.setStyle( (Qt::BrushStyle)str.toInt() ); \
425  \
426 QColor color; \
427 str = attribs.value("brush_color_r").toString(); \
428 if(str.isEmpty()) \
429  reader->raiseWarning(attributeWarning.subs("brush_color_r").toString()); \
430 else \
431  color.setRed( str.toInt() ); \
432  \
433 str = attribs.value("brush_color_g").toString(); \
434 if(str.isEmpty()) \
435  reader->raiseWarning(attributeWarning.subs("brush_color_g").toString()); \
436 else \
437  color.setGreen( str.toInt() ); \
438  \
439 str = attribs.value("brush_color_b").toString(); \
440 if(str.isEmpty()) \
441  reader->raiseWarning(attributeWarning.subs("brush_color_b").toString()); \
442 else \
443  color.setBlue( str.toInt() ); \
444  \
445 brush.setColor(color); \
446 } while(0)
447 
448 
449 
450 //Column
451 #define WRITE_COLUMN(column, columnName) \
452 do { \
453 if (column){ \
454  writer->writeAttribute( #columnName, column->path() ); \
455 } else { \
456  writer->writeAttribute( #columnName, QString() ); \
457 } \
458 } while(0)
459 
460 //column names can be empty in case no columns were used before save
461 //the actual pointers to the x- and y-columns are restored in Project::load()
462 #define READ_COLUMN(columnName) \
463 do { \
464  str = attribs.value(#columnName).toString(); \
465  d->columnName ##Path = str; \
466 } while(0)
467 
468 #define READ_INT_VALUE(name, var, type) \
469 str = attribs.value(name).toString(); \
470 if (str.isEmpty()) \
471  reader->raiseWarning(attributeWarning.subs(name).toString()); \
472 else \
473  d->var = (type)str.toInt();
474 
475 #define READ_DOUBLE_VALUE(name, var) \
476 str = attribs.value(name).toString(); \
477 if (str.isEmpty()) \
478  reader->raiseWarning(attributeWarning.subs(name).toString()); \
479 else \
480  d->var = str.toDouble();
481 
482 #define READ_STRING_VALUE(name, var) \
483 str = attribs.value(name).toString(); \
484 if (str.isEmpty()) \
485  reader->raiseWarning(attributeWarning.subs(name).toString()); \
486 else \
487  d->var = str;
488 
489 //used in Project::load()
490 #define RESTORE_COLUMN_POINTER(obj, col, Col) \
491 do { \
492 if (!obj->col ##Path().isEmpty()) { \
493  for (Column* column : columns) { \
494  if (!column) continue; \
495  if (column->path() == obj->col ##Path()) { \
496  obj->set## Col(column); \
497  break; \
498  } \
499  } \
500 } \
501 } while(0)
502 
503 
504 
505 #define WRITE_PATH(obj, name) \
506 do { \
507 if (obj){ \
508  writer->writeAttribute( #name, obj->path() ); \
509 } else { \
510  writer->writeAttribute( #name, QString() ); \
511 } \
512 } while(0)
513 
514 #define READ_PATH(name) \
515 do { \
516  str = attribs.value(#name).toString(); \
517  d->name ##Path = str; \
518 } while(0)
519 
520 #define RESTORE_POINTER(obj, name, Name, Type, list) \
521 do { \
522 if (!obj->name ##Path().isEmpty()) { \
523  for (AbstractAspect* aspect : list) { \
524  if (aspect->path() == obj->name ##Path()) { \
525  auto a = dynamic_cast<Type*>(aspect); \
526  if (!a) continue; \
527  obj->set## Name(a); \
528  break; \
529  } \
530  } \
531 } \
532 } while(0)
533 
534 #endif // MACROS_H
constexpr std::add_const_t< T > & qAsConst(T &t) noexcept
Definition: macros.h:58