Updated changelog.
[LameXP.git] / src / Model_MetaInfo.cpp
blob70a15cac1dc05e80483d5b985dd8dae2c3c6954b
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2023 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU GENERAL PUBLIC LICENSE as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version; always including the non-optional
9 // LAMEXP GNU GENERAL PUBLIC LICENSE ADDENDUM. See "License.txt" file!
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
23 #include "Model_MetaInfo.h"
24 #include "Genres.h"
26 #include <QMessageBox>
27 #include <QInputDialog>
28 #include <QFileInfo>
29 #include <QDir>
31 #define MODEL_ROW_COUNT 12
33 #define CHECK1(STR) (STR.isEmpty() ? (m_offset ? m_textNotSpecified : m_textUnknown) : STR)
34 #define CHECK2(VAL) ((VAL > 0) ? QString::number(VAL) : (m_offset ? m_textNotSpecified : m_textUnknown))
35 #define CHECK3(STR) (STR.isEmpty() ? Qt::darkGray : QVariant())
36 #define CHECK4(VAL) ((VAL == 0) ? Qt::darkGray : QVariant())
38 #define EXPAND(STR) QString(STR).leftJustified(96, ' ')
40 ////////////////////////////////////////////////////////////
41 // Constructor & Destructor
42 ////////////////////////////////////////////////////////////
44 MetaInfoModel::MetaInfoModel(AudioFileModel *file)
46 m_fullInfo(file),
47 m_metaInfo(&file->metaInfo()),
48 m_offset(0)
50 m_textUnknown = QString("(%1)").arg(tr("Unknown"));
51 m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
54 MetaInfoModel::MetaInfoModel(AudioFileModel_MetaInfo *metaInfo)
56 m_fullInfo(NULL),
57 m_metaInfo(metaInfo),
58 m_offset(6)
60 m_textUnknown = QString("(%1)").arg(tr("Unknown"));
61 m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
64 MetaInfoModel::~MetaInfoModel(void)
68 ////////////////////////////////////////////////////////////
69 // Public Functions
70 ////////////////////////////////////////////////////////////
72 int MetaInfoModel::columnCount(const QModelIndex& /*parent*/) const
74 return 2;
77 int MetaInfoModel::rowCount(const QModelIndex& /*parent*/) const
79 return MODEL_ROW_COUNT - m_offset;
82 QVariant MetaInfoModel::data(const QModelIndex &index, int role) const
84 if(role == Qt::DisplayRole)
86 switch(index.row() + m_offset)
88 case 0:
89 return (!index.column()) ? tr("Full Path") : CHECK1(QDir::toNativeSeparators(m_fullInfo->filePath()));
90 break;
91 case 1:
92 return (!index.column()) ? tr("Format") : CHECK1(m_fullInfo->audioBaseInfo());
93 break;
94 case 2:
95 return (!index.column()) ? tr("Container") : CHECK1(m_fullInfo->containerInfo());
96 break;
97 case 3:
98 return (!index.column()) ? tr("Compression") : CHECK1(m_fullInfo->audioCompressInfo());
99 break;
100 case 4:
101 return (!index.column()) ? tr("Duration") : CHECK1(m_fullInfo->durationInfo());
102 break;
103 case 5:
104 return (!index.column()) ? tr("Title") : CHECK1(m_metaInfo->title());
105 break;
106 case 6:
107 return (!index.column()) ? tr("Artist") : CHECK1(m_metaInfo->artist());
108 break;
109 case 7:
110 return (!index.column()) ? tr("Album") : CHECK1(m_metaInfo->album());
111 break;
112 case 8:
113 return (!index.column()) ? tr("Genre") : CHECK1(m_metaInfo->genre());
114 break;
115 case 9:
116 return (!index.column()) ? tr("Year") : CHECK2(m_metaInfo->year());
117 break;
118 case 10:
119 return (!index.column()) ? tr("Position") : ((m_metaInfo->position() == UINT_MAX) ? tr("Generate from list position") : CHECK2(m_metaInfo->position()));
120 break;
121 case 11:
122 return (!index.column()) ? tr("Comment") : CHECK1(m_metaInfo->comment());
123 break;
124 default:
125 return QVariant();
126 break;
129 else if(role == Qt::DecorationRole && index.column() == 0)
131 switch(index.row() + m_offset)
133 case 0:
134 return QIcon(":/icons/folder_page.png");
135 break;
136 case 1:
137 return QIcon(":/icons/sound.png");
138 break;
139 case 2:
140 return QIcon(":/icons/package.png");
141 break;
142 case 3:
143 return QIcon(":/icons/compress.png");
144 break;
145 case 4:
146 return QIcon(":/icons/clock_play.png");
147 break;
148 case 5:
149 return QIcon(":/icons/music.png");
150 break;
151 case 6:
152 return QIcon(":/icons/user.png");
153 break;
154 case 7:
155 return QIcon(":/icons/cd.png");
156 break;
157 case 8:
158 return QIcon(":/icons/star.png");
159 break;
160 case 9:
161 return QIcon(":/icons/date.png");
162 break;
163 case 10:
164 return QIcon(":/icons/timeline_marker.png");
165 break;
166 case 11:
167 return QIcon(":/icons/comment.png");
168 break;
169 default:
170 return QVariant();
171 break;
174 else if(role == Qt::TextColorRole && index.column() == 1)
176 switch(index.row() + m_offset)
178 case 0:
179 return CHECK3(m_fullInfo->filePath());
180 break;
181 case 1:
182 return CHECK3(m_fullInfo->audioBaseInfo());
183 break;
184 case 2:
185 return CHECK3(m_fullInfo->containerInfo());
186 break;
187 case 3:
188 return CHECK3(m_fullInfo->audioCompressInfo());
189 break;
190 case 4:
191 return CHECK4(m_fullInfo->durationInfo());
192 break;
193 case 5:
194 return CHECK3(m_metaInfo->title());
195 break;
196 case 6:
197 return CHECK3(m_metaInfo->artist());
198 break;
199 case 7:
200 return CHECK3(m_metaInfo->album());
201 break;
202 case 8:
203 return CHECK3(m_metaInfo->genre());
204 break;
205 case 9:
206 return CHECK4(m_metaInfo->year());
207 break;
208 case 10:
209 return CHECK4(m_metaInfo->position());
210 break;
211 case 11:
212 return CHECK3(m_metaInfo->comment());
213 break;
214 default:
215 return QVariant();
216 break;
219 else
221 return QVariant();
225 QVariant MetaInfoModel::headerData(int section, Qt::Orientation orientation, int role) const
227 if(role == Qt::DisplayRole)
229 if(orientation == Qt::Horizontal)
231 switch(section)
233 case 0:
234 return QVariant(tr("Property"));
235 break;
236 case 1:
237 return QVariant(tr("Value"));
238 break;
239 default:
240 return QVariant();
241 break;
244 else
246 return QVariant();
249 else
251 return QVariant();
255 bool MetaInfoModel::setData (const QModelIndex &index, const QVariant &value, int role)
257 if((role != Qt::EditRole) || (index.column() != 1) || !value.isValid())
259 return false;
262 switch(index.row() + m_offset)
264 case 0:
265 m_fullInfo->setFilePath(value.toString());
266 break;
267 case 1:
268 case 2:
269 case 3:
270 return false;
271 break;
272 case 4:
273 m_fullInfo->techInfo().setDuration(value.toUInt());
274 break;
275 case 5:
276 m_metaInfo->setTitle(value.toString());
277 break;
278 case 6:
279 m_metaInfo->setArtist(value.toString());
280 break;
281 case 7:
282 m_metaInfo->setAlbum(value.toString());
283 break;
284 case 8:
285 m_metaInfo->setGenre(value.toString());
286 break;
287 case 9:
288 m_metaInfo->setYear(value.toUInt());
289 break;
290 case 10:
291 m_metaInfo->setPosition(value.toUInt());
292 break;
293 case 11:
294 m_metaInfo->setComment(value.toString());
295 break;
296 default:
297 return false;
298 break;
301 emit dataChanged(index, index);
302 return true;
305 void MetaInfoModel::editItem(const QModelIndex &index, QWidget *parent)
307 int val = -1;
308 QStringList generes(QString("(%1)").arg(tr("Unspecified")));
309 QString temp;
311 QInputDialog input(parent);
312 input.setOkButtonText(tr("OK"));
313 input.setCancelButtonText(tr("Cancel"));
314 input.setTextEchoMode(QLineEdit::Normal);
316 switch(index.row() + m_offset)
318 case 5:
319 input.setWindowTitle(tr("Edit Title"));
320 input.setLabelText(EXPAND(tr("Please enter the title for this file:")));
321 input.setTextValue(m_metaInfo->title());
322 if(input.exec() != 0)
324 temp = input.textValue().simplified();
325 if(temp.isEmpty())
327 QMessageBox::warning(parent, tr("Edit Title"), tr("The title must not be empty. Generating title from file name!"));
328 temp = QFileInfo(m_fullInfo->filePath()).completeBaseName().replace("_", " ").simplified();
329 const int idx = temp.lastIndexOf(" - ");
330 if(idx >= 0) temp = temp.mid(idx + 3).trimmed();
332 beginResetModel();
333 m_metaInfo->setTitle(temp.isEmpty() ? QString() : temp);
334 endResetModel();
336 break;
337 case 6:
338 input.setWindowTitle(tr("Edit Artist"));
339 input.setLabelText(EXPAND(tr("Please enter the artist for this file:")));
340 input.setTextValue(m_metaInfo->artist());
341 if(input.exec() != 0)
343 temp = input.textValue().simplified();
344 beginResetModel();
345 m_metaInfo->setArtist(temp.isEmpty() ? QString() : temp);
346 endResetModel();
348 break;
349 case 7:
350 input.setWindowTitle(tr("Edit Album"));
351 input.setLabelText(EXPAND(tr("Please enter the album for this file:")));
352 input.setTextValue(m_metaInfo->album());
353 if(input.exec() != 0)
355 temp = input.textValue().simplified();
356 beginResetModel();
357 m_metaInfo->setAlbum(temp.isEmpty() ? QString() : temp);
358 endResetModel();
360 break;
361 case 8:
362 input.setWindowTitle(tr("Edit Genre"));
363 input.setLabelText(EXPAND(tr("Please enter the genre for this file:")));
364 for(int i = 0; g_lamexp_generes[i]; i++) generes << g_lamexp_generes[i];
365 input.setComboBoxItems(generes);
366 input.setTextValue(m_metaInfo->genre());
367 if(input.exec() != 0)
369 temp = input.textValue().simplified();
370 beginResetModel();
371 m_metaInfo->setGenre((temp.isEmpty() || !temp.compare(generes.at(0), Qt::CaseInsensitive)) ? QString() : temp);
372 endResetModel();
374 break;
375 case 9:
376 input.setWindowTitle(tr("Edit Year"));
377 input.setLabelText(EXPAND(tr("Please enter the year for this file:")));
378 input.setIntRange(0, 2100);
379 input.setIntValue((m_metaInfo->year() ? m_metaInfo->year() : 1900));
380 input.setIntStep(1);
381 if(input.exec() != 0)
383 val = input.intValue();
384 beginResetModel();
385 m_metaInfo->setYear(val);
386 endResetModel();
388 break;
389 case 10:
390 if(!m_offset)
392 input.setWindowTitle(tr("Edit Position"));
393 input.setLabelText(EXPAND(tr("Please enter the position (track no.) for this file:")));
394 input.setIntRange(0, 99);
395 input.setIntValue((m_metaInfo->position() ? m_metaInfo->position() : 1));
396 input.setIntStep(1);
397 if(input.exec() != 0)
399 val = input.intValue();
400 beginResetModel();
401 m_metaInfo->setPosition(val);
402 endResetModel();
405 else
407 QStringList options;
408 options << tr("Unspecified (copy from source file)") << tr("Generate from list position");
409 input.setWindowTitle(tr("Edit Position"));
410 input.setLabelText(EXPAND(tr("Please enter the position (track no.) for this file:")));
411 input.setComboBoxItems(options);
412 input.setTextValue(options.value((m_metaInfo->position() == UINT_MAX) ? 1 : 0));
413 if(input.exec() != 0)
415 temp = input.textValue().simplified();
416 beginResetModel();
417 m_metaInfo->setPosition((options.indexOf(temp) == 1) ? UINT_MAX : 0);
418 endResetModel();
421 break;
422 case 11:
423 input.setWindowTitle(tr("Edit Comment"));
424 input.setLabelText(EXPAND(tr("Please enter the comment for this file:")));
425 input.setTextValue((m_metaInfo->comment().isEmpty() ? tr("Encoded with LameXP") : m_metaInfo->comment()));
426 if(input.exec() != 0)
428 temp = input.textValue().simplified();
429 beginResetModel();
430 m_metaInfo->setComment(temp.isEmpty() ? QString() : temp);
431 endResetModel();
433 break;
434 default:
435 QMessageBox::warning(parent, tr("Not editable"), tr("Sorry, this property of the source file cannot be edited!"));
436 break;
440 void MetaInfoModel::editArtwork(const QString &imagePath)
442 m_metaInfo->setCover(imagePath, false);
445 void MetaInfoModel::clearData(bool clearMetaOnly)
447 beginResetModel();
449 m_textUnknown = QString("(%1)").arg(tr("Unknown"));
450 m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
452 if((!clearMetaOnly) && m_fullInfo)
454 m_fullInfo->techInfo().reset();
457 if(m_metaInfo)
459 m_metaInfo->reset();
460 m_metaInfo->setComment(tr("Encoded with LameXP"));
461 m_metaInfo->setPosition(m_offset ? UINT_MAX : 0);
464 if(m_fullInfo)
466 QString temp = QFileInfo(m_fullInfo->filePath()).baseName();
467 temp = temp.split("-", QString::SkipEmptyParts).last().trimmed();
468 m_metaInfo->setTitle(temp);
471 endResetModel();
474 Qt::ItemFlags MetaInfoModel::flags(const QModelIndex &index) const
476 return QAbstractTableModel::flags(index);
479 void MetaInfoModel::assignInfoFrom(const AudioFileModel &file)
481 beginResetModel();
482 const unsigned int position = m_metaInfo->position();
483 m_metaInfo->update(file.metaInfo(), true);
484 if(m_offset)
486 m_metaInfo->setTitle(QString());
487 m_metaInfo->setPosition(position ? UINT_MAX : 0);
488 m_metaInfo->setCover(QString(), false);
490 endResetModel();