From e787977a76ef3579d0fdd690530aa5c5ee231aff Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 6 Mar 2024 20:13:00 +0300 Subject: fixes #4273 (Msg_Export to share JSON export format from Import plugin) --- plugins/Msg_Export/res/resource.rc | 2 +- plugins/Msg_Export/src/FileViewer.cpp | 18 +-- plugins/Msg_Export/src/FileViewer.h | 2 - plugins/Msg_Export/src/main.cpp | 122 ++++++------------- plugins/Msg_Export/src/options.cpp | 70 ++++++----- plugins/Msg_Export/src/resource.h | 2 +- plugins/Msg_Export/src/stdafx.h | 18 +-- plugins/Msg_Export/src/utils.cpp | 219 ++++++++++------------------------ plugins/Msg_Export/src/utils.h | 5 +- 9 files changed, 155 insertions(+), 303 deletions(-) (limited to 'plugins/Msg_Export') diff --git a/plugins/Msg_Export/res/resource.rc b/plugins/Msg_Export/res/resource.rc index 2c9a4b412e..262a43280b 100644 --- a/plugins/Msg_Export/res/resource.rc +++ b/plugins/Msg_Export/res/resource.rc @@ -81,7 +81,7 @@ BEGIN CONTROL "Use JSON format for export",IDC_USE_JSON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,150,287,10 CONTROL "Use UTF-8 in new files",IDC_USE_UTF8_IN_NEW_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,163,287,10 CONTROL "Append extra new line",IDC_APPEND_NEWLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,176,287,10 - CONTROL "Use << and >>",IDC_USE_LESS_AND_GREATER_IN_EXPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,188,287,10 + CONTROL "Use << and >>",IDC_USE_ANGLE_BRACKETS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,188,287,10 END IDD_OPT_CONTACTS DIALOGEX 0, 0, 310, 234 diff --git a/plugins/Msg_Export/src/FileViewer.cpp b/plugins/Msg_Export/src/FileViewer.cpp index 50bda31613..cb9d162ef9 100644 --- a/plugins/Msg_Export/src/FileViewer.cpp +++ b/plugins/Msg_Export/src/FileViewer.cpp @@ -25,9 +25,6 @@ static UINT UM_FIND_CMD = RegisterWindowMessage(FINDMSGSTRING); #define ID_FV_SYNTAX_HL 0x0030 #define ID_FV_SAVE_AS_RTF 0x0040 -// Specifies if history is opened internaly or externaly -bool g_bUseIntViewer = true; - // External program used to view files wstring sFileViewerPrg; @@ -395,17 +392,6 @@ bool bOpenExternaly(MCONTACT hContact) return true; } -///////////////////////////////////////////////////////////////////////////////////////// -// Member Function : bGetInternalViewer -// Type : Global -// Parameters : None -// Returns : Returns true if - -bool bUseInternalViewer() -{ - return g_bUseIntViewer; -} - ///////////////////////////////////////////////////////////////////////////////////////// // Member Function : bUseInternalViewer // Type : Global @@ -414,8 +400,8 @@ bool bUseInternalViewer() bool bUseInternalViewer(bool bNew) { - g_bUseIntViewer = bNew; - if (g_bUseIntViewer && !hRichEditDll) { + g_plugin.bUseIntViewer = bNew; + if (g_plugin.bUseIntViewer && !hRichEditDll) { hRichEditDll = LoadLibraryA("Msftedit.dll"); if (!hRichEditDll) { LogLastError(L"Failed to load Rich Edit (Msftedit.dll)"); diff --git a/plugins/Msg_Export/src/FileViewer.h b/plugins/Msg_Export/src/FileViewer.h index 400938080e..13379b8753 100644 --- a/plugins/Msg_Export/src/FileViewer.h +++ b/plugins/Msg_Export/src/FileViewer.h @@ -26,8 +26,6 @@ bool bShowFileViewer(MCONTACT hContact); bool bUseInternalViewer(bool bNew); -extern bool g_bUseIntViewer; - extern wstring sFileViewerPrg; #endif diff --git a/plugins/Msg_Export/src/main.cpp b/plugins/Msg_Export/src/main.cpp index 76daadba0f..7f78b1eeb9 100644 --- a/plugins/Msg_Export/src/main.cpp +++ b/plugins/Msg_Export/src/main.cpp @@ -22,9 +22,7 @@ CMPlugin g_plugin; MWindowList hInternalWindowList = nullptr; -///////////////////////////////////////////////////// -// Remember to update the Version in the resource !!! -///////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), @@ -40,29 +38,24 @@ PLUGININFOEX pluginInfoEx = { }; CMPlugin::CMPlugin() : - PLUGIN(MODULENAME, pluginInfoEx) + PLUGIN(MODULENAME, pluginInfoEx), + bUseJson(MODULENAME, "UseJson", false), + bUseIntViewer(MODULENAME, "UseInternalViewer", true), + bAppendNewLine(MODULENAME, "AppendNewLine", true), + bReplaceHistory(MODULENAME, "ReplaceHistory", false), + bUseAngleBrackets(MODULENAME, "UseLessAndGreaterInExport", false), + bUseUtf8InNewFiles(MODULENAME, "UseUtf8InNewFiles", true) {} -///////////////////////////////////////////////////////////////////// -// Member Function : ShowExportHistory -// Type : Global -// Parameters : wParam - (MCONTACT)hContact -// lParam - ? -// Returns : static int -// Description : Called when user selects my menu item "Open Exported History" -// -// References : - -// Remarks : - -// Created : 020422, 22 April 2002 -// Developer : KN -///////////////////////////////////////////////////////////////////// - -static INT_PTR ShowExportHistory(WPARAM wParam, LPARAM) +///////////////////////////////////////////////////////////////////////////////////////// +// Services + +static INT_PTR ShowExportHistory(WPARAM hContact, LPARAM) { - if (g_bUseIntViewer) - bShowFileViewer(wParam); + if (g_plugin.bUseIntViewer) + bShowFileViewer(hContact); else - bOpenExternaly(wParam); + bOpenExternaly(hContact); return 0; } @@ -74,43 +67,28 @@ static INT_PTR ExportContactHistory(WPARAM hContact, LPARAM) return 0; } -///////////////////////////////////////////////////////////////////// -// Member Function : nSystemShutdown -// Type : Global -// Parameters : wparam - 0 -// lparam - 0 -// Returns : int -// Description : -// -// References : - -// Remarks : - -// Created : 020428, 28 April 2002 -// Developer : KN -///////////////////////////////////////////////////////////////////// - -int nSystemShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/) +///////////////////////////////////////////////////////////////////////////////////////// + +static int nSystemShutdown(WPARAM, LPARAM) { WindowList_Broadcast(hInternalWindowList, WM_CLOSE, 0, 0); return 0; } -///////////////////////////////////////////////////////////////////// -// Member Function : MainInit -// Type : Global -// Parameters : wparam - ? -// lparam - ? -// Returns : int -// Description : Called when system modules has been loaded -// -// References : - -// Remarks : - -// Created : 020422, 22 April 2002 -// Developer : KN -///////////////////////////////////////////////////////////////////// - -int MainInit(WPARAM /*wparam*/, LPARAM /*lparam*/) +static int OnModuleLoaded(WPARAM, LPARAM) +{ + if (g_pDriver = GetDatabasePlugin("JSON")) + g_bUseJson = g_plugin.bUseJson; + else + g_bUseJson = false; + + return 0; +} + +int MainInit(WPARAM, LPARAM) { bReadMirandaDirAndPath(); + OnModuleLoaded(0, 0); UpdateFileToColWidth(); CMenuItem mi(&g_plugin); @@ -121,7 +99,7 @@ int MainInit(WPARAM /*wparam*/, LPARAM /*lparam*/) mi.pszService = MS_EXPORT_HISTORY; Menu_AddContactMenuItem(&mi); - if (!g_bReplaceHistory) { + if (!g_plugin.bReplaceHistory) { SET_UID(mi, 0x701c543, 0xd078, 0x41dd, 0x95, 0xe3, 0x96, 0x49, 0x8a, 0x72, 0xc7, 0x50); mi.hIcolibItem = g_plugin.getIconHandle(IDI_MAIN); mi.position = 1000090100; @@ -130,22 +108,14 @@ int MainInit(WPARAM /*wparam*/, LPARAM /*lparam*/) Menu_AddContactMenuItem(&mi); } + HookEvent(ME_SYSTEM_MODULELOAD, OnModuleLoaded); + HookEvent(ME_SYSTEM_MODULEUNLOAD, OnModuleLoaded); HookEvent(ME_SYSTEM_SHUTDOWN, nSystemShutdown); return 0; } -///////////////////////////////////////////////////////////////////// -// Member Function : Load -// Type : Global -// Parameters : link - ? -// Returns : int -// Description : -// -// References : - -// Remarks : - -// Created : 020422, 22 April 2002 -// Developer : KN -///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// Plugin entry point static IconItem iconList[] = { @@ -172,19 +142,12 @@ int CMPlugin::Load() g_sTimeFormat = _DBGetStringW(0, MODULENAME, "TimeFormat", L"d s"); sFileViewerPrg = _DBGetStringW(0, MODULENAME, "FileViewerPrg", L""); - g_bUseIntViewer = getBool("UseInternalViewer", true); - - g_bUseJson = getBool("UseJson", false); - g_bAppendNewLine = getBool("AppendNewLine", true); - g_bReplaceHistory = getBool("ReplaceHistory", false); - g_bUseUtf8InNewFiles = getBool("UseUtf8InNewFiles", true); - g_bUseLessAndGreaterInExport = getBool("UseLessAndGreaterInExport", false); g_enRenameAction = (ENDialogAction)getByte("RenameAction", eDAPromptUser); g_enDeleteAction = (ENDialogAction)getByte("DeleteAction", eDAPromptUser); HANDLE hServiceFunc = nullptr; - if (g_bReplaceHistory) + if (g_plugin.bReplaceHistory) hServiceFunc = CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, ShowExportHistory); //this need new code if (!hServiceFunc) @@ -196,19 +159,6 @@ int CMPlugin::Load() return 0; } -///////////////////////////////////////////////////////////////////// -// Member Function : Unload -// Type : Global -// Parameters : none -// Returns : -// Description : -// -// References : - -// Remarks : - -// Created : 020422, 22 April 2002 -// Developer : KN -///////////////////////////////////////////////////////////////////// - int CMPlugin::Unload() { WindowList_Destroy(hInternalWindowList); diff --git a/plugins/Msg_Export/src/options.cpp b/plugins/Msg_Export/src/options.cpp index 31f4e5a6fc..1426854feb 100644 --- a/plugins/Msg_Export/src/options.cpp +++ b/plugins/Msg_Export/src/options.cpp @@ -169,10 +169,20 @@ void __cdecl exportContactsMessages(struct ExportDialogData *data) // Open/create file for writing wstring sFilePath = F.first; - HANDLE hFile = openCreateFile(sFilePath); - if (hFile == INVALID_HANDLE_VALUE) { - DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath, nullptr); - continue; + MDatabaseExport *pJson = nullptr; + HANDLE hFile; + + if (g_bUseJson) { + pJson = g_pDriver->Export(sFilePath.c_str()); + pJson->BeginExport(); + hFile = pJson; + } + else { + hFile = openCreateFile(sFilePath); + if (hFile == INVALID_HANDLE_VALUE) { + DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath, nullptr); + continue; + } } // At first write we need to have this false (to write file header, etc.), for each next write to same file use true @@ -189,7 +199,11 @@ void __cdecl exportContactsMessages(struct ExportDialogData *data) } // Close the file - CloseHandle(hFile); + if (pJson) { + pJson->EndExport(); + delete pJson; + } + else CloseHandle(hFile); SendMessage(hProg, PBM_SETPOS, ++nCur, 0); RedrawWindow(hDlg, nullptr, nullptr, RDW_ALLCHILDREN | RDW_UPDATENOW); @@ -204,18 +218,36 @@ void __cdecl exportContactsMessages(struct ExportDialogData *data) class CBasicOptDlg : public CDlgBase { CCtrlButton btnBrowseDir, btnBrowseFile; + CCtrlCheck chkJson, chkUseUtf8, chkAppendNewLine, chkIntViewer, chkAngleBrackets, chkReplaceHistory; CCtrlCombo cmbExportDir, cmbDefaultFile, cmbTimeFormat, cmbFileViewer; + bool bOrigReplaceHistory; + public: CBasicOptDlg() : CDlgBase(g_plugin, IDD_OPT_MSGEXPORT), btnBrowseDir(this, IDC_EXPORT_DIR_BROWSE), btnBrowseFile(this, IDC_FILE_VIEWER_BROWSE), + chkJson(this, IDC_USE_JSON), + chkUseUtf8(this, IDC_USE_UTF8_IN_NEW_FILES), + chkIntViewer(this, IDC_USE_INTERNAL_VIEWER), + chkAppendNewLine(this, IDC_APPEND_NEWLINE), + chkAngleBrackets(this, IDC_USE_ANGLE_BRACKETS), + chkReplaceHistory(this, IDC_REPLACE_MIRANDA_HISTORY), cmbExportDir(this, IDC_EXPORT_DIR), cmbTimeFormat(this, IDC_EXPORT_TIMEFORMAT), cmbFileViewer(this, IDC_FILE_VIEWER), cmbDefaultFile(this, IDC_DEFAULT_FILE) { + CreateLink(chkJson, g_plugin.bUseJson); + CreateLink(chkUseUtf8, g_plugin.bUseUtf8InNewFiles); + CreateLink(chkIntViewer, g_plugin.bUseIntViewer); + CreateLink(chkAppendNewLine, g_plugin.bAppendNewLine); + CreateLink(chkAngleBrackets, g_plugin.bUseAngleBrackets); + CreateLink(chkReplaceHistory, g_plugin.bReplaceHistory); + + bOrigReplaceHistory = g_plugin.bReplaceHistory; + btnBrowseDir.OnClick = Callback(this, &CBasicOptDlg::onClick_BrowseDir); btnBrowseFile.OnClick = Callback(this, &CBasicOptDlg::onClick_BrowseFile); } @@ -264,12 +296,7 @@ public: cmbFileViewer.AddString(L"C:\\WinNT\\Notepad.exe"); cmbFileViewer.AddString(L"C:\\Program Files\\Notepad++\\notepad++.exe"); - CheckDlgButton(m_hwnd, IDC_USE_JSON, g_bUseJson ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(m_hwnd, IDC_USE_INTERNAL_VIEWER, g_bUseIntViewer ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(m_hwnd, IDC_REPLACE_MIRANDA_HISTORY, g_bReplaceHistory ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(m_hwnd, IDC_APPEND_NEWLINE, g_bAppendNewLine ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(m_hwnd, IDC_USE_UTF8_IN_NEW_FILES, g_bUseUtf8InNewFiles ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(m_hwnd, IDC_USE_LESS_AND_GREATER_IN_EXPORT, g_bUseLessAndGreaterInExport ? BST_CHECKED : BST_UNCHECKED); + chkJson.Enable(g_pDriver != 0); return true; } @@ -303,27 +330,12 @@ public: sFileViewerPrg = szTemp; g_plugin.setWString("FileViewerPrg", sFileViewerPrg.c_str()); - bUseInternalViewer(IsDlgButtonChecked(m_hwnd, IDC_USE_INTERNAL_VIEWER) == BST_CHECKED); - g_plugin.setByte("UseInternalViewer", g_bUseIntViewer); - - bool bNewRp = IsDlgButtonChecked(m_hwnd, IDC_REPLACE_MIRANDA_HISTORY) == BST_CHECKED; - if (g_bReplaceHistory != bNewRp) { - g_bReplaceHistory = bNewRp; + if (bOrigReplaceHistory != g_plugin.bReplaceHistory) MessageBox(m_hwnd, TranslateT("You need to restart Miranda to change the history function"), MSG_BOX_TITEL, MB_OK); - } - g_plugin.setByte("ReplaceHistory", g_bReplaceHistory); - - g_bUseJson = IsDlgButtonChecked(m_hwnd, IDC_USE_JSON) == BST_CHECKED; - g_plugin.setByte("UseJson", g_bUseJson); - - g_bAppendNewLine = IsDlgButtonChecked(m_hwnd, IDC_APPEND_NEWLINE) == BST_CHECKED; - g_plugin.setByte("AppendNewLine", g_bAppendNewLine); - g_bUseUtf8InNewFiles = IsDlgButtonChecked(m_hwnd, IDC_USE_UTF8_IN_NEW_FILES) == BST_CHECKED; - g_plugin.setByte("UseUtf8InNewFiles", g_bUseUtf8InNewFiles); + if (chkJson.Enabled()) + g_bUseJson = g_plugin.bUseJson; - g_bUseLessAndGreaterInExport = IsDlgButtonChecked(m_hwnd, IDC_USE_LESS_AND_GREATER_IN_EXPORT) == BST_CHECKED; - g_plugin.setByte("UseLessAndGreaterInExport", g_bUseLessAndGreaterInExport); return true; } diff --git a/plugins/Msg_Export/src/resource.h b/plugins/Msg_Export/src/resource.h index d42cfb4645..194585b410 100644 --- a/plugins/Msg_Export/src/resource.h +++ b/plugins/Msg_Export/src/resource.h @@ -29,7 +29,7 @@ #define IDC_FILE_VIEWER_BROWSE 1063 #define IDC_FILE_VIEWER 1064 #define IDC_APPEND_NEWLINE 1065 -#define IDC_USE_LESS_AND_GREATER_IN_EXPORT 1066 +#define IDC_USE_ANGLE_BRACKETS 1066 #define IDC_FC_PROMPT 1067 #define IDC_FC_RENAME 1068 #define IDC_FC_NOTHING 1069 diff --git a/plugins/Msg_Export/src/stdafx.h b/plugins/Msg_Export/src/stdafx.h index 8c22887482..a914349564 100644 --- a/plugins/Msg_Export/src/stdafx.h +++ b/plugins/Msg_Export/src/stdafx.h @@ -32,22 +32,22 @@ using namespace std; #include #include -#include -#include #include #include #include +#include +#include +#include +#include +#include #include +#include #include #include -#include -#include -#include #include -#include #include -#include -#include +#include +#include #include "utils.h" #include "options.h" @@ -66,6 +66,8 @@ struct CMPlugin : public PLUGIN { CMPlugin(); + CMOption bUseJson, bAppendNewLine, bReplaceHistory, bUseIntViewer, bUseAngleBrackets, bUseUtf8InNewFiles; + int Load() override; int Unload() override; }; diff --git a/plugins/Msg_Export/src/utils.cpp b/plugins/Msg_Export/src/utils.cpp index c30c32a62b..8fa20770cc 100644 --- a/plugins/Msg_Export/src/utils.cpp +++ b/plugins/Msg_Export/src/utils.cpp @@ -49,22 +49,16 @@ map > clFileTo1ColWidth; // default line width int nMaxLineWidth = 80; -// Allow this plugin to replace the history function of miranda !! -bool g_bReplaceHistory; - // This enum define the actions which MsgExport must take when a File is renamed ENDialogAction g_enRenameAction; // This enum define the actions which MsgExport must take when a user is delete ENDialogAction g_enDeleteAction; -// If true MsgExport will use << and >> instead of the nick in the exported format -bool g_bUseLessAndGreaterInExport; - -bool g_bAppendNewLine; -bool g_bUseUtf8InNewFiles; bool g_bUseJson; +DATABASELINK *g_pDriver = nullptr; + const char szUtf8ByteOrderHeader[] = "\xEF\xBB\xBF"; bool bIsUtf8Header(uint8_t * pucByteOrder) { @@ -228,21 +222,6 @@ static bool bWriteTextToFile(HANDLE hFile, const wchar_t *pszSrc, bool bUtf8File return bWriteToFile(hFile, T2Utf(pszSrc), -1); } - -static bool bWriteTextToFile(HANDLE hFile, const char *pszSrc, bool bUtf8File, int nLen = -1) -{ - if (!bUtf8File) - return bWriteToFile(hFile, pszSrc, nLen); - - if (nLen != -1) { - char *tmp = (char*)alloca(nLen + 1); - mir_strncpy(tmp, pszSrc, nLen + 1); - pszSrc = tmp; - } - - return bWriteToFile(hFile, ptrA(mir_utf8encode(pszSrc)), -1); -} - ///////////////////////////////////////////////////////////////////// // Member Function : bWriteNewLine // Type : Global @@ -627,6 +606,7 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF wstring sLocalUser; wstring sRemoteUser; string::size_type nFirstColumnWidth; + auto *pJson = (MDatabaseExport *)hFile; const char *szProto = Proto_GetBaseAccountName(hContact); if (szProto == nullptr) { @@ -634,7 +614,7 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF return false; } - if (g_bUseLessAndGreaterInExport) { + if (g_plugin.bUseAngleBrackets) { sLocalUser = L"<<"; sRemoteUser = L">>"; nFirstColumnWidth = 4; @@ -656,14 +636,9 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF bool bWriteUTF8Format = false; if (bAppendOnly) { - bWriteUTF8Format = g_bUseUtf8InNewFiles; - - if (g_bUseJson) { - SetFilePointer(hFile, -3, nullptr, FILE_END); - bWriteToFile(hFile, ",", 1); - } + bWriteUTF8Format = g_plugin.bUseUtf8InNewFiles; } - else { + else if (!g_bUseJson) { DWORD dwHighSize = 0; DWORD dwLowSize = GetFileSize(hFile, &dwHighSize); if (dwLowSize == INVALID_FILE_SIZE || dwLowSize != 0 || dwHighSize != 0) { @@ -672,142 +647,54 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF if (ReadFile(hFile, ucByteOrder, 3, &dwDataRead, nullptr)) bWriteUTF8Format = bIsUtf8Header(ucByteOrder); - DWORD dwPtr = SetFilePointer(hFile, g_bUseJson ? -3 : 0, nullptr, FILE_END); + DWORD dwPtr = SetFilePointer(hFile, 0, nullptr, FILE_END); if (dwPtr == INVALID_SET_FILE_POINTER) return false; - if (g_bUseJson) - bWriteToFile(hFile, ",", 1); - } - else { - if (g_bUseJson) { - JSONNode pRoot, pInfo, pHist(JSON_ARRAY); - pInfo.set_name("info"); - pInfo.push_back(JSONNode("user", T2Utf(sRemoteUser.c_str()).get())); - pInfo.push_back(JSONNode("proto", szProto)); - - ptrW contactId(Contact::GetInfo(CNF_UNIQUEID, hContact, szProto)); - if (contactId != NULL) - pInfo.push_back(JSONNode("uin", T2Utf(contactId).get())); - - szTemp[0] = (wchar_t)db_get_b(hContact, szProto, "Gender", 0); - if (szTemp[0]) { - szTemp[1] = 0; - pInfo.push_back(JSONNode("gender", T2Utf(szTemp).get())); - } + bWriteUTF8Format = g_plugin.bUseUtf8InNewFiles; + if (bWriteUTF8Format) + if (!bWriteToFile(hFile, szUtf8ByteOrderHeader, sizeof(szUtf8ByteOrderHeader) - 1)) + return false; - int age = db_get_w(hContact, szProto, "Age", 0); - if (age != 0) - pInfo.push_back(JSONNode("age", age)); + CMStringW output = L"------------------------------------------------\r\n"; + output.AppendFormat(L"%s\r\n", TranslateT(" History for")); - for (auto &it : pSettings) { - wstring szValue = _DBGetStringW(hContact, szProto, it, L""); - if (!szValue.empty()) - pInfo.push_back(JSONNode(it, T2Utf(szValue.c_str()).get())); - } - pRoot.push_back(pInfo); + // This is written this way because I expect this will become a string the user may set + // in the options dialog. + output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User"), sRemoteUser.c_str()); + output.AppendFormat(L"%-10s: %S\r\n", TranslateT("Account"), szProto); - pHist.set_name("history"); - pRoot.push_back(pHist); + ptrW id(Contact::GetInfo(CNF_UNIQUEID, hContact, szProto)); + if (id != NULL) + output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User ID"), id.get()); - std::string output = pRoot.write_formatted(); - if (!bWriteTextToFile(hFile, output.c_str(), false, (int)output.size())) - return false; - - SetFilePointer(hFile, -3, nullptr, FILE_CURRENT); + szTemp[0] = (wchar_t)db_get_b(hContact, szProto, "Gender", 0); + if (szTemp[0]) { + szTemp[1] = 0; + output.AppendFormat(L"%-10s: %s\r\n", TranslateT("Gender"), szTemp); } - else { - bWriteUTF8Format = g_bUseUtf8InNewFiles; - if (bWriteUTF8Format) - if (!bWriteToFile(hFile, szUtf8ByteOrderHeader, sizeof(szUtf8ByteOrderHeader) - 1)) - return false; - - CMStringW output = L"------------------------------------------------\r\n"; - output.AppendFormat(L"%s\r\n", TranslateT(" History for")); - - // This is written this way because I expect this will become a string the user may set - // in the options dialog. - output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User"), sRemoteUser.c_str()); - output.AppendFormat(L"%-10s: %S\r\n", TranslateT("Account"), szProto); - - ptrW id(Contact::GetInfo(CNF_UNIQUEID, hContact, szProto)); - if (id != NULL) - output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User ID"), id.get()); - - szTemp[0] = (wchar_t)db_get_b(hContact, szProto, "Gender", 0); - if (szTemp[0]) { - szTemp[1] = 0; - output.AppendFormat(L"%-10s: %s\r\n", TranslateT("Gender"), szTemp); - } - int age = db_get_w(hContact, szProto, "Age", 0); - if (age != 0) - output.AppendFormat(L"%-10s: %d\r\n", TranslateT("Age"), age); + int age = db_get_w(hContact, szProto, "Age", 0); + if (age != 0) + output.AppendFormat(L"%-10s: %d\r\n", TranslateT("Age"), age); - for (auto &it : pSettings) { - wstring szValue = _DBGetStringW(hContact, szProto, it, L""); - if (!szValue.empty()) { - mir_snwprintf(szTemp, L"%-10s: %s\r\n", TranslateW(_A2T(it)), szValue.c_str()); - output += szTemp; - } + for (auto &it : pSettings) { + wstring szValue = _DBGetStringW(hContact, szProto, it, L""); + if (!szValue.empty()) { + mir_snwprintf(szTemp, L"%-10s: %s\r\n", TranslateW(_A2T(it)), szValue.c_str()); + output += szTemp; } + } - output += L"------------------------------------------------\r\n"; + output += L"------------------------------------------------\r\n"; - if (!bWriteTextToFile(hFile, output, bWriteUTF8Format, output.GetLength())) - return false; - } + if (!bWriteTextToFile(hFile, output, bWriteUTF8Format, output.GetLength())) + return false; } } if (g_bUseJson) { - JSONNode pRoot; - pRoot.push_back(JSONNode("type", dbei.eventType)); - if (mir_strcmp(dbei.szModule, szProto)) - pRoot.push_back(JSONNode("module", dbei.szModule)); - - if (dbei.szUserId && !(dbei.flags & DBEF_SENT)) - pRoot.push_back(JSONNode("member", T2Utf(sRemoteUser.c_str()).get())); - - TimeZone_PrintTimeStamp(UTC_TIME_HANDLE, dbei.timestamp, L"I", szTemp, _countof(szTemp), 0); - pRoot.push_back(JSONNode("isotime", T2Utf(szTemp).get())); - - std::string flags; - if (dbei.flags & DBEF_SENT) - flags += "m"; - if (dbei.flags & DBEF_READ) - flags += "r"; - if (dbei.flags & DBEF_BOOKMARK) - flags += "b"; - - pRoot.push_back(JSONNode("flags", flags)); - - if (dbei.eventType == EVENTTYPE_FILE) { - DB::FILE_BLOB blob(dbei); - - pRoot << WCHAR_PARAM("file", blob.getName()); - if (mir_wstrlen(blob.getDescr())) - pRoot << WCHAR_PARAM("descr", blob.getDescr()); - if (blob.isOffline()) { - pRoot << INT_PARAM("fileSize", blob.getSize()) << INT_PARAM("transferred", blob.getTransferred()); - if (mir_wstrlen(blob.getLocalName())) - pRoot << WCHAR_PARAM("localFile", blob.getLocalName()); - if (mir_strlen(blob.getUrl())) - pRoot << CHAR_PARAM("url", blob.getUrl()); - } - } - else { - ptrW msg(DbEvent_GetTextW(&dbei)); - if (msg) - pRoot.push_back(JSONNode("body", T2Utf(msg).get())); - } - - std::string output = pRoot.write_formatted(); - output += "\n]}"; - - if (!bWriteTextToFile(hFile, output.c_str(), false, (int)output.size())) - return false; - + pJson->ExportEvent(dbei); return true; } @@ -937,7 +824,7 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF bWriteTextToFile(hFile, szTemp, bWriteUTF8Format, n); } - bWriteToFile(hFile, g_bAppendNewLine ? "\r\n\r\n" : "\r\n"); + bWriteToFile(hFile, g_plugin.bAppendNewLine ? "\r\n\r\n" : "\r\n"); UpdateFileViews(sFilePath.c_str()); return true; } @@ -987,17 +874,37 @@ int nExportEvent(WPARAM hContact, LPARAM hDbEvent) // Open/create file for writing wstring sFilePath = GetFilePathFromUser(hContact); - HANDLE hFile = openCreateFile(sFilePath); - if (hFile == INVALID_HANDLE_VALUE) { - DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath, nullptr); - return 0; + MDatabaseExport *pJson = nullptr; + HANDLE hFile; + + if (g_bUseJson) { + pJson = g_pDriver->Export(sFilePath.c_str()); + if (pJson == nullptr) { + DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath, nullptr); + return 0; + } + + if (!pJson->BeginExport()) + pJson->ExportContact(hContact); + hFile = pJson; + } + else { + hFile = openCreateFile(sFilePath); + if (hFile == INVALID_HANDLE_VALUE) { + DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath, nullptr); + return 0; + } } // Write the event bExportEvent(hContact, hDbEvent, hFile, sFilePath, false); // Close the file - CloseHandle(hFile); + if (pJson) { + pJson->EndExport(); + delete pJson; + } + else CloseHandle(hFile); return 0; } diff --git a/plugins/Msg_Export/src/utils.h b/plugins/Msg_Export/src/utils.h index 8e50aeff9a..b5b650e2f3 100644 --- a/plugins/Msg_Export/src/utils.h +++ b/plugins/Msg_Export/src/utils.h @@ -36,12 +36,9 @@ extern wstring g_sDefaultFile; extern wstring g_sTimeFormat; extern map > clFileTo1ColWidth; -extern bool g_bAppendNewLine; extern bool g_bUseJson; -extern bool g_bUseUtf8InNewFiles; -extern bool g_bUseLessAndGreaterInExport; -extern bool g_bReplaceHistory; +extern DATABASELINK *g_pDriver; void LogLastError(const wchar_t *pszError); void DisplayErrorDialog(const wchar_t *pszError, wstring &sFilePath, DBEVENTINFO *dbei); -- cgit v1.2.3