File indexing completed on 2024-05-19 05:05:21

0001 /***************************************************************************
0002  *   SPDX-License-Identifier: GPL-2.0-or-later
0003  *                                                                         *
0004  *   SPDX-FileCopyrightText: 2004-2022 Thomas Fischer <fischer@unix-ag.uni-kl.de>
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  *   This program is distributed in the hope that it will be useful,       *
0012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0014  *   GNU General Public License for more details.                          *
0015  *                                                                         *
0016  *   You should have received a copy of the GNU General Public License     *
0017  *   along with this program; if not, see <https://www.gnu.org/licenses/>. *
0018  ***************************************************************************/
0019 
0020 #ifndef KBIBTEX_DATA_VALUE_H
0021 #define KBIBTEX_DATA_VALUE_H
0022 
0023 #include <QVector>
0024 #include <QVariant>
0025 #include <QSharedPointer>
0026 
0027 #ifdef HAVE_KF
0028 #include "kbibtexdata_export.h"
0029 #endif // HAVE_KF
0030 
0031 /**
0032   * Generic class of an information element in a @see Value object.
0033   * In BibTeX, ValueItems are concatenated by "#".
0034   */
0035 class KBIBTEXDATA_EXPORT ValueItem
0036 {
0037 public:
0038     enum class ReplaceMode {CompleteMatch, AnySubstring};
0039 
0040     ValueItem();
0041     virtual ~ValueItem();
0042 
0043     virtual void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) = 0;
0044 
0045     /**
0046       * Check if this object contains text pattern @p pattern.
0047       * @param pattern Pattern to check for
0048       * @param caseSensitive Case sensitivity setting for check
0049       * @return TRUE if pattern is contained within this value, otherwise FALSE
0050       */
0051     virtual bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const = 0;
0052 
0053     /**
0054       * Compare to instance if they contain the same content.
0055       * Subclasses implement under which conditions two instances are equal.
0056       * Subclasses of different type are never equal.
0057       * @param other other instance to compare with
0058       * @return TRUE if both instances are equal
0059       */
0060     virtual bool operator==(const ValueItem &other) const = 0;
0061     bool operator!=(const ValueItem &other) const;
0062 
0063     /**
0064      * Unique numeric identifier for every ValueItem instance.
0065      * @return Unique numeric identifier
0066      */
0067     quint64 id() const;
0068 
0069 protected:
0070     /// contains text fragments to be removed before performing a "contains pattern" operation
0071     /// includes among other "{" and "}"
0072     static const QRegularExpression ignoredInSorting;
0073 
0074 private:
0075     /// Unique numeric identifier
0076     const quint64 internalId;
0077     /// Keeping track of next available unique numeric identifier
0078     static quint64 internalIdCounter;
0079 };
0080 
0081 class KBIBTEXDATA_EXPORT Keyword: public ValueItem
0082 {
0083 public:
0084     Keyword(const Keyword &other);
0085     explicit Keyword(const QString &text);
0086 
0087     void setText(const QString &text);
0088     QString text() const;
0089 
0090     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) override;
0091     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const override;
0092     bool operator==(const ValueItem &other) const override;
0093 
0094     /**
0095      * Cheap and fast test if another ValueItem is a Keyword object.
0096      * @param other another ValueItem object to test
0097      * @return true if ValueItem is actually a Keyword
0098      */
0099     static bool isKeyword(const ValueItem &other);
0100 
0101 protected:
0102     QString m_text;
0103 };
0104 
0105 class KBIBTEXDATA_EXPORT Person: public ValueItem
0106 {
0107 public:
0108     /**
0109     * Create a representation for a person's name. In bibliographies,
0110     * a person is either an author or an editor. The four parameters
0111     * cover all common parts of a name. Only first and last name are
0112     * mandatory (each person should have those).
0113     @param firstName First name of a person. Example: "Peter"
0114     @param lastName Last name of a person. Example: "Smith"
0115     @param suffix Suffix after a name. Example: "jr."
0116     */
0117     Person(const QString &firstName, const QString &lastName, const QString &suffix = QString());
0118     Person(const Person &other);
0119 
0120     QString firstName() const;
0121     QString lastName() const;
0122     QString suffix() const;
0123 
0124     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) override;
0125     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const override;
0126     bool operator==(const ValueItem &other) const override;
0127 
0128     static QString transcribePersonName(const QString &formatting, const QString &firstName, const QString &lastName, const QString &suffix = QString());
0129     static QString transcribePersonName(const Person *person, const QString &formatting);
0130 
0131     /**
0132      * Cheap and fast test if another ValueItem is a Person object.
0133      * @param other another ValueItem object to test
0134      * @return true if ValueItem is actually a Person
0135      */
0136     static bool isPerson(const ValueItem &other);
0137 
0138 private:
0139     QString m_firstName;
0140     QString m_lastName;
0141     QString m_suffix;
0142 };
0143 
0144 Q_DECLARE_METATYPE(Person*)
0145 
0146 KBIBTEXDATA_EXPORT QDebug operator<<(QDebug dbg, const Person *person);
0147 
0148 
0149 class KBIBTEXDATA_EXPORT MacroKey: public ValueItem
0150 {
0151 public:
0152     MacroKey(const MacroKey &other);
0153     explicit MacroKey(const QString &text);
0154 
0155     void setText(const QString &text);
0156     QString text() const;
0157     bool isValid();
0158 
0159     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) override;
0160     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const override;
0161     bool operator==(const ValueItem &other) const override;
0162 
0163     /**
0164      * Cheap and fast test if another ValueItem is a MacroKey object.
0165      * @param other another ValueItem object to test
0166      * @return true if ValueItem is actually a MacroKey
0167      */
0168     static bool isMacroKey(const ValueItem &other);
0169 
0170 protected:
0171     QString m_text;
0172 };
0173 
0174 KBIBTEXDATA_EXPORT QDebug operator<<(QDebug dbg, const MacroKey &macrokey);
0175 
0176 
0177 class KBIBTEXDATA_EXPORT PlainText: public ValueItem
0178 {
0179 public:
0180     PlainText(const PlainText &other);
0181     explicit PlainText(const QString &text);
0182 
0183     void setText(const QString &text);
0184     QString text() const;
0185 
0186     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) override;
0187     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const override;
0188     bool operator==(const ValueItem &other) const override;
0189 
0190     /**
0191      * Cheap and fast test if another ValueItem is a PlainText object.
0192      * @param other another ValueItem object to test
0193      * @return true if ValueItem is actually a PlainText
0194      */
0195     static bool isPlainText(const ValueItem &other);
0196 
0197 protected:
0198     QString m_text;
0199 };
0200 
0201 KBIBTEXDATA_EXPORT QDebug operator<<(QDebug dbg, const PlainText &plainText);
0202 
0203 
0204 class KBIBTEXDATA_EXPORT VerbatimText: public ValueItem
0205 {
0206 public:
0207     VerbatimText(const VerbatimText &other);
0208     explicit VerbatimText(const QString &text);
0209 
0210     void setText(const QString &text);
0211     QString text() const;
0212     bool hasComment() const;
0213     void removeComment();
0214     void setComment(const QString &comment = QString());
0215     QString comment() const;
0216 
0217 
0218     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode) override;
0219     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const override;
0220     bool operator==(const ValueItem &other) const override;
0221 
0222     /**
0223      * Cheap and fast test if another ValueItem is a VerbatimText object.
0224      * @param other another ValueItem object to test
0225      * @return true if ValueItem is actually a VerbatimText
0226      */
0227     static bool isVerbatimText(const ValueItem &other);
0228 
0229 protected:
0230     bool m_hasComment;
0231     QString m_text, m_comment;
0232 
0233 private:
0234 #ifdef HAVE_KF
0235     struct ColorLabelPair {
0236         QString hexColor;
0237         QString label;
0238     };
0239 
0240     static QList<ColorLabelPair> colorLabelPairs;
0241     static bool colorLabelPairsInitialized;
0242 #endif // HAVE_KF
0243 };
0244 
0245 KBIBTEXDATA_EXPORT QDebug operator<<(QDebug dbg, const VerbatimText &verbatimText);
0246 
0247 
0248 /**
0249  * Container class to hold values of BibTeX entry fields and similar value types in BibTeX file.
0250  * A Value object is built from a list of @see ValueItem objects.
0251  * @author Thomas Fischer <fischer@unix-ag.uni-kl.de>
0252  */
0253 class KBIBTEXDATA_EXPORT Value: public QVector<QSharedPointer<ValueItem> >
0254 {
0255 public:
0256     Value();
0257     Value(const Value &other);
0258     Value(Value &&other);
0259     virtual ~Value();
0260 
0261     void replace(const QString &before, const QString &after, ValueItem::ReplaceMode replaceMode);
0262     void replace(const QString &before, const QSharedPointer<ValueItem> &after);
0263 
0264     /**
0265       * Check if this value contains text pattern @p pattern.
0266       * @param pattern Pattern to check for
0267       * @param caseSensitive Case sensitivity setting for check
0268       * @return TRUE if pattern is contained within this value, otherwise FALSE
0269       */
0270     bool containsPattern(const QString &pattern, Qt::CaseSensitivity caseSensitive = Qt::CaseInsensitive) const;
0271 
0272     bool contains(const ValueItem &item) const;
0273 
0274     Value &operator=(const Value &rhs);
0275     Value &operator=(Value &&rhs);
0276     Value &operator<<(const QSharedPointer<ValueItem> &value);
0277     bool operator==(const Value &rhs) const;
0278     bool operator!=(const Value &rhs) const;
0279 };
0280 
0281 KBIBTEXDATA_EXPORT QDebug operator<<(QDebug dbg, const Value &value);
0282 
0283 
0284 class KBIBTEXDATA_EXPORT PlainTextValue
0285 {
0286 public:
0287     enum FormattingOption {
0288         NoOptions = 0x0,
0289         BeautifyMonth = 0x1
0290     };
0291     Q_DECLARE_FLAGS(FormattingOptions, FormattingOption)
0292     static QString text(const Value &value, const FormattingOptions formattingOptions = FormattingOption::NoOptions);
0293     static QString text(const ValueItem &valueItem);
0294     static QString text(const QSharedPointer<const ValueItem> &valueItem);
0295 
0296 private:
0297     enum class ValueItemType { Other = 0, Person, Keyword};
0298 
0299     static QString text(const ValueItem &valueItem, ValueItemType &vit);
0300 };
0301 
0302 Q_DECLARE_OPERATORS_FOR_FLAGS(PlainTextValue::FormattingOptions)
0303 
0304 Q_DECLARE_METATYPE(Value)
0305 
0306 #endif // KBIBTEX_DATA_VALUE_H