149 lines
4.7 KiB
Python
149 lines
4.7 KiB
Python
|
|
"""
|
||
|
|
映射图管理控件
|
||
|
|
结合图形化编辑器和列表管理
|
||
|
|
"""
|
||
|
|
from PyQt5.QtWidgets import (
|
||
|
|
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
||
|
|
QSplitter, QGroupBox, QListWidget, QListWidgetItem,
|
||
|
|
QMessageBox, QLabel
|
||
|
|
)
|
||
|
|
from PyQt5.QtCore import Qt, pyqtSignal
|
||
|
|
|
||
|
|
from controllers.mapping_controller import MappingController
|
||
|
|
from controllers.field_controller import FieldController
|
||
|
|
from ui.widgets.graph_view_widget import GraphViewWidget
|
||
|
|
from utils.logger import get_logger
|
||
|
|
|
||
|
|
logger = get_logger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
class MappingManagementWidget(QWidget):
|
||
|
|
"""映射管理控件"""
|
||
|
|
|
||
|
|
mapping_selected = pyqtSignal(object)
|
||
|
|
|
||
|
|
def __init__(self, mapping_controller: MappingController,
|
||
|
|
field_controller: FieldController):
|
||
|
|
super().__init__()
|
||
|
|
self.mapping_controller = mapping_controller
|
||
|
|
self.field_controller = field_controller
|
||
|
|
self.current_mapping = None
|
||
|
|
|
||
|
|
self.init_ui()
|
||
|
|
self.load_mappings()
|
||
|
|
|
||
|
|
def init_ui(self):
|
||
|
|
"""初始化UI"""
|
||
|
|
main_layout = QVBoxLayout(self)
|
||
|
|
|
||
|
|
# 工具栏
|
||
|
|
toolbar_layout = QHBoxLayout()
|
||
|
|
|
||
|
|
self.add_mapping_btn = QPushButton("新建映射")
|
||
|
|
self.add_mapping_btn.clicked.connect(self.on_add_mapping)
|
||
|
|
|
||
|
|
self.delete_mapping_btn = QPushButton("删除映射")
|
||
|
|
self.delete_mapping_btn.clicked.connect(self.on_delete_mapping)
|
||
|
|
|
||
|
|
self.auto_layout_btn = QPushButton("自动布局")
|
||
|
|
self.auto_layout_btn.clicked.connect(self.on_auto_layout)
|
||
|
|
|
||
|
|
self.refresh_btn = QPushButton("刷新")
|
||
|
|
self.refresh_btn.clicked.connect(self.load_mappings)
|
||
|
|
|
||
|
|
toolbar_layout.addWidget(self.add_mapping_btn)
|
||
|
|
toolbar_layout.addWidget(self.delete_mapping_btn)
|
||
|
|
toolbar_layout.addWidget(self.auto_layout_btn)
|
||
|
|
toolbar_layout.addWidget(self.refresh_btn)
|
||
|
|
toolbar_layout.addStretch()
|
||
|
|
|
||
|
|
main_layout.addLayout(toolbar_layout)
|
||
|
|
|
||
|
|
# 分割器
|
||
|
|
splitter = QSplitter(Qt.Horizontal)
|
||
|
|
|
||
|
|
# 左侧:映射列表
|
||
|
|
left_widget = QWidget()
|
||
|
|
left_layout = QVBoxLayout(left_widget)
|
||
|
|
|
||
|
|
list_label = QLabel("映射列表:")
|
||
|
|
left_layout.addWidget(list_label)
|
||
|
|
|
||
|
|
self.mapping_list = QListWidget()
|
||
|
|
self.mapping_list.itemClicked.connect(self.on_mapping_clicked)
|
||
|
|
left_layout.addWidget(self.mapping_list)
|
||
|
|
|
||
|
|
# 右侧:图形化视图
|
||
|
|
right_widget = QWidget()
|
||
|
|
right_layout = QVBoxLayout(right_widget)
|
||
|
|
|
||
|
|
graph_label = QLabel("映射图:")
|
||
|
|
right_layout.addWidget(graph_label)
|
||
|
|
|
||
|
|
self.graph_view = GraphViewWidget()
|
||
|
|
right_layout.addWidget(self.graph_view)
|
||
|
|
|
||
|
|
splitter.addWidget(left_widget)
|
||
|
|
splitter.addWidget(right_widget)
|
||
|
|
splitter.setStretchFactor(0, 1)
|
||
|
|
splitter.setStretchFactor(1, 3)
|
||
|
|
|
||
|
|
main_layout.addWidget(splitter)
|
||
|
|
|
||
|
|
def load_mappings(self):
|
||
|
|
"""加载映射列表"""
|
||
|
|
self.mapping_list.clear()
|
||
|
|
|
||
|
|
# 加载映射图
|
||
|
|
graph = self.mapping_controller.get_mapping_graph()
|
||
|
|
if graph:
|
||
|
|
self.graph_view.load_graph(graph)
|
||
|
|
|
||
|
|
# 显示边(映射)列表
|
||
|
|
for edge in graph.edges:
|
||
|
|
item_text = f"{edge.mapping.source_field.full_name} -> {edge.mapping.target_field.full_name}"
|
||
|
|
item = QListWidgetItem(item_text)
|
||
|
|
item.setData(Qt.UserRole, edge.mapping)
|
||
|
|
self.mapping_list.addItem(item)
|
||
|
|
|
||
|
|
def on_mapping_clicked(self, item: QListWidgetItem):
|
||
|
|
"""映射被点击"""
|
||
|
|
mapping = item.data(Qt.UserRole)
|
||
|
|
if mapping:
|
||
|
|
self.current_mapping = mapping
|
||
|
|
self.mapping_selected.emit(mapping)
|
||
|
|
|
||
|
|
def on_add_mapping(self):
|
||
|
|
"""新建映射"""
|
||
|
|
from ui.dialogs.mapping_dialog import MappingDialog
|
||
|
|
|
||
|
|
dialog = MappingDialog(self)
|
||
|
|
if dialog.exec_():
|
||
|
|
self.load_mappings()
|
||
|
|
|
||
|
|
def on_delete_mapping(self):
|
||
|
|
"""删除映射"""
|
||
|
|
if not self.current_mapping:
|
||
|
|
QMessageBox.warning(self, "警告", "请先选择要删除的映射")
|
||
|
|
return
|
||
|
|
|
||
|
|
reply = QMessageBox.question(
|
||
|
|
self,
|
||
|
|
"确认删除",
|
||
|
|
"确定要删除该映射吗?",
|
||
|
|
QMessageBox.Yes | QMessageBox.No
|
||
|
|
)
|
||
|
|
|
||
|
|
if reply == QMessageBox.Yes:
|
||
|
|
if hasattr(self.current_mapping, 'id'):
|
||
|
|
success, msg = self.mapping_controller.delete_mapping(self.current_mapping.id)
|
||
|
|
if success:
|
||
|
|
QMessageBox.information(self, "成功", msg)
|
||
|
|
self.load_mappings()
|
||
|
|
else:
|
||
|
|
QMessageBox.warning(self, "失败", msg)
|
||
|
|
|
||
|
|
def on_auto_layout(self):
|
||
|
|
"""自动布局"""
|
||
|
|
self.graph_view.auto_layout()
|