From 10e52d5daf0e02ad736cd811d096c4bf04055d24 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sat, 9 Mar 2024 23:29:38 +0100 Subject: file match context menu: open as, open folder, copy path, copy line --- build_win32.bat | 2 +- imgui/imgui_spectrum.cpp | 2 +- src/main.cpp | 37 +++++++++++++++++++++++++-- src/platform.h | 3 +++ src/windows/main_windows.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/build_win32.bat b/build_win32.bat index 2530a2d..7c4e008 100644 --- a/build_win32.bat +++ b/build_win32.bat @@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary @set OUT_EXE=text-search @set INCLUDES=/I..\.. /I..\..\backends @set SOURCES=imgui/imgui*.cpp src/*.cpp imfiledialog/*.cpp src/windows/*.cpp imgui/backends/imgui_impl_win32.cpp src/widgets/*.cpp -@set LIBS=opengl32.lib Advapi32.lib Shell32.lib bin/debug/data.obj bin/debug/icon.res +@set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib bin/debug/data.obj bin/debug/icon.res @set FLAGS= windres misc/icon.rc -O coff -o bin/debug/icon.res ld -r -b binary -o bin/debug/data.obj LICENSE misc/logo_64.png imgui/LICENSE imfiledialog/LICENSE misc/search.png misc/folder.png diff --git a/imgui/imgui_spectrum.cpp b/imgui/imgui_spectrum.cpp index 30ff713..d7705f2 100644 --- a/imgui/imgui_spectrum.cpp +++ b/imgui/imgui_spectrum.cpp @@ -13,7 +13,7 @@ namespace ImGui { static const ImWchar rr[] = { - 0x2192, 0x2193, // Basic Latin + Latin Supplement + 0x2192, 0x2193, // → character. 0, }; diff --git a/src/main.cpp b/src/main.cpp index 345657f..dc9bf8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -256,9 +256,12 @@ void _ts_create_text_match_rows() { ImGui::TableHeader(match_info_txt); } + char match_nr[20]; + snprintf(match_nr, 20, "#%d", item+1); + ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::Text("#%d", item+1); + ImGui::Text("%s", match_nr); ImGui::TableNextColumn(); @@ -282,7 +285,37 @@ void _ts_create_text_match_rows() { ImGui::TextColored({255,0,0,255}, "%.*s", (int)file->word_match_length, file->line_info + file->word_match_offset); ImGui::SameLine(0.0f, 0.0f); ImGui::TextUnformatted(file->line_info + file->word_match_offset + file->word_match_length); - + + ImGui::SameLine(); + ImGui::Selectable("##nolabel", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap); + + static bool context_menu_open = false; + if (ImGui::IsItemClicked(ImGuiPopupFlags_MouseButtonRight)) { + ImGui::OpenPopup(match_nr); + context_menu_open = true; + } + + if (ImGui::BeginPopup(match_nr)) { +#if defined(_WIN32) + if (ImGui::MenuItem("Open as")) + { + ts_platform_open_file_as(file->file->path); + } + if (ImGui::MenuItem("Open folder")) { + ts_platform_open_file_in_folder(file->file->path); + } +#endif + if (ImGui::MenuItem("Copy path")) + { + ts_platform_copy_to_clipboard(file->file->path); + } + if (ImGui::MenuItem("Copy line")) + { + ts_platform_copy_to_clipboard(file->line_info); + } + ImGui::EndPopup(); + } + ImGui::TableNextColumn(); ImGui::Text("line %d", file->line_nr); } diff --git a/src/platform.h b/src/platform.h index fbcffc9..2fa1f43 100644 --- a/src/platform.h +++ b/src/platform.h @@ -35,5 +35,8 @@ bool ts_platform_dir_exists(utf8_int8_t* dir); ts_file_content ts_platform_read_file(char *path, const char *mode); void ts_platform_list_files_block(ts_search_result* result, wchar_t* start_dir = nullptr); uint64_t ts_platform_get_time(uint64_t compare = 0); // if compare is not 0, return difference between timestamp and now, in milliseconds. +bool ts_platform_copy_to_clipboard(utf8_int8_t* str); +void ts_platform_open_file_as(utf8_int8_t* str); +void ts_platform_open_file_in_folder(utf8_int8_t* file); #endif \ No newline at end of file diff --git a/src/windows/main_windows.cpp b/src/windows/main_windows.cpp index cec7d47..62c473c 100644 --- a/src/windows/main_windows.cpp +++ b/src/windows/main_windows.cpp @@ -14,6 +14,7 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif +#include #include #include #include @@ -76,6 +77,8 @@ uint64_t ts_platform_get_time(uint64_t compare) int main(int, char**) { + CoInitializeEx(0, COINIT_MULTITHREADED|COINIT_DISABLE_OLE1DDE); + // Create application window //ImGui_ImplWin32_EnableDpiAwareness(); WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; @@ -163,6 +166,8 @@ int main(int, char**) ::DestroyWindow(hwnd); ::UnregisterClassW(wc.lpszClassName, wc.hInstance); + CoUninitialize(); + return 0; } @@ -267,7 +272,6 @@ ts_file_content ts_platform_read_file(char *path, const char *mode) else { result.file_error = FILE_ERROR_GENERIC; - printf("ERROR: %d %s\n", errno, path); } goto done_failure; @@ -383,4 +387,59 @@ void ts_platform_list_files_block(ts_search_result* result, wchar_t* start_dir) while (FindNextFile(handle, (LPWIN32_FIND_DATAW)&file_info) != 0); FindClose(handle); +} + +void ts_platform_open_file_as(utf8_int8_t* str) { + OPENASINFO info; + + wchar_t convstr[MAX_INPUT_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, str, -1, convstr, MAX_INPUT_LENGTH); + + info.pcszFile = convstr; + info.pcszClass = nullptr; + info.oaifInFlags = OAIF_EXEC; + + SHOpenWithDialog(nullptr, &info); +} + +void ts_platform_open_file_in_folder(utf8_int8_t* file) { + + wchar_t convstr[MAX_INPUT_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, file, -1, convstr, MAX_INPUT_LENGTH); + PathCchRemoveFileSpec(convstr, MAX_INPUT_LENGTH); + ShellExecuteW(NULL, L"open", convstr, NULL, NULL, SW_SHOWDEFAULT); +} + +bool ts_platform_copy_to_clipboard(utf8_int8_t* str) { + HANDLE clipboard_data; + + wchar_t convstr[MAX_INPUT_LENGTH]; + memset(convstr, 0, sizeof(convstr)); + int result = MultiByteToWideChar(CP_UTF8, 0, str, -1, convstr, MAX_INPUT_LENGTH); + + size_t len = result; + size_t size = (len+1) * sizeof(wchar_t); + LPSTR dst; + + if (!OpenClipboard(NULL)) + return false; + + clipboard_data = GlobalAlloc(GMEM_MOVEABLE, size); + if (clipboard_data) + { + dst = (LPSTR)GlobalLock(clipboard_data); + memmove(dst, convstr, size); + dst[len*2] = 0; + GlobalUnlock(clipboard_data); + + SetClipboardData(CF_UNICODETEXT, clipboard_data); + } + else + { + CloseClipboard(); + return false; + } + + CloseClipboard(); + return true; } \ No newline at end of file -- cgit v1.2.3-70-g09d2