new connection editing
This commit is contained in:
@@ -235,7 +235,6 @@ class DocumentController(QObject):
|
||||
source: Endpoint,
|
||||
target: Endpoint,
|
||||
*,
|
||||
routing: str = "angled",
|
||||
waypoints: list[QPointF] | None = None,
|
||||
) -> str:
|
||||
if self.active_component_id is None:
|
||||
@@ -246,14 +245,11 @@ class DocumentController(QObject):
|
||||
raise ValueError("A connection endpoint no longer exists")
|
||||
if not PortTypeRegistry.compatible(source_port.type, target_port.type):
|
||||
raise ValueError(f"Cannot connect {source_port.type!r} to {target_port.type!r}")
|
||||
if routing not in {"direct", "angled", "spline"}:
|
||||
raise ValueError(f"Unknown connection routing: {routing}")
|
||||
connection = Connection(
|
||||
str(uuid4()),
|
||||
source,
|
||||
target,
|
||||
properties={
|
||||
"routing": routing,
|
||||
"waypoints": [{"x": point.x(), "y": point.y()} for point in (waypoints or [])],
|
||||
},
|
||||
)
|
||||
@@ -267,7 +263,6 @@ class DocumentController(QObject):
|
||||
end: QPointF,
|
||||
*,
|
||||
text: str = "",
|
||||
routing: str = "angled",
|
||||
waypoints: list[QPointF] | None = None,
|
||||
) -> str:
|
||||
if self.active_component_id is None:
|
||||
@@ -297,16 +292,13 @@ class DocumentController(QObject):
|
||||
layer=-1,
|
||||
properties={
|
||||
**style,
|
||||
"routing": routing,
|
||||
"waypoints": [{"x": point.x(), "y": point.y()} for point in (waypoints or [])],
|
||||
},
|
||||
)
|
||||
self.undo_stack.push(AddAnnotationCommand(self, self.active_component_id, annotation))
|
||||
return annotation.id
|
||||
|
||||
def set_route_waypoints(
|
||||
self, item_kind: str, item_id: str, waypoints: list[QPointF], routing: str | None = None
|
||||
) -> None:
|
||||
def set_route_waypoints(self, item_kind: str, item_id: str, waypoints: list[QPointF]) -> None:
|
||||
item = (
|
||||
self.active_graph.connections
|
||||
if item_kind == "connection"
|
||||
@@ -316,8 +308,6 @@ class DocumentController(QObject):
|
||||
return
|
||||
old = deepcopy(item.properties)
|
||||
new = deepcopy(old)
|
||||
if routing is not None:
|
||||
new["routing"] = routing
|
||||
new["waypoints"] = [{"x": point.x(), "y": point.y()} for point in waypoints]
|
||||
if old != new:
|
||||
self.undo_stack.push(
|
||||
|
||||
18
BEdit/src/bedit/gui/dialogs/connection_chooser.py
Normal file
18
BEdit/src/bedit/gui/dialogs/connection_chooser.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from PySide6.QtWidgets import QDialog
|
||||
|
||||
from bedit.gui.generated.ui_connection_chooser_dialog import Ui_ConnectionChooserDialog
|
||||
|
||||
|
||||
class ConnectionChooserDialog(QDialog):
|
||||
def __init__(self, labels: list[str], default_index: int = 0, parent=None) -> None:
|
||||
super().__init__(parent)
|
||||
self.ui = Ui_ConnectionChooserDialog()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.connectionList.addItems(labels)
|
||||
if labels:
|
||||
self.ui.connectionList.setCurrentRow(max(0, min(default_index, len(labels) - 1)))
|
||||
self.ui.buttonBox.button(self.ui.buttonBox.StandardButton.Ok).setEnabled(bool(labels))
|
||||
|
||||
@property
|
||||
def selected_index(self) -> int:
|
||||
return self.ui.connectionList.currentRow()
|
||||
@@ -215,6 +215,89 @@ ff\xa6\x5cP`\xb7\xadY\x1b\xde\x8b\xcb\x97/\xc3\
|
||||
\x80\x90\x84\xfe\x83\xfe\x0fl\x00\x00/\xbf\xf2\xf2\x7f\x9c\
|
||||
\xfd\x0bVu/\x8d\xbcS'\xfc\x00\x00\x00\x00IE\
|
||||
ND\xaeB`\x82\
|
||||
\x00\x00\x05\x08\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
\x00\x00 \x00\x00\x00 \x08\x03\x00\x00\x00D\xa4\x8a\xc6\
|
||||
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\
|
||||
\x9bx\x00\x00\x00\x07tIME\x07\xd9\x06\x0a\x00\x03\
|
||||
\x0a\xd2\xe0H^\x00\x00\x01\xfbPLTE\x00\x00\x00\
|
||||
\xa2\xa2\xa6\xa7\xa7\xab\xa8\xa8\xad\xaf\xaf\xb2\xb1\xb1\xb3\xb3\
|
||||
\xb3\xb5\xb6\xb6\xbb\xc4\xc4\xc8\xcb\xcb\xcf\xb9\xb9\xbb\xba\xba\
|
||||
\xbe\xc4\xc4\xca\xaa\xaa\xb0\xb0\xb0\xb4\xac\xac\xb2\xad\xad\xb2\
|
||||
\xcb\xcb\xd1\xbe\xbe\xc3\xc2\xc2\xc6\xa4\xa4\xa8\xad\xad\xb1\xae\
|
||||
\xae\xb1\xb5\xb5\xb6\xaf\xaf\xb3\xb0\xb0\xb3\xb4\xb4\xb9\xb4\xb4\
|
||||
\xba\xca\xca\xce\xa9\xa9\xad\xb2\xb2\xb6\xa7\xa7\xac\xa8\xa8\xac\
|
||||
\xcb\xcb\xcf\xcb\xcb\xd0\xa1\xa1\xa5\xa2\xa2\xa5\xb2\xb2\xb4\xa2\
|
||||
\xa2\xa8\xa4\xa4\xa9\xcc\xcc\xd0\x9c\x9c\xa1\x9e\x9e\xa3\xb3\xb3\
|
||||
\xb8\xb4\xb4\xb9\xc3\xc3\xc7\xc3\xc3\xc8\xac\xac\xb1\xad\xad\xb2\
|
||||
\xa6\xa6\xa9\xc7\xc7\xcc\xc8\xc8\xcc\xb1\xb1\xb3\xad\xad\xaf\x9d\
|
||||
\x9d\xa2\x9e\x9e\xa4\xa1\xa1\xa4\xa2\xa2\xa6\xcb\xcb\xcf\xcb\xcb\
|
||||
\xd0\x9a\x9a\x9e\x9b\x9b\xa0\xc5\xc5\xc7\xd2\xd2\xd3\xd2\xd2\xd4\
|
||||
\xd3\xd3\xd5\xd6\xd6\xd8\xd7\xd7\xd7\xd7\xd7\xd8\xd9\xd9\xdb\xda\
|
||||
\xda\xdb\xdc\xdc\xdd\xde\xde\xdf\xdf\xdf\xe1\xe0\xe0\xe1\xe2\xe2\
|
||||
\xe2\xe2\xe2\xe3\xe2\xe2\xe4\xe3\xe3\xe4\xe3\xe3\xe5\xe6\xe6\xe7\
|
||||
\xec\xec\xed\xed\xed\xee\xee\xee\xef\xef\xef\xf0\xf0\xf0\xf1\xf1\
|
||||
\xf1\xf1\x97\x97\x9c\x98\x98\x9e\x99\x99\x9e\x9a\x9a\x9f\xa7\xa7\
|
||||
\xaa\xa8\xa8\xab\xab\xab\xad\xab\xab\xae\xac\xac\xaf\xad\xad\xaf\
|
||||
\xad\xad\xb0\xae\xae\xb0\xae\xae\xb1\xaf\xaf\xb1\xb0\xb0\xb4\xb1\
|
||||
\xb1\xb4\xb3\xb3\xb8\xb5\xb5\xb8\xb7\xb7\xbb\xb8\xb8\xbc\xba\xba\
|
||||
\xbc\xbb\xbb\xbd\xbb\xbb\xbe\xbc\xbc\xbe\xbd\xbd\xc2\xbf\xbf\xc2\
|
||||
\xbf\xbf\xc4\xc5\xc5\xc7\xc9\xc9\xcd\xcb\xcb\xcf\xcc\xcc\xd0\xcd\
|
||||
\xcd\xd0\xce\xce\xd2\xd5\xd5\xd6\xd5\xd5\xd7\xd7\xd7\xd7\xd7\xd7\
|
||||
\xd9\xdb\xdb\xdd\xe0\xe0\xe0\xe0\xe0\xe1\xe1\xe1\xe1\xe2\xe2\xe2\
|
||||
\xe3\xe3\xe3\xe4\xe4\xe3\xe4\xe4\xe4\xe4\xe4\xe5\xe5\xe5\xe5\xe6\
|
||||
\xe6\xe6\xe7\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xea\xea\
|
||||
\xea\xeb\xeb\xea\xeb\xeb\xeb\xeb\xeb\xec\xec\xec\xea\xec\xec\xec\
|
||||
\xec\xec\xed\xed\xed\xec\xed\xed\xed\xed\xed\xee\xee\xee\xee\xef\
|
||||
\xef\xee\xef\xef\xef\xef\xef\xf0\xf0\xf0\xf0\xf1\xf1\xf1\xf2\xf2\
|
||||
\xf2\xf3\xf3\xf3\xf4\xf4\xf4\xf5\xf5\xf5\xf6\xf6\xf6\xf7\xf7\xf7\
|
||||
\xf8\xf8\xf8\xf9\xf9\xf9\xfa\xfa\xfa\xfb\xfb\xfb\xfc\xfc\xfc\xfd\
|
||||
\xfd\xfd\xfe\xfe\xfe\xff\xff\xffN\x89\xad\xb6\x00\x00\x00W\
|
||||
tRNS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x17\
|
||||
\x18+2668<<CZZ]^^^^\
|
||||
aq\x86\x8c\x8c\x8d\x8d\x95\x95\xb1\xcc\xcc\xcc\xd2\xd2\xda\
|
||||
\xda\xdc\xdc\xea\xea\xeb\xeb\xeb\xf1\xf5\xf6\xf6\xf6\xf6\xf6\xf6\
|
||||
\xfa\xfa\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\
|
||||
\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xee\x1d\xc8\xff\x00\
|
||||
\x00\x00\x01bKGD\xa8P\x086\x92\x00\x00\x02#\
|
||||
IDAT\x18\x19\x05\xc1\xcd\x8b\xd5e\x1c\x07\xd0\xf3\
|
||||
\xf9>w\xee\xdc\x19c\x1a4M\x223\x95\x8cj\x91\
|
||||
\x8bVE\x9b \x08!\xa1E\xabh\xd3\xbf\xd6\xa6\x82\
|
||||
6-\x0c{\xd9\x19\xb5\x09\x82\xa8\xb0\xec\x05\x99A/\
|
||||
5\xf9\x92\xe9tg~\xcf\xd39\x00\x00\x00\x00\x00`\
|
||||
\x03`\x03\x003\x00,N\xae\x1f}\xd9\xd7{\xab\xdb\
|
||||
\x0f\x01\x08`\xb1\xff\xe4\x89\xd7\xd7\x16\xf3\xb5i\xb5?\
|
||||
\x1d|\xb9\xdcY\xec\x03\x0d\xb0x\xf6\xad\xe9\xa5\xcd5\
|
||||
\xd3\xc8l\xb6\xf8\xf3\xb5\x7f\xef\xae\x80\x06\x1c{o\xf5\
|
||||
\xea\x99>j\x0a\x19\xfd\xa9G\xfez\xe3\x97\x87 \xe0\
|
||||
\xe8\xbb7\xde<\x9c\xf4>M&m^\xdd\x17O\xbf\
|
||||
\xff74\xac/\xde\xb9y\xa9\xc7\x88^css\xa6\
|
||||
s\xfa\xdbW~\xac\x89\x86\xe9|{{\x182Ff\
|
||||
\x1b\x12r\xd8\xce\x5c\x9d\xdfD\xc3\x13\x97.va\xa4\
|
||||
\xcf\x9b\xf4\x8c\x8c\xb8w\xea\xe4\xee?\x14\x8e\xef\x8c*\
|
||||
\xa92\x97\x91\xeaE\xdd\x9f\xfcp\x1cM\xdb\xbax1\
|
||||
\xc2H\x8d0\x92^\xfd\xc1\x8a3[\xbf\x1e\x8c2m\
|
||||
o#\xa9\xaa$#\xa1\xba\xc3V\xe9G\xb6'\xc5\xfa\
|
||||
I\x92J\xabdDF\xd4~\xa92_\xa7\xd8~\x0c\
|
||||
R\x92\xaa\x18\x91\xc3\x9eD\xd6\xb6)\xce6\x88$ \
|
||||
\x1cH\xa5j\xe3\x1c\xc5\x00\xaaR\xa9$LSI\xa5\
|
||||
2(v'0\x12I!\xbd)I\xfe\xdb\xa1\xd8[\
|
||||
\x82\xa4\xaa\x221zk\xa2\xb2\xda\xa3X}\x02\x88T\
|
||||
*Q\x9aJ\xea\xea\x8a\x92\xbb\xcf\x00FE%\x86\xd2\
|
||||
\x94\x8dsw\xa2\xf1`~\xe3\xf9@\x92a\xd0\x8d\xf4\
|
||||
\x1a\xae\xec\xfeLa\xf7D\x00\x92JR\xa5iGN\
|
||||
\xef\xa0\xe1\xdet\xfd\x02 b\x18\xe9\xc9\xec\xa3\xdf\xaf\
|
||||
\xa1P\xd7\x8f}<@\x92H\x952\xbb|\xeaz\xa1\
|
||||
a\xacn\xbd\xf0\xfds\x80\x11]\xd4\xe5cWn\x0f\
|
||||
4\xf0\xe0\xd6\xf9o^\x1c\x81\x0c\x8c\xf6\xc1\x89\xcf\x97\
|
||||
\xa0\x01\xf7\xff\xd8\xb0\xb5@b\xd4ly\xed\xb7\xaf\xf6\
|
||||
\x80\x06\x98vn.\x96\x9f\x9d\x9dG\xbf\xf3\xe1\xfe\xf2\
|
||||
\xd3\x9f\xa6\x0e\x04`\xed\xc0\xe3[\x8f^8\xac\xfa\xee\
|
||||
\xee\xbd\xa5\xb5\x03\x00\x00\xcc\xb1\xb9\x899\x00\x00\x00\x00\
|
||||
\x00\xfc\x0f\x04u\xc6)\xe3{\x06,\x00\x00\x00\x00I\
|
||||
END\xaeB`\x82\
|
||||
\x00\x00\x08h\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
@@ -520,6 +603,142 @@ K,~\x0d\x01\x02\xc2\x08\xa0\x0d\x98$\xc1\xd4\xe8C\
|
||||
S\xa0\x81ahl}\xb5P\xd4\xd7\xb8\xe9z\x86\x0e\
|
||||
>L\x06\x80\x01`\xc7\x01\x7f\x03\xdc\xff\x15WD\x01\
|
||||
nd\x00\x00\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x03o\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
|
||||
\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\
|
||||
\x00\x00\x00\x09pHYs\x00\x00\x03v\x00\x00\x03v\
|
||||
\x01}\xd5\x82\xcc\x00\x00\x00\x19tEXtSof\
|
||||
tware\x00www.inksca\
|
||||
pe.org\x9b\xee<\x1a\x00\x00\x02\xecID\
|
||||
ATx\xda\xed\x97\xddN\x1aA\x14\xc7gvfw\
|
||||
\xd9E\x10\x10\x95\xa47\xc6\xe2\x17\x9aX\xb7\x8am\xb5\
|
||||
\xe5\xda\xcb\xbeP\x13_\xc3X\xa9R\x04\xa5\xd6\xa8\xa5\
|
||||
j\x9b\x18\xb0I\xfb\x16\xbe\x81\xbdjb\xaa\xecN\xcf\
|
||||
\x0c\xccB\xd8\xc6H\x01\xe9\x85'9\xcc\xecY\xc2\xff\
|
||||
w>2\xcbb\xc6\x18\xea\xa5)\xe0\x0f\x00\xff\x17\xc0\
|
||||
\xc9\xc9\xe9\xce\xf1\xf1\xd7T\xcf\x00l\xdbYB\xc8Y\
|
||||
?::N\xf5\xac\x05cc\x8f\x0dJ\x15\x01q\xdf\
|
||||
\x00\x98\x7f\x04\x83\xc1\x1a\x04^?<\xfc\xfc\xea\xbe[\
|
||||
\x800\xc6\x02\x22\x1e\x8f\x1b\x8a\x82\xdf\x1e\x1c\x14_\xde\
|
||||
7\x80\xf0\xfe\xfe \x1a\x1f\x8f\x1b\xb0\xdd\xd8\xdf\xff\xb4\
|
||||
\xdcu\x80\xd5\xd5U\xcc\x98\x00p=\x14\xeaG\x93\x93\
|
||||
\xe3\x00\xc1\xd2\x85\xc2\xfer\xd7+\xc0\xc0`\xf1@L\
|
||||
MM\x18\x84\x90\x8d\xdd\xdd\x8fK]\x05p\x9cj\x05\
|
||||
\x9a!\xc2\xe1\x10\x9a\x9e\x9e0\x09\xc1\xe9|\xfe\xc3\x8b\
|
||||
\xae\x00$\x12\x09l\xdb\xcc\x15\xf5B\x84\x01\x22\x01\x10\
|
||||
\xca\xbbB\xa1\xf0\xbcK-\xb0\x1bD\xbd\x10\x91H\x18\
|
||||
\xcd\xcc$L\xdb\xc6\x9b\xb9\x1c@t\xbe\x05\x02\xe0V\
|
||||
\x88XlX\x9b\x9f\x9f\x0b0\x866\xb3\xd9\x9dg\x1d\
|
||||
\x03\x18\x1c\x1c\x84\x16\xa0\xfa\x10z!\xb0\xae\xeb>\x15\
|
||||
lxx\xc8W\x85`[\x99L~\xb1#\x00\xe5r\
|
||||
u\x08)\xa5\x9e\xac\x094\x9e\x8b+`\xbcS\xdcc\
|
||||
\xb1!}aa\xae\x8f1'\x93Ng\x16;4\x03\
|
||||
\x0e\xe2\x1a\x8d\x10\xb4j\xba\xb8\xdf`\x00{\x03\x83\xe9\
|
||||
X\xd6\x13\x13c%\xb3\xb6\x06\x10\xed\x00\xa4R\x5c\x00\
|
||||
\x09\x00\x09A\xc0`O\xb96\xc08\xdc\xf9\xa8\xd8\xb6\
|
||||
}]\xa9Tn\xe0\x1aZ7\x80\x92I\xcb4M5\
|
||||
\xb3\xb5\xb5\x9dl\xab\x02\xd0^.*\x00\xb86@\x10\
|
||||
\x08\x0ba\x998\x08_C\xf6\xb6l\x0f\xff\xee\xc0@\
|
||||
\x04Y\xd6\xac\xa9i\xfa{\x18\xcc\x85v\x00d\xf6\x98\
|
||||
\x80\xf1\xcc\xe1Z(\xd72\xaf\xf0\x98\x1c\xccf\x88\xd9\
|
||||
\xd9\x19\xd3\xe7\xd3\xb3\xf9\xfc\xe1|\xcb\x00\x81@\x00S\
|
||||
\xaarA\x84\xab\xc6\xa4C\xcc\xa9e\xcd\xa4\xe8\xdf \
|
||||
\x22\x91\x10?\xac\x00\x82f\xf7\xf6\x00\xa2\xf5\x0a\x10\xb1\
|
||||
rA\xeeP\x09\xbe\x8a\x16@A\x98\x14\xbc\x0d\x22\x1c\
|
||||
\xe6\xcf\x8e1\xbfa\xe8\xd9b\xf1\xcb\xd3\x96\x00\xa0\x02\
|
||||
|\x91\x102{\xe1r0\xef\x02\x11\x0a\x89?5~\
|
||||
J\xc9\xf6\xe9\xe9\x99u'\x80\x8b\x8b\x0b,*P7\
|
||||
W\x5c\x0ef+\x10\xc1`\x00\x8d\x8e\x8e\x00\x84\x9a;\
|
||||
;\xfbf\xdd\xa9\x02\x84\xd0\xe6\x90+\xfco\x10}h\
|
||||
d\xe4\x91_U\x95\xdc\xf9\xf9\x8f9O\xc5\x9b\x8eb\
|
||||
\xe8\xb7\xf6\xab\x5c\xfe\xeeW<h\xf2\xc7\xc5a\xe4\x89\
|
||||
+\x0av\x83\x8e\xc3\xe0Z\xde\xc3\xb5\xb9\xa1\x06!\xf8\
|
||||
\x0dl_\xa3\x06\xf3\xbc\x1b\x96J%zuu%\xfa\
|
||||
`\x18\x06\x96q8\x86\xdd\xfd\xe5\xa5\xe6\xee5Mm\
|
||||
\xd8\xff\xc4\xf5a\xae\xc7\xa3\xd1\xa8l\xf1\xf5\xca\xca\xca\
|
||||
\xefF\xbd\x87\x97\xd3\x9e\x03\xfc\x01x$\x0aI\xcbR\
|
||||
\xf1S\x00\x00\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x04\xc3\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
|
||||
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
|
||||
\x00\x00\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\
|
||||
B(\x9bx\x00\x00\x00\x07tIME\x07\xd9\x07\x0c\
|
||||
\x14\x17\x01h\xb8;C\x00\x00\x04CIDATx\
|
||||
\xda\xdd\xd6\x7fH\xdce\x1c\x07\xf0\xf7\xd7\xdd\xd7;\xcf\
|
||||
;m\x8av*\x82\x9b\xc6v\x88#%3K\xb1p\
|
||||
6i\xee&\xbbTJwl:\xd6Z\xb9J\xcd\xd3\
|
||||
\xb4\xb9\xb2\xd8b\xb8\xa8E0R\x1c\xb2\xb9Y\xdb\x1f\
|
||||
kZ\x84\x19bA3\xb0\xd9,E\xbc\xfcIj\xb3\
|
||||
\x89\xe4\xdd\xf9\xfdu\xf7\xf4\x1c\xf9\xc7\xed\x1b\x87\xdf\xd3\
|
||||
0\xe8\x05o\x9e\xe3\xe0\xf8<\xcf\xe7y\xee\xf9~\xb1\
|
||||
\xc9Jij\xf1\x1f\xd1[,\x16\x92\x90\x90@\x00,\
|
||||
\xd2\xec\x05\x15\x80MB\x0b_\x09\x09\x09!6\x9b\x0d\
|
||||
\xd4\x034\x9d4\xcd\xd8$OTTT\x90\xd8\xd8X\
|
||||
\x02\xc0;%\xd8\x0c\xd9\xd9\xd9\xf3\xf9\xf9\xf9n\xaf\xc2\
|
||||
\x9e\xcf6l\x06\x86aj\xea\xeb\xeb\x09m\xbf|\xf5\
|
||||
i\xd8\xa8\xa6\xdb$g\xad\x83W\x5c\x5cLRSS\
|
||||
\x89l\xf5\xdd\xa0\xd6}\x08\xcf\xfdD\x8e\xd1\xe2e\x00\
|
||||
\xfa\xde\xe9#\xf0%>>\xfejdd$\x19\x18\x18\
|
||||
\x80\x17\x86\xc6\x02\x7f\xd4}\xe5\x84\xc7\xe9~r\xf8L\
|
||||
?i\x802\x99UUU$..N\xde\xfa\x0b\xf0\
|
||||
Gu\xd7\x12\x1a\xfa\x08\xfb\xe6\xd7b\xc7\xdb\xdf\x92m\
|
||||
\xa0\x1az\x04%\x07\xef\xf7\x82\x82\x02\xf9\xc1\xf3\x8c*\
|
||||
P\x8a\xb7 @\x9d\xcc9\x1d\x1d\x8d\xbb\xd9\x22\xce\
|
||||
\xee\x98\x00\xf5Vv \xd6\xf0Ffffdww\
|
||||
7#k\xbd\x95F\x82R\x95]\xf6G\xaan\xfe\xd9\
|
||||
\x0e\xaa\xea\xc6\x22\x14\x0a)))!\xe9\xe9\xe9\xf2\x83\
|
||||
\xb7\x04\xa5J[\xc6\xf0\xf2\xb5\x85\xe4\xf2\xeb\x0b7A\
|
||||
\x9d\xf8l\x0eJm\xdf\xbe\xfd\xcb\xea\xeaj\xb7J\xa5\
|
||||
\x92\xef\xbd\x19JX>\x19\xc1\xd1K\x93\xea#m\x13\
|
||||
\xbf\x80:vy\x0aJXU*P\x99\xd5V\xab\xe7\
|
||||
\xbe\x97\xaf~\x18\xfe8\xd42\xd6_\xda6\x11U\xda\
|
||||
:\x06\x7fT\xc6\xc4,\x1f-,\xf4\x14$\xb2<\x0c\
|
||||
\x1fT\xf0r\xa0\xe9\x07ht\xfa,^\x10\x86\xaf\x94\
|
||||
=4\x07?\x94\xb3\xac5G\xa7\xd3%\xcd\xcc@m\
|
||||
0\xe0\xfc\xfc<V\x8b\x7fA3\x08\x1f\x18\xc8\x98?\
|
||||
\x18\xb0\x05l\x09\xdc\xc5\x10\xd1\xf9iy\xca\xda[F\
|
||||
s\x07\xd0\x1c\x0c\x0f_\xc96\x1a\xf1\xdb\xe2\x22\xf4,\
|
||||
\x8b\xb4\xa8(\x98o\xddB\xe7\xd2R\x04\x80?\x14u\
|
||||
\xc0tn\xc0 J.\xc7\xe7\xaf$9\xa1P\x9b\xa7\
|
||||
\xf5ju\xf3NZ\x9ca\x18Haa\x08\xa6\x13\x10\
|
||||
\xddn<\xedr}\xd4\xe9\xbb\xf8?\xef\x01ae\xe5\
|
||||
\xa0\xc0\xf3\x17\xa1PY@\x00\x9e\x03v\xec\xdc\xba\xb5\
|
||||
8:(\x08\xe3\x92\x04=\xc7!2,\x8c\xf4\x8e\x8e\
|
||||
\x8a'\x96\x97\xcb_\x03\xa0|\x02\x02\x9f&\xf0\xc2m\
|
||||
(\xd4BW\x99\xa0V\xb7?\x16\x1dM\xee\xd1\xe2\x8c\
|
||||
\xdd\x8eX\xad\x16K\xcb\xcb\xcc\xd0\xec\xec\x0b\xa0\xde\xf7\
|
||||
g\x02\xbc\xc0\x1b9\x9e\x9b\x87r\xc9\xe3EE)\xdf\
|
||||
\x89\xa2C\xb3\xb0\x80\x88\x88\x08\x12F\x1f>\x83\x83\x83\
|
||||
\xe3\xb5\xa2\xd8\x0a\x0f?; \x09\x1c\xa7\x85B\x06\x83\
|
||||
\xe1u5\xcb\x92\x17\x87\x86t\xfbGF\x9c,\xcf\xaf\
|
||||
\xdc\x9b\x9cd\x86\xef\xde-ldY\xf8m\xd7K\x1d\
|
||||
=I\xc7\xdb\xcd;\x0e7C\x01&77\x97\x18\x8d\
|
||||
\xc6\xfb\x1e6)*U\x1bd\x94w\x80\xe7z\x04\xce\
|
||||
\xf9\xcch\xeb\x11(PNo<x^2\xbd\xcc\xff\
|
||||
(I\x16\xf8\x81\x81\x97\xf8C-\xb1.\x978MD\
|
||||
W\xa0(\xf1\xe2\xec\xb5\x0a\xdf\x9b\x9f\x9c<\x17\x1a\x1a\
|
||||
\xfa`oo/\xb3\xda\x01\xcf\x18C3\xbb\xee\x0e\xfc\
|
||||
z\xb1lF\xe0V\xbe\x11%\xa1]^\x5c.##\
|
||||
\xe3\xc6\xe8\xe8(\xe3\xb5\x10\xb3\xac\xb8\xff\xa2\xccM\x08\
|
||||
\xdf\x7f68\xdct\x86\x84\x99\xce\x9e\x06\xa5\xdfs\x0a\
|
||||
rZ\xadV\xd7\xd5\xd5Ezzz\xdct\x22w\x00\
|
||||
\xbc\x07\x99uu`\xeez%\xb4z\xd6!\x08|\x12\
|
||||
\xcf;j\xf4{N\xf6\x11\xa8\x0c\xa0\x02\xb3j\x81U\
|
||||
N\xa7\xd3>==\xfd\xa1\xc3\xe1\x98\x92$\xe9I\x00\
|
||||
\xd6\x0dM\xc0d21\xf0\x8c\xfb\xf2\x98\x99K\xaf\x22\
|
||||
\x83\xf9~\xd8\xf1s\x83\x8a\xe3%\xb7\x9d\x13\xe7\xb6d\
|
||||
\xd5v\x0ab\xf0\x81\xd0\x9c\xba P\x8d'k\xa25\
|
||||
\x1a\xcd\x14\xfd\xdd\xb6\xc4\xc4\xc4El\x84\xe7\xaf\x04*\
|
||||
//\xef\xfeq\xef\xdf\xdf?\x9b\xb7\x9b\xe0\xd1w\x1b\
|
||||
\x9e\xdf\xf7\x14\xc1\xe3u\x04\xe9V\xdb\xf1S\x1f_\xc5\
|
||||
\xbf\xc9\xd3\x01\x9f\xa3\x0f\x17Z/\xe3\x7f\xe1/\x17\x85\
|
||||
\xd6\x06q(\x0e\x10\x00\x00\x00\x00IEND\xaeB\
|
||||
`\x82\
|
||||
\x00\x00\x02V\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
@@ -1210,6 +1429,113 @@ G%\xc7A \x00\x1d\xd0\x80I\xe0\x03\x10;3\x85\
|
||||
\xfaS\x08V\x01()\xc7\xe4\xb9C\x95,\x01\xd77\
|
||||
\x9aw\xed\x7f\xefoJ\x88l\x9a\x02\xc2\xbb\x00\x00\x00\
|
||||
\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x06\x8f\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
|
||||
\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\
|
||||
\x00\x00\x00\x09pHYs\x00\x00\x03v\x00\x00\x03v\
|
||||
\x01}\xd5\x82\xcc\x00\x00\x00\x19tEXtSof\
|
||||
tware\x00www.inksca\
|
||||
pe.org\x9b\xee<\x1a\x00\x00\x06\x0cID\
|
||||
ATx\xda\xddWYLUW\x14=NiSQ\
|
||||
\x8b\xad\xb1\xad\x16\x8d\x1dR\xd39\xa6\xa6\x95\xb6Im\
|
||||
b\xda\xaf\xfe\xe0w\xd3~\x01%6V\x1cA\x8b\x8a\
|
||||
\x10)NLB\xa1\x10@\x85\x08\x05\xc2P\xa8\x81\xfa\
|
||||
\xe1\x00\xca\xa48\x81\xa2(\x93\x82\x82\xcc\xd3\xe3\x9d\xdd\
|
||||
\xb5N^o.\x06\x1b\xb0$&}\xc9\x0a\xbcs\xef\
|
||||
;{\xed\xbd\xd7\xdeg\x1f%\x22O\x15\xff/\x02\xf8\
|
||||
L\x0b\x0a\x0ar{*\x046n\xdc\xf8Ahhh\
|
||||
[zz\xfahHHH*\x88\xcc|\xf4\x9d\x83\x07\
|
||||
\x0f.\xf2\xf6\xf6\x0e^\xb5j\xd5\xb7nnn\xeeS\
|
||||
F`\xd3\xa6M\xcb\xf7\xed\xdb\xd7WYY)W\xaf\
|
||||
^\x95K\x97.i\x18\xabpEczuu\xf5G\
|
||||
\x87\x0e\x1d\xfa\x04k\xad>>>G===W\xcc\
|
||||
\x993gj\x08l\xd9\xb2\xe5\xf5\xb0\xb0\xb0\xee\x0b\x17\
|
||||
.\xc8\xe5\xcb\x97\xa5\xa6\xa6Fjkk\xe5\xc6\x8d\x1b\
|
||||
:>>\xbe\xbd\xb4\xb4\xb4\x0c\xebCg\xce\x9c\x19\x01\
|
||||
\x89R___\xf7)K\xc1\x86\x0d\x1b\x96\xec\xdd\xbb\
|
||||
\xb7\x83F\xeb\xea\xea\xe4\xc1\x83\x07RUU%\xf0X\
|
||||
\xea\xeb\xeb\xe5\xf6\xed\xdb\x92\x96\x96\xa6\xcf\x9f?/\xd7\
|
||||
\xaf_\x97k\xd7\xae\x05N\x95\x06\x18\xf6W\x90\xf3v\
|
||||
\x84[n\xde\xbci\x0c\xb6\xb6\xb6Jww\xb70\x1a\
|
||||
$u\xeb\xd6-\xae\x19\x12\x88Joss\xf3\xe2)\
|
||||
!\xb0u\xeb\xd6\x05{\xf6\xeci\xb9r\xe5\x8a\xdc\xb9\
|
||||
s\x87\xde\x1b\x83\x0d\x0d\x0d\xd2\xde\xden\x91\xf8\xe7y\
|
||||
cc\xa3NHH\xe8\x1cO\x98O\x92s\xf7\xdd\xbb\
|
||||
w7 \x9c\x1a\x1e\x19\x0f\x07\x07\x07\x19^\x8a\x8f\x06\
|
||||
\x99\x0aC\xe2\xe2\xc5\x8bF\x0fMMM\xd4\x84\x13\xa4\
|
||||
S\xff\x13\x01z\xb0k\xd7\xaeZ(]\xdf\xbd{\xd7\
|
||||
\x0aqGG\x07I\xd0\x98\xf1\x9a\xc4\x1e>|H\x12\
|
||||
\x8c\x0c\xf3\xcf\xf7\x18\x95\xd1\x80\x80\x80\x1f\x9e\x98\xc0\xe6\
|
||||
\xcd\x9b\xbf\xce\xcd\xcd\x1d\xbe\x7f\xff\xbe\xf4\xf5\xf51\xb4\
|
||||
F\xf9mmm4h\x91\x00,=\xf4\xf4\xf4Xz\
|
||||
\xe0zjj\xea\xc0\xda\xb5kgL\x86\x00=\x9f\xbe\
|
||||
m\xdb\xb6H\xd4\xf1pdd\xa4\x93\xb5\xce\xcd\x1d\x0e\
|
||||
\x87\x09/\xbf\x83\x14\xd7H\x82\x9a`\xc8I\x8cD\xcd\
|
||||
:{\xc4\xe9\xd3\xa7%11q\x88\xfbM\x98\x00\xdb\
|
||||
\xeb\xf6\xed\xdb\xd3\xa1r\xa7\xe0\x93\x94\x94$qqq\
|
||||
\x9a\xf9\xee\xed\xed\xb5H\xd0\xbb\xce\xceN\xb3644\
|
||||
\xc4\xb0\xd3k\x920d\xd0\x07$##\xc3\x89\xea\xf9\
|
||||
~R)\x80\xe7\xbf\xc1\xc3Q|\xe4\xde\xbd{\xc6\xa3\
|
||||
\xa8\xa8(\x1d\x1b\x1b\xabY\xef\x03\x03\x03\x16\x09\x1a\xea\
|
||||
\xea\xea\x92\xfe\xfe~\x92\xa00\x99\x22\xe3yff\xa6\
|
||||
\x13)\xfciR\x22\x84`\x22(\x1cnF#$A\
|
||||
\xcf\xe8exx\xb8\x8e\x89\x89\xd1\x0c-\xc3\xceg\x14\
|
||||
\x1f\xbd\xe6s\x86\x9d\xbd\xe1\xd4\xa9S\x92\x95\x95\xa5Q\
|
||||
\xba?O\xea0\xc2\x0fB\xce\x9d;\xe7\xa0\xc7\x14\x12\
|
||||
=\xa5\x91\x91\x91\x11\xe6\xd8D\x03\x15\xa1\xa1\x09]V\
|
||||
V\xc6u\x8b\x04\x1b\x13SB\xcf\xb3\xb3\xb3u``\
|
||||
`\xd8dNC\xd6z\x00\x98;l\xa2b.\xe9\x19\
|
||||
\x8dX\xe1\xa5!DI\xa3\xc7\xeb\xb3g\xcf2J$\
|
||||
\xcbr3\x9e\xe7\xe4\xe4\xe8\x1d;v\x1c\xb6\x8c\xc5\xa9\
|
||||
Y*Je\x02_>\x8e\x00\x8f\xd5\x1fKJJ\x1c\
|
||||
\x14\x14@\xcf\xad\xf2\xa2\xd74@\x12\x5c\xa7\xfaYb\
|
||||
\xf8\x8d\xde\xbf\x7f\xbf.**\x221\xcb8\xc4{\xc4\
|
||||
2t\x5c\xcdP\xb1*\x03\x10\xa0O\x1dV\x9e\x5c\x7f\
|
||||
\xb4\xbf\x7fWXX8\xc2\x92b[%\xd8\xd5h\x8c\
|
||||
\xc2\xa2A6 \x0a\x8d$\x18\x11V\x03N<Y\xbf\
|
||||
~=C\xcdc\x98\x82\xd3;w\xee\xccf\x05\x891\
|
||||
\xa2\xa6\xa9x\x95\x0c\x88\x0d\xc5|6\xa6\xd6\x0f\x1c8\
|
||||
\xd0\xc7\x06\xc2~\xee2h\x95\x12I\xd0 U\xdd\xd2\
|
||||
\xd2b\xba\xdf\xb0cX\xca\x9a\xca\xa4\xbc\xbc\x5c\x8a\x8b\
|
||||
\x8b\x05\xbaq\xe2hv \xec\xb1cj=Q\xc5\x00\
|
||||
bC\x8dJP\xf3\xc7\x10`w\xc2\x0f\xfb\x11~\x0a\
|
||||
\x89\xe1\xb7\x0cB\xcd\xf4\x9c$\xac\xf6\xda\xd8\xd4(^\
|
||||
\xc5^27m\xae\x9c\xa8?!'O\x9ed\x7f\x18\
|
||||
e\xb7\xb4G\x15~\xff\xa2R\x94\xd8P\xa7\x8e\xa9\x85\
|
||||
|6^\x0a|q\xd08\x90\x06\x1e*$A\x83\x0c\
|
||||
3k\x9c\x9eS\x0f\xa6\xedz\x15z\x89:\xaa\x0c\xe6\
|
||||
\xa5\xcf\x93\xa8\xdc(\x09\x0e\x0e\xae\xb7\x9fxx\x16\x04\
|
||||
\x88\x0d\x0d\xea\x88Z\xfc\xafU\xe0\xef\xef\x9f\x8cM\x9c\
|
||||
(\x1fj\x80$\x98s\x9el\xec\x01l8\x86Dh\
|
||||
u\xa8\xa8tea\xf6\xb1\xd9\xce\xa5\xbf.]im\
|
||||
\x9c\xa6\xfc\xb9nC3\x08,{\xd4\xde\xe3N\xbc\x0e\
|
||||
\xe4Sc\xc0d\x09\x92\x84\xc99;\x1f\xbfs\xd2\xe1\
|
||||
\x9a_\x89\x9f\xa0\xa8,@\xe3-\xeaw\xb5\x0c\xff\xfb\
|
||||
\x00bC\x1b\xf0\xd6\x84\xfa\x00\xa7\x16N/h\xc1\x1a\
|
||||
#\x97\xa4\xa4\xa40\xe7\xc6 \xab\x83\x9d\x8f\xe9\xa0\xf0\
|
||||
\x0a\x0a\x0adu\xe2\xeaA\x95\xad\xc4\x866@\xdb\xbe\
|
||||
w\xaa,\xf5\xfe\x84\x1b\x11\xe76\x86\x9as\x1c\x1a\x92\
|
||||
^\xb7n\x9d`\xb8\x94\x8a\x8a\x0a\x920bd\xe7\xcb\
|
||||
\xcf\xcf\x17L\xc2]\x9c\x0bU\x9e\x0a\x07d\x1c\xf4\x00\
|
||||
+'|/\xe0\xc4\xca\xc9\x95\x13,'YN\xb4P\
|
||||
u\xbb\x9f\x9f\x9f\x8e\x8e\x8efk55\x9f\x97\x97'\
|
||||
,YN\xc4\xd6F\x05*Z\xfd\xa1\xc4\x86~\xac}\
|
||||
>\xa1\x8b\x09gt\xce\xea\x9c\xd99\xbbs\x86\xe7,\
|
||||
\xcf\x99\x9e\xb3=\xaa\xa3\x9c$0RIrr\xb2D\
|
||||
DD\x0c\xf2.`\xdf\xc84\x9b\x22\x95\xa4\xfeT\x02\
|
||||
\x0c\xa9\x13j\xcd\x84oF\xbc\xa5\xf0\xb6\xc2[\x0bo\
|
||||
/\xe3\x09\x13\x06S\x00'\xdak'oA\xe3n\x16\
|
||||
\xa4\xa6\xab\x12\x95\xaa\xfeR\xdf<\xd1\xd5\x0c\x9f\x99\xc0\
|
||||
s\xc0<\xe0E\xe0e\xc0\x03X\x06\xbc\xe9\xe1\xe1\xb1\
|
||||
\x02\x7f\xdf\x01\xde\x05\xde\xb3\x81\xdf\xdf\x06\x96\xf3=\xe0\
|
||||
5`)\xf0*\xf0\x12\xb0\x00x\x1ep\x03\x9e\x01\xc6\
|
||||
\x8ed\xec\xd9\x5c\x04\x9e\x05\xe6\x02/\xb8\x8c/\x01\xde\
|
||||
pm\xfe!\xf01\xf0\x19\xb0\x1aX\x03|\xe5\xfa\xfb\
|
||||
\x05\xf0)\xb0\x92\xef\xf1}\x12q\x91X\x04,\x04\xe6\
|
||||
so\x97\x8dY\x80i\xd5\x7f\x03\x81\xe3\xecT\x9c\xdf\
|
||||
M_\x00\x00\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x06\xf7\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
@@ -1739,6 +2065,76 @@ K\x80@\x89\x15\x8d\xc04\xd5\xb5^\xaf\x1bx\xfa\x19\
|
||||
\x84\xe7\x04\xcf\x88\xfd\xfd\xfd\xe4\xe8\xe8\xc8\x9dL&\x14\
|
||||
\xc7\xcc\x7f5p\xf2g\x94\xf7\x1f\xdf\x9a\xd2\x93\xfbC\
|
||||
\xb7\xa7\x00\x00\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x04<\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\
|
||||
\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
|
||||
\x00\x00\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\
|
||||
B(\x9bx\x00\x00\x00\x07tIME\x07\xd9\x06\x0a\
|
||||
\x00\x09%\x83\xde\x9d\x8d\x00\x00\x03\xbcIDATx\
|
||||
\xda\xedV\xcdKTQ\x14\xbfw\xe6\xcdG\xcf)\xc6\
|
||||
\x19B\xc5\x8a\x1aE\x86\xa4\x85\x91!\x13\x99\x8b(\x0d\
|
||||
\x94\xc12\x93\x04\xc9\x16m\x82P\xe8\x0f\x88v-l\
|
||||
\x1bA\xad\x22RC\xcbA\xa6,\xa5\x19\xd0\x81\xc6>\
|
||||
\x16-\xc2\x92 \x0cc2\xc7\xf2c\x9c\xcf\xdb9\xd1\
|
||||
y\xbc\xde\xbc)\xc6 \x10\xe6\x07\x87{\xdf\xbc;\xe7\
|
||||
\xf7;\xe7\xdc{\xeec\x05\x14\xb0\xa9\x10\x0e\xbf\xfa\xe7\
|
||||
5Z\xf0<\xc8w\xc0\xd0$\x84h\xe0\x9c\xef\x87\xb9\
|
||||
\x13l;\x98\x00\xfb\x02\xf6\x15\xdeM\xc3\xbbg0\xf7\
|
||||
\xd7\xd6\xd6\xccOM=g\x1e\xcf\xc1\x8d\x09\x08\x04&\
|
||||
\xd9\x91#\x87X(4}.\x93I\xf5\x18\x8d\xd2\xbe\
|
||||
m\xdb\xb62Y\xb6\x0a\xab\xd5\xcc\x8dF#\x032\x06\
|
||||
\xa4,\x9dN\xb3D\x22\xc5\xd6\xd7\xe3\x02\x8c\xc7bk\
|
||||
,\x99\xcc\xbc2\x18\x0c}\x1eO\xed\x1d\xf2\x95\x97\x80\
|
||||
`p\xca\x93J\xa5\xee\xdb\xed\xf6\xb2\xd2\xd2\xed\xc2f\
|
||||
+\xe2\xf0\x8c\x84\x8a!p\xccd28*s\x14\x86\
|
||||
b\xbe\x7f_\xe6\xd1\xe8\xb7\x8f\x92$\x9d\xac\xaf\xf7L\
|
||||
\xeb\xf1\x18\xd4\x0f~\xffS\x86\x98\x98\x08^\x81\xa8&\
|
||||
\xab\xab\xdd\xa5nw%+*\x9299V\x1b\x01\xe7\
|
||||
@\xc2,\x16\x0b\xb3\xd9l\xb0\xbe\x889\x9d\x0e\xeer\
|
||||
\xedfUU\x15;\xc1Wx|<p\x998rd\
|
||||
\x80D<\xb9%\xcbrw]\xdd\x01\x8a\x0cGL3\
|
||||
\xce\xb32\x80\xa5\x80T+\xd9@\xe0zz\xa62\xbd\
|
||||
~\xfd\x06\xca\x94\xb8\xde\xd8x\xb47g\x06|\xbeG\
|
||||
\x1d0tC\xba\xd019G\xc3yV\xc4f\xb3Y\
|
||||
!W\x8bR\xafC1kkk\xcc\xe5\xda\x85A\xf4\
|
||||
\xf8|\x8f\x9bu\x05\x0c\x0c\xf8L\xb0\xf0\xee\xe1\xc3\x1e\
|
||||
\x01@\xc7\xe8\x00G2E\x94\xc9d\xa2\xc8r\x12S\
|
||||
&b\xb1\x98\x92\x89\xca\xca=\xb0Ic#\xba\x02\x84\
|
||||
H\x5cv:\x8b\x7f\xd6\x9bj\x0cd\xba\x02\x88P\xbb\
|
||||
\x1fH\x14!\x1e\x8f\xff\xf6N\x96\xb7p(/\x04;\
|
||||
tI+\x00\xeb\xd3ZQ\xe1R;\xa0\x0c\xa8\xc5\xa8\
|
||||
I\xf5\xa2\xa7r\xa0?\x12\xae\x18\xfe^R\xe2\x14\xf1\
|
||||
x\xc2\xab\x15\x80\xc7\xc6]\x5cl'\xc5\x04\x85\x1c@\
|
||||
\x02\xfe&\x04k\xad=1\xf4?\xc8\xb0\x8d\x83\x007\
|
||||
\xad\x95hB;\x9e\xa0#\x02\x1dS$h\xea\x9d\xae\
|
||||
\xee\x09\xea}\xa0\x99c\x10\xb8&\xcd\xb32`6\x9b\
|
||||
f\xa2\xd1\xa5\x5c\x22\xb4\x91SZ\xd5u\xd7\x0a\xd2]\
|
||||
\xbb\xb2\x12\x13\xb0\x89g\xb4\x02\xf0X=x\xfbv\x86\
|
||||
\xfe\xac\x07r\xa4\x15\x82\xa3.\xb9\xd6\xf0\xf4\xcc\xcd}\
|
||||
\xe2\x92d|\x98%\x80s\xc3\xb5H$\xc2\x96\x97W\
|
||||
\x84N\x16\x88@wSjE\x91\x11\xe8yuuU\
|
||||
,-}\xc32]\xcf\x12\xd0\xd9\xd9\xbe\x0e\xad\xf4\xfc\
|
||||
\xd8\xd88\xd7\xa4U[K\xdd\x1e\xa1\xfe]k\xf4.\
|
||||
\x1c~\xc9\xa1y\x9d\xee\xea:\x9b\xd1\xed\x84\x1d\x1dm\
|
||||
\xb7\xd3\xe9T\xbf\xdf?\x86\x02\xf2\x11\xa1\xee\x19\xba%\
|
||||
\x08\x85\x9ec\xe47\x81c0g+\xee\xef\xbf\xcf\xda\
|
||||
\xdbO\x9d\x81T\xf5\x8d\x8c\x8c\xb2\xc5\xc5EA\xa9\xcf\
|
||||
!B7\x1b\xf4\x1e\xdb5\xdc\x88\x22\x18\x9c\x84\xbe\x10\
|
||||
\xbf\x0a\xbe/\x00\xc7\x9f/\xa3\xc1\xc1!\xd6\xd6\xd6\xca\
|
||||
\x86\x87G\x8e%\x93\x89{eee\xc5\xd5\xd5{\x05\
|
||||
\xf4\x08\xaew\xec\x10tQ\xa9\x8f\xf2\xc2\xc2\x82\x98\x9d\
|
||||
\xfd\xc0#\x91/\x118am^oK0\xaf\xef\x81\
|
||||
\xa1\xa1\x07\xac\xb5\xd5\xcb \x13\x17S\xa9d\xaf\xd5j\
|
||||
\xddS^^\x8e\xd7\xacp8\x1c\xdcb\xa1\x8bH\xe9\
|
||||
\xf9\x90\xb1\xa8\x00b>?\xff\x19\xdb\xf0;I2\xf7\
|
||||
\xb5\xb4\x9c\xb8A\xbe6\xfaIF7\xa5[\x88\xccq\
|
||||
\xa0k\x00\xc2\x1a\xfc\x1c\x83h\xe5_%Y\xc1\xa0a\
|
||||
|\x01\x85\x09\x800\x7fss\xd3{\xf6\x7fABG\
|
||||
Y\x01\x05l*\xfc\x00!\x00\x12\xf1%U\xb6\x0e\x00\
|
||||
\x00\x00\x00IEND\xaeB`\x82\
|
||||
\x00\x00\x02\x92\
|
||||
\x89\
|
||||
PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
|
||||
@@ -1875,6 +2271,10 @@ qt_resource_name = b"\
|
||||
\x00z\
|
||||
\x00o\x00o\x00m\x00-\x00o\x00r\x00i\x00g\x00i\x00n\x00a\x00l\x00.\x00p\x00n\x00g\
|
||||
\
|
||||
\x00\x0f\
|
||||
\x0bb\xb8g\
|
||||
\x00d\
|
||||
\x00r\x00a\x00w\x00-\x00c\x00i\x00r\x00c\x00l\x00e\x00.\x00p\x00n\x00g\
|
||||
\x00\x14\
|
||||
\x0b\xa9\xab'\
|
||||
\x00d\
|
||||
@@ -1889,6 +2289,15 @@ qt_resource_name = b"\
|
||||
\x09\xd0z\x07\
|
||||
\x00a\
|
||||
\x00r\x00r\x00o\x00w\x00-\x00u\x00p\x00.\x00p\x00n\x00g\
|
||||
\x00\x11\
|
||||
\x06\xfb\x85G\
|
||||
\x00d\
|
||||
\x00r\x00a\x00w\x00-\x00t\x00r\x00i\x00a\x00n\x00g\x00l\x00e\x00.\x00p\x00n\x00g\
|
||||
\
|
||||
\x00\x0d\
|
||||
\x0f\xba\x1e'\
|
||||
\x00d\
|
||||
\x00r\x00a\x00w\x00-\x00p\x00a\x00t\x00h\x00.\x00p\x00n\x00g\
|
||||
\x00\x0d\
|
||||
\x0b\xe6\x1f\xa7\
|
||||
\x00d\
|
||||
@@ -1922,6 +2331,11 @@ qt_resource_name = b"\
|
||||
\x00d\
|
||||
\x00r\x00a\x00w\x00-\x00b\x00e\x00z\x00i\x00e\x00r\x00-\x00c\x00u\x00r\x00v\x00e\
|
||||
\x00s\x00.\x00p\x00n\x00g\
|
||||
\x00\x13\
|
||||
\x04\xc4\x04G\
|
||||
\x00n\
|
||||
\x00e\x00t\x00w\x00o\x00r\x00k\x00-\x00c\x00o\x00n\x00n\x00e\x00c\x00t\x00.\x00p\
|
||||
\x00n\x00g\
|
||||
\x00\x0c\
|
||||
\x06\xeb\x97\xe7\
|
||||
\x00z\
|
||||
@@ -1948,6 +2362,10 @@ qt_resource_name = b"\
|
||||
\x00d\
|
||||
\x00o\x00c\x00u\x00m\x00e\x00n\x00t\x00-\x00s\x00a\x00v\x00e\x00.\x00p\x00n\x00g\
|
||||
\
|
||||
\x00\x10\
|
||||
\x03\xe6\xd3g\
|
||||
\x00d\
|
||||
\x00r\x00a\x00w\x00-\x00e\x00l\x00l\x00i\x00p\x00s\x00e\x00.\x00p\x00n\x00g\
|
||||
\x00\x12\
|
||||
\x09\xb3>\xc7\
|
||||
\x00d\
|
||||
@@ -1965,49 +2383,59 @@ qt_resource_struct = b"\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x03\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x03\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x01r\x00\x00\x00\x00\x00\x01\x00\x00:\x16\
|
||||
\x00\x00\x01\xde\x00\x00\x00\x00\x00\x01\x00\x00G\x5c\
|
||||
\x00\x00\x01\x9f{C\xf1'\
|
||||
\x00\x00\x02\x02\x00\x00\x00\x00\x00\x01\x00\x00Pr\
|
||||
\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x00dK\
|
||||
\x00\x00\x01\x9f{0\xc99\
|
||||
\x00\x00\x018\x00\x00\x00\x00\x00\x01\x00\x00/`\
|
||||
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00<\xa6\
|
||||
\x00\x00\x01\x9f\x7f&\x83\xcd\
|
||||
\x00\x00\x01\x18\x00\x00\x00\x00\x00\x01\x00\x00'x\
|
||||
\x00\x00\x01\x84\x00\x00\x00\x00\x00\x01\x00\x004\xbe\
|
||||
\x00\x00\x01\x9f{C\xf1\x18\
|
||||
\x00\x00\x02p\x00\x00\x00\x00\x00\x01\x00\x00`\xe1\
|
||||
\x00\x00\x03R\x00\x00\x00\x00\x00\x01\x00\x00}\x9f\
|
||||
\x00\x00\x01\x9f\x7fY\xceg\
|
||||
\x00\x00\x02P\x00\x00\x00\x00\x00\x01\x00\x00V\xbd\
|
||||
\x00\x00\x01\x9f\x7fV\xd5\xc0\
|
||||
\x00\x00\x03\x08\x00\x00\x00\x00\x00\x01\x00\x00t\xba\
|
||||
\x00\x00\x01\x9f\x7f&\x83r\
|
||||
\x00\x00\x01\xe4\x00\x00\x00\x00\x00\x01\x00\x00Iw\
|
||||
\x00\x00\x02|\x00\x00\x00\x00\x00\x01\x00\x00]P\
|
||||
\x00\x00\x01\x9f\x7f&\x83\xb1\
|
||||
\x00\x00\x01T\x00\x00\x00\x00\x00\x01\x00\x006\x96\
|
||||
\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x00$|\
|
||||
\x00\x00\x01\x9f\x7fY\xce\x82\
|
||||
\x00\x00\x01\xc0\x00\x00\x00\x00\x00\x01\x00\x00C\xdc\
|
||||
\x00\x00\x01\x9f{C\xf1.\
|
||||
\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x01\x00\x00!\xca\
|
||||
\x00\x00\x01d\x00\x00\x00\x00\x00\x01\x00\x00/\x10\
|
||||
\x00\x00\x01\x9f{{\xa5\xd5\
|
||||
\x00\x00\x02\xba\x00\x00\x00\x00\x00\x01\x00\x00i\xc6\
|
||||
\x00\x00\x03x\x00\x00\x00\x00\x00\x01\x00\x00\x81\xdf\
|
||||
\x00\x00\x01\x9f\x7f&\x83\x10\
|
||||
\x00\x00\x00\xba\x00\x00\x00\x00\x00\x01\x00\x00\x1b\xcd\
|
||||
\x00\x00\x00\xde\x00\x00\x00\x00\x00\x01\x00\x00 \xd9\
|
||||
\x00\x00\x01\x9f\x7f&\x83~\
|
||||
\x00\x00\x02L\x00\x00\x00\x00\x00\x01\x00\x00\x5c\xfe\
|
||||
\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00p\xd7\
|
||||
\x00\x00\x01\x9f\x7f&\x83T\
|
||||
\x00\x00\x00^\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xc1\
|
||||
\x00\x00\x01\x9f\x7fY\xce^\
|
||||
\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x11\xcd\
|
||||
\x00\x00\x01\x9f{0\xc9B\
|
||||
\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x1fp\
|
||||
\x00\x00\x01D\x00\x00\x00\x00\x00\x01\x00\x00,\xb6\
|
||||
\x00\x00\x01\x9f\x7f&\x83)\
|
||||
\x00\x00\x02*\x00\x00\x00\x00\x00\x01\x00\x00W|\
|
||||
\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00kU\
|
||||
\x00\x00\x01\x9f{C\xf1N\
|
||||
\x00\x00\x01\xb2\x00\x00\x00\x00\x00\x01\x00\x00EH\
|
||||
\x00\x00\x02\x1e\x00\x00\x00\x00\x00\x01\x00\x00R\x8e\
|
||||
\x00\x00\x01\x9f\x7f&\x82\xf2\
|
||||
\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x15-\
|
||||
\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x1a9\
|
||||
\x00\x00\x01\x9f{\x8d\xf34\
|
||||
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
\x00\x00\x01\x9f{0\xc9+\
|
||||
\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00=v\
|
||||
\x00\x00\x01\xfe\x00\x00\x00\x00\x00\x01\x00\x00J\xbc\
|
||||
\x00\x00\x01\x9f{C\xf1=\
|
||||
\x00\x00\x006\x00\x00\x00\x00\x00\x01\x00\x00\x05\x86\
|
||||
\x00\x00\x01\x9f\x7f&\x83\x99\
|
||||
\x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00l\x5c\
|
||||
\x00\x00\x03\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x84u\
|
||||
\x00\x00\x01\x9f{{\xa5\xe3\
|
||||
\x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x00d\xd3\
|
||||
\x00\x00\x01$\x00\x00\x00\x00\x00\x01\x00\x00'\xef\
|
||||
\x00\x00\x01\x9f\x7fV\xd5\xe5\
|
||||
\x00\x00\x03*\x00\x00\x00\x00\x00\x01\x00\x00x\xac\
|
||||
\x00\x00\x01\x9f{0\xc9R\
|
||||
"
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'connection_chooser_dialog.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.11.1
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
|
||||
QLabel, QListWidget, QListWidgetItem, QSizePolicy,
|
||||
QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_ConnectionChooserDialog(object):
|
||||
def setupUi(self, ConnectionChooserDialog):
|
||||
if not ConnectionChooserDialog.objectName():
|
||||
ConnectionChooserDialog.setObjectName(u"ConnectionChooserDialog")
|
||||
ConnectionChooserDialog.resize(460, 280)
|
||||
self.dialogLayout = QVBoxLayout(ConnectionChooserDialog)
|
||||
self.dialogLayout.setObjectName(u"dialogLayout")
|
||||
self.promptLabel = QLabel(ConnectionChooserDialog)
|
||||
self.promptLabel.setObjectName(u"promptLabel")
|
||||
|
||||
self.dialogLayout.addWidget(self.promptLabel)
|
||||
|
||||
self.connectionList = QListWidget(ConnectionChooserDialog)
|
||||
self.connectionList.setObjectName(u"connectionList")
|
||||
self.connectionList.setAlternatingRowColors(True)
|
||||
|
||||
self.dialogLayout.addWidget(self.connectionList)
|
||||
|
||||
self.buttonBox = QDialogButtonBox(ConnectionChooserDialog)
|
||||
self.buttonBox.setObjectName(u"buttonBox")
|
||||
self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok)
|
||||
|
||||
self.dialogLayout.addWidget(self.buttonBox)
|
||||
|
||||
|
||||
self.retranslateUi(ConnectionChooserDialog)
|
||||
self.buttonBox.accepted.connect(ConnectionChooserDialog.accept)
|
||||
self.buttonBox.rejected.connect(ConnectionChooserDialog.reject)
|
||||
self.connectionList.itemDoubleClicked.connect(ConnectionChooserDialog.accept)
|
||||
|
||||
QMetaObject.connectSlotsByName(ConnectionChooserDialog)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, ConnectionChooserDialog):
|
||||
ConnectionChooserDialog.setWindowTitle(QCoreApplication.translate("ConnectionChooserDialog", u"Select a Connection", None))
|
||||
self.promptLabel.setText(QCoreApplication.translate("ConnectionChooserDialog", u"Select a connection:", None))
|
||||
# retranslateUi
|
||||
|
||||
@@ -21,6 +21,7 @@ from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogBu
|
||||
QWidget)
|
||||
|
||||
from bedit.gui.graphics.icon_canvas import IconCanvasView
|
||||
from . import resources_rc
|
||||
|
||||
class Ui_IconEditorDialog(object):
|
||||
def setupUi(self, IconEditorDialog):
|
||||
@@ -33,6 +34,9 @@ class Ui_IconEditorDialog(object):
|
||||
self.shapeToolbarLayout.setObjectName(u"shapeToolbarLayout")
|
||||
self.pointerButton = QToolButton(IconEditorDialog)
|
||||
self.pointerButton.setObjectName(u"pointerButton")
|
||||
icon = QIcon()
|
||||
icon.addFile(u":/icons/icons/edit-select.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.pointerButton.setIcon(icon)
|
||||
self.pointerButton.setCheckable(True)
|
||||
self.pointerButton.setChecked(True)
|
||||
|
||||
@@ -45,36 +49,54 @@ class Ui_IconEditorDialog(object):
|
||||
|
||||
self.addRectangleButton = QToolButton(IconEditorDialog)
|
||||
self.addRectangleButton.setObjectName(u"addRectangleButton")
|
||||
icon1 = QIcon()
|
||||
icon1.addFile(u":/icons/icons/draw-rectangle.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addRectangleButton.setIcon(icon1)
|
||||
self.addRectangleButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addRectangleButton)
|
||||
|
||||
self.addCircleButton = QToolButton(IconEditorDialog)
|
||||
self.addCircleButton.setObjectName(u"addCircleButton")
|
||||
icon2 = QIcon()
|
||||
icon2.addFile(u":/icons/icons/draw-circle.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addCircleButton.setIcon(icon2)
|
||||
self.addCircleButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addCircleButton)
|
||||
|
||||
self.addEllipseButton = QToolButton(IconEditorDialog)
|
||||
self.addEllipseButton.setObjectName(u"addEllipseButton")
|
||||
icon3 = QIcon()
|
||||
icon3.addFile(u":/icons/icons/draw-ellipse.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addEllipseButton.setIcon(icon3)
|
||||
self.addEllipseButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addEllipseButton)
|
||||
|
||||
self.addLineButton = QToolButton(IconEditorDialog)
|
||||
self.addLineButton.setObjectName(u"addLineButton")
|
||||
icon4 = QIcon()
|
||||
icon4.addFile(u":/icons/icons/draw-bezier-curves.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addLineButton.setIcon(icon4)
|
||||
self.addLineButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addLineButton)
|
||||
|
||||
self.addTriangleButton = QToolButton(IconEditorDialog)
|
||||
self.addTriangleButton.setObjectName(u"addTriangleButton")
|
||||
icon5 = QIcon()
|
||||
icon5.addFile(u":/icons/icons/draw-triangle.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addTriangleButton.setIcon(icon5)
|
||||
self.addTriangleButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addTriangleButton)
|
||||
|
||||
self.addTextButton = QToolButton(IconEditorDialog)
|
||||
self.addTextButton.setObjectName(u"addTextButton")
|
||||
icon6 = QIcon()
|
||||
icon6.addFile(u":/icons/icons/draw-text.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.addTextButton.setIcon(icon6)
|
||||
self.addTextButton.setCheckable(True)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.addTextButton)
|
||||
@@ -85,16 +107,25 @@ class Ui_IconEditorDialog(object):
|
||||
|
||||
self.zoomInButton = QToolButton(IconEditorDialog)
|
||||
self.zoomInButton.setObjectName(u"zoomInButton")
|
||||
icon7 = QIcon()
|
||||
icon7.addFile(u":/icons/icons/zoom-in.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.zoomInButton.setIcon(icon7)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.zoomInButton)
|
||||
|
||||
self.zoomOutButton = QToolButton(IconEditorDialog)
|
||||
self.zoomOutButton.setObjectName(u"zoomOutButton")
|
||||
icon8 = QIcon()
|
||||
icon8.addFile(u":/icons/icons/zoom-out.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.zoomOutButton.setIcon(icon8)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.zoomOutButton)
|
||||
|
||||
self.centerButton = QToolButton(IconEditorDialog)
|
||||
self.centerButton.setObjectName(u"centerButton")
|
||||
icon9 = QIcon()
|
||||
icon9.addFile(u":/icons/icons/zoom-original.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.centerButton.setIcon(icon9)
|
||||
|
||||
self.shapeToolbarLayout.addWidget(self.centerButton)
|
||||
|
||||
@@ -142,18 +173,18 @@ class Ui_IconEditorDialog(object):
|
||||
self.addLineButton.setText(QCoreApplication.translate("IconEditorDialog", u"Line", None))
|
||||
self.addTriangleButton.setText(QCoreApplication.translate("IconEditorDialog", u"Triangle", None))
|
||||
self.addTextButton.setText(QCoreApplication.translate("IconEditorDialog", u"Text", None))
|
||||
self.zoomInButton.setText(QCoreApplication.translate("IconEditorDialog", u"+", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.zoomInButton.setToolTip(QCoreApplication.translate("IconEditorDialog", u"Zoom in", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.zoomOutButton.setText(QCoreApplication.translate("IconEditorDialog", u"\u2212", None))
|
||||
self.zoomInButton.setText(QCoreApplication.translate("IconEditorDialog", u"+", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.zoomOutButton.setToolTip(QCoreApplication.translate("IconEditorDialog", u"Zoom out", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.centerButton.setText(QCoreApplication.translate("IconEditorDialog", u"Fit", None))
|
||||
self.zoomOutButton.setText(QCoreApplication.translate("IconEditorDialog", u"\u2212", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.centerButton.setToolTip(QCoreApplication.translate("IconEditorDialog", u"Fit and center the icon canvas", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.centerButton.setText(QCoreApplication.translate("IconEditorDialog", u"Fit", None))
|
||||
self.deleteSelectedButton.setText(QCoreApplication.translate("IconEditorDialog", u"Delete selected", None))
|
||||
self.portHintLabel.setText(QCoreApplication.translate("IconEditorDialog", u"Green points are inputs; red points are outputs. Drag them to place connection anchors.", None))
|
||||
# retranslateUi
|
||||
|
||||
@@ -235,33 +235,36 @@ class Ui_MainWindow(object):
|
||||
|
||||
self.connectToolButton = QToolButton(self.workspaceHeader)
|
||||
self.connectToolButton.setObjectName(u"connectToolButton")
|
||||
icon16 = QIcon()
|
||||
icon16.addFile(u":/icons/icons/network-connect.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.connectToolButton.setIcon(icon16)
|
||||
self.connectToolButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.connectToolButton)
|
||||
|
||||
self.boxToolButton = QToolButton(self.workspaceHeader)
|
||||
self.boxToolButton.setObjectName(u"boxToolButton")
|
||||
icon16 = QIcon()
|
||||
icon16.addFile(u":/icons/icons/draw-rectangle.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.boxToolButton.setIcon(icon16)
|
||||
icon17 = QIcon()
|
||||
icon17.addFile(u":/icons/icons/draw-rectangle.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.boxToolButton.setIcon(icon17)
|
||||
self.boxToolButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.boxToolButton)
|
||||
|
||||
self.lineToolButton = QToolButton(self.workspaceHeader)
|
||||
self.lineToolButton.setObjectName(u"lineToolButton")
|
||||
icon17 = QIcon()
|
||||
icon17.addFile(u":/icons/icons/draw-bezier-curves.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.lineToolButton.setIcon(icon17)
|
||||
icon18 = QIcon()
|
||||
icon18.addFile(u":/icons/icons/draw-bezier-curves.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.lineToolButton.setIcon(icon18)
|
||||
self.lineToolButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.lineToolButton)
|
||||
|
||||
self.textToolButton = QToolButton(self.workspaceHeader)
|
||||
self.textToolButton.setObjectName(u"textToolButton")
|
||||
icon18 = QIcon()
|
||||
icon18.addFile(u":/icons/icons/draw-text.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.textToolButton.setIcon(icon18)
|
||||
icon19 = QIcon()
|
||||
icon19.addFile(u":/icons/icons/draw-text.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.textToolButton.setIcon(icon19)
|
||||
self.textToolButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.textToolButton)
|
||||
@@ -272,30 +275,6 @@ class Ui_MainWindow(object):
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.rotateToolButton)
|
||||
|
||||
self.routingLabel = QLabel(self.workspaceHeader)
|
||||
self.routingLabel.setObjectName(u"routingLabel")
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.routingLabel)
|
||||
|
||||
self.directRoutingButton = QToolButton(self.workspaceHeader)
|
||||
self.directRoutingButton.setObjectName(u"directRoutingButton")
|
||||
self.directRoutingButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.directRoutingButton)
|
||||
|
||||
self.angledRoutingButton = QToolButton(self.workspaceHeader)
|
||||
self.angledRoutingButton.setObjectName(u"angledRoutingButton")
|
||||
self.angledRoutingButton.setCheckable(True)
|
||||
self.angledRoutingButton.setChecked(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.angledRoutingButton)
|
||||
|
||||
self.splineRoutingButton = QToolButton(self.workspaceHeader)
|
||||
self.splineRoutingButton.setObjectName(u"splineRoutingButton")
|
||||
self.splineRoutingButton.setCheckable(True)
|
||||
|
||||
self.workspaceHeaderLayout.addWidget(self.splineRoutingButton)
|
||||
|
||||
|
||||
self.workspaceEditorLayout.addWidget(self.workspaceHeader)
|
||||
|
||||
@@ -545,10 +524,6 @@ class Ui_MainWindow(object):
|
||||
self.rotateToolButton.setToolTip(QCoreApplication.translate("MainWindow", u"Rotate selected blocks clockwise", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.rotateToolButton.setText(QCoreApplication.translate("MainWindow", u"Rotate", None))
|
||||
self.routingLabel.setText(QCoreApplication.translate("MainWindow", u"Line:", None))
|
||||
self.directRoutingButton.setText(QCoreApplication.translate("MainWindow", u"Direct", None))
|
||||
self.angledRoutingButton.setText(QCoreApplication.translate("MainWindow", u"Angled", None))
|
||||
self.splineRoutingButton.setText(QCoreApplication.translate("MainWindow", u"Spline", None))
|
||||
self.jsonEditor.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Component JSON", None))
|
||||
self.emptyWorkspaceLabel.setText(QCoreApplication.translate("MainWindow", u"No document open", None))
|
||||
self.menuFile.setTitle(QCoreApplication.translate("MainWindow", u"&File", None))
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
from PySide6.QtCore import QMimeData, QPointF, QRectF, Qt, Signal
|
||||
from PySide6.QtGui import (
|
||||
QColor,
|
||||
QDragEnterEvent,
|
||||
QDropEvent,
|
||||
QKeyEvent,
|
||||
QMouseEvent,
|
||||
QWheelEvent,
|
||||
QPainter,
|
||||
@@ -32,17 +34,26 @@ from PySide6.QtWidgets import (
|
||||
|
||||
from bedit.core.model import Annotation, Component, Connection, Endpoint, Port
|
||||
from bedit.gui.controllers.document import DocumentController
|
||||
from bedit.gui.dialogs.connection_chooser import ConnectionChooserDialog
|
||||
from bedit.gui.models.library_tree import COMPONENT_MIME_TYPE
|
||||
from bedit.gui.graphics.icon_renderer import icon_bounds, paint_icon
|
||||
from bedit.gui.graphics.icon_editor import ShapeOptionsDialog
|
||||
from bedit.gui.graphics.icon_renderer import shape_pen
|
||||
from bedit.gui.graphics.connection_styles import ConnectionStyle, connection_style
|
||||
from bedit.gui.preferences import application_settings
|
||||
from bedit.core.port_types import PortTypeRegistry
|
||||
|
||||
|
||||
SELECTION_MIME_TYPE = "application/x-bedit-selection"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ConnectionChoice:
|
||||
source: Endpoint
|
||||
target: Endpoint
|
||||
label: str
|
||||
|
||||
|
||||
def _graph_snap_size() -> int:
|
||||
return application_settings().value("grid/graphSnapSize", 8, type=int)
|
||||
|
||||
@@ -690,11 +701,10 @@ class GraphScene(QGraphicsScene):
|
||||
self.output_items: dict[str, InterfaceTerminalItem] = {}
|
||||
self.connection_items: dict[str, ConnectionGraphicsItem] = {}
|
||||
self.annotation_items: dict[str, QGraphicsItem] = {}
|
||||
self.pending_source: ConnectionPortItem | None = None
|
||||
self.pending_connection_item: ComponentGraphicsItem | ConnectionPortItem | None = None
|
||||
self.pending_waypoints: list[QPointF] = []
|
||||
self.pending_preview: QGraphicsPathItem | None = None
|
||||
self.interaction_mode = "pointer"
|
||||
self.connection_routing = "angled"
|
||||
self.drawing_start: QPointF | None = None
|
||||
self.drawing_waypoints: list[QPointF] = []
|
||||
self.setSceneRect(-2000, -2000, 4000, 4000)
|
||||
@@ -713,7 +723,7 @@ class GraphScene(QGraphicsScene):
|
||||
self.output_items.clear()
|
||||
self.connection_items.clear()
|
||||
self.annotation_items.clear()
|
||||
self.pending_source = None
|
||||
self.pending_connection_item = None
|
||||
self.pending_waypoints.clear()
|
||||
self.pending_preview = None
|
||||
owner = self.controller.active_component
|
||||
@@ -753,6 +763,7 @@ class GraphScene(QGraphicsScene):
|
||||
item = AnnotationGraphicsItem(annotation, self.controller)
|
||||
self.addItem(item)
|
||||
self.annotation_items[annotation.id] = item
|
||||
self._set_port_hints_visible(self.interaction_mode == "connect")
|
||||
|
||||
def set_component_position(self, component_id: str, position: QPointF) -> None:
|
||||
item = self.component_items.get(component_id)
|
||||
@@ -837,23 +848,65 @@ class GraphScene(QGraphicsScene):
|
||||
ports = component.output_ports if role == "source" else component.input_ports
|
||||
return ports.get(endpoint.port or "")
|
||||
|
||||
@staticmethod
|
||||
def _hitbox_intersection(component: ComponentGraphicsItem, reference: QPointF) -> QPointF:
|
||||
rect = component.hitbox.normalized()
|
||||
local = component.mapFromScene(reference)
|
||||
center = rect.center()
|
||||
delta = local - center
|
||||
if delta.isNull():
|
||||
return component.mapToScene(QPointF(rect.right(), center.y()))
|
||||
scales: list[float] = []
|
||||
if delta.x() != 0:
|
||||
scales.append((rect.width() / 2) / abs(delta.x()))
|
||||
if delta.y() != 0:
|
||||
scales.append((rect.height() / 2) / abs(delta.y()))
|
||||
return component.mapToScene(center + delta * min(scales))
|
||||
|
||||
def _endpoint_center(self, endpoint: Endpoint, role: str) -> QPointF | None:
|
||||
if endpoint.block is not None:
|
||||
component = self.component_items.get(endpoint.block)
|
||||
return component.mapToScene(component.hitbox.center()) if component else None
|
||||
port = self._endpoint_item(endpoint, role)
|
||||
return port.scenePos() if port else None
|
||||
|
||||
def _visible_endpoint(
|
||||
self, endpoint: Endpoint, role: str, reference: QPointF
|
||||
) -> QPointF | None:
|
||||
if endpoint.block is not None:
|
||||
component = self.component_items.get(endpoint.block)
|
||||
return self._hitbox_intersection(component, reference) if component else None
|
||||
port = self._endpoint_item(endpoint, role)
|
||||
return port.scenePos() if port else None
|
||||
|
||||
def _connection_geometry(
|
||||
self, connection: Connection, waypoints: list[QPointF]
|
||||
) -> tuple[QPointF, QPointF] | None:
|
||||
source_center = self._endpoint_center(connection.source, "source")
|
||||
target_center = self._endpoint_center(connection.target, "target")
|
||||
if source_center is None or target_center is None:
|
||||
return None
|
||||
start_reference = waypoints[0] if waypoints else target_center
|
||||
end_reference = waypoints[-1] if waypoints else source_center
|
||||
start = self._visible_endpoint(connection.source, "source", start_reference)
|
||||
end = self._visible_endpoint(connection.target, "target", end_reference)
|
||||
return (start, end) if start is not None and end is not None else None
|
||||
|
||||
def update_connection(self, connection_id: str) -> None:
|
||||
connection = self.controller.active_graph.connections.get(connection_id)
|
||||
graphics = self.connection_items.get(connection_id)
|
||||
if connection is None or graphics is None:
|
||||
return
|
||||
source = self._endpoint_item(connection.source, "source")
|
||||
target = self._endpoint_item(connection.target, "target")
|
||||
if source is None or target is None:
|
||||
return
|
||||
start, end = source.scenePos(), target.scenePos()
|
||||
routing = str(connection.properties.get("routing", "angled"))
|
||||
waypoints = [
|
||||
QPointF(float(point["x"]), float(point["y"]))
|
||||
for point in connection.properties.get("waypoints", [])
|
||||
if isinstance(point, dict) and "x" in point and "y" in point
|
||||
]
|
||||
path, direction_points = self._route_path(start, end, routing, waypoints)
|
||||
geometry = self._connection_geometry(connection, waypoints)
|
||||
if geometry is None:
|
||||
return
|
||||
start, end = geometry
|
||||
path, direction_points = self._route_path(start, end, waypoints)
|
||||
graphics.set_connection_path(path, direction_points)
|
||||
graphics.set_waypoints(waypoints)
|
||||
|
||||
@@ -868,112 +921,193 @@ class GraphScene(QGraphicsScene):
|
||||
QPointF(float(p["x"]), float(p["y"]))
|
||||
for p in annotation.properties.get("waypoints", [])
|
||||
]
|
||||
routing = str(annotation.properties.get("routing", "angled"))
|
||||
path, points = self._route_path(start, end, routing, waypoints)
|
||||
path, points = self._route_path(start, end, waypoints)
|
||||
graphics.setPath(path)
|
||||
graphics.set_waypoints(waypoints, start, end)
|
||||
|
||||
@staticmethod
|
||||
def _orthogonal_points(start: QPointF, end: QPointF, waypoints: list[QPointF]) -> list[QPointF]:
|
||||
points = [start]
|
||||
for waypoint in [*waypoints, end]:
|
||||
previous = points[-1]
|
||||
if previous.x() != waypoint.x() and previous.y() != waypoint.y():
|
||||
elbow = QPointF(waypoint.x(), previous.y())
|
||||
points.append(elbow)
|
||||
if waypoint != points[-1]:
|
||||
points.append(waypoint)
|
||||
return points
|
||||
|
||||
@staticmethod
|
||||
def _route_path(
|
||||
start: QPointF,
|
||||
end: QPointF,
|
||||
routing: str,
|
||||
waypoints: list[QPointF] | None = None,
|
||||
) -> tuple[QPainterPath, list[QPointF]]:
|
||||
waypoints = waypoints or []
|
||||
points = [start, *(waypoints or []), end]
|
||||
path = QPainterPath(start)
|
||||
if routing == "angled":
|
||||
points = GraphScene._orthogonal_points(start, end, waypoints)
|
||||
for point in points[1:]:
|
||||
path.lineTo(point)
|
||||
return path, points
|
||||
if routing == "direct":
|
||||
path.lineTo(end)
|
||||
return path, [start, end]
|
||||
if waypoints:
|
||||
points = [start, *waypoints, end]
|
||||
for index, point in enumerate(points[1:-1], start=1):
|
||||
following = points[index + 1]
|
||||
midpoint = QPointF((point.x() + following.x()) / 2, (point.y() + following.y()) / 2)
|
||||
path.quadTo(point, midpoint)
|
||||
path.quadTo(points[-2], end)
|
||||
return path, points
|
||||
distance = max(50.0, abs(end.x() - start.x()) * 0.5)
|
||||
first_control, second_control = start + QPointF(distance, 0), end - QPointF(distance, 0)
|
||||
path.cubicTo(first_control, second_control, end)
|
||||
return path, [start, first_control, second_control, end]
|
||||
for point in points[1:]:
|
||||
path.lineTo(point)
|
||||
return path, points
|
||||
|
||||
def set_interaction_mode(self, mode: str) -> None:
|
||||
self.interaction_mode = mode
|
||||
if mode != "connect":
|
||||
self._clear_pending_source()
|
||||
self._clear_pending_connection()
|
||||
self._clear_drawing()
|
||||
self._set_port_hints_visible(mode == "connect")
|
||||
|
||||
def set_connection_routing(self, routing: str) -> None:
|
||||
self.connection_routing = routing
|
||||
self._clear_pending_source()
|
||||
def _set_port_hints_visible(self, visible: bool) -> None:
|
||||
for component in self.component_items.values():
|
||||
for port in (*component.input_ports.values(), *component.output_ports.values()):
|
||||
port.setVisible(visible)
|
||||
for terminal in (*self.input_items.values(), *self.output_items.values()):
|
||||
terminal.connection_port.setVisible(visible)
|
||||
|
||||
@staticmethod
|
||||
def _clicked_component(
|
||||
item: QGraphicsItem | None,
|
||||
) -> ComponentGraphicsItem | None:
|
||||
if isinstance(item, ComponentGraphicsItem):
|
||||
return item
|
||||
if isinstance(item, ConnectionPortItem) and isinstance(
|
||||
item.parentItem(), ComponentGraphicsItem
|
||||
):
|
||||
return item.parentItem()
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _click_endpoint(item: QGraphicsItem | None) -> Endpoint | None:
|
||||
return item.endpoint if isinstance(item, ConnectionPortItem) else None
|
||||
|
||||
@staticmethod
|
||||
def _connection_anchor(
|
||||
item: ComponentGraphicsItem | ConnectionPortItem,
|
||||
) -> QPointF:
|
||||
return (
|
||||
item.scenePos()
|
||||
if isinstance(item, ConnectionPortItem)
|
||||
else item.sceneBoundingRect().center()
|
||||
)
|
||||
|
||||
def _connection_choices(
|
||||
self,
|
||||
first: ComponentGraphicsItem,
|
||||
second: ComponentGraphicsItem,
|
||||
) -> list[ConnectionChoice]:
|
||||
choices: list[ConnectionChoice] = []
|
||||
|
||||
def add_pairs(
|
||||
source_item: ComponentGraphicsItem, target_item: ComponentGraphicsItem
|
||||
) -> None:
|
||||
for output in source_item.component.outputs:
|
||||
for input_port in target_item.component.inputs:
|
||||
if not PortTypeRegistry.compatible(output.type, input_port.type):
|
||||
continue
|
||||
choices.append(
|
||||
ConnectionChoice(
|
||||
Endpoint(block=source_item.component_id, port=output.id),
|
||||
Endpoint(block=target_item.component_id, port=input_port.id),
|
||||
f"{source_item.component.name}.{output.name} → "
|
||||
f"{target_item.component.name}.{input_port.name}",
|
||||
)
|
||||
)
|
||||
|
||||
add_pairs(first, second)
|
||||
add_pairs(second, first)
|
||||
return choices
|
||||
|
||||
@staticmethod
|
||||
def _default_choice_index(
|
||||
choices: list[ConnectionChoice],
|
||||
first_component: ComponentGraphicsItem,
|
||||
second_component: ComponentGraphicsItem,
|
||||
first_endpoint: Endpoint | None,
|
||||
second_endpoint: Endpoint | None,
|
||||
) -> int:
|
||||
def score(choice: ConnectionChoice) -> int:
|
||||
value = 0
|
||||
if first_endpoint is not None and first_endpoint in (choice.source, choice.target):
|
||||
value += 8
|
||||
if second_endpoint is not None and second_endpoint in (choice.source, choice.target):
|
||||
value += 8
|
||||
if choice.source.block == first_component.component_id:
|
||||
value += 2
|
||||
if choice.target.block == second_component.component_id:
|
||||
value += 1
|
||||
return value
|
||||
|
||||
return max(range(len(choices)), key=lambda index: score(choices[index]))
|
||||
|
||||
def _finish_block_connection(
|
||||
self,
|
||||
second_item: ComponentGraphicsItem | ConnectionPortItem,
|
||||
) -> None:
|
||||
first_item = self.pending_connection_item
|
||||
if first_item is None:
|
||||
return
|
||||
first_component = self._clicked_component(first_item)
|
||||
second_component = self._clicked_component(second_item)
|
||||
if (
|
||||
first_component is None
|
||||
or second_component is None
|
||||
or first_component is second_component
|
||||
):
|
||||
self._clear_pending_connection()
|
||||
return
|
||||
choices = self._connection_choices(first_component, second_component)
|
||||
if not choices:
|
||||
QToolTip.showText(
|
||||
self.views()[0].mapToGlobal(self.views()[0].viewport().rect().center())
|
||||
if self.views()
|
||||
else QPointF().toPoint(),
|
||||
"These blocks have no compatible input/output pairs",
|
||||
)
|
||||
self._clear_pending_connection()
|
||||
return
|
||||
default = self._default_choice_index(
|
||||
choices,
|
||||
first_component,
|
||||
second_component,
|
||||
self._click_endpoint(first_item),
|
||||
self._click_endpoint(second_item),
|
||||
)
|
||||
dialog = ConnectionChooserDialog(
|
||||
[choice.label for choice in choices],
|
||||
default,
|
||||
self.views()[0] if self.views() else None,
|
||||
)
|
||||
if dialog.exec() == dialog.DialogCode.Accepted:
|
||||
choice = choices[dialog.selected_index]
|
||||
try:
|
||||
self.controller.connect(
|
||||
choice.source, choice.target, waypoints=self.pending_waypoints
|
||||
)
|
||||
except ValueError as error:
|
||||
QToolTip.showText(dialog.mapToGlobal(dialog.rect().center()), str(error))
|
||||
self._clear_pending_connection()
|
||||
|
||||
def mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None: # noqa: N802
|
||||
if self.interaction_mode in {"box", "text", "line"}:
|
||||
self._drawing_press(event)
|
||||
return
|
||||
if self.interaction_mode != "connect":
|
||||
self._clear_pending_source()
|
||||
self._clear_pending_connection()
|
||||
super().mousePressEvent(event)
|
||||
return
|
||||
if event.button() == Qt.MouseButton.RightButton:
|
||||
self._clear_pending_source()
|
||||
self._clear_pending_connection()
|
||||
event.accept()
|
||||
return
|
||||
item = self.itemAt(event.scenePos(), QTransform())
|
||||
if isinstance(item, ConnectionPortItem):
|
||||
if item.role == "source":
|
||||
self._clear_pending_source()
|
||||
self.pending_source = item
|
||||
component = self._clicked_component(item)
|
||||
if component is not None:
|
||||
clicked = item if isinstance(item, ConnectionPortItem) else component
|
||||
if self.pending_connection_item is None:
|
||||
self.pending_connection_item = clicked
|
||||
self.pending_waypoints = []
|
||||
item.setBrush(QColor("#f5b642"))
|
||||
if isinstance(clicked, ConnectionPortItem):
|
||||
clicked.setBrush(QColor("#f5b642"))
|
||||
self._create_preview()
|
||||
elif self.pending_source is not None:
|
||||
if self.pending_source.endpoint != item.endpoint:
|
||||
try:
|
||||
self.controller.connect(
|
||||
self.pending_source.endpoint,
|
||||
item.endpoint,
|
||||
routing=self.connection_routing,
|
||||
waypoints=(
|
||||
self._completed_angled_waypoints(
|
||||
self.pending_source.scenePos(),
|
||||
item.scenePos(),
|
||||
self.pending_waypoints,
|
||||
)
|
||||
if self.connection_routing == "angled"
|
||||
else self.pending_waypoints
|
||||
),
|
||||
)
|
||||
except ValueError as error:
|
||||
QToolTip.showText(event.screenPos(), str(error))
|
||||
self._clear_pending_source()
|
||||
self._update_preview(event.scenePos())
|
||||
else:
|
||||
self._finish_block_connection(clicked)
|
||||
event.accept()
|
||||
return
|
||||
if self.pending_source is not None and self.connection_routing == "angled":
|
||||
if self.pending_connection_item is not None:
|
||||
self.pending_waypoints.append(_snapped(event.scenePos()))
|
||||
self._update_preview(event.scenePos())
|
||||
event.accept()
|
||||
|
||||
def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None: # noqa: N802
|
||||
if self.interaction_mode == "connect" and self.pending_source is not None:
|
||||
if self.interaction_mode == "connect" and self.pending_connection_item is not None:
|
||||
self._update_preview(event.scenePos())
|
||||
event.accept()
|
||||
return
|
||||
@@ -1011,14 +1145,9 @@ class GraphScene(QGraphicsScene):
|
||||
self.drawing_start = point
|
||||
self.drawing_waypoints = []
|
||||
self._create_preview()
|
||||
elif self.interaction_mode == "line" and self.connection_routing == "angled":
|
||||
elif self.interaction_mode == "line":
|
||||
self.drawing_waypoints.append(point)
|
||||
self._update_drawing_preview(point)
|
||||
elif self.interaction_mode == "line":
|
||||
self.controller.add_annotation(
|
||||
"line", self.drawing_start, point, routing=self.connection_routing
|
||||
)
|
||||
self._clear_drawing()
|
||||
event.accept()
|
||||
|
||||
def mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None: # noqa: N802
|
||||
@@ -1029,21 +1158,12 @@ class GraphScene(QGraphicsScene):
|
||||
if self.drawing_waypoints and self.drawing_waypoints[-1] == end
|
||||
else self.drawing_waypoints
|
||||
)
|
||||
completed = self._completed_angled_waypoints(self.drawing_start, end, waypoints)
|
||||
self.controller.add_annotation(
|
||||
"line", self.drawing_start, end, routing="angled", waypoints=completed
|
||||
)
|
||||
self.controller.add_annotation("line", self.drawing_start, end, waypoints=waypoints)
|
||||
self._clear_drawing()
|
||||
event.accept()
|
||||
return
|
||||
super().mouseDoubleClickEvent(event)
|
||||
|
||||
@staticmethod
|
||||
def _completed_angled_waypoints(
|
||||
start: QPointF, end: QPointF, waypoints: list[QPointF]
|
||||
) -> list[QPointF]:
|
||||
return GraphScene._orthogonal_points(start, end, waypoints)[1:-1]
|
||||
|
||||
def _update_drawing_preview(self, cursor: QPointF) -> None:
|
||||
if self.drawing_start is None or self.pending_preview is None:
|
||||
return
|
||||
@@ -1052,13 +1172,11 @@ class GraphScene(QGraphicsScene):
|
||||
path = QPainterPath()
|
||||
path.addRect(QRectF(self.drawing_start, end).normalized())
|
||||
else:
|
||||
path, _ = self._route_path(
|
||||
self.drawing_start, end, self.connection_routing, self.drawing_waypoints
|
||||
)
|
||||
path, _ = self._route_path(self.drawing_start, end, self.drawing_waypoints)
|
||||
self.pending_preview.setPath(path)
|
||||
|
||||
def _clear_drawing(self) -> None:
|
||||
if self.pending_preview is not None and self.pending_source is None:
|
||||
if self.pending_preview is not None and self.pending_connection_item is None:
|
||||
self.removeItem(self.pending_preview)
|
||||
self.pending_preview = None
|
||||
self.drawing_start = None
|
||||
@@ -1118,10 +1236,7 @@ class GraphScene(QGraphicsScene):
|
||||
key=lambda index: segment_distance(snapped, anchors[index], anchors[index + 1]),
|
||||
)
|
||||
points.insert(insertion, snapped)
|
||||
routing = "angled" if item.properties.get("routing") == "direct" else None
|
||||
if routing == "angled" or item.properties.get("routing") == "angled":
|
||||
points = self._orthogonal_points(start, end, points)[1:-1]
|
||||
self.controller.set_route_waypoints(item_kind, item_id, points, routing)
|
||||
self.controller.set_route_waypoints(item_kind, item_id, points)
|
||||
|
||||
def move_route_node(self, item_kind: str, item_id: str, index: int, position: QPointF) -> None:
|
||||
item, points = self._route_values(item_kind, item_id)
|
||||
@@ -1147,14 +1262,6 @@ class GraphScene(QGraphicsScene):
|
||||
return
|
||||
if index < len(points):
|
||||
points[index] = position
|
||||
if item.properties.get("routing") == "angled":
|
||||
if item_kind == "annotation":
|
||||
start = QPointF(item.x, item.y)
|
||||
end = QPointF(item.x + item.width, item.y + item.height)
|
||||
else:
|
||||
graphics = self.connection_items[item_id]
|
||||
start, end = graphics.start, graphics.end
|
||||
points = self._orthogonal_points(start, end, points)[1:-1]
|
||||
self.controller.set_route_waypoints(item_kind, item_id, points)
|
||||
|
||||
def preview_route_node(
|
||||
@@ -1169,23 +1276,20 @@ class GraphScene(QGraphicsScene):
|
||||
return
|
||||
start = position if index == -1 else QPointF(item.x, item.y)
|
||||
end = position if index == -2 else QPointF(item.x + item.width, item.y + item.height)
|
||||
path, _direction_points = self._route_path(
|
||||
start,
|
||||
end,
|
||||
str(item.properties.get("routing", "angled")),
|
||||
points,
|
||||
)
|
||||
path, _direction_points = self._route_path(start, end, points)
|
||||
graphics.setPath(path)
|
||||
return
|
||||
if index >= len(points):
|
||||
return
|
||||
points[index] = position
|
||||
routing = str(item.properties.get("routing", "angled"))
|
||||
if item_kind == "connection":
|
||||
graphics = self.connection_items.get(item_id)
|
||||
if graphics is None:
|
||||
return
|
||||
path, direction_points = self._route_path(graphics.start, graphics.end, routing, points)
|
||||
geometry = self._connection_geometry(item, points)
|
||||
if geometry is None:
|
||||
return
|
||||
path, direction_points = self._route_path(*geometry, points)
|
||||
graphics.set_connection_path(path, direction_points)
|
||||
return
|
||||
graphics = self.annotation_items.get(item_id)
|
||||
@@ -1193,7 +1297,7 @@ class GraphScene(QGraphicsScene):
|
||||
return
|
||||
start = QPointF(item.x, item.y)
|
||||
end = QPointF(item.x + item.width, item.y + item.height)
|
||||
path, _direction_points = self._route_path(start, end, routing, points)
|
||||
path, _direction_points = self._route_path(start, end, points)
|
||||
graphics.setPath(path)
|
||||
|
||||
def delete_route_node(self, item_kind: str, item_id: str, index: int) -> None:
|
||||
@@ -1217,29 +1321,29 @@ class GraphScene(QGraphicsScene):
|
||||
self.addItem(self.pending_preview)
|
||||
|
||||
def _update_preview(self, cursor: QPointF) -> None:
|
||||
if self.pending_source is None or self.pending_preview is None:
|
||||
if self.pending_connection_item is None or self.pending_preview is None:
|
||||
return
|
||||
preview_cursor = _snapped(cursor) if self.connection_routing == "angled" else cursor
|
||||
preview_cursor = _snapped(cursor)
|
||||
path, _points = self._route_path(
|
||||
self.pending_source.scenePos(),
|
||||
self._connection_anchor(self.pending_connection_item),
|
||||
preview_cursor,
|
||||
self.connection_routing,
|
||||
self.pending_waypoints,
|
||||
)
|
||||
self.pending_preview.setPath(path)
|
||||
|
||||
def _clear_pending_source(self) -> None:
|
||||
if self.pending_source is not None:
|
||||
self.pending_source.setBrush(QColor("#ffffff"))
|
||||
def _clear_pending_connection(self) -> None:
|
||||
if isinstance(self.pending_connection_item, ConnectionPortItem):
|
||||
self.pending_connection_item.setBrush(QColor("#ffffff"))
|
||||
if self.pending_preview is not None:
|
||||
self.removeItem(self.pending_preview)
|
||||
self.pending_source = None
|
||||
self.pending_connection_item = None
|
||||
self.pending_waypoints.clear()
|
||||
self.pending_preview = None
|
||||
|
||||
|
||||
class GraphWorkspaceView(QGraphicsView):
|
||||
toolUsed = Signal()
|
||||
toolModeShortcutRequested = Signal(str)
|
||||
componentOptionsRequested = Signal(str)
|
||||
componentPortOptionsRequested = Signal(str)
|
||||
portOptionsRequested = Signal(str, str)
|
||||
@@ -1252,6 +1356,7 @@ class GraphWorkspaceView(QGraphicsView):
|
||||
self.tool_mode = "pointer"
|
||||
self.paste_count = 0
|
||||
self.setAcceptDrops(True)
|
||||
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
self.setMouseTracking(True)
|
||||
self.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)
|
||||
@@ -1304,6 +1409,23 @@ class GraphWorkspaceView(QGraphicsView):
|
||||
self._zoom(1.2 if event.angleDelta().y() > 0 else 1 / 1.2)
|
||||
event.accept()
|
||||
|
||||
def keyPressEvent(self, event: QKeyEvent) -> None: # noqa: N802
|
||||
if not event.isAutoRepeat() and event.key() == Qt.Key.Key_Space:
|
||||
self.toolModeShortcutRequested.emit(
|
||||
"connect" if self.tool_mode == "pointer" else "pointer"
|
||||
)
|
||||
event.accept()
|
||||
return
|
||||
if (
|
||||
not event.isAutoRepeat()
|
||||
and event.key() == Qt.Key.Key_Escape
|
||||
and self.tool_mode != "pointer"
|
||||
):
|
||||
self.toolModeShortcutRequested.emit("pointer")
|
||||
event.accept()
|
||||
return
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def set_model(self, controller: DocumentController) -> None:
|
||||
self.controller = controller
|
||||
scene = GraphScene(controller, self)
|
||||
@@ -1445,11 +1567,6 @@ class GraphWorkspaceView(QGraphicsView):
|
||||
if isinstance(scene, GraphScene):
|
||||
scene.set_interaction_mode(mode)
|
||||
|
||||
def set_connection_routing(self, routing: str) -> None:
|
||||
scene = self.scene()
|
||||
if isinstance(scene, GraphScene):
|
||||
scene.set_connection_routing(routing)
|
||||
|
||||
def mousePressEvent(self, event: QMouseEvent) -> None: # noqa: N802
|
||||
super().mousePressEvent(event)
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ class MainWindow(QMainWindow):
|
||||
self.ui.graphView.selectionAvailabilityChanged.connect(
|
||||
lambda _available: self._update_edit_actions()
|
||||
)
|
||||
self.ui.graphView.toolModeShortcutRequested.connect(self.set_graph_tool)
|
||||
self.mode_button_group = QButtonGroup(self)
|
||||
self.mode_button_group.setExclusive(True)
|
||||
self.mode_button_group.addButton(self.ui.pointerToolButton)
|
||||
@@ -99,14 +100,6 @@ class MainWindow(QMainWindow):
|
||||
self.mode_button_group.addButton(self.ui.boxToolButton)
|
||||
self.mode_button_group.addButton(self.ui.lineToolButton)
|
||||
self.mode_button_group.addButton(self.ui.textToolButton)
|
||||
self.routing_button_group = QButtonGroup(self)
|
||||
self.routing_button_group.setExclusive(True)
|
||||
for button in (
|
||||
self.ui.directRoutingButton,
|
||||
self.ui.angledRoutingButton,
|
||||
self.ui.splineRoutingButton,
|
||||
):
|
||||
self.routing_button_group.addButton(button)
|
||||
self.ui.navigateUpButton.clicked.connect(self.navigate_up)
|
||||
self.ui.navigateDownButton.clicked.connect(self.navigate_down)
|
||||
self.ui.pointerToolButton.clicked.connect(lambda: self.set_graph_tool("pointer"))
|
||||
@@ -115,9 +108,6 @@ class MainWindow(QMainWindow):
|
||||
self.ui.lineToolButton.clicked.connect(lambda: self.set_graph_tool("line"))
|
||||
self.ui.textToolButton.clicked.connect(lambda: self.set_graph_tool("text"))
|
||||
self.ui.rotateToolButton.clicked.connect(self.ui.graphView.rotate_selected)
|
||||
self.ui.directRoutingButton.clicked.connect(lambda: self.set_connection_routing("direct"))
|
||||
self.ui.angledRoutingButton.clicked.connect(lambda: self.set_connection_routing("angled"))
|
||||
self.ui.splineRoutingButton.clicked.connect(lambda: self.set_connection_routing("spline"))
|
||||
self.ui.applyJsonButton.clicked.connect(self.apply_json)
|
||||
self.document_controller.activeGraphChanged.connect(self._active_graph_changed)
|
||||
|
||||
@@ -255,10 +245,6 @@ class MainWindow(QMainWindow):
|
||||
self.ui.lineToolButton,
|
||||
self.ui.textToolButton,
|
||||
self.ui.rotateToolButton,
|
||||
self.ui.routingLabel,
|
||||
self.ui.directRoutingButton,
|
||||
self.ui.angledRoutingButton,
|
||||
self.ui.splineRoutingButton,
|
||||
):
|
||||
widget.setVisible(visible)
|
||||
|
||||
@@ -272,15 +258,6 @@ class MainWindow(QMainWindow):
|
||||
"text": self.ui.textToolButton,
|
||||
}[mode].setChecked(True)
|
||||
|
||||
def set_connection_routing(self, routing: str) -> None:
|
||||
self.ui.graphView.set_connection_routing(routing)
|
||||
buttons = {
|
||||
"direct": self.ui.directRoutingButton,
|
||||
"angled": self.ui.angledRoutingButton,
|
||||
"spline": self.ui.splineRoutingButton,
|
||||
}
|
||||
buttons[routing].setChecked(True)
|
||||
|
||||
def _load_source_json(self) -> None:
|
||||
component = self.document_controller.active_component
|
||||
if component is None:
|
||||
|
||||
Reference in New Issue
Block a user