[core] add copy table and paste table context menu items to App::PropertyVectorList property editor, addresses issue #17804

This commit is contained in:
mwganson
2024-11-14 01:31:04 +00:00
committed by Yorik van Havre
parent 30177e2cf2
commit c04bf0f075
2 changed files with 96 additions and 0 deletions

View File

@@ -26,6 +26,12 @@
#include "ui_VectorListEditor.h"
#include "QuantitySpinBox.h"
#include <Base/Console.h>
#include <QClipboard>
#include <QMimeData>
#include <QTextStream>
using namespace Gui;
@@ -132,6 +138,74 @@ void VectorTableModel::setValues(const QList<Base::Vector3d>& d)
endResetModel();
}
void Gui::VectorTableModel::copyToClipboard() const
{
QString clipboardText;
QTextStream stream(&clipboardText);
for (const auto& vector : vectors) {
stream << QString::number(vector.x, 'f', decimals) << '\t'
<< QString::number(vector.y, 'f', decimals) << '\t'
<< QString::number(vector.z, 'f', decimals) << '\n';
}
QApplication::clipboard()->setText(clipboardText);
}
void Gui::VectorTableModel::pasteFromClipboard()
{
QClipboard *clipboard = QApplication::clipboard();
QStringList lines = clipboard->text().split(QLatin1Char('\n'));
bool okAll = !lines.empty();
QList<Base::Vector3d> newVectors;
QLatin1Char tab('\t');
QLatin1Char semicolon(';');
QLatin1Char comma(',');
for (const QString& line : lines) {
if (line.isEmpty()) {
continue;
}
QChar delimiter = line.count(tab) == 2 ? tab
: line.count(semicolon) == 2 ? semicolon
: line.count(comma) == 2 ? comma
: QChar(QChar::Null);
if (delimiter.isNull()) {
okAll = false;
break;
}
QStringList components = line.split(delimiter);
if (components.size() == 3) {
bool okX, okY, okZ;
double x = components.at(0).toDouble(&okX);
double y = components.at(1).toDouble(&okY);
double z = components.at(2).toDouble(&okZ);
if (!okX || !okY || !okZ) {
okAll = false;
break;
}
newVectors.append(Base::Vector3d(x, y, z));
}
else {
okAll = false;
break;
}
}
if (okAll) {
setValues(newVectors);
}
else {
QString msg(tr("Unsupported format. Must be 3 values per row separated by tabs, semicolons, or commas:") + QLatin1String("\n"));
msg += clipboard->text();
Base::Console().Error(msg.toStdString().c_str());
}
}
const QList<Base::Vector3d>& VectorTableModel::values() const
{
return vectors;
@@ -238,10 +312,28 @@ VectorListEditor::VectorListEditor(int decimals, QWidget* parent)
connect(ui->toolButtonRemove, &QToolButton::clicked, this, &VectorListEditor::removeRow);
connect(ui->toolButtonAccept, &QToolButton::clicked, this, &VectorListEditor::acceptCurrent);
connect(ui->tableWidget, &QTableView::clicked, this, &VectorListEditor::clickedRow);
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->tableWidget, &QWidget::customContextMenuRequested, this, &VectorListEditor::showContextMenu);
}
VectorListEditor::~VectorListEditor() = default;
void VectorListEditor::showContextMenu(const QPoint& pos)
{
QMenu contextMenu(ui->tableWidget);
QAction *copyAction = contextMenu.addAction(tr("Copy table"));
connect(copyAction, &QAction::triggered, model, &VectorTableModel::copyToClipboard);
copyAction->setEnabled(!data.empty());
QAction *pasteAction = contextMenu.addAction(tr("Paste table"));
connect(pasteAction, &QAction::triggered, model, &VectorTableModel::pasteFromClipboard);
pasteAction->setEnabled(QApplication::clipboard()->mimeData()->hasText());
contextMenu.exec(ui->tableWidget->viewport()->mapToGlobal(pos));
}
void VectorListEditor::setValues(const QList<Base::Vector3d>& v)
{
data = v;

View File

@@ -27,6 +27,7 @@
#include <QDialog>
#include <QItemDelegate>
#include <QList>
#include <QMenu>
#include <memory>
#include <Base/Vector3D.h>
@@ -49,6 +50,8 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QModelIndex parent(const QModelIndex &index) const override;
void setValues(const QList<Base::Vector3d>& d);
void copyToClipboard() const;
void pasteFromClipboard();
const QList<Base::Vector3d>& values() const;
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
@@ -100,6 +103,7 @@ private Q_SLOTS:
void acceptCurrent();
void setCurrentRow(int);
void clickedRow(const QModelIndex&);
void showContextMenu(const QPoint&);
private:
std::unique_ptr<Ui_VectorListEditor> ui;