File indexing completed on 2024-11-10 04:16:02
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOPENINGHOURS_OPENINGHOURS_H 0008 #define KOPENINGHOURS_OPENINGHOURS_H 0009 0010 #include "kopeninghours_export.h" 0011 0012 #include <QExplicitlySharedDataPointer> 0013 #include <QMetaType> 0014 0015 class QByteArray; 0016 class QDateTime; 0017 class QJsonObject; 0018 class QString; 0019 class QTimeZone; 0020 0021 /** OSM opening hours parsing and evaluation. */ 0022 namespace KOpeningHours { 0023 0024 class Interval; 0025 class OpeningHoursPrivate; 0026 0027 /** An OSM opening hours specification. 0028 * This is the main entry point into this library, providing both a way to parse opening hours expressions 0029 * and to evaluate them. 0030 * @see https://wiki.openstreetmap.org/wiki/Key:opening_hours 0031 */ 0032 class KOPENINGHOURS_EXPORT OpeningHours 0033 { 0034 Q_GADGET 0035 Q_PROPERTY(Error error READ error) 0036 Q_PROPERTY(QString normalizedExpression READ normalizedExpressionString) 0037 Q_PROPERTY(float latitude READ latitude WRITE setLatitude) 0038 Q_PROPERTY(float longitude READ longitude WRITE setLongitude) 0039 #ifndef KOPENINGHOURS_VALIDATOR_ONLY 0040 Q_PROPERTY(QString region READ region WRITE setRegion) 0041 #endif 0042 Q_PROPERTY(QString timeZone READ timeZoneId WRITE setTimeZoneId) 0043 public: 0044 /** Evaluation modes for opening hours expressions. */ 0045 enum Mode { 0046 IntervalMode = 1, ///< Expressions that describe time ranges 0047 PointInTimeMode = 2, ///< Expressions that describe points in time 0048 }; 0049 Q_DECLARE_FLAGS(Modes, Mode) 0050 Q_FLAG(Modes) 0051 0052 /** Create an empty/invalid instance. */ 0053 explicit OpeningHours(); 0054 0055 /** Parse OSM opening hours expression @p openingHours. 0056 * @param modes Specify whether time interval and/or point in time expressions are expected. 0057 * If @p openingHours doesn't match @p modes, error() return IncompatibleMode. 0058 */ 0059 explicit OpeningHours(const QByteArray &openingHours, Modes modes = IntervalMode); 0060 /** Parse OSM opening hours expression @p openingHours. 0061 * @param modes Specify whether time interval and/or point in time expressions are expected. 0062 * If @p openingHours doesn't match @p modes, error() return IncompatibleMode. 0063 */ 0064 explicit OpeningHours(const char *openingHours, std::size_t size, Modes modes = IntervalMode); 0065 0066 OpeningHours(const OpeningHours&); 0067 OpeningHours(OpeningHours&&); 0068 ~OpeningHours(); 0069 0070 OpeningHours& operator=(const OpeningHours&); 0071 OpeningHours& operator=(OpeningHours&&); 0072 0073 /** Parse OSM opening hours expression @p openingHours. 0074 * @param modes Specify whether time interval and/or point in time expressions are expected. 0075 * If @p openingHours doesn't match @p modes, error() return IncompatibleMode. 0076 * Prefer this over creating new instances if you are processing <b>many</b> expressions 0077 * at once. 0078 */ 0079 void setExpression(const QByteArray &openingHours, Modes modes = IntervalMode); 0080 /** Parse OSM opening hours expression @p openingHours. 0081 * @param modes Specify whether time interval and/or point in time expressions are expected. 0082 * If @p openingHours doesn't match @p modes, error() return IncompatibleMode. 0083 * Prefer this over creating new instances if you are processing <b>many</b> expressions 0084 * at once. 0085 */ 0086 void setExpression(const char *openingHours, std::size_t size, Modes modes = IntervalMode); 0087 0088 /** Returns the OSM opening hours expression reconstructed from this object. 0089 * In many cases it will be the same as the expression given to the constructor 0090 * or to setExpression, but some normalization can happen as well, especially in 0091 * case of non-conform input. 0092 */ 0093 QByteArray normalizedExpression() const; 0094 0095 /** Returns a simplified OSM opening hours expression reconstructed from this object. 0096 * In many cases it will be the same as normalizedExpression(), but further 0097 * simplifications can happen, to make the expression shorter/simpler. 0098 */ 0099 QByteArray simplifiedExpression() const; 0100 0101 /** Geographic coordinate at which this expression should be evaluated. 0102 * This is needed for expressions containing location-based variable time references, 0103 * such as "sunset". If the expression requires a location, error() returns @c MissingLocation 0104 * if no location has been specified. 0105 */ 0106 Q_INVOKABLE void setLocation(float latitude, float longitude); 0107 0108 float latitude() const; 0109 void setLatitude(float latitude); 0110 float longitude() const; 0111 void setLongitude(float longitude); 0112 0113 #ifndef KOPENINGHOURS_VALIDATOR_ONLY 0114 /** ISO 3166-2 region or ISO 316-1 country in which this expression should be evaluated. 0115 * This is needed for expressions containing public holiday references ("PH"). 0116 * If the expression references a public holiday, error() returns @c MissingRegion 0117 * if no region has been specified, or if no holiday data is available for the specified region. 0118 */ 0119 void setRegion(QStringView region); 0120 QString region() const; 0121 #endif 0122 0123 /** Timezone in which this expression should be evaluated. 0124 * If not specified, this assumes local time. 0125 */ 0126 void setTimeZone(const QTimeZone &tz); 0127 QTimeZone timeZone() const; 0128 0129 /** Error codes. */ 0130 enum Error { 0131 Null, ///< no expression is set 0132 NoError, ///< there is no error, the expression is valid and can be used 0133 SyntaxError, ///< syntax error in the opening hours expression 0134 MissingRegion, ///< expression refers to public or school holidays, but that information is not available 0135 MissingLocation, ///< evaluation requires location information and those aren't set 0136 IncompatibleMode, ///< expression mode doesn't match the expected mode 0137 UnsupportedFeature, ///< expression uses a feature that isn't implemented/supported (yet) 0138 EvaluationError, ///< runtime error during evaluating the expression 0139 }; 0140 Q_ENUM(Error) 0141 0142 /** Error status of this expression. */ 0143 Error error() const; 0144 0145 #ifndef KOPENINGHOURS_VALIDATOR_ONLY 0146 /** Returns the interval containing @p dt. */ 0147 Q_INVOKABLE KOpeningHours::Interval interval(const QDateTime &dt) const; 0148 /** Returns the interval immediately following @p interval. */ 0149 Q_INVOKABLE KOpeningHours::Interval nextInterval(const KOpeningHours::Interval &interval) const; 0150 #endif 0151 0152 /** Convert opening hours in schema.org JSON-LD format. 0153 * This supports the following formats: 0154 * - https://schema.org/openingHours 0155 * - https://schema.org/openingHoursSpecification 0156 * - https://schema.org/specialOpeningHoursSpecification 0157 */ 0158 static OpeningHours fromJsonLd(const QJsonObject &obj); 0159 0160 private: 0161 // for QML bindings 0162 Q_DECL_HIDDEN QString normalizedExpressionString() const; 0163 Q_DECL_HIDDEN QString timeZoneId() const; 0164 Q_DECL_HIDDEN void setTimeZoneId(const QString &tzId); 0165 0166 QExplicitlySharedDataPointer<OpeningHoursPrivate> d; 0167 }; 0168 0169 } 0170 0171 Q_DECLARE_METATYPE(KOpeningHours::OpeningHours) 0172 0173 #endif // KOPENINGHOURS_OPENINGHOURS_H