Exemple #1
0
    def __init__(self, parent, **kwargs):
        super(BrowserTab, self).__init__(parent)
        self._parent = parent
        self.loading = False
        self.title = False

        # Search query

        self.search_query = {
            "id_view": kwargs.get("id_view", min(config["views"])),
            "fulltext": kwargs.get("fulltext", ""),
            "order": kwargs.get("order", "ctime desc"),
            "conds": kwargs.get("conds", []),
        }

        # Layout

        self.search_box = SearchWidget(self)
        if self.search_query.get("fulltext"):
            self.search_box.setText(self.search_query["fulltext"])

        self.first_load = True
        self.view = FireflyBrowserView(self)
        self.view.horizontalHeader().sectionResized.connect(self.on_section_resize)
        self.view.horizontalHeader().sortIndicatorChanged.connect(
            self.on_section_resize
        )

        action_clear = QAction(QIcon(pixlib["cancel"]), "&Clear search query", parent)
        action_clear.triggered.connect(self.on_clear)

        self.action_search = QMenu("Views")
        self.action_search.setStyleSheet(app_skin)
        self.action_search.menuAction().setIcon(QIcon(pixlib["search"]))
        self.action_search.menuAction().triggered.connect(self.load)
        self.load_view_menu()

        action_copy = QAction("Copy result", self)
        action_copy.setShortcut("CTRL+SHIFT+C")
        action_copy.triggered.connect(self.on_copy_result)
        self.addAction(action_copy)

        toolbar = QToolBar(self)
        toolbar.addAction(action_clear)
        toolbar.addAction(self.action_search.menuAction())

        search_layout = QHBoxLayout()
        search_layout.setContentsMargins(0, 0, 0, 0)
        search_layout.addWidget(self.search_box)
        search_layout.addWidget(toolbar)

        self.pager = Pager(self)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(search_layout, 0)
        layout.addWidget(self.view, 1)
        layout.addWidget(self.pager, 0)
        self.setLayout(layout)
Exemple #2
0
 def key_menu(self, key, position):
     menu = QMenu()
     section = QAction("Search in...")
     section.setEnabled(False)
     menu.addAction(section)
     for id_view in sorted(config["views"].keys(),
                           key=lambda k: config["views"][k]["position"]):
         view = config["views"][id_view]
         if view.get("separator", False):
             menu.addSeparator()
         action = QAction(view["title"], self)
         action.triggered.connect(
             functools.partial(self._parent.search_by_key, key, id_view))
         menu.addAction(action)
     menu.exec_(self.labels[key].mapToGlobal(position))
    def contextMenuEvent(self, event):
        menu = QMenu(self.parent())
        menu.setStyleSheet(app_skin)

        action_open_rundown = QAction("Open rundown", self)
        action_open_rundown.triggered.connect(self.on_open_rundown)
        menu.addAction(action_open_rundown)

        action_import_template = QAction("Import template", self)
        action_import_template.triggered.connect(
            functools.partial(self.parent().parent().import_template,
                              self.dow))
        menu.addAction(action_import_template)

        menu.exec_(event.globalPos())
    def contextMenuEvent(self, event):
        if not self.cursor_event:
            return

        menu = QMenu(self.parent())
        menu.setStyleSheet(app_skin)

        self.calendar.selected_event = self.cursor_event

        action_open_rundown = QAction("Open rundown", self)
        action_open_rundown.triggered.connect(self.on_open_rundown)
        menu.addAction(action_open_rundown)

        action_edit_event = QAction("Event details", self)
        action_edit_event.triggered.connect(self.on_edit_event)
        menu.addAction(action_edit_event)

        if has_right("scheduler_edit", self.calendar.id_channel):
            menu.addSeparator()
            action_delete_event = QAction("Delete event", self)
            action_delete_event.triggered.connect(self.on_delete_event)
            menu.addAction(action_delete_event)

        menu.exec_(event.globalPos())
