File indexing completed on 2024-05-12 15:27:58
0001 /*************************************************************************** 0002 File : CursorDock.cpp 0003 Project : LabPlot 0004 Description : This dock represents the data from the cursors in the cartesian plots 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2019 Martin Marmsoler (martin.marmsoler@gmail.com) 0007 Copyright : (C) 2019-2020 Alexander Semke (alexander.semke@web.de) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * This program 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 * This program 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, write to the Free Software * 0025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0026 * Boston, MA 02110-1301 USA * 0027 * * 0028 ***************************************************************************/ 0029 0030 #include "CursorDock.h" 0031 #include "ui_cursordock.h" 0032 #include "backend/worksheet/Worksheet.h" 0033 #include "backend/worksheet/WorksheetPrivate.h" 0034 #include "backend/worksheet/plots/cartesian/CartesianPlot.h" 0035 #include "backend/worksheet/plots/cartesian/XYCurve.h" 0036 #include "backend/worksheet/TreeModel.h" 0037 0038 #include <QKeyEvent> 0039 #include <QMenu> 0040 #include <QClipboard> 0041 0042 CursorDock::CursorDock(QWidget* parent) : QWidget(parent), ui(new Ui::CursorDock) { 0043 ui->setupUi(this); 0044 ui->tvCursorData->setModel(nullptr); 0045 0046 ui->bCollapseAll->setIcon(QIcon::fromTheme(QLatin1String("collapse-all"))); 0047 ui->bExpandAll->setIcon(QIcon::fromTheme(QLatin1String("expand-all"))); 0048 0049 ui->bCollapseAll->setToolTip(i18n("Collapse all curves")); 0050 ui->bExpandAll->setToolTip(i18n("Expand all curves")); 0051 0052 connect(ui->bCollapseAll, &QPushButton::clicked, this, &CursorDock::collapseAll); 0053 connect(ui->bExpandAll, &QPushButton::clicked, this, &CursorDock::expandAll); 0054 connect(ui->cbCursor0en, &QCheckBox::clicked, this, &CursorDock::cursor0EnableChanged); 0055 connect(ui->cbCursor1en, &QCheckBox::clicked, this, &CursorDock::cursor1EnableChanged); 0056 0057 //CTRL+C copies only the last cell in the selection, we want to copy the whole selection. 0058 //install event filters to handle CTRL+C key events. 0059 ui->tvCursorData->installEventFilter(this); 0060 0061 ui->tvCursorData->setContextMenuPolicy(Qt::CustomContextMenu); 0062 connect(ui->tvCursorData, &QTreeView::customContextMenuRequested, 0063 this, &CursorDock::contextMenuRequested); 0064 } 0065 0066 void CursorDock::setWorksheet(Worksheet* worksheet) { 0067 m_initializing = true; 0068 0069 ui->tvCursorData->setModel(worksheet->cursorModel()); 0070 ui->tvCursorData->resizeColumnToContents(0); 0071 m_plotList = worksheet->children<CartesianPlot>(); 0072 if (m_plotList.isEmpty()) 0073 return; 0074 0075 m_plot = m_plotList.first(); 0076 0077 bool cursor0Enabled = m_plot->cursor0Enable(); 0078 bool cursor1Enabled = m_plot->cursor1Enable(); 0079 ui->cbCursor0en->setChecked(cursor0Enabled); 0080 ui->cbCursor1en->setChecked(cursor1Enabled); 0081 0082 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), !cursor0Enabled); 0083 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), !cursor1Enabled); 0084 if (cursor0Enabled && cursor1Enabled) 0085 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), false); 0086 else 0087 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), true); 0088 0089 ui->tvCursorData->expandAll(); 0090 0091 // connect all plots as a workaround to not be able to know which plot is selected 0092 for (auto connection: selectedPlotsConnection) 0093 disconnect(connection); 0094 for (auto* plot : m_plotList) { 0095 selectedPlotsConnection << connect(plot, &CartesianPlot::cursor0EnableChanged, this, &CursorDock::plotCursor0EnableChanged); 0096 selectedPlotsConnection << connect(plot, &CartesianPlot::cursor1EnableChanged, this, &CursorDock::plotCursor1EnableChanged); 0097 } 0098 0099 m_initializing = false; 0100 } 0101 0102 CursorDock::~CursorDock() { 0103 delete ui; 0104 } 0105 0106 void CursorDock::collapseAll() { 0107 ui->tvCursorData->collapseAll(); 0108 } 0109 0110 void CursorDock::expandAll() { 0111 ui->tvCursorData->expandAll(); 0112 } 0113 0114 void CursorDock::cursor0EnableChanged(bool enable) { 0115 if (m_initializing) 0116 return; 0117 0118 for (auto* plot : m_plotList) 0119 plot->setCursor0Enable(enable); 0120 } 0121 0122 void CursorDock::cursor1EnableChanged(bool enable) { 0123 if (m_initializing) 0124 return; 0125 0126 for (auto* plot : m_plotList) 0127 plot->setCursor1Enable(enable); 0128 } 0129 0130 // ############################################################# 0131 // back from plot 0132 // ############################################################# 0133 void CursorDock::plotCursor0EnableChanged(bool enable) { 0134 m_initializing = true; 0135 0136 ui->cbCursor0en->setChecked(enable); 0137 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR0), !enable); 0138 if (enable && ui->cbCursor1en->isChecked()) 0139 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), false); 0140 else 0141 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), true); 0142 0143 m_initializing = false; 0144 } 0145 0146 void CursorDock::plotCursor1EnableChanged(bool enable) { 0147 m_initializing = true; 0148 0149 ui->cbCursor1en->setChecked(enable); 0150 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSOR1), !enable); 0151 if (enable && ui->cbCursor0en->isChecked()) 0152 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), false); 0153 else 0154 ui->tvCursorData->setColumnHidden(static_cast<int>(WorksheetPrivate::TreeModelColumn::CURSORDIFF), true); 0155 0156 m_initializing = false; 0157 } 0158 0159 bool CursorDock::eventFilter(QObject* obj, QEvent* event) { 0160 if (event->type() == QEvent::KeyPress && obj == ui->tvCursorData) { 0161 auto* key_event = static_cast<QKeyEvent*>(event); 0162 if (key_event->matches(QKeySequence::Copy)) { 0163 resultCopy(); 0164 return true; 0165 } 0166 } 0167 return QWidget::eventFilter(obj, event); 0168 } 0169 0170 void CursorDock::contextMenuRequested(QPoint pos) { 0171 auto* menu = new QMenu; 0172 menu->addAction(i18n("Copy Selection"), this, &CursorDock::resultCopy, QKeySequence::Copy); 0173 menu->addAction(i18n("Copy All"), this, &CursorDock::resultCopyAll); 0174 menu->exec(ui->tvCursorData->mapToGlobal(pos)); 0175 } 0176 0177 void CursorDock::resultCopy() { 0178 QString str; 0179 auto* model = ui->tvCursorData->model(); 0180 auto* selection = ui->tvCursorData->selectionModel(); 0181 const auto& indices = selection->selectedRows(); 0182 for (auto index : indices) { 0183 int row = index.row(); 0184 auto parent = index.parent(); 0185 for (int col = 0; col < model->columnCount(); ++col) { 0186 if (col != 0) 0187 str += QLatin1Char('\t'); 0188 str += model->data(model->index(row, col, parent)).toString(); 0189 } 0190 0191 str += QLatin1Char('\n'); 0192 } 0193 0194 QApplication::clipboard()->setText(str); 0195 } 0196 0197 void CursorDock::resultCopyAll() { 0198 QString str; 0199 auto* model = ui->tvCursorData->model(); 0200 for (int row = 0; row < model->rowCount(); ++row) { 0201 for (int col = 0; col < model->columnCount(); ++col) { 0202 if (col != 0) 0203 str += QLatin1Char('\t'); 0204 str += model->data(model->index(row, col)).toString(); 0205 } 0206 0207 str += QLatin1Char('\n'); 0208 0209 //iterate over all children of the current row 0210 auto index = model->index(row, 0); 0211 for (int row = 0; row < model->rowCount(index); ++row) { 0212 for (int col = 0; col < model->columnCount(); ++col) { 0213 if (col != 0) 0214 str += QLatin1Char('\t'); 0215 str += model->data(model->index(row, col, index)).toString(); 0216 } 0217 0218 str += QLatin1Char('\n'); 0219 } 0220 } 0221 0222 QApplication::clipboard()->setText(str); 0223 }