File indexing completed on 2024-05-19 04:56:00

0001 /**
0002  * \file commandstablemodel.cpp
0003  * Context menu commands configuration table model.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 13 Mar 2011
0008  *
0009  * Copyright (C) 2005-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 "commandstablemodel.h"
0028 #include "commandformatreplacer.h"
0029 #include "modelsectionresizemode.h"
0030 
0031 /** Column indices. */
0032 enum ColumnIndex {
0033   CI_Confirm,
0034   CI_Output,
0035   CI_Name,
0036   CI_Command,
0037   CI_NumColumns
0038 };
0039 
0040 /**
0041  * Constructor.
0042  * @param parent parent widget
0043  */
0044 CommandsTableModel::CommandsTableModel(QObject* parent)
0045   : QAbstractTableModel(parent)
0046 {
0047   setObjectName(QLatin1String("CommandsTableModel"));
0048 }
0049 
0050 /**
0051  * Get item flags for index.
0052  * @param index model index
0053  * @return item flags
0054  */
0055 Qt::ItemFlags CommandsTableModel::flags(const QModelIndex& index) const
0056 {
0057   Qt::ItemFlags theFlags = QAbstractTableModel::flags(index);
0058   if (index.isValid()) {
0059     theFlags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled;
0060     if (index.column() == CI_Confirm || index.column() == CI_Output) {
0061       theFlags |= Qt::ItemIsUserCheckable;
0062     } else {
0063       theFlags |= Qt::ItemIsEditable;
0064     }
0065   }
0066   return theFlags;
0067 }
0068 
0069 /**
0070  * Get data for a given role.
0071  * @param index model index
0072  * @param role item data role
0073  * @return data for role
0074  */
0075 QVariant CommandsTableModel::data(const QModelIndex& index, int role) const
0076 {
0077   if (!index.isValid() ||
0078       index.row() < 0 || index.row() >= m_cmdList.size() ||
0079       index.column() < 0 || index.column() >= CI_NumColumns)
0080     return QVariant();
0081   const UserActionsConfig::MenuCommand& item = m_cmdList.at(index.row());
0082   if (role == Qt::DisplayRole || role == Qt::EditRole) {
0083     switch (index.column()) {
0084     case CI_Name:
0085       return item.getName();
0086     case CI_Command:
0087       return item.getCommand();
0088     default: ;
0089     }
0090   }
0091   if (role == Qt::CheckStateRole) {
0092     switch (index.column()) {
0093     case CI_Confirm:
0094       return item.mustBeConfirmed() ? Qt::Checked : Qt::Unchecked;
0095     case CI_Output:
0096       return item.outputShown() ? Qt::Checked : Qt::Unchecked;
0097     default: ;
0098     }
0099   }
0100   return QVariant();
0101 }
0102 
0103 /**
0104  * Set data for a given role.
0105  * @param index model index
0106  * @param value data value
0107  * @param role item data role
0108  * @return true if successful
0109  */
0110 bool CommandsTableModel::setData(const QModelIndex& index,
0111                                  const QVariant& value, int role)
0112 {
0113   if (!index.isValid() ||
0114       index.row() < 0 || index.row() >= m_cmdList.size() ||
0115       index.column() < 0 || index.column() >= CI_NumColumns)
0116     return false;
0117   UserActionsConfig::MenuCommand& item = m_cmdList[index.row()]; // clazy:exclude=detaching-member
0118   if (role == Qt::EditRole) {
0119     switch (index.column()) {
0120     case CI_Name:
0121       item.setName(value.toString());
0122       break;
0123     case CI_Command:
0124       item.setCommand(value.toString());
0125       break;
0126     default:
0127       return false;
0128     }
0129   } else if (role == Qt::CheckStateRole) {
0130     switch (index.column()) {
0131     case CI_Confirm:
0132       item.setMustBeConfirmed(value.toInt() == Qt::Checked);
0133       break;
0134     case CI_Output:
0135       item.setOutputShown(value.toInt() == Qt::Checked);
0136       break;
0137     default:
0138       return false;
0139     }
0140   } else {
0141     return false;
0142   }
0143   emit dataChanged(index, index);
0144   return true;
0145 }
0146 
0147 /**
0148  * Get data for header section.
0149  * @param section column or row
0150  * @param orientation horizontal or vertical
0151  * @param role item data role
0152  * @return header data for role
0153  */
0154 QVariant CommandsTableModel::headerData(
0155     int section, Qt::Orientation orientation, int role) const
0156 {
0157   if (role == Qt::ToolTipRole && orientation == Qt::Horizontal &&
0158       section == CI_Command)
0159     return CommandFormatReplacer::getToolTip();
0160   if (role != Qt::DisplayRole)
0161     return QVariant();
0162   if (orientation == Qt::Horizontal) {
0163     switch (section) {
0164     case CI_Confirm:
0165       return tr("Confirm");
0166     case CI_Output:
0167       return tr("Output");
0168     case CI_Name:
0169       return tr("Name");
0170     case CI_Command:
0171       return tr("Command");
0172     default:
0173       return section + 1;
0174     }
0175   }
0176   return section + 1;
0177 }
0178 
0179 /**
0180  * Get number of rows.
0181  * @param parent parent model index, invalid for table models
0182  * @return number of rows,
0183  * if parent is valid number of children (0 for table models)
0184  */
0185 int CommandsTableModel::rowCount(const QModelIndex& parent) const
0186 {
0187   return parent.isValid() ? 0 : m_cmdList.size();
0188 }
0189 
0190 /**
0191  * Get number of columns.
0192  * @param parent parent model index, invalid for table models
0193  * @return number of columns,
0194  * if parent is valid number of children (0 for table models)
0195  */
0196 int CommandsTableModel::columnCount(const QModelIndex& parent) const
0197 {
0198   return parent.isValid() ? 0 : CI_NumColumns;
0199 }
0200 
0201 /**
0202  * Insert rows.
0203  * @param row rows are inserted before this row, if 0 at the begin,
0204  * if rowCount() at the end
0205  * @param count number of rows to insert
0206  * @return true if successful
0207  */
0208 bool CommandsTableModel::insertRows(int row, int count,
0209                         const QModelIndex&)
0210 {
0211   if (count > 0) {
0212     beginInsertRows(QModelIndex(), row, row + count - 1);
0213     for (int i = 0; i < count; ++i)
0214       m_cmdList.insert(row, UserActionsConfig::MenuCommand());
0215     endInsertRows();
0216   }
0217   return true;
0218 }
0219 
0220 /**
0221  * Remove rows.
0222  * @param row rows are removed starting with this row
0223  * @param count number of rows to remove
0224  * @return true if successful
0225  */
0226 bool CommandsTableModel::removeRows(int row, int count,
0227                         const QModelIndex&)
0228 {
0229   if (count > 0) {
0230     beginRemoveRows(QModelIndex(), row, row + count - 1);
0231     for (int i = 0; i < count; ++i)
0232       m_cmdList.removeAt(row);
0233     endRemoveRows();
0234   }
0235   return true;
0236 }
0237 
0238 /**
0239  * Get the resize modes to be used for the columns.
0240  * @return list of resize modes for the columns
0241  */
0242 QList<ModelSectionResizeMode>
0243     CommandsTableModel::getHorizontalResizeModes() const
0244 {
0245   QList<ModelSectionResizeMode> resizeModes;
0246   resizeModes.reserve(CI_NumColumns);
0247   for (int i = 0; i < CI_NumColumns; ++i) {
0248     auto mode = ModelSectionResizeMode::Interactive;
0249     if (i == CI_Confirm || i == CI_Output)
0250       mode = ModelSectionResizeMode::ResizeToContents;
0251     else if (i == CI_Command)
0252       mode = ModelSectionResizeMode::Stretch;
0253     resizeModes.append(mode);
0254   }
0255   return resizeModes;
0256 }
0257 
0258 /**
0259  * Set the model from the command list.
0260  * @param cmdList command list
0261  */
0262 void CommandsTableModel::setCommandList(
0263   const QList<UserActionsConfig::MenuCommand>& cmdList)
0264 {
0265   beginResetModel();
0266   m_cmdList = cmdList;
0267   endResetModel();
0268 }
0269 
0270 /**
0271  * Get the command list from the model.
0272  * @return command list
0273  */
0274 QList<UserActionsConfig::MenuCommand> CommandsTableModel::getCommandList() const
0275 {
0276   QList<UserActionsConfig::MenuCommand> cmdList;
0277   for (auto it = m_cmdList.constBegin(); it != m_cmdList.constEnd(); ++it) {
0278     if (!it->getName().isEmpty() ||
0279         it->getCommand() == QLatin1String("@separator") ||
0280         it->getCommand() == QLatin1String("@endmenu")) {
0281       cmdList.append(*it);
0282     }
0283   }
0284   if (cmdList.isEmpty()) {
0285     // Make sure that their is at least one entry, so that new entries can
0286     // be added.
0287     cmdList.append(UserActionsConfig::MenuCommand());
0288   }
0289   return cmdList;
0290 }