2023-01-23 08:44:16 +00:00
|
|
|
#include <imgui.h>
|
|
|
|
#include <ctime>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2023-01-29 10:08:27 +00:00
|
|
|
#include "../misc.h"
|
2023-01-23 08:44:16 +00:00
|
|
|
#include "../logcat_entry.h"
|
2023-02-02 12:50:28 +00:00
|
|
|
#include "../logcat_thread.h"
|
2023-01-23 08:44:16 +00:00
|
|
|
#include "main.h"
|
|
|
|
|
2023-02-11 02:28:10 +00:00
|
|
|
static inline void render_table_item_context_menu(const LogcatEntry& logcat_entry) {
|
|
|
|
std::string text = to_string(logcat_entry);
|
|
|
|
ImGui::TextDisabled("%s", text.c_str());
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::PushFont(nullptr);
|
|
|
|
|
|
|
|
if (ImGui::Selectable("Copy")) ImGui::SetClipboardText(text.c_str());
|
|
|
|
if (ImGui::Selectable("Copy Time")) {
|
|
|
|
struct tm tm;
|
|
|
|
char time_as_str[128] = {0};
|
|
|
|
strftime(time_as_str, 127 * sizeof(char), "%c", localtime_r(&logcat_entry.time, &tm));
|
|
|
|
ImGui::SetClipboardText(time_as_str);
|
|
|
|
}
|
|
|
|
if (ImGui::Selectable("Copy User", false, logcat_entry.user ? 0 : ImGuiSelectableFlags_Disabled)) {
|
|
|
|
ImGui::SetClipboardText(logcat_entry.user->c_str());
|
|
|
|
}
|
|
|
|
if (ImGui::Selectable("Copy PID")) ImGui::SetClipboardText(std::to_string(logcat_entry.pid).c_str());
|
|
|
|
if (ImGui::Selectable("Copy TID")) ImGui::SetClipboardText(std::to_string(logcat_entry.tid).c_str());
|
|
|
|
if (ImGui::Selectable("Copy Buffer")) ImGui::SetClipboardText(to_string(logcat_entry.buffer));
|
|
|
|
if (ImGui::Selectable("Copy Priority")) ImGui::SetClipboardText(to_string(logcat_entry.priority));
|
|
|
|
if (ImGui::Selectable("Copy Tag")) ImGui::SetClipboardText(logcat_entry.tag.c_str());
|
|
|
|
if (ImGui::Selectable("Copy Message")) ImGui::SetClipboardText(logcat_entry.message.c_str());
|
|
|
|
|
|
|
|
ImGui::PopFont();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void render_table_item(const LogcatEntry& logcat_entry, size_t logcat_entry_index, size_t* copying_entry_index) {
|
|
|
|
auto table_item_popup = [&]() {
|
|
|
|
bool popup_was_open = ImGui::IsPopupOpen("copy_popup");
|
|
|
|
ImGui::OpenPopupOnItemClick("copy_popup");
|
|
|
|
if (!popup_was_open) {
|
|
|
|
*copying_entry_index = logcat_entry_index;
|
2023-02-09 08:27:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
ImGui::TableNextRow();
|
2023-02-11 02:28:10 +00:00
|
|
|
if (ImGui::TableSetColumnIndex(0)) {
|
|
|
|
struct tm tm;
|
|
|
|
char time_as_str[128] = {0};
|
|
|
|
strftime(time_as_str, 127 * sizeof(char), "%c", localtime_r(&logcat_entry.time, &tm));
|
|
|
|
|
|
|
|
ImGui::TextUnformatted(time_as_str);
|
|
|
|
table_item_popup();
|
|
|
|
}
|
2023-02-09 08:27:39 +00:00
|
|
|
if (logcat_entry.user && ImGui::TableSetColumnIndex(1)) {
|
|
|
|
ImGui::TextUnformatted(*logcat_entry.user);
|
2023-02-11 02:28:10 +00:00
|
|
|
table_item_popup();
|
2023-02-09 08:27:39 +00:00
|
|
|
}
|
2023-02-11 02:28:10 +00:00
|
|
|
if (ImGui::TableSetColumnIndex(2)) { ImGui::Text("%zu", logcat_entry.pid); table_item_popup(); }
|
|
|
|
if (ImGui::TableSetColumnIndex(3)) { ImGui::Text("%zu", logcat_entry.tid); table_item_popup(); }
|
|
|
|
if (ImGui::TableSetColumnIndex(4)) { ImGui::TextUnformatted(to_string(logcat_entry.buffer)); table_item_popup(); }
|
|
|
|
if (ImGui::TableSetColumnIndex(5)) { ImGui::TextUnformatted(to_string(logcat_entry.priority)); table_item_popup(); }
|
|
|
|
if (ImGui::TableSetColumnIndex(6)) { ImGui::TextUnformatted(logcat_entry.tag); table_item_popup(); }
|
|
|
|
if (ImGui::TableSetColumnIndex(7)) { ImGui::TextUnformatted(logcat_entry.message); table_item_popup(); }
|
2023-02-09 08:27:39 +00:00
|
|
|
}
|
|
|
|
|
2023-01-29 07:56:05 +00:00
|
|
|
static inline void render_table(ImFont* monospace_font, std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets) {
|
2023-02-11 02:28:10 +00:00
|
|
|
static size_t copying_entry_index;
|
|
|
|
|
2023-01-29 07:56:05 +00:00
|
|
|
ImGui::TableSetupScrollFreeze(0, 1);
|
|
|
|
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("User", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("PID", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("TID", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("Buffer", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("Priority", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("Tag", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableSetupColumn("Message", ImGuiTableColumnFlags_None);
|
|
|
|
ImGui::TableHeadersRow();
|
2023-01-23 08:44:16 +00:00
|
|
|
|
|
|
|
ImGui::PushFont(monospace_font);
|
|
|
|
|
|
|
|
ImGuiListClipper clipper;
|
2023-01-28 14:11:46 +00:00
|
|
|
clipper.Begin(static_cast<int>(filtered_logcat_entry_offsets.size()));
|
2023-01-23 08:44:16 +00:00
|
|
|
while (clipper.Step()) {
|
2023-02-09 08:27:39 +00:00
|
|
|
for (int i_u = clipper.DisplayStart; i_u < clipper.DisplayEnd; i_u++) {
|
|
|
|
assert(i_u >= 0);
|
|
|
|
size_t i = static_cast<size_t>(i_u);
|
|
|
|
|
|
|
|
size_t logcat_entry_index = filtered_logcat_entry_offsets[i];
|
2023-02-11 02:28:10 +00:00
|
|
|
render_table_item(logcat_entries[logcat_entry_index], logcat_entry_index, ©ing_entry_index);
|
2023-01-23 08:44:16 +00:00
|
|
|
}
|
|
|
|
}
|
2023-02-05 14:02:36 +00:00
|
|
|
clipper.End();
|
2023-01-23 08:44:16 +00:00
|
|
|
|
2023-02-11 02:28:10 +00:00
|
|
|
if (ImGui::BeginPopup("copy_popup")) {
|
|
|
|
render_table_item_context_menu(logcat_entries[copying_entry_index]);
|
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
|
|
|
|
2023-01-23 08:44:16 +00:00
|
|
|
ImGui::PopFont();
|
|
|
|
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
|
|
|
|
ImGui::SetScrollHereY(1.0f);
|
|
|
|
}
|
2023-01-29 07:56:05 +00:00
|
|
|
|
|
|
|
ImGui::EndTable();
|
2023-01-23 08:44:16 +00:00
|
|
|
}
|
|
|
|
|
2023-02-02 12:50:28 +00:00
|
|
|
void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThread& logcat_thread,
|
2023-01-28 14:11:46 +00:00
|
|
|
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets,
|
2023-02-05 15:57:46 +00:00
|
|
|
const Config& __restrict active_config, Config& __restrict inactive_config,
|
|
|
|
bool* __restrict show_settings_window, bool* __restrict show_filters_window, bool* __restrict show_exclusions_window, bool* __restrict show_logs_window) {
|
2023-01-29 11:59:56 +00:00
|
|
|
|
|
|
|
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->WorkPos);
|
|
|
|
ImGui::SetNextWindowSize(ImGui::GetMainViewport()->WorkSize);
|
2023-02-04 07:31:50 +00:00
|
|
|
if (!ImGui::BeginWithCloseShortcut("LogMeow", nullptr,
|
2023-01-29 11:59:56 +00:00
|
|
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus)) {
|
2023-01-23 08:44:16 +00:00
|
|
|
ImGui::End();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-24 05:17:05 +00:00
|
|
|
if (ImGui::Button("Settings") && !*show_settings_window) {
|
2023-01-31 14:40:04 +00:00
|
|
|
inactive_config.logcat_command = active_config.logcat_command;
|
|
|
|
inactive_config.normal_font_size = active_config.normal_font_size;
|
|
|
|
inactive_config.monospace_font_size = active_config.monospace_font_size;
|
2023-01-23 08:44:16 +00:00
|
|
|
*show_settings_window = true;
|
|
|
|
}
|
2023-01-28 14:11:46 +00:00
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Filters") && !*show_filters_window) {
|
2023-01-31 14:40:04 +00:00
|
|
|
copy_filters(inactive_config.filters, active_config.filters);
|
2023-01-28 14:11:46 +00:00
|
|
|
*show_filters_window = true;
|
|
|
|
}
|
2023-02-01 15:22:08 +00:00
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Exclusions") && !*show_exclusions_window) {
|
|
|
|
copy_filters(inactive_config.exclusions, active_config.exclusions);
|
|
|
|
*show_exclusions_window = true;
|
|
|
|
}
|
2023-01-23 08:44:16 +00:00
|
|
|
ImGui::SameLine();
|
2023-02-05 14:02:36 +00:00
|
|
|
bool open_logs = latest_log_entries_read ? ImGui::Button("Logs") : ImGui::RedButton("Logs");
|
2023-01-29 10:08:27 +00:00
|
|
|
if (open_logs) {
|
2023-01-23 08:44:16 +00:00
|
|
|
*show_logs_window = true;
|
|
|
|
}
|
|
|
|
|
2023-02-02 12:50:28 +00:00
|
|
|
bool can_send_logcat_request = logcat_thread.logcat_process_request.load() == LogcatProcessRequest::None;
|
|
|
|
bool logcat_running = logcat_thread.logcat_process_running.test();
|
|
|
|
ImGui::AlignTextToFramePadding();
|
|
|
|
ImGui::TextUnformatted("Logcat:");
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
if (!can_send_logcat_request) {
|
|
|
|
ImGui::BeginDisabled();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Button("Start", !logcat_running)) {
|
2023-02-07 06:36:51 +00:00
|
|
|
logcat_entries.clear();
|
|
|
|
filtered_logcat_entry_offsets.clear();
|
2023-02-02 12:50:28 +00:00
|
|
|
logcat_thread.logcat_process_request.store(LogcatProcessRequest::Start);
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Stop", logcat_running)) {
|
|
|
|
logcat_thread.logcat_process_request.store(LogcatProcessRequest::Stop);
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Restart", logcat_running)) {
|
2023-02-07 06:36:51 +00:00
|
|
|
logcat_entries.clear();
|
|
|
|
filtered_logcat_entry_offsets.clear();
|
2023-02-02 12:50:28 +00:00
|
|
|
logcat_thread.logcat_process_request.store(LogcatProcessRequest::Start);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!can_send_logcat_request) {
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
}
|
|
|
|
|
2023-01-23 08:44:16 +00:00
|
|
|
ImGui::Separator();
|
|
|
|
// copied from imgui/imgui_demo.cpp: [SECTION] Example App: Debug Console / ShowExampleAppConsole()
|
|
|
|
// and [SECTION] Example App: Long Text / ShowExampleAppLongText()
|
|
|
|
// and [SECTION] Example App: Debug Log / ShowExampleAppLog()
|
2023-01-29 07:56:05 +00:00
|
|
|
// and Tables/Vertical scrolling, with clipping
|
|
|
|
const constexpr ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
|
|
|
|
if (ImGui::BeginTable("logcat", 8, flags)) {
|
|
|
|
render_table(monospace_font, logcat_entries, filtered_logcat_entry_offsets);
|
2023-01-23 08:44:16 +00:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|