diff --git a/launcher/control.py b/launcher/control.py index e0def64..4788117 100644 --- a/launcher/control.py +++ b/launcher/control.py @@ -188,13 +188,18 @@ def push(self, index): name = model.data(index, "name") self.breadcrumbs.append(name) - level = len(self.breadcrumbs) - handler = { - 1: self.on_project_changed, - 2: self.on_silo_changed, - 3: self.on_asset_changed, - 4: self.on_task_changed - }[level] + frame = self.current_frame() + + # If nothing is set as current frame we are at selecting projects + handler = self.on_project_changed + if frame: + handler = { + "project": self.on_silo_changed, + "silo": self.on_asset_changed, + "asset": self.on_asset_changed + }[self.current_frame()["type"]] + if "tasks" in frame and name in frame["tasks"]: + handler = self.on_task_changed handler(index) @@ -218,9 +223,12 @@ def pop(self, index=None): steps = len(self.breadcrumbs) - index - 1 for i in range(steps): - self._frames.pop() - self._model.pop() - self._actions.pop() + try: + self._frames.pop() + self._model.pop() + self._actions.pop() + except IndexError: + pass if not self.breadcrumbs: self.popped.emit() @@ -249,9 +257,6 @@ def init(self): if project["data"].get("visible", True) # Discard hidden projects ]) - frame = {"environment": {}} - self._frames[:] = [frame] - # Discover all registered actions discovered_actions = api.discover(api.Action) self._registered_actions[:] = discovered_actions @@ -293,11 +298,12 @@ def on_project_changed(self, index): ]) frame["project"] = project["_id"] - frame["environment"]["project"] = name + frame["environment"] = {"project": name} frame["environment"].update({ "project_%s" % key: str(value) for key, value in project["data"].items() }) + frame["type"] = "project" self._frames.append(frame) self.pushed.emit(name) @@ -308,41 +314,50 @@ def on_silo_changed(self, index): frame = self.current_frame() - self._model.push([ - dict({ - "_id": doc["_id"], - "name": doc["name"], - "icon": DEFAULTS["icon"]["asset"], - }, **doc["data"]) - for doc in sorted( - io.find({ - "type": "asset", - "parent": frame["project"], - "silo": name - }), - - # Hard-sort by group - # TODO(marcus): Sorting should really happen in - # the model, via e.g. a Proxy. - key=lambda item: ( - # Sort by group - item["data"].get( - "group", - - # Put items without a - # group at the top - "0"), - - # Sort inner items by name - item["name"] - ) + self.docs = sorted( + io.find({ + "type": "asset", + "parent": frame["project"], + "silo": name + }), + # Hard-sort by group + # TODO(marcus): Sorting should really happen in + # the model, via e.g. a Proxy. + key=lambda item: ( + # Sort by group + item["data"].get( + "group", + + # Put items without a + # group at the top + "0"), + + # Sort inner items by name + item["name"] ) - + ) + valid_docs = [] + for doc in self.docs: # Discard hidden items - if doc["data"].get("visible", True) - ]) + if not doc["data"].get("visible", True): + continue + + # Only show assets without a visual parent. + if "visualParent" not in doc["data"]: + valid_docs.append( + dict( + { + "_id": doc["_id"], + "name": doc["name"], + "icon": DEFAULTS["icon"]["asset"] + }, + **doc["data"] + ) + ) + self._model.push(valid_docs) frame["environment"]["silo"] = name + frame["type"] = "silo" self._frames.append(frame) self.pushed.emit(name) @@ -363,6 +378,7 @@ def on_asset_changed(self, index): "asset_%s" % key: value for key, value in asset["data"].items() }) + frame["type"] = "asset" # Get tasks from the project's configuration project_tasks = [task for task in frame["config"].get("tasks", [])] @@ -385,7 +401,28 @@ def on_asset_changed(self, index): if "icon" not in task: task['icon'] = DEFAULTS['icon']['task'] - self._model.push(sorted(tasks, key=lambda t: t["name"])) + sorted_tasks = sorted(tasks, key=lambda t: t["name"]) + + frame["tasks"] = [task["name"] for task in sorted_tasks] + + valid_docs = [] + for doc in self.docs: + if "visualParent" not in doc["data"]: + continue + + if doc["data"]["visualParent"] == asset["_id"]: + valid_docs.append( + dict( + { + "_id": doc["_id"], + "name": doc["name"], + "icon": DEFAULTS["icon"]["asset"] + }, + **doc["data"] + ) + ) + + self._model.push(sorted_tasks + valid_docs) self._frames.append(frame) self.pushed.emit(name) @@ -398,6 +435,7 @@ def on_task_changed(self, index): self._model.push([]) frame["environment"]["task"] = name + frame["type"] = "task" self._frames.append(frame) self.pushed.emit(name)