OSDN Git Service

Bump version.
[lamexp/LameXP.git] / src / Model_MetaInfo.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2020 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!
10 //
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.
15 //
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.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Model_MetaInfo.h"
24 #include "Genres.h"
25
26 #include <QMessageBox>
27 #include <QInputDialog>
28 #include <QFileInfo>
29 #include <QDir>
30
31 #define MODEL_ROW_COUNT 12
32
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())
37
38 #define EXPAND(STR) QString(STR).leftJustified(96, ' ')
39
40 ////////////////////////////////////////////////////////////
41 // Constructor & Destructor
42 ////////////////////////////////////////////////////////////
43
44 MetaInfoModel::MetaInfoModel(AudioFileModel *file)
45 :
46         m_fullInfo(file),
47         m_metaInfo(&file->metaInfo()),
48         m_offset(0)
49 {
50         m_textUnknown = QString("(%1)").arg(tr("Unknown"));
51         m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
52 }
53
54 MetaInfoModel::MetaInfoModel(AudioFileModel_MetaInfo *metaInfo)
55 :
56         m_fullInfo(NULL),
57         m_metaInfo(metaInfo),
58         m_offset(6)
59 {
60         m_textUnknown = QString("(%1)").arg(tr("Unknown"));
61         m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
62 }
63
64 MetaInfoModel::~MetaInfoModel(void)
65 {
66 }
67
68 ////////////////////////////////////////////////////////////
69 // Public Functions
70 ////////////////////////////////////////////////////////////
71
72 int MetaInfoModel::columnCount(const QModelIndex &parent) const
73 {
74         return 2;
75 }
76
77 int MetaInfoModel::rowCount(const QModelIndex &parent) const
78 {
79         return MODEL_ROW_COUNT - m_offset;
80 }
81
82 QVariant MetaInfoModel::data(const QModelIndex &index, int role) const
83 {
84         if(role == Qt::DisplayRole)
85         {
86                 switch(index.row() + m_offset)
87                 {
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;
127                 }
128         }
129         else if(role == Qt::DecorationRole && index.column() == 0)
130         {
131                 switch(index.row() + m_offset)
132                 {
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;
172                 }
173         }
174         else if(role == Qt::TextColorRole && index.column() == 1)
175         {
176                 switch(index.row() + m_offset)
177                 {
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;
217                 }
218         }
219         else
220         {
221                 return QVariant();
222         }
223 }
224
225 QVariant MetaInfoModel::headerData(int section, Qt::Orientation orientation, int role) const
226 {
227         if(role == Qt::DisplayRole)
228         {
229                 if(orientation == Qt::Horizontal)
230                 {
231                         switch(section)
232                         {
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;
242                         }
243                 }
244                 else
245                 {
246                         return QVariant();
247                 }
248         }
249         else
250         {
251                 return QVariant();
252         }
253 }
254
255 bool MetaInfoModel::setData (const QModelIndex &index, const QVariant &value, int role)
256 {
257         if((role != Qt::EditRole) || (index.column() != 1) || !value.isValid())
258         {
259                 return false;
260         }
261
262         switch(index.row() + m_offset)
263         {
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;
299         }
300
301         emit dataChanged(index, index);
302         return true;
303 }
304
305 void MetaInfoModel::editItem(const QModelIndex &index, QWidget *parent)
306 {
307         bool ok = false;
308         int val = -1;
309         QStringList generes(QString("(%1)").arg(tr("Unspecified")));
310         QString temp;
311
312         QInputDialog input(parent);
313         input.setOkButtonText(tr("OK"));
314         input.setCancelButtonText(tr("Cancel"));
315         input.setTextEchoMode(QLineEdit::Normal);
316
317         switch(index.row() + m_offset)
318         {
319         case 5:
320                 input.setWindowTitle(tr("Edit Title"));
321                 input.setLabelText(EXPAND(tr("Please enter the title for this file:")));
322                 input.setTextValue(m_metaInfo->title());
323                 if(input.exec() != 0)
324                 {
325                         temp = input.textValue().simplified();
326                         if(temp.isEmpty())
327                         {
328                                 QMessageBox::warning(parent, tr("Edit Title"), tr("The title must not be empty. Generating title from file name!"));
329                                 temp = QFileInfo(m_fullInfo->filePath()).completeBaseName().replace("_", " ").simplified();
330                                 int index = temp.lastIndexOf(" - ");
331                                 if(index >= 0) temp = temp.mid(index + 3).trimmed();
332                         }
333                         beginResetModel();
334                         m_metaInfo->setTitle(temp.isEmpty() ? QString() : temp);
335                         endResetModel();
336                 }
337                 break;
338         case 6:
339                 input.setWindowTitle(tr("Edit Artist"));
340                 input.setLabelText(EXPAND(tr("Please enter the artist for this file:")));
341                 input.setTextValue(m_metaInfo->artist());
342                 if(input.exec() != 0)
343                 {
344                         temp = input.textValue().simplified();
345                         beginResetModel();
346                         m_metaInfo->setArtist(temp.isEmpty() ? QString() : temp);
347                         endResetModel();
348                 }
349                 break;
350         case 7:
351                 input.setWindowTitle(tr("Edit Album"));
352                 input.setLabelText(EXPAND(tr("Please enter the album for this file:")));
353                 input.setTextValue(m_metaInfo->album());
354                 if(input.exec() != 0)
355                 {
356                         temp = input.textValue().simplified();
357                         beginResetModel();
358                         m_metaInfo->setAlbum(temp.isEmpty() ? QString() : temp);
359                         endResetModel();
360                 }
361                 break;
362         case 8:
363                 input.setWindowTitle(tr("Edit Genre"));
364                 input.setLabelText(EXPAND(tr("Please enter the genre for this file:")));
365                 for(int i = 0; g_lamexp_generes[i]; i++) generes << g_lamexp_generes[i];
366                 input.setComboBoxItems(generes);
367                 input.setTextValue(m_metaInfo->genre());
368                 if(input.exec() != 0)
369                 {
370                         temp = input.textValue().simplified();
371                         beginResetModel();
372                         m_metaInfo->setGenre((temp.isEmpty() || !temp.compare(generes.at(0), Qt::CaseInsensitive)) ? QString() : temp);
373                         endResetModel();
374                 }
375                 break;
376         case 9:
377                 input.setWindowTitle(tr("Edit Year"));
378                 input.setLabelText(EXPAND(tr("Please enter the year for this file:")));
379                 input.setIntRange(0, 2100);
380                 input.setIntValue((m_metaInfo->year() ? m_metaInfo->year() : 1900));
381                 input.setIntStep(1);
382                 if(input.exec() != 0)
383                 {
384                         val = input.intValue();
385                         beginResetModel();
386                         m_metaInfo->setYear(val);
387                         endResetModel();
388                 }
389                 break;
390         case 10:
391                 if(!m_offset)
392                 {
393                         input.setWindowTitle(tr("Edit Position"));
394                         input.setLabelText(EXPAND(tr("Please enter the position (track no.) for this file:")));
395                         input.setIntRange(0, 99);
396                         input.setIntValue((m_metaInfo->position() ? m_metaInfo->position() : 1));
397                         input.setIntStep(1);
398                         if(input.exec() != 0)
399                         {
400                                 val = input.intValue();
401                                 beginResetModel();
402                                 m_metaInfo->setPosition(val);
403                                 endResetModel();
404                         }
405                 }
406                 else
407                 {
408                         QStringList options;
409                         options << tr("Unspecified (copy from source file)") << tr("Generate from list position");
410                         input.setWindowTitle(tr("Edit Position"));
411                         input.setLabelText(EXPAND(tr("Please enter the position (track no.) for this file:")));
412                         input.setComboBoxItems(options);
413                         input.setTextValue(options.value((m_metaInfo->position() == UINT_MAX) ? 1 : 0));
414                         if(input.exec() != 0)
415                         {
416                                 temp = input.textValue().simplified();
417                                 beginResetModel();
418                                 m_metaInfo->setPosition((options.indexOf(temp) == 1) ? UINT_MAX : 0);
419                                 endResetModel();
420                         }
421                 }
422                 break;
423         case 11:
424                 input.setWindowTitle(tr("Edit Comment"));
425                 input.setLabelText(EXPAND(tr("Please enter the comment for this file:")));
426                 input.setTextValue((m_metaInfo->comment().isEmpty() ? tr("Encoded with LameXP") : m_metaInfo->comment()));
427                 if(input.exec() != 0)
428                 {
429                         temp = input.textValue().simplified();
430                         beginResetModel();
431                         m_metaInfo->setComment(temp.isEmpty() ? QString() : temp);
432                         endResetModel();
433                 }
434                 break;
435         default:
436                 QMessageBox::warning(parent, tr("Not editable"), tr("Sorry, this property of the source file cannot be edited!"));
437                 break;
438         }
439 }
440
441 void MetaInfoModel::editArtwork(const QString &imagePath)
442 {
443         m_metaInfo->setCover(imagePath, false);
444 }
445
446 void MetaInfoModel::clearData(bool clearMetaOnly)
447 {
448         beginResetModel();
449
450         m_textUnknown = QString("(%1)").arg(tr("Unknown"));
451         m_textNotSpecified = QString("(%1)").arg(tr("Not Specified"));
452
453         if((!clearMetaOnly) && m_fullInfo)
454         {
455                 m_fullInfo->techInfo().reset();
456         }
457
458         if(m_metaInfo)
459         {
460                 m_metaInfo->reset();
461                 m_metaInfo->setComment(tr("Encoded with LameXP"));
462                 m_metaInfo->setPosition(m_offset ? UINT_MAX : 0);
463         }
464
465         if(m_fullInfo)
466         {
467                 QString temp = QFileInfo(m_fullInfo->filePath()).baseName();
468                 temp = temp.split("-", QString::SkipEmptyParts).last().trimmed();
469                 m_metaInfo->setTitle(temp);
470         }
471
472         endResetModel();
473 }
474
475 Qt::ItemFlags MetaInfoModel::flags(const QModelIndex &index) const
476 {
477         return QAbstractTableModel::flags(index);
478 }
479
480 void MetaInfoModel::assignInfoFrom(const AudioFileModel &file)
481 {
482         beginResetModel();
483         const unsigned int position = m_metaInfo->position();
484         m_metaInfo->update(file.metaInfo(), true);
485         if(m_offset)
486         {
487                 m_metaInfo->setTitle(QString());
488                 m_metaInfo->setPosition(position ? UINT_MAX : 0);
489                 m_metaInfo->setCover(QString(), false);
490         }
491         endResetModel();
492 }