File indexing completed on 2025-02-23 04:34:24
0001 /** 0002 * \file subframeseditor.cpp 0003 * Editor for subframes contained in a frame. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 18 Sep 2015 0008 * 0009 * Copyright (C) 2015-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 "subframeseditor.h" 0028 #include <QVBoxLayout> 0029 #include <QHBoxLayout> 0030 #include <QPushButton> 0031 #include <QInputDialog> 0032 #include <QCoreApplication> 0033 #include "frametablemodel.h" 0034 #include "genremodel.h" 0035 #include "frametable.h" 0036 #include "framelist.h" 0037 #include "taggedfile.h" 0038 #include "editframefieldsdialog.h" 0039 #include "iplatformtools.h" 0040 0041 /** 0042 * Constructor. 0043 * 0044 * @param platformTools platform tools 0045 * @param app application context 0046 * @param taggedFile tagged file 0047 * @param tagNr tag number 0048 * @param parent parent widget 0049 */ 0050 SubframesEditor::SubframesEditor(IPlatformTools* platformTools, 0051 Kid3Application* app, 0052 const TaggedFile* taggedFile, 0053 Frame::TagNumber tagNr, 0054 QWidget* parent) 0055 : QWidget(parent), m_platformTools(platformTools), m_app(app), 0056 m_taggedFile(taggedFile), m_tagNr(tagNr), 0057 m_editFrameDialog(nullptr), m_editFrameRow(-1) 0058 { 0059 setObjectName(QLatin1String("SubframesEditor")); 0060 auto layout = new QHBoxLayout(this); 0061 m_frameTableModel = new FrameTableModel( 0062 false, platformTools->iconProvider(), this); 0063 m_frameTable = new FrameTable(m_frameTableModel, new GenreModel(false, this), 0064 this); 0065 layout->addWidget(m_frameTable); 0066 auto buttonLayout = new QVBoxLayout; 0067 m_editButton = new QPushButton(tr("Edit...")); 0068 m_editButton->setDefault(false); 0069 m_editButton->setAutoDefault(false); 0070 connect(m_editButton, &QAbstractButton::clicked, this, &SubframesEditor::onEditClicked); 0071 buttonLayout->addWidget(m_editButton); 0072 m_addButton = new QPushButton(tr("Add...")); 0073 m_addButton->setDefault(false); 0074 m_addButton->setAutoDefault(false); 0075 connect(m_addButton, &QAbstractButton::clicked, this, &SubframesEditor::onAddClicked); 0076 buttonLayout->addWidget(m_addButton); 0077 m_deleteButton = new QPushButton(tr("Delete")); 0078 m_deleteButton->setDefault(false); 0079 m_deleteButton->setAutoDefault(false); 0080 connect(m_deleteButton, &QAbstractButton::clicked, this, &SubframesEditor::onDeleteClicked); 0081 buttonLayout->addWidget(m_deleteButton); 0082 buttonLayout->addStretch(); 0083 layout->addLayout(buttonLayout); 0084 } 0085 0086 /** 0087 * Set subframes. 0088 * @param frames subframes, will be cleared 0089 */ 0090 void SubframesEditor::setFrames(FrameCollection& frames) 0091 { 0092 m_frameTableModel->transferFrames(frames); 0093 } 0094 0095 /** 0096 * Get subframes. 0097 * @param frames the subframes are returned here 0098 */ 0099 void SubframesEditor::getFrames(FrameCollection& frames) const 0100 { 0101 frames = m_frameTableModel->frames(); 0102 for (auto it = frames.begin(); it != frames.end(); ++it) { 0103 if (auto& frame = const_cast<Frame&>(*it); frame.isValueChanged()) { 0104 frame.setFieldListFromValue(); 0105 } 0106 } 0107 } 0108 0109 /** 0110 * Called when the Edit button is clicked. 0111 */ 0112 void SubframesEditor::onEditClicked() 0113 { 0114 QModelIndex index = m_frameTable->currentIndex(); 0115 if (const Frame* selectedFrame = m_frameTableModel->getFrameOfIndex(index)) { 0116 editFrame(*selectedFrame, index.row()); 0117 } 0118 } 0119 0120 /** 0121 * Called when the Add button is clicked. 0122 */ 0123 void SubframesEditor::onAddClicked() 0124 { 0125 bool ok = false; 0126 QStringList frameIds = m_taggedFile->getFrameIds(m_tagNr); 0127 QMap<QString, QString> nameMap = Frame::getDisplayNameMap(frameIds); 0128 QString displayName = QInputDialog::getItem( 0129 this, tr("Add Frame"), 0130 tr("Select the frame ID"), nameMap.keys(), 0, true, &ok); 0131 if (ok) { 0132 QString name = nameMap.value(displayName, displayName); 0133 Frame::Type type = Frame::getTypeFromName(name); 0134 Frame frame(type, QLatin1String(""), name, -1); 0135 m_taggedFile->addFieldList(m_tagNr, frame); 0136 editFrame(frame, -1); 0137 } 0138 } 0139 0140 /** 0141 * Called when the Delete button is clicked. 0142 */ 0143 void SubframesEditor::onDeleteClicked() 0144 { 0145 if (QModelIndex index = m_frameTable->currentIndex(); index.isValid()) { 0146 m_frameTableModel->removeRow(index.row()); 0147 } 0148 } 0149 0150 /** 0151 * Let user edit a frame and then update the fields 0152 * when the edits are accepted. 0153 * 0154 * @param frame frame to edit 0155 * @param row row of edited frame in frame table, -1 if newly added frame 0156 */ 0157 void SubframesEditor::editFrame(const Frame& frame, int row) 0158 { 0159 m_editFrame = frame; 0160 if (m_editFrame.isValueChanged()) { 0161 m_editFrame.setFieldListFromValue(); 0162 } 0163 m_editFrameRow = row; 0164 QString name(m_editFrame.getInternalName()); 0165 if (name.isEmpty()) { 0166 name = m_editFrame.getName(); 0167 } 0168 if (!name.isEmpty()) { 0169 if (int nlPos = name.indexOf(QLatin1Char('\n')); nlPos > 0) { 0170 // probably "TXXX - User defined text information\nDescription" or 0171 // "WXXX - User defined URL link\nDescription" 0172 name.truncate(nlPos); 0173 } 0174 name = QCoreApplication::translate("@default", name.toLatin1().data()); 0175 } 0176 if (!m_editFrameDialog) { 0177 m_editFrameDialog = new EditFrameFieldsDialog(m_platformTools, m_app, this); 0178 connect(m_editFrameDialog, &QDialog::finished, 0179 this, &SubframesEditor::onEditFrameDialogFinished); 0180 } 0181 m_editFrameDialog->setWindowTitle(name); 0182 m_editFrameDialog->setFrame(m_editFrame, m_taggedFile, m_tagNr); 0183 m_editFrameDialog->show(); 0184 } 0185 0186 /** 0187 * Called when the edit frame dialog is finished. 0188 * @param result dialog result 0189 */ 0190 void SubframesEditor::onEditFrameDialogFinished(int result) 0191 { 0192 if (auto dialog = 0193 qobject_cast<EditFrameFieldsDialog*>(sender())) { 0194 if (result == QDialog::Accepted) { 0195 if (const Frame::FieldList& fields = dialog->getUpdatedFieldList(); 0196 fields.isEmpty()) { 0197 m_editFrame.setValue(dialog->getFrameValue()); 0198 } else { 0199 m_editFrame.setFieldList(fields); 0200 m_editFrame.setValueFromFieldList(); 0201 } 0202 if (m_editFrameRow != -1) { 0203 m_frameTableModel->removeRow(m_editFrameRow); 0204 } 0205 m_frameTableModel->insertFrame(m_editFrame); 0206 } 0207 } 0208 }