File indexing completed on 2024-05-19 04:55:55

0001 /**
0002  * \file formatconfig.h
0003  * Format configuration.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 17 Sep 2003
0008  *
0009  * Copyright (C) 2003-2024  Urs Fleisch
0010  *
0011  * This file is part of Kid3.
0012  *
0013  * Kid3 is free software; you can redistribute it and/or modify
0014  * it under the terms of the GNU General Public License as published by
0015  * the Free Software Foundation; either version 2 of the License, or
0016  * (at your option) any later version.
0017  *
0018  * Kid3 is distributed in the hope that it will be useful,
0019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0021  * GNU General Public License for more details.
0022  *
0023  * You should have received a copy of the GNU General Public License
0024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0025  */
0026 
0027 #pragma once
0028 
0029 #include <QScopedPointer>
0030 #include <QVariantMap>
0031 #include <QStringList>
0032 #include "generalconfig.h"
0033 #include "kid3api.h"
0034 
0035 class QString;
0036 class QLocale;
0037 class FrameCollection;
0038 
0039 /**
0040  * Format configuration.
0041  */
0042 class KID3_CORE_EXPORT FormatConfig : public GeneralConfig {
0043   Q_OBJECT
0044   /** Mapping for string replacement */
0045   Q_PROPERTY(QStringList strRepMap READ strRepStringList
0046              WRITE setStrRepStringList NOTIFY strRepMapChanged)
0047   /** Case conversion option */
0048   Q_PROPERTY(int caseConversion READ caseConversion WRITE setCaseConversionInt
0049              NOTIFY caseConversionChanged)
0050   /** name of locale to use for string conversions */
0051   Q_PROPERTY(QString localeName READ localeName WRITE setLocaleName
0052              NOTIFY localeNameChanged)
0053   /** maximum length */
0054   Q_PROPERTY(int maximumLength READ maximumLength WRITE setMaximumLength
0055              NOTIFY maximumLengthChanged)
0056   /** true to enable length restriction */
0057   Q_PROPERTY(bool enableMaximumLength READ enableMaximumLength
0058              WRITE setEnableMaximumLength NOTIFY enableMaximumLengthChanged)
0059   /** true to enable formating in line edits */
0060   Q_PROPERTY(bool formatWhileEditing READ formatWhileEditing
0061              WRITE setFormatWhileEditing NOTIFY formatWhileEditingChanged)
0062   /** true if string replacement enabled */
0063   Q_PROPERTY(bool strRepEnabled READ strRepEnabled WRITE setStrRepEnabled
0064              NOTIFY strRepEnabledChanged)
0065   /** true to enable data validation */
0066   Q_PROPERTY(bool enableValidation READ enableValidation
0067              WRITE setEnableValidation NOTIFY enableValidationChanged)
0068   /** true to use format for playlist and folder names */
0069   Q_PROPERTY(bool useForOtherFileNames READ useForOtherFileNames
0070              WRITE setUseForOtherFileNames NOTIFY useForOtherFileNamesChanged)
0071   Q_ENUMS(CaseConversion)
0072 public:
0073   /** Case conversion options. */
0074   enum CaseConversion {
0075       NoChanges,
0076       AllLowercase,
0077       AllUppercase,
0078       FirstLetterUppercase,
0079       AllFirstLettersUppercase,
0080       NumCaseConversions
0081   };
0082 
0083   /**
0084    * Constructor.
0085    *
0086    * @param grp configuration group
0087    */
0088   explicit FormatConfig(const QString& grp);
0089 
0090   /**
0091    * Destructor.
0092    */
0093   ~FormatConfig() override;
0094 
0095   /**
0096    * Set specific properties for a filename format.
0097    * This will set default string conversions and not touch the file
0098    * extension when formatting.
0099    */
0100   void setAsFilenameFormatter();
0101 
0102   /**
0103    * Format a string using this configuration.
0104    *
0105    * @param str string to format
0106    */
0107   void formatString(QString& str) const;
0108 
0109   /**
0110    * Join base name and extension respecting maximum length.
0111    *
0112    * Truncation to maximumLength() is only done if enableMaximumLength() and
0113    * setAsFilenameFormatter() are set.
0114    *
0115    * @param baseName file name without extension
0116    * @param extension file name extension starting with dot
0117    * @return file name with extension, eventually truncated to maximum length.
0118    */
0119   QString joinFileName(const QString& baseName, const QString& extension) const;
0120 
0121   /**
0122    * Format frames using this configuration.
0123    *
0124    * @param frames frames
0125    */
0126   void formatFrames(FrameCollection& frames) const;
0127 
0128   /**
0129    * Format frames if format while editing is switched on.
0130    *
0131    * @param frames frames
0132    */
0133   void formatFramesIfEnabled(FrameCollection& frames) const;
0134 
0135   /**
0136    * Persist configuration.
0137    *
0138    * @param config KDE configuration
0139    */
0140   void writeToConfig(ISettings* config) const override;
0141 
0142   /**
0143    * Read persisted configuration.
0144    *
0145    * @param config KDE configuration
0146    */
0147   void readFromConfig(ISettings* config) override;
0148 
0149   /** Get mapping for string replacement. */
0150   QList<QPair<QString, QString>> strRepMap() const { return m_strRepMap; }
0151 
0152   /** Set mapping for string replacement. */
0153   void setStrRepMap(const QList<QPair<QString, QString>>& strRepMap);
0154 
0155   /** Get mapping for string replacement as a list with alternating key, values. */
0156   QStringList strRepStringList() const;
0157 
0158   /** Set mapping for string replacement from a list with alternating key, values. */
0159   void setStrRepStringList(const QStringList& lst);
0160 
0161   /** Get case conversion option. */
0162   CaseConversion caseConversion() const { return m_caseConversion; }
0163 
0164   /** Set case conversion option. */
0165   void setCaseConversion(CaseConversion caseConversion);
0166 
0167   /**
0168    * Get name of locale to use for string conversions.
0169    * @return locale name
0170    */
0171   QString localeName() const { return m_localeName; }
0172 
0173   /**
0174    * Set name of locale to use for string conversions.
0175    * @param localeName locale name
0176    */
0177   void setLocaleName(const QString& localeName);
0178 
0179   /** Check if formatting in line edits is enabled. */
0180   bool formatWhileEditing() const { return m_formatWhileEditing; }
0181 
0182   /** Set if formatting in line edits is enabled. */
0183   void setFormatWhileEditing(bool formatWhileEditing);
0184 
0185   /** Check if string replacement is enabled. */
0186   bool strRepEnabled() const { return m_strRepEnabled; }
0187 
0188   /** Set if string replacement is enabled. */
0189   void setStrRepEnabled(bool strRepEnabled);
0190 
0191   /** Check if data validation is enabled. */
0192   bool enableValidation() const { return m_enableValidation; }
0193 
0194   /** Set if data validation is enabled. */
0195   void setEnableValidation(bool enableValidation);
0196 
0197   /** Check if format shall be used for playlist and folder names. */
0198   bool useForOtherFileNames() const { return m_useForOtherFileNames; }
0199 
0200   /** Set if format shall be used for playlist and folder names. */
0201   void setUseForOtherFileNames(bool useForOtherFileNames);
0202 
0203   /** Check if length restriction is enabled. */
0204   bool enableMaximumLength() const { return m_enableMaximumLength; }
0205 
0206   /** Set if length restriction is enabled. */
0207   void setEnableMaximumLength(bool enableMaximumLength);
0208 
0209   /** Get maximum length. */
0210   int maximumLength() const { return m_maximumLength; }
0211 
0212   /** Set maximum length. */
0213   void setMaximumLength(int maximumLength);
0214 
0215   /**
0216    * Set if the formatter is omitting extensions to handle filenames.
0217    *
0218    * This is a setting for the formatter, not a configuration property.
0219    * It can be changed temporarily when formatting folder names in order to
0220    * switch off the special handling of extensions, which does not format
0221    * everything after a dot in the filename.
0222    *
0223    * @param filenameFormatter true to enable omitting extensions
0224    * @return previous filenameFormatter setting, provided to restore it after
0225    *         calling formatString().
0226    */
0227   bool switchFilenameFormatter(bool filenameFormatter) {
0228     bool oldValue = m_filenameFormatter;
0229     m_filenameFormatter = filenameFormatter;
0230     return oldValue;
0231   }
0232 
0233   /**
0234    * String list of case conversion names.
0235    */
0236   Q_INVOKABLE static QStringList getCaseConversionNames();
0237 
0238   /**
0239    * String list of locale names.
0240    */
0241   Q_INVOKABLE static QStringList getLocaleNames();
0242 
0243 signals:
0244   /** Emitted when @a strRepMap changed. */
0245   void strRepMapChanged(const QList<QPair<QString, QString>>& strRepMap);
0246 
0247   /** Emitted when @a caseConversion changed. */
0248   void caseConversionChanged(FormatConfig::CaseConversion caseConversion);
0249 
0250   /** Emitted when @a localeName changed. */
0251   void localeNameChanged(const QString& localeName);
0252 
0253   /** Emitted when @a formatWhileEditing changed. */
0254   void formatWhileEditingChanged(bool formatWhileEditing);
0255 
0256   /** Emitted when @a strRepEnabled changed. */
0257   void strRepEnabledChanged(bool strRepEnabled);
0258 
0259   /** Emitted when @a enableValidation changed. */
0260   void enableValidationChanged(bool enableValidation);
0261 
0262   /** Emitted when @a useForOtherFileNames changed. */
0263   void useForOtherFileNamesChanged(bool useForOtherFileNames);
0264 
0265   /** Emitted when @a enableMaximumLength changed. */
0266   void enableMaximumLengthChanged(bool enableMaximumLength);
0267 
0268   /** Emitted when @a maximumLength changed. */
0269   void maximumLengthChanged(int maximumLength);
0270 
0271 private:
0272   /** Returns a lowercase copy of @a str. */
0273   QString toLower(const QString& str) const;
0274 
0275   /** Returns an uppercase copy of @a str. */
0276   QString toUpper(const QString& str) const;
0277 
0278   void setCaseConversionInt(int caseConversion) {
0279     setCaseConversion(static_cast<CaseConversion>(caseConversion));
0280   }
0281 
0282   QList<QPair<QString, QString>> m_strRepMap;
0283   CaseConversion m_caseConversion;
0284   QString m_localeName;
0285   /** Locale to use for string conversions */
0286   QScopedPointer<const QLocale> m_locale;
0287   int m_maximumLength;
0288   bool m_useForOtherFileNames;
0289   bool m_enableMaximumLength;
0290   /** true if it is a file formatter */
0291   bool m_filenameFormatter;
0292   bool m_formatWhileEditing;
0293   bool m_strRepEnabled;
0294   bool m_enableValidation;
0295 };
0296 
0297 
0298 /**
0299  * FormatConfig subclass for stored filename format configuration instance.
0300  */
0301 class KID3_CORE_EXPORT FilenameFormatConfig
0302     : public StoredConfig<FilenameFormatConfig, FormatConfig> {
0303   Q_OBJECT
0304 public:
0305   /**
0306    * Constructor.
0307    */
0308   FilenameFormatConfig();
0309 
0310   /**
0311    * Destructor.
0312    */
0313   ~FilenameFormatConfig() override = default;
0314 
0315 private:
0316   friend FilenameFormatConfig&
0317   StoredConfig<FilenameFormatConfig, FormatConfig>::instance();
0318 
0319   /** Index in configuration storage */
0320   static int s_index;
0321 };
0322 
0323 
0324 /**
0325  * FormatConfig subclass for stored tag format configuration instance.
0326  */
0327 class KID3_CORE_EXPORT TagFormatConfig
0328     : public StoredConfig<TagFormatConfig, FormatConfig> {
0329   Q_OBJECT
0330 public:
0331   /**
0332    * Constructor.
0333    */
0334   TagFormatConfig();
0335 
0336   /**
0337    * Destructor.
0338    */
0339   ~TagFormatConfig() override = default;
0340 
0341 private:
0342   friend TagFormatConfig&
0343   StoredConfig<TagFormatConfig, FormatConfig>::instance();
0344 
0345   /** Index in configuration storage */
0346   static int s_index;
0347 };