Warning, file /office/skrooge/skgbasegui/skgtablewidget.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 /** @file
0007  * A table widget with more features.
0008  *
0009  * @author Stephane MANKOWSKI / Guillaume DE BURE
0010  */
0011 #include "skgtablewidget.h"
0012 
0013 #include <qapplication.h>
0014 #include <qclipboard.h>
0015 #include <qevent.h>
0016 #include <qscrollbar.h>
0017 
0018 #include <algorithm>
0019 
0020 #include "skgtraces.h"
0021 
0022 SKGTableWidget::SKGTableWidget(QWidget* iParent)
0023     : QTableWidget(iParent), stickH(false), stickV(false)
0024 {
0025     this->installEventFilter(this);
0026     connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &SKGTableWidget::onActionTriggered);
0027     connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &SKGTableWidget::onActionTriggered);
0028     connect(horizontalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTableWidget::onRangeChanged);
0029     connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTableWidget::onRangeChanged);
0030 }
0031 
0032 SKGTableWidget::~SKGTableWidget()
0033     = default;
0034 
0035 void SKGTableWidget::onRangeChanged()
0036 {
0037     auto* scrollb = qobject_cast<QScrollBar*>(sender());
0038     if ((stickH && scrollb == horizontalScrollBar()) || (stickV && scrollb == verticalScrollBar())) {
0039         scrollb->setValue(scrollb->maximum());
0040     }
0041 }
0042 
0043 void SKGTableWidget::onActionTriggered()
0044 {
0045     auto* scrollb = qobject_cast<QScrollBar*>(sender());
0046     if (scrollb != nullptr) {
0047         if (scrollb == horizontalScrollBar()) {
0048             stickH = (scrollb->value() == scrollb->maximum());
0049         }
0050         if (scrollb == verticalScrollBar()) {
0051             stickV = (scrollb->value() == scrollb->maximum());
0052         }
0053     }
0054 }
0055 
0056 void SKGTableWidget::setStickHorizontal(bool iStick)
0057 {
0058     stickH = iStick;
0059 }
0060 
0061 bool SKGTableWidget::stickHorizontal() const
0062 {
0063     return stickH;
0064 }
0065 
0066 void SKGTableWidget::setStickVertical(bool iStick)
0067 {
0068     stickV = iStick;
0069 }
0070 bool SKGTableWidget::stickVertical() const
0071 {
0072     return stickV;
0073 }
0074 
0075 bool SKGTableWidget::eventFilter(QObject* iObject, QEvent* iEvent)
0076 {
0077     if (iObject == this && iEvent != nullptr && iEvent->type() == QEvent::KeyPress) {
0078         auto* kevent = dynamic_cast<QKeyEvent*>(iEvent);
0079         if (kevent != nullptr) {
0080             if (kevent->key() == Qt::Key_Delete && state() != QAbstractItemView::EditingState) {
0081                 QList<QTableWidgetItem*> listOfSelectedItems = this->selectedItems();
0082                 int nb = listOfSelectedItems.count();
0083                 if (nb > 0) {
0084                     // Build list of indexes
0085                     QList<int> listIndex;
0086                     listIndex.reserve(nb);
0087                     for (int i = 0; i < nb; ++i) {
0088                         QModelIndex mIndex = this->indexFromItem(listOfSelectedItems.at(i));
0089                         if (!listIndex.contains(mIndex.row())) {
0090                             listIndex.append(mIndex.row());
0091                         }
0092                     }
0093 
0094                     // Sort reverse
0095                     std::sort(listIndex.begin(), listIndex.end(), std::greater<int>());
0096 
0097                     // Emit events
0098                     nb = listIndex.count();
0099                     for (int i = 0; i < nb; ++i) {
0100                         Q_EMIT removeLine(listIndex.at(i));
0101                     }
0102 
0103                     if (iEvent != nullptr) {
0104                         iEvent->accept();
0105                     }
0106                     return true;  // stop the process
0107                 }
0108             } else if (kevent->matches(QKeySequence::Copy) && this->state() != QAbstractItemView::EditingState) {
0109                 copy();
0110                 if (iEvent != nullptr) {
0111                     iEvent->accept();
0112                 }
0113                 return true;  // stop the process
0114             }
0115         }
0116     }
0117 
0118     return QTableWidget::eventFilter(iObject, iEvent);
0119 }
0120 
0121 void SKGTableWidget::copy()
0122 {
0123     QItemSelectionModel* selection = selectionModel();
0124     if (selection != nullptr) {
0125         QModelIndexList indexes = selection->selectedIndexes();
0126 
0127         if (indexes.empty()) {
0128             return;
0129         }
0130 
0131         std::sort(indexes.begin(), indexes.end());
0132 
0133         // You need a pair of indexes to find the row changes
0134         QModelIndex previous = indexes.first();
0135         indexes.removeFirst();
0136         QString header_text;
0137         bool header_done = false;
0138         QString selected_text;
0139         for (const auto& current : qAsConst(indexes)) {
0140             selected_text.append(model()->data(previous).toString());
0141             if (!header_done) {
0142                 header_text.append(model()->headerData(previous.column(), Qt::Horizontal).toString());
0143             }
0144             if (current.row() != previous.row()) {
0145                 selected_text.append(QLatin1Char('\n'));
0146                 header_done = true;
0147             } else {
0148                 selected_text.append(QLatin1Char(';'));
0149                 if (!header_done) {
0150                     header_text.append(QLatin1Char(';'));
0151                 }
0152             }
0153             previous = current;
0154         }
0155 
0156         // add last element
0157         selected_text.append(model()->data(previous).toString());
0158         selected_text.append(QLatin1Char('\n'));
0159         QApplication::clipboard()->setText(header_text + '\n' + selected_text);
0160     }
0161 }
0162 
0163