Repository: godotengine/godot
File: editor/inspector/editor_inspector.cpp (C++)

Code before:
			continue;
		}
		if (!current_category.ends_with(info.name)) {
			continue;
		}

		r_properties.push_back(prop_info.name);
	}
}

void EditorInspectorCategory::_handle_menu_option(int p_option) {
	switch (p_option) {
		case MENU_COPY_VALUE: {
			const Object *object = EditorInterface::get_singleton()->get_inspector()->get_edited_object();
			String category_name = info.name;
			if (!EditorNode::get_editor_data().is_type_recognized(info.name) && ResourceLoader::exists(info.hint_string, "Script")) {
				Ref<Script> scr = ResourceLoader::load(info.hint_string, "Script");
				if (scr.is_valid()) {
					category_name = scr->get_doc_class_name();
				}
			}
			Dictionary clipboard;
			LocalVector<String> properties;
			_collect_properties(object, properties);

			clipboard["path"] = category_name;
			for (const String &property_name : properties) {
				clipboard[property_name] = object->get(property_name);
			}
			InspectorDock::get_inspector_singleton()->set_property_clipboard(clipboard);
		} break;

		case MENU_PASTE_VALUE: {
			Object *object = EditorInterface::get_singleton()->get_inspector()->get_edited_object();
			const Dictionary clipboard = InspectorDock::get_inspector_singleton()->get_property_clipboard();
			const String path = clipboard["path"];
			String category_name = info.name;
			if (!EditorNode::get_editor_data().is_type_recognized(info.name) && ResourceLoader::exists(info.hint_string, "Script")) {
				Ref<Script> scr = ResourceLoader::load(info.hint_string, "Script");
				if (scr.is_valid()) {
					category_name = scr->get_doc_class_name();
				}
			}

			if (path != category_name) {
				break;
			}

			EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();

			if (const MultiNodeEdit *multi_node_edit = cast_to<MultiNodeEdit>(object)) {

Review comment (suggestion):
`path` is a valid property name and may cause a conflict. Use some special identifier, like `@path`.

Code after:
				ofs += hs + icon_size;
				w -= hs + icon_size;
			}

			if (is_layout_rtl()) {
				ofs = get_size().width - ofs - w;
			}

			// Use TextLine so we have access to accurate font metrics. This way,
			// we can ensure the line is vertically centered regardless of the font used
			// or its size.
			Ref<TextLine> tl;
			tl.instantiate();
			tl->add_string(label, font, font_size);
			tl->set_width(w);
			tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
			float text_pos_y = (get_size().height - tl->get_size().height) / 2 + v_margin_offset;
			Point2 text_pos = Point2(ofs, text_pos_y).round();
			tl->draw(get_canvas_item(), text_pos, theme_cache.font_color);
		} break;
	}
}

void EditorInspectorCategory::_accessibility_action_menu(const Variant &p_data) {
	_popup_context_menu(get_screen_position());
}

Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) const {
	// If it's not a doc tooltip, fallback to the default one.
	if (doc_class_name.is_empty()) {
		return nullptr;
	}

	return EditorHelpBitTooltip::make_tooltip(const_cast<EditorInspectorCategory *>(this), p_text);
}

void EditorInspectorCategory::set_as_favorite() {
	is_favorite = true;
	_update_icon();
}

void EditorInspectorCategory::set_property_info(const PropertyInfo &p_info) {
	info = p_info;

	Ref<Script> scr = _get_category_script(info);
	if (scr.is_valid()) {
		StringName script_name = EditorNode::get_editor_data().script_class_get_name(scr->get_path());
		if (script_name != StringName()) {
			label = script_name;
		}
	}