geometry: Profile: Copy/Paste using system clipboard.

mesh
Pierre-Antoine Rouby 2023-04-26 17:13:10 +02:00
parent 012f7ce445
commit e4c07e0e3e
8 changed files with 77 additions and 21 deletions

View File

@ -14,6 +14,29 @@ class PointXYZ(Point):
self._y = float(y) self._y = float(y)
self._z = float(z) 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): def __repr__(self):
return f"({self._x}, {self._y}, {self._z}, {self._name})" return f"({self._x}, {self._y}, {self._z}, {self._name})"

View File

@ -5,6 +5,7 @@ from typing import List
from tools import timer from tools import timer
from Model.Except import ClipboardFormatError
from Model.Geometry.Profile import Profile from Model.Geometry.Profile import Profile
from Model.Geometry.PointXYZ import PointXYZ from Model.Geometry.PointXYZ import PointXYZ
from Model.Geometry.Vector_1d import Vector1d from Model.Geometry.Vector_1d import Vector1d

View File

@ -20,6 +20,8 @@ from PyQt5.QtCore import (
) )
from PyQt5.uic import loadUi from PyQt5.uic import loadUi
from Model.Except import ClipboardFormatError
class WindowToolKit(object): class WindowToolKit(object):
def __init__(self, parent=None): def __init__(self, parent=None):
super(WindowToolKit, self).__init__() super(WindowToolKit, self).__init__()

View File

@ -386,6 +386,9 @@ class GeometryWindow(QMainWindow, WindowToolKit):
def paste(self): def paste(self):
header, data = self.parseClipboardTable() header, data = self.parseClipboardTable()
if len(data) == 0:
return
if len(header) != 0: if len(header) != 0:
header.append("reach") header.append("reach")
for row in data: for row in data:

View File

@ -141,8 +141,8 @@ class PasteCommand(QUndoCommand):
self._points.reverse() self._points.reverse()
def undo(self): def undo(self):
for ind in range(len(self._profiles)): for ind in range(len(self._points)):
self._profile.delete(self._row) self._profile.delete([self._row])
def redo(self): def redo(self):
for point in self._points: for point in self._points:

View File

@ -18,18 +18,17 @@ from PyQt5.QtWidgets import (
QUndoStack, QShortcut, QUndoStack, QShortcut,
) )
from View.ASubWindow import WindowToolKit
from View.Geometry.Profile.mainwindow_ui_profile import Ui_MainWindow from View.Geometry.Profile.mainwindow_ui_profile import Ui_MainWindow
from View.Geometry.Profile.Plot import Plot from View.Geometry.Profile.Plot import Plot
from View.Geometry.Profile.qtableview_profile import *
from Model.Geometry.Reach import Reach from Model.Geometry.Reach import Reach
from Model.Geometry.ProfileXYZ import ProfileXYZ from Model.Geometry.ProfileXYZ import ProfileXYZ
from View.Geometry.Profile.qtableview_profile import *
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
class ProfileWindow(QMainWindow): class ProfileWindow(QMainWindow, WindowToolKit):
def __init__(self, profile=None, parent=None): def __init__(self, profile=None, parent=None):
self.parent = parent self.parent = parent
super(ProfileWindow, self).__init__(self.parent) super(ProfileWindow, self).__init__(self.parent)
@ -132,6 +131,12 @@ class ProfileWindow(QMainWindow):
self.ui.tableView.model().blockSignals(False) self.ui.tableView.model().blockSignals(False)
def index_selected_row(self): def index_selected_row(self):
rows = self.ui.tableView\
.selectionModel()\
.selectedRows()
if len(rows) == 0:
return 0
return self.ui.tableView\ return self.ui.tableView\
.selectionModel()\ .selectionModel()\
.selectedRows()[0]\ .selectedRows()[0]\
@ -201,23 +206,36 @@ class ProfileWindow(QMainWindow):
self.update_plot() self.update_plot()
def copy(self): def copy(self):
rows = self.tableView\ rows = self.ui.tableView\
.selectionModel()\ .selectionModel()\
.selectedRows() .selectedRows()
table = []
self._clipboard = [] table.append(["x", "y", "z", "name"])
for row in rows: for row in rows:
self._clipboard.append( point = self._profile.point(row.row())
deepcopy( table.append(
self._reach.profile(row.row()) [
) point.x, point.y, point.z, point.name
]
) )
self.copyTableIntoClipboard(table)
def paste(self): 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() row = self.index_selected_row()
self._model.paste(row, self._clipboard) self._model.paste(row, header, data)
self.select_current_profile() self.update_plot()
def undo(self): def undo(self):
self._model.undo() self._model.undo()

View File

@ -1,6 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import numpy as np import numpy as np
from tools import timer, trace
from PyQt5.QtGui import ( from PyQt5.QtGui import (
QFont, QColor QFont, QColor
) )
@ -12,6 +15,7 @@ from PyQt5.QtCore import (
QVariant, QCoreApplication QVariant, QCoreApplication
) )
from Model.Geometry.PointXYZ import PointXYZ
from Model.Geometry.ProfileXYZ import ProfileXYZ from Model.Geometry.ProfileXYZ import ProfileXYZ
from View.Geometry.Profile.ProfileUndoCommand import * from View.Geometry.Profile.ProfileUndoCommand import *
@ -259,18 +263,24 @@ class TableEditableModel(QAbstractTableModel):
self.endMoveRows() self.endMoveRows()
self.layoutChanged.emit() self.layoutChanged.emit()
def paste(self, row, points): def paste(self, row, header, data):
if row > self._profile.number_points: if row > self._profile.number_points:
return return
if len(points) == 0: if len(data) == 0:
return return
self.layoutAboutToBeChanged.emit() self.layoutAboutToBeChanged.emit()
self._undo_stack.push( self._undo_stack.push(
PasteCommand( PasteCommand(
self._profile, row, points self._profile, row,
list(
map(
lambda d: PointXYZ.from_data(header, d),
data
)
)
) )
) )

View File

@ -212,7 +212,6 @@ class TableEditableModel(QAbstractTableModel):
self.endMoveRows() self.endMoveRows()
self.layoutChanged.emit() self.layoutChanged.emit()
@trace
def paste(self, row, header, data): def paste(self, row, header, data):
if row > self._reach.number_profiles: if row > self._reach.number_profiles:
return return