Exemple #5
0
    def contextMenuEvent(self, event):
        obj_set = list(set([itm.object_type for itm in self.selected_objects]))
        menu = QMenu(self)

        if len(obj_set) == 1:
            if len(self.selected_objects) == 1:
                if self.selected_objects[0]["item_role"] == "placeholder":
                    solvers = self.playout_config.get("solvers", [])
                    if solvers:
                        solver_menu = menu.addMenu("Solve using...")
                        for solver in solvers:
                            action_solve = QAction(solver.capitalize(), self)
                            action_solve.setStatusTip(
                                "Solve this placeholder using {}".format(
                                    solver))
                            action_solve.triggered.connect(
                                functools.partial(self.on_solve, solver))
                            solver_menu.addAction(action_solve)

                if obj_set[0] == "item" and self.selected_objects[0][
                        "id_asset"]:
                    action_trim = QAction("Trim", self)
                    action_trim.setStatusTip("Trim selected item")
                    action_trim.triggered.connect(self.on_trim)
                    menu.addAction(action_trim)

            if obj_set[0] == "item" and (
                    self.selected_objects[0]["id_asset"]
                    or self.selected_objects[0]["item_role"] == "live"):

                mode_menu = menu.addMenu("Run mode")

                action_mode_auto = QAction("&Auto", self)
                action_mode_auto.setStatusTip("Set run mode to auto")
                action_mode_auto.setCheckable(True)
                action_mode_auto.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_AUTO)
                action_mode_auto.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_AUTO))
                mode_menu.addAction(action_mode_auto)

                action_mode_manual = QAction("&Manual", self)
                action_mode_manual.setStatusTip("Set run mode to manual")
                action_mode_manual.setCheckable(True)
                action_mode_manual.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_MANUAL)
                action_mode_manual.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_MANUAL))
                mode_menu.addAction(action_mode_manual)

                action_mode_skip = QAction("&Skip", self)
                action_mode_skip.setStatusTip("Set run mode to skip")
                action_mode_skip.setCheckable(True)
                action_mode_skip.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_SKIP)
                action_mode_skip.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_SKIP))
                mode_menu.addAction(action_mode_skip)

                if self.selected_objects[0]["id_asset"]:
                    mode_menu.addSeparator()
                    action_mode_loop = QAction("&Loop", self)
                    action_mode_loop.setStatusTip("Loop item")
                    action_mode_loop.setCheckable(True)
                    action_mode_loop.setChecked(
                        bool(self.selected_objects[0]["loop"]))
                    action_mode_loop.triggered.connect(self.on_set_loop)
                    mode_menu.addAction(action_mode_loop)

            elif obj_set[0] == "event" and len(self.selected_objects) == 1:
                mode_menu = menu.addMenu("Run mode")

                action_mode_auto = QAction("&Auto", self)
                action_mode_auto.setStatusTip("Set run mode to auto")
                action_mode_auto.setCheckable(True)
                action_mode_auto.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_AUTO)
                action_mode_auto.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_AUTO))
                mode_menu.addAction(action_mode_auto)

                action_mode_manual = QAction("&Manual", self)
                action_mode_manual.setStatusTip("Set run mode to manual")
                action_mode_manual.setCheckable(True)
                action_mode_manual.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_MANUAL)
                action_mode_manual.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_MANUAL))
                mode_menu.addAction(action_mode_manual)

                action_mode_soft = QAction("&Soft", self)
                action_mode_soft.setStatusTip("Set run mode to soft")
                action_mode_soft.setCheckable(True)
                action_mode_soft.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_SOFT)
                action_mode_soft.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_SOFT))
                mode_menu.addAction(action_mode_soft)

                action_mode_hard = QAction("&Hard", self)
                action_mode_hard.setStatusTip("Set run mode to hard")
                action_mode_hard.setCheckable(True)
                action_mode_hard.setChecked(
                    self.selected_objects[0]["run_mode"] == RunMode.RUN_HARD)
                action_mode_hard.triggered.connect(
                    functools.partial(self.on_set_mode, RunMode.RUN_HARD))
                mode_menu.addAction(action_mode_hard)

        if "item" in obj_set:
            if len(self.selected_objects
                   ) == 1 and self.selected_objects[0]["item_role"] in [
                       "placeholder", "lead_in", "lead_out", "live"
                   ]:
                pass
            else:
                action_send_to = QAction("&Send to...", self)
                action_send_to.setStatusTip(
                    "Create action for selected asset(s)")
                action_send_to.triggered.connect(self.on_send_to)
                menu.addAction(action_send_to)

        if "event" in obj_set:
            pass

        if len(obj_set) > 0:
            menu.addSeparator()

            action_delete = QAction("&Delete", self)
            action_delete.setStatusTip("Delete selected object")
            action_delete.triggered.connect(self.on_delete)
            menu.addAction(action_delete)

            if len(self.selected_objects) == 1:
                if "event" in obj_set:
                    action_edit = QAction("Edit", self)
                    action_edit.triggered.connect(self.on_edit_event)
                    menu.addAction(action_edit)
                elif self.selected_objects[0]["item_role"] in [
                        "placeholder", "live"
                ]:
                    action_edit = QAction("Edit", self)
                    action_edit.triggered.connect(self.on_edit_item)
                    menu.addAction(action_edit)

        menu.exec_(event.globalPos())
