| 3063 | } |
| 3064 | } |
| 3065 | void reshade::runtime::draw_gui_log() |
| 3066 | { |
| 3067 | std::error_code ec; |
| 3068 | std::filesystem::path log_path = global_config().path(); |
| 3069 | log_path.replace_extension(L".log"); |
| 3070 | |
| 3071 | const bool filter_changed = imgui::search_input_box(_log_filter, sizeof(_log_filter), -(ImGui::GetFrameHeight() + 8.0f * ImGui::GetFontSize() + 2 * _imgui_context->Style.ItemSpacing.x)); |
| 3072 | |
| 3073 | ImGui::SameLine(); |
| 3074 | |
| 3075 | if (ImGui::Button(ICON_FK_FOLDER, ImVec2(ImGui::GetFrameHeight(), 0.0f))) |
| 3076 | utils::open_explorer(log_path); |
| 3077 | ImGui::SetItemTooltip(_("Open folder in explorer")); |
| 3078 | |
| 3079 | ImGui::SameLine(); |
| 3080 | |
| 3081 | if (ImGui::Button(_("Clear Log"), ImVec2(8.0f * ImGui::GetFontSize(), 0.0f))) |
| 3082 | // Close and open the stream again, which will clear the file too |
| 3083 | log::open_log_file(log_path, ec); |
| 3084 | |
| 3085 | ImGui::Spacing(); |
| 3086 | |
| 3087 | const uintmax_t file_size = std::filesystem::file_size(log_path, ec); |
| 3088 | // Defer log reloading during user interface interactions to avoid interfering with tab switching |
| 3089 | if (filter_changed || (_last_log_size != file_size && !ImGui::IsAnyItemActive() && !ImGui::IsAnyItemFocused() && !_log_editor.has_selection())) |
| 3090 | { |
| 3091 | _log_editor.set_readonly(true); |
| 3092 | |
| 3093 | if (FILE *const file = _wfsopen(log_path.c_str(), L"r", SH_DENYNO)) |
| 3094 | { |
| 3095 | if (filter_changed || file_size <= _last_log_size) |
| 3096 | _log_editor.clear_text(); |
| 3097 | else |
| 3098 | fseek(file, static_cast<long>(_last_log_size), SEEK_SET); |
| 3099 | |
| 3100 | char line_data[2048]; |
| 3101 | while (fgets(line_data, sizeof(line_data), file)) |
| 3102 | { |
| 3103 | const std::string_view line(line_data); |
| 3104 | if (string_contains(line, _log_filter)) |
| 3105 | { |
| 3106 | if (line.back() != '\n') |
| 3107 | continue; |
| 3108 | |
| 3109 | const imgui::code_editor::text_pos line_pos_beg = _log_editor.get_text_end(); |
| 3110 | _log_editor.append_text(line); |
| 3111 | const imgui::code_editor::text_pos line_pos_end = _log_editor.get_text_end(); |
| 3112 | |
| 3113 | imgui::code_editor::color col = imgui::code_editor::color_default; |
| 3114 | /**/ if (line.find("ERROR |") != std::string_view::npos) |
| 3115 | col = imgui::code_editor::color_error_marker; |
| 3116 | else if (line.find("WARN |") != std::string_view::npos) |
| 3117 | col = imgui::code_editor::color_warning_marker; |
| 3118 | else if (line.find("DEBUG |") != std::string_view::npos) |
| 3119 | col = imgui::code_editor::color_comment; |
| 3120 | else if (line.find("error") != std::string_view::npos) |
| 3121 | col = imgui::code_editor::color_error_marker; |
| 3122 | else if (line.find("warning") != std::string_view::npos) |
nothing calls this directly
no test coverage detected