File indexing completed on 2025-02-23 04:34:23
0001 /** 0002 * \file formatlistedit.cpp 0003 * Widget to edit a format list. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 13 Aug 2011 0008 * 0009 * Copyright (C) 2011-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 "formatlistedit.h" 0028 #include <QPushButton> 0029 #include <QLineEdit> 0030 #include <QComboBox> 0031 #include <QLayout> 0032 #include <QFormLayout> 0033 #include <QSizePolicy> 0034 0035 /** 0036 * Constructor. 0037 * 0038 * @param labels list of label texts for fields in a single format 0039 * @param tooltips list of tooltips, one string per label, empty if not used 0040 * @param parent parent widget 0041 */ 0042 FormatListEdit::FormatListEdit(const QStringList& labels, 0043 const QStringList& tooltips, 0044 QWidget* parent) 0045 : QWidget(parent) 0046 { 0047 setObjectName(QLatin1String("FormatListEdit")); 0048 auto hlayout = new QHBoxLayout(this); 0049 hlayout->setContentsMargins(0, 0, 0, 0); 0050 auto formatLayout = new QFormLayout; 0051 formatLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); 0052 bool comboBoxCreated = false; 0053 for (int i = 0; i < labels.size(); ++i) { 0054 const QString& label = labels.at(i); 0055 const QString& toolTip = tooltips.at(i); 0056 if (!comboBoxCreated) { 0057 m_formatComboBox = new QComboBox; 0058 m_formatComboBox->setEditable(true); 0059 m_formatComboBox->setInsertPolicy(QComboBox::NoInsert); 0060 connect(m_formatComboBox, static_cast<void (QComboBox::*)(int)>( 0061 &QComboBox::activated), 0062 this, &FormatListEdit::updateLineEdits); 0063 connect(m_formatComboBox->lineEdit(), &QLineEdit::editingFinished, 0064 this, &FormatListEdit::commitCurrentEdits); 0065 if (!toolTip.isEmpty()) 0066 m_formatComboBox->setToolTip(toolTip); 0067 formatLayout->addRow(label, m_formatComboBox); 0068 comboBoxCreated = true; 0069 } else { 0070 auto ed = new QLineEdit; 0071 connect(ed, &QLineEdit::returnPressed, this, &FormatListEdit::formatChanged); 0072 if (!toolTip.isEmpty()) 0073 ed->setToolTip(toolTip); 0074 formatLayout->addRow(label, ed); 0075 m_lineEdits.append(ed); // clazy:exclude=reserve-candidates 0076 } 0077 } 0078 hlayout->addLayout(formatLayout); 0079 auto vlayout = new QVBoxLayout; 0080 #ifdef Q_OS_MAC 0081 vlayout->setSpacing(6); 0082 #endif 0083 m_addPushButton = new QPushButton(tr("&Add")); 0084 m_addPushButton->setAutoDefault(false); 0085 m_removePushButton = new QPushButton(tr("&Remove")); 0086 m_removePushButton->setAutoDefault(false); 0087 vlayout->addWidget(m_addPushButton); 0088 vlayout->addWidget(m_removePushButton); 0089 vlayout->addStretch(); 0090 hlayout->addLayout(vlayout); 0091 connect(m_addPushButton, &QAbstractButton::clicked, this, &FormatListEdit::addItem); 0092 connect(m_removePushButton, &QAbstractButton::clicked, this, &FormatListEdit::removeItem); 0093 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 0094 } 0095 0096 /** 0097 * Set format strings. 0098 * 0099 * @param formats list of format stringlists, the first stringlist contains 0100 * the names, the second the corresponding string for the first line edit, 0101 * etc. 0102 * @param index index to select, -1 to keep current index 0103 */ 0104 void FormatListEdit::setFormats(const QList<QStringList>& formats, int index) 0105 { 0106 m_formats = formats; 0107 if (index >= 0) { 0108 m_formatComboBox->setCurrentIndex(index); 0109 updateComboBoxAndLineEdits(index); 0110 } 0111 } 0112 0113 /** 0114 * Get format strings. 0115 * 0116 * @param index if not null, the current index is returned here 0117 * 0118 * @return list of format stringlists, the first stringlist contains 0119 * the names, the second the corresponding string for the first line edit, 0120 * etc. 0121 */ 0122 QList<QStringList> FormatListEdit::getFormats(int* index) 0123 { 0124 commitCurrentEdits(); 0125 if (index) { 0126 *index = m_formatComboBox->currentIndex(); 0127 } 0128 return m_formats; 0129 } 0130 0131 /** 0132 * Get a format string from the format currently displayed in the GUI. 0133 * 0134 * @param formatNr index of the format stringlist, 0 is the format name 0135 * 1 the first line edit, etc. 0136 * 0137 * @return format string. 0138 */ 0139 QString FormatListEdit::getCurrentFormat(int formatNr) const 0140 { 0141 if (formatNr == 0) { 0142 return m_formatComboBox->currentText(); 0143 } 0144 if (formatNr > 0 && formatNr - 1 < m_lineEdits.size()) { 0145 return m_lineEdits.at(formatNr - 1)->text(); 0146 } 0147 return QString(); 0148 } 0149 0150 /** 0151 * Update GUI controls from formats. 0152 * 0153 * @param index combo box index to set 0154 */ 0155 void FormatListEdit::updateComboBoxAndLineEdits(int index) 0156 { 0157 m_formatComboBox->clear(); 0158 if (!m_formats.isEmpty()) { 0159 #if QT_VERSION >= 0x050600 0160 const QStringList& firstFormat = m_formats.constFirst(); 0161 #else 0162 const QStringList& firstFormat = m_formats.first(); 0163 #endif 0164 m_formatComboBox->addItems(firstFormat); 0165 if (index >= 0 && index < firstFormat.size()) { 0166 m_formatComboBox->setCurrentIndex(index); 0167 updateLineEdits(index); 0168 } 0169 } 0170 } 0171 0172 /** 0173 * Set the currently selected format from the contents of the controls. 0174 */ 0175 void FormatListEdit::commitCurrentEdits() 0176 { 0177 int index = m_formatComboBox->currentIndex(); 0178 if (index < 0) 0179 return; 0180 0181 if (m_formatComboBox->itemText(index) != m_formatComboBox->currentText()) { 0182 m_formatComboBox->setItemText(index, m_formatComboBox->currentText()); 0183 } 0184 0185 for (int i = 0; i < m_formats.size() && i - 1 < m_lineEdits.size(); ++i) { 0186 QString text(i == 0 0187 ? m_formatComboBox->currentText() 0188 : m_lineEdits.at(i - 1)->text()); 0189 if (QStringList& fmts = m_formats[i]; index < fmts.size()) { // clazy:exclude=detaching-member 0190 fmts[index] = text; 0191 } 0192 } 0193 } 0194 0195 /** 0196 * Set the format lineedits to the format of the index. 0197 * 0198 * @param index selected item in combo box 0199 */ 0200 void FormatListEdit::updateLineEdits(int index) 0201 { 0202 for (int i = 0; i < m_lineEdits.size() && i + 1 < m_formats.size(); ++i) { 0203 QLineEdit* le = m_lineEdits.at(i); 0204 if (const QStringList& fmts = m_formats.at(i + 1); index < fmts.size()) { 0205 le->setText(fmts.at(index)); 0206 } else { 0207 le->clear(); 0208 } 0209 } 0210 emit formatChanged(); 0211 } 0212 0213 /** 0214 * Add a new item. 0215 */ 0216 void FormatListEdit::addItem() 0217 { 0218 commitCurrentEdits(); 0219 if (!m_formats.isEmpty()) { 0220 // first search for an existing empty format 0221 int index = -1; 0222 #if QT_VERSION >= 0x050600 0223 for (int fmtIdx = m_formats.constFirst().size() - 1; fmtIdx > 0; --fmtIdx) 0224 #else 0225 for (int fmtIdx = m_formats.first().size() - 1; fmtIdx > 0; --fmtIdx) 0226 #endif 0227 { 0228 bool allEmpty = true; 0229 for (int leIdx = 1; leIdx < m_formats.size(); ++leIdx) { 0230 if (const QStringList& fmts = m_formats.at(leIdx); 0231 fmtIdx < fmts.size() && !fmts.at(fmtIdx).isEmpty()) { 0232 allEmpty = false; 0233 break; 0234 } 0235 } 0236 if (allEmpty) { 0237 index = fmtIdx; 0238 break; 0239 } 0240 } 0241 0242 if (index == -1) { 0243 // no empty format found, add a new one 0244 for (int i = 0; i < m_formats.size(); ++i) { 0245 m_formats[i].append(i == 0 ? tr("New") : QLatin1String("")); 0246 } 0247 #if QT_VERSION >= 0x050600 0248 index = m_formats.constFirst().size() - 1; 0249 #else 0250 index = m_formats.first().size() - 1; 0251 #endif 0252 } 0253 updateComboBoxAndLineEdits(index); 0254 m_formatComboBox->lineEdit()->setFocus(); 0255 m_formatComboBox->lineEdit()->selectAll(); 0256 } 0257 } 0258 0259 /** 0260 * Remove the selected item. 0261 */ 0262 void FormatListEdit::removeItem() 0263 { 0264 int index = m_formatComboBox->currentIndex(); 0265 if (index < 0) 0266 return; 0267 0268 for (int i = 0; i < m_formats.size(); ++i) { 0269 if (index < m_formats.at(i).size()) { 0270 m_formats[i].removeAt(index); 0271 } 0272 } 0273 if (!m_formats.isEmpty()) { 0274 #if QT_VERSION >= 0x050600 0275 const QStringList& fmts = m_formats.constFirst(); 0276 #else 0277 const QStringList& fmts = m_formats.first(); 0278 #endif 0279 if (index >= fmts.size()) { 0280 index = fmts.size() - 1; 0281 } 0282 if (index < 0) { 0283 addItem(); 0284 } else { 0285 updateComboBoxAndLineEdits(index); 0286 } 0287 } 0288 }