File indexing completed on 2024-05-12 04:55:48
0001 /** 0002 * \file taglibfile.h 0003 * Handling of tagged files using TagLib. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 12 Sep 2006 0008 * 0009 * Copyright (C) 2006-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 <QtGlobal> 0030 #include "taggedfile.h" 0031 #include "tagconfig.h" 0032 #include <taglib.h> 0033 #include <fileref.h> 0034 #include <id3v2frame.h> 0035 0036 /** TagLib version in with 8 bits for major, minor and patch version. */ 0037 #define TAGLIB_VERSION (((TAGLIB_MAJOR_VERSION) << 16) + \ 0038 ((TAGLIB_MINOR_VERSION) << 8) + (TAGLIB_PATCH_VERSION)) 0039 0040 class QTextCodec; 0041 class FileIOStream; 0042 0043 namespace TagLib { 0044 namespace MP4 { 0045 class Tag; 0046 } 0047 } 0048 0049 class TagLibFile; 0050 0051 namespace TagLibFileInternal { 0052 0053 void fixUpTagLibFrameValue(const TagLibFile* self, 0054 Frame::Type frameType, QString& value); 0055 0056 } 0057 0058 /** List box item containing tagged file. */ 0059 class TagLibFile : public TaggedFile { 0060 public: 0061 /** 0062 * Constructor. 0063 * 0064 * @param idx index in tagged file system model 0065 */ 0066 explicit TagLibFile(const QPersistentModelIndex& idx); 0067 0068 /** 0069 * Destructor. 0070 */ 0071 ~TagLibFile() override; 0072 0073 /** 0074 * Get key of tagged file format. 0075 * @return "TaglibMetadata". 0076 */ 0077 QString taggedFileKey() const override; 0078 0079 /** 0080 * Get features supported. 0081 * @return bit mask with Feature flags set. 0082 */ 0083 int taggedFileFeatures() const override; 0084 0085 /** 0086 * Get currently active tagged file features. 0087 * @return active tagged file features (TF_ID3v23, TF_ID3v24, or 0). 0088 * @see setActiveTaggedFileFeatures() 0089 */ 0090 int activeTaggedFileFeatures() const override; 0091 0092 /** 0093 * Activate some features provided by the tagged file. 0094 * TagLibFile provides the TF_ID3v23 and TF_ID3v24 features, which determine 0095 * the ID3v2 version used in writeTags() (the overload without id3v2Version). 0096 * If 0 is set, the default behavior applies, i.e. for new files, 0097 * TagConfig::id3v2Version() is used, else the existing version. 0098 * 0099 * @param features TF_ID3v23, TF_ID3v24, or 0 0100 */ 0101 void setActiveTaggedFileFeatures(int features) override; 0102 0103 /** 0104 * Read tags from file. 0105 * 0106 * @param force true to force reading even if tags were already read. 0107 */ 0108 void readTags(bool force) override; 0109 0110 /** 0111 * Write tags to file and rename it if necessary. 0112 * 0113 * @param force true to force writing even if file was not changed. 0114 * @param renamed will be set to true if the file was renamed, 0115 * i.e. the file name is no longer valid, else *renamed 0116 * is left unchanged 0117 * @param preserve true to preserve file time stamps 0118 * 0119 * @return true if ok, false if the file could not be written or renamed. 0120 */ 0121 bool writeTags(bool force, bool* renamed, bool preserve) override; 0122 0123 /** 0124 * Free resources allocated when calling readTags(). 0125 * 0126 * @param force true to force clearing even if the tags are modified 0127 */ 0128 void clearTags(bool force) override; 0129 0130 /** 0131 * Write tags to file and rename it if necessary. 0132 * 0133 * @param force true to force writing even if file was not changed. 0134 * @param renamed will be set to true if the file was renamed, 0135 * i.e. the file name is no longer valid, else *renamed 0136 * is left unchanged 0137 * @param preserve true to preserve file time stamps 0138 * @param id3v2Version ID3v2 version to use, 0 to use existing or preferred, 0139 * 3 to force ID3v2.3.0, 4 to force ID3v2.4.0. Is ignored 0140 * if TagLib version is less than 1.8.0. 0141 * 0142 * @return true if ok, false if the file could not be written or renamed. 0143 */ 0144 bool writeTags(bool force, bool* renamed, bool preserve, int id3v2Version); 0145 0146 /** 0147 * Remove frames. 0148 * 0149 * @param tagNr tag number 0150 * @param flt filter specifying which frames to remove 0151 */ 0152 void deleteFrames(Frame::TagNumber tagNr, const FrameFilter& flt) override; 0153 0154 /** 0155 * Check if tag information has already been read. 0156 * 0157 * @return true if information is available, 0158 * false if the tags have not been read yet, in which case 0159 * hasTag() does not return meaningful information. 0160 */ 0161 bool isTagInformationRead() const override; 0162 0163 /** 0164 * Check if file has a tag. 0165 * 0166 * @param tagNr tag number 0167 * @return true if a V1 tag is available. 0168 * @see isTagInformationRead() 0169 */ 0170 bool hasTag(Frame::TagNumber tagNr) const override; 0171 0172 /** 0173 * Check if tags are supported by the format of this file. 0174 * 0175 * @param tagNr tag number 0176 * @return true. 0177 */ 0178 bool isTagSupported(Frame::TagNumber tagNr) const override; 0179 0180 /** 0181 * Get technical detail information. 0182 * 0183 * @param info the detail information is returned here 0184 */ 0185 void getDetailInfo(DetailInfo& info) const override; 0186 0187 /** 0188 * Get duration of file. 0189 * 0190 * @return duration in seconds, 0191 * 0 if unknown. 0192 */ 0193 unsigned getDuration() const override; 0194 0195 /** 0196 * Get file extension including the dot. 0197 * 0198 * @return file extension ".mp3". 0199 */ 0200 QString getFileExtension() const override; 0201 0202 /** 0203 * Get the format of tag. 0204 * 0205 * @param tagNr tag number 0206 * @return string describing format of tag 1, 0207 * e.g. "ID3v1.1", "ID3v2.3", "Vorbis", "APE", 0208 * QString::null if unknown. 0209 */ 0210 QString getTagFormat(Frame::TagNumber tagNr) const override; 0211 0212 /** 0213 * Get a specific frame from the tags. 0214 * 0215 * @param tagNr tag number 0216 * @param type frame type 0217 * @param frame the frame is returned here 0218 * 0219 * @return true if ok. 0220 */ 0221 bool getFrame(Frame::TagNumber tagNr, Frame::Type type, Frame& frame) const override; 0222 0223 /** 0224 * Set a frame in the tags. 0225 * 0226 * @param tagNr tag number 0227 * @param frame frame to set 0228 * 0229 * @return true if ok. 0230 */ 0231 bool setFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0232 0233 /** 0234 * Add a frame in the tags. 0235 * 0236 * @param tagNr tag number 0237 * @param frame frame to add, a field list may be added by this method 0238 * 0239 * @return true if ok. 0240 */ 0241 bool addFrame(Frame::TagNumber tagNr, Frame& frame) override; 0242 0243 /** 0244 * Delete a frame from the tags. 0245 * 0246 * @param tagNr tag number 0247 * @param frame frame to delete. 0248 * 0249 * @return true if ok. 0250 */ 0251 bool deleteFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0252 0253 /** 0254 * Get all frames in tag. 0255 * 0256 * @param tagNr tag number 0257 * @param frames frame collection to set. 0258 */ 0259 void getAllFrames(Frame::TagNumber tagNr, FrameCollection& frames) override; 0260 0261 /** 0262 * Close file handle which is held open by the TagLib object. 0263 */ 0264 void closeFileHandle() override; 0265 0266 /** 0267 * Get a list of frame IDs which can be added. 0268 * @param tagNr tag number 0269 * @return list with frame IDs. 0270 */ 0271 QStringList getFrameIds(Frame::TagNumber tagNr) const override; 0272 0273 /** 0274 * Add a suitable field list for the frame if missing. 0275 * If a frame is created, its field list is empty. This method will create 0276 * a field list appropriate for the frame type and tagged file type if no 0277 * field list exists. 0278 * @param tagNr tag number 0279 * @param frame frame where field list is added 0280 */ 0281 void addFieldList(Frame::TagNumber tagNr, Frame& frame) const override; 0282 0283 /** 0284 * Static initialization. 0285 * Registers file types. 0286 */ 0287 static void staticInit(); 0288 0289 /** 0290 * Get the default text encoding. 0291 * @return default text encoding. 0292 */ 0293 static TagLib::String::Type getDefaultTextEncoding() { return s_defaultTextEncoding; } 0294 0295 /** 0296 * Notify about configuration change. 0297 * This method shall be called when the configuration changes. 0298 */ 0299 static void notifyConfigurationChange(); 0300 0301 private: 0302 friend void TagLibFileInternal::fixUpTagLibFrameValue( 0303 const TagLibFile* self, Frame::Type frameType, QString& value); 0304 0305 TagLibFile(const TagLibFile&); 0306 TagLibFile& operator=(const TagLibFile&); 0307 0308 /** 0309 * Close file handle. 0310 * TagLib keeps the file handle open until the FileRef is destroyed. 0311 * This causes problems when the operating system has a limited number of 0312 * open file handles. This method closes the file by assigning a new file 0313 * reference. Note that this will also invalidate the tag pointers. 0314 * The file is only closed if there are no unsaved tag changes or if the 0315 * @a force parameter is set. 0316 * 0317 * @param force true to close the file even if tags are changed 0318 */ 0319 void closeFile(bool force = false); 0320 0321 /** 0322 * Make sure that file is open. 0323 * This method should be called before accessing m_fileRef, m_tag. 0324 * 0325 * @param force true to force reopening of file even if it is already open 0326 */ 0327 void makeFileOpen(bool force = false) const; 0328 0329 /** 0330 * Create tag if it does not already exist so that it can be set. 0331 * 0332 * @param tagNr tag number 0333 * @return true if tag can be set. 0334 */ 0335 bool makeTagSettable(Frame::TagNumber tagNr); 0336 0337 /** 0338 * Cache technical detail information. 0339 */ 0340 void readAudioProperties(); 0341 0342 /** 0343 * Get tracker name of a module file. 0344 * 0345 * @return tracker name, null if not found. 0346 */ 0347 QString getTrackerName() const; 0348 0349 /** 0350 * Set m_id3v2Version to 3 or 4 from tag if it exists, else to 0. 0351 * @param id3v2Tag ID3v2 tag 0352 */ 0353 void setId3v2VersionFromTag(const TagLib::ID3v2::Tag* id3v2Tag); 0354 0355 /** 0356 * Set m_id3v2Version from given value (3 or 4) or use default from 0357 * configuration if not already set to 3 or 4. 0358 * @param id3v2Version 3 or 4 to force version, 0 to use existing version 0359 * or default 0360 */ 0361 void setId3v2VersionOrDefault(int id3v2Version); 0362 0363 /** 0364 * Get internal name of a Vorbis frame. 0365 * 0366 * @param frame frame 0367 * 0368 * @return Vorbis key. 0369 */ 0370 QString getVorbisName(const Frame& frame) const; 0371 0372 /** 0373 * Set a frame in an MP4 tag. 0374 * @param frame frame to set 0375 * @param mp4Tag MP4 tag 0376 */ 0377 void setMp4Frame(const Frame& frame, TagLib::MP4::Tag* mp4Tag); 0378 0379 /** 0380 * Get the format of a tag. 0381 * 0382 * @param tag tag, 0 if no tag available 0383 * @param type the tag type is returned here 0384 * 0385 * @return string describing format of tag, 0386 * e.g. "ID3v1.1", "ID3v2.3", "Vorbis", "APE", 0387 * QString::null if unknown. 0388 */ 0389 static QString getTagFormat(const TagLib::Tag* tag, TagType& type); 0390 0391 /** 0392 * Set the encoding to be used for tag 1. 0393 * 0394 * @param name of encoding, default is ISO 8859-1 0395 */ 0396 static void setTextEncodingV1(const QString& name); 0397 0398 /** 0399 * Set the default text encoding. 0400 * 0401 * @param textEnc default text encoding 0402 */ 0403 static void setDefaultTextEncoding(TagConfig::TextEncoding textEnc); 0404 0405 static const int NUM_TAGS = 3; 0406 0407 bool m_tagInformationRead; 0408 bool m_hasTag[NUM_TAGS]; 0409 bool m_isTagSupported[NUM_TAGS]; 0410 0411 bool m_fileRead; /**< true if file has been read */ 0412 0413 TagLib::FileRef m_fileRef; /**< file reference */ 0414 TagLib::Tag* m_tag[NUM_TAGS]; 0415 FileIOStream* m_stream; 0416 int m_id3v2Version; /**< 3 for ID3v2.3, 4 for ID3v2.4, 0 if none */ 0417 int m_activatedFeatures; /**< TF_ID3v23, TF_ID3v24, or 0 */ 0418 0419 /* Cached information updated in readTags() */ 0420 unsigned m_duration; 0421 TagType m_tagType[NUM_TAGS]; 0422 QString m_tagFormat[NUM_TAGS]; 0423 QString m_fileExtension; 0424 DetailInfo m_detailInfo; 0425 0426 class Pictures : public QList<Frame> { 0427 public: 0428 Pictures() : m_read(false) {} 0429 bool isRead() const { return m_read; } 0430 void setRead(bool read) { m_read = read; } 0431 0432 private: 0433 bool m_read; 0434 }; 0435 0436 Pictures m_pictures; 0437 0438 /** default text encoding */ 0439 static TagLib::String::Type s_defaultTextEncoding; 0440 };