fix(product-suite): own original image drag lifecycle
This commit is contained in:
@@ -12,6 +12,7 @@ from PySide6.QtCore import (
|
||||
QByteArray,
|
||||
QBuffer,
|
||||
QIODevice,
|
||||
QMimeData,
|
||||
QPointF,
|
||||
QRect,
|
||||
QRegularExpression,
|
||||
@@ -23,6 +24,7 @@ from PySide6.QtCore import (
|
||||
)
|
||||
from PySide6.QtGui import (
|
||||
QColor,
|
||||
QDrag,
|
||||
QFont,
|
||||
QIcon,
|
||||
QImage,
|
||||
@@ -283,10 +285,12 @@ class ProductOriginalDelegate(QStyledItemDelegate):
|
||||
class ProductOriginalList(QListWidget):
|
||||
MAX_VISIBLE_ASSETS = 16
|
||||
EMPTY_STATE_TEXT = "暂无商品原图"
|
||||
INTERNAL_MIME_TYPE = "application/x-cmshopee-product-original"
|
||||
|
||||
filesDropped = Signal(list)
|
||||
clipboardImage = Signal(bytes)
|
||||
orderChanged = Signal(list)
|
||||
orderRestoreRequested = Signal()
|
||||
deleteRequested = Signal(int)
|
||||
deleteAssetsRequested = Signal(list)
|
||||
checkedAssetsChanged = Signal(list)
|
||||
@@ -369,7 +373,12 @@ class ProductOriginalList(QListWidget):
|
||||
if event.mimeData().hasUrls():
|
||||
event.acceptProposedAction()
|
||||
return
|
||||
if event.source() is self and self._reordering_enabled and self._dragged_item is not None:
|
||||
if (
|
||||
event.source() is self
|
||||
and event.mimeData().hasFormat(self.INTERNAL_MIME_TYPE)
|
||||
and self._reordering_enabled
|
||||
and self._dragged_item is not None
|
||||
):
|
||||
event.setDropAction(Qt.MoveAction)
|
||||
event.accept()
|
||||
return
|
||||
@@ -382,7 +391,11 @@ class ProductOriginalList(QListWidget):
|
||||
if not self._reordering_enabled:
|
||||
event.ignore()
|
||||
return
|
||||
if event.source() is self and self._dragged_item is not None:
|
||||
if (
|
||||
event.source() is self
|
||||
and event.mimeData().hasFormat(self.INTERNAL_MIME_TYPE)
|
||||
and self._dragged_item is not None
|
||||
):
|
||||
event.setDropAction(Qt.MoveAction)
|
||||
event.accept()
|
||||
return
|
||||
@@ -397,7 +410,10 @@ class ProductOriginalList(QListWidget):
|
||||
if not self._reordering_enabled:
|
||||
event.ignore()
|
||||
return
|
||||
if event.source() is not self:
|
||||
if (
|
||||
event.source() is not self
|
||||
or not event.mimeData().hasFormat(self.INTERNAL_MIME_TYPE)
|
||||
):
|
||||
event.ignore()
|
||||
return
|
||||
if not self._move_dragged_item_to(event.position().toPoint()):
|
||||
@@ -410,10 +426,22 @@ class ProductOriginalList(QListWidget):
|
||||
item = self.currentItem()
|
||||
if not self._begin_internal_drag(item):
|
||||
return
|
||||
drag = QDrag(self)
|
||||
mime_data = QMimeData()
|
||||
mime_data.setData(
|
||||
self.INTERNAL_MIME_TYPE,
|
||||
QByteArray(str(int(item.data(Qt.UserRole))).encode("ascii")),
|
||||
)
|
||||
drag.setMimeData(mime_data)
|
||||
pixmap = item.icon().pixmap(self.iconSize())
|
||||
if not pixmap.isNull():
|
||||
drag.setPixmap(pixmap)
|
||||
drag.setHotSpot(pixmap.rect().center())
|
||||
completed_action = Qt.IgnoreAction
|
||||
try:
|
||||
super().startDrag(Qt.MoveAction)
|
||||
completed_action = drag.exec(Qt.MoveAction, Qt.MoveAction)
|
||||
finally:
|
||||
self._finish_internal_drag()
|
||||
self._finish_internal_drag(completed_action == Qt.MoveAction)
|
||||
|
||||
def _begin_internal_drag(self, item):
|
||||
if (
|
||||
@@ -430,7 +458,7 @@ class ProductOriginalList(QListWidget):
|
||||
self._pending_order = None
|
||||
return True
|
||||
|
||||
def _finish_internal_drag(self):
|
||||
def _finish_internal_drag(self, move_completed=True):
|
||||
pending_order = self._pending_order
|
||||
drag_start_ids = self._drag_start_ids
|
||||
self._dragged_item = None
|
||||
@@ -440,11 +468,13 @@ class ProductOriginalList(QListWidget):
|
||||
return False
|
||||
current_ids = self.asset_ids()
|
||||
if (
|
||||
current_ids != pending_order
|
||||
not move_completed
|
||||
or current_ids != pending_order
|
||||
or len(pending_order) != len(set(pending_order))
|
||||
or len(pending_order) != len(drag_start_ids)
|
||||
or set(pending_order) != set(drag_start_ids)
|
||||
):
|
||||
self.orderRestoreRequested.emit()
|
||||
return False
|
||||
self.orderChanged.emit(list(pending_order))
|
||||
return True
|
||||
@@ -2574,6 +2604,7 @@ class ProductSuiteTab(QWidget):
|
||||
self.original_list.filesDropped.connect(self.import_files)
|
||||
self.original_list.clipboardImage.connect(self.import_clipboard_image)
|
||||
self.original_list.orderChanged.connect(self.reorder_originals)
|
||||
self.original_list.orderRestoreRequested.connect(self._restore_original_order_after_drag)
|
||||
self.original_list.deleteRequested.connect(self.delete_original)
|
||||
self.original_list.deleteAssetsRequested.connect(self.delete_originals)
|
||||
self.original_list.checkedAssetsChanged.connect(self._on_original_checks_changed)
|
||||
@@ -3738,6 +3769,13 @@ class ProductSuiteTab(QWidget):
|
||||
self._status("已更新商品原图顺序,第一张图片为主图", "success")
|
||||
self._refresh_originals(state)
|
||||
|
||||
def _restore_original_order_after_drag(self):
|
||||
state = self._displayed_state
|
||||
if state is None or state.project_id is None:
|
||||
return
|
||||
self._refresh_originals(state)
|
||||
self._status("原图排序未完成,已恢复原顺序,请重试", "warning")
|
||||
|
||||
def _asset_for_item(self, item):
|
||||
state = self._displayed_state
|
||||
if state is None or item is None:
|
||||
|
||||
Reference in New Issue
Block a user