def preview_toolbar(wnd):
    toolbar = QToolBar(wnd)

    action_poster = QMenu("Set poster", wnd)
    action_poster.menuAction().setIcon(QIcon(pixlib["set-poster"]))
    action_poster.menuAction().triggered.connect(wnd.set_poster)
    action_poster.menuAction().setStatusTip("Set poster frame")

    action_poster_set = QAction("Set poster", wnd)
    action_poster_set.triggered.connect(wnd.set_poster)
    action_poster.addAction(action_poster_set)

    action_poster_goto = QAction("Go to poster", wnd)
    action_poster_goto.triggered.connect(wnd.go_to_poster)
    action_poster.addAction(action_poster_goto)

    toolbar.addAction(action_poster.menuAction())

    action_save_marks = QAction(QIcon(pixlib["save-marks"]), "Save marks", wnd)
    action_save_marks.setStatusTip("Save marks")
    action_save_marks.triggered.connect(wnd.save_marks)
    toolbar.addAction(action_save_marks)

    # TODO
    # action_restore_marks = QAction(QIcon(pix_lib["restore-marks"]), 'Restore', wnd)
    # action_restore_marks.setStatusTip('Restore marks')
    # action_restore_marks.triggered.connect(wnd.restore_marks)
    # toolbar.addAction(action_restore_marks)

    action_create_subclip = QAction(
        QIcon(pixlib["create-subclip"]), "Create subclip", wnd
    )
    action_create_subclip.setStatusTip("Create subclip")
    action_create_subclip.triggered.connect(wnd.create_subclip)
    toolbar.addAction(action_create_subclip)

    action_manage_subclips = QAction(
        QIcon(pixlib["manage-subclips"]), "Manage subclips", wnd
    )
    action_manage_subclips.setStatusTip("Manage subclips")
    action_manage_subclips.triggered.connect(wnd.manage_subclips)
    toolbar.addAction(action_manage_subclips)

    return toolbar
Exemple #7
0
    def contextMenuEvent(self, event):
        if not self.view.selected_objects:
            return
        menu = QMenu(self)
        objs = self.view.selected_objects

        states = set([obj["status"] for obj in objs])

        if states == set([ObjectStatus.TRASHED]):
            action_untrash = QAction("Untrash", self)
            action_untrash.setStatusTip("Take selected asset(s) from trash")
            action_untrash.triggered.connect(self.on_untrash)
            menu.addAction(action_untrash)

        if states == set([ObjectStatus.ARCHIVED]):
            action_unarchive = QAction("Unarchive", self)
            action_unarchive.setStatusTip("Take selected asset(s) from archive")
            action_unarchive.triggered.connect(self.on_unarchive)
            menu.addAction(action_unarchive)

        elif states.issubset(
            [ObjectStatus.ONLINE, ObjectStatus.CREATING, ObjectStatus.OFFLINE]
        ):
            action_move_to_trash = QAction("Move to trash", self)
            action_move_to_trash.setStatusTip("Move selected asset(s) to trash")
            action_move_to_trash.triggered.connect(self.on_trash)
            menu.addAction(action_move_to_trash)

            action_move_to_archive = QAction("Move to archive", self)
            action_move_to_archive.setStatusTip("Move selected asset(s) to archive")
            action_move_to_archive.triggered.connect(self.on_archive)
            menu.addAction(action_move_to_archive)

        action_reset = QAction("Reset", self)
        action_reset.setStatusTip("Reload asset metadata")
        action_reset.triggered.connect(self.on_reset)
        menu.addAction(action_reset)

        action_batch_ops = QAction("&Batch ops...", self)
        action_batch_ops.setStatusTip("Batch operations")
        action_batch_ops.triggered.connect(self.on_batch_ops)
        menu.addAction(action_batch_ops)

        if len(objs) == 1:
            menu.addSeparator()
            for link in config["folders"][objs[0]["id_folder"]].get("links", []):
                action_link = QAction(link["title"])
                action_link.triggered.connect(
                    functools.partial(self.link_exec, objs[0], **link)
                )
                menu.addAction(action_link)

        menu.addSeparator()

        action_send_to = QAction("&Send to...", self)
        action_send_to.setStatusTip("Create action for selected asset(s)")
        action_send_to.triggered.connect(self.on_send_to)
        menu.addAction(action_send_to)

        menu.exec_(event.globalPos())
