File indexing completed on 2024-05-12 03:47:46
0001 /* 0002 File : macros.h 0003 Project : LabPlot 0004 Description : Various preprocessor macros 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2008 Tilman Benkert <thzs@gmx.net> 0007 SPDX-FileCopyrightText: 2013-2015 Alexander Semke <alexander.semke@web.de> 0008 SPDX-FileCopyrightText: 2016-2021 Stefan Gerlach <stefan.gerlach@uni.kn> 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #ifndef MACROS_H 0013 #define MACROS_H 0014 0015 #include <QApplication> 0016 #include <QMetaEnum> 0017 0018 #include "macrosWarningStyle.h" 0019 0020 // C++ style warning (works on Windows) 0021 #include <iomanip> 0022 #include <iostream> 0023 #define WARN(x) \ 0024 std::cout << std::dec << std::setprecision(std::numeric_limits<double>::digits10 + 1) << std::boolalpha << x \ 0025 << std::resetiosflags(std::ios_base::boolalpha) << std::setprecision(-1) << std::endl; 0026 0027 #ifndef NDEBUG 0028 #include <QDebug> 0029 #define QDEBUG(x) qDebug() << x; 0030 #define DEBUG(x) WARN(x) 0031 #else 0032 #define QDEBUG(x) \ 0033 { } 0034 #define DEBUG(x) \ 0035 { } 0036 #endif 0037 0038 #define DEBUG_TEXTLABEL_BOUNDING_RECT 0 0039 #define DEBUG_TEXTLABEL_GLUEPOINTS 0 0040 #define DEBUG_AXIS_BOUNDING_RECT 0 0041 0042 struct Lock { 0043 inline explicit Lock(bool& variable) 0044 : variable(variable) { 0045 // Make sure it is not already locked 0046 // somewhere else 0047 assert(!variable); 0048 this->variable = true; 0049 } 0050 0051 inline ~Lock() { 0052 variable = false; 0053 } 0054 0055 private: 0056 bool& variable; 0057 }; 0058 0059 /*! 0060 * Used for example for connections with NumberSpinbox because those are using 0061 * a feedback and so breaking the connection dock -> element -> dock is not desired 0062 */ 0063 #define CONDITIONAL_RETURN_NO_LOCK \ 0064 if (m_initializing) \ 0065 return; 0066 0067 /*! 0068 * Lock mechanism used in docks to prevent loops (dock -> element -> dock) 0069 * dock (locking) -> element: No feedback to the dock 0070 */ 0071 #define CONDITIONAL_LOCK_RETURN \ 0072 CONDITIONAL_RETURN_NO_LOCK \ 0073 const Lock lock(m_initializing); 0074 0075 #define WAIT_CURSOR QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)) 0076 #define RESET_CURSOR QApplication::restoreOverrideCursor() 0077 0078 #ifdef HAVE_WINDOWS 0079 #define STDSTRING(qstr) qstr.toUtf8().constData() 0080 #else 0081 #define STDSTRING(qstr) qstr.toStdString() 0082 #endif 0083 #define UTF8_QSTRING(str) QString::fromUtf8(str) 0084 0085 #define CHECK(expr) \ 0086 if (!(expr)) { \ 0087 DEBUG(Q_FUNC_INFO << ", FAILING " #expr); \ 0088 return false; \ 0089 } 0090 // check if var is in [min, max) 0091 #define INRANGE(var, min, max) (var >= min && var < max) 0092 0093 // access enums in Q_OBJECT/Q_GADGET classes 0094 #define ENUM_TO_STRING(class, enum, index) \ 0095 (class ::staticMetaObject.enumerator(class ::staticMetaObject.indexOfEnumerator(#enum)).valueToKey(static_cast<int>(index))) 0096 #define ENUM_COUNT(class, enum) (class ::staticMetaObject.enumerator(class ::staticMetaObject.indexOfEnumerator(#enum)).keyCount()) 0097 0098 //////////////////////// LineEdit Access /////////////////////////////// 0099 #define SET_INT_FROM_LE(var, le) \ 0100 { \ 0101 bool ok; \ 0102 const int tmp = QLocale().toInt((le)->text(), &ok); \ 0103 if (ok) \ 0104 var = tmp; \ 0105 } 0106 0107 #define SET_DOUBLE_FROM_LE(var, le) \ 0108 { \ 0109 bool ok; \ 0110 const double tmp = QLocale().toDouble((le)->text(), &ok); \ 0111 if (ok) \ 0112 var = tmp; \ 0113 } 0114 0115 // including enable recalculate 0116 #define SET_DOUBLE_FROM_LE_REC(var, le) \ 0117 { \ 0118 QString str = (le)->text().trimmed(); \ 0119 if (!str.isEmpty()) { \ 0120 bool ok; \ 0121 const double tmp = QLocale().toDouble(str, &ok); \ 0122 if (ok) { \ 0123 var = tmp; \ 0124 enableRecalculate(); \ 0125 } \ 0126 } \ 0127 } 0128 0129 //////////////////////// Accessor /////////////////////////////// 0130 0131 // type: BASIC (by value), CLASS (by reference) 0132 // D: private var, SHARED: Q_D 0133 // DECL and IMPL 0134 #define BASIC_ACCESSOR(type, var, method, Method) \ 0135 type method() const { \ 0136 return var; \ 0137 }; \ 0138 void set##Method(const type value) { \ 0139 var = value; \ 0140 } 0141 #define CLASS_ACCESSOR(type, var, method, Method) \ 0142 type method() const { \ 0143 return var; \ 0144 }; \ 0145 void set##Method(const type& value) { \ 0146 var = value; \ 0147 } 0148 0149 #define BASIC_D_ACCESSOR_DECL(type, method, Method) \ 0150 type method() const; \ 0151 void set##Method(const type value); 0152 #define CLASS_D_ACCESSOR_DECL(type, method, Method) \ 0153 type method() const; \ 0154 void set##Method(const type& value); 0155 0156 #define BASIC_D_INDEX_ACCESSOR_DECL(type, method, Method) \ 0157 type method(int index) const; \ 0158 void set##Method(int index, type value); 0159 0160 // replaces CLASS_D_READER_IMPL 0161 #define BASIC_D_READER_IMPL(classname, type, method, var) \ 0162 type classname::method() const { \ 0163 Q_D(const classname); \ 0164 return d->var; \ 0165 } 0166 // replaces CLASS_SHARED_D_READER_IMPL 0167 #define BASIC_SHARED_D_READER_IMPL(classname, type, method, var) \ 0168 type classname::method() const { \ 0169 Q_D(const classname); \ 0170 return d->var; \ 0171 } 0172 0173 #define BASIC_D_ACCESSOR_IMPL(classname, type, method, Method, var) \ 0174 void classname::set##Method(const type value) { \ 0175 Q_D(classname); \ 0176 d->var = value; \ 0177 } \ 0178 BASIC_D_READER_IMPL(classname, type, method, var) 0179 0180 #define CLASS_D_ACCESSOR_IMPL(classname, type, method, Method, var) \ 0181 void classname::set##Method(const type& value) { \ 0182 Q_D(classname); \ 0183 d->var = value; \ 0184 } \ 0185 BASIC_D_READER_IMPL(classname, type, method, var) 0186 0187 #define BASIC_SHARED_D_ACCESSOR_IMPL(classname, type, method, Method, var) \ 0188 void classname::set##Method(const type value) { \ 0189 Q_D(classname); \ 0190 d->var = value; \ 0191 } \ 0192 BASIC_SHARED_D_READER_IMPL(classname, type, method, var) 0193 0194 #define CLASS_SHARED_D_ACCESSOR_IMPL(classname, type, method, Method, var) \ 0195 void classname::set##Method(const type& value) { \ 0196 Q_D(classname); \ 0197 d->var = value; \ 0198 } \ 0199 BASIC_SHARED_D_READER_IMPL(classname, type, method, var) 0200 0201 #define POINTER_D_ACCESSOR_DECL(type, method, Method) \ 0202 type* method() const; \ 0203 void set##Method(type* ptr); 0204 0205 #define FLAG_D_ACCESSOR_DECL(Method) \ 0206 bool is##Method() const; \ 0207 bool has##Method() const; \ 0208 void set##Method(const bool value = true); \ 0209 void enable##Method(const bool value = true); 0210 0211 #define FLAG_D_ACCESSOR_IMPL(classname, Method, var) \ 0212 void classname::set##Method(const bool value) { \ 0213 d->var = value; \ 0214 } \ 0215 void classname::enable##Method(const bool value) { \ 0216 d->var = value; \ 0217 } \ 0218 bool classname::is##Method() const { \ 0219 return d->var; \ 0220 } \ 0221 bool classname::has##Method() const { \ 0222 return d->var; \ 0223 } 0224 0225 //////////////////////// Standard Setter ///////////////////// 0226 0227 #define STD_SETTER_CMD_IMPL(class_name, cmd_name, value_type, field_name) \ 0228 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0229 public: \ 0230 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0231 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) { \ 0232 } \ 0233 }; 0234 0235 // setter class with finalize() 0236 #define STD_SETTER_CMD_IMPL_F(class_name, cmd_name, value_type, field_name, finalize_method) \ 0237 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0238 public: \ 0239 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0240 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) { \ 0241 } \ 0242 virtual void finalize() override { \ 0243 m_target->finalize_method(); \ 0244 } \ 0245 }; 0246 0247 // setter class with signal emitting. 0248 #define STD_SETTER_CMD_IMPL_S(class_name, cmd_name, value_type, field_name) \ 0249 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0250 public: \ 0251 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description, QUndoCommand* parent = nullptr) \ 0252 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description, parent) { \ 0253 } \ 0254 virtual void finalize() override { \ 0255 Q_EMIT m_target->q->field_name##Changed(m_target->*m_field); \ 0256 } \ 0257 }; 0258 0259 // setter class with finalize() and signal emitting. 0260 #define STD_SETTER_CMD_IMPL_F_S(class_name, cmd_name, value_type, field_name, finalize_method) \ 0261 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0262 public: \ 0263 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description, QUndoCommand* parent = nullptr) \ 0264 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description, parent) { \ 0265 } \ 0266 virtual void finalize() override { \ 0267 m_target->finalize_method(); \ 0268 Q_EMIT m_target->q->field_name##Changed(m_target->*m_field); \ 0269 } \ 0270 }; 0271 0272 // setter class with finalize() and signal emitting, one field_name signal and one custom signal. 0273 #define STD_SETTER_CMD_IMPL_F_S_SC(class_name, cmd_name, value_type, field_name, finalize_method, custom_signal) \ 0274 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0275 public: \ 0276 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description, QUndoCommand* parent = nullptr) \ 0277 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description, parent) { \ 0278 } \ 0279 virtual void finalize() override { \ 0280 m_target->finalize_method(); \ 0281 Q_EMIT m_target->q->field_name##Changed(m_target->*m_field); \ 0282 Q_EMIT m_target->q->custom_signal(); \ 0283 } \ 0284 }; 0285 0286 // setter class with finalize() and signal emitting for changing several properties in one single step (embedded in beginMacro/endMacro) 0287 #define STD_SETTER_CMD_IMPL_M_F_S(class_name, cmd_name, value_type, field_name, finalize_method) \ 0288 class class_name##cmd_name##Cmd : public StandardMacroSetterCmd<class_name::Private, value_type> { \ 0289 public: \ 0290 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0291 : StandardMacroSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) { \ 0292 } \ 0293 virtual void finalize() override { \ 0294 m_target->finalize_method(); \ 0295 Q_EMIT m_target->q->field_name##Changed(m_target->*m_field); \ 0296 } \ 0297 virtual void finalizeUndo() override { \ 0298 Q_EMIT m_target->q->field_name##Changed(m_target->*m_field); \ 0299 } \ 0300 }; 0301 0302 #define STD_SETTER_CMD_IMPL_I(class_name, cmd_name, value_type, field_name, init_method) \ 0303 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0304 public: \ 0305 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0306 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) { \ 0307 } \ 0308 virtual void initialize() { \ 0309 m_target->init_method(); \ 0310 } \ 0311 }; 0312 0313 #define STD_SETTER_CMD_IMPL_IF(class_name, cmd_name, value_type, field_name, init_method, finalize_method) \ 0314 class class_name##cmd_name##Cmd : public StandardSetterCmd<class_name::Private, value_type> { \ 0315 public: \ 0316 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0317 : StandardSetterCmd<class_name::Private, value_type>(target, &class_name::Private::field_name, newValue, description) { \ 0318 } \ 0319 virtual void initialize() { \ 0320 m_target->init_method(); \ 0321 } \ 0322 virtual void finalize() { \ 0323 m_target->finalize_method(); \ 0324 } \ 0325 }; 0326 0327 #define STD_SWAP_METHOD_SETTER_CMD_IMPL(class_name, cmd_name, value_type, method_name) \ 0328 class class_name##cmd_name##Cmd : public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \ 0329 public: \ 0330 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0331 : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) { \ 0332 } \ 0333 }; 0334 0335 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_F(class_name, cmd_name, value_type, method_name, finalize_method) \ 0336 class class_name##cmd_name##Cmd : public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \ 0337 public: \ 0338 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0339 : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) { \ 0340 } \ 0341 virtual void finalize() override { \ 0342 m_target->finalize_method(); \ 0343 } \ 0344 }; 0345 0346 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_I(class_name, cmd_name, value_type, method_name, init_method) \ 0347 class class_name##cmd_name##Cmd : public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \ 0348 public: \ 0349 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0350 : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) { \ 0351 } \ 0352 virtual void initialize() { \ 0353 m_target->init_method(); \ 0354 } \ 0355 }; 0356 0357 #define STD_SWAP_METHOD_SETTER_CMD_IMPL_IF(class_name, cmd_name, value_type, method_name, init_method, finalize_method) \ 0358 class class_name##cmd_name##Cmd : public StandardSwapMethodSetterCmd<class_name::Private, value_type> { \ 0359 public: \ 0360 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description) \ 0361 : StandardSwapMethodSetterCmd<class_name::Private, value_type>(target, &class_name::Private::method_name, newValue, description) { \ 0362 } \ 0363 virtual void initialize() { \ 0364 m_target->init_method(); \ 0365 } \ 0366 virtual void finalize() { \ 0367 m_target->finalize_method(); \ 0368 } \ 0369 }; 0370 0371 // setter class for QGraphicsitem settings because 0372 // there field_name() and setter_method() is used to get and set values 0373 // with finalize() function and signal emitting. 0374 #define GRAPHICSITEM_SETTER_CMD_IMPL_F_S(class_name, cmd_name, value_type, field_name, setter_method, finalize_method) \ 0375 class class_name##cmd_name##Cmd : public QUndoCommand { \ 0376 public: \ 0377 class_name##cmd_name##Cmd(class_name::Private* target, value_type newValue, const KLocalizedString& description, QUndoCommand* parent = nullptr) \ 0378 : QUndoCommand(parent) \ 0379 , m_target(target) \ 0380 , m_otherValue(newValue) { \ 0381 setText(description.subs(m_target->name()).toString()); \ 0382 } \ 0383 void redo() override { \ 0384 value_type tmp = m_target->field_name(); \ 0385 m_target->setter_method(m_otherValue); \ 0386 m_otherValue = tmp; \ 0387 QUndoCommand::redo(); /* redo all childs */ \ 0388 finalize(); \ 0389 } \ 0390 \ 0391 void undo() override { \ 0392 redo(); \ 0393 } \ 0394 void finalize() { \ 0395 m_target->finalize_method(); \ 0396 Q_EMIT m_target->q->field_name##Changed(m_target->field_name()); \ 0397 } \ 0398 \ 0399 private: \ 0400 class_name::Private* m_target; \ 0401 value_type m_otherValue; \ 0402 }; 0403 0404 //////////////////////// XML - serialization/deserialization ///// 0405 // TODO: do we really need all these tabs? 0406 // TODO: why "do {...} while(0)"? 0407 0408 // QColor 0409 #define WRITE_QCOLOR(color) \ 0410 { \ 0411 writer->writeAttribute(QStringLiteral("color_r"), QString::number(color.red())); \ 0412 writer->writeAttribute(QStringLiteral("color_g"), QString::number(color.green())); \ 0413 writer->writeAttribute(QStringLiteral("color_b"), QString::number(color.blue())); \ 0414 } 0415 0416 #define WRITE_QCOLOR2(color, label) \ 0417 { \ 0418 writer->writeAttribute(QStringLiteral(label "_r"), QString::number(color.red())); \ 0419 writer->writeAttribute(QStringLiteral(label "_g"), QString::number(color.green())); \ 0420 writer->writeAttribute(QStringLiteral(label "_b"), QString::number(color.blue())); \ 0421 } 0422 0423 #define READ_QCOLOR(color) \ 0424 { \ 0425 str = attribs.value(QStringLiteral("color_r")).toString(); \ 0426 if (str.isEmpty()) \ 0427 reader->raiseMissingAttributeWarning(QStringLiteral("color_r")); \ 0428 else \ 0429 color.setRed(str.toInt()); \ 0430 \ 0431 str = attribs.value(QStringLiteral("color_g")).toString(); \ 0432 if (str.isEmpty()) \ 0433 reader->raiseMissingAttributeWarning(QStringLiteral("color_g")); \ 0434 else \ 0435 color.setGreen(str.toInt()); \ 0436 \ 0437 str = attribs.value(QStringLiteral("color_b")).toString(); \ 0438 if (str.isEmpty()) \ 0439 reader->raiseMissingAttributeWarning(QStringLiteral("color_b")); \ 0440 else \ 0441 color.setBlue(str.toInt()); \ 0442 } 0443 0444 #define READ_QCOLOR2(color, label) \ 0445 { \ 0446 str = attribs.value(QStringLiteral(label "_r")).toString(); \ 0447 if (str.isEmpty()) \ 0448 reader->raiseMissingAttributeWarning(QStringLiteral(label "_r")); \ 0449 else \ 0450 color.setRed(str.toInt()); \ 0451 \ 0452 str = attribs.value(QStringLiteral(label "_g")).toString(); \ 0453 if (str.isEmpty()) \ 0454 reader->raiseMissingAttributeWarning(QStringLiteral(label "_g")); \ 0455 else \ 0456 color.setGreen(str.toInt()); \ 0457 \ 0458 str = attribs.value(QStringLiteral(label "_b")).toString(); \ 0459 if (str.isEmpty()) \ 0460 reader->raiseMissingAttributeWarning(QStringLiteral(label "_b")); \ 0461 else \ 0462 color.setBlue(str.toInt()); \ 0463 } 0464 // QPen 0465 #define WRITE_QPEN(pen) \ 0466 { \ 0467 writer->writeAttribute(QStringLiteral("style"), QString::number(pen.style())); \ 0468 writer->writeAttribute(QStringLiteral("color_r"), QString::number(pen.color().red())); \ 0469 writer->writeAttribute(QStringLiteral("color_g"), QString::number(pen.color().green())); \ 0470 writer->writeAttribute(QStringLiteral("color_b"), QString::number(pen.color().blue())); \ 0471 writer->writeAttribute(QStringLiteral("width"), QString::number(pen.widthF())); \ 0472 } 0473 0474 #define READ_QPEN(pen) \ 0475 { \ 0476 str = attribs.value(QStringLiteral("style")).toString(); \ 0477 if (str.isEmpty()) \ 0478 reader->raiseMissingAttributeWarning(QStringLiteral("style")); \ 0479 else \ 0480 pen.setStyle(static_cast<Qt::PenStyle>(str.toInt())); \ 0481 \ 0482 QColor color; \ 0483 str = attribs.value(QStringLiteral("color_r")).toString(); \ 0484 if (str.isEmpty()) \ 0485 reader->raiseMissingAttributeWarning(QStringLiteral("color_r")); \ 0486 else \ 0487 color.setRed(str.toInt()); \ 0488 \ 0489 str = attribs.value(QStringLiteral("color_g")).toString(); \ 0490 if (str.isEmpty()) \ 0491 reader->raiseMissingAttributeWarning(QStringLiteral("color_g")); \ 0492 else \ 0493 color.setGreen(str.toInt()); \ 0494 \ 0495 str = attribs.value(QStringLiteral("color_b")).toString(); \ 0496 if (str.isEmpty()) \ 0497 reader->raiseMissingAttributeWarning(QStringLiteral("color_b")); \ 0498 else \ 0499 color.setBlue(str.toInt()); \ 0500 \ 0501 pen.setColor(color); \ 0502 \ 0503 str = attribs.value(QStringLiteral("width")).toString(); \ 0504 if (str.isEmpty()) \ 0505 reader->raiseMissingAttributeWarning(QStringLiteral("width")); \ 0506 else \ 0507 pen.setWidthF(str.toDouble()); \ 0508 } 0509 0510 // QFont 0511 #define WRITE_QFONT(font) \ 0512 { \ 0513 writer->writeAttribute(QStringLiteral("fontFamily"), font.family()); \ 0514 writer->writeAttribute(QStringLiteral("fontSize"), QString::number(font.pixelSize())); \ 0515 writer->writeAttribute(QStringLiteral("fontPointSize"), QString::number(font.pointSize())); \ 0516 writer->writeAttribute(QStringLiteral("fontWeight"), QString::number(font.weight())); \ 0517 writer->writeAttribute(QStringLiteral("fontItalic"), QString::number(font.italic())); \ 0518 } 0519 0520 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // uses font.setLegacyWeight(int) 0521 #define READ_QFONT(font) \ 0522 { \ 0523 str = attribs.value(QStringLiteral("fontFamily")).toString(); \ 0524 if (str.isEmpty()) \ 0525 reader->raiseMissingAttributeWarning(QStringLiteral("fontFamily")); \ 0526 else \ 0527 font.setFamily(str); \ 0528 \ 0529 str = attribs.value(QStringLiteral("fontSize")).toString(); \ 0530 if (str.isEmpty()) \ 0531 reader->raiseMissingAttributeWarning(QStringLiteral("fontSize")); \ 0532 else { \ 0533 int size = str.toInt(); \ 0534 if (size != -1) \ 0535 font.setPixelSize(size); \ 0536 } \ 0537 \ 0538 str = attribs.value(QStringLiteral("fontPointSize")).toString(); \ 0539 if (str.isEmpty()) \ 0540 reader->raiseMissingAttributeWarning(QStringLiteral("fontPointSize")); \ 0541 else { \ 0542 int size = str.toInt(); \ 0543 if (size != -1) \ 0544 font.setPointSize(size); \ 0545 } \ 0546 \ 0547 str = attribs.value(QStringLiteral("fontWeight")).toString(); \ 0548 if (str.isEmpty()) \ 0549 reader->raiseMissingAttributeWarning(QStringLiteral("fontWeight")); \ 0550 else \ 0551 font.setLegacyWeight(str.toInt()); \ 0552 \ 0553 str = attribs.value(QStringLiteral("fontItalic")).toString(); \ 0554 if (str.isEmpty()) \ 0555 reader->raiseMissingAttributeWarning(QStringLiteral("fontItalic")); \ 0556 else \ 0557 font.setItalic(str.toInt()); \ 0558 } 0559 #else 0560 #define READ_QFONT(font) \ 0561 { \ 0562 str = attribs.value(QStringLiteral("fontFamily")).toString(); \ 0563 if (str.isEmpty()) \ 0564 reader->raiseMissingAttributeWarning(QStringLiteral("fontFamily")); \ 0565 else \ 0566 font.setFamily(str); \ 0567 \ 0568 str = attribs.value(QStringLiteral("fontSize")).toString(); \ 0569 if (str.isEmpty()) \ 0570 reader->raiseMissingAttributeWarning(QStringLiteral("fontSize")); \ 0571 else { \ 0572 int size = str.toInt(); \ 0573 if (size != -1) \ 0574 font.setPixelSize(size); \ 0575 } \ 0576 \ 0577 str = attribs.value(QStringLiteral("fontPointSize")).toString(); \ 0578 if (str.isEmpty()) \ 0579 reader->raiseMissingAttributeWarning(QStringLiteral("fontPointSize")); \ 0580 else { \ 0581 int size = str.toInt(); \ 0582 if (size != -1) \ 0583 font.setPointSize(size); \ 0584 } \ 0585 \ 0586 str = attribs.value(QStringLiteral("fontWeight")).toString(); \ 0587 if (str.isEmpty()) \ 0588 reader->raiseMissingAttributeWarning(QStringLiteral("fontWeight")); \ 0589 else \ 0590 font.setWeight(str.toInt()); \ 0591 \ 0592 str = attribs.value(QStringLiteral("fontItalic")).toString(); \ 0593 if (str.isEmpty()) \ 0594 reader->raiseMissingAttributeWarning(QStringLiteral("fontItalic")); \ 0595 else \ 0596 font.setItalic(str.toInt()); \ 0597 } 0598 #endif 0599 0600 // QBrush 0601 #define WRITE_QBRUSH(brush) \ 0602 { \ 0603 writer->writeAttribute(QStringLiteral("brush_style"), QString::number(brush.style())); \ 0604 writer->writeAttribute(QStringLiteral("brush_color_r"), QString::number(brush.color().red())); \ 0605 writer->writeAttribute(QStringLiteral("brush_color_g"), QString::number(brush.color().green())); \ 0606 writer->writeAttribute(QStringLiteral("brush_color_b"), QString::number(brush.color().blue())); \ 0607 } 0608 0609 #define READ_QBRUSH(brush) \ 0610 { \ 0611 str = attribs.value(QStringLiteral("brush_style")).toString(); \ 0612 if (str.isEmpty()) \ 0613 reader->raiseMissingAttributeWarning(QStringLiteral("brush_style")); \ 0614 else \ 0615 brush.setStyle(static_cast<Qt::BrushStyle>(str.toInt())); \ 0616 \ 0617 QColor color; \ 0618 str = attribs.value(QStringLiteral("brush_color_r")).toString(); \ 0619 if (str.isEmpty()) \ 0620 reader->raiseMissingAttributeWarning(QStringLiteral("brush_color_r")); \ 0621 else \ 0622 color.setRed(str.toInt()); \ 0623 \ 0624 str = attribs.value(QStringLiteral("brush_color_g")).toString(); \ 0625 if (str.isEmpty()) \ 0626 reader->raiseMissingAttributeWarning(QStringLiteral("brush_color_g")); \ 0627 else \ 0628 color.setGreen(str.toInt()); \ 0629 \ 0630 str = attribs.value(QStringLiteral("brush_color_b")).toString(); \ 0631 if (str.isEmpty()) \ 0632 reader->raiseMissingAttributeWarning(QStringLiteral("brush_color_b")); \ 0633 else \ 0634 color.setBlue(str.toInt()); \ 0635 \ 0636 brush.setColor(color); \ 0637 } 0638 0639 // Column 0640 #define WRITE_COLUMN(column, columnName) \ 0641 if (column) { \ 0642 writer->writeAttribute(QStringLiteral(#columnName), column->path()); \ 0643 } else { \ 0644 writer->writeAttribute(QStringLiteral(#columnName), QString()); \ 0645 } 0646 0647 // column names can be empty in case no columns were used before save 0648 // the actual pointers to the x- and y-columns are restored in Project::load() 0649 #define READ_COLUMN(columnName) \ 0650 { \ 0651 str = attribs.value(QStringLiteral(#columnName)).toString(); \ 0652 d->columnName##Path = str; \ 0653 } 0654 0655 #define READ_INT_VALUE_DIRECT(name, var, type) \ 0656 { \ 0657 str = attribs.value(QStringLiteral(name)).toString(); \ 0658 if (str.isEmpty()) \ 0659 reader->raiseMissingAttributeWarning(QStringLiteral(name)); \ 0660 else \ 0661 var = static_cast<type>(str.toInt()); \ 0662 } 0663 0664 #define READ_INT_VALUE(name, var, type) READ_INT_VALUE_DIRECT(name, d->var, type) 0665 0666 #define READ_DOUBLE_VALUE(name, var) \ 0667 { \ 0668 str = attribs.value(QStringLiteral(name)).toString(); \ 0669 if (str.isEmpty()) \ 0670 reader->raiseMissingAttributeWarning(QStringLiteral(name)); \ 0671 else \ 0672 d->var = str.toDouble(); \ 0673 } 0674 0675 #define QGRAPHICSITEM_READ_DOUBLE_VALUE(name, Var) \ 0676 { \ 0677 str = attribs.value(QStringLiteral(name)).toString(); \ 0678 if (str.isEmpty()) \ 0679 reader->raiseMissingAttributeWarning(QStringLiteral(name)); \ 0680 else \ 0681 d->set##Var(str.toDouble()); \ 0682 } 0683 0684 #define READ_STRING_VALUE(name, var) \ 0685 { d->var = attribs.value(QLatin1String(name)).toString(); } 0686 0687 // used in Project::load() 0688 #define RESTORE_COLUMN_POINTER(obj, col, Col) \ 0689 if (!obj->col##Path().isEmpty()) { \ 0690 for (Column * column : columns) { \ 0691 if (!column) \ 0692 continue; \ 0693 if (column->path() == obj->col##Path()) { \ 0694 obj->set##Col(column); \ 0695 break; \ 0696 } \ 0697 } \ 0698 } 0699 0700 #define WRITE_PATH(obj, name) \ 0701 if (obj) { \ 0702 writer->writeAttribute(QLatin1String(#name), obj->path()); \ 0703 } else { \ 0704 writer->writeAttribute(QLatin1String(#name), QString()); \ 0705 } 0706 0707 #define READ_PATH(name) \ 0708 { \ 0709 str = attribs.value(QLatin1String(#name)).toString(); \ 0710 d->name##Path = str; \ 0711 } 0712 0713 #define RESTORE_POINTER(obj, name, Name, Type, list) \ 0714 if (!obj->name##Path().isEmpty()) { \ 0715 for (AbstractAspect * aspect : list) { \ 0716 if (aspect->path() == obj->name##Path()) { \ 0717 auto a = dynamic_cast<Type*>(aspect); \ 0718 if (!a) \ 0719 continue; \ 0720 obj->set##Name(a); \ 0721 break; \ 0722 } \ 0723 } \ 0724 } 0725 0726 #endif // MACROS_H