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

0001 /**
0002  * \file configtable.cpp
0003  * Table with context menu to add, delete and clear rows.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 10 Oct 2005
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 "configtable.h"
0028 #include <QToolTip>
0029 #include <QMenu>
0030 #include "modelsectionresizemode.h"
0031 
0032 /**
0033  * Constructor.
0034  *
0035  * @param model item model
0036  * @param parent parent widget
0037  */
0038 ConfigTable::ConfigTable(QAbstractItemModel* model, QWidget* parent)
0039   : AbstractListEdit(m_tableView = new QTableView, model, parent)
0040 {
0041   setObjectName(QLatin1String("ConfigTable"));
0042   setAddButtonText(tr("&Add"));
0043   hideEditButton();
0044   m_tableView->setContextMenuPolicy(Qt::CustomContextMenu);
0045   connect(m_tableView, &QWidget::customContextMenuRequested,
0046       this, &ConfigTable::customContextMenu);
0047 }
0048 
0049 /**
0050  * Set the resize modes to be used for the columns.
0051  * @param resizeModes list of resize modes for the columns
0052  */
0053 void ConfigTable::setHorizontalResizeModes(
0054   const QList<ModelSectionResizeMode>& resizeModes)
0055 {
0056   Q_STATIC_ASSERT(static_cast<QHeaderView::ResizeMode>(
0057     ModelSectionResizeMode::Interactive) == QHeaderView::Interactive);
0058   Q_STATIC_ASSERT(static_cast<QHeaderView::ResizeMode>(
0059     ModelSectionResizeMode::Stretch) == QHeaderView::Stretch);
0060   Q_STATIC_ASSERT(static_cast<QHeaderView::ResizeMode>(
0061     ModelSectionResizeMode::Fixed) == QHeaderView::Fixed);
0062   Q_STATIC_ASSERT(static_cast<QHeaderView::ResizeMode>(
0063     ModelSectionResizeMode::ResizeToContents) == QHeaderView::ResizeToContents);
0064   QHeaderView* header = m_tableView->horizontalHeader();
0065   int col = 0;
0066   for (auto mode : resizeModes)
0067     header->setSectionResizeMode(col++,
0068                                  static_cast<QHeaderView::ResizeMode>(mode));
0069 }
0070 
0071 /**
0072  * Insert a new row into the table.
0073  *
0074  * @param row the new row is inserted after this row
0075  */
0076 void ConfigTable::addRow(int row)
0077 {
0078   m_tableView->model()->insertRow(row + 1);
0079 }
0080 
0081 /**
0082  * Delete a row from the table.
0083  *
0084  * @param row row to delete
0085  */
0086 void ConfigTable::deleteRow(int row)
0087 {
0088   if (m_tableView->model()->rowCount() <= 1)
0089     return;
0090   m_tableView->model()->removeRow(row);
0091 }
0092 
0093 /**
0094  * Clear a row in the table.
0095  *
0096  * @param row row to clear
0097  */
0098 void ConfigTable::clearRow(int row)
0099 {
0100   if (row < m_tableView->model()->rowCount() && m_tableView->model()->removeRow(row))
0101     m_tableView->model()->insertRow(row);
0102 }
0103 
0104 /**
0105  * Execute a context menu action.
0106  *
0107  * @param action action of selected menu
0108  */
0109 void ConfigTable::executeAction(const QAction* action)
0110 {
0111   if (action) {
0112     int row = action->data().toInt();
0113     int cmd = row & 3;
0114     row >>= 2;
0115     switch (cmd) {
0116       case 0:
0117         addRow(row);
0118         break;
0119       case 1:
0120         deleteRow(row);
0121         break;
0122       case 2:
0123       default:
0124         clearRow(row);
0125         break;
0126     }
0127   }
0128 }
0129 
0130 /**
0131  * Display context menu.
0132  *
0133  * @param row row at which context menu is displayed
0134  * @param pos position where context menu is drawn on screen
0135  */
0136 void ConfigTable::contextMenu(int row, int /* col */, const QPoint& pos)
0137 {
0138   QMenu menu(this);
0139   QAction* action;
0140   if (row >= -1) {
0141     action = menu.addAction(tr("&Insert row"));
0142     if (action) action->setData(row << 2);
0143   }
0144   if (row >= 0) {
0145     action = menu.addAction(tr("&Delete row"));
0146     if (action) action->setData((row << 2) | 1);
0147     action = menu.addAction(tr("&Clear row"));
0148     if (action) action->setData((row << 2) | 2);
0149   }
0150   connect(&menu, &QMenu::triggered, this, &ConfigTable::executeAction);
0151   menu.setMouseTracking(true);
0152   menu.exec(pos);
0153 }
0154 
0155 /**
0156  * Display custom context menu.
0157  *
0158  * @param pos position where context menu is drawn on screen
0159  */
0160 void ConfigTable::customContextMenu(const QPoint& pos)
0161 {
0162   if (QModelIndex index = m_tableView->indexAt(pos); index.isValid()) {
0163     contextMenu(index.row(), index.column(), mapToGlobal(pos));
0164   }
0165 }
0166 
0167 /**
0168  * Add a new item.
0169  */
0170 void ConfigTable::addItem()
0171 {
0172   addRow(getItemView()->model()->rowCount() - 1);
0173 }
0174 
0175 /**
0176  * Edit the selected item.
0177  */
0178 void ConfigTable::editItem()
0179 {
0180 }