Exemple #8
0
class BrowserTab(QWidget):
    def __init__(self, parent, **kwargs):
        super(BrowserTab, self).__init__(parent)
        self._parent = parent
        self.loading = False
        self.title = False

        # Search query

        self.search_query = {
            "id_view": kwargs.get("id_view", min(config["views"])),
            "fulltext": kwargs.get("fulltext", ""),
            "order": kwargs.get("order", "ctime desc"),
            "conds": kwargs.get("conds", []),
        }

        # Layout

        self.search_box = SearchWidget(self)
        if self.search_query.get("fulltext"):
            self.search_box.setText(self.search_query["fulltext"])

        self.first_load = True
        self.view = FireflyBrowserView(self)
        self.view.horizontalHeader().sectionResized.connect(self.on_section_resize)
        self.view.horizontalHeader().sortIndicatorChanged.connect(
            self.on_section_resize
        )

        action_clear = QAction(QIcon(pixlib["cancel"]), "&Clear search query", parent)
        action_clear.triggered.connect(self.on_clear)

        self.action_search = QMenu("Views")
        self.action_search.setStyleSheet(app_skin)
        self.action_search.menuAction().setIcon(QIcon(pixlib["search"]))
        self.action_search.menuAction().triggered.connect(self.load)
        self.load_view_menu()

        action_copy = QAction("Copy result", self)
        action_copy.setShortcut("CTRL+SHIFT+C")
        action_copy.triggered.connect(self.on_copy_result)
        self.addAction(action_copy)

        toolbar = QToolBar(self)
        toolbar.addAction(action_clear)
        toolbar.addAction(self.action_search.menuAction())

        search_layout = QHBoxLayout()
        search_layout.setContentsMargins(0, 0, 0, 0)
        search_layout.addWidget(self.search_box)
        search_layout.addWidget(toolbar)

        self.pager = Pager(self)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(search_layout, 0)
        layout.addWidget(self.view, 1)
        layout.addWidget(self.pager, 0)
        self.setLayout(layout)

    def model(self):
        return self.view.model()

    @property
    def id_view(self):
        return self.search_query["id_view"]

    @property
    def main_window(self):
        return self._parent.main_window

    @property
    def app_state(self):
        return self._parent.app_state

    def load_view_menu(self):
        i = 1
        for id_view in sorted(
            config["views"].keys(), key=lambda k: config["views"][k]["position"]
        ):
            view = config["views"][id_view]
            if view.get("separator", False):
                self.action_search.addSeparator()
            action = QAction(view["title"], self)
            action.setCheckable(True)
            if i < 10:
                action.setShortcut(f"ALT+{i}")
            action.id_view = id_view
            action.triggered.connect(functools.partial(self.set_view, id_view))
            self.action_search.addAction(action)
            i += 1

    def on_section_resize(self, *args, **kwargs):
        if self.loading:
            return
        if "browser_view_sizes" not in self.app_state:
            self.app_state["browser_view_sizes"] = {}
        if "browser_default_sizes" not in self.app_state:
            self.app_state["browser_default_sizes"] = {}

        data = {}
        for i, h in enumerate(self.model().header_data):
            w = self.view.horizontalHeader().sectionSize(i)
            self.app_state["browser_default_sizes"][h] = w
            data[h] = w
        self.app_state["browser_view_sizes"][self.id_view] = data

    #
    # Do browse
    #

    def load(self, **kwargs):
        self.loading = True
        self.old_view = self.search_query.get("id_view", -1)
        search_string = self.search_box.text()
        self.search_query["fulltext"] = search_string
        self.search_query.update(kwargs)
        if self.search_query.get("id_view") != self.old_view:
            self.view.current_page = 1
        self.model().load(self.load_callback, **self.search_query)

    def load_callback(self):
        if self.first_load or self.id_view != self.old_view:
            view_state = self.app_state.get("browser_view_sizes", {}).get(
                self.id_view, {}
            )
            default_sizes = self.app_state.get("browser_defaut_sizes", {})
            for i, h in enumerate(self.model().header_data):
                if h in view_state:
                    w = view_state[h]
                elif h in default_sizes:
                    w = default_sizes[h]
                elif h in ["title", "subtitle"]:
                    w = 300
                elif h in ["qc/state"]:
                    w = 20
                else:
                    w = 120
                self.view.horizontalHeader().resizeSection(i, w)
            for action in self.action_search.actions():
                if not hasattr(action, "id_view"):
                    continue
                if action.id_view == self.id_view:
                    action.setChecked(True)
                else:
                    action.setChecked(False)
            self.first_load = False

        self.loading = False
        self._parent.redraw_tabs()

    def on_clear(self):
        self.search_box.setText("")
        self.load(fulltext="")

    def set_view(self, id_view):
        self.search_query["conds"] = []
        self.title = False
        self.load(id_view=id_view)

    def contextMenuEvent(self, event):
        if not self.view.selected_objects:
            return
        menu = QMenu(self)
        objs = self.view.selected_objects

        states = set([obj["status"] for obj in objs])

        if states == set([ObjectStatus.TRASHED]):
            action_untrash = QAction("Untrash", self)
            action_untrash.setStatusTip("Take selected asset(s) from trash")
            action_untrash.triggered.connect(self.on_untrash)
            menu.addAction(action_untrash)

        if states == set([ObjectStatus.ARCHIVED]):
            action_unarchive = QAction("Unarchive", self)
            action_unarchive.setStatusTip("Take selected asset(s) from archive")
            action_unarchive.triggered.connect(self.on_unarchive)
            menu.addAction(action_unarchive)

        elif states.issubset(
            [ObjectStatus.ONLINE, ObjectStatus.CREATING, ObjectStatus.OFFLINE]
        ):
            action_move_to_trash = QAction("Move to trash", self)
            action_move_to_trash.setStatusTip("Move selected asset(s) to trash")
            action_move_to_trash.triggered.connect(self.on_trash)
            menu.addAction(action_move_to_trash)

            action_move_to_archive = QAction("Move to archive", self)
            action_move_to_archive.setStatusTip("Move selected asset(s) to archive")
            action_move_to_archive.triggered.connect(self.on_archive)
            menu.addAction(action_move_to_archive)

        action_reset = QAction("Reset", self)
        action_reset.setStatusTip("Reload asset metadata")
        action_reset.triggered.connect(self.on_reset)
        menu.addAction(action_reset)

        action_batch_ops = QAction("&Batch ops...", self)
        action_batch_ops.setStatusTip("Batch operations")
        action_batch_ops.triggered.connect(self.on_batch_ops)
        menu.addAction(action_batch_ops)

        if len(objs) == 1:
            menu.addSeparator()
            for link in config["folders"][objs[0]["id_folder"]].get("links", []):
                action_link = QAction(link["title"])
                action_link.triggered.connect(
                    functools.partial(self.link_exec, objs[0], **link)
                )
                menu.addAction(action_link)

        menu.addSeparator()

        action_send_to = QAction("&Send to...", self)
        action_send_to.setStatusTip("Create action for selected asset(s)")
        action_send_to.triggered.connect(self.on_send_to)
        menu.addAction(action_send_to)

        menu.exec_(event.globalPos())

    def link_exec(self, obj, **kwargs):
        param = kwargs["target_key"]
        value = obj[kwargs["source_key"]]
        self._parent.new_tab(
            obj["title"], id_view=kwargs["id_view"], conds=[f"'{param}' = '{value}'"]
        )
        self._parent.redraw_tabs()

    def on_send_to(self):
        objs = self.view.selected_objects
        if objs:
            show_send_to_dialog(objs)

    def on_batch_ops(self):
        objs = self.view.selected_objects
        if objs:
            if show_batch_ops_dialog(objs):
                self.load()

    def on_reset(self):
        objects = [
            obj.id
            for obj in self.view.selected_objects
            if obj["status"]
            not in [ObjectStatus.ARCHIVED, ObjectStatus.TRASHED, ObjectStatus.RESET]
        ]
        if not objects:
            return
        response = api.set(objects=objects, data={"status": ObjectStatus.RESET})
        if not response:
            return
        self.refresh_assets(*objects, request_data=True)

    def on_trash(self):
        objects = [
            obj.id
            for obj in self.view.selected_objects
            if obj["status"] not in [ObjectStatus.ARCHIVED, ObjectStatus.TRASHED]
        ]
        if not objects:
            return
        ret = QMessageBox.question(
            self,
            "Trash",
            f"Do you really want to trash {len(objects)} selected asset(s)?",
            QMessageBox.Yes | QMessageBox.No,
        )
        if ret == QMessageBox.Yes:
            response = api.set(objects=objects, data={"status": ObjectStatus.TRASHED})
        else:
            return
        if not response:
            logging.error("Unable to trash:\n\n" + response.message)
            return
        self.refresh_assets(*objects, request_data=True)

    def on_untrash(self):
        objects = [
            obj.id
            for obj in self.view.selected_objects
            if obj["status"] in [ObjectStatus.TRASHED]
        ]
        if not objects:
            return
        response = api.set(objects=objects, data={"status": ObjectStatus.CREATING})
        if not response:
            logging.error("Unable to untrash:\n\n" + response.message)
            return
        self.refresh_assets(*objects, request_data=True)

    def on_archive(self):
        objects = [
            obj.id
            for obj in self.view.selected_objects
            if obj["status"] not in [ObjectStatus.ARCHIVED, ObjectStatus.TRASHED]
        ]
        if not objects:
            return
        ret = QMessageBox.question(
            self,
            "Archive",
            f"Do you really want to move {len(objects)} selected asset(s) to archive?",
            QMessageBox.Yes | QMessageBox.No,
        )
        if ret == QMessageBox.Yes:
            response = api.set(objects=objects, data={"status": ObjectStatus.ARCHIVED})
        else:
            return
        if not response:
            logging.error("Unable to archive:\n\n" + response.message)
            return
        self.refresh_assets(*objects, request_data=True)

    def on_unarchive(self):
        objects = [
            obj.id
            for obj in self.view.selected_objects
            if obj["status"] in [ObjectStatus.ARCHIVED]
        ]
        if not objects:
            return
        response = api.set(objects=objects, data={"status": ObjectStatus.RETRIEVING})
        if not response:
            logging.error("Unable to unarchive:\n\n" + response.message)
            return
        self.refresh_assets(*objects, request_data=True)

    def on_choose_columns(self):
        # TODO
        logging.error("Not implemented")

    def on_copy_result(self):
        result = ""
        for obj in self.view.selected_objects:
            result += "{}\n".format(
                "\t".join(
                    [obj.format_display(key) or "" for key in self.model().header_data]
                )
            )
        clipboard = QApplication.clipboard()
        clipboard.setText(result)

    def refresh_assets(self, *objects, request_data=False):
        if request_data:
            asset_cache.request([[aid, 0] for aid in objects])
        for row, obj in enumerate(self.model().object_data):
            if obj.id in objects:
                self.model().object_data[row] = asset_cache[obj.id]
                self.model().dataChanged.emit(
                    self.model().index(row, 0),
                    self.model().index(row, len(self.model().header_data) - 1),
                )

    def seismic_handler(self, message):
        pass  # No seismic message needed - refresh_assets method does the job