Skip to content

Commit

Permalink
Merge pull request #376 from pypeclub/cleanup/PYPE-222_switch_asset_GUI
Browse files Browse the repository at this point in the history
Improve Asset Switcher GUI
  • Loading branch information
davidlatwe authored Jul 4, 2019
2 parents 0eec3db + 02deb7b commit 447abf1
Showing 1 changed file with 276 additions and 21 deletions.
297 changes: 276 additions & 21 deletions avalon/tools/cbsceneinventory/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,23 +481,44 @@ def __init__(self, parent=None, items=None):
self._representations_box = SearchComboBox(
placeholder="<representation>")

input_layout = QtWidgets.QHBoxLayout()
self._asset_label = QtWidgets.QLabel('')
self._subset_label = QtWidgets.QLabel('')
self._repre_label = QtWidgets.QLabel('')

main_layout = QtWidgets.QVBoxLayout()
context_layout = QtWidgets.QHBoxLayout()
asset_layout = QtWidgets.QVBoxLayout()
subset_layout = QtWidgets.QVBoxLayout()
repre_layout = QtWidgets.QVBoxLayout()

accept_icon = qta.icon("fa.check", color="white")
accept_btn = QtWidgets.QPushButton()
accept_btn.setIcon(accept_icon)
accept_btn.setFixedWidth(24)
accept_btn.setFixedHeight(24)

input_layout.addWidget(self._assets_box)
input_layout.addWidget(self._subsets_box)
input_layout.addWidget(self._representations_box)
input_layout.addWidget(accept_btn)
asset_layout.addWidget(self._assets_box)
asset_layout.addWidget(self._asset_label)
subset_layout.addWidget(self._subsets_box)
subset_layout.addWidget(self._subset_label)
repre_layout.addWidget(self._representations_box)
repre_layout.addWidget(self._repre_label)

context_layout.addLayout(asset_layout)
context_layout.addLayout(subset_layout)
context_layout.addLayout(repre_layout)
context_layout.addWidget(accept_btn)

self._input_layout = input_layout
self._accept_btn = accept_btn

self.setLayout(input_layout)
self._assets_box.currentIndexChanged.connect(self.on_assets_change)
self._subsets_box.currentIndexChanged.connect(self.on_subset_change)
self._representations_box.currentIndexChanged.connect(
self.on_repre_change
)

main_layout.addLayout(context_layout)
self.setLayout(main_layout)
self.setWindowTitle("Switch selected items ...")

self.connections()
Expand All @@ -513,32 +534,266 @@ def __init__(self, parent=None, items=None):
def connections(self):
self._accept_btn.clicked.connect(self._on_accept)

def refresh(self):
"""Build the need comboboxes with content"""
def on_assets_change(self):
self.refresh(1)

assets = sorted(self._get_assets())
self._assets_box.populate(assets)
def on_subset_change(self):
self.refresh(2)

subsets = sorted(self._get_subsets())
self._subsets_box.populate(subsets)
def on_repre_change(self):
self.refresh(3)

def refresh(self, refresh_type=0):
"""Build the need comboboxes with content"""
if refresh_type < 1:
assets = sorted(self._get_assets())
self._assets_box.populate(assets)

if refresh_type < 2:
last_subset = self._subsets_box.currentText()

subsets = sorted(self._get_subsets())
self._subsets_box.populate(subsets)

if (last_subset != "" and last_subset in list(subsets)):
index = None
for i in range(self._subsets_box.count()):
if last_subset == str(self._subsets_box.itemText(i)):
index = i
break
if index is not None:
self._subsets_box.setCurrentIndex(index)

if refresh_type < 3:
last_repre = self._representations_box.currentText()

representations = sorted(self._get_representations())
self._representations_box.populate(representations)

if (last_repre != "" and last_repre in list(representations)):
index = None
for i in range(self._representations_box.count()):
if last_repre == self._representations_box.itemText(i):
index = i
break
if index is not None:
self._representations_box.setCurrentIndex(index)

self.set_labels()
self.validate()

def set_labels(self):
default = "*No changes"
asset_label = default
subset_label = default
repre_label = default

if self._assets_box.currentText() != '':
asset_label = self._assets_box.currentText()
if self._subsets_box.currentText() != '':
subset_label = self._subsets_box.currentText()
if self._representations_box.currentText() != '':
repre_label = self._representations_box.currentText()

self._asset_label.setText(asset_label)
self._subset_label.setText(subset_label)
self._repre_label.setText(repre_label)

def validate(self):
asset_name = self._assets_box.get_valid_value() or None
subset_name = self._subsets_box.get_valid_value() or None
repre_name = self._representations_box.get_valid_value() or None

