diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py index 7df8123c8c4d5b3d5bdf7ed636894b57313dda09..78d5a09fb5f8aee6001c212f44e65c3d2894e700 100644 --- a/src/Model/Geometry/PointXYZ.py +++ b/src/Model/Geometry/PointXYZ.py @@ -14,6 +14,29 @@ class PointXYZ(Point): self._y = float(y) self._z = float(z) + @classmethod + def from_data(cls, header, data): + point = None + try: + if len(header) == 0: + point = cls( + *data + ) + else: + valid_header = {'name', 'x', 'y', 'z'} + d = {} + for i, v in enumerate(data): + h = header[i].strip().lower().split(' ')[0] + if h in valid_header: + d[h] = v + + point = cls(**d) + except Exception as e: + raise ClipboardFormatError(header, data) + + return point + + def __repr__(self): return f"({self._x}, {self._y}, {self._z}, {self._name})" diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 1f2b0dddb43b69ed017e96f4e09d4181d84a7e61..5edff60dfc3b3aa8f43e65efeaf9f991b19f5f58 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -5,6 +5,7 @@ from typing import List from tools import timer +from Model.Except import ClipboardFormatError from Model.Geometry.Profile import Profile from Model.Geometry.PointXYZ import PointXYZ from Model.Geometry.Vector_1d import Vector1d diff --git a/src/View/ASubWindow.py b/src/View/ASubWindow.py index 89fd37b3d6c624bfb95116242a85b0bce55e4a55..9dd04f123c82ca477681ccabf796aac258dccbb2 100644 --- a/src/View/ASubWindow.py +++ b/src/View/ASubWindow.py @@ -20,6 +20,8 @@ from PyQt5.QtCore import ( ) from PyQt5.uic import loadUi +from Model.Except import ClipboardFormatError + class WindowToolKit(object): def __init__(self, parent=None): super(WindowToolKit, self).__init__() diff --git a/src/View/Geometry/GeometryWindow.py b/src/View/Geometry/GeometryWindow.py index 3c162535f1871aa03a5bb8dcc2c571bbc503ef2f..7fc7f85164a9ffb86a3fe3d2c443983c173f458d 100644 --- a/src/View/Geometry/GeometryWindow.py +++ b/src/View/Geometry/GeometryWindow.py @@ -386,6 +386,9 @@ class GeometryWindow(QMainWindow, WindowToolKit): def paste(self): header, data = self.parseClipboardTable() + if len(data) == 0: + return + if len(header) != 0: header.append("reach") for row in data: diff --git a/src/View/Geometry/Profile/ProfileUndoCommand.py b/src/View/Geometry/Profile/ProfileUndoCommand.py index 7036d6613311a844e280a3ef0a61d795b3451e5d..d0d45b990af3c56b1041c59bfbf57cbdcbaeff74 100644 --- a/src/View/Geometry/Profile/ProfileUndoCommand.py +++ b/src/View/Geometry/Profile/ProfileUndoCommand.py @@ -141,8 +141,8 @@ class PasteCommand(QUndoCommand): self._points.reverse() def undo(self): - for ind in range(len(self._profiles)): - self._profile.delete(self._row) + for ind in range(len(self._points)): + self._profile.delete([self._row]) def redo(self): for point in self._points: diff --git a/src/View/Geometry/Profile/ProfileWindow.py b/src/View/Geometry/Profile/ProfileWindow.py index d17d98d0212b216457114c27f1f6838912ed7b7c..3654b8051050353bf9d1f94e0e03bc67f5b3471f 100644 --- a/src/View/Geometry/Profile/ProfileWindow.py +++ b/src/View/Geometry/Profile/ProfileWindow.py @@ -18,18 +18,17 @@ from PyQt5.QtWidgets import ( QUndoStack, QShortcut, ) +from View.ASubWindow import WindowToolKit from View.Geometry.Profile.mainwindow_ui_profile import Ui_MainWindow - from View.Geometry.Profile.Plot import Plot - +from View.Geometry.Profile.qtableview_profile import * from Model.Geometry.Reach import Reach from Model.Geometry.ProfileXYZ import ProfileXYZ -from View.Geometry.Profile.qtableview_profile import * _translate = QCoreApplication.translate -class ProfileWindow(QMainWindow): +class ProfileWindow(QMainWindow, WindowToolKit): def __init__(self, profile=None, parent=None): self.parent = parent super(ProfileWindow, self).__init__(self.parent) @@ -132,6 +131,12 @@ class ProfileWindow(QMainWindow): self.ui.tableView.model().blockSignals(False) def index_selected_row(self): + rows = self.ui.tableView\ + .selectionModel()\ + .selectedRows() + if len(rows) == 0: + return 0 + return self.ui.tableView\ .selectionModel()\ .selectedRows()[0]\ @@ -201,23 +206,36 @@ class ProfileWindow(QMainWindow): self.update_plot() def copy(self): - rows = self.tableView\ - .selectionModel()\ - .selectedRows() - - self._clipboard = [] + rows = self.ui.tableView\ + .selectionModel()\ + .selectedRows() + table = [] + table.append(["x", "y", "z", "name"]) for row in rows: - self._clipboard.append( - deepcopy( - self._reach.profile(row.row()) - ) + point = self._profile.point(row.row()) + table.append( + [ + point.x, point.y, point.z, point.name + ] ) + self.copyTableIntoClipboard(table) + def paste(self): + header, data = self.parseClipboardTable() + + if len(data) == 0: + return + + if len(header) != 0: + header.append("profile") + for row in data: + row.append(self._profile) + row = self.index_selected_row() - self._model.paste(row, self._clipboard) - self.select_current_profile() + self._model.paste(row, header, data) + self.update_plot() def undo(self): self._model.undo() diff --git a/src/View/Geometry/Profile/qtableview_profile.py b/src/View/Geometry/Profile/qtableview_profile.py index 7ba364e96641a4761ef53ee15f96cc1df5f696a6..5cba2a16613e22f2cf85162a6224eefd48a231fb 100644 --- a/src/View/Geometry/Profile/qtableview_profile.py +++ b/src/View/Geometry/Profile/qtableview_profile.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- import numpy as np + +from tools import timer, trace + from PyQt5.QtGui import ( QFont, QColor ) @@ -12,6 +15,7 @@ from PyQt5.QtCore import ( QVariant, QCoreApplication ) +from Model.Geometry.PointXYZ import PointXYZ from Model.Geometry.ProfileXYZ import ProfileXYZ from View.Geometry.Profile.ProfileUndoCommand import * @@ -259,18 +263,24 @@ class TableEditableModel(QAbstractTableModel): self.endMoveRows() self.layoutChanged.emit() - def paste(self, row, points): + def paste(self, row, header, data): if row > self._profile.number_points: return - if len(points) == 0: + if len(data) == 0: return self.layoutAboutToBeChanged.emit() self._undo_stack.push( PasteCommand( - self._profile, row, points + self._profile, row, + list( + map( + lambda d: PointXYZ.from_data(header, d), + data + ) + ) ) ) diff --git a/src/View/Geometry/qtableview_reach.py b/src/View/Geometry/qtableview_reach.py index bf6d28ef396c2930580a865d72ca5c8a27b18ce7..db4aba722af8140a78b8ea5d38d3615b55580752 100644 --- a/src/View/Geometry/qtableview_reach.py +++ b/src/View/Geometry/qtableview_reach.py @@ -212,7 +212,6 @@ class TableEditableModel(QAbstractTableModel): self.endMoveRows() self.layoutChanged.emit() - @trace def paste(self, row, header, data): if row > self._reach.number_profiles: return