mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-18 07:23:03 +08:00
273 lines
7.2 KiB
Python
273 lines
7.2 KiB
Python
"""
|
|
Conditional block widget for the AutoScript orchestration dialog.
|
|
"""
|
|
from PySide6.QtCore import Slot
|
|
from PySide6.QtWidgets import (
|
|
QComboBox,
|
|
QGroupBox,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QPushButton,
|
|
QSizePolicy,
|
|
QVBoxLayout,
|
|
QWidget,
|
|
)
|
|
|
|
from gui.ALAutoScriptOrchDialog._widgets import (
|
|
ActionStepFrame,
|
|
ConditionRowFrame,
|
|
)
|
|
|
|
|
|
class ConditionalBlock(QGroupBox):
|
|
|
|
def __init__(
|
|
self,
|
|
blockIndex: int,
|
|
varMgr = None,
|
|
parent = None
|
|
):
|
|
|
|
super().__init__(parent)
|
|
self.blockIndex = blockIndex
|
|
self._varMgr = varMgr
|
|
self._actionWidgets = []
|
|
self._conditionRows = []
|
|
|
|
self.setupUi()
|
|
self.connectSignals()
|
|
self.addInitialConditionRow()
|
|
|
|
|
|
def setupUi(
|
|
self
|
|
):
|
|
|
|
self.setUpdatesEnabled(False)
|
|
self.setStyleSheet(
|
|
"QGroupBox { font-weight: bold; border: 1px solid #ccc; "
|
|
"margin-top: 5px; padding-top: 5px; }"
|
|
)
|
|
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
|
mainLayout = QVBoxLayout(self)
|
|
mainLayout.setSpacing(6)
|
|
mainLayout.setContentsMargins(8, 8, 8, 8)
|
|
|
|
headerLayout = QHBoxLayout()
|
|
headerLayout.setSpacing(8)
|
|
self.typeCombo = QComboBox(self)
|
|
self.typeCombo.addItem("IF", "IF")
|
|
self.typeCombo.addItem("ELSE IF", "ELSE IF")
|
|
self.typeCombo.addItem("ELSE", "ELSE")
|
|
self.typeCombo.setFixedHeight(25)
|
|
if self.blockIndex == 0:
|
|
self.typeCombo.setEnabled(False)
|
|
headerLayout.addWidget(QLabel("类型:", self))
|
|
headerLayout.addWidget(self.typeCombo)
|
|
headerLayout.addStretch()
|
|
self.deleteBlockBtn = QPushButton("删除此块", self)
|
|
self.deleteBlockBtn.setStyleSheet("color: red;")
|
|
self.deleteBlockBtn.setFixedHeight(25)
|
|
headerLayout.addWidget(self.deleteBlockBtn)
|
|
mainLayout.addLayout(headerLayout)
|
|
|
|
self.conditionWidget = QWidget(self)
|
|
self.conditionWidget.setSizePolicy(
|
|
QSizePolicy.Preferred, QSizePolicy.Preferred
|
|
)
|
|
condLayout = QVBoxLayout(self.conditionWidget)
|
|
condLayout.setContentsMargins(4, 4, 4, 4)
|
|
condLayout.setSpacing(6)
|
|
|
|
self.condRowsLayout = QVBoxLayout()
|
|
self.condRowsLayout.setSpacing(4)
|
|
condLayout.addLayout(self.condRowsLayout)
|
|
self.addCondBtn = QPushButton("+ 添加条件", self.conditionWidget)
|
|
self.addCondBtn.setFixedHeight(25)
|
|
condLayout.addWidget(self.addCondBtn)
|
|
mainLayout.addWidget(self.conditionWidget)
|
|
self.actionLabel = QLabel("执行步骤:", self)
|
|
self.actionLabel.setFixedHeight(25)
|
|
mainLayout.addWidget(self.actionLabel)
|
|
self.actionsLayout = QVBoxLayout()
|
|
self.actionsLayout.setSpacing(4)
|
|
mainLayout.addLayout(self.actionsLayout)
|
|
self.addActionBtn = QPushButton("+ 添加执行步骤", self)
|
|
self.addActionBtn.setFixedHeight(25)
|
|
mainLayout.addWidget(self.addActionBtn)
|
|
self.setUpdatesEnabled(True)
|
|
|
|
|
|
def connectSignals(
|
|
self
|
|
):
|
|
|
|
self.typeCombo.currentIndexChanged.connect(self.onTypeChanged)
|
|
self.addCondBtn.clicked.connect(self.addConditionRow)
|
|
self.addActionBtn.clicked.connect(self.addActionStep)
|
|
|
|
|
|
def addInitialConditionRow(
|
|
self
|
|
):
|
|
|
|
row = ConditionRowFrame(
|
|
self._varMgr, self.blockIndex,
|
|
isFirst=True, parent=self
|
|
)
|
|
self._conditionRows.append(row)
|
|
self.condRowsLayout.addWidget(row)
|
|
|
|
|
|
def addConditionRow(
|
|
self
|
|
):
|
|
|
|
row = ConditionRowFrame(
|
|
self._varMgr, self.blockIndex,
|
|
isFirst=False, parent=self
|
|
)
|
|
row.deleteBtn.clicked.connect(lambda: self.removeConditionRow(row))
|
|
self._conditionRows.append(row)
|
|
self.condRowsLayout.addWidget(row)
|
|
|
|
|
|
def removeConditionRow(
|
|
self,
|
|
row: ConditionRowFrame
|
|
):
|
|
|
|
if row in self._conditionRows and len(self._conditionRows) > 1:
|
|
self._conditionRows.remove(row)
|
|
self.condRowsLayout.removeWidget(row)
|
|
row.hide()
|
|
row.deleteLater()
|
|
|
|
|
|
def addActionStep(
|
|
self
|
|
):
|
|
|
|
step = ActionStepFrame(self._varMgr, self.blockIndex, parent=self)
|
|
step.deleteBtn.clicked.connect(lambda: self.removeActionStep(step))
|
|
self._actionWidgets.append(step)
|
|
self.actionsLayout.addWidget(step)
|
|
|
|
|
|
def removeActionStep(
|
|
self,
|
|
step: ActionStepFrame
|
|
):
|
|
|
|
if step in self._actionWidgets:
|
|
self._actionWidgets.remove(step)
|
|
self.actionsLayout.removeWidget(step)
|
|
step.hide()
|
|
step.deleteLater()
|
|
|
|
@Slot(int)
|
|
def onTypeChanged(
|
|
self,
|
|
_idx
|
|
):
|
|
|
|
isCond = self.typeCombo.currentData() in ("IF", "ELSE IF")
|
|
self.conditionWidget.setVisible(isCond)
|
|
self.actionLabel.setText(
|
|
"执行步骤:" if isCond else "ELSE 执行步骤:"
|
|
)
|
|
|
|
|
|
def getBlockType(
|
|
self
|
|
) -> str:
|
|
|
|
return self.typeCombo.currentData()
|
|
|
|
|
|
def getConditionRows(
|
|
self
|
|
):
|
|
|
|
return list(self._conditionRows)
|
|
|
|
|
|
def getActionSteps(
|
|
self
|
|
):
|
|
|
|
return list(self._actionWidgets)
|
|
|
|
|
|
def countActionSteps(
|
|
self
|
|
) -> int:
|
|
|
|
return len(self._actionWidgets)
|
|
|
|
|
|
def toScriptLines(
|
|
self
|
|
) -> list:
|
|
|
|
blockType = self.getBlockType()
|
|
lines = []
|
|
|
|
if blockType in ("IF", "ELSE IF"):
|
|
condTexts = [
|
|
r.toConditionText() for r in self._conditionRows if r.toConditionText()
|
|
]
|
|
if not condTexts:
|
|
condTexts = [".TRUE."]
|
|
|
|
if len(condTexts) == 1:
|
|
combined = condTexts[0]
|
|
else:
|
|
parts = []
|
|
for i, ct in enumerate(condTexts):
|
|
if i > 0:
|
|
logic = self._conditionRows[i].getLogic() or ".AND."
|
|
parts.append(f" {logic} ")
|
|
parts.append(f"({ct})")
|
|
combined = "".join(parts)
|
|
if blockType == "IF":
|
|
lines.append(f"IF({combined}) THEN")
|
|
else:
|
|
lines.append(f"ELSE IF({combined}) THEN")
|
|
else:
|
|
lines.append("ELSE")
|
|
for step in self._actionWidgets:
|
|
scriptLine = step.toScriptLine()
|
|
if scriptLine:
|
|
lines.append(scriptLine)
|
|
return lines
|
|
|
|
|
|
def refreshVarCombos(
|
|
self
|
|
):
|
|
|
|
for row in self._conditionRows:
|
|
row.refreshVarCombos()
|
|
for step in self._actionWidgets:
|
|
step.refreshVarCombos()
|
|
|
|
|
|
def setPrevBlockType(
|
|
self,
|
|
prevType: str | None
|
|
):
|
|
|
|
model = self.typeCombo.model()
|
|
if model is None:
|
|
return
|
|
for data in ("ELSE IF", "ELSE"):
|
|
idx = self.typeCombo.findData(data)
|
|
if idx < 0:
|
|
continue
|
|
item = model.item(idx)
|
|
shouldEnable = prevType != "ELSE"
|
|
item.setEnabled(shouldEnable)
|
|
if prevType == "ELSE" and self.typeCombo.currentData() in ("ELSE IF", "ELSE"):
|
|
self.typeCombo.setCurrentIndex(0)
|