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

0001 /**
0002  * \file exportconfig.cpp
0003  * Configuration for export dialog.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 30 Jun 2013
0008  *
0009  * Copyright (C) 2013-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 "exportconfig.h"
0028 #include "isettings.h"
0029 
0030 int ExportConfig::s_index = -1;
0031 
0032 /**
0033  * Constructor.
0034  */
0035 ExportConfig::ExportConfig()
0036   : StoredConfig(QLatin1String("Export")),
0037     m_exportSrcV1(Frame::TagV1), m_exportFormatIdx(0)
0038 {
0039   m_exportFormatNames.append(QLatin1String("CSV unquoted"));
0040   m_exportFormatHeaders.append(QLatin1String(""));
0041   m_exportFormatTracks.append(QLatin1String(
0042     R"(%{track}\t%{title}\t%{artist}\t%{album}\t)"
0043     R"(%{year}\t%{genre}\t%{comment}\t%{duration}.00)"));
0044   m_exportFormatTrailers.append(QLatin1String(""));
0045 
0046   m_exportFormatNames.append(QLatin1String("CSV quoted"));
0047   m_exportFormatHeaders.append(QLatin1String(""));
0048   m_exportFormatTracks.append(QLatin1String(
0049     R"("%{track}"\t"%{title}"\t"%{artist}"\t"%{album}"\t)"
0050     R"("%{year}"\t"%{genre}"\t"%{comment}"\t"%{duration}.00")"));
0051   m_exportFormatTrailers.append(QLatin1String(""));
0052 
0053   m_exportFormatNames.append(QLatin1String("CSV more unquoted"));
0054   m_exportFormatHeaders.append(QLatin1String(
0055     "Track\\tTitle\\tArtist\\tAlbum\\tDate\\tGenre\\tComment\\tDuration\\t"
0056     "Album Artist\\tArranger\\tAuthor\\tBPM\\tComposer\\t"
0057     "Conductor\\tCopyright\\tDisc Number\\tEncoded-by\\tGrouping\\tISRC\\t"
0058     "Language\\tLyricist\\tLyrics\\tMedia\\tOriginal Album\\t"
0059     "Original Artist\\tOriginal Date\\tPart\\tPerformer\\t"
0060     "Publisher\\tRemixer\\tSubtitle\\tWebsite"));
0061   m_exportFormatTracks.append(QLatin1String(
0062     "%{track}\\t%{title}\\t%{artist}\\t%{album}\\t%{year}\\t%{genre}\\t%{comment}\\t"
0063     "%{duration}.00\\t"
0064     "%{album artist}\\t%{arranger}\\t%{author}\\t%{bpm}\\t%{composer}\\t"
0065     "%{conductor}\\t%{copyright}\\t%{disc number}\\t%{encoded-by}\\t%{grouping}\\t%{isrc}\\t"
0066     "%{language}\\t%{lyricist}\\t%{lyrics}\\t%{media}\\t%{original album}\\t"
0067     "%{original artist}\\t%{original date}\\t%{part}\\t%{performer}\\t"
0068     "%{publisher}\\t%{remixer}\\t%{subtitle}\\t%{website}"));
0069   m_exportFormatTrailers.append(QLatin1String(""));
0070 
0071   m_exportFormatNames.append(QLatin1String("CSV more quoted"));
0072   m_exportFormatHeaders.append(QLatin1String(
0073     "\"Track\"\\t\"Title\"\\t\"Artist\"\\t\"Album\"\\t\"Date\"\\t"
0074     "\"Genre\"\\t\"Comment\"\\t\"Duration\"\\t"
0075     "\"Album Artist\"\\t\"Arranger\"\\t\"Author\"\\t\"BPM\"\\t"
0076     "\"Composer\"\\t\"Conductor\"\\t\"Copyright\"\\t\"Disc Number\"\\t"
0077     "\"Encoded-by\"\\t\"Grouping\"\\t\"ISRC\"\\t\"Language\"\\t\"Lyricist\"\\t\"Lyrics\"\\t"
0078     "\"Media\"\\t\"Original Album\"\\t\"Original Artist\"\\t"
0079     "\"Original Date\"\\t\"Part\"\\t\"Performer\"\\t\"Publisher\"\\t"
0080     "\"Remixer\"\\t\"Subtitle\"\\t\"Website\""));
0081   m_exportFormatTracks.append(QLatin1String(
0082     "\"%{track}\"\\t\"%{title}\"\\t\"%{artist}\"\\t\"%{album}\"\\t\"%{year}\"\\t"
0083     "\"%{genre}\"\\t\"%{comment}\"\\t\"%{duration}.00\"\\t"
0084     "\"%{album artist}\"\\t\"%{arranger}\"\\t\"%{author}\"\\t\"%{bpm}\"\\t"
0085     "\"%{composer}\"\\t\"%{conductor}\"\\t\"%{copyright}\"\\t\"%{disc number}\"\\t"
0086     "\"%{encoded-by}\"\\t\"%{grouping}\"\\t\"%{isrc}\"\\t"
0087     "\"%{language}\"\\t\"%{lyricist}\"\\t\"%{lyrics}\"\\t"
0088     "\"%{media}\"\\t\"%{original album}\"\\t\"%{original artist}\"\\t"
0089     "\"%{original date}\"\\t\"%{part}\"\\t\"%{performer}\"\\t\"%{publisher}\"\\t"
0090     "\"%{remixer}\"\\t\"%{subtitle}\"\\t\"%{website}\""));
0091   m_exportFormatTrailers.append(QLatin1String(""));
0092 
0093   m_exportFormatNames.append(QLatin1String("Extended M3U"));
0094   m_exportFormatHeaders.append(QLatin1String("#EXTM3U"));
0095   m_exportFormatTracks.append(
0096         QLatin1String("#EXTINF:%{seconds},%{artist} - %{title}\\n%{filepath}"));
0097   m_exportFormatTrailers.append(QLatin1String(""));
0098 
0099   m_exportFormatNames.append(QLatin1String("Extended PLS"));
0100   m_exportFormatHeaders.append(QLatin1String("[playlist]"));
0101   m_exportFormatTracks.append(QLatin1String(
0102     "File%{tracknumber}=%{filepath}\\nTitle%{tracknumber}=%{artist} - %{title}"
0103     "\\nLength%{tracknumber}=%{seconds}"));
0104   m_exportFormatTrailers.append(QLatin1String("NumberOfEntries=%{tracks}\\nVersion=2"));
0105 
0106   m_exportFormatNames.append(QLatin1String("HTML"));
0107   m_exportFormatHeaders.append(QLatin1String(
0108     R"(<html>\n <head>\n  <title>%h{artist} - %h{album}</title>\n </head>\n)"
0109     R"( <body>\n  <h1>%h{artist} - %h{album}</h1>\n  <dl>)"));
0110   m_exportFormatTracks.append(
0111     QLatin1String("   <dt><a href=\"%{url}\">%h{track}. %h{title}</a></dt>"));
0112   m_exportFormatTrailers.append(QLatin1String("  </dl>\\n </body>\\n</html>"));
0113 
0114   m_exportFormatNames.append(QLatin1String("Kover XML"));
0115   m_exportFormatHeaders.append(QLatin1String(
0116     R"(<kover>\n <title>\n  <text><![CDATA[%{artist} ]]></text>\n  )"
0117     R"(<text><![CDATA[%{album}]]></text>\n </title>\n <content>)"));
0118   m_exportFormatTracks.append(
0119         QLatin1String("  <text><![CDATA[%{track}. %{title}]]></text>"));
0120   m_exportFormatTrailers.append(QLatin1String(" </content>\\n</kover>"));
0121 
0122   m_exportFormatNames.append(QLatin1String("Technical Details"));
0123   m_exportFormatHeaders.append(QLatin1String(
0124     R"(File\tBitrate\tVBR\tDuration\tSamplerate\tChannels\tMode\tCodec)"));
0125   m_exportFormatTracks.append(QLatin1String(
0126     R"(%{file}\t%{bitrate}\t%{vbr}\t%{duration}\t%{samplerate}\t%{channels}\t%{mode}\t%{codec})"));
0127   m_exportFormatTrailers.append(QLatin1String(""));
0128 
0129   m_exportFormatNames.append(QLatin1String("CDRDAO TOC"));
0130   m_exportFormatHeaders.append(QLatin1String(
0131     R"(CD_DA\nCD_TEXT {\n  LANGUAGE_MAP {\n    0 : EN\n  }\n  LANGUAGE 0 {\n)"
0132     R"(    TITLE "%{album}"\n    PERFORMER "%{artist}"\n  }\n}\n)"));
0133   m_exportFormatTracks.append(QLatin1String(
0134     R"(TRACK AUDIO\nCD_TEXT {\n  LANGUAGE 0 {\n    TITLE "%{title}"\n)"
0135     R"(    PERFORMER "%{artist}"\n  }\n}\nFILE "%{file}" 0\n)"));
0136   m_exportFormatTrailers.append(QLatin1String(""));
0137 
0138   m_exportFormatNames.append(QLatin1String("Custom Format"));
0139   m_exportFormatHeaders.append(QLatin1String(""));
0140   m_exportFormatTracks.append(QLatin1String(""));
0141   m_exportFormatTrailers.append(QLatin1String(""));
0142 }
0143 
0144 /**
0145  * Persist configuration.
0146  *
0147  * @param config configuration
0148  */
0149 void ExportConfig::writeToConfig(ISettings* config) const
0150 {
0151   config->beginGroup(m_group);
0152   config->setValue(QLatin1String("ExportSourceV1"),
0153                    QVariant(m_exportSrcV1 == Frame::TagV1));
0154   config->setValue(QLatin1String("ExportFormatNames"),
0155                    QVariant(m_exportFormatNames));
0156   config->setValue(QLatin1String("ExportFormatHeaders"),
0157                    QVariant(m_exportFormatHeaders));
0158   config->setValue(QLatin1String("ExportFormatTracks"),
0159                    QVariant(m_exportFormatTracks));
0160   config->setValue(QLatin1String("ExportFormatTrailers"),
0161                    QVariant(m_exportFormatTrailers));
0162   config->setValue(QLatin1String("ExportFormatIdx"),
0163                    QVariant(m_exportFormatIdx));
0164   config->endGroup();
0165   config->beginGroup(m_group, true);
0166   config->setValue(QLatin1String("ExportWindowGeometry"),
0167                    QVariant(m_exportWindowGeometry));
0168   config->endGroup();
0169 }
0170 
0171 /**
0172  * Read persisted configuration.
0173  *
0174  * @param config configuration
0175  */
0176 void ExportConfig::readFromConfig(ISettings* config)
0177 {
0178   config->beginGroup(m_group);
0179   m_exportSrcV1 = config->value(QLatin1String("ExportSourceV1"),
0180       m_exportSrcV1 == Frame::TagV1).toBool()
0181       ? Frame::TagV1 : Frame::TagV2;
0182   QStringList expNames = config->value(QLatin1String("ExportFormatNames"),
0183                                        m_exportFormatNames).toStringList();
0184   QStringList expHeaders = config->value(QLatin1String("ExportFormatHeaders"),
0185                                          m_exportFormatHeaders).toStringList();
0186   QStringList expTracks = config->value(QLatin1String("ExportFormatTracks"),
0187                                         m_exportFormatTracks).toStringList();
0188   QStringList expTrailers = config->value(QLatin1String("ExportFormatTrailers"),
0189                                           m_exportFormatTrailers).toStringList();
0190   m_exportFormatIdx = config->value(QLatin1String("ExportFormatIdx"),
0191                                     m_exportFormatIdx).toInt();
0192   config->endGroup();
0193   config->beginGroup(m_group, true);
0194   m_exportWindowGeometry = config->value(QLatin1String("ExportWindowGeometry"),
0195                                          m_exportWindowGeometry).toByteArray();
0196   config->endGroup();
0197 
0198   // KConfig seems to strip empty entries from the end of the string lists,
0199   // so we have to append them again.
0200   const int numExpNames = expNames.size();
0201   while (expHeaders.size() < numExpNames) expHeaders.append(QLatin1String(""));
0202   while (expTracks.size() < numExpNames) expTracks.append(QLatin1String(""));
0203   while (expTrailers.size() < numExpNames) expTrailers.append(QLatin1String(""));
0204 
0205   for (auto expNamesIt = expNames.constBegin(), expHeadersIt = expHeaders.constBegin(),
0206          expTracksIt = expTracks.constBegin(), expTrailersIt = expTrailers.constBegin();
0207        expNamesIt != expNames.constEnd() && expHeadersIt != expHeaders.constEnd() &&
0208          expTracksIt != expTracks.constEnd() && expTrailersIt != expTrailers.constEnd();
0209        ++expNamesIt, ++expHeadersIt, ++expTracksIt, ++expTrailersIt) {
0210     if (int idx = m_exportFormatNames.indexOf(*expNamesIt); idx >= 0) {
0211       m_exportFormatHeaders[idx] = *expHeadersIt;
0212       m_exportFormatTracks[idx] = *expTracksIt;
0213       m_exportFormatTrailers[idx] = *expTrailersIt;
0214     } else if (!expNamesIt->isEmpty()) {
0215       m_exportFormatNames.append(*expNamesIt);
0216       m_exportFormatHeaders.append(*expHeadersIt);
0217       m_exportFormatTracks.append(*expTracksIt);
0218       m_exportFormatTrailers.append(*expTrailersIt);
0219     }
0220   }
0221 
0222   if (m_exportFormatIdx >=  m_exportFormatNames.size())
0223     m_exportFormatIdx = 0;
0224 
0225   // Use HTML escaping for old HTML export format.
0226   if (int htmlIdx = m_exportFormatNames.indexOf(QLatin1String("HTML"));
0227       htmlIdx != -1) {
0228     if (m_exportFormatHeaders.at(htmlIdx) == QLatin1String(
0229       R"(<html>\n <head>\n  <title>%{artist} - %{album}</title>\n )"
0230       R"(</head>\n <body>\n  <h1>%{artist} - %{album}</h1>\n  <dl>)")) {
0231       m_exportFormatHeaders[htmlIdx] = QLatin1String(
0232         R"(<html>\n <head>\n  <title>%h{artist} - %h{album}</title>\n )"
0233         R"(</head>\n <body>\n  <h1>%h{artist} - %h{album}</h1>\n  <dl>)");
0234     }
0235     if (m_exportFormatTracks.at(htmlIdx) ==
0236         QLatin1String("   <dt><a href=\"%{url}\">%{track}. %{title}</a></dt>")) {
0237       m_exportFormatTracks[htmlIdx] =
0238           QLatin1String("   <dt><a href=\"%{url}\">%h{track}. %h{title}</a></dt>");
0239     }
0240   }
0241 }
0242 
0243 void ExportConfig::setExportSource(Frame::TagVersion exportSource)
0244 {
0245   if (m_exportSrcV1 != exportSource) {
0246     m_exportSrcV1 = exportSource;
0247     emit exportSourceChanged(m_exportSrcV1);
0248   }
0249 }
0250 
0251 void ExportConfig::setExportFormatNames(const QStringList& exportFormatNames)
0252 {
0253   if (m_exportFormatNames != exportFormatNames) {
0254     m_exportFormatNames = exportFormatNames;
0255     emit exportFormatNamesChanged(m_exportFormatNames);
0256   }
0257 }
0258 
0259 void ExportConfig::setExportFormatHeaders(const QStringList& exportFormatHeaders)
0260 {
0261   if (m_exportFormatHeaders != exportFormatHeaders) {
0262     m_exportFormatHeaders = exportFormatHeaders;
0263     emit exportFormatHeadersChanged(m_exportFormatHeaders);
0264   }
0265 }
0266 
0267 void ExportConfig::setExportFormatTracks(const QStringList& exportFormatTracks)
0268 {
0269   if (m_exportFormatTracks != exportFormatTracks) {
0270     m_exportFormatTracks = exportFormatTracks;
0271     emit exportFormatTracksChanged(m_exportFormatTracks);
0272   }
0273 }
0274 
0275 void ExportConfig::setExportFormatTrailers(const QStringList& exportFormatTrailers)
0276 {
0277   if (m_exportFormatTrailers != exportFormatTrailers) {
0278     m_exportFormatTrailers = exportFormatTrailers;
0279     emit exportFormatTrailersChanged(m_exportFormatTrailers);
0280   }
0281 }
0282 
0283 void ExportConfig::setExportFormatIndex(int exportFormatIndex)
0284 {
0285   if (m_exportFormatIdx != exportFormatIndex) {
0286     m_exportFormatIdx = exportFormatIndex;
0287     emit exportFormatIndexChanged(m_exportFormatIdx);
0288   }
0289 }
0290 
0291 void ExportConfig::setExportWindowGeometry(const QByteArray& exportWindowGeometry)
0292 {
0293   if (m_exportWindowGeometry != exportWindowGeometry) {
0294     m_exportWindowGeometry = exportWindowGeometry;
0295     emit exportWindowGeometryChanged(m_exportWindowGeometry);
0296   }
0297 }