File indexing completed on 2024-04-14 04:43:15

0001 /* AUDEX CDDA EXTRACTOR
0002  * SPDX-FileCopyrightText: Copyright (C) 2007 Marco Nelles
0003  * <https://userbase.kde.org/Audex>
0004  *
0005  * SPDX-License-Identifier: GPL-3.0-or-later
0006  */
0007 
0008 #include "profilemodel.h"
0009 
0010 #include <QIcon>
0011 
0012 ProfileModel::ProfileModel(QObject *parent)
0013 {
0014     Q_UNUSED(parent);
0015     revert();
0016 }
0017 
0018 ProfileModel::~ProfileModel()
0019 {
0020     clear();
0021 }
0022 
0023 int ProfileModel::rowCount(const QModelIndex &parent) const
0024 {
0025     Q_UNUSED(parent);
0026     return p_cache.count();
0027 }
0028 
0029 int ProfileModel::columnCount(const QModelIndex &parent) const
0030 {
0031     Q_UNUSED(parent);
0032     return PROFILE_MODEL_COLUMN_NUM;
0033 }
0034 
0035 QVariant ProfileModel::data(const QModelIndex &index, int role) const
0036 {
0037     if (!index.isValid())
0038         return QVariant();
0039 
0040     if ((index.row() < 0) || (index.row() >= p_cache.count()))
0041         return QVariant();
0042 
0043     if (role == Qt::TextAlignmentRole)
0044         return int(Qt::AlignLeft | Qt::AlignVCenter);
0045 
0046     if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
0047         switch (index.column()) {
0048         case PROFILE_MODEL_COLUMN_PROFILEINDEX_INDEX:
0049             return p_cache.at(index.row())[PROFILE_MODEL_PROFILEINDEX_KEY];
0050         case PROFILE_MODEL_COLUMN_NAME_INDEX:
0051             return p_cache.at(index.row())[PROFILE_MODEL_NAME_KEY];
0052         case PROFILE_MODEL_COLUMN_ICON_INDEX:
0053             return p_cache.at(index.row())[PROFILE_MODEL_ICON_KEY];
0054 
0055         case PROFILE_MODEL_COLUMN_ENCODER_SELECTED_INDEX:
0056             return p_cache.at(index.row())[PROFILE_MODEL_ENCODER_SELECTED_KEY];
0057 
0058         case PROFILE_MODEL_COLUMN_SCHEME_INDEX:
0059             return p_cache.at(index.row())[PROFILE_MODEL_SCHEME_KEY];
0060         case PROFILE_MODEL_COLUMN_FAT32COMPATIBLE_INDEX:
0061             return p_cache.at(index.row())[PROFILE_MODEL_FAT32COMPATIBLE_KEY];
0062         case PROFILE_MODEL_COLUMN_UNDERSCORE_INDEX:
0063             return p_cache.at(index.row())[PROFILE_MODEL_UNDERSCORE_KEY];
0064         case PROFILE_MODEL_COLUMN_2DIGITSTRACKNUM_INDEX:
0065             return p_cache.at(index.row())[PROFILE_MODEL_2DIGITSTRACKNUM_KEY];
0066         case PROFILE_MODEL_COLUMN_SC_INDEX:
0067             return p_cache.at(index.row())[PROFILE_MODEL_SC_KEY];
0068         case PROFILE_MODEL_COLUMN_SC_SCALE_INDEX:
0069             return p_cache.at(index.row())[PROFILE_MODEL_SC_SCALE_KEY];
0070         case PROFILE_MODEL_COLUMN_SC_SIZE_INDEX:
0071             return p_cache.at(index.row())[PROFILE_MODEL_SC_SIZE_KEY];
0072         case PROFILE_MODEL_COLUMN_SC_FORMAT_INDEX:
0073             return p_cache.at(index.row())[PROFILE_MODEL_SC_FORMAT_KEY];
0074         case PROFILE_MODEL_COLUMN_SC_NAME_INDEX:
0075             return p_cache.at(index.row())[PROFILE_MODEL_SC_NAME_KEY];
0076         case PROFILE_MODEL_COLUMN_PL_INDEX:
0077             return p_cache.at(index.row())[PROFILE_MODEL_PL_KEY];
0078         case PROFILE_MODEL_COLUMN_PL_FORMAT_INDEX:
0079             return p_cache.at(index.row())[PROFILE_MODEL_PL_FORMAT_KEY];
0080         case PROFILE_MODEL_COLUMN_PL_NAME_INDEX:
0081             return p_cache.at(index.row())[PROFILE_MODEL_PL_NAME_KEY];
0082         case PROFILE_MODEL_COLUMN_PL_ABS_FILE_PATH_INDEX:
0083             return p_cache.at(index.row())[PROFILE_MODEL_PL_ABS_FILE_PATH_KEY];
0084         case PROFILE_MODEL_COLUMN_PL_UTF8_INDEX:
0085             return p_cache.at(index.row())[PROFILE_MODEL_PL_UTF8_KEY];
0086         case PROFILE_MODEL_COLUMN_INF_INDEX:
0087             return p_cache.at(index.row())[PROFILE_MODEL_INF_KEY];
0088         case PROFILE_MODEL_COLUMN_INF_TEXT_INDEX:
0089             return p_cache.at(index.row())[PROFILE_MODEL_INF_TEXT_KEY];
0090         case PROFILE_MODEL_COLUMN_INF_NAME_INDEX:
0091             return p_cache.at(index.row())[PROFILE_MODEL_INF_NAME_KEY];
0092         case PROFILE_MODEL_COLUMN_INF_SUFFIX_INDEX:
0093             return p_cache.at(index.row())[PROFILE_MODEL_INF_SUFFIX_KEY];
0094         case PROFILE_MODEL_COLUMN_HL_INDEX:
0095             return p_cache.at(index.row())[PROFILE_MODEL_HL_KEY];
0096         case PROFILE_MODEL_COLUMN_HL_FORMAT_INDEX:
0097             return p_cache.at(index.row())[PROFILE_MODEL_HL_FORMAT_KEY];
0098         case PROFILE_MODEL_COLUMN_HL_NAME_INDEX:
0099             return p_cache.at(index.row())[PROFILE_MODEL_HL_NAME_KEY];
0100         case PROFILE_MODEL_COLUMN_CUE_INDEX:
0101             return p_cache.at(index.row())[PROFILE_MODEL_CUE_KEY];
0102         case PROFILE_MODEL_COLUMN_CUE_NAME_INDEX:
0103             return p_cache.at(index.row())[PROFILE_MODEL_CUE_NAME_KEY];
0104         case PROFILE_MODEL_COLUMN_CUE_ADD_MCN_AND_ISRC_INDEX:
0105             return p_cache.at(index.row())[PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY];
0106         case PROFILE_MODEL_COLUMN_LOG_INDEX:
0107             return p_cache.at(index.row())[PROFILE_MODEL_LOG_KEY];
0108         case PROFILE_MODEL_COLUMN_LOG_NAME_INDEX:
0109             return p_cache.at(index.row())[PROFILE_MODEL_LOG_NAME_KEY];
0110         case PROFILE_MODEL_COLUMN_LOG_WRITE_TIMESTAMPS_INDEX:
0111             return p_cache.at(index.row())[PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY];
0112         case PROFILE_MODEL_COLUMN_SF_INDEX:
0113             return p_cache.at(index.row())[PROFILE_MODEL_SF_KEY];
0114         case PROFILE_MODEL_COLUMN_SF_NAME_INDEX:
0115             return p_cache.at(index.row())[PROFILE_MODEL_SF_NAME_KEY];
0116         case PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_INDEX:
0117             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY];
0118         case PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_INDEX:
0119             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY];
0120         case PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_INDEX:
0121             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY];
0122         case PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_INDEX:
0123             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY];
0124         case PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_INDEX:
0125             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY];
0126         case PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_INDEX:
0127             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY];
0128         case PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_INDEX:
0129             return p_cache.at(index.row())[PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY];
0130         }
0131     }
0132 
0133     if (role == Qt::DecorationRole) {
0134         QString iconName(p_cache.at(index.row())[PROFILE_MODEL_ICON_KEY].toString());
0135 
0136         if (!iconName.isEmpty()) {
0137             QIcon icon = QIcon::fromTheme(iconName);
0138             if (icon.isNull() && QFile::exists(iconName))
0139                 icon = QIcon(iconName);
0140             if (!icon.isNull())
0141                 return icon;
0142         }
0143 
0144         return QIcon::fromTheme(DEFAULT_ICON);
0145     }
0146 
0147     return QVariant();
0148 }
0149 
0150 bool ProfileModel::setData(const QModelIndex &index, const QVariant &value, int role)
0151 {
0152     if (!index.isValid())
0153         return false;
0154 
0155     if ((index.row() < 0) || (index.row() >= p_cache.count()))
0156         return false;
0157 
0158     beginResetModel();
0159 
0160     if (role == Qt::EditRole) {
0161         if (!validateData(index, value))
0162             return false;
0163 
0164         switch (index.column()) {
0165         case PROFILE_MODEL_COLUMN_PROFILEINDEX_INDEX:
0166             p_cache[index.row()][PROFILE_MODEL_PROFILEINDEX_KEY] = value;
0167             break;
0168         case PROFILE_MODEL_COLUMN_NAME_INDEX:
0169             p_cache[index.row()][PROFILE_MODEL_NAME_KEY] = value;
0170             break;
0171         case PROFILE_MODEL_COLUMN_ICON_INDEX:
0172             p_cache[index.row()][PROFILE_MODEL_ICON_KEY] = value;
0173             break;
0174         case PROFILE_MODEL_COLUMN_ENCODER_SELECTED_INDEX:
0175             p_cache[index.row()][PROFILE_MODEL_ENCODER_SELECTED_KEY] = value;
0176             break;
0177         case PROFILE_MODEL_COLUMN_SCHEME_INDEX:
0178             p_cache[index.row()][PROFILE_MODEL_SCHEME_KEY] = value;
0179             break;
0180         case PROFILE_MODEL_COLUMN_FAT32COMPATIBLE_INDEX:
0181             p_cache[index.row()][PROFILE_MODEL_FAT32COMPATIBLE_KEY] = value;
0182             break;
0183         case PROFILE_MODEL_COLUMN_UNDERSCORE_INDEX:
0184             p_cache[index.row()][PROFILE_MODEL_UNDERSCORE_KEY] = value;
0185             break;
0186         case PROFILE_MODEL_COLUMN_2DIGITSTRACKNUM_INDEX:
0187             p_cache[index.row()][PROFILE_MODEL_2DIGITSTRACKNUM_KEY] = value;
0188             break;
0189 
0190         case PROFILE_MODEL_COLUMN_SC_INDEX:
0191             p_cache[index.row()][PROFILE_MODEL_SC_KEY] = value;
0192             break;
0193         case PROFILE_MODEL_COLUMN_SC_SCALE_INDEX:
0194             p_cache[index.row()][PROFILE_MODEL_SC_SCALE_KEY] = value;
0195             break;
0196         case PROFILE_MODEL_COLUMN_SC_SIZE_INDEX:
0197             p_cache[index.row()][PROFILE_MODEL_SC_SIZE_KEY] = value;
0198             break;
0199         case PROFILE_MODEL_COLUMN_SC_FORMAT_INDEX:
0200             p_cache[index.row()][PROFILE_MODEL_SC_FORMAT_KEY] = value;
0201             break;
0202         case PROFILE_MODEL_COLUMN_SC_NAME_INDEX:
0203             p_cache[index.row()][PROFILE_MODEL_SC_NAME_KEY] = value;
0204             break;
0205 
0206         case PROFILE_MODEL_COLUMN_PL_INDEX:
0207             p_cache[index.row()][PROFILE_MODEL_PL_KEY] = value;
0208             break;
0209         case PROFILE_MODEL_COLUMN_PL_FORMAT_INDEX:
0210             p_cache[index.row()][PROFILE_MODEL_PL_FORMAT_KEY] = value;
0211             break;
0212         case PROFILE_MODEL_COLUMN_PL_NAME_INDEX:
0213             p_cache[index.row()][PROFILE_MODEL_PL_NAME_KEY] = value;
0214             break;
0215         case PROFILE_MODEL_COLUMN_PL_ABS_FILE_PATH_INDEX:
0216             p_cache[index.row()][PROFILE_MODEL_PL_ABS_FILE_PATH_KEY] = value;
0217             break;
0218         case PROFILE_MODEL_COLUMN_PL_UTF8_INDEX:
0219             p_cache[index.row()][PROFILE_MODEL_PL_UTF8_KEY] = value;
0220             break;
0221 
0222         case PROFILE_MODEL_COLUMN_INF_INDEX:
0223             p_cache[index.row()][PROFILE_MODEL_INF_KEY] = value;
0224             break;
0225         case PROFILE_MODEL_COLUMN_INF_TEXT_INDEX:
0226             p_cache[index.row()][PROFILE_MODEL_INF_TEXT_KEY] = value;
0227             break;
0228         case PROFILE_MODEL_COLUMN_INF_NAME_INDEX:
0229             p_cache[index.row()][PROFILE_MODEL_INF_NAME_KEY] = value;
0230             break;
0231         case PROFILE_MODEL_COLUMN_INF_SUFFIX_INDEX:
0232             p_cache[index.row()][PROFILE_MODEL_INF_SUFFIX_KEY] = value;
0233             break;
0234 
0235         case PROFILE_MODEL_COLUMN_HL_INDEX:
0236             p_cache[index.row()][PROFILE_MODEL_HL_KEY] = value;
0237             break;
0238         case PROFILE_MODEL_COLUMN_HL_FORMAT_INDEX:
0239             p_cache[index.row()][PROFILE_MODEL_HL_FORMAT_KEY] = value;
0240             break;
0241         case PROFILE_MODEL_COLUMN_HL_NAME_INDEX:
0242             p_cache[index.row()][PROFILE_MODEL_HL_NAME_KEY] = value;
0243             break;
0244 
0245         case PROFILE_MODEL_COLUMN_CUE_INDEX:
0246             p_cache[index.row()][PROFILE_MODEL_CUE_KEY] = value;
0247             break;
0248         case PROFILE_MODEL_COLUMN_CUE_NAME_INDEX:
0249             p_cache[index.row()][PROFILE_MODEL_CUE_NAME_KEY] = value;
0250             break;
0251         case PROFILE_MODEL_COLUMN_CUE_ADD_MCN_AND_ISRC_INDEX:
0252             p_cache[index.row()][PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY] = value;
0253             break;
0254 
0255         case PROFILE_MODEL_COLUMN_LOG_INDEX:
0256             p_cache[index.row()][PROFILE_MODEL_LOG_KEY] = value;
0257             break;
0258         case PROFILE_MODEL_COLUMN_LOG_NAME_INDEX:
0259             p_cache[index.row()][PROFILE_MODEL_LOG_NAME_KEY] = value;
0260             break;
0261         case PROFILE_MODEL_COLUMN_LOG_WRITE_TIMESTAMPS_INDEX:
0262             p_cache[index.row()][PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY] = value;
0263             break;
0264 
0265         case PROFILE_MODEL_COLUMN_SF_INDEX:
0266             p_cache[index.row()][PROFILE_MODEL_SF_KEY] = value;
0267             break;
0268         case PROFILE_MODEL_COLUMN_SF_NAME_INDEX:
0269             p_cache[index.row()][PROFILE_MODEL_SF_NAME_KEY] = value;
0270             break;
0271 
0272         case PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_INDEX:
0273             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY] = value;
0274             break;
0275         case PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_INDEX:
0276             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY] = value;
0277             break;
0278         case PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_INDEX:
0279             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY] = value;
0280             break;
0281         case PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_INDEX:
0282             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY] = value;
0283             break;
0284         case PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_INDEX:
0285             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY] = value;
0286             break;
0287         case PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_INDEX:
0288             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY] = value;
0289             break;
0290         case PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_INDEX:
0291             p_cache[index.row()][PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY] = value;
0292             break;
0293 
0294         default:
0295             break;
0296         }
0297         return true;
0298     }
0299 
0300     endResetModel();
0301 
0302     p_error = Error(i18n("Unknown error. No index found in profile model."), i18n("This is an internal error. Please report."), Error::ERROR, this);
0303 
0304     return false;
0305 }
0306 
0307 bool ProfileModel::removeRows(int row, int count, const QModelIndex &parent)
0308 {
0309     Q_UNUSED(parent);
0310 
0311     if ((row < 0) || (row >= p_cache.count()))
0312         return false;
0313 
0314     if (count <= 0)
0315         return false;
0316 
0317     beginResetModel();
0318     int c;
0319     if (row + count > p_cache.count())
0320         c = p_cache.count();
0321     else
0322         c = row + count;
0323 
0324     for (int i = row; i < c; ++i)
0325         p_cache.removeAt(i);
0326 
0327     endResetModel();
0328 
0329     // update current profile index. maybe current has been deleted?
0330     setCurrentProfileIndex(p_current_profile_index);
0331 
0332     Q_EMIT profilesRemovedOrInserted();
0333 
0334     return true;
0335 }
0336 
0337 bool ProfileModel::insertRows(int row, int count, const QModelIndex &parent)
0338 {
0339     Q_UNUSED(parent);
0340 
0341     if ((row < 0) || (row > p_cache.count()))
0342         return false;
0343 
0344     if (count <= 0)
0345         return false;
0346 
0347     bool wasEmpty = (p_cache.count() == 0);
0348 
0349     beginResetModel();
0350 
0351     if (row == p_cache.count())
0352         for (int i = 0; i < count; ++i)
0353             p_cache.append(p_new_profile());
0354     else
0355         for (int i = row; i < count; ++i)
0356             p_cache.insert(i, p_new_profile());
0357 
0358     endResetModel();
0359 
0360     if (wasEmpty) {
0361         // set first profile as current index
0362         setCurrentProfileIndex(p_cache.at(0)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt());
0363     }
0364 
0365     Q_EMIT profilesRemovedOrInserted();
0366 
0367     return true;
0368 }
0369 
0370 bool ProfileModel::validateData(const QModelIndex &index, const QVariant &value)
0371 {
0372     switch (index.column()) {
0373     case PROFILE_MODEL_COLUMN_ICON_INDEX:
0374         break;
0375 
0376     case PROFILE_MODEL_COLUMN_NAME_INDEX: {
0377         if (value.toString().isEmpty()) {
0378             p_error = Error(i18n("Profile name must not be empty."), i18n("You have given no name for the profile. Please set one."), Error::ERROR, this);
0379             return false;
0380         }
0381         // check if name is unique
0382         bool found = false;
0383         for (int i = 0; i < p_cache.count(); ++i) {
0384             if (i == index.row())
0385                 continue;
0386             if (value.toString() == p_cache.at(i)[PROFILE_MODEL_NAME_KEY].toString()) {
0387                 found = true;
0388                 break;
0389             }
0390         }
0391         if (found) {
0392             p_error = Error(i18n("Profile name already exists."),
0393                             i18n("Your profile name %1 already exists in the set of profiles. Please choose a unique one.", value.toString()),
0394                             Error::ERROR,
0395                             this);
0396             return false;
0397         }
0398     }
0399 
0400     break;
0401 
0402     case PROFILE_MODEL_COLUMN_ENCODER_SELECTED_INDEX:
0403         if (value.toInt() == -1) {
0404             p_error = Error(i18n("Profile encoder is not defined."), i18n("You have given no encoder for the profile. Please set one."), Error::ERROR, this);
0405             return false;
0406         }
0407         break;
0408 
0409     case PROFILE_MODEL_COLUMN_SCHEME_INDEX:
0410         if (value.toString().isEmpty()) {
0411             p_error = Error(i18n("Profile filename scheme is not defined."),
0412                             i18n("You have given no filename scheme for the profile. Please set one."),
0413                             Error::ERROR,
0414                             this);
0415             return false;
0416         }
0417         break;
0418 
0419     case PROFILE_MODEL_COLUMN_FAT32COMPATIBLE_INDEX:
0420         break;
0421 
0422     case PROFILE_MODEL_COLUMN_UNDERSCORE_INDEX:
0423         break;
0424 
0425     case PROFILE_MODEL_COLUMN_2DIGITSTRACKNUM_INDEX:
0426         break;
0427 
0428     case PROFILE_MODEL_COLUMN_SC_INDEX:
0429         break;
0430 
0431     case PROFILE_MODEL_COLUMN_SC_SCALE_INDEX:
0432         break;
0433 
0434     case PROFILE_MODEL_COLUMN_SC_SIZE_INDEX:
0435         break;
0436 
0437     case PROFILE_MODEL_COLUMN_SC_FORMAT_INDEX:
0438         if ((value.toString() != "JPEG") && (value.toString() != "JPG") && (value.toString() != "PNG") && (value.toString() != "TIFF")
0439             && (value.toString() != "TIF") && (value.toString() != "BMP")) {
0440             p_error = Error(i18n("The image file format is unknown."),
0441                             i18n("Your given image file format is unknown. Please choose on of these formats: JPEG, PNG, TIFF or BMP."),
0442                             Error::ERROR,
0443                             this);
0444             return false;
0445         }
0446         break;
0447 
0448     case PROFILE_MODEL_COLUMN_SC_NAME_INDEX:
0449         if (value.toString().isEmpty()) {
0450             p_error = Error(i18n("Cover name must not be empty."), i18n("You have given no name for the cover. Please set one."), Error::ERROR, this);
0451             return false;
0452         }
0453         break;
0454 
0455     case PROFILE_MODEL_COLUMN_PL_INDEX:
0456         break;
0457 
0458     case PROFILE_MODEL_COLUMN_PL_FORMAT_INDEX:
0459         if ((value.toString() != "M3U") && (value.toString() != "PLS") && (value.toString() != "XSPF")) {
0460             p_error = Error(i18n("The playlist file format is unknown."),
0461                             i18n("Your given playlist file format is unknown. Please choose on of these formats: M3U, PLS or XSPF."),
0462                             Error::ERROR,
0463                             this);
0464             return false;
0465         }
0466         break;
0467 
0468     case PROFILE_MODEL_COLUMN_PL_NAME_INDEX:
0469         if (value.toString().isEmpty()) {
0470             p_error = Error(i18n("Playlist name must not be empty."), i18n("You have given no name for the playlist. Please set one."), Error::ERROR, this);
0471             return false;
0472         }
0473         break;
0474 
0475     case PROFILE_MODEL_COLUMN_PL_ABS_FILE_PATH_INDEX:
0476         break;
0477 
0478     case PROFILE_MODEL_COLUMN_PL_UTF8_INDEX:
0479         break;
0480 
0481     case PROFILE_MODEL_COLUMN_INF_INDEX:
0482         break;
0483 
0484     case PROFILE_MODEL_COLUMN_INF_TEXT_INDEX:
0485         break;
0486 
0487     case PROFILE_MODEL_COLUMN_INF_NAME_INDEX:
0488         if (value.toString().isEmpty()) {
0489             p_error =
0490                 Error(i18n("Info text name must not be empty."), i18n("You have given no name for the info text file. Please set one."), Error::ERROR, this);
0491             return false;
0492         }
0493         break;
0494 
0495     case PROFILE_MODEL_COLUMN_INF_SUFFIX_INDEX:
0496         if (value.toString().isEmpty()) {
0497             p_error = Error(i18n("Info text file name suffix must not be empty."),
0498                             i18n("You have given no suffix for the info text file. Please set one."),
0499                             Error::ERROR,
0500                             this);
0501             return false;
0502         }
0503         break;
0504 
0505     case PROFILE_MODEL_COLUMN_HL_INDEX:
0506         break;
0507     case PROFILE_MODEL_COLUMN_HL_FORMAT_INDEX:
0508         if ((value.toString() != "SFV") && (value.toString() != "MD5") && (value.toString() != "SHA-256")) {
0509             p_error = Error(i18n("The hashlist file format is unknown."),
0510                             i18n("Your given hashlist file format is unknown. Please choose one of these formats: SFV, MD5, SHA-256."),
0511                             Error::ERROR,
0512                             this);
0513             return false;
0514         }
0515         break;
0516 
0517     case PROFILE_MODEL_COLUMN_HL_NAME_INDEX:
0518         if (value.toString().isEmpty()) {
0519             p_error = Error(i18n("Hashlist name must not be empty."), i18n("You have given no name for the hashlist. Please set one."), Error::ERROR, this);
0520             return false;
0521         }
0522         break;
0523 
0524     case PROFILE_MODEL_COLUMN_CUE_INDEX:
0525         break;
0526 
0527     case PROFILE_MODEL_COLUMN_CUE_NAME_INDEX:
0528         if (value.toString().isEmpty()) {
0529             p_error =
0530                 Error(i18n("Cue filename name must not be empty."), i18n("You have given no name for the cue sheet. Please set one."), Error::ERROR, this);
0531             return false;
0532         }
0533         break;
0534 
0535     case PROFILE_MODEL_COLUMN_CUE_ADD_MCN_AND_ISRC_INDEX:
0536         break;
0537 
0538     case PROFILE_MODEL_COLUMN_LOG_INDEX:
0539         break;
0540 
0541     case PROFILE_MODEL_COLUMN_LOG_NAME_INDEX:
0542         if (value.toString().isEmpty()) {
0543             p_error = Error(i18n("Log filename name must not be empty."), i18n("You have given no name for the log file. Please set one."), Error::ERROR, this);
0544             return false;
0545         }
0546         break;
0547 
0548     case PROFILE_MODEL_COLUMN_LOG_WRITE_TIMESTAMPS_INDEX:
0549         break;
0550 
0551     case PROFILE_MODEL_COLUMN_SF_INDEX:
0552         break;
0553 
0554     case PROFILE_MODEL_COLUMN_SF_NAME_INDEX:
0555         if (value.toString().isEmpty()) {
0556             p_error =
0557                 Error(i18n("Filename name must not be empty."), i18n("You have given no name for the single audio file. Please set one."), Error::ERROR, this);
0558             return false;
0559         }
0560         break;
0561 
0562     case PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_INDEX:
0563         break;
0564 
0565     case PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_INDEX:
0566         break;
0567 
0568     case PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_INDEX:
0569         break;
0570 
0571     case PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_INDEX:
0572         break;
0573 
0574     case PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_INDEX:
0575         break;
0576 
0577     case PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_INDEX:
0578         break;
0579 
0580     case PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_INDEX:
0581         break;
0582 
0583     default:
0584         return false;
0585     }
0586 
0587     return true;
0588 }
0589 
0590 void ProfileModel::setCurrentProfileIndex(int profile_index)
0591 {
0592     int pi = profile_index;
0593     if (p_cache.count() == 0) {
0594         pi = -1;
0595     } else if (!indexExists(profile_index)) {
0596         // set first profile as current index
0597         pi = p_cache.at(0)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt();
0598     }
0599     if (pi != p_current_profile_index) {
0600         p_current_profile_index = pi;
0601         KConfig config;
0602         KConfigGroup profilesGroup(&config, "Profiles");
0603         profilesGroup.writeEntry("Standard", pi);
0604         profilesGroup.config()->sync();
0605         Q_EMIT currentProfileIndexChanged(pi);
0606     }
0607 }
0608 
0609 int ProfileModel::setRowAsCurrentProfileIndex(int row)
0610 {
0611     int i = p_cache.at(row).value(PROFILE_MODEL_PROFILEINDEX_KEY, -1).toInt();
0612     setCurrentProfileIndex(i);
0613     return i;
0614 }
0615 
0616 int ProfileModel::currentProfileIndex() const
0617 {
0618     if (p_cache.count() == 0)
0619         return -1;
0620     return p_current_profile_index;
0621 }
0622 
0623 int ProfileModel::currentProfileRow() const
0624 {
0625     return getRowByIndex(p_current_profile_index);
0626 }
0627 
0628 int ProfileModel::getRowByIndex(int profile_index) const
0629 {
0630     for (int i = 0; i < p_cache.count(); ++i)
0631         if (profile_index == p_cache.at(i)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt())
0632             return i;
0633     return -1;
0634 }
0635 
0636 void ProfileModel::clear()
0637 {
0638     p_cache.clear();
0639     p_current_profile_index = -1;
0640 }
0641 
0642 bool ProfileModel::nameExists(const QString &name) const
0643 {
0644     for (int j = 0; j < p_cache.count(); ++j)
0645         if (name == p_cache.at(j)[PROFILE_MODEL_NAME_KEY].toString())
0646             return true;
0647 
0648     return false;
0649 }
0650 
0651 bool ProfileModel::indexExists(int profile_index) const
0652 {
0653     for (int j = 0; j < p_cache.count(); ++j)
0654         if (profile_index == p_cache.at(j)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt())
0655             return true;
0656 
0657     return false;
0658 }
0659 
0660 int ProfileModel::getNewIndex() const
0661 {
0662     QSet<int> indexes;
0663     QList<Profile>::ConstIterator it(p_cache.begin()), end(p_cache.end());
0664 
0665     for (; it != end; ++it)
0666         indexes.insert((*it)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt());
0667 
0668     for (int i = 0; i < INT_MAX; ++i)
0669         if (!indexes.contains(i))
0670             return i;
0671 
0672     return -1;
0673 }
0674 
0675 static bool lessThan(const Profile &p1, const Profile &p2)
0676 {
0677     return (QString::localeAwareCompare(p1[PROFILE_MODEL_NAME_KEY].toString(), p2[PROFILE_MODEL_NAME_KEY].toString()) < 0);
0678 }
0679 
0680 void ProfileModel::sortItems()
0681 {
0682     beginResetModel();
0683     std::sort(p_cache.begin(), p_cache.end(), lessThan);
0684     endResetModel();
0685     Q_EMIT profilesRemovedOrInserted();
0686 }
0687 
0688 void ProfileModel::autoCreate()
0689 {
0690     bool flag = false;
0691 
0692     bool wasEmpty = (p_cache.count() == 0);
0693 
0694     if (EncoderAssistant::available(EncoderAssistant::LAME) && (!nameExists(EncoderAssistant::name(EncoderAssistant::LAME)))) {
0695         Profile p = p_new_profile();
0696         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::LAME);
0697         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::LAME);
0698         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::LAME;
0699         p[PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY] = EncoderAssistant::stdParameters(EncoderAssistant::LAME).toString();
0700         p_cache.append(p);
0701         flag = true;
0702     }
0703 
0704     if (EncoderAssistant::available(EncoderAssistant::OGGENC) && (!nameExists(EncoderAssistant::name(EncoderAssistant::OGGENC)))) {
0705         Profile p = p_new_profile();
0706         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::OGGENC);
0707         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::OGGENC);
0708         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::OGGENC;
0709         p[PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY] = EncoderAssistant::stdParameters(EncoderAssistant::OGGENC).toString();
0710         p_cache.append(p);
0711         flag = true;
0712     }
0713 
0714     if (EncoderAssistant::available(EncoderAssistant::OPUSENC) && !nameExists(EncoderAssistant::name(EncoderAssistant::OPUSENC))) {
0715         Profile p = p_new_profile();
0716         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::OPUSENC);
0717         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::OPUSENC);
0718         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::OPUSENC;
0719         p[PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY] = EncoderAssistant::stdParameters(EncoderAssistant::OPUSENC).toString();
0720         p_cache.append(p);
0721         flag = true;
0722     }
0723 
0724     if (EncoderAssistant::available(EncoderAssistant::FLAC) && !nameExists(EncoderAssistant::name(EncoderAssistant::FLAC))) {
0725         Profile p = p_new_profile();
0726         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::FLAC);
0727         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::FLAC);
0728         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::FLAC;
0729         p[PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY] = EncoderAssistant::stdParameters(EncoderAssistant::FLAC).toString();
0730         p_cache.append(p);
0731         flag = true;
0732     }
0733 
0734     if (EncoderAssistant::available(EncoderAssistant::FAAC) && !nameExists(EncoderAssistant::name(EncoderAssistant::FAAC))) {
0735         Profile p = p_new_profile();
0736         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::FAAC);
0737         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::FAAC);
0738         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::FAAC;
0739         p[PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY] = EncoderAssistant::stdParameters(EncoderAssistant::FAAC).toString();
0740         p_cache.append(p);
0741         flag = true;
0742     }
0743 
0744     if (EncoderAssistant::available(EncoderAssistant::WAVE) && !nameExists(EncoderAssistant::name(EncoderAssistant::WAVE))) {
0745         Profile p = p_new_profile();
0746         p[PROFILE_MODEL_NAME_KEY] = EncoderAssistant::name(EncoderAssistant::WAVE);
0747         p[PROFILE_MODEL_ICON_KEY] = EncoderAssistant::icon(EncoderAssistant::WAVE);
0748         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = (int)EncoderAssistant::WAVE;
0749         p_cache.append(p);
0750         flag = true;
0751     }
0752 
0753     if (flag) {
0754         sortItems();
0755         if (wasEmpty) {
0756             // set first profile as current index
0757             setCurrentProfileIndex(p_cache.at(0)[PROFILE_MODEL_PROFILEINDEX_KEY].toInt());
0758         }
0759     }
0760 
0761     commit();
0762 }
0763 
0764 EncoderAssistant::Encoder ProfileModel::getSelectedEncoderFromCurrentIndex()
0765 {
0766     return (EncoderAssistant::Encoder)data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_SELECTED_INDEX)).toInt();
0767 }
0768 
0769 const Parameters ProfileModel::getSelectedEncoderParametersFromCurrentIndex()
0770 {
0771     Parameters parameters;
0772 
0773     EncoderAssistant::Encoder encoder = getSelectedEncoderFromCurrentIndex();
0774     // what parameters does the encoder start with?
0775     switch (encoder) {
0776     case EncoderAssistant::LAME:
0777         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_INDEX)).toString());
0778         break;
0779     case EncoderAssistant::OGGENC:
0780         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_INDEX)).toString());
0781         break;
0782     case EncoderAssistant::OPUSENC:
0783         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_INDEX)).toString());
0784         break;
0785     case EncoderAssistant::FLAC:
0786         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_INDEX)).toString());
0787         break;
0788     case EncoderAssistant::FAAC:
0789         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_INDEX)).toString());
0790         break;
0791     case EncoderAssistant::WAVE:
0792         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_INDEX)).toString());
0793         break;
0794     case EncoderAssistant::CUSTOM:
0795         parameters.fromString(data(index(currentProfileRow(), PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_INDEX)).toString());
0796         break;
0797     case EncoderAssistant::NUM:;
0798     }
0799 
0800     return parameters;
0801 }
0802 
0803 const QString ProfileModel::getSelectedEncoderSchemeFromCurrentIndex()
0804 {
0805     EncoderAssistant::Encoder encoder = getSelectedEncoderFromCurrentIndex();
0806     Parameters parameters(getSelectedEncoderParametersFromCurrentIndex());
0807 
0808     return EncoderAssistant::scheme(encoder, parameters);
0809 }
0810 
0811 const QString ProfileModel::getSelectedEncoderSuffixFromCurrentIndex()
0812 {
0813     EncoderAssistant::Encoder encoder = getSelectedEncoderFromCurrentIndex();
0814     Parameters parameters(getSelectedEncoderParametersFromCurrentIndex());
0815 
0816     switch (encoder) {
0817     case EncoderAssistant::LAME:
0818         return parameters.value(ENCODER_LAME_SUFFIX_KEY, ENCODER_LAME_SUFFIX).toString();
0819     case EncoderAssistant::OGGENC:
0820         return parameters.value(ENCODER_OGGENC_SUFFIX_KEY, ENCODER_OGGENC_SUFFIX).toString();
0821     case EncoderAssistant::OPUSENC:
0822         return parameters.value(ENCODER_OPUSENC_SUFFIX_KEY, ENCODER_OPUSENC_SUFFIX).toString();
0823     case EncoderAssistant::FLAC:
0824         return parameters.value(ENCODER_FLAC_SUFFIX_KEY, ENCODER_FLAC_SUFFIX).toString();
0825     case EncoderAssistant::FAAC:
0826         return parameters.value(ENCODER_FAAC_SUFFIX_KEY, ENCODER_FAAC_SUFFIX).toString();
0827     case EncoderAssistant::WAVE:
0828         return parameters.value(ENCODER_WAVE_SUFFIX_KEY, ENCODER_WAVE_SUFFIX).toString();
0829     case EncoderAssistant::CUSTOM:
0830         return parameters.value(ENCODER_CUSTOM_SUFFIX_KEY, ENCODER_CUSTOM_SUFFIX).toString();
0831     case EncoderAssistant::NUM:
0832         return "";
0833     }
0834 
0835     return "";
0836 }
0837 
0838 const QString ProfileModel::getSelectedEncoderNameAndVersion()
0839 {
0840     EncoderAssistant::Encoder encoder = getSelectedEncoderFromCurrentIndex();
0841 
0842     return QString("%1 %2").arg(EncoderAssistant::encoderName(encoder), EncoderAssistant::version(encoder));
0843 }
0844 
0845 bool ProfileModel::isSelectedEncoderWithEmbedCover()
0846 {
0847     EncoderAssistant::Encoder encoder = getSelectedEncoderFromCurrentIndex();
0848     Parameters parameters(getSelectedEncoderParametersFromCurrentIndex());
0849 
0850     switch (encoder) {
0851     case EncoderAssistant::LAME:
0852         return parameters.value(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER).toBool();
0853     case EncoderAssistant::OGGENC:
0854         return false;
0855     case EncoderAssistant::OPUSENC:
0856         return parameters.value(ENCODER_OPUSENC_EMBED_COVER_KEY, ENCODER_OPUSENC_EMBED_COVER).toBool();
0857     case EncoderAssistant::FLAC:
0858         return parameters.value(ENCODER_FLAC_EMBED_COVER_KEY, ENCODER_FLAC_EMBED_COVER).toBool();
0859     case EncoderAssistant::FAAC:
0860         return parameters.value(ENCODER_FAAC_EMBED_COVER_KEY, ENCODER_FAAC_EMBED_COVER).toBool();
0861     case EncoderAssistant::WAVE:
0862         return false;
0863     case EncoderAssistant::CUSTOM:
0864         return true;
0865     case EncoderAssistant::NUM:
0866         return false;
0867     }
0868 
0869     return false;
0870 }
0871 
0872 Error ProfileModel::lastError() const
0873 {
0874     return p_error;
0875 }
0876 
0877 void ProfileModel::commit()
0878 {
0879     KConfig config;
0880     p_save(&config);
0881 }
0882 
0883 const Profile ProfileModel::p_new_profile()
0884 {
0885     Profile p;
0886 
0887     p[PROFILE_MODEL_PROFILEINDEX_KEY] = getNewIndex();
0888     p[PROFILE_MODEL_NAME_KEY] = DEFAULT_NAME;
0889 
0890     p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = DEFAULT_ENCODER_SELECTED;
0891 
0892     p[PROFILE_MODEL_SCHEME_KEY] = DEFAULT_SCHEME;
0893 
0894     p[PROFILE_MODEL_FAT32COMPATIBLE_KEY] = DEFAULT_FAT32;
0895     p[PROFILE_MODEL_UNDERSCORE_KEY] = DEFAULT_UNDERSCORE;
0896     p[PROFILE_MODEL_2DIGITSTRACKNUM_KEY] = DEFAULT_2DIGITSTRACKNUM;
0897 
0898     p[PROFILE_MODEL_SC_KEY] = DEFAULT_SC;
0899     p[PROFILE_MODEL_SC_SCALE_KEY] = DEFAULT_SC_SCALE;
0900     p[PROFILE_MODEL_SC_SIZE_KEY] = DEFAULT_SC_SIZE;
0901     p[PROFILE_MODEL_SC_FORMAT_KEY] = DEFAULT_SC_FORMAT;
0902     p[PROFILE_MODEL_SC_NAME_KEY] = DEFAULT_SC_NAME;
0903     p[PROFILE_MODEL_PL_KEY] = DEFAULT_PL;
0904     p[PROFILE_MODEL_PL_FORMAT_KEY] = DEFAULT_PL_FORMAT;
0905     p[PROFILE_MODEL_PL_NAME_KEY] = DEFAULT_PL_NAME;
0906     p[PROFILE_MODEL_PL_ABS_FILE_PATH_KEY] = DEFAULT_PL_ABS_FILE_PATH;
0907     p[PROFILE_MODEL_PL_UTF8_KEY] = DEFAULT_PL_UTF8;
0908     p[PROFILE_MODEL_INF_KEY] = DEFAULT_INF;
0909     p[PROFILE_MODEL_INF_TEXT_KEY] = DEFAULT_INF_TEXT;
0910     p[PROFILE_MODEL_INF_NAME_KEY] = DEFAULT_INF_NAME;
0911     p[PROFILE_MODEL_INF_SUFFIX_KEY] = DEFAULT_INF_SUFFIX;
0912     p[PROFILE_MODEL_HL_KEY] = DEFAULT_HL;
0913     p[PROFILE_MODEL_HL_FORMAT_KEY] = DEFAULT_HL_FORMAT;
0914     p[PROFILE_MODEL_HL_NAME_KEY] = DEFAULT_HL_NAME;
0915     p[PROFILE_MODEL_CUE_KEY] = DEFAULT_CUE;
0916     p[PROFILE_MODEL_CUE_NAME_KEY] = DEFAULT_CUE_NAME;
0917     p[PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY] = DEFAULT_CUE_ADD_MCN_AND_ISRC;
0918     p[PROFILE_MODEL_LOG_KEY] = DEFAULT_LOG;
0919     p[PROFILE_MODEL_LOG_NAME_KEY] = DEFAULT_LOG_NAME;
0920     p[PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY] = DEFAULT_LOG_WRITE_TIMESTAMPS;
0921     p[PROFILE_MODEL_SF_KEY] = DEFAULT_SF;
0922     p[PROFILE_MODEL_SF_NAME_KEY] = DEFAULT_SF_NAME;
0923 
0924     p[PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0925     p[PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0926     p[PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0927     p[PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0928     p[PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0929     p[PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0930     p[PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY] = DEFAULT_ENCODER_PARAMETERS;
0931 
0932     return p;
0933 }
0934 
0935 void ProfileModel::p_new_name(QString &name)
0936 {
0937     for (int j = 0; j < p_cache.count(); ++j)
0938         if (name == p_cache.at(j)[PROFILE_MODEL_NAME_KEY].toString()) {
0939             name = QString("%1 (%2)").arg(name).arg(i18n("Copy"));
0940             p_new_name(name);
0941             return;
0942         }
0943 }
0944 
0945 void ProfileModel::revert()
0946 {
0947     clear();
0948     KConfig config;
0949     p_load(&config);
0950 }
0951 
0952 int ProfileModel::copy(const int profileRow)
0953 {
0954     beginResetModel();
0955     if ((profileRow < 0) || (profileRow >= rowCount()))
0956         return -1;
0957 
0958     int key = getNewIndex();
0959     Profile p = p_cache[profileRow];
0960 
0961     QString name = p_cache[profileRow][PROFILE_MODEL_NAME_KEY].toString();
0962     p_new_name(name);
0963     p[PROFILE_MODEL_NAME_KEY] = name;
0964     p[PROFILE_MODEL_PROFILEINDEX_KEY] = key;
0965     p_cache.append(p);
0966 
0967     endResetModel();
0968     Q_EMIT profilesRemovedOrInserted();
0969 
0970     return key;
0971 }
0972 
0973 bool ProfileModel::saveProfilesToFile(const QString &filename)
0974 {
0975     KConfig config(filename);
0976     p_save(&config);
0977     return true;
0978 }
0979 
0980 bool ProfileModel::loadProfilesFromFile(const QString &filename)
0981 {
0982     KConfig config(filename);
0983     beginResetModel();
0984     p_load(&config);
0985     endResetModel();
0986     commit();
0987     return true;
0988 }
0989 
0990 void ProfileModel::p_save(KConfig *config)
0991 {
0992     KConfigGroup profilesGroup(config, "Profiles");
0993     profilesGroup.deleteGroup();
0994     profilesGroup.writeEntry("Standard", p_current_profile_index);
0995     profilesGroup.writeEntry("Count", p_cache.count());
0996 
0997     for (int i = 0; i < p_cache.count(); ++i) {
0998         KConfigGroup subGroup(&profilesGroup, QString("Profile %1").arg(i));
0999 
1000         subGroup.writeEntry(PROFILE_MODEL_PROFILEINDEX_KEY, p_cache[i][PROFILE_MODEL_PROFILEINDEX_KEY]);
1001         subGroup.writeEntry(PROFILE_MODEL_NAME_KEY, p_cache[i][PROFILE_MODEL_NAME_KEY]);
1002         subGroup.writeEntry(PROFILE_MODEL_ICON_KEY, p_cache[i][PROFILE_MODEL_ICON_KEY]);
1003 
1004         subGroup.writeEntry(PROFILE_MODEL_ENCODER_SELECTED_KEY, p_cache[i][PROFILE_MODEL_ENCODER_SELECTED_KEY]);
1005 
1006         subGroup.writeEntry(PROFILE_MODEL_SCHEME_KEY, p_cache[i][PROFILE_MODEL_SCHEME_KEY]);
1007         subGroup.writeEntry(PROFILE_MODEL_FAT32COMPATIBLE_KEY, p_cache[i][PROFILE_MODEL_FAT32COMPATIBLE_KEY]);
1008         subGroup.writeEntry(PROFILE_MODEL_UNDERSCORE_KEY, p_cache[i][PROFILE_MODEL_UNDERSCORE_KEY]);
1009         subGroup.writeEntry(PROFILE_MODEL_2DIGITSTRACKNUM_KEY, p_cache[i][PROFILE_MODEL_2DIGITSTRACKNUM_KEY]);
1010 
1011         subGroup.writeEntry(PROFILE_MODEL_SC_KEY, p_cache[i][PROFILE_MODEL_SC_KEY]);
1012         subGroup.writeEntry(PROFILE_MODEL_SC_SCALE_KEY, p_cache[i][PROFILE_MODEL_SC_SCALE_KEY]);
1013         subGroup.writeEntry(PROFILE_MODEL_SC_SIZE_KEY, p_cache[i][PROFILE_MODEL_SC_SIZE_KEY]);
1014         subGroup.writeEntry(PROFILE_MODEL_SC_FORMAT_KEY, p_cache[i][PROFILE_MODEL_SC_FORMAT_KEY]);
1015         subGroup.writeEntry(PROFILE_MODEL_SC_NAME_KEY, p_cache[i][PROFILE_MODEL_SC_NAME_KEY]);
1016         subGroup.writeEntry(PROFILE_MODEL_PL_KEY, p_cache[i][PROFILE_MODEL_PL_KEY]);
1017         subGroup.writeEntry(PROFILE_MODEL_PL_FORMAT_KEY, p_cache[i][PROFILE_MODEL_PL_FORMAT_KEY]);
1018         subGroup.writeEntry(PROFILE_MODEL_PL_NAME_KEY, p_cache[i][PROFILE_MODEL_PL_NAME_KEY]);
1019         subGroup.writeEntry(PROFILE_MODEL_PL_ABS_FILE_PATH_KEY, p_cache[i][PROFILE_MODEL_PL_ABS_FILE_PATH_KEY]);
1020         subGroup.writeEntry(PROFILE_MODEL_PL_UTF8_KEY, p_cache[i][PROFILE_MODEL_PL_UTF8_KEY]);
1021         subGroup.writeEntry(PROFILE_MODEL_INF_KEY, p_cache[i][PROFILE_MODEL_INF_KEY]);
1022         subGroup.writeEntry(PROFILE_MODEL_INF_TEXT_KEY, p_cache[i][PROFILE_MODEL_INF_TEXT_KEY]);
1023         subGroup.writeEntry(PROFILE_MODEL_INF_NAME_KEY, p_cache[i][PROFILE_MODEL_INF_NAME_KEY]);
1024         subGroup.writeEntry(PROFILE_MODEL_INF_SUFFIX_KEY, p_cache[i][PROFILE_MODEL_INF_SUFFIX_KEY]);
1025         subGroup.writeEntry(PROFILE_MODEL_HL_KEY, p_cache[i][PROFILE_MODEL_HL_KEY]);
1026         subGroup.writeEntry(PROFILE_MODEL_HL_FORMAT_KEY, p_cache[i][PROFILE_MODEL_HL_FORMAT_KEY]);
1027         subGroup.writeEntry(PROFILE_MODEL_HL_NAME_KEY, p_cache[i][PROFILE_MODEL_HL_NAME_KEY]);
1028         subGroup.writeEntry(PROFILE_MODEL_CUE_KEY, p_cache[i][PROFILE_MODEL_CUE_KEY]);
1029         subGroup.writeEntry(PROFILE_MODEL_CUE_NAME_KEY, p_cache[i][PROFILE_MODEL_CUE_NAME_KEY]);
1030         subGroup.writeEntry(PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY, p_cache[i][PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY]);
1031         subGroup.writeEntry(PROFILE_MODEL_LOG_KEY, p_cache[i][PROFILE_MODEL_LOG_KEY]);
1032         subGroup.writeEntry(PROFILE_MODEL_LOG_NAME_KEY, p_cache[i][PROFILE_MODEL_LOG_NAME_KEY]);
1033         subGroup.writeEntry(PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY, p_cache[i][PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY]);
1034         subGroup.writeEntry(PROFILE_MODEL_SF_KEY, p_cache[i][PROFILE_MODEL_SF_KEY]);
1035         subGroup.writeEntry(PROFILE_MODEL_SF_NAME_KEY, p_cache[i][PROFILE_MODEL_SF_NAME_KEY]);
1036 
1037         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY]);
1038         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY]);
1039         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY]);
1040         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY]);
1041         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY]);
1042         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY]);
1043         subGroup.writeEntry(PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY, p_cache[i][PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY]);
1044     }
1045 
1046     if (p_cache.count() > 0)
1047         profilesGroup.config()->sync();
1048 }
1049 
1050 void ProfileModel::p_load(KConfig *config)
1051 {
1052     KConfigGroup profilesGroup(config, "Profiles");
1053     clear();
1054     p_current_profile_index = profilesGroup.readEntry("Standard", -1);
1055     int profileCount = profilesGroup.readEntry("Count", QVariant(0)).toInt();
1056 
1057     for (int i = 0; i < profileCount; ++i) {
1058         Profile p;
1059         KConfigGroup subGroup(&profilesGroup, QString("Profile %1").arg(i));
1060 
1061         p[PROFILE_MODEL_PROFILEINDEX_KEY] = subGroup.readEntry(PROFILE_MODEL_PROFILEINDEX_KEY, DEFAULT_PROFILEINDEX);
1062         p[PROFILE_MODEL_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_NAME_KEY, DEFAULT_NAME);
1063         p[PROFILE_MODEL_ICON_KEY] = subGroup.readEntry(PROFILE_MODEL_ICON_KEY, DEFAULT_ICON);
1064 
1065         p[PROFILE_MODEL_ENCODER_SELECTED_KEY] = subGroup.readEntry(PROFILE_MODEL_ENCODER_SELECTED_KEY, DEFAULT_ENCODER_SELECTED);
1066 
1067         p[PROFILE_MODEL_SCHEME_KEY] = subGroup.readEntry(PROFILE_MODEL_SCHEME_KEY, DEFAULT_SCHEME);
1068         p[PROFILE_MODEL_FAT32COMPATIBLE_KEY] = subGroup.readEntry(PROFILE_MODEL_FAT32COMPATIBLE_KEY, DEFAULT_FAT32);
1069         p[PROFILE_MODEL_UNDERSCORE_KEY] = subGroup.readEntry(PROFILE_MODEL_UNDERSCORE_KEY, DEFAULT_UNDERSCORE);
1070         p[PROFILE_MODEL_2DIGITSTRACKNUM_KEY] = subGroup.readEntry(PROFILE_MODEL_2DIGITSTRACKNUM_KEY, DEFAULT_2DIGITSTRACKNUM);
1071 
1072         p[PROFILE_MODEL_SC_KEY] = subGroup.readEntry(PROFILE_MODEL_SC_KEY, DEFAULT_SC);
1073         p[PROFILE_MODEL_SC_SCALE_KEY] = subGroup.readEntry(PROFILE_MODEL_SC_SCALE_KEY, DEFAULT_SC_SCALE);
1074         p[PROFILE_MODEL_SC_SIZE_KEY] = subGroup.readEntry(PROFILE_MODEL_SC_SIZE_KEY, DEFAULT_SC_SIZE);
1075         p[PROFILE_MODEL_SC_FORMAT_KEY] = subGroup.readEntry(PROFILE_MODEL_SC_FORMAT_KEY, DEFAULT_SC_FORMAT);
1076         p[PROFILE_MODEL_SC_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_SC_NAME_KEY, DEFAULT_SC_NAME);
1077         p[PROFILE_MODEL_PL_KEY] = subGroup.readEntry(PROFILE_MODEL_PL_KEY, DEFAULT_PL);
1078         p[PROFILE_MODEL_PL_FORMAT_KEY] = subGroup.readEntry(PROFILE_MODEL_PL_FORMAT_KEY, DEFAULT_PL_NAME);
1079         p[PROFILE_MODEL_PL_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_PL_NAME_KEY, DEFAULT_PL_NAME);
1080         p[PROFILE_MODEL_PL_ABS_FILE_PATH_KEY] = subGroup.readEntry(PROFILE_MODEL_PL_ABS_FILE_PATH_KEY, DEFAULT_PL_ABS_FILE_PATH);
1081         p[PROFILE_MODEL_PL_UTF8_KEY] = subGroup.readEntry(PROFILE_MODEL_PL_UTF8_KEY, DEFAULT_PL_UTF8);
1082         p[PROFILE_MODEL_INF_KEY] = subGroup.readEntry(PROFILE_MODEL_INF_KEY, DEFAULT_INF);
1083         p[PROFILE_MODEL_INF_TEXT_KEY] = subGroup.readEntry(PROFILE_MODEL_INF_TEXT_KEY, DEFAULT_INF_TEXT);
1084         p[PROFILE_MODEL_INF_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_INF_NAME_KEY, DEFAULT_INF_NAME);
1085         p[PROFILE_MODEL_INF_SUFFIX_KEY] = subGroup.readEntry(PROFILE_MODEL_INF_SUFFIX_KEY, DEFAULT_INF_SUFFIX);
1086         p[PROFILE_MODEL_HL_KEY] = subGroup.readEntry(PROFILE_MODEL_HL_KEY, DEFAULT_HL);
1087         p[PROFILE_MODEL_HL_FORMAT_KEY] = subGroup.readEntry(PROFILE_MODEL_HL_FORMAT_KEY, DEFAULT_HL_FORMAT);
1088         p[PROFILE_MODEL_HL_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_HL_NAME_KEY, DEFAULT_HL_NAME);
1089         p[PROFILE_MODEL_CUE_KEY] = subGroup.readEntry(PROFILE_MODEL_CUE_KEY, DEFAULT_CUE);
1090         p[PROFILE_MODEL_CUE_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_CUE_NAME_KEY, DEFAULT_CUE_NAME);
1091         p[PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY] = subGroup.readEntry(PROFILE_MODEL_CUE_ADD_MCN_AND_ISRC_KEY, DEFAULT_CUE_ADD_MCN_AND_ISRC);
1092         p[PROFILE_MODEL_LOG_KEY] = subGroup.readEntry(PROFILE_MODEL_LOG_KEY, DEFAULT_LOG);
1093         p[PROFILE_MODEL_LOG_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_LOG_NAME_KEY, DEFAULT_LOG_NAME);
1094         p[PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY] = subGroup.readEntry(PROFILE_MODEL_LOG_WRITE_TIMESTAMPS_KEY, DEFAULT_LOG_WRITE_TIMESTAMPS);
1095         p[PROFILE_MODEL_SF_KEY] = subGroup.readEntry(PROFILE_MODEL_SF_KEY, DEFAULT_SF);
1096         p[PROFILE_MODEL_SF_NAME_KEY] = subGroup.readEntry(PROFILE_MODEL_SF_NAME_KEY, DEFAULT_SF_NAME);
1097 
1098         p[PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY] = subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_LAME_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1099         p[PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY] =
1100             subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_OGGENC_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1101         p[PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY] =
1102             subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_OPUSENC_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1103         p[PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY] = subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_FLAC_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1104         p[PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY] = subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_FAAC_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1105         p[PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY] = subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_WAVE_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1106         p[PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY] =
1107             subGroup.readEntry(PROFILE_MODEL_COLUMN_ENCODER_CUSTOM_PARAMETERS_KEY, DEFAULT_ENCODER_PARAMETERS);
1108 
1109         p_cache.append(p);
1110     }
1111 
1112     if (profileCount > 0) {
1113         if (p_current_profile_index == -1)
1114             p_current_profile_index = 0;
1115         Q_EMIT profilesRemovedOrInserted();
1116     }
1117 }