File indexing completed on 2024-05-19 04:55:59
0001 /** 0002 * \file textimporter.cpp 0003 * Import tags from text. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 19 Jun 2011 0008 * 0009 * Copyright (C) 2011-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 #include "textimporter.h" 0028 #include "importparser.h" 0029 #include "trackdatamodel.h" 0030 0031 /** 0032 * Constructor. 0033 * 0034 * @param trackDataModel track data to be filled with imported values 0035 */ 0036 TextImporter::TextImporter(TrackDataModel* trackDataModel) 0037 : m_headerParser(new ImportParser), 0038 m_trackParser(new ImportParser), 0039 m_trackDataModel(trackDataModel) 0040 { 0041 } 0042 0043 /** 0044 * Destructor. 0045 */ 0046 TextImporter::~TextImporter() 0047 { 0048 // Must not be inline because of forwared declared QScopedPointer. 0049 } 0050 0051 /** 0052 * Look for album specific information (artist, album, year, genre) in 0053 * a header. 0054 * 0055 * @param frames frames to put resulting values in, 0056 * fields which are not found are not touched. 0057 * 0058 * @return true if one or more field were found. 0059 */ 0060 bool TextImporter::parseHeader(TrackData& frames) 0061 { 0062 int pos = 0; 0063 m_headerParser->setFormat(m_headerFormat); 0064 return m_headerParser->getNextTags(m_text, frames, pos); 0065 } 0066 0067 /** 0068 * Update track data list with imported tags. 0069 * 0070 * @param text text to import 0071 * @param headerFormat header format 0072 * @param trackFormat track format 0073 * 0074 * @return true if tags were found. 0075 */ 0076 bool TextImporter::updateTrackData( 0077 const QString& text, 0078 const QString& headerFormat, const QString& trackFormat) { 0079 m_text = text; 0080 m_headerFormat = headerFormat; 0081 m_trackFormat = trackFormat; 0082 0083 TrackData framesHdr; 0084 (void)parseHeader(framesHdr); 0085 0086 TrackData frames(framesHdr); 0087 bool start = true; 0088 ImportTrackDataVector trackDataVector(m_trackDataModel->getTrackData()); 0089 auto it = trackDataVector.begin(); 0090 bool atTrackDataListEnd = it == trackDataVector.end(); 0091 while (getNextTags(frames, start)) { 0092 start = false; 0093 if (atTrackDataListEnd) { 0094 ImportTrackData trackData; 0095 trackData.setFrameCollection(frames); 0096 trackDataVector.push_back(trackData); 0097 } else { 0098 while (!atTrackDataListEnd && !it->isEnabled()) { 0099 ++it; 0100 atTrackDataListEnd = it == trackDataVector.end(); 0101 } 0102 if (!atTrackDataListEnd) { 0103 it->setFrameCollection(frames); 0104 ++it; 0105 atTrackDataListEnd = it == trackDataVector.end(); 0106 } 0107 } 0108 frames = framesHdr; 0109 } 0110 frames.clear(); 0111 while (!atTrackDataListEnd) { 0112 if (it->isEnabled()) { 0113 if (it->getFileDuration() == 0) { 0114 it = trackDataVector.erase(it); 0115 } else { 0116 it->setFrameCollection(frames); 0117 it->setImportDuration(0); 0118 ++it; 0119 } 0120 } else { 0121 ++it; 0122 } 0123 atTrackDataListEnd = it == trackDataVector.end(); 0124 } 0125 0126 if (!start) { 0127 /* start is false => tags were found */ 0128 if (QList<int> trackDuration = getTrackDurations(); 0129 !trackDuration.isEmpty()) { 0130 it = trackDataVector.begin(); 0131 for (auto tdit = trackDuration.constBegin(); 0132 tdit != trackDuration.constEnd(); 0133 ++tdit) { 0134 if (it != trackDataVector.end()) { 0135 if (it->isEnabled()) { 0136 it->setImportDuration(*tdit); 0137 } 0138 ++it; 0139 } else { 0140 break; 0141 } 0142 } 0143 } 0144 m_trackDataModel->setTrackData(trackDataVector); 0145 return true; 0146 } 0147 return false; 0148 } 0149 0150 /** 0151 * Get next line as frames from imported file or clipboard. 0152 * 0153 * @param frames frames 0154 * @param start true to start with the first line, false for all 0155 * other lines 0156 * 0157 * @return true if ok (result in st), 0158 * false if end of file reached. 0159 */ 0160 bool TextImporter::getNextTags(TrackData& frames, bool start) 0161 { 0162 static int pos = 0; 0163 if (start || pos == 0) { 0164 pos = 0; 0165 m_trackParser->setFormat(m_trackFormat, true); 0166 } 0167 return m_trackParser->getNextTags(m_text, frames, pos); 0168 } 0169 0170 /** 0171 * Get list with track durations. 0172 * 0173 * @return list with track durations, 0174 * empty if no track durations found. 0175 */ 0176 QList<int> TextImporter::getTrackDurations() const 0177 { 0178 QList<int> lst; 0179 if (m_headerParser) { 0180 lst = m_headerParser->getTrackDurations(); 0181 } 0182 if (lst.isEmpty() && m_trackParser) { 0183 lst = m_trackParser->getTrackDurations(); 0184 } 0185 return lst; 0186 } 0187 0188 /** 0189 * Import text from tags to other tags. 0190 * 0191 * @param sourceFormat format to create source text 0192 * @param extractionFormat regular expression to extract other tags 0193 * @param trackDataVector track data to process 0194 */ 0195 void TextImporter::importFromTags( 0196 const QString& sourceFormat, 0197 const QString& extractionFormat, 0198 ImportTrackDataVector& trackDataVector) 0199 { 0200 ImportParser parser; 0201 parser.setFormat(extractionFormat); 0202 for (auto it = trackDataVector.begin(); it != trackDataVector.end(); ++it) { 0203 if (it->isEnabled()) { 0204 QString text(it->formatString(sourceFormat)); 0205 int pos = 0; 0206 parser.getNextTags(text, *it, pos); 0207 } 0208 } 0209 } 0210 0211 /** 0212 * Import text from tags to other tags. 0213 * 0214 * @param sourceFormat format to create source text 0215 * @param parser import parser which is initialized with extraction format 0216 * @param trackData track data to process 0217 */ 0218 void TextImporter::importFromTags( 0219 const QString& sourceFormat, ImportParser& parser, TrackData& trackData) 0220 { 0221 QString text(trackData.formatString(sourceFormat)); 0222 int pos = 0; 0223 parser.getNextTags(text, trackData, pos); 0224 }