Add basic export code

This commit is contained in:
blankie 2023-03-29 00:03:16 +07:00
parent d4e6d72a18
commit 72591390d6
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
6 changed files with 108 additions and 2 deletions

View File

@ -9,7 +9,7 @@ project(logmeow CXX)
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
find_package(Freetype 2 REQUIRED) find_package(Freetype 2 REQUIRED)
find_package(nlohmann_json REQUIRED) find_package(nlohmann_json REQUIRED)
list(APPEND LIBS -lpcre2-8 -lpcre2-posix SDL2 nlohmann_json::nlohmann_json imgui) list(APPEND LIBS -lpcre2-8 -lpcre2-posix SDL2 nlohmann_json::nlohmann_json imgui nfd)
list(APPEND IMGUI_LIBS SDL2 Freetype::Freetype) list(APPEND IMGUI_LIBS SDL2 Freetype::Freetype)
set(INCLUDES "") set(INCLUDES "")
@ -19,7 +19,7 @@ set(DEFINITIONS "")
# imgui include because https://github.com/ocornut/imgui/issues/6184#issuecomment-1439570929 # imgui include because https://github.com/ocornut/imgui/issues/6184#issuecomment-1439570929
list(APPEND INCLUDES thirdparty thirdparty/imgui /usr/include/SDL2) list(APPEND INCLUDES thirdparty thirdparty/imgui /usr/include/SDL2)
list(APPEND SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp filters.cpp misc.cpp pcre2_wrapper.cpp list(APPEND SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp filters.cpp misc.cpp pcre2_wrapper.cpp
group_panel.cpp fragments/filters.cpp windows/logs.cpp windows/settings.cpp windows/main.cpp) group_panel.cpp fragments/filters.cpp fragments/export.cpp windows/logs.cpp windows/settings.cpp windows/main.cpp)
list(APPEND IMGUI_SOURCES thirdparty/imgui/imgui.cpp thirdparty/imgui/imgui_draw.cpp thirdparty/imgui/imgui_widgets.cpp thirdparty/imgui/imgui_tables.cpp list(APPEND IMGUI_SOURCES thirdparty/imgui/imgui.cpp thirdparty/imgui/imgui_draw.cpp thirdparty/imgui/imgui_widgets.cpp thirdparty/imgui/imgui_tables.cpp
thirdparty/imgui/misc/cpp/imgui_stdlib.cpp thirdparty/imgui/misc/freetype/imgui_freetype.cpp thirdparty/imgui/misc/cpp/imgui_stdlib.cpp thirdparty/imgui/misc/freetype/imgui_freetype.cpp
thirdparty/imgui/backends/imgui_impl_sdl2.cpp thirdparty/imgui/backends/imgui_impl_opengl3.cpp) thirdparty/imgui/backends/imgui_impl_sdl2.cpp thirdparty/imgui/backends/imgui_impl_opengl3.cpp)
@ -88,6 +88,9 @@ target_compile_definitions(imgui PRIVATE ${DEFINITIONS})
# it seems like compilers may issue a warning for unknown warnings to ignore # it seems like compilers may issue a warning for unknown warnings to ignore
target_compile_options(imgui PRIVATE ${FLAGS} -Wno-unknown-warning-option -Wno-conversion) target_compile_options(imgui PRIVATE ${FLAGS} -Wno-unknown-warning-option -Wno-conversion)
set(NFD_PORTAL ON)
add_subdirectory(thirdparty/nativefiledialog-extended)
add_executable(${PROJECT_NAME} ${SOURCES}) add_executable(${PROJECT_NAME} ${SOURCES})
set_target_properties(${PROJECT_NAME} set_target_properties(${PROJECT_NAME}
PROPERTIES PROPERTIES

71
fragments/export.cpp Normal file
View File

@ -0,0 +1,71 @@
#include <imgui/imgui.h>
#include <nativefiledialog-extended/src/include/nfd.h>
#include <optional>
#include "../file.h"
#include "../logcat_entry.h"
#include "export.h"
enum class ExportAmount : int {
All = 0,
Filtered = 1,
};
static inline void export_logcat_entries(File& file, const std::vector<LogcatEntry>& logcat_entries,
const std::vector<size_t>& filtered_logcat_entry_offsets, ExportAmount export_amount, bool export_buffers);
static inline std::optional<File> save_file_picker();
void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::vector<size_t>& filtered_logcat_entry_offsets) {
static ExportAmount export_amount = ExportAmount::Filtered;
static bool export_buffers = true;
ImGui::RadioButton("Export all entries", reinterpret_cast<int*>(&export_amount), static_cast<int>(ExportAmount::All));
ImGui::RadioButton("Export filtered entries", reinterpret_cast<int*>(&export_amount), static_cast<int>(ExportAmount::Filtered));
ImGui::Checkbox("Export buffers", &export_buffers);
ImGui::Separator();
if (ImGui::Button("Export to File")) {
std::optional<File> file = save_file_picker();
if (file) {
export_logcat_entries(*file, logcat_entries, filtered_logcat_entry_offsets, export_amount, export_buffers);
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if (ImGui::Button("Export to Clipboard")) {
// TODO exist
}
}
static inline void export_logcat_entries(File& file, const std::vector<LogcatEntry>& logcat_entries,
const std::vector<size_t>& filtered_logcat_entry_offsets, ExportAmount export_amount, bool export_buffers) {
// TODO actually do the job
file.write(std::string("Count of all entries: ") + std::to_string(logcat_entries.size()) + '\n');
file.write(std::string("Count of filtered entries: ") + std::to_string(filtered_logcat_entry_offsets.size()) + '\n');
file.write(std::string("Export amount: ") + (export_amount == ExportAmount::All ? "all" : "filtered") + '\n');
file.write(std::string("Export buffers: ") + (export_buffers ? "true" : "false") + '\n');
}
static inline std::optional<File> save_file_picker() {
nfdchar_t* path;
nfdfilteritem_t filters[1] = {{"Log file", "log"}};
nfdresult_t res = NFD_SaveDialog(&path, filters, 1, nullptr, "logcat.log");
if (res == NFD_OKAY) {
try {
File file(path, "w");
NFD_FreePath(path);
return std::move(file);
} catch (const std::exception& e) {
NFD_FreePath(path);
log(std::string("Failed to open file from file picker: ") + e.what());
}
} else if (res == NFD_CANCEL) {
// dialog was canceled, shrug
} else {
log(std::string("Failed to open file picker: ") + NFD_GetError());
}
return std::nullopt;
}

8
fragments/export.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <vector>
#include <stddef.h>
struct LogcatEntry; // forward declaration from ../logcat_entry.h
void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::vector<size_t>& filtered_logcat_entry_offsets);

View File

@ -12,6 +12,7 @@
#else #else
#include <SDL_opengl.h> #include <SDL_opengl.h>
#endif #endif
#include <nativefiledialog-extended/src/include/nfd.h>
#include "log.h" #include "log.h"
#include "fonts.h" #include "fonts.h"
@ -47,6 +48,13 @@ int main() {
return 1; return 1;
} }
// Setup NFDe
if (NFD_Init() != NFD_OKAY) {
SDL_Quit();
fprintf(stderr, "NFD_Init(): %s\n", NFD_GetError());
return 1;
}
// Decide GL+GLSL versions // Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2) #if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100 // GL ES 2.0 + GLSL 100
@ -178,6 +186,8 @@ int main() {
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
NFD_Quit();
SDL_GL_DeleteContext(gl_context); SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();

@ -0,0 +1 @@
Subproject commit 7909f55d912fe353ee2df6b08eec9313b50685f7

View File

@ -1,4 +1,5 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <imgui/imgui_internal.h>
#include <ctime> #include <ctime>
#include <string> #include <string>
#include <vector> #include <vector>
@ -7,6 +8,7 @@
#include "../config.h" #include "../config.h"
#include "../logcat_entry.h" #include "../logcat_entry.h"
#include "../logcat_thread.h" #include "../logcat_thread.h"
#include "../fragments/export.h"
#include "main.h" #include "main.h"
static inline void render_table_item_context_menu(const LogcatEntry& logcat_entry) { static inline void render_table_item_context_menu(const LogcatEntry& logcat_entry) {
@ -166,6 +168,17 @@ void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThr
ImGui::EndDisabled(); ImGui::EndDisabled();
} }
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
if (ImGui::Button("Export")) {
ImGui::OpenPopup("export_logcat");
}
if (ImGui::BeginPopup("export_logcat")) {
export_fragment(logcat_entries, filtered_logcat_entry_offsets);
ImGui::EndPopup();
}
ImGui::Separator(); ImGui::Separator();
// copied from imgui/imgui_demo.cpp: [SECTION] Example App: Debug Console / ShowExampleAppConsole() // copied from imgui/imgui_demo.cpp: [SECTION] Example App: Debug Console / ShowExampleAppConsole()
// and [SECTION] Example App: Long Text / ShowExampleAppLongText() // and [SECTION] Example App: Long Text / ShowExampleAppLongText()