File indexing completed on 2025-02-23 04:34:22

0001 /**
0002  * \file abstractlistedit.cpp
0003  * Widget to edit a list.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 2 Jan 2013
0008  *
0009  * Copyright (C) 2013-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 "abstractlistedit.h"
0028 #include <QPushButton>
0029 #include <QLayout>
0030 #include <QAbstractItemView>
0031 
0032 /**
0033  * Constructor.
0034  *
0035  * @param itemView item view, e.g. a QListView
0036  * @param model item model, e.g. a QStringListModel
0037  * @param parent parent widget
0038  */
0039 AbstractListEdit::AbstractListEdit(QAbstractItemView* itemView,
0040                                    QAbstractItemModel* model, QWidget* parent)
0041   : QWidget(parent)
0042 {
0043   setObjectName(QLatin1String("AbstractListEdit"));
0044   auto hlayout = new QHBoxLayout(this);
0045   m_itemView = itemView;
0046   m_itemView->setModel(model);
0047   hlayout->setContentsMargins(0, 0, 0, 0);
0048   hlayout->addWidget(m_itemView);
0049   auto vlayout = new QVBoxLayout;
0050   m_addPushButton = new QPushButton(tr("&Add..."), this);
0051   m_moveUpPushButton = new QPushButton(tr("Move &Up"), this);
0052   m_moveDownPushButton = new QPushButton(tr("Move &Down"), this);
0053   m_editPushButton = new QPushButton(tr("&Edit..."), this);
0054   m_removePushButton = new QPushButton(tr("&Remove"), this);
0055   vlayout->addWidget(m_addPushButton);
0056   vlayout->addWidget(m_moveUpPushButton);
0057   vlayout->addWidget(m_moveDownPushButton);
0058   vlayout->addWidget(m_editPushButton);
0059   vlayout->addWidget(m_removePushButton);
0060   vlayout->addStretch();
0061 
0062   connect(m_addPushButton, &QAbstractButton::clicked, this, &AbstractListEdit::addItem);
0063   connect(m_moveUpPushButton, &QAbstractButton::clicked, this, &AbstractListEdit::moveUpItem);
0064   connect(m_moveDownPushButton, &QAbstractButton::clicked, this, &AbstractListEdit::moveDownItem);
0065   connect(m_editPushButton, &QAbstractButton::clicked, this, &AbstractListEdit::editItem);
0066   connect(m_removePushButton, &QAbstractButton::clicked, this, &AbstractListEdit::removeItem);
0067   connect(m_itemView->selectionModel(),
0068           &QItemSelectionModel::currentChanged,
0069           this, &AbstractListEdit::setButtonEnableState);
0070 
0071   setButtonEnableState();
0072   hlayout->addLayout(vlayout);
0073 }
0074 
0075 /**
0076  * Disable editing of items.
0077  * When editing is disabled, the Add, Edit and Remove buttons are hidden.
0078  * @param disable true to disable, false (default) to enable editing.
0079  */
0080 void AbstractListEdit::setEditingDisabled(bool disable)
0081 {
0082   m_addPushButton->setHidden(disable);
0083   m_editPushButton->setHidden(disable);
0084   m_removePushButton->setHidden(disable);
0085 }
0086 
0087 /**
0088  * Set text for Add button.
0089  * @param text button text
0090  */
0091 void AbstractListEdit::setAddButtonText(const QString& text)
0092 {
0093   m_addPushButton->setText(text);
0094 }
0095 
0096 /**
0097  * Remove the selected item.
0098  */
0099 void AbstractListEdit::removeItem()
0100 {
0101   if (QModelIndex index = m_itemView->currentIndex(); index.isValid()) {
0102     QAbstractItemModel* model = m_itemView->model();
0103     model->removeRow(index.row());
0104     setButtonEnableState();
0105   }
0106 }
0107 
0108 /**
0109  * Move the selected item up.
0110  */
0111 void AbstractListEdit::moveUpItem()
0112 {
0113   if (QModelIndex index = m_itemView->currentIndex();
0114       index.isValid() && index.row() > 0) {
0115     int row = index.row();
0116     QAbstractItemModel* model = m_itemView->model();
0117     const int numColumns = model->columnCount();
0118     QVector<QVariant> editValues(numColumns);
0119     QVector<QVariant> checkValues(numColumns);
0120     for (int column = 0; column < numColumns; ++column) {
0121       QModelIndex idx = model->index(row, column);
0122       editValues[column] = idx.data(Qt::EditRole);
0123       checkValues[column] = idx.data(Qt::CheckStateRole);
0124     }
0125     model->removeRow(row);
0126     model->insertRow(row - 1);
0127     for (int column = 0; column < numColumns; ++column) {
0128       QModelIndex idx = model->index(row - 1, column);
0129       model->setData(idx, editValues.at(column), Qt::EditRole);
0130       model->setData(idx, checkValues.at(column), Qt::CheckStateRole);
0131     }
0132     QModelIndex newIndex = model->index(row - 1, index.column());
0133     m_itemView->setCurrentIndex(newIndex);
0134   }
0135 }
0136 
0137 /**
0138  * Move the selected item down.
0139  */
0140 void AbstractListEdit::moveDownItem()
0141 {
0142   QModelIndex index = m_itemView->currentIndex();
0143   if (QAbstractItemModel* model = m_itemView->model();
0144       index.isValid() && index.row() < model->rowCount() - 1) {
0145     const int numColumns = model->columnCount();
0146     int row = index.row();
0147     QVector<QVariant> editValues(numColumns);
0148     QVector<QVariant> checkValues(numColumns);
0149     for (int column = 0; column < numColumns; ++column) {
0150       QModelIndex idx = model->index(row, column);
0151       editValues[column] = idx.data(Qt::EditRole);
0152       checkValues[column] = idx.data(Qt::CheckStateRole);
0153     }
0154     model->removeRow(row);
0155     model->insertRow(row + 1);
0156     for (int column = 0; column < numColumns; ++column) {
0157       QModelIndex idx = model->index(row + 1, column);
0158       model->setData(idx, editValues.at(column), Qt::EditRole);
0159       model->setData(idx, checkValues.at(column), Qt::CheckStateRole);
0160     }
0161     QModelIndex newIndex = model->index(row + 1, index.column());
0162     m_itemView->setCurrentIndex(newIndex);
0163   }
0164 }
0165 
0166 /**
0167  * Change state of buttons according to the current item and the count.
0168  */
0169 void AbstractListEdit::setButtonEnableState()
0170 {
0171   QModelIndex index = m_itemView->currentIndex();
0172   QAbstractItemModel* model = m_itemView->model();
0173   int idx = -1;
0174   if (index.isValid())
0175     idx = index.row();
0176   m_moveUpPushButton->setEnabled(idx > 0);
0177   m_moveDownPushButton->setEnabled(
0178       idx >= 0 &&
0179       idx < model->rowCount() - 1);
0180   m_editPushButton->setEnabled(idx >= 0);
0181   m_removePushButton->setEnabled(idx >= 0);
0182 }
0183 
0184 /**
0185  * Hide the Edit button.
0186  */
0187 void AbstractListEdit::hideEditButton()
0188 {
0189   m_editPushButton->hide();
0190 }