def apply_changes(self):
        """Treat data and, if valid, perform changes."""
        current_packs = set(
            get_formatted_local_node_packs(APP_REFS.source_path)
            + get_formatted_installed_node_packs(APP_REFS.source_path)
        )

        final_selection = {item[1].node_pack for item in self.node_pack_widget_list}

        if current_packs == final_selection:

            create_and_show_dialog(
                (
                    "There is no change to apply, the node packs selected"
                    " already correspond to the current node pack selection."
                ),
                level_name='info',
            )

            return

        ### check existence of orphaned nodes

        existing_node_pack_names = {
            node.id: node.data["script_id"][0]
            for node in APP_REFS.gm.nodes
            if "script_id" in node.data
        }

        final_node_pack_names = {
            pack.name if isinstance(pack, Path) else pack for pack in final_selection
        }

        orphaned_nodes = {
            node_id: node_pack_name
            for node_id, node_pack_name in existing_node_pack_names.items()
            if node_pack_name not in final_node_pack_names
        }

        if orphaned_nodes:

            orphan_node_ids = tuple(orphaned_nodes)

            create_and_show_dialog(
                "Can't proceed with operation, because there are nodes"
                " in the node layout still using some of the packs to be"
                f" removed: the nodes of ids {orphan_node_ids}"
            )

            return

        ### separate node packs

        local_node_packs = [
            str(node_pack)
            for node_pack in final_selection
            if isinstance(node_pack, Path)
        ]

        installed_node_packs = [
            node_pack for node_pack in final_selection if isinstance(node_pack, str)
        ]

        ### try loading node packs

        try:
            load_scripts(local_node_packs, installed_node_packs)

        except Exception as err:

            ## report problem to user
            show_dialog_from_key("error_while_loading_node_packs_dialog")

            ## also log it

            msg = "Unexpected error(s) while trying to load node packs from form"

            logger.exception(msg)

            USER_LOGGER.error(f"{msg}\n\n{err}")

            return

        ###
        APP_REFS.data["node_packs"] = local_node_packs
        APP_REFS.data["installed_node_packs"] = installed_node_packs

        ###

        APP_REFS.data["node_packs"] = local_node_packs = [
            str(node_pack)
            for node_pack in final_selection
            if isinstance(node_pack, Path)
        ]

        APP_REFS.data["installed_node_packs"] = installed_node_packs = [
            node_pack for node_pack in final_selection if isinstance(node_pack, str)
        ]

        ### rebuild canvas popup menu
        APP_REFS.wm.create_canvas_popup_menu()

        ###
        indicate_unsaved()

        ###
        set_status_message("Changed selected node pack(s)")

        ### trigger exiting the form by setting special
        ### flag to False
        self.running = False
Treat data and, if valid, perform changes.
nodezator/editing/nodepacksforms/selection.py