2023-03-28 17:03:16 +00:00
|
|
|
#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 {
|
2023-03-29 14:28:31 +00:00
|
|
|
All,
|
|
|
|
Filtered,
|
2023-03-28 17:03:16 +00:00
|
|
|
};
|
|
|
|
|
2023-03-29 14:28:31 +00:00
|
|
|
static inline void export_logcat_entries(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers, File& file);
|
|
|
|
static inline void export_logcat_entries_to_clipboard(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers);
|
2023-03-30 15:56:43 +00:00
|
|
|
static void export_logcat_entries(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers, auto cb);
|
2023-03-28 17:03:16 +00:00
|
|
|
static inline std::optional<File> save_file_picker();
|
|
|
|
|
2023-03-29 10:08:31 +00:00
|
|
|
void export_fragment(const LogcatEntries& logcat_entries) {
|
2023-03-28 17:03:16 +00:00
|
|
|
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) {
|
|
|
|
ImGui::CloseCurrentPopup();
|
2023-03-29 14:28:31 +00:00
|
|
|
try {
|
|
|
|
export_logcat_entries(logcat_entries, export_amount, export_buffers, *file);
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
log(std::string("Failed to export logcat entries: ") + e.what());
|
|
|
|
}
|
2023-03-28 17:03:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Export to Clipboard")) {
|
2023-03-29 14:28:31 +00:00
|
|
|
ImGui::CloseCurrentPopup();
|
|
|
|
try {
|
|
|
|
export_logcat_entries_to_clipboard(logcat_entries, export_amount, export_buffers);
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
log(std::string("Failed to export logcat entries: ") + e.what());
|
|
|
|
}
|
2023-03-28 17:03:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-29 14:28:31 +00:00
|
|
|
static inline void export_logcat_entries(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers, File& file) {
|
|
|
|
export_logcat_entries(logcat_entries, export_amount, export_buffers, [&](std::string line) {
|
|
|
|
file.write(std::move(line));
|
|
|
|
file.write("\n", 1);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void export_logcat_entries_to_clipboard(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers) {
|
|
|
|
std::string text;
|
|
|
|
export_logcat_entries(logcat_entries, export_amount, export_buffers, [&](std::string line) {
|
|
|
|
text += std::move(line);
|
|
|
|
text += '\n';
|
|
|
|
});
|
|
|
|
ImGui::SetClipboardText(text.c_str());
|
|
|
|
}
|
|
|
|
|
2023-03-30 15:56:43 +00:00
|
|
|
static void export_logcat_entries(const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers, auto cb) {
|
2023-03-29 14:28:31 +00:00
|
|
|
size_t size;
|
|
|
|
const LogcatEntry& (LogcatEntries::*get_fn)(size_t) const;
|
|
|
|
unsigned int buffers_printed = 0;
|
|
|
|
std::optional<Buffer> last_buffer;
|
|
|
|
|
|
|
|
switch (export_amount) {
|
|
|
|
case ExportAmount::All:
|
|
|
|
size = logcat_entries.size_all();
|
|
|
|
get_fn = &LogcatEntries::at_all;
|
|
|
|
break;
|
|
|
|
case ExportAmount::Filtered:
|
|
|
|
size = logcat_entries.size_filtered();
|
|
|
|
get_fn = &LogcatEntries::at_filtered;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
|
|
const LogcatEntry& entry = (logcat_entries.*get_fn)(i);
|
|
|
|
if (export_buffers && (!last_buffer || *last_buffer != entry.buffer)) {
|
|
|
|
const char* prefix = buffers_printed & static_cast<unsigned int>(entry.buffer)
|
|
|
|
? "switch to"
|
|
|
|
: "beginning of";
|
|
|
|
cb(std::string("--------- ") + prefix + ' ' + to_string_lower(entry.buffer));
|
|
|
|
buffers_printed |= static_cast<unsigned int>(entry.buffer);
|
|
|
|
last_buffer = entry.buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
cb(to_string(entry));
|
|
|
|
}
|
2023-03-28 17:03:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2023-06-21 11:45:08 +00:00
|
|
|
return file;
|
2023-03-28 17:03:16 +00:00
|
|
|
} 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 {
|
2023-03-29 15:21:55 +00:00
|
|
|
// ignore error when failing to open the file picker
|
2023-03-28 17:03:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
}
|