From 30516cfd877bf99f56ef43a7fe50ff8154f703b8 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 2 Nov 2023 16:25:16 +0300 Subject: =?UTF-8?q?fixes=20#3596=20(ICQ:=20"Copy=20URL"=20=D0=B2=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=BD=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8E=20=D0=B6=D1=83=D1=80=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D0=B0/=D0=B8=D1=81=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=84=D1=84=D0=BB=D0=B0=D0=B9=D0=BD=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B9=D0=BB=D0=B5=20=D0=BE=D1=82=D0=B4=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=20=D0=B1=D0=B5=D1=81=D1=81=D0=BC=D1=8B=D1=81=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=83=D1=8E=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D1=83)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/m_protosvc.h | 11 +++++-- libs/win32/mir_app.lib | Bin 272382 -> 272378 bytes libs/win64/mir_app.lib | Bin 271564 -> 271560 bytes plugins/NewStory/src/history_control.cpp | 13 ++++++++ plugins/NewStory/src/history_control.h | 1 + plugins/NewStory/src/history_menus.cpp | 28 +++++++++++------ protocols/ICQ-WIM/src/proto.cpp | 16 ++++++---- src/mir_app/src/file.cpp | 2 +- src/mir_app/src/file.h | 17 ++++++++--- src/mir_app/src/mir_app.def | 2 +- src/mir_app/src/mir_app64.def | 2 +- src/mir_app/src/srmm_log_rtf.cpp | 10 ++++-- src/mir_app/src/srmm_util.cpp | 51 +++++++++++++++++-------------- 13 files changed, 103 insertions(+), 50 deletions(-) diff --git a/include/m_protosvc.h b/include/m_protosvc.h index 6d47da323e..dcc7438b0d 100644 --- a/include/m_protosvc.h +++ b/include/m_protosvc.h @@ -806,11 +806,12 @@ __forceinline INT_PTR ProtoChainRecvFile(MCONTACT hContact, PROTORECVFILE *pre) #define OFD_DOWNLOAD 0x0001 #define OFD_SAVEAS 0x0002 +#define OFD_COPYURL 0x0004 #define OFD_RUN 0x1000 struct MIR_APP_EXPORT OFDTHREAD : public MNonCopyable { - OFDTHREAD(MEVENT, const CMStringW &, bool); + OFDTHREAD(MEVENT hDbEvent, const CMStringW &path, int iCommand); ~OFDTHREAD(); void Finish(); @@ -818,8 +819,14 @@ struct MIR_APP_EXPORT OFDTHREAD : public MNonCopyable MEVENT hDbEvent; MFilePath wszPath; - bool bOpen; struct OFD_Callback *pCallback = nullptr; + bool bOpen = false, bCopy = false; +}; + +struct OFD_Callback +{ + virtual ~OFD_Callback() {} + virtual void Invoke(const OFDTHREAD &ofd) = 0; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index d625caaa61..902b5ccca6 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index 66a8412127..a3f9c345f3 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index c95a155fb8..a5cb42ee01 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -300,6 +300,19 @@ void NewstoryListData::Copy(bool bTextOnly) Utils_ClipboardCopy(res); } +void NewstoryListData::CopyUrl() +{ + if (auto *pItem = GetItem(caret)) { + DB::EventInfo dbei(pItem->hEvent); + DB::FILE_BLOB blob(dbei); + + //if (pItem->m_bOfflineDownloaded) +// Utils_ClipboardCopy(blob.getLocalName()); + // else + Srmm_DownloadOfflineFile(pItem->hContact, pItem->hEvent, OFD_COPYURL); + } +} + void NewstoryListData::DeleteItems(void) { if (IDYES != MessageBoxW(m_hwnd, TranslateT("Are you sure to remove selected event(s)?"), _T(MODULETITLE), MB_YESNOCANCEL | MB_ICONQUESTION)) diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index 332c8eb7d7..b773c43c6b 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -63,6 +63,7 @@ struct NewstoryListData : public MZeroedObject void Clear(); void ClearSelection(int iFirst, int iLast); void Copy(bool bTextOnly = false); + void CopyUrl(); void DeleteItems(void); void Download(int iOptions); void EndEditItem(bool bAccept); diff --git a/plugins/NewStory/src/history_menus.cpp b/plugins/NewStory/src/history_menus.cpp index 71bdb16ce8..2a5186e49e 100644 --- a/plugins/NewStory/src/history_menus.cpp +++ b/plugins/NewStory/src/history_menus.cpp @@ -20,7 +20,7 @@ along with this program. If not, see . enum { - MENU_COPY, MENU_COPYTEXT, MENU_QUOTE, + MENU_COPY, MENU_COPYTEXT, MENU_COPYURL, MENU_QUOTE, MENU_SAVEAS, MENU_DOWNLOAD, MENU_EDIT, MENU_DELETE, MENU_SELECTALL, MENU_BOOKMARK, @@ -28,17 +28,19 @@ enum static int hMenuObject; static HANDLE hEventPreBuildMenu; -static HGENMENU hmiHistory, hmiCopy, hmiSaveAs, hmiDownload, hmiQuote; +static HGENMENU hmiHistory, hmiCopy, hmiCopyUrl, hmiSaveAs, hmiDownload, hmiQuote; static HGENMENU hmiEdit, hmiBookmark, hmiDelete; HMENU NSMenu_Build(NewstoryListData *data, ItemData *item) { if (item->m_bOfflineFile) { - Menu_ModifyItem(hmiCopy, (item->m_bOfflineDownloaded) ? TranslateT("Copy file name") : TranslateT("Copy URL")); + Menu_ModifyItem(hmiCopyUrl, (item->m_bOfflineDownloaded) ? TranslateT("Copy file name") : TranslateT("Copy URL")); + Menu_ShowItem(hmiCopyUrl, true); Menu_ShowItem(hmiSaveAs, true); Menu_ShowItem(hmiDownload, !item->m_bOfflineDownloaded); } else { + Menu_ShowItem(hmiCopyUrl, false); Menu_ShowItem(hmiSaveAs, false); Menu_ShowItem(hmiDownload, false); } @@ -84,6 +86,10 @@ static INT_PTR NSMenuHelper(WPARAM wParam, LPARAM lParam) pData->Copy(true); break; + case MENU_COPYURL: + pData->CopyUrl(); + break; + case MENU_QUOTE: pData->Quote(); break; @@ -204,19 +210,23 @@ void InitMenus() mi.name.a = LPGEN("Copy"); hmiCopy = Menu_AddNewStoryMenuItem(&mi, MENU_COPY); - mi.position = 100001; + mi.position++; mi.name.a = LPGEN("Copy text"); hmiCopy = Menu_AddNewStoryMenuItem(&mi, MENU_COPYTEXT); - mi.position = 100002; + mi.position++; + mi.name.a = LPGEN("Copy URL"); + hmiCopyUrl = Menu_AddNewStoryMenuItem(&mi, MENU_COPYURL); + + mi.position++; mi.name.a = LPGEN("Quote"); hmiQuote = Menu_AddNewStoryMenuItem(&mi, MENU_QUOTE); - mi.position = 100003; + mi.position++; mi.name.a = LPGEN("Save as"); hmiSaveAs = Menu_AddNewStoryMenuItem(&mi, MENU_SAVEAS); - mi.position = 100004; + mi.position++; mi.name.a = LPGEN("Download"); hmiDownload = Menu_AddNewStoryMenuItem(&mi, MENU_DOWNLOAD); @@ -224,11 +234,11 @@ void InitMenus() mi.name.a = LPGEN("Edit"); hmiEdit = Menu_AddNewStoryMenuItem(&mi, MENU_EDIT); - mi.position = 200001; + mi.position++; mi.name.a = LPGEN("Delete"); hmiDelete = Menu_AddNewStoryMenuItem(&mi, MENU_DELETE); - mi.position = 200002; + mi.position++; mi.name.a = LPGEN("Toggle bookmark"); hmiBookmark = Menu_AddNewStoryMenuItem(&mi, MENU_BOOKMARK); diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index 93664a6ed3..aec09ffb55 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -231,19 +231,23 @@ void __cdecl CIcqProto::OfflineFileThread(void *pParam) auto *ofd = (OFDTHREAD *)pParam; DB::EventInfo dbei(ofd->hDbEvent); - if (dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) { - JSONNode root = JSONNode::parse((const char *)dbei.pBlob); - if (m_bOnline && root) { - MCONTACT hContact = db_event_getContact(ofd->hDbEvent); - if (auto *pFileInfo = RetrieveFileInfo(hContact, fileText2url(root["u"].as_mstring()))) { + if (m_bOnline && dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) { + DB::FILE_BLOB blob(dbei); + MCONTACT hContact = db_event_getContact(ofd->hDbEvent); + if (auto *pFileInfo = RetrieveFileInfo(hContact, fileText2url(blob.getUrl()))) { + if (!ofd->bCopy) { auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, pFileInfo->szUrl, &CIcqProto::OnFileRecv); pReq->pUserInfo = ofd; pReq->AddHeader("Sec-Fetch-User", "?1"); pReq->AddHeader("Sec-Fetch-Site", "cross-site"); pReq->AddHeader("Sec-Fetch-Mode", "navigate"); Push(pReq); + return; // ofd is used inside CIcqProto::OnFileRecv, don't remove it } - return; + + ofd->wszPath.Empty(); + ofd->wszPath.Append(_A2T(pFileInfo->szUrl)); + ofd->pCallback->Invoke(*ofd); } } diff --git a/src/mir_app/src/file.cpp b/src/mir_app/src/file.cpp index 04cc6c0af8..8274b8fb22 100644 --- a/src/mir_app/src/file.cpp +++ b/src/mir_app/src/file.cpp @@ -297,7 +297,7 @@ MEVENT Proto_RecvFile(MCONTACT hContact, PROTORECVFILE *pre) // or if they are less than a limit (if a transfer has specified file size) if (bSilent && File::bOfflineAuto) if (File::iOfflineSize == 0 || (blob.getSize() > 0 && blob.getSize() < File::iOfflineSize * 1024)) - DownloadOfflineFile(hContact, hdbe, false, new OFD_Download()); + DownloadOfflineFile(hContact, hdbe, dbei, false, new OFD_Download()); bool bShow = !Contact::IsGroupChat(hContact); if (bShow && blob.isOffline()) { diff --git a/src/mir_app/src/file.h b/src/mir_app/src/file.h index 2decb52aa5..9a21931359 100644 --- a/src/mir_app/src/file.h +++ b/src/mir_app/src/file.h @@ -143,10 +143,19 @@ int GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, void GetSensiblyFormattedSize(__int64 size, wchar_t *szOut, int cchOut, int unitsOverride, int appendUnits, int *unitsUsed); // downloads or launches cloud file -struct OFD_Callback + +struct OFD_CopyUrl : public OFD_Callback { - virtual ~OFD_Callback() {} - virtual void Invoke(const OFDTHREAD &ofd) = 0; + CMStringW wszUrl; + + OFD_CopyUrl(const CMStringW &url) : + wszUrl(url) + {} + + void Invoke(const OFDTHREAD &ofd) override + { + Utils_ClipboardCopy(ofd.wszPath.IsEmpty() ? wszUrl : ofd.wszPath); + } }; struct OFD_Download : public OFD_Callback @@ -175,4 +184,4 @@ public: } }; -void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen, OFD_Callback *pCallback); +void DownloadOfflineFile(MCONTACT, MEVENT, DB::EventInfo &dbei, int iCommand, OFD_Callback *pCallback); diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index fb83d97f00..e0919c872a 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -875,7 +875,7 @@ Clist_RemoveEvent @989 ?Chat_EmptyHistory@@YGXPAUSESSION_INFO@@@Z @992 NONAME ?Utils_Unzip@@YG?AVMBinBuffer@@PBXI@Z @993 NONAME ?OnNickListTimer@CSrmmBaseDialog@@AAEXPAVCTimer@@@Z @994 NONAME -??0OFDTHREAD@@QAE@IABV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@_N@Z @995 NONAME +??0OFDTHREAD@@QAE@IABV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@H@Z @995 NONAME ??1OFDTHREAD@@QAE@XZ @996 NONAME ?Finish@OFDTHREAD@@QAEXXZ @997 NONAME ?getLocalName@FILE_BLOB@DB@@QBEPB_WXZ @998 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index d977ff1183..c60f03222e 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -875,7 +875,7 @@ Clist_RemoveEvent @989 ?Chat_EmptyHistory@@YAXPEAUSESSION_INFO@@@Z @992 NONAME ?Utils_Unzip@@YA?AVMBinBuffer@@PEBX_K@Z @993 NONAME ?OnNickListTimer@CSrmmBaseDialog@@AEAAXPEAVCTimer@@@Z @994 NONAME -??0OFDTHREAD@@QEAA@IAEBV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@_N@Z @995 NONAME +??0OFDTHREAD@@QEAA@IAEBV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@H@Z @995 NONAME ??1OFDTHREAD@@QEAA@XZ @996 NONAME ?Finish@OFDTHREAD@@QEAAXXZ @997 NONAME ?getLocalName@FILE_BLOB@DB@@QEBAPEB_WXZ @998 NONAME diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp index 852b07b192..91e8b40cb6 100644 --- a/src/mir_app/src/srmm_log_rtf.cpp +++ b/src/mir_app/src/srmm_log_rtf.cpp @@ -215,8 +215,8 @@ INT_PTR CRtfLogWindow::Notify(WPARAM, LPARAM lParam) DB::EventInfo dbei(hDbEvent); if (!dbei) return FALSE; + DB::FILE_BLOB blob(dbei); - int nCmd = 2; if (pLink->msg == WM_RBUTTONDOWN) { HMENU hMenu = CreatePopupMenu(); @@ -235,11 +235,15 @@ INT_PTR CRtfLogWindow::Notify(WPARAM, LPARAM lParam) switch (nCmd) { case 2: case 3: - DownloadOfflineFile(m_pDlg.m_hContact, hDbEvent, nCmd == 2, new OFD_Download()); + DownloadOfflineFile(m_pDlg.m_hContact, hDbEvent, dbei, nCmd == 2, new OFD_Download()); break; case 4: - Utils_ClipboardCopy(blob.getUrl()); + { + OFDTHREAD *ofd = new OFDTHREAD(hDbEvent, L"", OFD_COPYURL); + ofd->pCallback = new OFD_CopyUrl(blob.getUrl()); + CallProtoService(dbei.szModule, PS_OFFLINEFILE, (WPARAM)ofd, 0); + } break; case 5: diff --git a/src/mir_app/src/srmm_util.cpp b/src/mir_app/src/srmm_util.cpp index 2cd125e453..87e0b890a3 100644 --- a/src/mir_app/src/srmm_util.cpp +++ b/src/mir_app/src/srmm_util.cpp @@ -114,11 +114,12 @@ MIR_APP_DLL(int) Srmm_GetWindowData(MCONTACT hContact, MessageWindowData &mwd) ///////////////////////////////////////////////////////////////////////////////////////// // downloads or launches cloud file -OFDTHREAD::OFDTHREAD(MEVENT _1, const CMStringW &_2, bool _3) : +OFDTHREAD::OFDTHREAD(MEVENT _1, const CMStringW &_2, int iCommand) : hDbEvent(_1), - wszPath(_2), - bOpen(_3) + wszPath(_2) { + bOpen = (iCommand & OFD_RUN) != 0; + bCopy = (iCommand & OFD_COPYURL) != 0; } OFDTHREAD::~OFDTHREAD() @@ -166,12 +167,8 @@ static void GenerateLocalName(const DB::EventInfo &dbei, DB::FILE_BLOB &blob, MC blob.setLocalName(FindUniqueFileName(wszFullName)); } -void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen, OFD_Callback *pCallback) +void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, DB::EventInfo &dbei, int iCommand, OFD_Callback *pCallback) { - DB::EventInfo dbei(hDbEvent); - if (!dbei) - return; - DB::FILE_BLOB blob(dbei); if (!blob.isOffline()) return; @@ -191,12 +188,12 @@ void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen, OFD_Cal } if (bDownloaded) { - OFDTHREAD ofd(hDbEvent, blob.getLocalName(), bOpen); + OFDTHREAD ofd(hDbEvent, blob.getLocalName(), iCommand); pCallback->Invoke(ofd); delete pCallback; } else { - OFDTHREAD *ofd = new OFDTHREAD(hDbEvent, blob.getLocalName(), bOpen); + OFDTHREAD *ofd = new OFDTHREAD(hDbEvent, blob.getLocalName(), iCommand); ofd->pCallback = pCallback; CallProtoService(dbei.szModule, PS_OFFLINEFILE, (WPARAM)ofd, 0); } @@ -204,19 +201,23 @@ void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen, OFD_Cal MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, int iCommand) { - bool bOpen = false; - if (iCommand & OFD_RUN) { - bOpen = true; - iCommand &= ~OFD_RUN; - } + DB::EventInfo dbei(hDbEvent); + if (!dbei) + return; - if (iCommand == OFD_SAVEAS) { - DB::EventInfo dbei(hDbEvent); - if (!dbei) - return; + DB::FILE_BLOB blob(dbei); + OFD_Callback *pCallback = 0; + + switch (iCommand & 0xFFF) { + case OFD_COPYURL: + pCallback = new OFD_CopyUrl(blob.getUrl()); + break; - DB::FILE_BLOB blob(dbei); + case OFD_DOWNLOAD: + pCallback = new OFD_Download(); + break; + case OFD_SAVEAS: wchar_t str[MAX_PATH]; mir_wstrncpy(str, blob.getName(), _countof(str)); @@ -230,10 +231,14 @@ MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, i ofn.lpstrFile = str; ofn.nMaxFile = _countof(str); ofn.nMaxFileTitle = MAX_PATH; - if (GetSaveFileNameW(&ofn)) - DownloadOfflineFile(hContact, hDbEvent, bOpen, new OFD_SaveAs(str)); + if (!GetSaveFileNameW(&ofn)) + return; + + pCallback = new OFD_SaveAs(str); + break; } - else DownloadOfflineFile(hContact, hDbEvent, bOpen, new OFD_Download()); + + DownloadOfflineFile(hContact, hDbEvent, dbei, iCommand, pCallback); } ///////////////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3