From ba22942e9a4829c8dc8cae7e3dae61b11fc620aa Mon Sep 17 00:00:00 2001 From: Takashi Sawanaka Date: Sun, 16 Jul 2023 20:20:52 +0900 Subject: [PATCH] Add Generate Report menu item --- src/WinWebDiff/Resource.h | 8 +- src/WinWebDiff/WinWebDiff.cpp | 125 ++++++++++++++++++++++++++++ src/WinWebDiff/WinWebDiff.rc | Bin 15494 -> 15936 bytes src/WinWebDiffLib/WebDiffWindow.hpp | 16 ++++ src/WinWebDiffLib/WebWindow.hpp | 29 +++++++ src/WinWebDiffLib/WinWebDiffLib.h | 3 +- 6 files changed, 177 insertions(+), 4 deletions(-) diff --git a/src/WinWebDiff/Resource.h b/src/WinWebDiff/Resource.h index d4d3edf..1bccd82 100644 --- a/src/WinWebDiff/Resource.h +++ b/src/WinWebDiff/Resource.h @@ -8,9 +8,11 @@ #define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDM_FILE_NEW 106 -#define IDM_FILE_NEW_TAB 107 -#define IDM_FILE_CLOSE_TAB 108 -#define IDM_FILE_RELOAD 109 +#define IDM_FILE_NEW3 107 +#define IDM_FILE_NEW_TAB 108 +#define IDM_FILE_CLOSE_TAB 109 +#define IDM_FILE_RELOAD 110 +#define IDM_FILE_GENERATE_REPORT 111 #define IDM_VIEW_SIZE_FIT_TO_WINDOW 120 #define IDM_VIEW_SIZE_320x512 121 #define IDM_VIEW_SIZE_375x600 122 diff --git a/src/WinWebDiff/WinWebDiff.cpp b/src/WinWebDiff/WinWebDiff.cpp index d3cc604..5f5f4de 100644 --- a/src/WinWebDiff/WinWebDiff.cpp +++ b/src/WinWebDiff/WinWebDiff.cpp @@ -4,10 +4,14 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include #include #pragma comment(lib, "comctl32.lib") @@ -265,6 +269,97 @@ bool CompareFiles(const std::vector& filenames, const std::wstring return true; } +std::string ToUTF8(const wchar_t* text) +{ + int size = WideCharToMultiByte(CP_UTF8, 0, text, -1, nullptr, 0, NULL, NULL); + std::string utf8(size, 0); + WideCharToMultiByte(CP_UTF8, 0, text, -1, utf8.data(), static_cast(utf8.size()), NULL, NULL); + utf8.resize(strlen(utf8.c_str())); + return utf8; +} + +void AppMsgBox(const std::wstring& text, int types) +{ + PostMessage(m_hWnd, WM_USER + 100, reinterpret_cast(new std::wstring(text)), types); +} + +bool GenerateHTMLReport(const wchar_t* filename) +{ + const int BUFFER_SIZE = 4096; + wchar_t tmp[BUFFER_SIZE]; + wchar_t rptdir_full[BUFFER_SIZE]; + std::wstring rptdir; + std::wstring rptfilepath[3]; + std::wstring difffilename[3]; + std::vector rptfilepath_utf8, difffilename_utf8; + wcscpy_s(rptdir_full, filename); + PathRemoveExtensionW(rptdir_full); + PathAddExtensionW(rptdir_full, L".files"); + rptdir = PathFindFileName(rptdir_full); + CreateDirectoryW(rptdir_full, nullptr); + const wchar_t* pfilenames[3]{}; + std::vector filenames; + for (int i = 0; i < m_pWebDiffWindow->GetPaneCount(); ++i) + { + rptfilepath[i] = m_pWebDiffWindow->GetCurrentUrl(i); + rptfilepath_utf8.push_back(ToUTF8(rptfilepath[i].c_str())); + wsprintfW(tmp, L"%d.pdf", i + 1); + difffilename[i] = rptdir + L"/" + tmp; + difffilename_utf8.push_back(ToUTF8(difffilename[i].c_str())); + filenames.push_back(std::wstring(rptdir_full) + L"/" + tmp); + pfilenames[i] = filenames[i].c_str(); + } + std::ofstream fout; + try + { + fout.open(filename, std::ios::out | std::ios::trunc); + fout << + "" << std::endl << + "" << std::endl << + "" << std::endl << + "" << std::endl << + "WinMerge Webpage Compare Report" << std::endl << + "" << std::endl << + "" << std::endl << + "" << std::endl << + "" << std::endl << + "" << std::endl; + for (int i = 0; i < m_pWebDiffWindow->GetPaneCount(); ++i) + fout << "" << std::endl; + fout << + "" << std::endl << + "" << std::endl; + for (int i = 0; i < m_pWebDiffWindow->GetPaneCount(); ++i) + fout << "" << std::endl; + fout << + "" << std::endl << + "
" << rptfilepath_utf8[i] << "
" << std::endl << + "" << std::endl << + "" << std::endl; + } + catch (...) + { + return false; + } + m_pWebDiffWindow->SaveDiffFiles(IWebDiffWindow::PDF, pfilenames, + Callback([](const WebDiffCallbackResult& result) -> HRESULT + { + if (SUCCEEDED(result.errorCode)) + AppMsgBox(L"The report has been created successfully.", MB_OK | MB_ICONINFORMATION); + else + AppMsgBox(L"Failed to create the report", MB_OK | MB_ICONWARNING); + return S_OK; + }) + .Get()); + return true; +} + void UpdateMenuState(HWND hWnd) { HMENU hMenu = GetMenu(hWnd); @@ -300,6 +395,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FILE_NEW: m_pWebDiffWindow->New(2, nullptr); break; + case IDM_FILE_NEW3: + m_pWebDiffWindow->New(3, nullptr); + break; case IDM_FILE_NEW_TAB: { int nActivePane = m_pWebDiffWindow->GetActivePane(); @@ -315,6 +413,26 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FILE_RELOAD: m_pWebDiffWindow->ReloadAll(); break; + case IDM_FILE_GENERATE_REPORT: + { + wchar_t szFileName[MAX_PATH] = {0}, szFile[MAX_PATH] = {0}; + OPENFILENAMEW ofn = {0}; + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = L"HTML file(*.html)\0*.html\0\0"; + ofn.lpstrFile = szFileName; + ofn.lpstrFileTitle = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.nMaxFileTitle = sizeof(szFile); + ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; + ofn.lpstrTitle = L"Generate HTML Report File"; + ofn.lpstrDefExt = L"html"; + if (GetSaveFileNameW(&ofn) != 0) + { + GenerateHTMLReport(ofn.lpstrFile); + } + break; + } case IDM_EXIT: DestroyWindow(hWnd); break; @@ -482,6 +600,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; } + case WM_USER + 100: + { + std::wstring* ptext = reinterpret_cast(wParam); + MessageBoxW(m_hWnd, ptext->c_str(), L"WinWebDiff", static_cast(lParam)); + delete ptext; + break; + } case WM_PAINT: { PAINTSTRUCT ps; diff --git a/src/WinWebDiff/WinWebDiff.rc b/src/WinWebDiff/WinWebDiff.rc index aeca3dfb832c7d969f9901d7372a9a21aa046a8e..dd0c8ac5d5245e84927bbd3b3ba067378fb34684 100644 GIT binary patch delta 152 zcmZpxJW#X2g-ck2L5;zfL4l!wA(0`EA(f$+L345-zvAQ#yd0AoxC9uDCokmIoFv1t z*@26VadM25jj}sX6-Z?fP)7-nR$vGMk_8O;K#>v#JrJDiC@2rq%_Zy3;L6|!#6b*> k3?V=|9>{WK2w?CB(jh>T)j=js_TsJs(pH;Kaqlqz0B>(); + for (int pane = 0; pane < m_nPanes; ++pane) + sfilenames->push_back(filenames[pane]); + ComPtr callback2(callback); + HRESULT hr = saveFilesLoop(kind, sfilenames, + Callback([this, sfilenames, callback2](const WebDiffCallbackResult& result) -> HRESULT + { + if (callback2) + return callback2->Invoke({ result.errorCode, nullptr }); + return S_OK; + }).Get()); + return hr; + } + HRESULT ClearBrowsingData(int pane, BrowsingDataType datakinds) override { int spane = pane, epane = pane; diff --git a/src/WinWebDiffLib/WebWindow.hpp b/src/WinWebDiffLib/WebWindow.hpp index d38189b..2db4512 100644 --- a/src/WinWebDiffLib/WebWindow.hpp +++ b/src/WinWebDiffLib/WebWindow.hpp @@ -548,6 +548,8 @@ class CWebWindow return SaveText(filename, callback); case IWebDiffWindow::RESOURCETREE: return SaveResourceTree(filename, callback); + case IWebDiffWindow::PDF: + return SavePDF(filename, callback); default: return E_INVALIDARG; } @@ -974,6 +976,33 @@ class CWebWindow return hr; } + HRESULT SavePDF(const std::wstring& filename, IWebDiffCallback* callback) + { + if (!GetActiveWebView()) + return E_FAIL; + ComPtr callback2(callback); + wil::com_ptr webview2_7 = GetActiveTab()->m_webview.try_query(); + if (!webview2_7) + return E_NOINTERFACE; + wil::com_ptr printSettings; + wil::com_ptr webviewEnvironment6 = m_webviewEnvironment.try_query(); + if (webviewEnvironment6) + { + webviewEnvironment6->CreatePrintSettings(&printSettings); + printSettings->put_ShouldPrintBackgrounds(true); + } + HRESULT hr = webview2_7->PrintToPdf(filename.c_str(), printSettings.get(), + Callback( + [callback2](HRESULT errorCode, BOOL isSucessful) -> HRESULT { + if (callback2) + return callback2->Invoke({ errorCode, nullptr}); + return S_OK; + }).Get()); + if (FAILED(hr) && callback2) + return callback2->Invoke({ hr, nullptr }); + return hr; + } + HRESULT CallDevToolsProtocolMethod(const wchar_t* methodName, const wchar_t* params, IWebDiffCallback *callback, bool showError = true) { if (!GetActiveWebView()) diff --git a/src/WinWebDiffLib/WinWebDiffLib.h b/src/WinWebDiffLib/WinWebDiffLib.h index e96fd46..bc73c2b 100644 --- a/src/WinWebDiffLib/WinWebDiffLib.h +++ b/src/WinWebDiffLib/WinWebDiffLib.h @@ -35,7 +35,7 @@ struct IWebDiffWindow }; enum FormatType { - SCREENSHOT, FULLSIZE_SCREENSHOT, HTML, TEXT, RESOURCETREE + SCREENSHOT, FULLSIZE_SCREENSHOT, HTML, TEXT, RESOURCETREE, PDF }; enum BrowsingDataType { @@ -116,6 +116,7 @@ struct IWebDiffWindow virtual HRESULT Recompare(IWebDiffCallback* callback) = 0; virtual HRESULT SaveFile(int pane, FormatType kind, const wchar_t* filename, IWebDiffCallback* callback) = 0; virtual HRESULT SaveFiles(FormatType kind, const wchar_t* filenames[], IWebDiffCallback* callback) = 0; + virtual HRESULT SaveDiffFiles(FormatType kind, const wchar_t* filenames[], IWebDiffCallback* callback) = 0; virtual HRESULT ClearBrowsingData(int pane, BrowsingDataType datakinds) = 0; virtual const wchar_t *GetCurrentUrl(int pane) = 0; virtual int GetPaneCount() const = 0;