asset_ok = True
subset_ok = True
repre_ok = True
for item in self._items:
if any(not x for x in [asset_name, subset_name, repre_name]):
_id = io.ObjectId(item["representation"])
representation = io.find_one({
"type": "representation",
"_id": _id
})
version, subset, asset, project = io.parenthood(representation)

if asset_name is None:
asset_name = asset["name"]

if subset_name is None:
subset_name = subset["name"]

if repre_name is None:
repre_name = representation["name"]

asset = io.find_one({"name": asset_name, "type": "asset"})
if asset is None:
asset_ok = False
continue
subset = io.find_one({
"name": subset_name,
"type": "subset",
"parent": asset["_id"]
})
if subset is None:
subset_ok = False
continue
version = io.find_one(
{
"type": "version",
"parent": subset["_id"]
},
sort=[('name', -1)]
)
if version is None:
repre_ok = False
continue

representations = sorted(self._get_representations())
self._representations_box.populate(representations)
repre = io.find_one({
"name": repre_name,
"type": "representation",
"parent": version["_id"]
})
if repre is None:
repre_ok = False

asset_sheet = ''
subset_sheet = ''
repre_sheet = ''
accept_sheet = ''
error_msg = '*Please select'
if asset_ok is False:
asset_sheet = 'border: 1px solid red;'
self._asset_label.setText(error_msg)
if subset_ok is False:
subset_sheet = 'border: 1px solid red;'
self._subset_label.setText(error_msg)
if repre_ok is False:
repre_sheet = 'border: 1px solid red;'
self._repre_label.setText(error_msg)
if asset_ok and subset_ok and repre_ok:
accept_sheet = 'border: 1px solid green;'

self._assets_box.setStyleSheet(asset_sheet)
self._subsets_box.setStyleSheet(subset_sheet)
self._representations_box.setStyleSheet(repre_sheet)

self._accept_btn.setEnabled(asset_ok and subset_ok and repre_ok)
self._accept_btn.setStyleSheet(accept_sheet)

def _get_assets(self):
return self._get_document_names("asset")
filtered_assets = []
for asset in io.find({'type': 'asset'}):
subsets = io.find({
'type': 'subset',
'parent': asset['_id']
})
for subs in subsets:
filtered_assets.append(asset['name'])
break

return filtered_assets

def _get_subsets(self):
return self._get_document_names("subset")
# Filter subsets by asset in dropdown
if self._assets_box.currentText() != "":
parents = []
parents.append(io.find_one({
'type': 'asset',
'name': self._assets_box.currentText()
}))

return self._get_document_names("subset", parents)
# If any asset in dropdown is selected
# - filter subsets by selected assets in scene inventory
assets = []
for item in self._items:
_id = io.ObjectId(item["representation"])
representation = io.find_one(
{"type": "representation", "_id": _id}
)
version, subset, asset, project = io.parenthood(representation)
assets.append(asset)

possible_subsets = None
for asset in assets:
subsets = io.find({
'type': 'subset',
'parent': asset['_id']
})
asset_subsets = set()
for subset in subsets:
asset_subsets.add(subset['name'])

if possible_subsets is None:
possible_subsets = asset_subsets
else:
possible_subsets = (possible_subsets & asset_subsets)

return list(possible_subsets)

def _get_representations(self):
return self._get_document_names("representation")
if self._subsets_box.currentText() != "":
subsets = []
parents = []
subsets.append(self._subsets_box.currentText())

for subset in subsets:
entity = io.find_one({
'type': 'subset',
'name': subset
})

entity = io.find_one(
{
'type': 'version',
'parent': entity['_id']
},
sort=[('name', -1)]
)
if entity not in parents:
parents.append(entity)

return self._get_document_names("representation", parents)

versions = []
for item in self._items:
_id = io.ObjectId(item["representation"])
representation = io.find_one(
{"type": "representation", "_id": _id}
)
version, subset, asset, project = io.parenthood(representation)
versions.append(version)

possible_repres = None
for version in versions:
representations = io.find({
'type': 'representation',
'parent': version['_id']
})
repres = set()
for repre in representations:
repres.add(repre['name'])

if possible_repres is None:
possible_repres = repres
else:
possible_repres = (possible_repres & repres)

return list(possible_repres)

def _get_document_names(self, document_type, parent=None):
def _get_document_names(self, document_type, parents=[]):

query = {"type": document_type}
if parent:
query["parent"] = parent["_id"]

if len(parents) == 1:
query["parent"] = parents[0]["_id"]
elif len(parents) > 1:
or_exprs = []
for parent in parents:
expr = {"parent": parent["_id"]}
or_exprs.append(expr)

query["$or"] = or_exprs

return io.find(query).distinct("name")

Expand Down

0 comments on commit 447abf1

Please sign in to comment.